diff options
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/android/os_android.cpp | 2 | ||||
| -rw-r--r-- | platform/iphone/ios.h | 11 | ||||
| -rw-r--r-- | platform/iphone/ios.mm | 99 | ||||
| -rw-r--r-- | platform/iphone/os_iphone.mm | 8 | ||||
| -rw-r--r-- | platform/javascript/javascript_singleton.cpp | 2 | ||||
| -rw-r--r-- | platform/linuxbsd/detect.py | 10 | ||||
| -rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 36 |
7 files changed, 148 insertions, 20 deletions
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 54124c22d0..fc46005b41 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -139,7 +139,7 @@ void OS_Android::finalize() { } OS_Android *OS_Android::get_singleton() { - return (OS_Android *)OS::get_singleton(); + return static_cast<OS_Android *>(OS::get_singleton()); } GodotJavaWrapper *OS_Android::get_godot_java() { diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h index 03e663b05c..0607d7b395 100644 --- a/platform/iphone/ios.h +++ b/platform/iphone/ios.h @@ -32,15 +32,26 @@ #define IOS_H #include "core/object/class_db.h" +#import <CoreHaptics/CoreHaptics.h> class iOS : public Object { GDCLASS(iOS, Object); static void _bind_methods(); +private: + CHHapticEngine *haptic_engine API_AVAILABLE(ios(13)) = nullptr; + + CHHapticEngine *get_haptic_engine_instance() API_AVAILABLE(ios(13)); + void start_haptic_engine(); + void stop_haptic_engine(); + public: static void alert(const char *p_alert, const char *p_title); + bool supports_haptic_engine(); + void vibrate_haptic_engine(float p_duration_seconds); + String get_model() const; String get_rate_url(int p_app_id) const; diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm index ad1ea70c10..cca28cc055 100644 --- a/platform/iphone/ios.mm +++ b/platform/iphone/ios.mm @@ -32,11 +32,110 @@ #import "app_delegate.h" #import "view_controller.h" + +#import <CoreHaptics/CoreHaptics.h> #import <UIKit/UIKit.h> #include <sys/sysctl.h> void iOS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rate_url", "app_id"), &iOS::get_rate_url); + ClassDB::bind_method(D_METHOD("supports_haptic_engine"), &iOS::supports_haptic_engine); + ClassDB::bind_method(D_METHOD("start_haptic_engine"), &iOS::start_haptic_engine); + ClassDB::bind_method(D_METHOD("stop_haptic_engine"), &iOS::stop_haptic_engine); +}; + +bool iOS::supports_haptic_engine() { + if (@available(iOS 13, *)) { + id<CHHapticDeviceCapability> capabilities = [CHHapticEngine capabilitiesForHardware]; + return capabilities.supportsHaptics; + } + + return false; +} + +CHHapticEngine *iOS::get_haptic_engine_instance() API_AVAILABLE(ios(13)) { + if (haptic_engine == nullptr) { + NSError *error = nullptr; + haptic_engine = [[CHHapticEngine alloc] initAndReturnError:&error]; + + if (!error) { + [haptic_engine setAutoShutdownEnabled:true]; + } else { + haptic_engine = nullptr; + NSLog(@"Could not initialize haptic engine: %@", error); + } + } + + return haptic_engine; +} + +void iOS::vibrate_haptic_engine(float p_duration_seconds) API_AVAILABLE(ios(13)) { + if (@available(iOS 13, *)) { // We need the @available check every time to make the compiler happy... + if (supports_haptic_engine()) { + CHHapticEngine *haptic_engine = get_haptic_engine_instance(); + if (haptic_engine) { + NSDictionary *hapticDict = @{ + CHHapticPatternKeyPattern : @[ + @{CHHapticPatternKeyEvent : @{ + CHHapticPatternKeyEventType : CHHapticEventTypeHapticTransient, + CHHapticPatternKeyTime : @(CHHapticTimeImmediate), + CHHapticPatternKeyEventDuration : @(p_duration_seconds) + }, + }, + ], + }; + + NSError *error; + CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithDictionary:hapticDict error:&error]; + + [[haptic_engine createPlayerWithPattern:pattern error:&error] startAtTime:0 error:&error]; + + NSLog(@"Could not vibrate using haptic engine: %@", error); + } + + return; + } + } + + NSLog(@"Haptic engine is not supported in this version of iOS"); +} + +void iOS::start_haptic_engine() { + if (@available(iOS 13, *)) { + if (supports_haptic_engine()) { + CHHapticEngine *haptic_engine = get_haptic_engine_instance(); + if (haptic_engine) { + [haptic_engine startWithCompletionHandler:^(NSError *returnedError) { + if (returnedError) { + NSLog(@"Could not start haptic engine: %@", returnedError); + } + }]; + } + + return; + } + } + + NSLog(@"Haptic engine is not supported in this version of iOS"); +} + +void iOS::stop_haptic_engine() { + if (@available(iOS 13, *)) { + if (supports_haptic_engine()) { + CHHapticEngine *haptic_engine = get_haptic_engine_instance(); + if (haptic_engine) { + [haptic_engine stopWithCompletionHandler:^(NSError *returnedError) { + if (returnedError) { + NSLog(@"Could not stop haptic engine: %@", returnedError); + } + }]; + } + + return; + } + } + + NSLog(@"Haptic engine is not supported in this version of iOS"); } void iOS::alert(const char *p_alert, const char *p_title) { diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index ea1bc0ef64..f7974c4b3d 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -298,8 +298,12 @@ String OSIPhone::get_processor_name() const { } void OSIPhone::vibrate_handheld(int p_duration_ms) { - // iOS does not support duration for vibration - AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); + if (ios->supports_haptic_engine()) { + ios->vibrate_haptic_engine((float)p_duration_ms / 1000.f); + } else { + // iOS <13 does not support duration for vibration + AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); + } } bool OSIPhone::_check_internal_feature_support(const String &p_feature) { diff --git a/platform/javascript/javascript_singleton.cpp b/platform/javascript/javascript_singleton.cpp index c9c4d6e1b9..8dc7aba5f8 100644 --- a/platform/javascript/javascript_singleton.cpp +++ b/platform/javascript/javascript_singleton.cpp @@ -207,7 +207,7 @@ int JavaScriptObjectImpl::_variant2js(const void **p_args, int p_pos, godot_js_w break; case Variant::INT: { const int64_t tmp = v->operator int64_t(); - if (tmp >= 1 << 31) { + if (tmp >= 1LL << 31) { r_val->r = (double)tmp; return Variant::FLOAT; } diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 39f9b99108..2fba58fc53 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -319,20 +319,21 @@ def configure(env): if os.system("pkg-config --exists alsa") == 0: # 0 means found env["alsa"] = True env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) + env.ParseConfig("pkg-config alsa --cflags") # Only cflags, we dlopen the library. else: print("Warning: ALSA libraries not found. Disabling the ALSA audio driver.") if env["pulseaudio"]: if os.system("pkg-config --exists libpulse") == 0: # 0 means found env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"]) - env.ParseConfig("pkg-config --cflags libpulse") + env.ParseConfig("pkg-config libpulse --cflags") # Only cflags, we dlopen the library. else: print("Warning: PulseAudio development libraries not found. Disabling the PulseAudio audio driver.") if env["dbus"]: if os.system("pkg-config --exists dbus-1") == 0: # 0 means found env.Append(CPPDEFINES=["DBUS_ENABLED"]) - env.ParseConfig("pkg-config --cflags --libs dbus-1") + env.ParseConfig("pkg-config dbus-1 --cflags --libs") else: print("Warning: D-Bus development libraries not found. Disabling screensaver prevention.") @@ -341,6 +342,7 @@ def configure(env): if env["udev"]: if os.system("pkg-config --exists libudev") == 0: # 0 means found env.Append(CPPDEFINES=["UDEV_ENABLED"]) + env.ParseConfig("pkg-config libudev --cflags") # Only cflags, we dlopen the library. else: print("Warning: libudev development libraries not found. Disabling controller hotplugging support.") else: @@ -366,11 +368,11 @@ def configure(env): if not env["use_volk"]: env.ParseConfig("pkg-config vulkan --cflags --libs") if not env["builtin_glslang"]: - # No pkgconfig file for glslang so far + # No pkgconfig file so far, hardcode expected lib name. env.Append(LIBS=["glslang", "SPIRV"]) env.Append(CPPDEFINES=["GLES3_ENABLED"]) - env.Append(LIBS=["GL"]) + env.ParseConfig("pkg-config gl --cflags --libs") env.Append(LIBS=["pthread"]) diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 7da30ac363..a36fcabd91 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -670,17 +670,17 @@ void DisplayServerX11::_clipboard_transfer_ownership(Atom p_source, Window x11_w int DisplayServerX11::get_screen_count() const { _THREAD_SAFE_METHOD_ + int count = 0; // Using Xinerama Extension int event_base, error_base; - const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); - if (!ext_okay) { - return 0; + if (XineramaQueryExtension(x11_display, &event_base, &error_base)) { + XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count); + XFree(xsi); + } else { + count = XScreenCount(x11_display); } - int count; - XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count); - XFree(xsi); return count; } @@ -712,6 +712,19 @@ Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const { if (xsi) { XFree(xsi); } + } else { + int count = XScreenCount(x11_display); + if (p_screen < count) { + Window root = XRootWindow(x11_display, p_screen); + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, root, &xwa); + rect.position.x = xwa.x; + rect.position.y = xwa.y; + rect.size.width = xwa.width; + rect.size.height = xwa.height; + } else { + ERR_PRINT("Invalid screen index: " + itos(p_screen) + "(count: " + itos(count) + ")."); + } } return rect; @@ -2130,7 +2143,7 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co unsigned char *data = nullptr; if (XGetWindowProperty(x11_display, wd.x11_window, prop, 0, sizeof(Hints), False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { if (data && (format == 32) && (len >= 5)) { - borderless = !((Hints *)data)->decorations; + borderless = !(reinterpret_cast<Hints *>(data)->decorations); } if (data) { XFree(data); @@ -2162,7 +2175,7 @@ void DisplayServerX11::window_request_attention(WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); - WindowData &wd = windows[p_window]; + const WindowData &wd = windows[p_window]; // Using EWMH -- Extended Window Manager Hints // // Sets the _NET_WM_STATE_DEMANDS_ATTENTION atom for WM_STATE @@ -2188,7 +2201,7 @@ void DisplayServerX11::window_move_to_foreground(WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); - WindowData &wd = windows[p_window]; + const WindowData &wd = windows[p_window]; XEvent xev; Atom net_active_window = XInternAtom(x11_display, "_NET_ACTIVE_WINDOW", False); @@ -2534,10 +2547,9 @@ DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, unsigned long bytes_after = 0; unsigned char *ret = nullptr; - int read_bytes = 1024; - // Keep trying to read the property until there are no bytes unread. if (p_property != None) { + int read_bytes = 1024; do { if (ret != nullptr) { XFree(ret); @@ -2557,7 +2569,7 @@ DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, return p; } -static Atom pick_target_from_list(Display *p_display, Atom *p_list, int p_count) { +static Atom pick_target_from_list(Display *p_display, const Atom *p_list, int p_count) { static const char *target_type = "text/uri-list"; for (int i = 0; i < p_count; i++) { |