diff options
Diffstat (limited to 'platform')
-rw-r--r-- | platform/android/export/export.cpp | 16 | ||||
-rw-r--r-- | platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java | 12 | ||||
-rw-r--r-- | platform/android/java/src/org/godotengine/godot/GodotView.java | 4 | ||||
-rw-r--r-- | platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java | 14 | ||||
-rw-r--r-- | platform/android/os_android.cpp | 49 | ||||
-rw-r--r-- | platform/android/os_android.h | 1 | ||||
-rw-r--r-- | platform/iphone/app_delegate.h | 1 | ||||
-rw-r--r-- | platform/iphone/app_delegate.mm | 182 | ||||
-rw-r--r-- | platform/iphone/export/export.cpp | 67 | ||||
-rw-r--r-- | platform/iphone/gl_view.h | 2 | ||||
-rw-r--r-- | platform/iphone/gl_view.mm | 24 | ||||
-rw-r--r-- | platform/iphone/in_app_store.mm | 1 | ||||
-rw-r--r-- | platform/iphone/os_iphone.cpp | 51 | ||||
-rw-r--r-- | platform/iphone/os_iphone.h | 7 | ||||
-rw-r--r-- | platform/javascript/os_javascript.cpp | 35 | ||||
-rw-r--r-- | platform/uwp/app.cpp | 83 | ||||
-rw-r--r-- | platform/uwp/app.h | 1 | ||||
-rw-r--r-- | platform/uwp/export/export.cpp | 8 | ||||
-rw-r--r-- | platform/windows/os_windows.cpp | 45 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 17 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 1 |
21 files changed, 299 insertions, 322 deletions
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 6d9f0a7e9a..6ed03d7aee 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1153,7 +1153,7 @@ public: String package_name = p_preset->get("package/unique_name"); if (remove_prev) { - ep.step("Uninstalling..", 1); + ep.step("Uninstalling...", 1); print_line("Uninstalling previous version: " + devices[p_device].name); @@ -1232,7 +1232,7 @@ public: } } - ep.step("Running on Device..", 3); + ep.step("Running on Device...", 3); args.clear(); args.push_back("-s"); args.push_back(devices[p_device].id); @@ -1323,6 +1323,8 @@ public: virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) { + ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); + String src_apk; EditorProgress ep("export", "Exporting for Android", 105); @@ -1490,7 +1492,7 @@ public: ret = unzGoToNextFile(pkg); } - ep.step("Adding Files..", 1); + ep.step("Adding Files...", 1); Error err = OK; Vector<String> cl = cmdline.strip_edges().split(" "); for (int i = 0; i < cl.size(); i++) { @@ -1624,14 +1626,14 @@ public: password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass"); user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user"); - ep.step("Signing Debug APK..", 103); + ep.step("Signing Debug APK...", 103); } else { keystore = release_keystore; password = release_password; user = release_username; - ep.step("Signing Release APK..", 103); + ep.step("Signing Release APK...", 103); } if (!FileAccess::exists(keystore)) { @@ -1663,7 +1665,7 @@ public: return ERR_CANT_CREATE; } - ep.step("Verifying APK..", 104); + ep.step("Verifying APK...", 104); args.clear(); args.push_back("-verify"); @@ -1683,7 +1685,7 @@ public: static const int ZIP_ALIGNMENT = 4; - ep.step("Aligning APK..", 105); + ep.step("Aligning APK...", 105); unzFile tmp_unaligned = unzOpen2(unaligned_path.utf8().get_data(), &io); if (!tmp_unaligned) { diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java index d72c590378..bde4221644 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java @@ -101,12 +101,12 @@ public class GodotPaymentV3 extends Godot.SingletonBase { GodotLib.calldeferred(purchaseCallbackId, "consume_not_required", new Object[] {}); } - public void callbackFailConsume() { - GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[] {}); + public void callbackFailConsume(String message) { + GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[] { message }); } - public void callbackFail() { - GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[] {}); + public void callbackFail(String message) { + GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[] { message }); } public void callbackCancel() { @@ -165,11 +165,11 @@ public class GodotPaymentV3 extends Godot.SingletonBase { } public void callbackDisconnected() { - GodotLib.calldeferred(purchaseCallbackId, "iap_disconnected", new Object[]{}); + GodotLib.calldeferred(purchaseCallbackId, "iap_disconnected", new Object[] {}); } public void callbackConnected() { - GodotLib.calldeferred(purchaseCallbackId, "iap_connected", new Object[]{}); + GodotLib.calldeferred(purchaseCallbackId, "iap_connected", new Object[] {}); } // true if connected, false otherwise diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index 0222758c2b..23723c2696 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -261,7 +261,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { }; int source = event.getSource(); - if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { + if ((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { final int button = get_godot_button(keyCode); final int device = find_joy_device(event.getDeviceId()); @@ -302,7 +302,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { int source = event.getSource(); //Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD))); - if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { + if ((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { if (event.getRepeatCount() > 0) // ignore key echo return true; diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java index 441a311358..b7bf2362cc 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java @@ -116,7 +116,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } @Override @@ -148,7 +148,7 @@ public class PaymentsManager { @Override protected void error(String message) { Log.d("godot", "consumeUnconsumedPurchases :" + message); - godotPaymentV3.callbackFailConsume(); + godotPaymentV3.callbackFailConsume(message); } @Override @@ -222,7 +222,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } } .consume(sku); @@ -231,7 +231,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } @Override @@ -258,7 +258,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } } .consume(sku); @@ -266,7 +266,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } @Override @@ -291,7 +291,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFailConsume(); + godotPaymentV3.callbackFailConsume(message); } } .consume(sku); diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 5557c1de44..fc41adeb76 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -330,17 +330,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> if (touch.size()) { //end all if exist - { - Ref<InputEventMouseButton> ev; - ev.instance(); - ev->set_button_index(BUTTON_LEFT); - ev->set_button_mask(BUTTON_MASK_LEFT); - ev->set_pressed(false); - ev->set_position(touch[0].pos); - ev->set_global_position(touch[0].pos); - input->parse_input_event(ev); - } - for (int i = 0; i < touch.size(); i++) { Ref<InputEventScreenTouch> ev; @@ -358,21 +347,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> touch[i].pos = p_points[i].pos; } - { - //send mouse - Ref<InputEventMouseButton> ev; - ev.instance(); - // ev.type = Ref<InputEvent>::MOUSE_BUTTON; - ev->set_button_index(BUTTON_LEFT); - ev->set_button_mask(BUTTON_MASK_LEFT); - ev->set_pressed(true); - ev->set_position(touch[0].pos); - ev->set_global_position(touch[0].pos); - input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y)); - last_mouse = touch[0].pos; - input->parse_input_event(ev); - } - //send touch for (int i = 0; i < touch.size(); i++) { @@ -387,19 +361,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> } break; case 1: { //motion - if (p_points.size()) { - //send mouse, should look for point 0? - Ref<InputEventMouseMotion> ev; - ev.instance(); - ev->set_button_mask(BUTTON_MASK_LEFT); - ev->set_position(p_points[0].pos); - input->set_mouse_position(Point2(ev->get_position().x, ev->get_position().y)); - ev->set_speed(input->get_last_mouse_speed()); - ev->set_relative(p_points[0].pos - last_mouse); - last_mouse = p_points[0].pos; - input->parse_input_event(ev); - } - ERR_FAIL_COND(touch.size() != p_points.size()); for (int i = 0; i < touch.size(); i++) { @@ -432,16 +393,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> if (touch.size()) { //end all if exist - Ref<InputEventMouseButton> ev; - ev.instance(); - ev->set_button_index(BUTTON_LEFT); - ev->set_button_mask(BUTTON_MASK_LEFT); - ev->set_pressed(false); - ev->set_position(touch[0].pos); - ev->set_global_position(touch[0].pos); - input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y)); - input->parse_input_event(ev); - for (int i = 0; i < touch.size(); i++) { Ref<InputEventScreenTouch> ev; diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 12181b3688..d2457e538d 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -93,7 +93,6 @@ public: private: Vector<TouchPos> touch; - Point2 last_mouse; GFXInitFunc gfx_init_func; void *gfx_init_ud; diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h index f14864b5b7..c34b5053d6 100644 --- a/platform/iphone/app_delegate.h +++ b/platform/iphone/app_delegate.h @@ -37,6 +37,7 @@ @interface AppDelegate : NSObject <UIApplicationDelegate, GLViewDelegate> { //@property (strong, nonatomic) UIWindow *window; ViewController *view_controller; + bool is_focus_out; }; @property(strong, nonatomic) UIWindow *window; diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 5c3799ab09..7ed1328b20 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -79,6 +79,7 @@ static ViewController *mainViewController = nil; } NSMutableDictionary *ios_joysticks = nil; +NSMutableArray *pending_ios_joysticks = nil; - (GCControllerPlayerIndex)getFreePlayerIndex { bool have_player_1 = false; @@ -115,6 +116,66 @@ NSMutableDictionary *ios_joysticks = nil; }; }; +void _ios_add_joystick(GCController *controller, AppDelegate *delegate) { + // get a new id for our controller + int joy_id = OSIPhone::get_singleton()->get_unused_joy_id(); + if (joy_id != -1) { + // assign our player index + if (controller.playerIndex == GCControllerPlayerIndexUnset) { + controller.playerIndex = [delegate getFreePlayerIndex]; + }; + + // tell Godot about our new controller + OSIPhone::get_singleton()->joy_connection_changed( + joy_id, true, [controller.vendorName UTF8String]); + + // add it to our dictionary, this will retain our controllers + [ios_joysticks setObject:controller + forKey:[NSNumber numberWithInt:joy_id]]; + + // set our input handler + [delegate setControllerInputHandler:controller]; + } else { + printf("Couldn't retrieve new joy id\n"); + }; +} + +static void on_focus_out(ViewController *view_controller, bool *is_focus_out) { + if (!*is_focus_out) { + *is_focus_out = true; + if (OS::get_singleton()->get_main_loop()) + OS::get_singleton()->get_main_loop()->notification( + MainLoop::NOTIFICATION_WM_FOCUS_OUT); + + [view_controller.view stopAnimation]; + if (OS::get_singleton()->native_video_is_playing()) { + OSIPhone::get_singleton()->native_video_focus_out(); + } + + AudioDriverCoreAudio *audio = dynamic_cast<AudioDriverCoreAudio *>(AudioDriverCoreAudio::get_singleton()); + if (audio) + audio->stop(); + } +} + +static void on_focus_in(ViewController *view_controller, bool *is_focus_out) { + if (*is_focus_out) { + *is_focus_out = false; + if (OS::get_singleton()->get_main_loop()) + OS::get_singleton()->get_main_loop()->notification( + MainLoop::NOTIFICATION_WM_FOCUS_IN); + + [view_controller.view startAnimation]; + if (OSIPhone::get_singleton()->native_video_is_playing()) { + OSIPhone::get_singleton()->native_video_unpause(); + } + + AudioDriverCoreAudio *audio = dynamic_cast<AudioDriverCoreAudio *>(AudioDriverCoreAudio::get_singleton()); + if (audio) + audio->start(); + } +} + - (void)controllerWasConnected:(NSNotification *)notification { // create our dictionary if we don't have one yet if (ios_joysticks == nil) { @@ -127,28 +188,12 @@ NSMutableDictionary *ios_joysticks = nil; printf("Couldn't retrieve new controller\n"); } else if ([[ios_joysticks allKeysForObject:controller] count] != 0) { printf("Controller is already registered\n"); + } else if (frame_count > 1) { + _ios_add_joystick(controller, self); } else { - // get a new id for our controller - int joy_id = OSIPhone::get_singleton()->get_unused_joy_id(); - if (joy_id != -1) { - // assign our player index - if (controller.playerIndex == GCControllerPlayerIndexUnset) { - controller.playerIndex = [self getFreePlayerIndex]; - }; - - // tell Godot about our new controller - OSIPhone::get_singleton()->joy_connection_changed( - joy_id, true, [controller.vendorName UTF8String]); - - // add it to our dictionary, this will retain our controllers - [ios_joysticks setObject:controller - forKey:[NSNumber numberWithInt:joy_id]]; - - // set our input handler - [self setControllerInputHandler:controller]; - } else { - printf("Couldn't retrieve new joy id\n"); - }; + if (pending_ios_joysticks == nil) + pending_ios_joysticks = [[NSMutableArray alloc] init]; + [pending_ios_joysticks addObject:controller]; }; }; @@ -352,6 +397,27 @@ NSMutableDictionary *ios_joysticks = nil; [ios_joysticks dealloc]; ios_joysticks = nil; }; + + if (pending_ios_joysticks != nil) { + [pending_ios_joysticks dealloc]; + pending_ios_joysticks = nil; + }; +}; + +OS::VideoMode _get_video_mode() { + int backingWidth; + int backingHeight; + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, + GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, + GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + OS::VideoMode vm; + vm.fullscreen = true; + vm.width = backingWidth; + vm.height = backingHeight; + vm.resizable = false; + return vm; }; static int frame_count = 0; @@ -360,19 +426,7 @@ static int frame_count = 0; switch (frame_count) { case 0: { - int backingWidth; - int backingHeight; - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, - GL_RENDERBUFFER_WIDTH_OES, &backingWidth); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, - GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); - - OS::VideoMode vm; - vm.fullscreen = true; - vm.width = backingWidth; - vm.height = backingHeight; - vm.resizable = false; - OS::get_singleton()->set_video_mode(vm); + OS::get_singleton()->set_video_mode(_get_video_mode()); if (!OS::get_singleton()) { exit(0); @@ -410,6 +464,14 @@ static int frame_count = 0; Main::setup2(); ++frame_count; + if (pending_ios_joysticks != nil) { + for (GCController *controller in pending_ios_joysticks) { + _ios_add_joystick(controller, self); + } + [pending_ios_joysticks dealloc]; + pending_ios_joysticks = nil; + } + // this might be necessary before here NSDictionary *dict = [[NSBundle mainBundle] infoDictionary]; for (NSString *key in dict) { @@ -543,6 +605,8 @@ static int frame_count = 0; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { CGRect rect = [[UIScreen mainScreen] bounds]; + is_focus_out = false; + [application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; // disable idle timer // application.idleTimerDisabled = YES; @@ -562,18 +626,13 @@ static int frame_count = 0; //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | // UIViewAutoresizingFlexibleWidth]; - int backingWidth; - int backingHeight; - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, - GL_RENDERBUFFER_WIDTH_OES, &backingWidth); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, - GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + OS::VideoMode vm = _get_video_mode(); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; - int err = iphone_main(backingWidth, backingHeight, gargc, gargv, String::utf8([documentsDirectory UTF8String])); + int err = iphone_main(vm.width, vm.height, gargc, gargv, String::utf8([documentsDirectory UTF8String])); if (err != 0) { // bail, things did not go very well for us, should probably output a message on screen with our error code... exit(0); @@ -607,6 +666,12 @@ static int frame_count = 0; [self initGameControllers]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(onAudioInterruption:) + name:AVAudioSessionInterruptionNotification + object:[AVAudioSession sharedInstance]]; + // OSIPhone::screen_width = rect.size.width - rect.origin.x; // OSIPhone::screen_height = rect.size.height - rect.origin.y; @@ -618,6 +683,18 @@ static int frame_count = 0; return TRUE; }; +- (void)onAudioInterruption:(NSNotification *)notification { + if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) { + if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) { + NSLog(@"Audio interruption began"); + on_focus_out(view_controller, &is_focus_out); + } else if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeEnded]]) { + NSLog(@"Audio interruption ended"); + on_focus_in(view_controller, &is_focus_out); + } + } +}; + - (void)applicationWillTerminate:(UIApplication *)application { [self deinitGameControllers]; @@ -635,14 +712,7 @@ static int frame_count = 0; - (void)applicationDidEnterBackground:(UIApplication *)application { ///@TODO maybe add pause motionManager? and where would we unpause it? - if (OS::get_singleton()->get_main_loop()) - OS::get_singleton()->get_main_loop()->notification( - MainLoop::NOTIFICATION_WM_FOCUS_OUT); - - [view_controller.view stopAnimation]; - if (OS::get_singleton()->native_video_is_playing()) { - OSIPhone::get_singleton()->native_video_focus_out(); - }; + on_focus_out(view_controller, &is_focus_out); } - (void)applicationWillEnterForeground:(UIApplication *)application { @@ -657,19 +727,7 @@ static int frame_count = 0; } - (void)applicationDidBecomeActive:(UIApplication *)application { - if (OS::get_singleton()->get_main_loop()) - OS::get_singleton()->get_main_loop()->notification( - MainLoop::NOTIFICATION_WM_FOCUS_IN); - - [view_controller.view - startAnimation]; // FIXME: resume seems to be recommended elsewhere - if (OSIPhone::get_singleton()->native_video_is_playing()) { - OSIPhone::get_singleton()->native_video_unpause(); - }; - - // Fixed audio can not resume if it is interrupted cause by an incoming phone call - if (AudioDriverCoreAudio::get_singleton() != NULL) - AudioDriverCoreAudio::get_singleton()->start(); + on_focus_in(view_controller, &is_focus_out); } - (void)dealloc { diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index e3119814f4..4c1e02baf7 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -147,6 +147,26 @@ Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_ge return archs; } +struct LoadingScreenInfo { + const char *preset_key; + const char *export_name; +}; + +static const LoadingScreenInfo loading_screen_infos[] = { + { "landscape_launch_screens/iphone_2436x1125", "Default-Landscape-X.png" }, + { "landscape_launch_screens/iphone_2208x1242", "Default-Landscape-736h@3x.png" }, + { "landscape_launch_screens/ipad_1024x768", "Default-Landscape.png" }, + { "landscape_launch_screens/ipad_2048x1536", "Default-Landscape@2x.png" }, + + { "portrait_launch_screens/iphone_640x960", "Default-480h@2x.png" }, + { "portrait_launch_screens/iphone_640x1136", "Default-568h@2x.png" }, + { "portrait_launch_screens/iphone_750x1334", "Default-667h@2x.png" }, + { "portrait_launch_screens/iphone_1125x2436", "Default-Portrait-X.png" }, + { "portrait_launch_screens/ipad_768x1024", "Default-Portrait.png" }, + { "portrait_launch_screens/ipad_1536x2048", "Default-Portrait@2x.png" }, + { "portrait_launch_screens/iphone_1242x2208", "Default-Portrait-736h@3x.png" } +}; + void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) { r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); @@ -172,6 +192,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/iphone_120x120", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPhone/iPod Touch with retina display r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/ipad_76x76", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPad + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/app_store_1024x1024", PROPERTY_HINT_FILE, "png"), "")); // App Store r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/iphone_180x180", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPhone with retina HD display r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/ipad_152x152", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPad with retina display @@ -179,15 +200,9 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_40x40", PROPERTY_HINT_FILE, "png"), "")); // Spotlight r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "png"), "")); // Spotlight on devices with retina display - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "landscape_launch_screens/iphone_2208x1242", PROPERTY_HINT_FILE, "png"), "")); // iPhone 6 Plus, 6s Plus, 7 Plus - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "landscape_launch_screens/ipad_2732x2048", PROPERTY_HINT_FILE, "png"), "")); // 12.9-inch iPad Pro - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "landscape_launch_screens/ipad_2048x1536", PROPERTY_HINT_FILE, "png"), "")); // Other iPads - - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "portrait_launch_screens/iphone_640x1136", PROPERTY_HINT_FILE, "png"), "")); // iPhone 5, 5s, SE - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "portrait_launch_screens/iphone_750x1334", PROPERTY_HINT_FILE, "png"), "")); // iPhone 6, 6s, 7 - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "portrait_launch_screens/iphone_1242x2208", PROPERTY_HINT_FILE, "png"), "")); // iPhone 6 Plus, 6s Plus, 7 Plus - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "portrait_launch_screens/ipad_2048x2732", PROPERTY_HINT_FILE, "png"), "")); // 12.9-inch iPad Pro - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "portrait_launch_screens/ipad_1536x2048", PROPERTY_HINT_FILE, "png"), "")); // Other iPads + for (int i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) { + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "png"), "")); + } r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false)); @@ -313,6 +328,7 @@ static const IconInfo icon_infos[] = { { "required_icons/iphone_120x120", "iphone", "Icon-120.png", "120", "3x", "40x40", true }, { "required_icons/ipad_76x76", "ipad", "Icon-76.png", "76", "1x", "76x76", false }, + { "required_icons/app_store_1024x1024", "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024", false }, { "optional_icons/iphone_180x180", "iphone", "Icon-180.png", "180", "3x", "60x60", false }, @@ -380,23 +396,6 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr return OK; } -struct LoadingScreenInfo { - const char *preset_key; - const char *export_name; -}; - -static const LoadingScreenInfo loading_screen_infos[] = { - { "landscape_launch_screens/iphone_2208x1242", "Default-Landscape-736h@3x.png" }, - { "landscape_launch_screens/ipad_2732x2048", "Default-Landscape-1366h@2x.png" }, - { "landscape_launch_screens/ipad_2048x1536", "Default-Landscape@2x.png" }, - - { "portrait_launch_screens/iphone_640x1136", "Default-568h@2x.png" }, - { "portrait_launch_screens/iphone_750x1334", "Default-667h@2x.png" }, - { "portrait_launch_screens/iphone_1242x2208", "Default-Portrait-736h@3x.png" }, - { "portrait_launch_screens/ipad_2048x2732", "Default-Portrait-1366h@2x.png" }, - { "portrait_launch_screens/ipad_1536x2048", "Default-Portrait@2x.png" } -}; - Error EditorExportPlatformIOS::_export_loading_screens(const Ref<EditorExportPreset> &p_preset, const String &p_dest_dir) { DirAccess *da = DirAccess::open(p_dest_dir); ERR_FAIL_COND_V(!da, ERR_CANT_OPEN); @@ -404,12 +403,14 @@ Error EditorExportPlatformIOS::_export_loading_screens(const Ref<EditorExportPre for (int i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) { LoadingScreenInfo info = loading_screen_infos[i]; String loading_screen_file = p_preset->get(info.preset_key); - Error err = da->copy(loading_screen_file, p_dest_dir + info.export_name); - if (err) { - memdelete(da); - String err_str = String("Failed to export loading screen (") + info.preset_key + ") from path: " + loading_screen_file; - ERR_PRINT(err_str.utf8().get_data()); - return err; + if (loading_screen_file.size() > 0) { + Error err = da->copy(loading_screen_file, p_dest_dir + info.export_name); + if (err) { + memdelete(da); + String err_str = String("Failed to export loading screen (") + info.preset_key + ") from path: " + loading_screen_file; + ERR_PRINT(err_str.utf8().get_data()); + return err; + } } } memdelete(da); @@ -887,7 +888,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p if (err) return err; - err = _export_loading_screens(p_preset, dest_dir + binary_name + "/"); + err = _export_loading_screens(p_preset, dest_dir + binary_name + "/Images.xcassets/LaunchImage.launchimage/"); if (err) return err; diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h index 85376ebc08..0d101eb696 100644 --- a/platform/iphone/gl_view.h +++ b/platform/iphone/gl_view.h @@ -83,6 +83,8 @@ @property(strong, nonatomic) MPMoviePlayerController *moviePlayerController; @property(strong, nonatomic) UIWindow *backgroundWindow; +@property(nonatomic) UITextAutocorrectionType autocorrectionType; + - (void)startAnimation; - (void)stopAnimation; - (void)drawView; diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index 69116c64c6..478a3125af 100644 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -78,6 +78,16 @@ void _hide_keyboard() { keyboard_text = ""; }; +Rect2 _get_ios_window_safe_area(float p_window_width, float p_window_height) { + UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0); + if (_instance != nil && [_instance respondsToSelector:@selector(safeAreaInsets)]) { + insets = [_instance safeAreaInsets]; + } + ERR_FAIL_COND_V(insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0, + Rect2(0, 0, p_window_width, p_window_height)); + return Rect2(insets.left, insets.top, p_window_width - insets.right - insets.left, p_window_height - insets.bottom - insets.top); +} + bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { p_path = ProjectSettings::get_singleton()->globalize_path(p_path); @@ -326,9 +336,7 @@ static void clear_touches() { // Generate IDs for a framebuffer object and a color renderbuffer UIScreen *mainscr = [UIScreen mainScreen]; printf("******** screen size %i, %i\n", (int)mainscr.currentMode.size.width, (int)mainscr.currentMode.size.height); - float minPointSize = MIN(mainscr.bounds.size.width, mainscr.bounds.size.height); - float minScreenSize = MIN(mainscr.currentMode.size.width, mainscr.currentMode.size.height); - self.contentScaleFactor = minScreenSize / minPointSize; + self.contentScaleFactor = mainscr.nativeScale; glGenFramebuffersOES(1, &viewFramebuffer); glGenRenderbuffersOES(1, &viewRenderbuffer); @@ -489,7 +497,7 @@ static void clear_touches() { int tid = get_touch_id(touch); ERR_FAIL_COND(tid == -1); CGPoint touchPoint = [touch locationInView:self]; - OSIPhone::get_singleton()->mouse_button(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1, tid == 0); + OSIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1); }; }; } @@ -506,10 +514,9 @@ static void clear_touches() { continue; int tid = get_touch_id(touch); ERR_FAIL_COND(tid == -1); - int first = get_first_id(touch); CGPoint touchPoint = [touch locationInView:self]; CGPoint prev_point = [touch previousLocationInView:self]; - OSIPhone::get_singleton()->mouse_move(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, first == tid); + OSIPhone::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor); }; }; } @@ -525,9 +532,9 @@ static void clear_touches() { continue; int tid = get_touch_id(touch); ERR_FAIL_COND(tid == -1); - int rem = remove_touch(touch); + remove_touch(touch); CGPoint touchPoint = [touch locationInView:self]; - OSIPhone::get_singleton()->mouse_button(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false, rem == 0); + OSIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false); }; }; } @@ -627,6 +634,7 @@ static void clear_touches() { } init_touches(); self.multipleTouchEnabled = YES; + self.autocorrectionType = UITextAutocorrectionTypeNo; printf("******** adding observer for sound routing changes\n"); [[NSNotificationCenter defaultCenter] diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm index 6fa189e917..2cdd477ed1 100644 --- a/platform/iphone/in_app_store.mm +++ b/platform/iphone/in_app_store.mm @@ -238,6 +238,7 @@ Error InAppStore::restore_purchases() { ret["type"] = "purchase"; ret["result"] = "error"; ret["product_id"] = pid; + ret["error"] = String::utf8([transaction.error.localizedDescription UTF8String]); InAppStore::get_singleton()->_post_event(ret); [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } break; diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index c4c59431f2..f618c80a77 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -190,7 +190,7 @@ void OSIPhone::key(uint32_t p_key, bool p_pressed) { 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) { +void OSIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick) { if (!GLOBAL_DEF("debug/disable_touch", false)) { Ref<InputEventScreenTouch> ev; @@ -202,28 +202,10 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_ queue_event(ev); }; - mouse_list.pressed[p_idx] = p_pressed; - - if (p_use_as_mouse) { - - Ref<InputEventMouseButton> ev; - ev.instance(); - - ev->set_position(Vector2(p_x, p_y)); - ev->set_global_position(Vector2(p_x, p_y)); - - //mouse_list.pressed[p_idx] = p_pressed; - - input->set_mouse_position(ev->get_position()); - ev->set_button_index(BUTTON_LEFT); - ev->set_doubleclick(p_doubleclick); - ev->set_pressed(p_pressed); - - queue_event(ev); - }; + touch_list.pressed[p_idx] = p_pressed; }; -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) { +void OSIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) { if (!GLOBAL_DEF("debug/disable_touch", false)) { @@ -234,21 +216,6 @@ void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_ ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y)); queue_event(ev); }; - - if (p_use_as_mouse) { - Ref<InputEventMouseMotion> ev; - ev.instance(); - - ev->set_position(Vector2(p_x, p_y)); - ev->set_global_position(Vector2(p_x, p_y)); - ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y)); - - input->set_mouse_position(ev->get_position()); - ev->set_speed(input->get_last_mouse_speed()); - ev->set_button_mask(BUTTON_LEFT); // pressed - - queue_event(ev); - }; }; void OSIPhone::queue_event(const Ref<InputEvent> &p_event) { @@ -262,10 +229,10 @@ void OSIPhone::touches_cancelled() { for (int i = 0; i < MAX_MOUSE_COUNT; i++) { - if (mouse_list.pressed[i]) { + if (touch_list.pressed[i]) { // send a mouse_up outside the screen - mouse_button(i, -1, -1, false, false, false); + touch_press(i, -1, -1, false, false); }; }; }; @@ -376,7 +343,7 @@ Point2 OSIPhone::get_mouse_position() const { int OSIPhone::get_mouse_button_state() const { - return mouse_list.pressed[0]; + return 0; }; void OSIPhone::set_window_title(const String &p_title){}; @@ -504,6 +471,12 @@ Size2 OSIPhone::get_window_size() const { return Vector2(video_mode.width, video_mode.height); } +extern Rect2 _get_ios_window_safe_area(float p_window_width, float p_window_height); + +Rect2 OSIPhone::get_window_safe_area() const { + return _get_ios_window_safe_area(video_mode.width, video_mode.height); +} + bool OSIPhone::has_touchscreen_ui_hint() const { return true; diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 2e4458aeed..7d73a6fe5c 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -106,7 +106,7 @@ private: }; }; - MouseList mouse_list; + MouseList touch_list; Vector3 last_accel; @@ -127,8 +127,8 @@ public: uint8_t get_orientations() const; - void mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse); - void mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, bool p_use_as_mouse); + void touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick); + void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y); void touches_cancelled(); void key(uint32_t p_key, bool p_pressed); void set_virtual_keyboard_height(int p_height); @@ -177,6 +177,7 @@ public: virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); virtual Size2 get_window_size() const; + virtual Rect2 get_window_safe_area() const; virtual bool has_touchscreen_ui_hint() const; diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index a275fb7929..1b5463e40d 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -285,23 +285,6 @@ static EM_BOOL _touchpress_callback(int event_type, const EmscriptenTouchEvent * _input->parse_input_event(ev); } - - if (touch_event->touches[lowest_id_index].isChanged) { - - Ref<InputEventMouseButton> ev_mouse; - ev_mouse.instance(); - ev_mouse->set_button_mask(_input->get_mouse_button_mask()); - dom2godot_mod(touch_event, ev_mouse); - - const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index]; - ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY)); - ev_mouse->set_global_position(ev_mouse->get_position()); - - ev_mouse->set_button_index(BUTTON_LEFT); - ev_mouse->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART); - - _input->parse_input_event(ev_mouse); - } return true; } @@ -327,24 +310,6 @@ static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *t _input->parse_input_event(ev); } - - if (touch_event->touches[lowest_id_index].isChanged) { - - Ref<InputEventMouseMotion> ev_mouse; - ev_mouse.instance(); - dom2godot_mod(touch_event, ev_mouse); - ev_mouse->set_button_mask(_input->get_mouse_button_mask()); - - const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index]; - ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY)); - ev_mouse->set_global_position(ev_mouse->get_position()); - - ev_mouse->set_relative(ev_mouse->get_position() - _input->get_mouse_position()); - _input->set_mouse_position(ev_mouse->get_position()); - ev_mouse->set_speed(_input->get_last_mouse_speed()); - - _input->parse_input_event(ev_mouse); - } return true; } diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp index 5ff62b38f9..c18aa36402 100644 --- a/platform/uwp/app.cpp +++ b/platform/uwp/app.cpp @@ -85,8 +85,7 @@ App::App() : mWindowHeight(0), mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT), - mEglSurface(EGL_NO_SURFACE), - number_of_contacts(0) { + mEglSurface(EGL_NO_SURFACE) { } // The first method called when the IFrameworkView is being created. @@ -271,48 +270,44 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor last_touch_y[screen_touch->get_index()] = pos.Y; os->input_event(screen_touch); - if (number_of_contacts > 1) - return; + } else { - }; // fallthrought of sorts - - Ref<InputEventMouseButton> mouse_button; - mouse_button.instance(); - mouse_button->set_device(0); - mouse_button->set_pressed(p_pressed); - mouse_button->set_button_index(but); - mouse_button->set_position(Vector2(pos.X, pos.Y)); - mouse_button->set_global_position(Vector2(pos.X, pos.Y)); - - if (p_is_wheel) { - if (point->Properties->MouseWheelDelta > 0) { - mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP); - } else if (point->Properties->MouseWheelDelta < 0) { - mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN); + Ref<InputEventMouseButton> mouse_button; + mouse_button.instance(); + mouse_button->set_device(0); + mouse_button->set_pressed(p_pressed); + mouse_button->set_button_index(but); + mouse_button->set_position(Vector2(pos.X, pos.Y)); + mouse_button->set_global_position(Vector2(pos.X, pos.Y)); + + if (p_is_wheel) { + if (point->Properties->MouseWheelDelta > 0) { + mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP); + } else if (point->Properties->MouseWheelDelta < 0) { + mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN); + } } - } - last_touch_x[31] = pos.X; - last_touch_y[31] = pos.Y; + last_touch_x[31] = pos.X; + last_touch_y[31] = pos.Y; - os->input_event(mouse_button); - - if (p_is_wheel) { - // Send release for mouse wheel - mouse_button->set_pressed(false); os->input_event(mouse_button); + + if (p_is_wheel) { + // Send release for mouse wheel + mouse_button->set_pressed(false); + os->input_event(mouse_button); + } } }; void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) { - number_of_contacts++; pointer_event(sender, args, true); }; void App::OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) { - number_of_contacts--; pointer_event(sender, args, false); }; @@ -351,7 +346,7 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint; Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os); - if (point->IsInContact && _is_touch(point)) { + if (_is_touch(point)) { Ref<InputEventScreenDrag> screen_drag; screen_drag.instance(); @@ -361,25 +356,23 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()])); os->input_event(screen_drag); - if (number_of_contacts > 1) - return; - - }; // fallthrought of sorts + } else { - // In case the mouse grabbed, MouseMoved will handle this - if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED) - return; + // In case the mouse grabbed, MouseMoved will handle this + if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED) + return; - Ref<InputEventMouseMotion> mouse_motion; - mouse_motion.instance(); - mouse_motion->set_device(0); - mouse_motion->set_position(Vector2(pos.X, pos.Y)); - mouse_motion->set_global_position(Vector2(pos.X, pos.Y)); - mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31])); + Ref<InputEventMouseMotion> mouse_motion; + mouse_motion.instance(); + mouse_motion->set_device(0); + mouse_motion->set_position(Vector2(pos.X, pos.Y)); + mouse_motion->set_global_position(Vector2(pos.X, pos.Y)); + mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31])); - last_mouse_pos = pos; + last_mouse_pos = pos; - os->input_event(mouse_motion); + os->input_event(mouse_motion); + } } void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) { diff --git a/platform/uwp/app.h b/platform/uwp/app.h index c23270b8ba..5f69f2cb0e 100644 --- a/platform/uwp/app.h +++ b/platform/uwp/app.h @@ -107,7 +107,6 @@ namespace GodotUWP int last_touch_x[32]; // 20 fingers, index 31 reserved for the mouse int last_touch_y[32]; - int number_of_contacts; Windows::Foundation::Point last_mouse_pos; }; } diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 7d7bee9227..3c537b3b58 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -122,6 +122,14 @@ class AppxPackager { Vector<BlockHash> hashes; uLong file_crc32; ZPOS64_T zip_offset; + + FileMeta() : + lfh_size(0), + compressed(false), + compressed_size(0), + uncompressed_size(0), + file_crc32(0), + zip_offset(0) {} }; String progress_task; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 9c37b65d77..bed5781ae4 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -188,6 +188,10 @@ void OS_Windows::initialize_core() { ticks_start = 0; ticks_start = get_ticks_usec(); + // set minimum resolution for periodic timers, otherwise Sleep(n) may wait at least as + // long as the windows scheduler resolution (~16-30ms) even for calls like Sleep(1) + timeBeginPeriod(1); + process_map = memnew((Map<ProcessID, ProcessInfo>)); IP_Unix::make_default(); @@ -342,6 +346,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; case WM_MOUSEMOVE: { + if (input->is_emulating_mouse_from_touch()) { + // Universal translation enabled; ignore OS translation + LPARAM extra = GetMessageExtraInfo(); + if (IsPenEvent(extra)) { + break; + } + } + if (outside) { //mouse enter @@ -367,18 +379,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode. if (!window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) break; - /* - LPARAM extra = GetMessageExtraInfo(); - if (IsPenEvent(extra)) { - - int idx = extra & 0x7f; - _drag_event(idx, uMsg, wParam, lParam); - if (idx != 0) { - return 0; - }; - // fallthrough for mouse event - }; - */ Ref<InputEventMouseMotion> mm; mm.instance(); @@ -448,18 +448,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) /*case WM_XBUTTONDOWN: case WM_XBUTTONUP: */ { - /* - LPARAM extra = GetMessageExtraInfo(); - if (IsPenEvent(extra)) { - - int idx = extra & 0x7f; - _touch_event(idx, uMsg, wParam, lParam); - if (idx != 0) { - return 0; - }; - // fallthrough for mouse event - }; - */ + if (input->is_emulating_mouse_from_touch()) { + // Universal translation enabled; ignore OS translation + LPARAM extra = GetMessageExtraInfo(); + if (IsPenEvent(extra)) { + break; + } + } Ref<InputEventMouseButton> mb; mb.instance(); @@ -1261,6 +1256,8 @@ void OS_Windows::finalize() { void OS_Windows::finalize_core() { + timeEndPeriod(1); + memdelete(process_map); TCPServerWinsock::cleanup(); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 1928800d8c..336068cb1e 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1690,6 +1690,11 @@ void OS_X11::process_xevents() { if (touch.state.has(index)) // Defensive break; touch.state[index] = pos; + if (touch.state.size() == 1) { + // X11 may send a motion event when a touch gesture begins, that would result + // in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out + touch.mouse_pos_to_filter = pos; + } input->parse_input_event(st); } else { if (!touch.state.has(index)) // Defensive @@ -1896,6 +1901,18 @@ void OS_X11::process_xevents() { // to be able to send relative motion events. Point2i pos(event.xmotion.x, event.xmotion.y); + // Avoidance of spurious mouse motion (see handling of touch) + bool filter = false; + // Adding some tolerance to match better Point2i to Vector2 + if (touch.state.size() && Vector2(pos).distance_squared_to(touch.mouse_pos_to_filter) < 2) { + filter = true; + } + // Invalidate to avoid filtering a possible legitimate similar event coming later + touch.mouse_pos_to_filter = Vector2(1e10, 1e10); + if (filter) { + break; + } + if (mouse_mode == MOUSE_MODE_CAPTURED) { if (pos == Point2i(current_videomode.width / 2, current_videomode.height / 2)) { diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 610dba0716..0a39da77de 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -127,6 +127,7 @@ class OS_X11 : public OS_Unix { Vector<int> devices; XIEventMask event_mask; Map<int, Vector2> state; + Vector2 mouse_pos_to_filter; } touch; #endif |