package funkin; import funkin.save.Save; /** * A core class which provides a store of user-configurable, globally relevant values. */ class Preferences { /** * FPS * @default `60` */ public static var framerate(get, set):Int; static function get_framerate():Int { #if web return 60; #else return Save?.instance?.options?.framerate ?? 60; #end } static function set_framerate(value:Int):Int { #if web return 60; #else var save:Save = Save.instance; save.options.framerate = value; save.flush(); FlxG.updateFramerate = value; FlxG.drawFramerate = value; return value; #end } /** * Whether some particularly foul language is displayed. * @default `true` */ public static var naughtyness(get, set):Bool; static function get_naughtyness():Bool { return Save?.instance?.options?.naughtyness; } static function set_naughtyness(value:Bool):Bool { var save:Save = Save.instance; save.options.naughtyness = value; save.flush(); return value; } /** * If enabled, the strumline is at the bottom of the screen rather than the top. * @default `false` */ public static var downscroll(get, set):Bool; static function get_downscroll():Bool { return Save?.instance?.options?.downscroll; } static function set_downscroll(value:Bool):Bool { var save:Save = Save.instance; save.options.downscroll = value; save.flush(); return value; } /** * If disabled, flashing lights in the main menu and other areas will be less intense. * @default `true` */ public static var flashingLights(get, set):Bool; static function get_flashingLights():Bool { return Save?.instance?.options?.flashingLights ?? true; } static function set_flashingLights(value:Bool):Bool { var save:Save = Save.instance; save.options.flashingLights = value; save.flush(); return value; } /** * If disabled, the camera bump synchronized to the beat. * @default `false` */ public static var zoomCamera(get, set):Bool; static function get_zoomCamera():Bool { return Save?.instance?.options?.zoomCamera; } static function set_zoomCamera(value:Bool):Bool { var save:Save = Save.instance; save.options.zoomCamera = value; save.flush(); return value; } /** * If enabled, an FPS and memory counter will be displayed even if this is not a debug build. * @default `false` */ public static var debugDisplay(get, set):Bool; static function get_debugDisplay():Bool { return Save?.instance?.options?.debugDisplay; } static function set_debugDisplay(value:Bool):Bool { if (value != Save.instance.options.debugDisplay) { toggleDebugDisplay(value); } var save = Save.instance; save.options.debugDisplay = value; save.flush(); return value; } /** * If enabled, the game will automatically pause when tabbing out. * @default `true` */ public static var autoPause(get, set):Bool; static function get_autoPause():Bool { return Save?.instance?.options?.autoPause ?? true; } static function set_autoPause(value:Bool):Bool { if (value != Save.instance.options.autoPause) FlxG.autoPause = value; var save:Save = Save.instance; save.options.autoPause = value; save.flush(); return value; } public static var unlockedFramerate(get, set):Bool; static function get_unlockedFramerate():Bool { return Save?.instance?.options?.unlockedFramerate; } static function set_unlockedFramerate(value:Bool):Bool { if (value != Save.instance.options.unlockedFramerate) { #if web toggleFramerateCap(value); #end } var save:Save = Save.instance; save.options.unlockedFramerate = value; save.flush(); return value; } #if web // We create a haxe version of this just for readability. // We use these to override `window.requestAnimationFrame` in Javascript to uncap the framerate / "animation" request rate // Javascript is crazy since u can just do stuff like that lol public static function unlockedFramerateFunction(callback, element) { var currTime = Date.now().getTime(); var timeToCall = 0; var id = js.Browser.window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); return id; } // Lime already implements their own little framerate cap, so we can just use that // This also gets set in the init function in Main.hx, since we need to definitely override it public static var lockedFramerateFunction = untyped js.Syntax.code("window.requestAnimationFrame"); #end /** * Loads the user's preferences from the save data and apply them. */ public static function init():Void { // Apply the autoPause setting (enables automatic pausing on focus lost). FlxG.autoPause = Preferences.autoPause; // Apply the debugDisplay setting (enables the FPS and RAM display). toggleDebugDisplay(Preferences.debugDisplay); #if web toggleFramerateCap(Preferences.unlockedFramerate); #end } static function toggleFramerateCap(unlocked:Bool):Void { #if web var framerateFunction = unlocked ? unlockedFramerateFunction : lockedFramerateFunction; untyped js.Syntax.code("window.requestAnimationFrame = framerateFunction;"); #end } static function toggleDebugDisplay(show:Bool):Void { if (show) { // Enable the debug display. FlxG.stage.addChild(Main.fpsCounter); #if !html5 FlxG.stage.addChild(Main.memoryCounter); #end } else { // Disable the debug display. FlxG.stage.removeChild(Main.fpsCounter); #if !html5 FlxG.stage.removeChild(Main.memoryCounter); #end } } }