From c4e2b900c12771601561a37161c3cce312271cf3 Mon Sep 17 00:00:00 2001 From: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com> Date: Mon, 2 Feb 2026 18:32:49 +0200 Subject: [PATCH] Implement `SDL3` Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com> Co-Authored-By: Karim Akra <144803230+KarimAkra@users.noreply.github.com> --- hmm.json | 8 +- source/Main.hx | 17 +- source/funkin/InitState.hx | 21 ++- source/funkin/Preferences.hx | 60 +++++-- .../external/apple/project/src/ScreenUtil.mm | 43 +++-- source/funkin/external/windows/WinAPI.hx | 47 ----- .../windows/project/include/winapi.hpp | 42 ----- .../external/windows/project/src/winapi.cpp | 67 ------- source/funkin/input/Controls.hx | 2 +- source/funkin/input/PreciseInputManager.hx | 26 +-- source/funkin/mobile/util/FNFCUtil.hx | 2 +- source/funkin/mobile/util/ScreenUtil.hx | 26 ++- source/funkin/save/Save.hx | 2 +- source/funkin/ui/FullScreenScaleMode.hx | 7 +- source/funkin/ui/debug/FunkinDebugDisplay.hx | 46 +++-- .../dialogs/ChartEditorUploadChartDialog.hx | 6 +- .../dialogs/ChartEditorUploadVocalsDialog.hx | 6 +- .../handlers/ChartEditorDialogHandler.hx | 4 +- .../ui/debug/stage/StageBuilderState.hx | 2 +- .../ui/debug/stageeditor/StageEditorState.hx | 2 +- .../components/BackupAvailableDialog.hx | 2 +- .../stageeditor/components/WelcomeDialog.hx | 8 +- source/funkin/ui/options/PreferencesMenu.hx | 26 ++- .../ui/transition/preload/FunkinPreloader.hx | 4 +- source/funkin/util/FileUtil.hx | 168 ++++++++++-------- source/funkin/util/WindowUtil.hx | 50 +----- templates/haxe/ApplicationMain.hx | 23 +-- 27 files changed, 267 insertions(+), 450 deletions(-) diff --git a/hmm.json b/hmm.json index 60216837d..2d0e71bd7 100644 --- a/hmm.json +++ b/hmm.json @@ -52,14 +52,14 @@ "name": "flixel", "type": "git", "dir": null, - "ref": "c8e79d2a42f9c11c639519ef2a6fd7ef2379a8aa", + "ref": "ab6cc8c14878be3a1a918d85668efc3b6a6263f2", "url": "https://github.com/FunkinCrew/flixel" }, { "name": "flixel-addons", "type": "git", "dir": null, - "ref": "6fa30b3f5209146c852c25f3d1003e08898083e2", + "ref": "60e3076e1ed8cc6ad0cad5e72fe3c3d5e91207b7", "url": "https://github.com/FunkinCrew/flixel-addons" }, { @@ -169,7 +169,7 @@ "name": "lime", "type": "git", "dir": null, - "ref": "0125dc5dc1116b65e49c51cf8f2769577e668999", + "ref": "248ea4175a9150320243378107b3820e154f328b", "url": "https://github.com/FunkinCrew/lime" }, { @@ -183,7 +183,7 @@ "name": "openfl", "type": "git", "dir": null, - "ref": "92d7607f309c6c0705456a2e943f1aa0f052463d", + "ref": "0600b18e624aa8054ea86fc795c4d8e5bc004fbe", "url": "https://github.com/FunkinCrew/openfl" }, { diff --git a/source/Main.hx b/source/Main.hx index 51f923c66..c0e0ed3b6 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -177,7 +177,9 @@ class Main extends Sprite // This allows the blend mode shader to work everywhere. untyped FlxG.cameras = new funkin.graphics.FunkinCameraFrontEnd(); - var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, Preferences.framerate, Preferences.framerate, skipSplash, + var framerate:Int = Preferences.unlockedFramerate ? 0 : Preferences.framerate; + + var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash, (FlxG.stage.window.fullscreen || Preferences.autoFullscreen)); // FlxG.game._customSoundTray wants just the class, it calls new from @@ -251,14 +253,7 @@ class Main extends Sprite function repositionCounters(lerp:Bool):Void { // Calling this so it gets scaled based on the resolution of the game and device's resolution. - var scale:Float = Math.min(FlxG.stage.stageWidth / FlxG.width, FlxG.stage.stageHeight / FlxG.height); - - #if android - scale = Math.max(scale, 1); - #else - scale = Math.min(scale, 1); - #end - final thypos:Float = Math.max(FullScreenScaleMode.notchSize.x, 10); + var scale:Float = Math.max(Math.min(FlxG.stage.stageWidth / FlxG.width, FlxG.stage.stageHeight / FlxG.height), 1); if (debugDisplay != null) { @@ -266,13 +261,15 @@ class Main extends Sprite if (FlxG.game != null) { + final thypos:Float = Math.max(FullScreenScaleMode.notchSize.x, 10); + if (lerp) { debugDisplay.x = flixel.math.FlxMath.lerp(debugDisplay.x, FlxG.game.x + thypos, FlxG.elapsed * 3); } else { - debugDisplay.x = FlxG.game.x + FullScreenScaleMode.notchSize.x + 10; + debugDisplay.x = FlxG.game.x + thypos; } debugDisplay.y = FlxG.game.y + (3 * scale); diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index f7c1db7e0..54a959f72 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -311,19 +311,34 @@ class InitState extends FlxState #if FEATURE_LOST_FOCUS_VOLUME @:noCompletion var _lastFocusVolume:Null; - function onLostFocus() + function onLostFocus():Void { if (FlxG.sound.muted || FlxG.sound.volume == 0 || FlxG.autoPause) return; _lastFocusVolume = FlxG.sound.volume; FlxG.sound.volume *= Constants.LOST_FOCUS_VOLUME_MULTIPLIER; } + #end - function onGainFocus() + function onGainFocus():Void { + #if !mobile + if (Preferences.unlockedFramerate) + { + FlxG.updateFramerate = 0; + FlxG.drawFramerate = 0; + } + else + { + FlxG.updateFramerate = Preferences.framerate; + FlxG.drawFramerate = Preferences.framerate; + } + #end + + #if FEATURE_LOST_FOCUS_VOLUME if (FlxG.sound.muted || FlxG.autoPause) return; if (_lastFocusVolume != null) FlxG.sound.volume = _lastFocusVolume; + #end } - #end /** * Start the game. diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index 17d5aceab..c9941abba 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -41,12 +41,23 @@ class Preferences { #if web return 60; + #elseif mobile + var refreshRate:Int = FlxG.stage.window.displayMode.refreshRate; + + if (refreshRate < 60) refreshRate = 60; + + return refreshRate; #else var save:Save = Save.instance; save.options.framerate = value; Save.system.flush(); - FlxG.updateFramerate = value; - FlxG.drawFramerate = value; + + if (!unlockedFramerate) + { + FlxG.updateFramerate = value; + FlxG.drawFramerate = value; + } + return value; #end } @@ -69,13 +80,13 @@ class Preferences static function set_naughtyness(value:Bool):Bool { #if NO_FEATURE_NAUGHTYNESS - value = false; - #end - + return false; + #else var save:Save = Save.instance; save.options.naughtyness = value; Save.system.flush(); return value; + #end } /** @@ -146,8 +157,7 @@ class Preferences { #if NO_FEATURE_DEBUG_DISPLAY return DebugDisplayMode.Off; - #end - + #else #if hl // Account for when debugDisplay used to be a boolean var options:Null = Save.instance?.options; @@ -158,18 +168,22 @@ class Preferences Save.system.flush(); } #end - return Save?.instance?.options?.debugDisplay ?? 'Off'; + #end } static function set_debugDisplay(value:DebugDisplayMode):DebugDisplayMode { + #if NO_FEATURE_DEBUG_DISPLAY + return DebugDisplayMode.Off; + #else if (value != Save.instance.options.debugDisplay) setDebugDisplayMode(value); var save = Save.instance; save.options.debugDisplay = value; Save.system.flush(); return value; + #end } /** @@ -264,18 +278,23 @@ class Preferences { #if mobile return false; - #end + #else return Save?.instance?.options?.autoPause ?? true; + #end } static function set_autoPause(value:Bool):Bool { + #if mobile + return false; + #else if (value != Save.instance.options.autoPause) FlxG.autoPause = value; var save:Save = Save.instance; save.options.autoPause = value; Save.system.flush(); return value; + #end } /** @@ -325,6 +344,9 @@ class Preferences static function get_vsyncMode():lime.ui.WindowVSyncMode { + #if mobile + return lime.ui.WindowVSyncMode.OFF; + #else var value = Save?.instance?.options?.vsyncMode ?? "Off"; return switch (value) @@ -338,10 +360,14 @@ class Preferences default: lime.ui.WindowVSyncMode.OFF; }; + #end } static function set_vsyncMode(value:lime.ui.WindowVSyncMode):lime.ui.WindowVSyncMode { + #if mobile + return lime.ui.WindowVSyncMode.OFF; + #else var string; switch (value) @@ -362,28 +388,35 @@ class Preferences save.options.vsyncMode = string; Save.system.flush(); return value; + #end } public static var unlockedFramerate(get, set):Bool; static function get_unlockedFramerate():Bool { + #if mobile + return false; + #else return Save?.instance?.options?.unlockedFramerate ?? false; + #end } static function set_unlockedFramerate(value:Bool):Bool { + #if mobile + return false; + #else if (value != Save.instance.options.unlockedFramerate) { - #if web toggleFramerateCap(value); - #end } var save:Save = Save.instance; save.options.unlockedFramerate = value; Save.system.flush(); return value; + #end } #if web @@ -496,9 +529,7 @@ class Preferences setDebugDisplayMode(Preferences.debugDisplay); setDebugDisplayBGOpacity(Preferences.debugDisplayBGOpacity / 100); - #if web toggleFramerateCap(Preferences.unlockedFramerate); - #end #if mobile // Apply the allowScreenTimeout setting. @@ -511,6 +542,9 @@ class Preferences #if web var framerateFunction = unlocked ? unlockedFramerateFunction : lockedFramerateFunction; untyped js.Syntax.code("window.requestAnimationFrame = framerateFunction;"); + #else + FlxG.drawFramerate = unlocked ? 0 : framerate; + FlxG.updateFramerate = unlocked ? 0 : framerate; #end } diff --git a/source/funkin/external/apple/project/src/ScreenUtil.mm b/source/funkin/external/apple/project/src/ScreenUtil.mm index f2a960858..d2e204775 100644 --- a/source/funkin/external/apple/project/src/ScreenUtil.mm +++ b/source/funkin/external/apple/project/src/ScreenUtil.mm @@ -11,16 +11,18 @@ void Apple_ScreenUtil_GetSafeAreaInsets(double* top, double* bottom, double* lef #if TARGET_OS_IOS if (@available(iOS 11, *)) { - UIWindow* window = [UIApplication sharedApplication].windows[0]; - UIEdgeInsets safeAreaInsets = window.safeAreaInsets; - float scale = [UIScreen mainScreen].scale; + UIWindow *window = [UIApplication sharedApplication].windows[0]; + if (window) + { + UIEdgeInsets insets = window.safeAreaInsets; + CGFloat scale = window.screen.nativeScale; - (*top) = safeAreaInsets.top * scale; - (*bottom) = safeAreaInsets.bottom * scale; - (*left) = safeAreaInsets.left * scale; - (*right) = safeAreaInsets.right * scale; - - return; + (*top) = (double)(insets.top * scale); + (*bottom) = (double)(insets.bottom * scale); + (*left) = (double)(insets.left * scale); + (*right) = (double)(insets.right * scale); + return; + } } #endif @@ -33,13 +35,22 @@ void Apple_ScreenUtil_GetSafeAreaInsets(double* top, double* bottom, double* lef void Apple_ScreenUtil_GetScreenSize(double* width, double* height) { #if TARGET_OS_IOS - CGRect screenRect = [[UIScreen mainScreen] bounds]; - float scale = [UIScreen mainScreen].scale; + if (@available(iOS 11, *)) + { + UIWindow *window = [UIApplication sharedApplication].windows[0]; + if (window && window.rootViewController) + { + UIView *view = window.rootViewController.view; + CGSize size = view.bounds.size; + CGFloat scale = window.screen.nativeScale; - (*width) = (double)screenRect.size.width * scale; - (*height) = (double)screenRect.size.height * scale; - #else - (*width) = 0.0; - (*width) = 0.0; + (*width) = (double)((int)(size.width * scale)); + (*height) = (double)((int)(size.height * scale)); + return; + } + } #endif + + (*width) = 0.0; + (*height) = 0.0; } diff --git a/source/funkin/external/windows/WinAPI.hx b/source/funkin/external/windows/WinAPI.hx index ffcad68f8..a2b6f16be 100644 --- a/source/funkin/external/windows/WinAPI.hx +++ b/source/funkin/external/windows/WinAPI.hx @@ -8,36 +8,6 @@ package funkin.external.windows; @:include('winapi.hpp') extern class WinAPI { - /** - * Shows a message box with an error icon. - * - * @param handle A handle to the parent window. - * @param message The message to display. - * @param title The title of the message box. - */ - @:native('WINAPI_ShowError') - static function showError(handle:cpp.RawPointer, message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void; - - /** - * Shows a message box with a warning icon. - * - * @param handle A handle to the parent window. - * @param message The message to display. - * @param title The title of the message box. - */ - @:native('WINAPI_ShowWarning') - static function showWarning(handle:cpp.RawPointer, message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void; - - /** - * Shows a message box with an information icon. - * - * @param handle A handle to the parent window. - * @param message The message to display. - * @param title The title of the message box. - */ - @:native('WINAPI_ShowInformation') - static function showInformation(handle:cpp.RawPointer, message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void; - /** * Disables the "Report to Microsoft" dialog that appears when the application crashes. */ @@ -57,22 +27,5 @@ extern class WinAPI */ @:native('WINAPI_GetProcessMemoryWorkingSetSize') static function getProcessMemoryWorkingSetSize():cpp.SizeT; - - /** - * Sets the dark mode for the active window. - * - * @param handle A handle to the parent window. - * @param enable Whether to enable or disable dark mode. - */ - @:native('WINAPI_SetDarkMode') - static function setDarkMode(handle:cpp.RawPointer, enable:Bool):Void; - - /** - * Checks if the system is using dark mode. - * - * @return True if system is in dark mode, false otherwise. - */ - @:native('WINAPI_IsSystemDarkMode') - static function isSystemDarkMode():Bool; } #end diff --git a/source/funkin/external/windows/project/include/winapi.hpp b/source/funkin/external/windows/project/include/winapi.hpp index 9c6a3ce1c..f0ebadd06 100644 --- a/source/funkin/external/windows/project/include/winapi.hpp +++ b/source/funkin/external/windows/project/include/winapi.hpp @@ -1,32 +1,5 @@ #pragma once -/** - * Shows an error message box. - * - * @param handle A handle to the parent window - * @param message The error message to display - * @param title The title of the message box - */ -void WINAPI_ShowError(void* handle, const char *message, const char *title); - -/** - * Shows a warning message box. - * - * @param handle A handle to the parent window - * @param message The warning message to display - * @param title The title of the message box - */ -void WINAPI_ShowWarning(void* handle, const char *message, const char *title); - -/** - * Shows an information message box. - * - * @param handle A handle to the parent window - * @param message The information message to display - * @param title The title of the message box - */ -void WINAPI_ShowInformation(void* handle, const char *message, const char *title); - /** * Disables Windows error reporting dialogs. */ @@ -45,18 +18,3 @@ void WINAPI_DisableWindowsGhosting(); * @return The working set size in bytes. Returns 0 if the query fails. */ size_t WINAPI_GetProcessMemoryWorkingSetSize(); - -/** - * Sets dark mode on a window - * @param handle A handle to the parent window. - * - * @param enable True to enable dark mode, false to disable - */ -void WINAPI_SetDarkMode(void* handle, bool enable); - -/** - * Checks if the system is using dark mode. - * - * @return True if system is in dark mode, false otherwise - */ -bool WINAPI_IsSystemDarkMode(); diff --git a/source/funkin/external/windows/project/src/winapi.cpp b/source/funkin/external/windows/project/src/winapi.cpp index 370664b9e..ff27e2b0a 100644 --- a/source/funkin/external/windows/project/src/winapi.cpp +++ b/source/funkin/external/windows/project/src/winapi.cpp @@ -11,37 +11,6 @@ #include #include -void WINAPI_ShowError(void* handle, const char *message, const char *title) -{ - HWND hwnd = (HWND)handle; - - if (!IsWindow(hwnd)) - hwnd = nullptr; - - MessageBox(hwnd, message, title, MB_OK | MB_ICONERROR); -} - -void WINAPI_ShowWarning(void* handle, const char *message, const char *title) -{ - HWND hwnd = (HWND)handle; - - if (!IsWindow(hwnd)) - hwnd = nullptr; - - MessageBox(hwnd, message, title, MB_OK | MB_ICONWARNING); -} - -void WINAPI_ShowInformation(void* handle, const char *message, const char *title) -{ - HWND hwnd = (HWND)handle; - - if (!IsWindow(hwnd)) - hwnd = nullptr; - - MessageBox(hwnd, message, title, MB_OK | MB_ICONINFORMATION); -} - - void WINAPI_DisableErrorReporting() { SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); @@ -61,39 +30,3 @@ size_t WINAPI_GetProcessMemoryWorkingSetSize() return 0; } - -void WINAPI_SetDarkMode(void* handle, bool enable) -{ - HWND hwnd = (HWND)handle; - - if (!IsWindow(hwnd)) - return; - - int darkMode = enable ? 1 : 0; - - if (DwmSetWindowAttribute(hwnd, 20, &darkMode, sizeof(darkMode)) != S_OK) - DwmSetWindowAttribute(hwnd, 19, &darkMode, sizeof(darkMode)); - - UpdateWindow(hwnd); -} - -bool WINAPI_IsSystemDarkMode() -{ - HKEY hKey; - DWORD dwValue = 0; - DWORD dwSize = sizeof(DWORD); - DWORD dwType = REG_DWORD; - - if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) == ERROR_SUCCESS) - { - if (RegQueryValueEx(hKey, "AppsUseLightTheme", NULL, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS) - { - RegCloseKey(hKey); - return dwValue == 0; - } - - RegCloseKey(hKey); - } - - return false; -} diff --git a/source/funkin/input/Controls.hx b/source/funkin/input/Controls.hx index fb89f19e1..5e5a4d4a5 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -1180,7 +1180,7 @@ class FunkinAction extends FlxActionDigital public var nameReleased(default, null):Null; var cache:Map = []; + {timestamp:Float, value:Bool}> = []; public function new(?name:String = "", ?namePressed:String, ?nameReleased:String) { diff --git a/source/funkin/input/PreciseInputManager.hx b/source/funkin/input/PreciseInputManager.hx index 060a4cb97..b860f1c6b 100644 --- a/source/funkin/input/PreciseInputManager.hx +++ b/source/funkin/input/PreciseInputManager.hx @@ -133,11 +133,6 @@ class PreciseInputManager extends FlxKeyManager }; } - /** - * Convert from int to Int64. - */ - static final NS_PER_MS:Int64 = Constants.NS_PER_MS; - /** * Returns a precise timestamp, measured in nanoseconds. * Timestamp is only useful for comparing against other timestamps. @@ -151,11 +146,11 @@ class PreciseInputManager extends FlxKeyManager // NOTE: This timestamp isn't that precise on standard HTML5 builds. // This is because of browser safeguards against timing attacks. // See https://web.dev/coop-coep to enable headers which allow for more precise timestamps. - return haxe.Int64.fromFloat(js.Browser.window.performance.now()) * NS_PER_MS; + return haxe.Int64.fromFloat(js.Browser.window.performance.now()) * Constants.NS_PER_MS; #elseif lime_cffi // NOTE: If the game hard crashes on this line, rebuild Lime! // `lime rebuild windows -clean` - return lime._internal.backend.native.NativeCFFI.lime_sdl_get_ticks() * NS_PER_MS; + return Int64.fromFloat(lime._internal.backend.native.NativeCFFI.lime_system_get_timer()); #else throw "Eric didn't implement precise timestamps on this platform!"; #end @@ -290,11 +285,6 @@ class PreciseInputManager extends FlxKeyManager var key:FlxKey = convertKeyCode(keyCode); if (_keyList.indexOf(key) == -1) return; - // TODO: Remove this line with SDL3 when timestamps change meaning. - // This is because SDL3's timestamps are measured in nanoseconds, not milliseconds. - timestamp *= Constants.NS_PER_MS; // 18126000000 38367000000 - // timestamp -= globalOffset * Constants.NS_PER_MS; - // trace(timestamp); updateKeyStates(key, true); if (getInputByKey(key)?.justPressed ?? false) @@ -313,10 +303,6 @@ class PreciseInputManager extends FlxKeyManager var key:FlxKey = convertKeyCode(keyCode); if (_keyList.indexOf(key) == -1) return; - // TODO: Remove this line with SDL3 when timestamps change meaning. - // This is because SDL3's timestamps ar e measured in nanoseconds, not milliseconds. - timestamp *= Constants.NS_PER_MS; - updateKeyStates(key, false); if (getInputByKey(key)?.justReleased ?? false) @@ -337,10 +323,6 @@ class PreciseInputManager extends FlxKeyManager var buttonListEntry = _buttonList.get(gamepad.id); if (buttonListEntry == null || buttonListEntry.indexOf(buttonId) == -1) return; - // TODO: Remove this line with SDL3 when timestamps change meaning. - // This is because SDL3's timestamps ar e measured in nanoseconds, not milliseconds. - timestamp *= Constants.NS_PER_MS; - updateButtonStates(gamepad, buttonId, true); if (getInputByButton(gamepad, buttonId)?.justPressed ?? false) @@ -361,10 +343,6 @@ class PreciseInputManager extends FlxKeyManager var buttonListEntry = _buttonList.get(gamepad.id); if (buttonListEntry == null || buttonListEntry.indexOf(buttonId) == -1) return; - // TODO: Remove this line with SDL3 when timestamps change meaning. - // This is because SDL3's timestamps ar e measured in nanoseconds, not milliseconds. - timestamp *= Constants.NS_PER_MS; - updateButtonStates(gamepad, buttonId, false); if (getInputByButton(gamepad, buttonId)?.justReleased ?? false) diff --git a/source/funkin/mobile/util/FNFCUtil.hx b/source/funkin/mobile/util/FNFCUtil.hx index 5adefcd0a..a784a81cd 100644 --- a/source/funkin/mobile/util/FNFCUtil.hx +++ b/source/funkin/mobile/util/FNFCUtil.hx @@ -22,7 +22,7 @@ class FNFCUtil onFNFCOpen = new FlxTypedSignalVoid>(); #if ios - FlxG.stage.window.onDropFile.add(function(_) + FlxG.stage.window.onDropFile.add(function(path:String, state:String, x:Float, y:Float):Void { final url = queryFNFC(); if (url != null) getFNFCFromURL(url); diff --git a/source/funkin/mobile/util/ScreenUtil.hx b/source/funkin/mobile/util/ScreenUtil.hx index 4cfd3e092..8bc8c8efd 100644 --- a/source/funkin/mobile/util/ScreenUtil.hx +++ b/source/funkin/mobile/util/ScreenUtil.hx @@ -5,8 +5,9 @@ import funkin.external.apple.ScreenUtil as NativeScreenUtil; #elseif android import funkin.external.android.ScreenUtil as NativeScreenUtil; #end -import lime.math.Rectangle; import lime.system.System; +import lime.app.Application; +import openfl.geom.Rectangle; /** * A Utility class to get mobile screen related informations. @@ -22,6 +23,9 @@ class ScreenUtil { final notchRect:Rectangle = new Rectangle(); + notchRect.x = 0.0; + notchRect.y = 0.0; + #if android final rectDimensions:Array> = [[], [], [], []]; @@ -59,32 +63,24 @@ class ScreenUtil var bottomInset:Float = -1; var deviceWidth:Float = -1; var deviceHeight:Float = -1; - var displayOrientation:DisplayOrientation = System.getDisplayOrientation(0); NativeScreenUtil.getSafeAreaInsets(cpp.RawPointer.addressOf(topInset), cpp.RawPointer.addressOf(bottomInset), cpp.RawPointer.addressOf(leftInset), cpp.RawPointer.addressOf(rightInset)); - NativeScreenUtil.getScreenSize(cpp.RawPointer.addressOf(deviceWidth), cpp.RawPointer.addressOf(deviceHeight)); - notchRect.x = 0; - notchRect.y = 0.0; - // Calculate the rectangle dimensions for the notch // Note: iOS only spits out *insets* for "safe areas", so we can only get a broad position for the notch - // left + right insets are the same, so we can use either // Note: *inset* is the distance from the edge of the screen where a safe area gets defined // see: https://developer.apple.com/documentation/uikit/uiview/safeareainsets - switch (displayOrientation) + switch (System.getDisplayOrientation(Application.current.window.display)) { case DISPLAY_ORIENTATION_LANDSCAPE: // landscape - notchRect.width = leftInset + rightInset; - notchRect.height = bottomInset - topInset; - notchRect.y = topInset; + notchRect.width = leftInset; + notchRect.height = deviceHeight; case DISPLAY_ORIENTATION_LANDSCAPE_FLIPPED: // landscape - notchRect.width = leftInset + rightInset; - notchRect.height = bottomInset - topInset; - notchRect.y = topInset; - notchRect.x = deviceWidth - notchRect.width; // move notchRect if we are flipped, notch is at the right of screen + notchRect.width = leftInset; + notchRect.height = deviceHeight; + notchRect.x = deviceWidth - rightInset; case DISPLAY_ORIENTATION_PORTRAIT: // portrait notchRect.width = deviceWidth; notchRect.height = topInset; diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 11a345fe8..52df067cb 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -1223,7 +1223,7 @@ typedef SaveDataOptions = var audioVisualOffset:Int; /** - * If we want the framerate to be unlocked on HTML5. + * If we want the framerate to be unlocked. * @default `false` */ var unlockedFramerate:Bool; diff --git a/source/funkin/ui/FullScreenScaleMode.hx b/source/funkin/ui/FullScreenScaleMode.hx index db2716866..03d24ad6c 100644 --- a/source/funkin/ui/FullScreenScaleMode.hx +++ b/source/funkin/ui/FullScreenScaleMode.hx @@ -385,7 +385,7 @@ class FullScreenScaleMode extends flixel.system.scaleModes.BaseScaleMode } #if mobile - private function updateDeviceNotch(notch:lime.math.Rectangle):Void + private function updateDeviceNotch(notch:openfl.geom.Rectangle):Void { notchPosition.set(enabled ? notch.x : 0, enabled ? notch.y : 0); notchSize.set(enabled ? notch.width : 0, enabled ? notch.height : 0); @@ -403,11 +403,6 @@ class FullScreenScaleMode extends flixel.system.scaleModes.BaseScaleMode gameNotchPosition *= scale; gameNotchSize *= scale; } - - #if ios - gameNotchPosition /= 2; - gameNotchSize /= 2; - #end } #end diff --git a/source/funkin/ui/debug/FunkinDebugDisplay.hx b/source/funkin/ui/debug/FunkinDebugDisplay.hx index 42f8665de..48927cd88 100644 --- a/source/funkin/ui/debug/FunkinDebugDisplay.hx +++ b/source/funkin/ui/debug/FunkinDebugDisplay.hx @@ -7,13 +7,11 @@ import openfl.display.Shape; import openfl.display.Sprite; import openfl.text.TextField; import openfl.text.TextFormat; +import openfl.Lib; /** * A debug overlay showing useful info. */ -#if lime_cffi -@:access(lime._internal.backend.native.NativeCFFI) -#end class FunkinDebugDisplay extends Sprite { static final UPDATE_DELAY:Int = 100; @@ -31,15 +29,15 @@ class FunkinDebugDisplay extends Sprite */ public var backgroundOpacity(default, set):Float = 0.5; - var currentFPS:Int; var deltaTimeout:Float; var times:Array; var color:Int; + var fps:Int; + var fpsPeak:Int; #if !html5 var gcMem:Float; var gcMemPeak:Float; - var taskMem:Float; var taskMemPeak:Float; #end @@ -58,16 +56,20 @@ class FunkinDebugDisplay extends Sprite this.x = x; this.y = y; - this.currentFPS = 0; + this.deltaTimeout = 0.0; + this.times = []; + this.color = color; + + this.fps = 0; + this.fpsPeak = 0; #if !html5 this.gcMem = 0.0; this.gcMemPeak = 0.0; this.taskMem = 0.0; this.taskMemPeak = 0.0; #end - this.times = []; - this.color = color; + this.backgroundOpacity = 0; this.isAdvanced = false; } @@ -147,15 +149,9 @@ class FunkinDebugDisplay extends Sprite addChild(infoDisplay); } - override function __enterFrame(deltaTime:Int):Void + override function __enterFrame(deltaTime:Float):Void { - #if lime_cffi - final currentTime:Float = lime._internal.backend.native.NativeCFFI.lime_sdl_get_ticks(); - #elseif html5 - final currentTime:Float = js.Browser.window.performance.now(); - #else - final currentTime:Float = haxe.Timer.stamp() * 1000; - #end + final currentTime:Float = Lib.getTimer(); times.push(currentTime); @@ -170,7 +166,9 @@ class FunkinDebugDisplay extends Sprite return; } - currentFPS = times.length; + fps = times.length; + + if (fps > fpsPeak) fpsPeak = fps; #if !html5 gcMem = MemoryUtil.getGCMemory(); @@ -206,7 +204,7 @@ class FunkinDebugDisplay extends Sprite #end final info:Array = []; - info.push('FPS: $currentFPS'); + info.push('FPS: $fps'); info.push('AVG FPS: ${Math.floor(fpsGraph.average())}'); info.push('1% LOW FPS: ${Math.floor(fpsGraph.lowest())}'); fpsGraph.textDisplay.text = info.join('\n'); @@ -227,7 +225,7 @@ class FunkinDebugDisplay extends Sprite { final info:Array = []; - info.push('FPS: $currentFPS'); + info.push('FPS: $fps'); #if !html5 info.push('GC MEM: ${FlxStringUtil.formatBytes(gcMem).toLowerCase()} / ${FlxStringUtil.formatBytes(gcMemPeak).toLowerCase()}'); @@ -240,20 +238,20 @@ class FunkinDebugDisplay extends Sprite } } - function updateFPSGraph(?currentFPS:Int = 0):Void + function updateFPSGraph():Void { - fpsGraph.maxValue = FlxG.drawFramerate; - fpsGraph.update(times.length); + fpsGraph.maxValue = fpsPeak; + fpsGraph.update(fps); } #if !html5 - function updateGcMemGraph(?currentFPS:Int = 0):Void + function updateGcMemGraph():Void { gcMemGraph.maxValue = gcMemPeak; gcMemGraph.update(gcMem); } - function updateTaskMemGraph(?currentFPS:Int = 0):Void + function updateTaskMemGraph():Void { if (taskMemGraph != null) { diff --git a/source/funkin/ui/debug/charting/dialogs/ChartEditorUploadChartDialog.hx b/source/funkin/ui/debug/charting/dialogs/ChartEditorUploadChartDialog.hx index 0c02b3d25..ddfaecdc8 100644 --- a/source/funkin/ui/debug/charting/dialogs/ChartEditorUploadChartDialog.hx +++ b/source/funkin/ui/debug/charting/dialogs/ChartEditorUploadChartDialog.hx @@ -94,12 +94,8 @@ class ChartEditorUploadChartDialog extends ChartEditorBaseDialog if (this.locked) return; this.lock(); - // TODO / BUG: File filtering not working on mac finder dialog, so we don't use it for now - #if !mac + FileUtil.browseForBinaryFile('Open Chart', [FileUtil.FILE_EXTENSION_INFO_FNFC], onSelectFile, onCancelBrowse); - #else - FileUtil.browseForBinaryFile('Open Chart', null, onSelectFile, onCancelBrowse); - #end } /** diff --git a/source/funkin/ui/debug/charting/dialogs/ChartEditorUploadVocalsDialog.hx b/source/funkin/ui/debug/charting/dialogs/ChartEditorUploadVocalsDialog.hx index c6e135912..52da10ead 100644 --- a/source/funkin/ui/debug/charting/dialogs/ChartEditorUploadVocalsDialog.hx +++ b/source/funkin/ui/debug/charting/dialogs/ChartEditorUploadVocalsDialog.hx @@ -210,12 +210,8 @@ class ChartEditorUploadVocalsDialog extends ChartEditorBaseDialog if (this.locked) return; this.lock(); - // TODO / BUG: File filtering not working on mac finder dialog, so we don't use it for now - #if !mac + FileUtil.browseForBinaryFile('Open Chart', [FileUtil.FILE_EXTENSION_INFO_FNFC], onSelectFile, onCancelBrowse); - #else - FileUtil.browseForBinaryFile('Open Chart', null, onSelectFile, onCancelBrowse); - #end } /** diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx index 6176d1dd5..735717895 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx @@ -1268,7 +1268,7 @@ class ChartEditorDialogHandler importBox.onClick = function(_) { // TODO / BUG: File filtering not working on mac finder dialog, so we don't use it for now - Dialogs.openBinaryFile('Import Chart - ${prettyFormat}', #if !mac fileFilter ?? [] #else [] #end, function(selectedFile:SelectedFileInfo) + Dialogs.openBinaryFile('Import Chart - ${prettyFormat}', fileFilter ?? [], function(selectedFile:SelectedFileInfo) { if (selectedFile != null && selectedFile.bytes != null) { @@ -1651,7 +1651,7 @@ class ChartEditorDialogHandler static final EPSILON:Float = 0.01; - static function onDropFile(path:String):Void + static function onDropFile(path:String, state:String, x:Float, y:Float):Void { // a VERY short timer to wait for the mouse position to update new FlxTimer().start(EPSILON, function(_) diff --git a/source/funkin/ui/debug/stage/StageBuilderState.hx b/source/funkin/ui/debug/stage/StageBuilderState.hx index de84bda3d..5cff90dbc 100644 --- a/source/funkin/ui/debug/stage/StageBuilderState.hx +++ b/source/funkin/ui/debug/stage/StageBuilderState.hx @@ -94,7 +94,7 @@ class StageBuilderState extends MusicBeatState hudGrp.add(saveSceneBtn); #if desktop - FlxG.stage.window.onDropFile.add(function(path:String) + FlxG.stage.window.onDropFile.add(function(path:String, state:String, x:Float, y:Float) { trace("DROPPED FILE FROM: " + Std.string(path)); diff --git a/source/funkin/ui/debug/stageeditor/StageEditorState.hx b/source/funkin/ui/debug/stageeditor/StageEditorState.hx index 7ecfae023..ec31c0535 100644 --- a/source/funkin/ui/debug/stageeditor/StageEditorState.hx +++ b/source/funkin/ui/debug/stageeditor/StageEditorState.hx @@ -427,7 +427,7 @@ class StageEditorState extends UIState // Some callbacks. findObjDialog = new FindObjDialog(this, selectedSprite == null ? "" : selectedSprite.name); - FlxG.stage.window.onDropFile.add(function(path:String):Void + FlxG.stage.window.onDropFile.add(function(path:String, state:String, x:Float, y:Float):Void { if (!allowInput || welcomeDialog != null) return; diff --git a/source/funkin/ui/debug/stageeditor/components/BackupAvailableDialog.hx b/source/funkin/ui/debug/stageeditor/components/BackupAvailableDialog.hx index d0e3a8952..05215a91b 100644 --- a/source/funkin/ui/debug/stageeditor/components/BackupAvailableDialog.hx +++ b/source/funkin/ui/debug/stageeditor/components/BackupAvailableDialog.hx @@ -60,7 +60,7 @@ class BackupAvailableDialog extends Dialog { if (FileUtil.fileExists(filePath) && state.welcomeDialog != null) // doing a check in case a sleezy FUCK decides to delete the backup file AFTER dialog opens { - state.welcomeDialog.loadFromFilePath(filePath); + state.welcomeDialog.loadFromFilePath(filePath, null, 0, 0); } hideDialog(DialogButton.APPLY); } diff --git a/source/funkin/ui/debug/stageeditor/components/WelcomeDialog.hx b/source/funkin/ui/debug/stageeditor/components/WelcomeDialog.hx index eedba9c6b..8af2aafbf 100644 --- a/source/funkin/ui/debug/stageeditor/components/WelcomeDialog.hx +++ b/source/funkin/ui/debug/stageeditor/components/WelcomeDialog.hx @@ -45,7 +45,7 @@ class WelcomeDialog extends Dialog fileText.onClick = function(_) { fileText.hide(); - loadFromFilePath(file); + loadFromFilePath(file, null, 0, 0); }; #if sys @@ -59,7 +59,7 @@ class WelcomeDialog extends Dialog } boxDrag.onClick = function(_) FileUtil.browseForBinaryFile("Open Stage Data", [FileUtil.FILE_EXTENSION_INFO_FNFS], - (fileInfo) -> loadFromFilePath(fileInfo.fullPath)); + (fileInfo) -> loadFromFilePath(fileInfo.fullPath, null, 0, 0)); var defaultStages:Array = StageRegistry.instance.listEntryIds(); defaultStages.sort(funkin.util.SortUtil.alphabetically); @@ -106,7 +106,7 @@ class WelcomeDialog extends Dialog killDaDialog(); } - public function loadFromFilePath(file:String) + public function loadFromFilePath(file:String, state:String, x:Float, y:Float) { if (!stageEditorState.saved) { @@ -116,7 +116,7 @@ class WelcomeDialog extends Dialog if (btn == DialogButton.YES) { stageEditorState.saved = true; - loadFromFilePath(file); + loadFromFilePath(file, state, x, y); } }); diff --git a/source/funkin/ui/options/PreferencesMenu.hx b/source/funkin/ui/options/PreferencesMenu.hx index 2c9df6c5a..c0b3ef720 100644 --- a/source/funkin/ui/options/PreferencesMenu.hx +++ b/source/funkin/ui/options/PreferencesMenu.hx @@ -177,15 +177,8 @@ class PreferencesMenu extends Page }, Preferences.autoFullscreen); #end - #if web - createPrefItemCheckbox('Unlocked Framerate', 'When enabled, the framerate is unlocked.', function(value:Bool):Void - { - Preferences.unlockedFramerate = value; - }, Preferences.unlockedFramerate); - #else - // disabled on macos due to "error: Late swap tearing currently unsupported" // disable on mobile since it barely has any effect - #if !(mac || mobile) + #if !mobile createPrefItemEnum('VSync', "When enabled, the game attempts to match the framerate with your monitor's refresh rate.", ["Off" => WindowVSyncMode.OFF, "On" => WindowVSyncMode.ON, "Adaptive" => WindowVSyncMode.ADAPTIVE,], function(key:String, value:WindowVSyncMode):Void { @@ -197,13 +190,16 @@ class PreferencesMenu extends Page case WindowVSyncMode.ON: "On"; case WindowVSyncMode.ADAPTIVE: "Adaptive"; }); - #end - #if !mobile - createPrefItemNumber('FPS', 'The maximum framerate that the game targets.', function(value:Float) - { - Preferences.framerate = Std.int(value); - }, null, Preferences.framerate, 30, 500, 5, 0); - #end + createPrefItemCheckbox('Unlocked Framerate', 'When enabled, the framerate is unlocked.\nThis setting is mutually exclusive with FPS.', + function(value:Bool):Void + { + Preferences.unlockedFramerate = value; + }, Preferences.unlockedFramerate); + createPrefItemNumber('FPS', 'The maximum framerate that the game targets.\nThis setting is mutually exclusive with Unlocked Framerate.', + function(value:Float) + { + Preferences.framerate = Std.int(value); + }, null, Preferences.framerate, 30, 500, 5, 0); #end #if FEATURE_SCREENSHOTS diff --git a/source/funkin/ui/transition/preload/FunkinPreloader.hx b/source/funkin/ui/transition/preload/FunkinPreloader.hx index 27c5f5097..4465b4c70 100644 --- a/source/funkin/ui/transition/preload/FunkinPreloader.hx +++ b/source/funkin/ui/transition/preload/FunkinPreloader.hx @@ -149,7 +149,7 @@ class FunkinPreloader extends FlxBasePreloader // Scale assets to the screen size. // Desktop is always 1:1 scale, mobile needs DPI normalization for consistent positioning #if mobile - var display = lime.system.System.getDisplay(0); + var display = Lib.current.stage.window.display; var dpiScale = display.dpi / 160.0; // 160 is Android's baseline DPI var normalizedWidth = this._width / dpiScale; ratio = normalizedWidth / BASE_WIDTH; @@ -925,7 +925,7 @@ class FunkinPreloader extends FlxBasePreloader */ function isLandscapeFlipped():Bool { - return lime.system.System.getDisplayOrientation(0) == DISPLAY_ORIENTATION_LANDSCAPE_FLIPPED; + return lime.system.System.getDisplayOrientation(lime.app.Application.current.window.display) == DISPLAY_ORIENTATION_LANDSCAPE_FLIPPED; } function immediatelyStartGame():Void diff --git a/source/funkin/util/FileUtil.hx b/source/funkin/util/FileUtil.hx index cc113c738..becb06e21 100644 --- a/source/funkin/util/FileUtil.hx +++ b/source/funkin/util/FileUtil.hx @@ -3,6 +3,7 @@ package funkin.util; import haxe.zip.Entry; import lime.utils.Bytes; import lime.ui.FileDialog; +import openfl.Lib; import openfl.net.FileFilter; import haxe.io.Path; import openfl.net.FileReference; @@ -159,7 +160,6 @@ class FileUtil /** * Browses for a directory, then calls `onSelect(path)` when a path chosen. - * Note that on HTML5 this will immediately fail. * * @param typeFilter TODO What does this do? * @return Whether the file dialog was opened successfully. @@ -167,19 +167,7 @@ class FileUtil public static function browseForDirectory(?typeFilter:Array, onSelect:(String) -> Void, ?onCancel:() -> Void, ?defaultPath:String, ?dialogTitle:String):Bool { - #if desktop - var filter:Null = convertTypeFilter(typeFilter); - var fileDialog:FileDialog = new FileDialog(); - fileDialog.onSelect.add(onSelect); - if (onCancel != null) - { - fileDialog.onCancel.add(onCancel); - } - - fileDialog.browse(OPEN_DIRECTORY, filter, defaultPath, dialogTitle); - - return true; - #else + #if html5 trace('WARNING: browseForDirectory not implemented for this platform'); if (onCancel != null) @@ -188,6 +176,26 @@ class FileUtil } return false; + #else + FileDialog.openDirectory(Lib.current.stage.window, function(filepaths:Array):Void + { + if (filepaths.length > 0) + { + if (onSelect != null) + { + onSelect(filepaths[0]); + } + } + else + { + if (onCancel != null) + { + onCancel(); + } + } + }, defaultPath, false); + + return true; #end } @@ -200,19 +208,7 @@ class FileUtil public static function browseForMultipleFiles(?typeFilter:Array, onSelect:(Array) -> Void, ?onCancel:() -> Void, ?defaultPath:String, ?dialogTitle:String):Bool { - #if desktop - var filter:Null = convertTypeFilter(typeFilter); - var fileDialog:FileDialog = new FileDialog(); - fileDialog.onSelectMultiple.add(onSelect); - if (onCancel != null) - { - fileDialog.onCancel.add(onCancel); - } - - fileDialog.browse(OPEN_MULTIPLE, filter, defaultPath, dialogTitle); - - return true; - #else + #if html5 trace('WARNING: browseForMultipleFiles not implemented for this platform'); if (onCancel != null) @@ -221,12 +217,32 @@ class FileUtil } return false; + #else + FileDialog.openFile(Lib.current.stage.window, function(filepaths:Array, filter):Void + { + if (filepaths.length > 0) + { + if (onSelect != null) + { + onSelect(filepaths); + } + } + else + { + if (onCancel != null) + { + onCancel(); + } + } + }, @:privateAccess openfl.filesystem.File.__getFilterTypes(typeFilter ?? []), + defaultPath, true); + + return true; #end } /** * Browses for a file location to save to, then calls `onSave(path)` when a path chosen. - * Note that on HTML5 you can't do much with this, you should call `saveFile(resource:haxe.io.Bytes)` instead. * * @param typeFilter TODO What does this do? * @return Whether the file dialog was opened successfully. @@ -234,19 +250,7 @@ class FileUtil public static function browseForSaveFile(?typeFilter:Array, onSelect:(String) -> Void, ?onCancel:() -> Void, ?defaultPath:String, ?dialogTitle:String):Bool { - #if desktop - var filter:Null = convertTypeFilter(typeFilter); - var fileDialog:FileDialog = new FileDialog(); - fileDialog.onSelect.add(onSelect); - if (onCancel != null) - { - fileDialog.onCancel.add(onCancel); - } - - fileDialog.browse(SAVE, filter, defaultPath, dialogTitle); - - return true; - #else + #if html5 trace('WARNING: browseForSaveFile not implemented for this platform'); if (onCancel != null) @@ -255,6 +259,25 @@ class FileUtil } return false; + #else + FileDialog.saveFile(Lib.current.stage.window, function(filepath:String, filter):Void + { + if (filepath != null) + { + if (onSelect != null) + { + onSelect(filepath); + } + } + else + { + if (onCancel != null) + { + onCancel(); + } + } + }, @:privateAccess openfl.filesystem.File.__getFilterTypes(typeFilter ?? []), defaultPath); + return true; #end } @@ -267,39 +290,7 @@ class FileUtil public static function saveFile(data:Bytes, ?typeFilter:Array, ?onSave:(String) -> Void, ?onCancel:() -> Void, ?defaultFileName:String, ?dialogTitle:String):Bool { - #if desktop - var filter:Null = convertTypeFilter(typeFilter); - var fileDialog:FileDialog = new FileDialog(); - if (onSave != null) - { - fileDialog.onSave.add(onSave); - } - - if (onCancel != null) - { - fileDialog.onCancel.add(onCancel); - } - - fileDialog.save(data, filter, defaultFileName, dialogTitle); - - return true; - #elseif html5 - var filter:Null = defaultFileName != null ? Path.extension(defaultFileName) : null; - var fileDialog:FileDialog = new FileDialog(); - if (onSave != null) - { - fileDialog.onSave.add(onSave); - } - - if (onCancel != null) - { - fileDialog.onCancel.add(onCancel); - } - - fileDialog.save(data, filter, defaultFileName, dialogTitle); - - return true; - #else + #if html5 trace('WARNING: saveFile not implemented for this platform'); if (onCancel != null) @@ -308,6 +299,32 @@ class FileUtil } return false; + #else + FileDialog.saveFile(Lib.current.stage.window, function(filepath:String, filter):Void + { + if (filepath != null) + { + if (data != null) + { + Bytes.toFile(filepath, data); + } + + if (onSave != null) + { + onSave(filepath); + } + } + else + { + if (onCancel != null) + { + onCancel(); + } + } + }, @:privateAccess openfl.filesystem.File.__getFilterTypes(typeFilter ?? []), + defaultFileName); + + return true; #end } @@ -1236,8 +1253,7 @@ class FileUtil /** * Utilities for reading and writing files on various platforms. * Wrapper for `FileUtil` that sanitizes paths for script safety. - */ -@:nullSafety + */ @:nullSafety class FileUtilSandboxed { /** diff --git a/source/funkin/util/WindowUtil.hx b/source/funkin/util/WindowUtil.hx index ff2fa69bd..7a50439a5 100644 --- a/source/funkin/util/WindowUtil.hx +++ b/source/funkin/util/WindowUtil.hx @@ -155,15 +155,7 @@ class WindowUtil */ public static function showError(name:String, desc:String):Void { - #if (windows && cpp) - final handleVal:Float = lime.app.Application.current.window.nativeHandle; - - final handlePtr:cpp.RawPointer = untyped __cpp__('(void*)(uintptr_t){0}', handleVal); - - funkin.external.windows.WinAPI.showError(handlePtr, desc, name); - #else - lime.app.Application.current.window.alert(desc, name); - #end + lime.app.Application.current.window.alert(lime.ui.MessageBoxType.ERROR, desc, name); } /** @@ -173,15 +165,7 @@ class WindowUtil */ public static function showWarning(name:String, desc:String):Void { - #if (windows && cpp) - final handleVal:Float = lime.app.Application.current.window.nativeHandle; - - final handlePtr:cpp.RawPointer = untyped __cpp__('(void*)(uintptr_t){0}', handleVal); - - funkin.external.windows.WinAPI.showWarning(handlePtr, desc, name); - #else - lime.app.Application.current.window.alert(desc, name); - #end + lime.app.Application.current.window.alert(lime.ui.MessageBoxType.WARNING, desc, name); } /** @@ -191,38 +175,11 @@ class WindowUtil */ public static function showInformation(name:String, desc:String):Void { - #if (windows && cpp) - final handleVal:Float = lime.app.Application.current.window.nativeHandle; - - final handlePtr:cpp.RawPointer = untyped __cpp__('(void*)(uintptr_t){0}', handleVal); - - funkin.external.windows.WinAPI.showInformation(handlePtr, desc, name); - #else - lime.app.Application.current.window.alert(desc, name); - #end - } - - /** - * Sets the dark mode appearance for the specified window. - * - * @param window The window instance to modify. - * @param value Whether to enable (`true`) or disable (`false`) dark mode. - */ - public static function setDarkMode(window:lime.ui.Window, value:Bool):Void - { - #if (windows && cpp) - final handleVal:Float = window.nativeHandle; - - final handlePtr:cpp.RawPointer = untyped __cpp__('(void*)(uintptr_t){0}', handleVal); - - funkin.external.windows.WinAPI.setDarkMode(handlePtr, value); - #end + lime.app.Application.current.window.alert(lime.ui.MessageBoxType.INFORMATION, desc, name); } public static function setVSyncMode(value:lime.ui.WindowVSyncMode):Void { - // vsync crap dont worky on mac rn derp - #if !mac var res:Bool = FlxG.stage.application.window.setVSyncMode(value); // SDL_GL_SetSwapInterval returns the value we assigned on success, https://wiki.libsdl.org/SDL2/SDL_GL_GetSwapInterval#return-value. @@ -232,6 +189,5 @@ class WindowUtil trace('Failed to set VSync mode to ' + value); FlxG.stage.application.window.setVSyncMode(lime.ui.WindowVSyncMode.OFF); } - #end } } diff --git a/templates/haxe/ApplicationMain.hx b/templates/haxe/ApplicationMain.hx index b0d2d8673..eef8180d0 100644 --- a/templates/haxe/ApplicationMain.hx +++ b/templates/haxe/ApplicationMain.hx @@ -28,10 +28,6 @@ class ApplicationMain { #if !macro - #if (windows && cpp) - public static var systemDarkMode:Bool = false; - #end - public static function main():Void { #if (windows && cpp) @@ -40,9 +36,6 @@ class ApplicationMain // Disable Windows error reporting (avoids sending bug reports to Microsoft). funkin.external.windows.WinAPI.disableErrorReporting(); - - // Whether the system is currently using dark mode. - systemDarkMode = funkin.external.windows.WinAPI.isSystemDarkMode(); #end lime.system.System.__registerEntryPoint("::APP_FILE::", create); @@ -62,6 +55,10 @@ class ApplicationMain GamemodeClient.request_start(); #end + ::if (WIN_ORIENTATION != "auto"):: + lime.system.System.setHint("ORIENTATIONS", ::if (WIN_ORIENTATION == "portrait")::"Portrait PortraitUpsideDown"::else::"LandscapeLeft LandscapeRight"::end::); + ::end:: + final appMeta:Map = []; appMeta.set("build", "::meta.buildNumber::"); @@ -78,19 +75,10 @@ class ApplicationMain var app = new openfl.display.Application(appMeta); - #if ((windows && cpp) || linux) + #if linux app.onCreateWindow.add(function(window:lime.ui.Window):Void { - #if (windows && cpp) - if (systemDarkMode) - { - window.setDarkMode(systemDarkMode); - } - #end - - #if linux window.setIcon(new ApplicationIcon()); - #end }); #end @@ -103,6 +91,7 @@ class ApplicationMain var attributes:lime.ui.WindowAttributes = { allowHighDPI: ::allowHighDPI::, alwaysOnTop: ::alwaysOnTop::, + transparent: ::transparent::, borderless: ::borderless::, // display: ::display::, element: null,