os_bb10.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*************************************************************************/
  2. /* os_bb10.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "os_bb10.h"
  30. #include "drivers/gles2/rasterizer_gles2.h"
  31. #include "drivers/gles1/rasterizer_gles1.h"
  32. #include "servers/visual/visual_server_raster.h"
  33. #include "core/os/dir_access.h"
  34. #include "core/globals.h"
  35. #include "main/main.h"
  36. #include "bbutil.h"
  37. #include <stdlib.h>
  38. #include <stdbool.h>
  39. #include <assert.h>
  40. #include "core/os/keyboard.h"
  41. #include "bps/bps.h"
  42. #include "bps/screen.h"
  43. #include "bps/navigator.h"
  44. #include "bps/accelerometer.h"
  45. #include "bps/orientation.h"
  46. #include "bps/virtualkeyboard.h"
  47. #include "bps/audiodevice.h"
  48. #ifdef BB10_SCORELOOP_ENABLED
  49. #include "modules/scoreloop/scoreloop_bb10.h"
  50. #endif
  51. static char launch_dir[512];
  52. char* launch_dir_ptr;
  53. int OSBB10::get_video_driver_count() const {
  54. return 1;
  55. }
  56. const char * OSBB10::get_video_driver_name(int p_driver) const {
  57. return "GLES2";
  58. }
  59. OS::VideoMode OSBB10::get_default_video_mode() const {
  60. return OS::VideoMode();
  61. }
  62. int OSBB10::get_audio_driver_count() const {
  63. return 1;
  64. }
  65. const char * OSBB10::get_audio_driver_name(int p_driver) const {
  66. return "BB10";
  67. }
  68. void OSBB10::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
  69. data_dir = getenv("HOME");
  70. //Create a screen context that will be used to create an EGL surface to to receive libscreen events
  71. screen_create_context(&screen_cxt,0);
  72. //Initialize BPS library
  73. bps_initialize();
  74. //Use utility code to initialize EGL for 2D rendering with GL ES 1.1
  75. enum RENDERING_API api = GL_ES_2;
  76. #ifdef BB10_LGLES_OVERRIDE
  77. api = GL_ES_1;
  78. #endif
  79. if (EXIT_SUCCESS != bbutil_init(screen_cxt, api)) {
  80. bbutil_terminate();
  81. screen_destroy_context(screen_cxt);
  82. return;
  83. };
  84. EGLint surface_width, surface_height;
  85. eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
  86. eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
  87. printf("screen size: %ix%i\n", surface_width, surface_height);
  88. VideoMode mode;
  89. mode.width = surface_width;
  90. mode.height = surface_height;
  91. mode.fullscreen = true;
  92. mode.resizable = false;
  93. set_video_mode(mode);
  94. //Signal BPS library that navigator and screen events will be requested
  95. screen_request_events(screen_cxt);
  96. navigator_request_events(0);
  97. virtualkeyboard_request_events(0);
  98. audiodevice_request_events(0);
  99. #ifdef DEBUG_ENABLED
  100. bps_set_verbosity(3);
  101. #endif
  102. accel_supported = accelerometer_is_supported();
  103. if (accel_supported)
  104. accelerometer_set_update_frequency(FREQ_40_HZ);
  105. pitch = 0;
  106. roll = 0;
  107. #ifdef BB10_LGLES_OVERRIDE
  108. rasterizer = memnew( RasterizerGLES1(false) );
  109. #else
  110. rasterizer = memnew( RasterizerGLES2(false, false) );
  111. #endif
  112. visual_server = memnew( VisualServerRaster(rasterizer) );
  113. visual_server->init();
  114. visual_server->cursor_set_visible(false, 0);
  115. audio_driver = memnew(AudioDriverBB10);
  116. audio_driver->set_singleton();
  117. audio_driver->init(NULL);
  118. sample_manager = memnew( SampleManagerMallocSW );
  119. audio_server = memnew( AudioServerSW(sample_manager) );
  120. audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,false);
  121. audio_server->init();
  122. spatial_sound_server = memnew( SpatialSoundServerSW );
  123. spatial_sound_server->init();
  124. spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
  125. spatial_sound_2d_server->init();
  126. //
  127. physics_server = memnew( PhysicsServerSW );
  128. physics_server->init();
  129. physics_2d_server = memnew( Physics2DServerSW );
  130. physics_2d_server->init();
  131. input = memnew( InputDefault );
  132. #ifdef PAYMENT_SERVICE_ENABLED
  133. payment_service = memnew(PaymentService);
  134. Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", payment_service));
  135. #endif
  136. }
  137. void OSBB10::set_main_loop( MainLoop * p_main_loop ) {
  138. input->set_main_loop(p_main_loop);
  139. main_loop=p_main_loop;
  140. }
  141. void OSBB10::delete_main_loop() {
  142. memdelete( main_loop );
  143. main_loop = NULL;
  144. }
  145. void OSBB10::finalize() {
  146. if(main_loop)
  147. memdelete(main_loop);
  148. main_loop=NULL;
  149. spatial_sound_server->finish();
  150. memdelete(spatial_sound_server);
  151. spatial_sound_2d_server->finish();
  152. memdelete(spatial_sound_2d_server);
  153. //if (debugger_connection_console) {
  154. // memdelete(debugger_connection_console);
  155. //}
  156. audio_server->finish();
  157. memdelete(audio_server);
  158. memdelete(sample_manager);
  159. visual_server->finish();
  160. memdelete(visual_server);
  161. memdelete(rasterizer);
  162. physics_server->finish();
  163. memdelete(physics_server);
  164. physics_2d_server->finish();
  165. memdelete(physics_2d_server);
  166. #ifdef PAYMENT_SERVICE_ENABLED
  167. memdelete(payment_service);
  168. #endif
  169. memdelete(input);
  170. bbutil_terminate();
  171. screen_destroy_context(screen_cxt);
  172. bps_shutdown();
  173. }
  174. void OSBB10::set_mouse_show(bool p_show) {
  175. //android has no mouse...
  176. }
  177. void OSBB10::set_mouse_grab(bool p_grab) {
  178. //it really has no mouse...!
  179. }
  180. bool OSBB10::is_mouse_grab_enabled() const {
  181. //*sigh* technology has evolved so much since i was a kid..
  182. return false;
  183. }
  184. Point2 OSBB10::get_mouse_pos() const {
  185. return Point2();
  186. }
  187. int OSBB10::get_mouse_button_state() const {
  188. return 0;
  189. }
  190. void OSBB10::set_window_title(const String& p_title) {
  191. }
  192. //interesting byt not yet
  193. //void set_clipboard(const String& p_text);
  194. //String get_clipboard() const;
  195. void OSBB10::set_video_mode(const VideoMode& p_video_mode,int p_screen) {
  196. default_videomode = p_video_mode;
  197. }
  198. OS::VideoMode OSBB10::get_video_mode(int p_screen) const {
  199. return default_videomode;
  200. }
  201. void OSBB10::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const {
  202. p_list->push_back(default_videomode);
  203. }
  204. String OSBB10::get_name() {
  205. return "BlackBerry 10";
  206. }
  207. MainLoop *OSBB10::get_main_loop() const {
  208. return main_loop;
  209. }
  210. bool OSBB10::can_draw() const {
  211. return !minimized;
  212. }
  213. void OSBB10::set_cursor_shape(CursorShape p_shape) {
  214. //android really really really has no mouse.. how amazing..
  215. }
  216. void OSBB10::handle_screen_event(bps_event_t *event) {
  217. screen_event_t screen_event = screen_event_get_event(event);
  218. int screen_val;
  219. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val);
  220. int pos[2];
  221. switch (screen_val) {
  222. case SCREEN_EVENT_MTOUCH_TOUCH:
  223. case SCREEN_EVENT_MTOUCH_RELEASE: {
  224. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos);
  225. InputEvent ievent;
  226. ievent.type = InputEvent::SCREEN_TOUCH;
  227. ievent.ID = ++last_id;
  228. ievent.device = 0;
  229. ievent.screen_touch.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH);
  230. ievent.screen_touch.x = pos[0];
  231. ievent.screen_touch.y = pos[1];
  232. Point2 mpos(ievent.screen_touch.x, ievent.screen_touch.y);
  233. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]);
  234. ievent.screen_touch.index = pos[0];
  235. last_touch_x[pos[0]] = ievent.screen_touch.x;
  236. last_touch_y[pos[0]] = ievent.screen_touch.y;
  237. input->parse_input_event( ievent );
  238. if (ievent.screen_touch.index == 0) {
  239. InputEvent ievent;
  240. ievent.type = InputEvent::MOUSE_BUTTON;
  241. ievent.ID = ++last_id;
  242. ievent.device = 0;
  243. ievent.mouse_button.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH);
  244. ievent.mouse_button.button_index = BUTTON_LEFT;
  245. ievent.mouse_button.doubleclick = 0;
  246. ievent.mouse_button.x = ievent.mouse_button.global_x = mpos.x;
  247. ievent.mouse_button.y = ievent.mouse_button.global_y = mpos.y;
  248. input->parse_input_event( ievent );
  249. };
  250. } break;
  251. case SCREEN_EVENT_MTOUCH_MOVE: {
  252. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos);
  253. InputEvent ievent;
  254. ievent.type = InputEvent::SCREEN_DRAG;
  255. ievent.ID = ++last_id;
  256. ievent.device = 0;
  257. ievent.screen_drag.x = pos[0];
  258. ievent.screen_drag.y = pos[1];
  259. /*
  260. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pos);
  261. ievent.screen_drag.relative_x = ievent.screen_drag.x - pos[0];
  262. ievent.screen_drag.relative_y = ievent.screen_drag.y - pos[1];
  263. */
  264. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]);
  265. ievent.screen_drag.index = pos[0];
  266. ievent.screen_drag.relative_x = ievent.screen_drag.x - last_touch_x[ievent.screen_drag.index];
  267. ievent.screen_drag.relative_y = ievent.screen_drag.y - last_touch_y[ievent.screen_drag.index];
  268. last_touch_x[ievent.screen_drag.index] = ievent.screen_drag.x;
  269. last_touch_y[ievent.screen_drag.index] = ievent.screen_drag.y;
  270. Point2 mpos(ievent.screen_drag.x, ievent.screen_drag.y);
  271. Point2 mrel(ievent.screen_drag.relative_x, ievent.screen_drag.relative_y);
  272. input->parse_input_event( ievent );
  273. if (ievent.screen_touch.index == 0) {
  274. InputEvent ievent;
  275. ievent.type = InputEvent::MOUSE_MOTION;
  276. ievent.ID = ++last_id;
  277. ievent.device = 0;
  278. ievent.mouse_motion.x = ievent.mouse_motion.global_x = mpos.x;
  279. ievent.mouse_motion.y = ievent.mouse_motion.global_y = mpos.y;
  280. input->set_mouse_pos(Point2(ievent.mouse_motion.x,ievent.mouse_motion.y));
  281. ievent.mouse_motion.speed_x=input->get_mouse_speed().x;
  282. ievent.mouse_motion.speed_y=input->get_mouse_speed().y;
  283. ievent.mouse_motion.relative_x = mrel.x;
  284. ievent.mouse_motion.relative_y = mrel.y;
  285. ievent.mouse_motion.button_mask = 1; // pressed
  286. input->parse_input_event( ievent );
  287. };
  288. } break;
  289. case SCREEN_EVENT_KEYBOARD: {
  290. InputEvent ievent;
  291. ievent.type = InputEvent::KEY;
  292. ievent.ID = ++last_id;
  293. ievent.device = 0;
  294. int val = 0;
  295. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SCAN, &val);
  296. ievent.key.scancode = val;
  297. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &val);
  298. ievent.key.unicode = val;
  299. if (val == 61448) {
  300. ievent.key.scancode = KEY_BACKSPACE;
  301. ievent.key.unicode = KEY_BACKSPACE;
  302. };
  303. if (val == 61453) {
  304. ievent.key.scancode = KEY_ENTER;
  305. ievent.key.unicode = KEY_ENTER;
  306. };
  307. int flags;
  308. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
  309. ievent.key.pressed = flags & 1; // bit 1 is pressed apparently
  310. int mod;
  311. screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);
  312. input->parse_input_event( ievent );
  313. } break;
  314. default:
  315. break;
  316. }
  317. };
  318. void OSBB10::handle_accelerometer() {
  319. if (!accel_supported)
  320. return;
  321. if (!fullscreen)
  322. return;
  323. double force_x, force_y, force_z;
  324. accelerometer_read_forces(&force_x, &force_y, &force_z);
  325. Vector3 accel = Vector3(force_x, flip_accelerometer ? force_y : -force_y, force_z);
  326. input->set_accelerometer(accel);
  327. // rotate 90 degrees
  328. //input->set_accelerometer(Vector3(force_y, flip_accelerometer?force_x:(-force_x), force_z));
  329. };
  330. void OSBB10::_resize(bps_event_t* event) {
  331. int angle = navigator_event_get_orientation_angle(event);
  332. bbutil_rotate_screen_surface(angle);
  333. EGLint surface_width, surface_height;
  334. eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
  335. eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
  336. VideoMode mode;
  337. mode.width = surface_width;
  338. mode.height = surface_height;
  339. mode.fullscreen = true;
  340. mode.resizable = false;
  341. set_video_mode(mode);
  342. };
  343. void OSBB10::process_events() {
  344. handle_accelerometer();
  345. bps_event_t *event = NULL;
  346. do {
  347. int rc = bps_get_event(&event, 0);
  348. assert(rc == BPS_SUCCESS);
  349. if (!event) break;
  350. #ifdef BB10_SCORELOOP_ENABLED
  351. ScoreloopBB10* sc = Globals::get_singleton()->get_singleton_object("Scoreloop")->cast_to<ScoreloopBB10>();
  352. if (sc->handle_event(event))
  353. continue;
  354. #endif
  355. #ifdef PAYMENT_SERVICE_ENABLED
  356. if (payment_service->handle_event(event))
  357. continue;
  358. #endif
  359. int domain = bps_event_get_domain(event);
  360. if (domain == screen_get_domain()) {
  361. handle_screen_event(event);
  362. } else if (domain == navigator_get_domain()) {
  363. if (NAVIGATOR_EXIT == bps_event_get_code(event)) {
  364. if (main_loop)
  365. main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
  366. bps_event_destroy(event);
  367. exit(0);
  368. return;
  369. /*
  370. } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION_CHECK) {
  371. int angle = navigator_event_get_orientation_angle(event);
  372. navigator_orientation_check_response(event, false);
  373. } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION) {
  374. _resize(event);
  375. */
  376. } else if (bps_event_get_code(event) == NAVIGATOR_WINDOW_STATE) {
  377. int state = navigator_event_get_window_state(event);
  378. bool was_fullscreen = fullscreen;
  379. minimized = state == NAVIGATOR_WINDOW_INVISIBLE;
  380. fullscreen = state == NAVIGATOR_WINDOW_FULLSCREEN;
  381. set_low_processor_usage_mode(!fullscreen);
  382. if (fullscreen != was_fullscreen) {
  383. if (fullscreen) {
  384. audio_server->set_fx_global_volume_scale(fullscreen_mixer_volume);
  385. audio_server->set_stream_global_volume_scale(fullscreen_stream_volume);
  386. } else {
  387. fullscreen_mixer_volume = audio_server->get_fx_global_volume_scale();
  388. fullscreen_stream_volume = audio_server->get_stream_global_volume_scale();
  389. audio_server->set_fx_global_volume_scale(0);
  390. audio_server->set_stream_global_volume_scale(0);
  391. };
  392. };
  393. };
  394. } else if (domain == audiodevice_get_domain()) {
  395. const char * audiodevice_path = audiodevice_event_get_path(event);
  396. printf("************* got audiodevice event, path %s\n", audiodevice_path);
  397. audio_driver->finish();
  398. audio_driver->init(audiodevice_path);
  399. audio_driver->start();
  400. };
  401. //bps_event_destroy(event);
  402. } while (event);
  403. };
  404. bool OSBB10::has_virtual_keyboard() const {
  405. return true;
  406. };
  407. void OSBB10::show_virtual_keyboard(const String& p_existing_text,const Rect2& p_screen_rect) {
  408. virtualkeyboard_show();
  409. };
  410. void OSBB10::hide_virtual_keyboard() {
  411. virtualkeyboard_hide();
  412. };
  413. void OSBB10::run() {
  414. if (!main_loop)
  415. return;
  416. main_loop->init();
  417. int flip = bbutil_is_flipped();
  418. int rot = bbutil_get_rotation();
  419. flip_accelerometer = rot == 90;
  420. printf("**************** rot is %i, flip %i\n", rot, (int)flip_accelerometer);
  421. /*
  422. orientation_direction_t orientation;
  423. int angle;
  424. orientation_get(&orientation, &angle);
  425. printf("******************** orientation %i, %i, %i\n", orientation, ORIENTATION_BOTTOM_UP, ORIENTATION_TOP_UP);
  426. if (orientation == ORIENTATION_BOTTOM_UP) {
  427. flip_accelerometer = true;
  428. };
  429. */
  430. while (true) {
  431. process_events(); // get rid of pending events
  432. if (Main::iteration()==true)
  433. break;
  434. bbutil_swap();
  435. //#ifdef DEBUG_ENABLED
  436. fflush(stdout);
  437. //#endif
  438. };
  439. main_loop->finish();
  440. };
  441. bool OSBB10::has_touchscreen_ui_hint() const {
  442. return true;
  443. }
  444. Error OSBB10::shell_open(String p_uri) {
  445. char* msg = NULL;
  446. int ret = navigator_invoke(p_uri.utf8().get_data(), &msg);
  447. return ret == BPS_SUCCESS ? OK : FAILED;
  448. };
  449. String OSBB10::get_data_dir() const {
  450. return data_dir;
  451. };
  452. OSBB10::OSBB10() {
  453. main_loop=NULL;
  454. last_id=1;
  455. minimized = false;
  456. fullscreen = true;
  457. flip_accelerometer = true;
  458. fullscreen_mixer_volume = 1;
  459. fullscreen_stream_volume = 1;
  460. printf("godot bb10!\n");
  461. getcwd(launch_dir, sizeof(launch_dir));
  462. printf("launch dir %s\n", launch_dir);
  463. chdir("app/native");
  464. launch_dir_ptr = launch_dir;
  465. }
  466. OSBB10::~OSBB10() {
  467. }