diff options
Diffstat (limited to 'platform/iphone/os_iphone.cpp')
| -rw-r--r-- | platform/iphone/os_iphone.cpp | 507 |
1 files changed, 507 insertions, 0 deletions
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp new file mode 100644 index 000000000..3b3b30cb8 --- /dev/null +++ b/platform/iphone/os_iphone.cpp @@ -0,0 +1,507 @@ +/*************************************************************************/ +/* os_iphone.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 IPHONE_ENABLED + +#include "os_iphone.h" + +#include "drivers/gles2/rasterizer_gles2.h" +#include "drivers/gles1/rasterizer_gles1.h" + +#include "servers/visual/visual_server_raster.h" +#include "servers/visual/visual_server_wrap_mt.h" + +#include "main/main.h" +#include "audio_driver_iphone.h" + +#include "core/os/dir_access.h" +#include "core/globals.h" + +#include "sem_iphone.h" + +int OSIPhone::get_video_driver_count() const { + + return 1; +}; + +const char * OSIPhone::get_video_driver_name(int p_driver) const { + + return "openglES"; +}; + +OSIPhone* OSIPhone::get_singleton() { + + return (OSIPhone*)OS::get_singleton(); +}; + + +OS::VideoMode OSIPhone::get_default_video_mode() const { + + return video_mode; +}; + +uint8_t OSIPhone::get_orientations() const { + + return supported_orientations; +}; + +extern int gl_view_base_fb; // from gl_view.mm + +void OSIPhone::set_data_dir(String p_dir) { + + DirAccess* da = DirAccess::open(p_dir); + + data_dir = da->get_current_dir(); + + memdelete(da); +}; + +void OSIPhone::set_unique_ID(String p_ID) { + + unique_ID = p_ID; +}; + +String OSIPhone::get_unique_ID() const { + + return unique_ID; +}; + +void OSIPhone::initialize_core() { + + OS_Unix::initialize_core(); + SemaphoreIphone::make_default(); +}; + +void OSIPhone::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { + + supported_orientations = 0; + supported_orientations |= ((GLOBAL_DEF("video_mode/allow_horizontal", true)?1:0) << LandscapeLeft); + supported_orientations |= ((GLOBAL_DEF("video_mode/allow_horizontal_flipped", false)?1:0) << LandscapeRight); + supported_orientations |= ((GLOBAL_DEF("video_mode/allow_vertical", false)?1:0) << PortraitDown); + supported_orientations |= ((GLOBAL_DEF("video_mode/allow_vertical_flipped", false)?1:0) << PortraitUp); + +#ifdef GLES1_OVERRIDE + rasterizer = memnew( RasterizerGLES1 ); +#else + rasterizer_gles22 = memnew( RasterizerGLES2(false, false, false) ); + rasterizer = rasterizer_gles22; + rasterizer_gles22->set_base_framebuffer(gl_view_base_fb); +#endif + + visual_server = memnew( VisualServerRaster(rasterizer) ); + if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { + + visual_server = memnew(VisualServerWrapMT(visual_server, false)); + }; + visual_server->init(); + + visual_server->init(); + visual_server->cursor_set_visible(false, 0); + + audio_driver = memnew(AudioDriverIphone); + audio_driver->set_singleton(); + audio_driver->init(); + + sample_manager = memnew( SampleManagerMallocSW ); + audio_server = memnew( AudioServerSW(sample_manager) ); + 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 IOS_SCORELOOP_ENABLED + scoreloop = memnew(ScoreloopIOS); + Globals::get_singleton()->add_singleton(Globals::Singleton("Scoreloop", scoreloop)); + scoreloop->connect(); +#endif + */ + +#ifdef GAME_CENTER_ENABLED + game_center = memnew(GameCenter); + Globals::get_singleton()->add_singleton(Globals::Singleton("GameCenter", game_center)); + game_center->connect(); +#endif + +#ifdef STOREKIT_ENABLED + store_kit = memnew(InAppStore); + Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", store_kit)); +#endif +}; + +MainLoop *OSIPhone::get_main_loop() const { + + return main_loop; +}; + + +void OSIPhone::set_main_loop( MainLoop * p_main_loop ) { + + main_loop = p_main_loop; + + if (main_loop) { + input->set_main_loop(p_main_loop); + main_loop->init(); + } +}; + + +bool OSIPhone::iterate() { + + if (!main_loop) + return true; + + if (main_loop) { + for (int i=0; i<event_count; i++) { + + input->parse_input_event(event_queue[i]); + }; + }; + event_count = 0; + + return Main::iteration(); +}; + +void OSIPhone::key(uint32_t p_key, bool p_pressed) { + + InputEvent ev; + ev.type = InputEvent::KEY; + ev.ID = ++last_event_id; + ev.key.echo = false; + ev.key.pressed = p_pressed; + ev.key.scancode = p_key; + ev.key.unicode = p_key; + queue_event(ev); +}; + +void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse) { + + InputEvent ev; + ev.type = InputEvent::SCREEN_TOUCH; + ev.ID = ++last_event_id; + ev.screen_touch.index=p_idx; + ev.screen_touch.pressed=p_pressed; + ev.screen_touch.x=p_x; + ev.screen_touch.y=p_y; + queue_event(ev); + + if (p_use_as_mouse) { + + InputEvent ev; + ev.type = InputEvent::MOUSE_BUTTON; + ev.device = 0; + ev.mouse_button.pointer_index = p_idx; + ev.ID = ++last_event_id; + + // swaped it for tilted screen + //ev.mouse_button.x = ev.mouse_button.global_x = video_mode.height - p_y; + //ev.mouse_button.y = ev.mouse_button.global_y = p_x; + ev.mouse_button.x = ev.mouse_button.global_x = p_x; + ev.mouse_button.y = ev.mouse_button.global_y = p_y; + + ev.mouse_button.button_index = BUTTON_LEFT; + ev.mouse_button.doubleclick = p_doubleclick; + ev.mouse_button.pressed = p_pressed; + + mouse_list.pressed[p_idx] = p_pressed; + + queue_event(ev); + }; +}; + +void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, bool p_use_as_mouse) { + + InputEvent ev; + ev.type=InputEvent::SCREEN_DRAG; + ev.ID = ++last_event_id; + ev.screen_drag.index=p_idx; + ev.screen_drag.x=p_x; + ev.screen_drag.y=p_y; + ev.screen_drag.relative_x = p_x - p_prev_x; + ev.screen_drag.relative_y = p_y - p_prev_y; + queue_event(ev); + + if (p_use_as_mouse) { + InputEvent ev; + ev.type = InputEvent::MOUSE_MOTION; + ev.device = 0; + ev.mouse_motion.pointer_index = p_idx; + ev.ID = ++last_event_id; + + if (true) { // vertical + + ev.mouse_motion.x = ev.mouse_button.global_x = p_x; + ev.mouse_motion.y = ev.mouse_button.global_y = p_y; + ev.mouse_motion.relative_x = ev.mouse_motion.x - p_prev_x; + ev.mouse_motion.relative_y = ev.mouse_motion.y - p_prev_y; + + } else { // horizontal? + ev.mouse_motion.x = ev.mouse_button.global_x = video_mode.height - p_y; + ev.mouse_motion.y = ev.mouse_button.global_y = p_x; + ev.mouse_motion.relative_x = ev.mouse_motion.x - (video_mode.height - p_prev_x); + ev.mouse_motion.relative_y = ev.mouse_motion.y - p_prev_x; + }; + + input->set_mouse_pos(Point2(ev.mouse_motion.x,ev.mouse_motion.y)); + ev.mouse_motion.speed_x=input->get_mouse_speed().x; + ev.mouse_motion.speed_y=input->get_mouse_speed().y; + ev.mouse_motion.button_mask = 1; // pressed + + queue_event(ev); + }; +}; + +void OSIPhone::queue_event(const InputEvent& p_event) { + + ERR_FAIL_INDEX( event_count, MAX_EVENTS ); + + event_queue[event_count++] = p_event; +}; + +void OSIPhone::touches_cancelled() { + + for (int i=0; i<MAX_MOUSE_COUNT; i++) { + + if (mouse_list.pressed[i]) { + + // send a mouse_up outside the screen + mouse_button(i, -1, -1, false, false, false); + }; + }; +}; + +static const float ACCEL_RANGE = 1; + +void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) { + + input->set_accelerometer(Vector3(p_x / (float)ACCEL_RANGE, p_y / (float)ACCEL_RANGE, -p_z / (float)ACCEL_RANGE)); + + /* + if (p_x != last_accel.x) { + //printf("updating accel x %f\n", p_x); + InputEvent ev; + ev.type = InputEvent::JOYSTICK_MOTION; + ev.device = 0; + ev.joy_motion.axis = JOY_ANALOG_0_X; + ev.joy_motion.axis_value = (p_x / (float)ACCEL_RANGE); + ev.ID = ++last_event_id; + last_accel.x = p_x; + queue_event(ev); + }; + if (p_y != last_accel.y) { + //printf("updating accel y %f\n", p_y); + InputEvent ev; + ev.type = InputEvent::JOYSTICK_MOTION; + ev.device = 0; + ev.joy_motion.axis = JOY_ANALOG_0_Y; + ev.joy_motion.axis_value = (p_y / (float)ACCEL_RANGE); + ev.ID = ++last_event_id; + last_accel.y = p_y; + queue_event(ev); + }; + if (p_z != last_accel.z) { + //printf("updating accel z %f\n", p_z); + InputEvent ev; + ev.type = InputEvent::JOYSTICK_MOTION; + ev.device = 0; + ev.joy_motion.axis = JOY_ANALOG_1_X; + ev.joy_motion.axis_value = ( (1.0 - p_z) / (float)ACCEL_RANGE); + ev.ID = ++last_event_id; + last_accel.z = p_z; + queue_event(ev); + }; + */ +}; + + + +void OSIPhone::delete_main_loop() { + + if (main_loop) { + main_loop->finish(); + memdelete(main_loop); + }; + + main_loop = NULL; +}; + +void OSIPhone::finalize() { + + if(main_loop) // should not happen? + memdelete(main_loop); + + visual_server->finish(); + memdelete(visual_server); + memdelete(rasterizer); + + physics_server->finish(); + memdelete(physics_server); + + physics_2d_server->finish(); + memdelete(physics_2d_server); + + spatial_sound_server->finish(); + memdelete(spatial_sound_server); + + memdelete(input); + + spatial_sound_2d_server->finish(); + memdelete(spatial_sound_2d_server); + +}; + +void OSIPhone::set_mouse_show(bool p_show) { }; +void OSIPhone::set_mouse_grab(bool p_grab) { }; + +bool OSIPhone::is_mouse_grab_enabled() const { + + return true; +}; + +Point2 OSIPhone::get_mouse_pos() const { + + return Point2(); +}; + +int OSIPhone::get_mouse_button_state() const { + + return mouse_list.pressed[0]; +}; + +void OSIPhone::set_window_title(const String& p_title) { }; + +void OSIPhone::set_video_mode(const VideoMode& p_video_mode, int p_screen) { + + video_mode = p_video_mode; +}; + +OS::VideoMode OSIPhone::get_video_mode(int p_screen) const { + + return video_mode; +}; + +void OSIPhone::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const { + + p_list->push_back(video_mode); +}; + +bool OSIPhone::can_draw() const { + + return true; +}; + +int OSIPhone::set_base_framebuffer(int p_fb) { + + if (rasterizer_gles22) { + rasterizer_gles22->set_base_framebuffer(p_fb); + }; + return 0; +}; + +bool OSIPhone::has_virtual_keyboard() const { + return true; +}; + +extern void _show_keyboard(String p_existing); +extern void _hide_keyboard(); +extern Error _shell_open(String p_uri); + +void OSIPhone::show_virtual_keyboard(const String& p_existing_text,const Rect2& p_screen_rect) { + _show_keyboard(p_existing_text); +}; + +void OSIPhone::hide_virtual_keyboard() { + _hide_keyboard(); +}; + +Error OSIPhone::shell_open(String p_uri) { + return _shell_open(p_uri); +}; + + +void OSIPhone::set_cursor_shape(CursorShape p_shape) { + + +}; + +String OSIPhone::get_data_dir() const { + + return data_dir; +}; + +String OSIPhone::get_name() { + + return "iOS"; +}; + +bool OSIPhone::has_touchscreen_ui_hint() const { + + return true; +} + +void OSIPhone::set_locale(String p_locale) +{ + locale_code = p_locale; +} + +String OSIPhone::get_locale() const { + return locale_code; +} + +OSIPhone::OSIPhone(int width, int height) { + + rasterizer_gles22 = NULL; + main_loop = NULL; + visual_server = NULL; + rasterizer = NULL; + + VideoMode vm; + vm.fullscreen = true; + vm.width = width; + vm.height = height; + vm.resizable = false; + set_video_mode(vm); + event_count = 0; + last_event_id = 0; +}; + +OSIPhone::~OSIPhone() { + +} + +#endif |
