diff options
| author | Juan Linietsky | 2014-02-09 22:10:30 -0300 |
|---|---|---|
| committer | Juan Linietsky | 2014-02-09 22:10:30 -0300 |
| commit | 0b806ee0fc9097fa7bda7ac0109191c9c5e0a1ac (patch) | |
| tree | 276c4d099e178eb67fbd14f61d77b05e3808e9e3 /platform/bb10 | |
| parent | 0e49da1687bc8192ed210947da52c9e5c5f301bb (diff) | |
| download | godot-0b806ee.tar.gz godot-0b806ee.tar.zst godot-0b806ee.zip | |
GODOT IS OPEN SOURCE
Diffstat (limited to 'platform/bb10')
| -rw-r--r-- | platform/bb10/SCsub | 30 | ||||
| -rw-r--r-- | platform/bb10/audio_driver_bb10.cpp | 255 | ||||
| -rw-r--r-- | platform/bb10/audio_driver_bb10.h | 78 | ||||
| -rw-r--r-- | platform/bb10/bar/bar-descriptor.xml | 65 | ||||
| -rw-r--r-- | platform/bb10/bar/icon.png | bin | 0 -> 8188 bytes | |||
| -rw-r--r-- | platform/bb10/bbutil.c | 513 | ||||
| -rw-r--r-- | platform/bb10/bbutil.h | 96 | ||||
| -rw-r--r-- | platform/bb10/detect.py | 91 | ||||
| -rw-r--r-- | platform/bb10/export/export.cpp | 805 | ||||
| -rw-r--r-- | platform/bb10/export/export.h | 3 | ||||
| -rw-r--r-- | platform/bb10/godot_bb10.cpp | 48 | ||||
| -rw-r--r-- | platform/bb10/logo.png | bin | 0 -> 1852 bytes | |||
| -rw-r--r-- | platform/bb10/os_bb10.cpp | 630 | ||||
| -rw-r--r-- | platform/bb10/os_bb10.h | 157 | ||||
| -rw-r--r-- | platform/bb10/payment_service.cpp | 150 | ||||
| -rw-r--r-- | platform/bb10/payment_service.h | 69 | ||||
| -rw-r--r-- | platform/bb10/platform_config.h | 29 |
17 files changed, 3019 insertions, 0 deletions
diff --git a/platform/bb10/SCsub b/platform/bb10/SCsub new file mode 100644 index 000000000..2e8ef4700 --- /dev/null +++ b/platform/bb10/SCsub @@ -0,0 +1,30 @@ +Import('env') + +bb10_lib = [ + + 'bbutil.c', + 'os_bb10.cpp', + 'audio_driver_bb10.cpp', + 'godot_bb10.cpp', + 'payment_service.cpp', +] + +env_bps = env.Clone() +if env['bb10_payment_service'] == "yes": + env_bps.Append(CPPFLAGS=['-DPAYMENT_SERVICE_ENABLED']) + +if env['bb10_lgles_override'] == "yes": + env_bps.Append(CPPFLAGS=['-DBB10_LGLES_OVERRIDE']) + + +prog = None +if env["target"]=="release": + prog = env_bps.Program('#platform/bb10/godot_bb10_opt', bb10_lib) +else: + prog = env_bps.Program('#platform/bb10/godot_bb10', bb10_lib) + +import os +fname = os.path.basename(str(prog[0])) + +env.Command('#bin/'+fname, prog, Copy('bin/'+fname, prog[0])) + diff --git a/platform/bb10/audio_driver_bb10.cpp b/platform/bb10/audio_driver_bb10.cpp new file mode 100644 index 000000000..ac6a008a0 --- /dev/null +++ b/platform/bb10/audio_driver_bb10.cpp @@ -0,0 +1,255 @@ +/*************************************************************************/ +/* audio_driver_bb10.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "audio_driver_bb10.h" + +#include <errno.h> + +Error AudioDriverBB10::init() { + return init(NULL); +}; + +Error AudioDriverBB10::init(const char* p_name) { + + active=false; + thread_exited=false; + exit_thread=false; + pcm_open = false; + samples_in = NULL; + samples_out = NULL; + + mix_rate = 44100; + output_format = OUTPUT_STEREO; + + char* dev_name; + if (p_name == NULL) { + dev_name = "pcmPreferred"; + } else { + dev_name = (char *) p_name; + } + printf("******** reconnecting to device %s\n", dev_name); + int card, dev; + int ret = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK); + ERR_FAIL_COND_V(ret < 0, FAILED); + pcm_open = true; + + snd_pcm_channel_info_t cinfo; + zeromem(&cinfo, sizeof (cinfo)); + cinfo.channel = SND_PCM_CHANNEL_PLAYBACK; + snd_pcm_plugin_info(pcm_handle, &cinfo); + + printf("rates %i, %i, %i, %i, %i\n", cinfo.rates, cinfo.rates & SND_PCM_RATE_44100, cinfo.rates & SND_PCM_RATE_32000, cinfo.rates & SND_PCM_RATE_22050, cinfo.max_rate); + + mix_rate = cinfo.max_rate; + + printf("formats %i, %i, %i\n", cinfo.formats, cinfo.formats & SND_PCM_FMT_S16_BE, cinfo.formats & SND_PCM_FMT_S16_LE); + ERR_FAIL_COND_V(!(cinfo.formats & SND_PCM_FMT_S16_LE), FAILED); + + printf("voices %i\n", cinfo.max_voices); + output_format = cinfo.max_voices >= 2 ? OUTPUT_STEREO : OUTPUT_MONO; + + snd_pcm_channel_params_t cp; + zeromem(&cp, sizeof(cp)); + cp.mode = SND_PCM_MODE_BLOCK; + cp.channel = SND_PCM_CHANNEL_PLAYBACK; + cp.start_mode = SND_PCM_START_DATA; + cp.stop_mode = SND_PCM_STOP_STOP; + //cp.buf.block.frag_size = cinfo.max_fragment_size; + cp.buf.block.frag_size = 512; + cp.buf.block.frags_max = 1; + cp.buf.block.frags_min = 1; + cp.format.interleave = 1; + cp.format.rate = mix_rate; + cp.format.voices = output_format == OUTPUT_MONO ? 1 : 2; + cp.format.format = SND_PCM_SFMT_S16_LE; + + ret = snd_pcm_plugin_params(pcm_handle, &cp); + printf("ret is %i, %i\n", ret, cp.why_failed); + ERR_FAIL_COND_V(ret < 0, FAILED); + + ret = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK); + ERR_FAIL_COND_V(ret < 0, FAILED); + + snd_mixer_group_t group; + zeromem(&group, sizeof(group)); + snd_pcm_channel_setup_t setup; + zeromem(&setup, sizeof(setup)); + setup.channel = SND_PCM_CHANNEL_PLAYBACK; + setup.mode = SND_PCM_MODE_BLOCK; + setup.mixer_gid = &group.gid; + ret = snd_pcm_plugin_setup(pcm_handle, &setup); + ERR_FAIL_COND_V(ret < 0, FAILED); + + pcm_frag_size = setup.buf.block.frag_size; + pcm_max_frags = 1; + + sample_buf_count = pcm_frag_size * pcm_max_frags / 2; + printf("sample count %i, %i, %i\n", sample_buf_count, pcm_frag_size, pcm_max_frags); + samples_in = memnew_arr(int32_t, sample_buf_count); + samples_out = memnew_arr(int16_t, sample_buf_count); + + thread = Thread::create(AudioDriverBB10::thread_func, this); + + return OK; +}; + +void AudioDriverBB10::thread_func(void* p_udata) { + + AudioDriverBB10* ad = (AudioDriverBB10*)p_udata; + + int channels = (ad->output_format == OUTPUT_MONO ? 1 : 2); + int frame_count = ad->sample_buf_count / channels; + int bytes_out = frame_count * channels * 2; + + while (!ad->exit_thread) { + + + if (!ad->active) { + + for (int i=0; i < ad->sample_buf_count; i++) { + + ad->samples_out[i] = 0; + }; + } else { + + ad->lock(); + + ad->audio_server_process(frame_count, ad->samples_in); + + ad->unlock(); + + for(int i=0;i<frame_count*channels;i++) { + + ad->samples_out[i]=ad->samples_in[i]>>16; + } + }; + + + int todo = bytes_out; + int total = 0; + + while (todo) { + + uint8_t* src = (uint8_t*)ad->samples_out; + int wrote = snd_pcm_plugin_write(ad->pcm_handle, (void*)(src + total), todo); + if (wrote < 0) { + // error? + break; + }; + total += wrote; + todo -= wrote; + if (wrote < todo) { + if (ad->thread_exited) { + break; + }; + printf("pcm_write underrun %i, errno %i\n", (int)ad->thread_exited, errno); + snd_pcm_channel_status_t status; + zeromem(&status, sizeof(status)); + // put in non-blocking mode + snd_pcm_nonblock_mode(ad->pcm_handle, 1); + status.channel = SND_PCM_CHANNEL_PLAYBACK; + int ret = snd_pcm_plugin_status(ad->pcm_handle, &status); + //printf("status return %i, %i, %i, %i, %i\n", ret, errno, status.status, SND_PCM_STATUS_READY, SND_PCM_STATUS_UNDERRUN); + snd_pcm_nonblock_mode(ad->pcm_handle, 0); + if (ret < 0) { + break; + }; + if (status.status == SND_PCM_STATUS_READY || + status.status == SND_PCM_STATUS_UNDERRUN) { + snd_pcm_plugin_prepare(ad->pcm_handle, SND_PCM_CHANNEL_PLAYBACK); + } else { + break; + }; + }; + }; + }; + + snd_pcm_plugin_flush (ad->pcm_handle, SND_PCM_CHANNEL_PLAYBACK); + + ad->thread_exited=true; + printf("**************** audio thread exit\n"); +}; + +void AudioDriverBB10::start() { + + active = true; +}; + +int AudioDriverBB10::get_mix_rate() const { + + return mix_rate; +}; + +AudioDriverSW::OutputFormat AudioDriverBB10::get_output_format() const { + + return output_format; +}; +void AudioDriverBB10::lock() { + + if (!thread) + return; + mutex->lock(); +}; +void AudioDriverBB10::unlock() { + + if (!thread) + return; + mutex->unlock(); +}; + +void AudioDriverBB10::finish() { + + if (!thread) + return; + + exit_thread = true; + Thread::wait_to_finish(thread); + + if (pcm_open) + snd_pcm_close(pcm_handle); + + if (samples_in) { + memdelete_arr(samples_in); + memdelete_arr(samples_out); + }; + + memdelete(thread); + thread = NULL; +}; + +AudioDriverBB10::AudioDriverBB10() { + + mutex = Mutex::create(); +}; + +AudioDriverBB10::~AudioDriverBB10() { + + memdelete(mutex); + mutex = NULL; +}; + diff --git a/platform/bb10/audio_driver_bb10.h b/platform/bb10/audio_driver_bb10.h new file mode 100644 index 000000000..98b99107d --- /dev/null +++ b/platform/bb10/audio_driver_bb10.h @@ -0,0 +1,78 @@ +/*************************************************************************/ +/* audio_driver_bb10.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "servers/audio/audio_server_sw.h" + +#include "core/os/thread.h" +#include "core/os/mutex.h" + +#include <sys/asoundlib.h> + +class AudioDriverBB10 : public AudioDriverSW { + + Thread* thread; + Mutex* mutex; + + snd_pcm_t* pcm_handle; + + int32_t* samples_in; + int16_t* samples_out; + int sample_buf_count; + + static void thread_func(void* p_udata); + + int mix_rate; + OutputFormat output_format; + + int pcm_frag_size; + int pcm_max_frags; + + bool active; + bool thread_exited; + mutable bool exit_thread; + bool pcm_open; + +public: + + const char* get_name() const { + return "BB10"; + }; + + virtual Error init(); + virtual Error init(const char* p_name); + virtual void start(); + virtual int get_mix_rate() const; + virtual OutputFormat get_output_format() const; + virtual void lock(); + virtual void unlock(); + virtual void finish(); + + AudioDriverBB10(); + ~AudioDriverBB10(); +}; + diff --git a/platform/bb10/bar/bar-descriptor.xml b/platform/bb10/bar/bar-descriptor.xml new file mode 100644 index 000000000..df5d34e07 --- /dev/null +++ b/platform/bb10/bar/bar-descriptor.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<qnx xmlns="http://www.qnx.com/schemas/application/1.0"> + +<!-- BlackBerry® 10 application descriptor file. + + Specifies parameters for identifying, installing, and launching native applications on BlackBerry® 10 OS. +--> + + <!-- A universally unique application identifier. Must be unique across all BlackBerry applications. + Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. --> + <id>com.godot.game</id> + + <!-- The name that is displayed in the BlackBerry application installer. + May have multiple values for each language. See samples or xsd schema file. Optional. --> + <name>Godot Game</name> + + <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. + Values can also be 1-part or 2-part. It is not necessary to have a 3-part value. + An updated version of application must have a versionNumber value higher than the previous version. Required. --> + <versionNumber>0.0.1</versionNumber> + + <!-- Fourth digit segment of the package version. First three segments are taken from the + <versionNumber> element. Must be an integer from 0 to 2^16-1 --> + <buildId>0</buildId> + + <!-- Description, displayed in the BlackBerry application installer. + May have multiple values for each language. See samples or xsd schema file. Optional. --> + <description>Game made with Godot Engine</description> + + <!-- Name of author which is used for signing. Must match the developer name of your development certificate. --> + <author>You Name or Company</author> + <authorId>authorIDherePlease</authorId> + + <!-- Unique author ID assigned by signing authority. Required if using debug tokens. --> + <!-- <authorId>ABC1234YjsnUk235h</authorId> --> + + <initialWindow> + <aspectRatio>landscape</aspectRatio> + <autoOrients>false</autoOrients> + <systemChrome>none</systemChrome> + <transparent>false</transparent> + </initialWindow> + + <!-- The category where the application appears. Either core.games or core.media. --> + <category>core.games</category> + <permission>read_device_identifying_information</permission> + <permission>access_internet</permission> + <asset path="assets">assets</asset> + <configuration name="Device-Debug"> + <platformArchitecture>armle-v7</platformArchitecture> + <asset path="godot_bb10.qnx.armle" entry="true" type="Qnx/Elf">godot_bb10.qnx.armle</asset> + </configuration> + <configuration name="Device-Release"> + <platformArchitecture>armle-v7</platformArchitecture> + <asset path="godot_bb10_opt.qnx.armle" entry="true" type="Qnx/Elf">godot_bb10_opt.qnx.armle</asset> + </configuration> + <!-- The icon for the application. --> + <icon> + <image>icon.png</image> + </icon> + + <!-- Ensure that shared libraries in the package are found at run-time. --> + <env var="LD_LIBRARY_PATH" value="app/native/lib:/usr/lib/qt4/lib"/> + +</qnx> diff --git a/platform/bb10/bar/icon.png b/platform/bb10/bar/icon.png Binary files differnew file mode 100644 index 000000000..a837c8009 --- /dev/null +++ b/platform/bb10/bar/icon.png diff --git a/platform/bb10/bbutil.c b/platform/bb10/bbutil.c new file mode 100644 index 000000000..fce52c5b8 --- /dev/null +++ b/platform/bb10/bbutil.c @@ -0,0 +1,513 @@ +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/keycodes.h> +#include <time.h> + +#include "bbutil.h" + +EGLDisplay egl_disp; +EGLSurface egl_surf; + +static EGLConfig egl_conf; +static EGLContext egl_ctx; + +static screen_context_t screen_ctx; +static screen_window_t screen_win; +static screen_display_t screen_disp; + + +static void +bbutil_egl_perror(const char *msg) { + static const char *errmsg[] = { + "function succeeded", + "EGL is not initialized, or could not be initialized, for the specified display", + "cannot access a requested resource", + "failed to allocate resources for the requested operation", + "an unrecognized attribute or attribute value was passed in an attribute list", + "an EGLConfig argument does not name a valid EGLConfig", + "an EGLContext argument does not name a valid EGLContext", + "the current surface of the calling thread is no longer valid", + "an EGLDisplay argument does not name a valid EGLDisplay", + "arguments are inconsistent", + "an EGLNativePixmapType argument does not refer to a valid native pixmap", + "an EGLNativeWindowType argument does not refer to a valid native window", + "one or more argument values are invalid", + "an EGLSurface argument does not name a valid surface configured for rendering", + "a power management event has occurred", + }; + + fprintf(stderr, "%s: %s\n", msg, errmsg[eglGetError() - EGL_SUCCESS]); +} +EGLConfig bbutil_choose_config(EGLDisplay egl_disp, enum RENDERING_API api) { + EGLConfig egl_conf = (EGLConfig)0; + EGLConfig *egl_configs; + EGLint egl_num_configs; + EGLint val; + EGLBoolean rc; + EGLint i; + + rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglGetConfigs"); + return egl_conf; + } + if (egl_num_configs == 0) { + fprintf(stderr, "eglGetConfigs: could not find a configuration\n"); + return egl_conf; + } + + egl_configs = malloc(egl_num_configs * sizeof(*egl_configs)); + if (egl_configs == NULL) { + fprintf(stderr, "could not allocate memory for %d EGL configs\n", egl_num_configs); + return egl_conf; + } + + rc = eglGetConfigs(egl_disp, egl_configs, + egl_num_configs, &egl_num_configs); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglGetConfigs"); + free(egl_configs); + return egl_conf; + } + + for (i = 0; i < egl_num_configs; i++) { + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val); + if (!(val & EGL_WINDOW_BIT)) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val); + if (!(val & api)) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val); + if ((api & (GL_ES_1|GL_ES_2)) && (val == 0)) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RED_SIZE, &val); + if (val != 8) { + continue; + } + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_GREEN_SIZE, &val); + if (val != 8) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BLUE_SIZE, &val); + if (val != 8) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BUFFER_SIZE, &val); + if (val != 32) { + continue; + } + + egl_conf = egl_configs[i]; + break; + } + + free(egl_configs); + + if (egl_conf == (EGLConfig)0) { + fprintf(stderr, "bbutil_choose_config: could not find a matching configuration\n"); + } + + return egl_conf; +} + +int +bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api) { + int usage; + int format = SCREEN_FORMAT_RGBX8888; + int nbuffers = 2; + EGLint interval = 1; + int rc; + EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + + if (api == GL_ES_1) { + usage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION; + } else if (api == GL_ES_2) { + usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION; + } else if (api == VG) { + usage = SCREEN_USAGE_OPENVG | SCREEN_USAGE_ROTATION; + } else { + fprintf(stderr, "invalid api setting\n"); + return EXIT_FAILURE; + } + + //Simple egl initialization + screen_ctx = ctx; + + egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (egl_disp == EGL_NO_DISPLAY) { + bbutil_egl_perror("eglGetDisplay"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglInitialize(egl_disp, NULL, NULL); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglInitialize"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + if ((api == GL_ES_1) || (api == GL_ES_2)) { + rc = eglBindAPI(EGL_OPENGL_ES_API); + } else if (api == VG) { + rc = eglBindAPI(EGL_OPENVG_API); + } + + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglBindApi"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + egl_conf = bbutil_choose_config(egl_disp, api); + if (egl_conf == (EGLConfig)0) { + bbutil_terminate(); + return EXIT_FAILURE; + } + + if (api == GL_ES_2) { + egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes); + } else { + egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, NULL); + } + + if (egl_ctx == EGL_NO_CONTEXT) { + bbutil_egl_perror("eglCreateContext"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_create_window(&screen_win, screen_ctx); + if (rc) { + perror("screen_create_window"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format); + if (rc) { + perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage); + if (rc) { + perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp); + if (rc) { + perror("screen_get_window_property_pv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int screen_resolution[2]; + + rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution); + if (rc) { + perror("screen_get_display_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int angle = atoi(getenv("ORIENTATION")); + + screen_display_mode_t screen_mode; + rc = screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode); + if (rc) { + perror("screen_get_display_property_pv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int size[2]; + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_get_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int buffer_size[2] = {size[0], size[1]}; + + if ((angle == 0) || (angle == 180)) { + if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) || + ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) { + buffer_size[1] = size[0]; + buffer_size[0] = size[1]; + } + } else if ((angle == 90) || (angle == 270)){ + if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) || + ((screen_mode.width < screen_mode.height && size[0] < size[1]))) { + buffer_size[1] = size[0]; + buffer_size[0] = size[1]; + } + } else { + fprintf(stderr, "Navigator returned an unexpected orientation angle.\n"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size); + if (rc) { + perror("screen_set_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle); + if (rc) { + perror("screen_set_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_create_window_buffers(screen_win, nbuffers); + if (rc) { + perror("screen_create_window_buffers"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_create_window_group(screen_win, get_window_group_id()); + if (rc) { + perror("screen_create_window_group"); + bbutil_terminate(); + return EXIT_FAILURE; + } + /* if (screen_create_window_group(screen_win, get_window_group_id()) != 0) goto fail; */ + + int idle_mode = SCREEN_IDLE_MODE_KEEP_AWAKE; + screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_IDLE_MODE, &idle_mode); + + egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); + if (egl_surf == EGL_NO_SURFACE) { + bbutil_egl_perror("eglCreateWindowSurface"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglSwapInterval(egl_disp, interval); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapInterval"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +int +bbutil_init_gl2d() { +#if 0 + EGLint surface_width, surface_height; + + if ((egl_disp == EGL_NO_DISPLAY) || (egl_surf == EGL_NO_SURFACE) ){ + return EXIT_FAILURE; + } + + eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); + eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); + + glShadeModel(GL_SMOOTH); + + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + + glViewport(0, 0, surface_width, surface_height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glOrthof(0.0f, (float)(surface_width) / (float)(surface_height), 0.0f, 1.0f, -1.0f, 1.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +#endif + + return EXIT_SUCCESS; +} + +int +bbutil_init(screen_context_t ctx, enum RENDERING_API api) { + if (EXIT_SUCCESS != bbutil_init_egl(ctx, api)) { + return EXIT_FAILURE; + } + + if ((GL_ES_1 == api) && (EXIT_SUCCESS != bbutil_init_gl2d())) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +int bbutil_is_flipped() { + + int ret; + screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_FLIP, &ret); + return ret; +}; + +int bbutil_get_rotation() { + + int ret; + screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &ret); + return ret; +}; + + +void +bbutil_terminate() { + //Typical EGL cleanup + if (egl_disp != EGL_NO_DISPLAY) { + eglMakeCurrent(egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (egl_surf != EGL_NO_SURFACE) { + eglDestroySurface(egl_disp, egl_surf); + egl_surf = EGL_NO_SURFACE; + } + if (egl_ctx != EGL_NO_CONTEXT) { + eglDestroyContext(egl_disp, egl_ctx); + egl_ctx = EGL_NO_CONTEXT; + } + if (screen_win != NULL) { + screen_destroy_window(screen_win); + screen_win = NULL; + } + eglTerminate(egl_disp); + egl_disp = EGL_NO_DISPLAY; + } + eglReleaseThread(); +} + +void +bbutil_swap() { + int rc = eglSwapBuffers(egl_disp, egl_surf); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapBuffers"); + } +} + +void +bbutil_clear() { + glClear(GL_COLOR_BUFFER_BIT); +} + +char * +get_window_group_id() +{ + static char s_window_group_id[16] = ""; + + if (s_window_group_id[0] == '\0') { + snprintf(s_window_group_id, sizeof(s_window_group_id), "%d", getpid()); + } + + return s_window_group_id; +} + + +int bbutil_rotate_screen_surface(int angle) { + int rc, rotation, skip = 1, temp;; + EGLint interval = 1; + int size[2]; + + if ((angle != 0) && (angle != 90) && (angle != 180) && (angle != 270)) { + fprintf(stderr, "Invalid angle\n"); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &rotation); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + switch (angle - rotation) { + case -270: + case -90: + case 90: + case 270: + temp = size[0]; + size[0] = size[1]; + size[1] = temp; + skip = 0; + break; + } + + if (!skip) { + rc = eglMakeCurrent(egl_disp, NULL, NULL, NULL); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = eglDestroySurface(egl_disp, egl_surf); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); + if (egl_surf == EGL_NO_SURFACE) { + bbutil_egl_perror("eglCreateWindowSurface"); + return EXIT_FAILURE; + } + + rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = eglSwapInterval(egl_disp, interval); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapInterval"); + return EXIT_FAILURE; + } + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + diff --git a/platform/bb10/bbutil.h b/platform/bb10/bbutil.h new file mode 100644 index 000000000..8df513cb7 --- /dev/null +++ b/platform/bb10/bbutil.h @@ -0,0 +1,96 @@ +/*************************************************************************/ +/* bbutil.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef _UTILITY_H_INCLUDED +#define _UTILITY_H_INCLUDED + +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <screen/screen.h> +#include <sys/platform.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern EGLDisplay egl_disp; +extern EGLSurface egl_surf; + +enum RENDERING_API {GL_ES_1 = EGL_OPENGL_ES_BIT, GL_ES_2 = EGL_OPENGL_ES2_BIT, VG = EGL_OPENVG_BIT}; + +/** + * Initializes EGL, GL and loads a default font + * + * \param libscreen context that will be used for EGL setup + * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE + */ +int bbutil_init(screen_context_t ctx, enum RENDERING_API api); + +/** + * Initializes EGL + * + * \param libscreen context that will be used for EGL setup + * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE + */ +int bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api); + +/** + * Initializes GL 1.1 for simple 2D rendering. GL2 initialization will be added at a later point. + * + * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE + */ +int bbutil_init_gl2d(); + +int bbutil_is_flipped(); +int bbutil_get_rotation(); + +char *get_window_group_id(); + +int bbutil_rotate_screen_surface(int angle); + +/** + * Terminates EGL + */ +void bbutil_terminate(); + +/** + * Swaps default bbutil window surface to the screen + */ +void bbutil_swap(); + +/** + * Clears the screen of any existing text. + * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call + */ +void bbutil_clear(); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/platform/bb10/detect.py b/platform/bb10/detect.py new file mode 100644 index 000000000..22940c0f2 --- /dev/null +++ b/platform/bb10/detect.py @@ -0,0 +1,91 @@ +import os +import sys +import string +import methods + + +def is_active(): + return True + +def get_name(): + return "BlackBerry 10" + +def can_build(): + + import os + if (not os.environ.has_key("QNX_TARGET")): + return False + return True + +def get_opts(): + + return [ + ('QNX_HOST', 'path to qnx host', os.environ.get("QNX_HOST", 0)), + ('QNX_TARGET', 'path to qnx target', os.environ.get("QNX_TARGET", 0)), + ('QNX_CONFIGURATION', 'path to qnx configuration', os.environ.get("QNX_CONFIGURATION", 0)), + ('qnx_target', 'Qnx target (armle or x86', 'armle'), + ('bb10_payment_service', 'Enable Payment Service for BlackBerry10', 'yes'), + ('bb10_lgles_override', 'Force legacy GLES (1.1) on iOS', 'no'), + ('bb10_exceptions', 'Use exceptions when compiling on bb10', 'no'), + ] + +def get_flags(): + + return [ + ('lua', 'no'), + ('tools', 'no'), + ('nedmalloc', 'no'), + ] + +def configure(env): + + if env['PLATFORM'] == 'win32': + env.Tool('mingw') + env['SPAWN'] = methods.win32_spawn + + env['qnx_target_ver'] = env['qnx_target'] + if env['qnx_target'] == "armle": + env['qnx_prefix'] = 'ntoarmv7' + env['qnx_target_ver'] = 'armle-v7' + else: + env['qnx_prefix'] = 'ntox86' + + env['OBJSUFFIX'] = ".qnx.${qnx_target}.o" + env['LIBSUFFIX'] = ".qnx.${qnx_target}.a" + env['PROGSUFFIX'] = ".qnx.${qnx_target}" + print("PROGSUFFIX: "+env['PROGSUFFIX']+" target: "+env['qnx_target']) + + env.PrependENVPath('PATH', env['QNX_CONFIGURATION'] + '/bin') + env.PrependENVPath('PATH', env['QNX_CONFIGURATION'] + '/usr/bin') + env['ENV']['QNX_HOST'] = env['QNX_HOST'] + env['ENV']['QNX_TARGET'] = env['QNX_TARGET'] + env['ENV']['QNX_CONFIGURATION'] = env['QNX_CONFIGURATION'] + + env['CC'] = '$qnx_prefix-gcc' + env['CXX'] = '$qnx_prefix-g++' + env['AR'] = '$qnx_prefix-ar' + env['RANLIB'] = '$qnx_prefix-ranlib' + + env.Append(CPPPATH = ['#platform/bb10']) + env.Append(LIBPATH = ['#platform/bb10/lib/$qnx_target', '#platform/bb10/lib/$qnx_target_ver']) + env.Append(CCFLAGS = string.split('-DBB10_ENABLED -DUNIX_ENABLED -DGLES2_ENABLED -DGLES1_ENABLED -D_LITTLE_ENDIAN -DNO_THREADS -DNO_FCNTL')) + if env['bb10_exceptions']=="yes": + env.Append(CCFLAGS = ['-fexceptions']) + else: + env.Append(CCFLAGS = ['-fno-exceptions']) + + #env.Append(LINKFLAGS = string.split() + + if (env["target"]=="release"): + + env.Append(CCFLAGS=['-O3','-DRELEASE_BUILD']) + env['OBJSUFFIX'] = "_opt"+env['OBJSUFFIX'] + env['LIBSUFFIX'] = "_opt"+env['LIBSUFFIX'] + + elif (env["target"]=="debug"): + + env.Append(CCFLAGS=['-g', '-O0','-DDEBUG_ENABLED', '-D_DEBUG']) + env.Append(LINKFLAGS=['-g']) + + env.Append(LIBS=['bps', 'pps', 'screen', 'socket', 'EGL', 'GLESv2', 'GLESv1_CM', 'm', 'asound']) + diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp new file mode 100644 index 000000000..0a19e71f0 --- /dev/null +++ b/platform/bb10/export/export.cpp @@ -0,0 +1,805 @@ +#include "version.h" +#include "export.h" +#include "tools/editor/editor_settings.h" +#include "tools/editor/editor_import_export.h" +#include "tools/editor/editor_node.h" +#include "io/zip_io.h" +#include "io/marshalls.h" +#include "globals.h" +#include "os/file_access.h" +#include "os/os.h" +#include "platform/bb10/logo.h" +#include "io/xml_parser.h" + +#define MAX_DEVICES 5 + +class EditorExportPlatformBB10 : public EditorExportPlatform { + + OBJ_TYPE( EditorExportPlatformBB10,EditorExportPlatform ); + + String custom_package; + + int version_code; + String version_name; + String package; + String name; + String category; + String description; + String author_name; + String author_id; + String icon; + + + + struct Device { + + int index; + String name; + String description; + }; + + Vector<Device> devices; + bool devices_changed; + Mutex *device_lock; + Thread *device_thread; + Ref<ImageTexture> logo; + + volatile bool quit_request; + + + static void _device_poll_thread(void *ud); + + void _fix_descriptor(Vector<uint8_t>& p_manifest); +protected: + + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List<PropertyInfo> *p_list) const; + +public: + + virtual String get_name() const { return "BlackBerry 10"; } + virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_ETC1; } + virtual Ref<Texture> get_logo() const { return logo; } + + + virtual bool poll_devices(); + virtual int get_device_count() const; + virtual String get_device_name(int p_device) const; + virtual String get_device_info(int p_device) const; + virtual Error run(int p_device); + + virtual bool requieres_password(bool p_debug) const { return !p_debug; } + virtual String get_binary_extension() const { return "bar"; } + virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + + virtual bool can_export(String *r_error=NULL) const; + + EditorExportPlatformBB10(); + ~EditorExportPlatformBB10(); +}; + +bool EditorExportPlatformBB10::_set(const StringName& p_name, const Variant& p_value) { + + String n=p_name; + + if (n=="version/code") + version_code=p_value; + else if (n=="version/name") + version_name=p_value; + else if (n=="package/unique_name") + package=p_value; + else if (n=="package/category") + category=p_value; + else if (n=="package/name") + name=p_value; + else if (n=="package/description") + description=p_value; + else if (n=="package/icon") + icon=p_value; + else if (n=="package/custom_template") + custom_package=p_value; + else if (n=="release/author") + author_name=p_value; + else if (n=="release/author_id") + author_id=p_value; + else + return false; + + return true; +} + +bool EditorExportPlatformBB10::_get(const StringName& p_name,Variant &r_ret) const{ + + String n=p_name; + + if (n=="version/code") + r_ret=version_code; + else if (n=="version/name") + r_ret=version_name; + else if (n=="package/unique_name") + r_ret=package; + else if (n=="package/category") + r_ret=category; + else if (n=="package/name") + r_ret=name; + else if (n=="package/description") + r_ret=description; + else if (n=="package/icon") + r_ret=icon; + else if (n=="package/custom_template") + r_ret=custom_package; + else if (n=="release/author") + r_ret=author_name; + else if (n=="release/author_id") + r_ret=author_id; + else + return false; + + return true; +} +void EditorExportPlatformBB10::_get_property_list( List<PropertyInfo> *p_list) const{ + + p_list->push_back( PropertyInfo( Variant::INT, "version/code", PROPERTY_HINT_RANGE,"1,65535,1")); + p_list->push_back( PropertyInfo( Variant::STRING, "version/name") ); + p_list->push_back( PropertyInfo( Variant::STRING, "package/unique_name") ); + p_list->push_back( PropertyInfo( Variant::STRING, "package/category") ); + p_list->push_back( PropertyInfo( Variant::STRING, "package/name") ); + p_list->push_back( PropertyInfo( Variant::STRING, "package/description",PROPERTY_HINT_MULTILINE_TEXT) ); + p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") ); + p_list->push_back( PropertyInfo( Variant::STRING, "package/custom_template", PROPERTY_HINT_FILE,"zip")); + p_list->push_back( PropertyInfo( Variant::STRING, "release/author") ); + p_list->push_back( PropertyInfo( Variant::STRING, "release/author_id") ); + + //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)")); + +} + +void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) { + + String fpath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp_bar-settings.xml"); + { + FileAccessRef f = FileAccess::open(fpath,FileAccess::WRITE); + f->store_buffer(p_descriptor.ptr(),p_descriptor.size()); + } + + Ref<XMLParser> parser = memnew( XMLParser ); + Error err = parser->open(fpath); + ERR_FAIL_COND(err!=OK); + + String txt; + err = parser->read(); + Vector<String> depth; + + while(err!=ERR_FILE_EOF) { + + ERR_FAIL_COND(err!=OK); + + switch(parser->get_node_type()) { + + case XMLParser::NODE_NONE: { + print_line("???"); + } break; + case XMLParser::NODE_ELEMENT: { + String e="<"; + e+=parser->get_node_name(); + for(int i=0;i<parser->get_attribute_count();i++) { + e+=" "; + e+=parser->get_attribute_name(i)+"=\""; + e+=parser->get_attribute_value(i)+"\" "; + } + + + + if (parser->is_empty()) { + e+="/"; + } else { + depth.push_back(parser->get_node_name()); + } + + e+=">"; + txt+=e; + + } break; + case XMLParser::NODE_ELEMENT_END: { + + txt+="</"+parser->get_node_name()+">"; + if (depth.size() && depth[depth.size()-1]==parser->get_node_name()) { + depth.resize(depth.size()-1); + } + + + } break; + case XMLParser::NODE_TEXT: { + if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="id") { + + txt+=package; + } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="name") { + + String aname; + if (this->name!="") { + aname=this->name; + } else { + aname = Globals::get_singleton()->get("application/name"); + + } + + if (aname=="") { + aname=_MKSTR(VERSION_NAME); + } + + txt+=aname; + + } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="versionNumber") { + txt+=itos(version_code); + } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="description") { + txt+=description; + } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="author") { + txt+=author_name; + } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="authorId") { + txt+=author_id; + } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="category") { + txt+=category; + } else { + txt+=parser->get_node_data(); + } + } break; + case XMLParser::NODE_COMMENT: { + txt+="<!--"+parser->get_node_name()+"-->"; + } break; + case XMLParser::NODE_CDATA: { + //ignore + //print_line("cdata"); + } break; + case XMLParser::NODE_UNKNOWN: { + //ignore + txt+="<"+parser->get_node_name()+">"; + } break; + } + + err = parser->read(); + } + + + CharString cs = txt.utf8(); + p_descriptor.resize(cs.length()); + for(int i=0;i<cs.length();i++) + p_descriptor[i]=cs[i]; + +} + + + +Error EditorExportPlatformBB10::export_project(const String& p_path,bool p_debug,const String& p_password) { + + + EditorProgress ep("export","Exporting for BlackBerry 10",104); + + String template_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/"; + + String src_template=custom_package!=""?custom_package:template_path.plus_file("bb10.zip"); + + + FileAccess *src_f=NULL; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + + ep.step("Creating FileSystem for BAR",0); + + unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io); + if (!pkg) { + + EditorNode::add_io_error("Could not find template zip to export:\n"+src_template); + return ERR_FILE_NOT_FOUND; + } + + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->change_dir(EditorSettings::get_singleton()->get_settings_path()); + + + if (da->change_dir("tmp")!=OK) { + da->make_dir("tmp"); + if (da->change_dir("tmp")!=OK) + return ERR_CANT_CREATE; + } + + if (da->change_dir("bb10_export")!=OK) { + da->make_dir("bb10_export"); + if (da->change_dir("bb10_export")!=OK) { + return ERR_CANT_CREATE; + } + } + + + String bar_dir = da->get_current_dir(); + if (bar_dir.ends_with("/")) { + bar_dir=bar_dir.substr(0,bar_dir.length()-1); + } + + //THIS IS SUPER, SUPER DANGEROUS!!!! + //CAREFUL WITH THIS CODE, MIGHT DELETE USERS HARD DRIVE OR HOME DIR + //EXTRA CHECKS ARE IN PLACE EVERYWERE TO MAKE SURE NOTHING BAD HAPPENS BUT STILL.... + //BE SUPER CAREFUL WITH THIS PLEASE!!! + //BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!! + + if (bar_dir.ends_with("bb10_export")) { + Error err = da->erase_contents_recursive(); + if (err!=OK) { + EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir); + ERR_FAIL_COND_V(err!=OK,err); + } + + } else { + print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!"); + ERR_FAIL_V(ERR_OMFG_THIS_IS_VERY_VERY_BAD); + } + + + ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); + int ret = unzGoToFirstFile(pkg); + + + + while(ret==UNZ_OK) { + + //get filename + unz_file_info info; + char fname[16384]; + ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); + + String file=fname; + + Vector<uint8_t> data; + data.resize(info.uncompressed_size); + + //read + unzOpenCurrentFile(pkg); + unzReadCurrentFile(pkg,data.ptr(),data.size()); + unzCloseCurrentFile(pkg); + + //write + + if (file=="bar-descriptor.xml") { + + _fix_descriptor(data); + } + + if (file=="icon.png") { + bool found=false; + + if (this->icon!="" && this->icon.ends_with(".png")) { + + FileAccess *f = FileAccess::open(this->icon,FileAccess::READ); + if (f) { + + data.resize(f->get_len()); + f->get_buffer(data.ptr(),data.size()); + memdelete(f); + found=true; + } + + } + + if (!found) { + + String appicon = Globals::get_singleton()->get("application/icon"); + if (appicon!="" && appicon.ends_with(".png")) { + FileAccess*f = FileAccess::open(appicon,FileAccess::READ); + if (f) { + data.resize(f->get_len()); + f->get_buffer(data.ptr(),data.size()); + memdelete(f); + } + } + } + } + + + if (file.find("/")) { + + da->make_dir_recursive(file.get_base_dir()); + } + + FileAccessRef wf = FileAccess::open(bar_dir.plus_file(file),FileAccess::WRITE); + wf->store_buffer(data.ptr(),data.size()); + + ret = unzGoToNextFile(pkg); + } + + ep.step("Finding Files..",1); + + Vector<StringName> files=get_dependencies(false); + + ep.step("Adding Files..",2); + + da->change_dir(bar_dir); + da->make_dir("assets"); + Error err = da->change_dir("assets"); + ERR_FAIL_COND_V(err,err); + + String asset_dir=da->get_current_dir(); + if (!asset_dir.ends_with("/")) + asset_dir+="/"; + + for(int i=0;i<files.size();i++) { + + String fname=files[i]; + Vector<uint8_t> data = get_exported_file(fname); + /* + FileAccess *f=FileAccess::open(files[i],FileAccess::READ); + if (!f) { + EditorNode::add_io_error("Couldn't read: "+String(files[i])); + } + ERR_CONTINUE(!f); + data.resize(f->get_len()); + f->get_buffer(data.ptr(),data.size()); +*/ + String dst_path=fname; + dst_path=dst_path.replace_first("res://",asset_dir); + + da->make_dir_recursive(dst_path.get_base_dir()); + + ep.step("Adding File: "+String(files[i]).get_file(),3+i*100/files.size()); + + FileAccessRef fr = FileAccess::open(dst_path,FileAccess::WRITE); + fr->store_buffer(data.ptr(),data.size()); + } + + + ep.step("Creating BAR Package..",104); + + String bb_packager=EditorSettings::get_singleton()->get("blackberry/host_tools"); + bb_packager=bb_packager.plus_file("blackberry-nativepackager"); + if (OS::get_singleton()->get_name()=="Windows") + bb_packager+=".exe"; + + + if (!FileAccess::exists(bb_packager)) { + EditorNode::add_io_error("Can't find packager:\n"+bb_packager); + return ERR_CANT_OPEN; + } + + List<String> args; + args.push_back("-package"); + args.push_back(p_path); + if (p_debug) { + + String debug_token=EditorSettings::get_singleton()->get("blackberry/debug_token"); + if (!FileAccess::exists(debug_token)) { + EditorNode::add_io_error("Debug token not found!"); + } else { + args.push_back("-debugToken"); + args.push_back(debug_token); + } + args.push_back("-devMode"); + args.push_back("-configuration"); + args.push_back("Device-Debug"); + } else { + + args.push_back("-configuration"); + args.push_back("Device-Release"); + } + args.push_back(bar_dir.plus_file("bar-descriptor.xml")); + + int ec; + + err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec); + + if (err!=OK) + return err; + if (ec!=0) + return ERR_CANT_CREATE; + + return OK; + +} + + +bool EditorExportPlatformBB10::poll_devices() { + + bool dc=devices_changed; + devices_changed=false; + return dc; +} + +int EditorExportPlatformBB10::get_device_count() const { + + device_lock->lock(); + int dc=devices.size(); + device_lock->unlock(); + + return dc; + +} +String EditorExportPlatformBB10::get_device_name(int p_device) const { + + ERR_FAIL_INDEX_V(p_device,devices.size(),""); + device_lock->lock(); + String s=devices[p_device].name; + device_lock->unlock(); + return s; +} +String EditorExportPlatformBB10::get_device_info(int p_device) const { + + ERR_FAIL_INDEX_V(p_device,devices.size(),""); + device_lock->lock(); + String s=devices[p_device].description; + device_lock->unlock(); + return s; +} + +void EditorExportPlatformBB10::_device_poll_thread(void *ud) { + + EditorExportPlatformBB10 *ea=(EditorExportPlatformBB10 *)ud; + + while(!ea->quit_request) { + + String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools"); + bb_deploy=bb_deploy.plus_file("blackberry-deploy"); + bool windows = OS::get_singleton()->get_name()=="Windows"; + if (windows) + bb_deploy+=".exe"; + + if (!FileAccess::exists(bb_deploy)) { + OS::get_singleton()->delay_usec(3000000); + continue; //adb not configured + } + + Vector<Device> devices; + + + for (int i=0;i<MAX_DEVICES;i++) { + + String host = EditorSettings::get_singleton()->get("blackberry/device_"+itos(i+1)+"/host"); + if (host==String()) + continue; + String pass = EditorSettings::get_singleton()->get("blackberry/device_"+itos(i+1)+"/password"); + if (pass==String()) + continue; + + List<String> args; + args.push_back("-listDeviceInfo"); + args.push_back(host); + args.push_back("-password"); + args.push_back(pass); + + + int ec; + String dp; + + Error err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,&dp,&ec); + + if (err==OK && ec==0) { + + Device dev; + dev.index=i; + String descr; + Vector<String> ls=dp.split("\n"); + + for(int i=0;i<ls.size();i++) { + + String l = ls[i].strip_edges(); + if (l.begins_with("modelfullname::")) { + dev.name=l.get_slice("::",1); + descr+="Model: "+dev.name+"\n"; + } + if (l.begins_with("modelnumber::")) { + String s = l.get_slice("::",1); + dev.name+=" ("+s+")"; + descr+="Model Number: "+s+"\n"; + } + if (l.begins_with("scmbundle::")) + descr+="OS Version: "+l.get_slice("::",1)+"\n"; + if (l.begins_with("[n]debug_token_expiration::")) + descr+="Debug Token Expires:: "+l.get_slice("::",1)+"\n"; + + } + + dev.description=descr; + devices.push_back(dev); + } + + } + + bool changed=false; + + + ea->device_lock->lock(); + + if (ea->devices.size()!=devices.size()) { + changed=true; + } else { + + for(int i=0;i<ea->devices.size();i++) { + + if (ea->devices[i].index!=devices[i].index) { + changed=true; + break; + } + } + } + + if (changed) { + + ea->devices=devices; + ea->devices_changed=true; + } + + ea->device_lock->unlock(); + + OS::get_singleton()->delay_usec(3000000); + + } + +} + +Error EditorExportPlatformBB10::run(int p_device) { + + ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER); + + String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools"); + bb_deploy=bb_deploy.plus_file("blackberry-deploy"); + if (OS::get_singleton()->get_name()=="Windows") + bb_deploy+=".exe"; + + if (!FileAccess::exists(bb_deploy)) { + EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy); + return ERR_FILE_NOT_FOUND; + } + + + device_lock->lock(); + + + EditorProgress ep("run","Running on "+devices[p_device].name,3); + + //export_temp + ep.step("Exporting APK",0); + + String export_to=EditorSettings::get_singleton()->get_settings_path().plus_file("/tmp/tmpexport.bar"); + Error err = export_project(export_to,true); + if (err) { + device_lock->unlock(); + return err; + } +#if 0 + ep.step("Uninstalling..",1); + + print_line("Uninstalling previous version: "+devices[p_device].name); + List<String> args; + args.push_back("-s"); + args.push_back(devices[p_device].id); + args.push_back("uninstall"); + args.push_back(package); + int rv; + err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv); + + if (err || rv!=0) { + EditorNode::add_io_error("Could not install to device."); + device_lock->unlock(); + return ERR_CANT_CREATE; + } + + print_line("Installing into device (please wait..): "+devices[p_device].name); + +#endif + ep.step("Installing to Device (please wait..)..",2); + + List<String> args; + args.clear(); + args.push_back("-installApp"); + args.push_back("-launchApp"); + args.push_back("-device"); + int idx = devices[p_device].index; + String host = EditorSettings::get_singleton()->get("blackberry/device_"+itos(p_device+1)+"/host"); + String pass = EditorSettings::get_singleton()->get("blackberry/device_"+itos(p_device+1)+"/password"); + args.push_back(host); + args.push_back("-password"); + args.push_back(pass); + args.push_back(export_to); + + int rv; + err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,NULL,&rv); + if (err || rv!=0) { + EditorNode::add_io_error("Could not install to device."); + device_lock->unlock(); + return ERR_CANT_CREATE; + } + + device_lock->unlock(); + return OK; + + +} + + +EditorExportPlatformBB10::EditorExportPlatformBB10() { + + version_code=1; + version_name="1.0"; + package="com.godot.noname"; + category="core.games"; + name=""; + author_name="Cert. Name"; + author_id="Cert. ID"; + description="Game made with Godot Engine"; + + device_lock = Mutex::create(); + quit_request=false; + + device_thread=Thread::create(_device_poll_thread,this); + devices_changed=true; + + Image img( _bb10_logo ); + logo = Ref<ImageTexture>( memnew( ImageTexture )); + logo->create_from_image(img); +} + +bool EditorExportPlatformBB10::can_export(String *r_error) const { + + bool valid=true; + String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools"); + String err; + + if (!FileAccess::exists(bb_deploy.plus_file("blackberry-deploy"))) { + + valid=false; + err+="Blackberry host tools not configured in editor settings.\n"; + } + + String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/"; + + if (!FileAccess::exists(exe_path+"bb10.zip")) { + valid=false; + err+="No export template found.\nDownload and install export templates.\n"; + } + + String debug_token=EditorSettings::get_singleton()->get("blackberry/debug_token"); + + if (!FileAccess::exists(debug_token)) { + valid=false; + err+="No debug token set, will not be able to test on device.\n"; + } + + + if (custom_package!="" && !FileAccess::exists(custom_package)) { + valid=false; + err+="Custom release package not found.\n"; + } + + if (r_error) + *r_error=err; + + return valid; +} + + +EditorExportPlatformBB10::~EditorExportPlatformBB10() { + + quit_request=true; + Thread::wait_to_finish(device_thread); +} + + +void register_bb10_exporter() { + + EDITOR_DEF("blackberry/host_tools",""); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"blackberry/host_tools",PROPERTY_HINT_GLOBAL_DIR)); + EDITOR_DEF("blackberry/debug_token",""); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"blackberry/debug_token",PROPERTY_HINT_GLOBAL_FILE,"bar")); + EDITOR_DEF("blackberry/device_1/host",""); + EDITOR_DEF("blackberry/device_1/password",""); + EDITOR_DEF("blackberry/device_2/host",""); + EDITOR_DEF("blackberry/device_2/password",""); + EDITOR_DEF("blackberry/device_3/host",""); + EDITOR_DEF("blackberry/device_3/password",""); + EDITOR_DEF("blackberry/device_4/host",""); + EDITOR_DEF("blackberry/device_4/password",""); + EDITOR_DEF("blackberry/device_5/host",""); + EDITOR_DEF("blackberry/device_5/password",""); + + Ref<EditorExportPlatformBB10> exporter = Ref<EditorExportPlatformBB10>( memnew(EditorExportPlatformBB10) ); + EditorImportExport::get_singleton()->add_export_platform(exporter); + + +} + diff --git a/platform/bb10/export/export.h b/platform/bb10/export/export.h new file mode 100644 index 000000000..06c7a681b --- /dev/null +++ b/platform/bb10/export/export.h @@ -0,0 +1,3 @@ + + +void register_bb10_exporter(); diff --git a/platform/bb10/godot_bb10.cpp b/platform/bb10/godot_bb10.cpp new file mode 100644 index 000000000..f7e154d64 --- /dev/null +++ b/platform/bb10/godot_bb10.cpp @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* godot_bb10.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "main/main.h" +#include "os_bb10.h" + +#include <unistd.h> + +int main(int argc, char* argv[]) { + + OSBB10 os; + + Error err = Main::setup(argv[0],argc-1,&argv[1]); + if (err!=OK) + return 255; + + if (Main::start()) + os.run(); // it is actually the OS that decides how to run + Main::cleanup(); + + return os.get_exit_code(); +} + diff --git a/platform/bb10/logo.png b/platform/bb10/logo.png Binary files differnew file mode 100644 index 000000000..d0fb1966a --- /dev/null +++ b/platform/bb10/logo.png diff --git a/platform/bb10/os_bb10.cpp b/platform/bb10/os_bb10.cpp new file mode 100644 index 000000000..ff43a68b1 --- /dev/null +++ b/platform/bb10/os_bb10.cpp @@ -0,0 +1,630 @@ +/*************************************************************************/ +/* os_bb10.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "os_bb10.h" + +#include "drivers/gles2/rasterizer_gles2.h" +#include "drivers/gles1/rasterizer_gles1.h" +#include "servers/visual/visual_server_raster.h" +#include "core/os/dir_access.h" + +#include "core/globals.h" +#include "main/main.h" +#include "bbutil.h" +#include <stdlib.h> +#include <stdbool.h> +#include <assert.h> +#include "core/os/keyboard.h" + +#include "bps/bps.h" +#include "bps/screen.h" +#include "bps/navigator.h" +#include "bps/accelerometer.h" +#include "bps/orientation.h" +#include "bps/virtualkeyboard.h" +#include "bps/audiodevice.h" + +#ifdef BB10_SCORELOOP_ENABLED +#include "modules/scoreloop/scoreloop_bb10.h" +#endif + +static char launch_dir[512]; +char* launch_dir_ptr; + +int OSBB10::get_video_driver_count() const { + + return 1; +} +const char * OSBB10::get_video_driver_name(int p_driver) const { + + return "GLES2"; +} + +OS::VideoMode OSBB10::get_default_video_mode() const { + + return OS::VideoMode(); +} + +int OSBB10::get_audio_driver_count() const { + + return 1; +} +const char * OSBB10::get_audio_driver_name(int p_driver) const { + + return "BB10"; +} + +void OSBB10::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { + + data_dir = getenv("HOME"); + + //Create a screen context that will be used to create an EGL surface to to receive libscreen events + screen_create_context(&screen_cxt,0); + + //Initialize BPS library + bps_initialize(); + + //Use utility code to initialize EGL for 2D rendering with GL ES 1.1 + enum RENDERING_API api = GL_ES_2; + #ifdef BB10_LGLES_OVERRIDE + api = GL_ES_1; + #endif + if (EXIT_SUCCESS != bbutil_init(screen_cxt, api)) { + bbutil_terminate(); + screen_destroy_context(screen_cxt); + return; + }; + + EGLint surface_width, surface_height; + + eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); + eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); + printf("screen size: %ix%i\n", surface_width, surface_height); + VideoMode mode; + mode.width = surface_width; + mode.height = surface_height; + mode.fullscreen = true; + mode.resizable = false; + set_video_mode(mode); + + //Signal BPS library that navigator and screen events will be requested + screen_request_events(screen_cxt); + navigator_request_events(0); + virtualkeyboard_request_events(0); + audiodevice_request_events(0); + + #ifdef DEBUG_ENABLED + bps_set_verbosity(3); + #endif + + accel_supported = accelerometer_is_supported(); + if (accel_supported) + accelerometer_set_update_frequency(FREQ_40_HZ); + pitch = 0; + roll = 0; + + #ifdef BB10_LGLES_OVERRIDE + rasterizer = memnew( RasterizerGLES1(false) ); + #else + rasterizer = memnew( RasterizerGLES2(false, false) ); + #endif + + visual_server = memnew( VisualServerRaster(rasterizer) ); + visual_server->init(); + visual_server->cursor_set_visible(false, 0); + + audio_driver = memnew(AudioDriverBB10); + audio_driver->set_singleton(); + audio_driver->init(NULL); + + sample_manager = memnew( SampleManagerMallocSW ); + audio_server = memnew( AudioServerSW(sample_manager) ); + audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,false); + audio_server->init(); + + spatial_sound_server = memnew( SpatialSoundServerSW ); + spatial_sound_server->init(); + + spatial_sound_2d_server = memnew( SpatialSound2DServerSW ); + spatial_sound_2d_server->init(); + + // + physics_server = memnew( PhysicsServerSW ); + physics_server->init(); + physics_2d_server = memnew( Physics2DServerSW ); + physics_2d_server->init(); + + input = memnew( InputDefault ); + + #ifdef PAYMENT_SERVICE_ENABLED + payment_service = memnew(PaymentService); + Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", payment_service)); + #endif + +} + +void OSBB10::set_main_loop( MainLoop * p_main_loop ) { + + input->set_main_loop(p_main_loop); + main_loop=p_main_loop; +} + +void OSBB10::delete_main_loop() { + + memdelete( main_loop ); + main_loop = NULL; +} + +void OSBB10::finalize() { + + if(main_loop) + memdelete(main_loop); + main_loop=NULL; + + spatial_sound_server->finish(); + memdelete(spatial_sound_server); + spatial_sound_2d_server->finish(); + memdelete(spatial_sound_2d_server); + + //if (debugger_connection_console) { +// memdelete(debugger_connection_console); +//} + + audio_server->finish(); + memdelete(audio_server); + memdelete(sample_manager); + + visual_server->finish(); + memdelete(visual_server); + memdelete(rasterizer); + + physics_server->finish(); + memdelete(physics_server); + + physics_2d_server->finish(); + memdelete(physics_2d_server); + + #ifdef PAYMENT_SERVICE_ENABLED + memdelete(payment_service); + #endif + + memdelete(input); + + bbutil_terminate(); + screen_destroy_context(screen_cxt); + + bps_shutdown(); +} + +void OSBB10::set_mouse_show(bool p_show) { + + //android has no mouse... +} + +void OSBB10::set_mouse_grab(bool p_grab) { + + //it really has no mouse...! +} + +bool OSBB10::is_mouse_grab_enabled() const { + + //*sigh* technology has evolved so much since i was a kid.. + return false; +} +Point2 OSBB10::get_mouse_pos() const { + + return Point2(); +} +int OSBB10::get_mouse_button_state() const { + + return 0; +} +void OSBB10::set_window_title(const String& p_title) { + + +} + +//interesting byt not yet +//void set_clipboard(const String& p_text); +//String get_clipboard() const; + +void OSBB10::set_video_mode(const VideoMode& p_video_mode,int p_screen) { + + default_videomode = p_video_mode; +} + +OS::VideoMode OSBB10::get_video_mode(int p_screen) const { + + return default_videomode; +} +void OSBB10::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const { + + p_list->push_back(default_videomode); +} + +String OSBB10::get_name() { + + return "BlackBerry 10"; +} + +MainLoop *OSBB10::get_main_loop() const { + + return main_loop; +} + +bool OSBB10::can_draw() const { + + return !minimized; +} + +void OSBB10::set_cursor_shape(CursorShape p_shape) { + + //android really really really has no mouse.. how amazing.. +} + +void OSBB10::handle_screen_event(bps_event_t *event) { + + screen_event_t screen_event = screen_event_get_event(event); + + int screen_val; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val); + + int pos[2]; + + switch (screen_val) { + case SCREEN_EVENT_MTOUCH_TOUCH: + case SCREEN_EVENT_MTOUCH_RELEASE: { + + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos); + + InputEvent ievent; + ievent.type = InputEvent::SCREEN_TOUCH; + ievent.ID = ++last_id; + ievent.device = 0; + ievent.screen_touch.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH); + ievent.screen_touch.x = pos[0]; + ievent.screen_touch.y = pos[1]; + Point2 mpos(ievent.screen_touch.x, ievent.screen_touch.y); + + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]); + ievent.screen_touch.index = pos[0]; + + last_touch_x[pos[0]] = ievent.screen_touch.x; + last_touch_y[pos[0]] = ievent.screen_touch.y; + + input->parse_input_event( ievent ); + + if (ievent.screen_touch.index == 0) { + + InputEvent ievent; + ievent.type = InputEvent::MOUSE_BUTTON; + ievent.ID = ++last_id; + ievent.device = 0; + ievent.mouse_button.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH); + ievent.mouse_button.button_index = BUTTON_LEFT; + ievent.mouse_button.doubleclick = 0; + ievent.mouse_button.x = ievent.mouse_button.global_x = mpos.x; + ievent.mouse_button.y = ievent.mouse_button.global_y = mpos.y; + input->parse_input_event( ievent ); + }; + + + } break; + case SCREEN_EVENT_MTOUCH_MOVE: { + + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos); + + InputEvent ievent; + ievent.type = InputEvent::SCREEN_DRAG; + ievent.ID = ++last_id; + ievent.device = 0; + ievent.screen_drag.x = pos[0]; + ievent.screen_drag.y = pos[1]; + + /* + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pos); + ievent.screen_drag.relative_x = ievent.screen_drag.x - pos[0]; + ievent.screen_drag.relative_y = ievent.screen_drag.y - pos[1]; + */ + + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]); + ievent.screen_drag.index = pos[0]; + + + ievent.screen_drag.relative_x = ievent.screen_drag.x - last_touch_x[ievent.screen_drag.index]; + ievent.screen_drag.relative_y = ievent.screen_drag.y - last_touch_y[ievent.screen_drag.index]; + + last_touch_x[ievent.screen_drag.index] = ievent.screen_drag.x; + last_touch_y[ievent.screen_drag.index] = ievent.screen_drag.y; + + Point2 mpos(ievent.screen_drag.x, ievent.screen_drag.y); + Point2 mrel(ievent.screen_drag.relative_x, ievent.screen_drag.relative_y); + + input->parse_input_event( ievent ); + + if (ievent.screen_touch.index == 0) { + + InputEvent ievent; + ievent.type = InputEvent::MOUSE_MOTION; + ievent.ID = ++last_id; + ievent.device = 0; + ievent.mouse_motion.x = ievent.mouse_motion.global_x = mpos.x; + ievent.mouse_motion.y = ievent.mouse_motion.global_y = mpos.y; + input->set_mouse_pos(Point2(ievent.mouse_motion.x,ievent.mouse_motion.y)); + ievent.mouse_motion.speed_x=input->get_mouse_speed().x; + ievent.mouse_motion.speed_y=input->get_mouse_speed().y; + ievent.mouse_motion.relative_x = mrel.x; + ievent.mouse_motion.relative_y = mrel.y; + ievent.mouse_motion.button_mask = 1; // pressed + + input->parse_input_event( ievent ); + }; + } break; + + case SCREEN_EVENT_KEYBOARD: { + + InputEvent ievent; + ievent.type = InputEvent::KEY; + ievent.ID = ++last_id; + ievent.device = 0; + int val = 0; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SCAN, &val); + ievent.key.scancode = val; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &val); + ievent.key.unicode = val; + if (val == 61448) { + ievent.key.scancode = KEY_BACKSPACE; + ievent.key.unicode = KEY_BACKSPACE; + }; + if (val == 61453) { + ievent.key.scancode = KEY_ENTER; + ievent.key.unicode = KEY_ENTER; + }; + + int flags; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags); + ievent.key.pressed = flags & 1; // bit 1 is pressed apparently + + int mod; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_MODIFIERS, &mod); + + input->parse_input_event( ievent ); + } break; + + default: + break; + + } +}; + +void OSBB10::handle_accelerometer() { + + if (!accel_supported) + return; + + if (!fullscreen) + return; + + double force_x, force_y, force_z; + accelerometer_read_forces(&force_x, &force_y, &force_z); + Vector3 accel = Vector3(force_x, flip_accelerometer ? force_y : -force_y, force_z); + input->set_accelerometer(accel); + // rotate 90 degrees + //input->set_accelerometer(Vector3(force_y, flip_accelerometer?force_x:(-force_x), force_z)); +}; + + +void OSBB10::_resize(bps_event_t* event) { + + int angle = navigator_event_get_orientation_angle(event); + bbutil_rotate_screen_surface(angle); + + EGLint surface_width, surface_height; + eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); + eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); + + VideoMode mode; + mode.width = surface_width; + mode.height = surface_height; + mode.fullscreen = true; + mode.resizable = false; + set_video_mode(mode); +}; + +void OSBB10::process_events() { + + handle_accelerometer(); + + bps_event_t *event = NULL; + + do { + int rc = bps_get_event(&event, 0); + assert(rc == BPS_SUCCESS); + + if (!event) break; + + #ifdef BB10_SCORELOOP_ENABLED + ScoreloopBB10* sc = Globals::get_singleton()->get_singleton_object("Scoreloop")->cast_to<ScoreloopBB10>(); + if (sc->handle_event(event)) + continue; + #endif + + #ifdef PAYMENT_SERVICE_ENABLED + if (payment_service->handle_event(event)) + continue; + #endif + + int domain = bps_event_get_domain(event); + if (domain == screen_get_domain()) { + + handle_screen_event(event); + + } else if (domain == navigator_get_domain()) { + + if (NAVIGATOR_EXIT == bps_event_get_code(event)) { + if (main_loop) + main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); + bps_event_destroy(event); + exit(0); + return; + /* + } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION_CHECK) { + + int angle = navigator_event_get_orientation_angle(event); + navigator_orientation_check_response(event, false); + + } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION) { + + _resize(event); + */ + } else if (bps_event_get_code(event) == NAVIGATOR_WINDOW_STATE) { + + int state = navigator_event_get_window_state(event); + bool was_fullscreen = fullscreen; + minimized = state == NAVIGATOR_WINDOW_INVISIBLE; + fullscreen = state == NAVIGATOR_WINDOW_FULLSCREEN; + set_low_processor_usage_mode(!fullscreen); + if (fullscreen != was_fullscreen) { + if (fullscreen) { + audio_server->set_fx_global_volume_scale(fullscreen_mixer_volume); + audio_server->set_stream_global_volume_scale(fullscreen_stream_volume); + } else { + fullscreen_mixer_volume = audio_server->get_fx_global_volume_scale(); + fullscreen_stream_volume = audio_server->get_stream_global_volume_scale(); + audio_server->set_fx_global_volume_scale(0); + audio_server->set_stream_global_volume_scale(0); + }; + }; + }; + } else if (domain == audiodevice_get_domain()) { + + const char * audiodevice_path = audiodevice_event_get_path(event); + printf("************* got audiodevice event, path %s\n", audiodevice_path); + audio_driver->finish(); + audio_driver->init(audiodevice_path); + audio_driver->start(); + }; + + //bps_event_destroy(event); + } while (event); +}; + +bool OSBB10::has_virtual_keyboard() const { + + return true; +}; + +void OSBB10::show_virtual_keyboard(const String& p_existing_text,const Rect2& p_screen_rect) { + + virtualkeyboard_show(); +}; + +void OSBB10::hide_virtual_keyboard() { + + virtualkeyboard_hide(); +}; + +void OSBB10::run() { + + if (!main_loop) + return; + + main_loop->init(); + + int flip = bbutil_is_flipped(); + int rot = bbutil_get_rotation(); + flip_accelerometer = rot == 90; + printf("**************** rot is %i, flip %i\n", rot, (int)flip_accelerometer); + /* + orientation_direction_t orientation; + int angle; + orientation_get(&orientation, &angle); + printf("******************** orientation %i, %i, %i\n", orientation, ORIENTATION_BOTTOM_UP, ORIENTATION_TOP_UP); + if (orientation == ORIENTATION_BOTTOM_UP) { + flip_accelerometer = true; + }; + */ + + + while (true) { + + process_events(); // get rid of pending events + if (Main::iteration()==true) + break; + bbutil_swap(); + //#ifdef DEBUG_ENABLED + fflush(stdout); + //#endif + }; + + main_loop->finish(); + +}; + +bool OSBB10::has_touchscreen_ui_hint() const { + + return true; +} + +Error OSBB10::shell_open(String p_uri) { + + char* msg = NULL; + int ret = navigator_invoke(p_uri.utf8().get_data(), &msg); + + return ret == BPS_SUCCESS ? OK : FAILED; +}; + +String OSBB10::get_data_dir() const { + + return data_dir; +}; + + +OSBB10::OSBB10() { + + main_loop=NULL; + last_id=1; + minimized = false; + fullscreen = true; + flip_accelerometer = true; + fullscreen_mixer_volume = 1; + fullscreen_stream_volume = 1; + + + printf("godot bb10!\n"); + getcwd(launch_dir, sizeof(launch_dir)); + printf("launch dir %s\n", launch_dir); + chdir("app/native/assets"); + launch_dir_ptr = launch_dir; +} + +OSBB10::~OSBB10() { + + +} + diff --git a/platform/bb10/os_bb10.h b/platform/bb10/os_bb10.h new file mode 100644 index 000000000..28149c15b --- /dev/null +++ b/platform/bb10/os_bb10.h @@ -0,0 +1,157 @@ +/*************************************************************************/ +/* os_bb10.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef OS_BB10_H +#define OS_BB10_H + +#include "os/input.h" +#include "drivers/unix/os_unix.h" +#include "os/main_loop.h" +#include "servers/physics/physics_server_sw.h" +#include "servers/spatial_sound/spatial_sound_server_sw.h" +#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h" +#include "servers/audio/audio_server_sw.h" +#include "servers/physics_2d/physics_2d_server_sw.h" +#include "servers/visual/rasterizer.h" +#include "audio_driver_bb10.h" +#include "payment_service.h" + +#include <screen/screen.h> +#include <sys/platform.h> +#include "bps/event.h" + +#include <stdint.h> + +class OSBB10 : public OS_Unix { + + unsigned int last_id; + + screen_context_t screen_cxt; + float fullscreen_mixer_volume; + float fullscreen_stream_volume; + + Rasterizer *rasterizer; + VisualServer *visual_server; +// AudioDriverPSP audio_driver_psp; + AudioServerSW *audio_server; + SampleManagerMallocSW *sample_manager; + SpatialSoundServerSW *spatial_sound_server; + SpatialSound2DServerSW *spatial_sound_2d_server; + PhysicsServer *physics_server; + Physics2DServer *physics_2d_server; + AudioDriverBB10* audio_driver; + +#ifdef PAYMENT_SERVICE_ENABLED + PaymentService* payment_service; +#endif + + VideoMode default_videomode; + MainLoop * main_loop; + + void process_events(); + + void _resize(bps_event_t *event); + void handle_screen_event(bps_event_t *event); + void handle_accelerometer(); + + int last_touch_x[16]; + int last_touch_y[16]; + + bool accel_supported; + float pitch; + float roll; + + bool minimized; + bool fullscreen; + bool flip_accelerometer; + String data_dir; + + InputDefault *input; +public: + + // functions used by main to initialize/deintialize the OS + virtual int get_video_driver_count() const; + virtual const char * get_video_driver_name(int p_driver) const; + + virtual VideoMode get_default_video_mode() const; + + virtual String get_data_dir() const; + + virtual int get_audio_driver_count() const; + virtual const char * get_audio_driver_name(int p_driver) const; + + virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver); + + virtual void set_main_loop( MainLoop * p_main_loop ); + virtual void delete_main_loop(); + + virtual void finalize(); + + typedef int64_t ProcessID; + + static OS* get_singleton(); + + virtual void set_mouse_show(bool p_show); + virtual void set_mouse_grab(bool p_grab); + virtual bool is_mouse_grab_enabled() const; + virtual Point2 get_mouse_pos() const; + virtual int get_mouse_button_state() const; + virtual void set_window_title(const String& p_title); + + //virtual void set_clipboard(const String& p_text); + //virtual String get_clipboard() const; + + + virtual bool has_virtual_keyboard() const; + virtual void show_virtual_keyboard(const String& p_existing_text,const Rect2& p_screen_rect); + virtual void hide_virtual_keyboard(); + + virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0); + virtual VideoMode get_video_mode(int p_screen=0) const; + virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + + virtual String get_name(); + virtual MainLoop *get_main_loop() const; + + virtual bool can_draw() const; + + virtual void set_cursor_shape(CursorShape p_shape); + + virtual bool has_touchscreen_ui_hint() const; + + virtual Error shell_open(String p_uri); + + void run(); + + OSBB10(); + ~OSBB10(); + +}; + +#endif + diff --git a/platform/bb10/payment_service.cpp b/platform/bb10/payment_service.cpp new file mode 100644 index 000000000..f6ffffd83 --- /dev/null +++ b/platform/bb10/payment_service.cpp @@ -0,0 +1,150 @@ +/*************************************************************************/ +/* payment_service.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifdef PAYMENT_SERVICE_ENABLED + +#include "payment_service.h" + +#include "bbutil.h" +#include <string.h> +#include <errno.h> +#include <unistd.h> +extern char* launch_dir_ptr; + +void PaymentService::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("request_product_info"),&PaymentService::request_product_info); + ObjectTypeDB::bind_method(_MD("purchase"),&PaymentService::purchase); + + ObjectTypeDB::bind_method(_MD("get_pending_event_count"),&PaymentService::get_pending_event_count); + ObjectTypeDB::bind_method(_MD("pop_pending_event"),&PaymentService::pop_pending_event); +}; + +Error PaymentService::request_product_info(Variant p_params) { + + return ERR_UNAVAILABLE; +}; + +Error PaymentService::purchase(Variant p_params) { + + Dictionary params = p_params; + ERR_FAIL_COND_V((!params.has("product_id")) && (!params.has("product_sku")), ERR_INVALID_PARAMETER); + + char* id = NULL; + char* sku = NULL; + + CharString p_id = params.has("product_id")?String(params["product_id"]).ascii():CharString(); + CharString p_sku = params.has("product_sku")?String(params["product_sku"]).ascii():CharString(); + unsigned int request_id; + chdir(launch_dir_ptr); + int ret = paymentservice_purchase_request(params.has("product_sku") ? NULL : p_id.get_data(), + params.has("product_sku") ? p_sku.get_data() : NULL, + NULL, NULL, NULL, NULL, get_window_group_id(), &request_id); + chdir("app/native"); + + if (ret != BPS_SUCCESS) { + int eret = errno; + printf("purchase error %i, %x, %i, %x\n", ret, ret, eret, eret); + ERR_FAIL_V((Error)eret); + return (Error)eret; + }; + return OK; +}; + + +bool PaymentService::handle_event(bps_event_t* p_event) { + + if (bps_event_get_domain(p_event) != paymentservice_get_domain()) { + return false; + }; + + Dictionary dict; + int res = paymentservice_event_get_response_code(p_event); + if (res == SUCCESS_RESPONSE) { + dict["result"] = "ok"; + + res = bps_event_get_code(p_event); + if (res == PURCHASE_RESPONSE) { + dict["type"] = "purchase"; + const char* pid = paymentservice_event_get_digital_good_id(p_event, 0); + dict["product_id"] = String(pid?pid:""); + }; + + } else { + const char* desc = paymentservice_event_get_error_text(p_event); + if (strcmp(desc, "alreadyPurchased") == 0) { + dict["result"] = "ok"; + } else { + dict["result"] = "error"; + dict["error_description"] = paymentservice_event_get_error_text(p_event); + dict["error_code"] = paymentservice_event_get_error_id(p_event); + printf("error code is %i\n", paymentservice_event_get_error_id(p_event)); + printf("error description is %s\n", paymentservice_event_get_error_text(p_event)); + }; + dict["product_id"] = ""; + }; + + res = bps_event_get_code(p_event); + if (res == PURCHASE_RESPONSE) { + dict["type"] = "purchase"; + }; + + printf("********** adding event with result %ls\n", String(dict["result"]).c_str()); + pending_events.push_back(dict); + + return true; +}; + +int PaymentService::get_pending_event_count() { + return pending_events.size(); +}; + +Variant PaymentService::pop_pending_event() { + + Variant front = pending_events.front()->get(); + pending_events.pop_front(); + + return front; +}; + +PaymentService::PaymentService() { + + paymentservice_request_events(0); +#ifdef DEBUG_ENABLED + paymentservice_set_connection_mode(true); +#else + paymentservice_set_connection_mode(false); +#endif +}; + +PaymentService::~PaymentService() { + +}; + + +#endif diff --git a/platform/bb10/payment_service.h b/platform/bb10/payment_service.h new file mode 100644 index 000000000..09eda11d2 --- /dev/null +++ b/platform/bb10/payment_service.h @@ -0,0 +1,69 @@ +/*************************************************************************/ +/* payment_service.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifdef PAYMENT_SERVICE_ENABLED + +#ifndef PAYMENT_SERVICE_H +#define PAYMENT_SERVICE_H + +#include <bps/bps.h> +#include <bps/event.h> +#include <bps/paymentservice.h> + +#include "core/object.h" + +class PaymentService : public Object { + + OBJ_TYPE(PaymentService, Object); + + static void _bind_methods(); + + List<Variant> pending_events; + +public: + + Error request_product_info(Variant p_params); + Error purchase(Variant p_params); + + int get_pending_event_count(); + Variant pop_pending_event(); + + bool handle_event(bps_event_t* p_event); + + PaymentService(); + ~PaymentService(); +}; + + + +#endif + + +#endif + + diff --git a/platform/bb10/platform_config.h b/platform/bb10/platform_config.h new file mode 100644 index 000000000..38fc934ae --- /dev/null +++ b/platform/bb10/platform_config.h @@ -0,0 +1,29 @@ +/*************************************************************************/ +/* platform_config.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include <alloca.h> |
