diff --git a/assets/preload/images/fonts/bold.fla b/assets/preload/images/fonts/bold.fla index b6d6dcae0..f98b5865c 100644 Binary files a/assets/preload/images/fonts/bold.fla and b/assets/preload/images/fonts/bold.fla differ diff --git a/assets/preload/images/fonts/bold.png b/assets/preload/images/fonts/bold.png index 0fe4e4af3..a8d80f55b 100644 Binary files a/assets/preload/images/fonts/bold.png and b/assets/preload/images/fonts/bold.png differ diff --git a/assets/preload/images/fonts/bold.xml b/assets/preload/images/fonts/bold.xml index 18b6fd24f..0d3578fed 100644 --- a/assets/preload/images/fonts/bold.xml +++ b/assets/preload/images/fonts/bold.xml @@ -2,108 +2,256 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/Controls.hx b/source/Controls.hx index bb24d7883..c864cc918 100644 --- a/source/Controls.hx +++ b/source/Controls.hx @@ -11,45 +11,33 @@ import flixel.input.gamepad.FlxGamepadButton; import flixel.input.gamepad.FlxGamepadInputID; import flixel.input.keyboard.FlxKey; -#if (haxe >= "4.0.0") -enum abstract Action(String) to String from String -{ - var UP = "up"; - var LEFT = "left"; - var RIGHT = "right"; - var DOWN = "down"; - var UP_P = "up-press"; - var LEFT_P = "left-press"; - var RIGHT_P = "right-press"; - var DOWN_P = "down-press"; - var UP_R = "up-release"; - var LEFT_R = "left-release"; - var RIGHT_R = "right-release"; - var DOWN_R = "down-release"; - var ACCEPT = "accept"; - var BACK = "back"; - var PAUSE = "pause"; - var RESET = "reset"; - #if CAN_CHEAT - var CHEAT = "cheat"; - #end -} -#else @:enum abstract Action(String) to String from String { - var UP = "up"; - var LEFT = "left"; - var RIGHT = "right"; - var DOWN = "down"; - var UP_P = "up-press"; - var LEFT_P = "left-press"; - var RIGHT_P = "right-press"; - var DOWN_P = "down-press"; - var UP_R = "up-release"; - var LEFT_R = "left-release"; - var RIGHT_R = "right-release"; - var DOWN_R = "down-release"; + var UI_UP = "ui_up"; + var UI_LEFT = "ui_left"; + var UI_RIGHT = "ui_right"; + var UI_DOWN = "ui_down"; + var UI_UP_P = "ui_up-press"; + var UI_LEFT_P = "ui_left-press"; + var UI_RIGHT_P = "ui_right-press"; + var UI_DOWN_P = "ui_down-press"; + var UI_UP_R = "ui_up-release"; + var UI_LEFT_R = "ui_left-release"; + var UI_RIGHT_R = "ui_right-release"; + var UI_DOWN_R = "ui_down-release"; + var NOTE_UP = "note_up"; + var NOTE_LEFT = "note_left"; + var NOTE_RIGHT = "note_right"; + var NOTE_DOWN = "note_down"; + var NOTE_UP_P = "note_up-press"; + var NOTE_LEFT_P = "note_left-press"; + var NOTE_RIGHT_P = "note_right-press"; + var NOTE_DOWN_P = "note_down-press"; + var NOTE_UP_R = "note_up-release"; + var NOTE_LEFT_R = "note_left-release"; + var NOTE_RIGHT_R = "note_right-release"; + var NOTE_DOWN_R = "note_down-release"; var ACCEPT = "accept"; var BACK = "back"; var PAUSE = "pause"; @@ -58,7 +46,6 @@ abstract Action(String) to String from String var CHEAT = "cheat"; #end } -#end enum Device { @@ -73,10 +60,14 @@ enum Device */ enum Control { - UP; - LEFT; - RIGHT; - DOWN; + UI_UP; + UI_LEFT; + UI_RIGHT; + UI_DOWN; + NOTE_UP; + NOTE_LEFT; + NOTE_RIGHT; + NOTE_DOWN; RESET; ACCEPT; BACK; @@ -100,18 +91,30 @@ enum KeyboardScheme */ class Controls extends FlxActionSet { - var _up = new FlxActionDigital(Action.UP); - var _left = new FlxActionDigital(Action.LEFT); - var _right = new FlxActionDigital(Action.RIGHT); - var _down = new FlxActionDigital(Action.DOWN); - var _upP = new FlxActionDigital(Action.UP_P); - var _leftP = new FlxActionDigital(Action.LEFT_P); - var _rightP = new FlxActionDigital(Action.RIGHT_P); - var _downP = new FlxActionDigital(Action.DOWN_P); - var _upR = new FlxActionDigital(Action.UP_R); - var _leftR = new FlxActionDigital(Action.LEFT_R); - var _rightR = new FlxActionDigital(Action.RIGHT_R); - var _downR = new FlxActionDigital(Action.DOWN_R); + var _ui_up = new FlxActionDigital(Action.UI_UP); + var _ui_left = new FlxActionDigital(Action.UI_LEFT); + var _ui_right = new FlxActionDigital(Action.UI_RIGHT); + var _ui_down = new FlxActionDigital(Action.UI_DOWN); + var _ui_upP = new FlxActionDigital(Action.UI_UP_P); + var _ui_leftP = new FlxActionDigital(Action.UI_LEFT_P); + var _ui_rightP = new FlxActionDigital(Action.UI_RIGHT_P); + var _ui_downP = new FlxActionDigital(Action.UI_DOWN_P); + var _ui_upR = new FlxActionDigital(Action.UI_UP_R); + var _ui_leftR = new FlxActionDigital(Action.UI_LEFT_R); + var _ui_rightR = new FlxActionDigital(Action.UI_RIGHT_R); + var _ui_downR = new FlxActionDigital(Action.UI_DOWN_R); + var _note_up = new FlxActionDigital(Action.NOTE_UP); + var _note_left = new FlxActionDigital(Action.NOTE_LEFT); + var _note_right = new FlxActionDigital(Action.NOTE_RIGHT); + var _note_down = new FlxActionDigital(Action.NOTE_DOWN); + var _note_upP = new FlxActionDigital(Action.NOTE_UP_P); + var _note_leftP = new FlxActionDigital(Action.NOTE_LEFT_P); + var _note_rightP = new FlxActionDigital(Action.NOTE_RIGHT_P); + var _note_downP = new FlxActionDigital(Action.NOTE_DOWN_P); + var _note_upR = new FlxActionDigital(Action.NOTE_UP_R); + var _note_leftR = new FlxActionDigital(Action.NOTE_LEFT_R); + var _note_rightR = new FlxActionDigital(Action.NOTE_RIGHT_R); + var _note_downR = new FlxActionDigital(Action.NOTE_DOWN_R); var _accept = new FlxActionDigital(Action.ACCEPT); var _back = new FlxActionDigital(Action.BACK); var _pause = new FlxActionDigital(Action.PAUSE); @@ -120,149 +123,77 @@ class Controls extends FlxActionSet var _cheat = new FlxActionDigital(Action.CHEAT); #end - #if (haxe >= "4.0.0") - var byName:Map = []; - #else var byName:Map = new Map(); - #end public var gamepadsAdded:Array = []; public var keyboardScheme = KeyboardScheme.None; - public var UP(get, never):Bool; + public var UI_UP (get, never):Bool; inline function get_UI_UP () return _ui_up .check(); + public var UI_LEFT (get, never):Bool; inline function get_UI_LEFT () return _ui_left .check(); + public var UI_RIGHT(get, never):Bool; inline function get_UI_RIGHT() return _ui_right.check(); + public var UI_DOWN (get, never):Bool; inline function get_UI_DOWN () return _ui_down .check(); - inline function get_UP() - return _up.check(); + public var UI_UP_P (get, never):Bool; inline function get_UI_UP_P () return _ui_upP .check(); + public var UI_LEFT_P (get, never):Bool; inline function get_UI_LEFT_P () return _ui_leftP .check(); + public var UI_RIGHT_P(get, never):Bool; inline function get_UI_RIGHT_P() return _ui_rightP.check(); + public var UI_DOWN_P (get, never):Bool; inline function get_UI_DOWN_P () return _ui_downP .check(); - public var LEFT(get, never):Bool; + public var UI_UP_R (get, never):Bool; inline function get_UI_UP_R () return _ui_upR .check(); + public var UI_LEFT_R (get, never):Bool; inline function get_UI_LEFT_R () return _ui_leftR .check(); + public var UI_RIGHT_R(get, never):Bool; inline function get_UI_RIGHT_R() return _ui_rightR.check(); + public var UI_DOWN_R (get, never):Bool; inline function get_UI_DOWN_R () return _ui_downR .check(); + + public var NOTE_UP (get, never):Bool; inline function get_NOTE_UP () return _note_up .check(); + public var NOTE_LEFT (get, never):Bool; inline function get_NOTE_LEFT () return _note_left .check(); + public var NOTE_RIGHT(get, never):Bool; inline function get_NOTE_RIGHT() return _note_right.check(); + public var NOTE_DOWN (get, never):Bool; inline function get_NOTE_DOWN () return _note_down .check(); - inline function get_LEFT() - return _left.check(); + public var NOTE_UP_P (get, never):Bool; inline function get_NOTE_UP_P () return _note_upP .check(); + public var NOTE_LEFT_P (get, never):Bool; inline function get_NOTE_LEFT_P () return _note_leftP .check(); + public var NOTE_RIGHT_P(get, never):Bool; inline function get_NOTE_RIGHT_P() return _note_rightP.check(); + public var NOTE_DOWN_P (get, never):Bool; inline function get_NOTE_DOWN_P () return _note_downP .check(); - public var RIGHT(get, never):Bool; - - inline function get_RIGHT() - return _right.check(); - - public var DOWN(get, never):Bool; - - inline function get_DOWN() - return _down.check(); - - public var UP_P(get, never):Bool; - - inline function get_UP_P() - return _upP.check(); - - public var LEFT_P(get, never):Bool; - - inline function get_LEFT_P() - return _leftP.check(); - - public var RIGHT_P(get, never):Bool; - - inline function get_RIGHT_P() - return _rightP.check(); - - public var DOWN_P(get, never):Bool; - - inline function get_DOWN_P() - return _downP.check(); - - public var UP_R(get, never):Bool; - - inline function get_UP_R() - return _upR.check(); - - public var LEFT_R(get, never):Bool; - - inline function get_LEFT_R() - return _leftR.check(); - - public var RIGHT_R(get, never):Bool; - - inline function get_RIGHT_R() - return _rightR.check(); - - public var DOWN_R(get, never):Bool; - - inline function get_DOWN_R() - return _downR.check(); - - public var ACCEPT(get, never):Bool; - - inline function get_ACCEPT() - return _accept.check(); - - public var BACK(get, never):Bool; - - inline function get_BACK() - return _back.check(); - - public var PAUSE(get, never):Bool; - - inline function get_PAUSE() - return _pause.check(); - - public var RESET(get, never):Bool; - - inline function get_RESET() - return _reset.check(); + public var NOTE_UP_R (get, never):Bool; inline function get_NOTE_UP_R () return _note_upR .check(); + public var NOTE_LEFT_R (get, never):Bool; inline function get_NOTE_LEFT_R () return _note_leftR .check(); + public var NOTE_RIGHT_R(get, never):Bool; inline function get_NOTE_RIGHT_R() return _note_rightR.check(); + public var NOTE_DOWN_R (get, never):Bool; inline function get_NOTE_DOWN_R () return _note_downR .check(); + public var ACCEPT(get, never):Bool; inline function get_ACCEPT() return _accept.check(); + public var BACK (get, never):Bool; inline function get_BACK () return _back .check(); + public var PAUSE (get, never):Bool; inline function get_PAUSE () return _pause .check(); + public var RESET (get, never):Bool; inline function get_RESET () return _reset .check(); #if CAN_CHEAT - public var CHEAT(get, never):Bool; - - inline function get_CHEAT() - return _cheat.check(); + public var CHEAT (get, never):Bool; inline function get_CHEAT () return _cheat.check (); #end - #if (haxe >= "4.0.0") - public function new(name, scheme = None) - { - super(name); - - add(_up); - add(_left); - add(_right); - add(_down); - add(_upP); - add(_leftP); - add(_rightP); - add(_downP); - add(_upR); - add(_leftR); - add(_rightR); - add(_downR); - add(_accept); - add(_back); - add(_pause); - add(_reset); - #if CAN_CHEAT - add(_cheat); - #end - - for (action in digitalActions) - byName[action.name] = action; - - setKeyboardScheme(scheme, false); - } - #else public function new(name, scheme:KeyboardScheme = null) { super(name); - add(_up); - add(_left); - add(_right); - add(_down); - add(_upP); - add(_leftP); - add(_rightP); - add(_downP); - add(_upR); - add(_leftR); - add(_rightR); - add(_downR); + add(_ui_up); + add(_ui_left); + add(_ui_right); + add(_ui_down); + add(_ui_upP); + add(_ui_leftP); + add(_ui_rightP); + add(_ui_downP); + add(_ui_upR); + add(_ui_leftR); + add(_ui_rightR); + add(_ui_downR); + add(_note_up); + add(_note_left); + add(_note_right); + add(_note_down); + add(_note_upP); + add(_note_leftP); + add(_note_rightP); + add(_note_downP); + add(_note_upR); + add(_note_leftR); + add(_note_rightR); + add(_note_downR); add(_accept); add(_back); add(_pause); @@ -273,12 +204,12 @@ class Controls extends FlxActionSet for (action in digitalActions) byName[action.name] = action; - + if (scheme == null) scheme = None; + setKeyboardScheme(scheme, false); } - #end override function update() { @@ -315,10 +246,14 @@ class Controls extends FlxActionSet { return switch (control) { - case UP: _up; - case DOWN: _down; - case LEFT: _left; - case RIGHT: _right; + case UI_UP: _ui_up; + case UI_DOWN: _ui_down; + case UI_LEFT: _ui_left; + case UI_RIGHT: _ui_right; + case NOTE_UP: _note_up; + case NOTE_DOWN: _note_down; + case NOTE_LEFT: _note_left; + case NOTE_RIGHT: _note_right; case ACCEPT: _accept; case BACK: _back; case PAUSE: _pause; @@ -345,22 +280,38 @@ class Controls extends FlxActionSet { switch (control) { - case UP: - func(_up, PRESSED); - func(_upP, JUST_PRESSED); - func(_upR, JUST_RELEASED); - case LEFT: - func(_left, PRESSED); - func(_leftP, JUST_PRESSED); - func(_leftR, JUST_RELEASED); - case RIGHT: - func(_right, PRESSED); - func(_rightP, JUST_PRESSED); - func(_rightR, JUST_RELEASED); - case DOWN: - func(_down, PRESSED); - func(_downP, JUST_PRESSED); - func(_downR, JUST_RELEASED); + case UI_UP: + func(_ui_up, PRESSED); + func(_ui_upP, JUST_PRESSED); + func(_ui_upR, JUST_RELEASED); + case UI_LEFT: + func(_ui_left, PRESSED); + func(_ui_leftP, JUST_PRESSED); + func(_ui_leftR, JUST_RELEASED); + case UI_RIGHT: + func(_ui_right, PRESSED); + func(_ui_rightP, JUST_PRESSED); + func(_ui_rightR, JUST_RELEASED); + case UI_DOWN: + func(_ui_down, PRESSED); + func(_ui_downP, JUST_PRESSED); + func(_ui_downR, JUST_RELEASED); + case NOTE_UP: + func(_note_up, PRESSED); + func(_note_upP, JUST_PRESSED); + func(_note_upR, JUST_RELEASED); + case NOTE_LEFT: + func(_note_left, PRESSED); + func(_note_leftP, JUST_PRESSED); + func(_note_leftR, JUST_RELEASED); + case NOTE_RIGHT: + func(_note_right, PRESSED); + func(_note_rightP, JUST_PRESSED); + func(_note_rightR, JUST_RELEASED); + case NOTE_DOWN: + func(_note_down, PRESSED); + func(_note_downP, JUST_PRESSED); + func(_note_downR, JUST_RELEASED); case ACCEPT: func(_accept, JUST_PRESSED); case BACK: @@ -399,16 +350,6 @@ class Controls extends FlxActionSet public function copyFrom(controls:Controls, ?device:Device) { - #if (haxe >= "4.0.0") - for (name => action in controls.byName) - { - for (input in action.inputs) - { - if (device == null || isDevice(input, device)) - byName[name].add(cast input); - } - } - #else for (name in controls.byName.keys()) { var action = controls.byName[name]; @@ -418,21 +359,14 @@ class Controls extends FlxActionSet byName[name].add(cast input); } } - #end switch (device) { case null: // add all - #if (haxe >= "4.0.0") - for (gamepad in controls.gamepadsAdded) - if (!gamepadsAdded.contains(gamepad)) - gamepadsAdded.push(gamepad); - #else for (gamepad in controls.gamepadsAdded) if (gamepadsAdded.indexOf(gamepad) == -1) gamepadsAdded.push(gamepad); - #end mergeKeyboardScheme(controls.keyboardScheme); @@ -468,11 +402,7 @@ class Controls extends FlxActionSet */ public function bindKeys(control:Control, keys:Array) { - #if (haxe >= "4.0.0") - inline forEachBound(control, (action, state) -> addKeys(action, keys, state)); - #else forEachBound(control, function(action, state) addKeys(action, keys, state)); - #end } /** @@ -481,11 +411,7 @@ class Controls extends FlxActionSet */ public function unbindKeys(control:Control, keys:Array) { - #if (haxe >= "4.0.0") - inline forEachBound(control, (action, _) -> removeKeys(action, keys)); - #else forEachBound(control, function(action, _) removeKeys(action, keys)); - #end } inline static function addKeys(action:FlxActionDigital, keys:Array, state:FlxInputState) @@ -512,65 +438,43 @@ class Controls extends FlxActionSet keyboardScheme = scheme; - #if (haxe >= "4.0.0") switch (scheme) { case Solo: - inline bindKeys(Control.UP, [W, FlxKey.UP]); - inline bindKeys(Control.DOWN, [S, FlxKey.DOWN]); - inline bindKeys(Control.LEFT, [A, FlxKey.LEFT]); - inline bindKeys(Control.RIGHT, [D, FlxKey.RIGHT]); - inline bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]); - inline bindKeys(Control.BACK, [BACKSPACE, ESCAPE]); - inline bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]); - inline bindKeys(Control.RESET, [R]); - case Duo(true): - inline bindKeys(Control.UP, [W]); - inline bindKeys(Control.DOWN, [S]); - inline bindKeys(Control.LEFT, [A]); - inline bindKeys(Control.RIGHT, [D]); - inline bindKeys(Control.ACCEPT, [G, Z]); - inline bindKeys(Control.BACK, [H, X]); - inline bindKeys(Control.PAUSE, [ONE]); - inline bindKeys(Control.RESET, [R]); - case Duo(false): - inline bindKeys(Control.UP, [FlxKey.UP]); - inline bindKeys(Control.DOWN, [FlxKey.DOWN]); - inline bindKeys(Control.LEFT, [FlxKey.LEFT]); - inline bindKeys(Control.RIGHT, [FlxKey.RIGHT]); - inline bindKeys(Control.ACCEPT, [O]); - inline bindKeys(Control.BACK, [P]); - inline bindKeys(Control.PAUSE, [ENTER]); - inline bindKeys(Control.RESET, [BACKSPACE]); - case None: // nothing - case Custom: // nothing - } - #else - switch (scheme) - { - case Solo: - bindKeys(Control.UP, [W, FlxKey.UP]); - bindKeys(Control.DOWN, [S, FlxKey.DOWN]); - bindKeys(Control.LEFT, [A, FlxKey.LEFT]); - bindKeys(Control.RIGHT, [D, FlxKey.RIGHT]); + bindKeys(Control.UI_UP, [W, FlxKey.UP]); + bindKeys(Control.UI_DOWN, [S, FlxKey.DOWN]); + bindKeys(Control.UI_LEFT, [A, FlxKey.LEFT]); + bindKeys(Control.UI_RIGHT, [D, FlxKey.RIGHT]); + bindKeys(Control.NOTE_UP, [W, FlxKey.UP]); + bindKeys(Control.NOTE_DOWN, [S, FlxKey.DOWN]); + bindKeys(Control.NOTE_LEFT, [A, FlxKey.LEFT]); + bindKeys(Control.NOTE_RIGHT, [D, FlxKey.RIGHT]); bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]); bindKeys(Control.BACK, [BACKSPACE, ESCAPE]); bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]); bindKeys(Control.RESET, [R]); case Duo(true): - bindKeys(Control.UP, [W]); - bindKeys(Control.DOWN, [S]); - bindKeys(Control.LEFT, [A]); - bindKeys(Control.RIGHT, [D]); + bindKeys(Control.UI_UP, [W]); + bindKeys(Control.UI_DOWN, [S]); + bindKeys(Control.UI_LEFT, [A]); + bindKeys(Control.UI_RIGHT, [D]); + bindKeys(Control.NOTE_UP, [W]); + bindKeys(Control.NOTE_DOWN, [S]); + bindKeys(Control.NOTE_LEFT, [A]); + bindKeys(Control.NOTE_RIGHT, [D]); bindKeys(Control.ACCEPT, [G, Z]); bindKeys(Control.BACK, [H, X]); bindKeys(Control.PAUSE, [ONE]); bindKeys(Control.RESET, [R]); case Duo(false): - bindKeys(Control.UP, [FlxKey.UP]); - bindKeys(Control.DOWN, [FlxKey.DOWN]); - bindKeys(Control.LEFT, [FlxKey.LEFT]); - bindKeys(Control.RIGHT, [FlxKey.RIGHT]); + bindKeys(Control.UI_UP, [FlxKey.UP]); + bindKeys(Control.UI_DOWN, [FlxKey.DOWN]); + bindKeys(Control.UI_LEFT, [FlxKey.LEFT]); + bindKeys(Control.UI_RIGHT, [FlxKey.RIGHT]); + bindKeys(Control.NOTE_UP, [FlxKey.UP]); + bindKeys(Control.NOTE_DOWN, [FlxKey.DOWN]); + bindKeys(Control.NOTE_LEFT, [FlxKey.LEFT]); + bindKeys(Control.NOTE_RIGHT, [FlxKey.RIGHT]); bindKeys(Control.ACCEPT, [O]); bindKeys(Control.BACK, [P]); bindKeys(Control.PAUSE, [ENTER]); @@ -578,7 +482,6 @@ class Controls extends FlxActionSet case None: // nothing case Custom: // nothing } - #end } function removeKeyboard() @@ -599,26 +502,16 @@ class Controls extends FlxActionSet { gamepadsAdded.push(id); - #if (haxe >= "4.0.0") - for (control => buttons in buttonMap) - inline bindButtons(control, id, buttons); - #else for (control in buttonMap.keys()) bindButtons(control, id, buttonMap[control]); - #end } inline function addGamepadLiteral(id:Int, ?buttonMap:Map>):Void { gamepadsAdded.push(id); - #if (haxe >= "4.0.0") - for (control => buttons in buttonMap) - inline bindButtons(control, id, buttons); - #else for (control in buttonMap.keys()) bindButtons(control, id, buttonMap[control]); - #end } public function removeGamepad(deviceID:Int = FlxInputDeviceID.ALL):Void @@ -639,34 +532,29 @@ class Controls extends FlxActionSet public function addDefaultGamepad(id):Void { - #if !switch addGamepadLiteral(id, [ - Control.ACCEPT => [A], - Control.BACK => [B], - Control.UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP], - Control.DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN], - Control.LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT], - Control.RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT], - Control.PAUSE => [START], - Control.RESET => [Y] - ]); - #else - addGamepadLiteral(id, [ - //Swap A and B for switch + #if switch Control.ACCEPT => [B], Control.BACK => [A], - Control.UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP], - Control.DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN], - Control.LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT], - Control.RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT], + #else + Control.ACCEPT => [A], + Control.BACK => [B], + #end + Control.UI_UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP], + Control.UI_DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN], + Control.UI_LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT], + Control.UI_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT], + // don't swap A/B or X/Y for switch on these. A is always the bottom face button + Control.NOTE_UP => [DPAD_UP, Y, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP], + Control.NOTE_DOWN => [DPAD_DOWN, A, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN], + Control.NOTE_LEFT => [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT], + Control.NOTE_RIGHT => [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT], Control.PAUSE => [START], - //Swap Y and X for switch - Control.RESET => [Y], + Control.RESET => [Y] #if CAN_CHEAT - Control.CHEAT => [X] + ,Control.CHEAT => [X] #end ]); - #end } /** @@ -675,11 +563,7 @@ class Controls extends FlxActionSet */ public function bindButtons(control:Control, id, buttons) { - #if (haxe >= "4.0.0") - inline forEachBound(control, (action, state) -> addButtons(action, buttons, state, id)); - #else forEachBound(control, function(action, state) addButtons(action, buttons, state, id)); - #end } /** @@ -688,11 +572,7 @@ class Controls extends FlxActionSet */ public function unbindButtons(control:Control, gamepadID:Int, buttons) { - #if (haxe >= "4.0.0") - inline forEachBound(control, (action, _) -> removeButtons(action, gamepadID, buttons)); - #else forEachBound(control, function(action, _) removeButtons(action, gamepadID, buttons)); - #end } inline static function addButtons(action:FlxActionDigital, buttons:Array, state, id) diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 872e44d27..9bf241128 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -166,8 +166,8 @@ class FreeplayState extends MusicBeatState scoreText.text = "PERSONAL BEST:" + lerpScore; - var upP = controls.UP_P; - var downP = controls.DOWN_P; + var upP = controls.UI_UP_P; + var downP = controls.UI_DOWN_P; var accepted = controls.ACCEPT; if (upP) @@ -179,9 +179,9 @@ class FreeplayState extends MusicBeatState changeSelection(1); } - if (controls.LEFT_P) + if (controls.UI_LEFT_P) changeDiff(-1); - if (controls.RIGHT_P) + if (controls.UI_RIGHT_P) changeDiff(1); if (controls.BACK) diff --git a/source/GitarooPause.hx b/source/GitarooPause.hx index cb9705c55..1e9a1c8cd 100644 --- a/source/GitarooPause.hx +++ b/source/GitarooPause.hx @@ -52,7 +52,7 @@ class GitarooPause extends MusicBeatState override function update(elapsed:Float) { - if (controls.LEFT_P || controls.RIGHT_P) + if (controls.UI_LEFT_P || controls.UI_RIGHT_P) changeThing(); if (controls.ACCEPT) diff --git a/source/InputFormatter.hx b/source/InputFormatter.hx index c80c67384..2ace8b0ac 100644 --- a/source/InputFormatter.hx +++ b/source/InputFormatter.hx @@ -148,7 +148,7 @@ class InputFormatter } @:forward -enum abstract ControllerName(String) from String to String +@:enum abstract ControllerName(String) from String to String { var OUYA = "Ouya" ; var PS4 = "PS4" ; diff --git a/source/LoadingState.hx b/source/LoadingState.hx index 23bce2e68..b479250d7 100644 --- a/source/LoadingState.hx +++ b/source/LoadingState.hx @@ -80,7 +80,7 @@ class LoadingState extends MusicBeatState if (!Assets.cache.hasSound(path)) { var library = Assets.getLibrary("songs"); - final symbolPath = path.split(":").pop(); + var symbolPath = path.split(":").pop(); // @:privateAccess // library.types.set(symbolPath, SOUND); // @:privateAccess diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index 26d893b30..0513d82a7 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -24,6 +24,7 @@ import ui.NgPrompt; import ui.AtlasMenuList; import ui.MenuList; +import ui.OptionsState; import ui.Prompt; using StringTools; @@ -80,16 +81,16 @@ class MainMenuState extends MusicBeatState }); - var hasPopupBlocker = #if web true #else false #end; menuItems.enabled = false;// disable for intro menuItems.createItem('story mode', function () startExitState(new StoryMenuState())); menuItems.createItem('freeplay', function () startExitState(new FreeplayState())); // addMenuItem('options', function () startExitState(new OptionMenu())); #if CAN_OPEN_LINKS + var hasPopupBlocker = #if web true #else false #end; menuItems.createItem('donate', selectDonate, hasPopupBlocker); #end - menuItems.createItem('options', function () startExitState(new OptionsMenu())); + menuItems.createItem('options', function () startExitState(new OptionsState())); // #if newgrounds // if (NGio.isLoggedIn) // menuItems.createItem("logout", selectLogout); @@ -136,6 +137,7 @@ class MainMenuState extends MusicBeatState camFollow.setPosition(selected.getGraphicMidpoint().x, selected.getGraphicMidpoint().y); } + #if CAN_OPEN_LINKS function selectDonate() { #if linux @@ -144,6 +146,7 @@ class MainMenuState extends MusicBeatState FlxG.openURL('https://ninja-muffin24.itch.io/funkin'); #end } + #end #if newgrounds function selectLogin() diff --git a/source/OptionsMenu.hx b/source/OptionsMenu_old.hx similarity index 96% rename from source/OptionsMenu.hx rename to source/OptionsMenu_old.hx index c3dc35a09..36cd79d7f 100644 --- a/source/OptionsMenu.hx +++ b/source/OptionsMenu_old.hx @@ -12,14 +12,6 @@ import flixel.text.FlxText; import flixel.util.FlxColor; import lime.utils.Assets; -class OptionsMenu extends MusicBeatState -{ - override function create() - { - add(new ui.ControlsMenu()); - } -} - class OptionsMenu_old extends MusicBeatState { var selector:FlxText; diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index 69bdf6007..7a5d56a38 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -47,7 +47,7 @@ class PauseSubState extends MusicBeatSubstate changeSelection(); - cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; + // cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; } override function update(elapsed:Float) @@ -57,8 +57,8 @@ class PauseSubState extends MusicBeatSubstate super.update(elapsed); - var upP = controls.UP_P; - var downP = controls.DOWN_P; + var upP = controls.UI_UP_P; + var downP = controls.UI_DOWN_P; var accepted = controls.ACCEPT; if (upP) diff --git a/source/PlayState.hx b/source/PlayState.hx index 2f699ea45..cf9006af9 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -1188,6 +1188,7 @@ class PlayState extends MusicBeatState { if (paused) { + camHUD.exists = false; if (FlxG.sound.music != null) { FlxG.sound.music.pause(); @@ -1213,6 +1214,7 @@ class PlayState extends MusicBeatState if (!startTimer.finished) startTimer.active = true; paused = false; + camHUD.exists = true; } super.closeSubState(); @@ -1835,20 +1837,20 @@ class PlayState extends MusicBeatState private function keyShit():Void { // HOLDING - var up = controls.UP; - var right = controls.RIGHT; - var down = controls.DOWN; - var left = controls.LEFT; + var up = controls.NOTE_UP; + var right = controls.NOTE_RIGHT; + var down = controls.NOTE_DOWN; + var left = controls.NOTE_LEFT; - var upP = controls.UP_P; - var rightP = controls.RIGHT_P; - var downP = controls.DOWN_P; - var leftP = controls.LEFT_P; + var upP = controls.NOTE_UP_P; + var rightP = controls.NOTE_RIGHT_P; + var downP = controls.NOTE_DOWN_P; + var leftP = controls.NOTE_LEFT_P; - var upR = controls.UP_R; - var rightR = controls.RIGHT_R; - var downR = controls.DOWN_R; - var leftR = controls.LEFT_R; + var upR = controls.NOTE_UP_R; + var rightR = controls.NOTE_RIGHT_R; + var downR = controls.NOTE_DOWN_R; + var leftR = controls.NOTE_LEFT_R; var controlArray:Array = [leftP, downP, upP, rightP]; @@ -2067,10 +2069,10 @@ class PlayState extends MusicBeatState { // just double pasting this shit cuz fuk u // REDO THIS SYSTEM! - var upP = controls.UP_P; - var rightP = controls.RIGHT_P; - var downP = controls.DOWN_P; - var leftP = controls.LEFT_P; + var upP = controls.NOTE_UP_P; + var rightP = controls.NOTE_RIGHT_P; + var downP = controls.NOTE_DOWN_P; + var leftP = controls.NOTE_LEFT_P; if (leftP) noteMiss(0); diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index b985369b8..22ba229ca 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -237,29 +237,29 @@ class StoryMenuState extends MusicBeatState { if (!selectedWeek) { - if (controls.UP_P) + if (controls.UI_UP_P) { changeWeek(-1); } - if (controls.DOWN_P) + if (controls.UI_DOWN_P) { changeWeek(1); } - if (controls.RIGHT) + if (controls.UI_RIGHT) rightArrow.animation.play('press') else rightArrow.animation.play('idle'); - if (controls.LEFT) + if (controls.UI_LEFT) leftArrow.animation.play('press'); else leftArrow.animation.play('idle'); - if (controls.RIGHT_P) + if (controls.UI_RIGHT_P) changeDifficulty(1); - if (controls.LEFT_P) + if (controls.UI_LEFT_P) changeDifficulty(-1); } diff --git a/source/ui/AtlasText.hx b/source/ui/AtlasText.hx index 579c35729..4c5f653b2 100644 --- a/source/ui/AtlasText.hx +++ b/source/ui/AtlasText.hx @@ -18,23 +18,24 @@ abstract BoldText(AtlasText) from AtlasText to AtlasText */ class AtlasText extends FlxTypedSpriteGroup { - static var maxHeights = new Map(); - public var text(default, set):String; + static var fonts = new Map(); + static var casesAllowed = new Map(); + public var text(default, set):String = ""; - var atlas:FlxAtlasFrames; - var maxHeight = 0.0; + var font:AtlasFontData; - public function new (x = 0.0, y = 0.0, text:String, font:AtlasFont = Default) + public var atlas(get, never):FlxAtlasFrames; + inline function get_atlas() return font.atlas; + public var caseAllowed(get, never):Case; + inline function get_caseAllowed() return font.caseAllowed; + public var maxHeight(get, never):Float; + inline function get_maxHeight() return font.maxHeight; + + public function new (x = 0.0, y = 0.0, text:String, fontName:AtlasFont = Default) { - atlas = Paths.getSparrowAtlas("fonts/" + font.getName().toLowerCase()); - if (maxHeights.exists(font)) - { - maxHeight = 0; - for (frame in atlas.frames) - maxHeight = Math.max(maxHeight, frame.frame.height); - maxHeights[font] = maxHeight; - } - maxHeight = maxHeights[font]; + if (!fonts.exists(fontName)) + fonts[fontName] = new AtlasFontData(fontName); + font = fonts[fontName]; super(x, y); @@ -43,18 +44,87 @@ class AtlasText extends FlxTypedSpriteGroup function set_text(value:String) { - if (this.text == value) + if (value == null) + value = ""; + + var caseValue = restrictCase(value); + var caseText = restrictCase(this.text); + + this.text = value; + if (caseText == caseValue) + return value; // cancel redraw + + if (caseValue.indexOf(caseText) == 0) + { + // new text is just old text with additions at the end, append the difference + appendTextCased(caseValue.substr(caseText.length)); return this.text; + } + + value = caseValue; group.kill(); + if (value == "") + return this.text; + + appendTextCased(this.text); + return this.text; + } + + /** + * Adds new characters, without needing to redraw the previous characters + * @param text The text to add. + * @throws String if `text` is null. + */ + public function appendText(text:String) + { + if (text == null) + throw "cannot append null"; + + if (text == "") + return; + + this.text = this.text + text; + } + + /** + * Converts all characters to fit the font's `allowedCase`. + * @param text + */ + function restrictCase(text:String) + { + return switch(caseAllowed) + { + case Both: text; + case Upper: text.toUpperCase(); + case Lower: text.toLowerCase(); + } + } + + /** + * Adds new text on top of the existing text. Helper for other methods; DOESN'T CHANGE `this.text`. + * @param text The text to add, assumed to match the font's `caseAllowed`. + */ + function appendTextCased(text:String) + { + var charCount = group.countLiving(); var xPos:Float = 0; var yPos:Float = 0; - - var charCount = 0; - for (char in value.split("")) + // `countLiving` returns -1 if group is empty + if (charCount == -1) + charCount = 0; + else if (charCount > 0) { - switch(char) + var lastChar = group.members[charCount - 1]; + xPos = lastChar.x + lastChar.width; + yPos = lastChar.y + lastChar.height - maxHeight; + } + + var splitValues = text.split(""); + for (i in 0...splitValues.length) + { + switch(splitValues[i]) { case " ": { @@ -63,9 +133,9 @@ class AtlasText extends FlxTypedSpriteGroup case "\n": { xPos = 0; - yPos += 55; + yPos += maxHeight; } - default: + case char: { var charSprite:AtlasChar; if (group.members.length <= charCount) @@ -85,8 +155,6 @@ class AtlasText extends FlxTypedSpriteGroup } } } - // updateHitbox(); - return this.text = value; } } @@ -105,7 +173,8 @@ class AtlasChar extends FlxSprite { if (this.char != value) { - animation.addByPrefix("anim", getAnimPrefix(value), 24); + var prefix = getAnimPrefix(value); + animation.addByPrefix("anim", prefix, 24); animation.play("anim"); updateHitbox(); } @@ -133,6 +202,47 @@ class AtlasChar extends FlxSprite } } +private class AtlasFontData +{ + static public var upperChar = ~/^[A-Z]\d+$/; + static public var lowerChar = ~/^[a-z]\d+$/; + + public var atlas:FlxAtlasFrames; + public var maxHeight:Float = 0.0; + public var caseAllowed:Case = Both; + + public function new (name:AtlasFont) + { + atlas = Paths.getSparrowAtlas("fonts/" + name.getName().toLowerCase()); + atlas.parent.destroyOnNoUse = false; + atlas.parent.persist = true; + + var containsUpper = false; + var containsLower = false; + + for (frame in atlas.frames) + { + maxHeight = Math.max(maxHeight, frame.frame.height); + + if (!containsUpper) + containsUpper = upperChar.match(frame.name); + + if (!containsLower) + containsLower = lowerChar.match(frame.name); + } + + if (containsUpper != containsLower) + caseAllowed = containsUpper ? Upper : Lower; + } +} + +enum Case +{ + Both; + Upper; + Lower; +} + enum AtlasFont { Default; diff --git a/source/ui/ControlsMenu.hx b/source/ui/ControlsMenu.hx index 7dbc20983..90d3909bc 100644 --- a/source/ui/ControlsMenu.hx +++ b/source/ui/ControlsMenu.hx @@ -11,71 +11,77 @@ import Controls; import ui.AtlasText; import ui.TextMenuList; -class ControlsMenu extends flixel.group.FlxGroup +class ControlsMenu extends ui.OptionsState.Page { - var controlGrid:TextMenuList; - var labels:FlxTypedGroup; - var menuCamera:FlxCamera; - - public function new() - { - super(); - - var menuBG = new FlxSprite().loadGraphic(Paths.image('menuDesat')); - menuBG.color = 0xFFea71fd; - menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); - menuBG.updateHitbox(); - menuBG.screenCenter(); - add(menuBG); - - camera = FlxG.camera; - FlxG.cameras.add(menuCamera = new FlxCamera()); - menuCamera.bgColor = 0x0; - - add(labels = new FlxTypedGroup()); - labels.camera = menuCamera; - - add(controlGrid = new TextMenuList(Columns(2))); - controlGrid.camera = menuCamera; - - // FlxG.debugger.drawDebug = true; - var controlList = Control.createAll(); - for (i in 0...controlList.length) - { - var control = controlList[i]; - var name = control.getName(); - var y = (70 * i) + 30; - var label = labels.add(new BoldText(0, y, name)); - label.x += 100; - createItem(500, y, control, 0); - createItem(700, y, control, 1); - } - - var selected = controlGrid.members[0]; - var camFollow = new FlxObject(FlxG.width / 2, selected.y); - menuCamera.follow(camFollow, LOCKON, 0.06); - controlGrid.onChange.add(function (selected) camFollow.y = selected.y); - } - - function createItem(x = 0.0, y = 0.0, control:Control, index:Int) - { - var list = PlayerSettings.player1.controls.getInputsFor(control, Keys); - var name = "---"; - if (list.length > index) - { - if (list[index] == FlxKey.ESCAPE) - return createItem(x, y, control, 2); - - name = InputFormatter.format(list[index], Keys); - } - - trace(control.getName() + " " + index + ": " + name); - return controlGrid.createItem(x, y, name, Default, onSelect.bind(name, control, index)); - } - - function onSelect(name:String, control:Control, index:Int):Void - { - controlGrid.enabled = false; - // var prompt = new Prompt(); - } + var controlGrid:TextMenuList; + var labels:FlxTypedGroup; + var menuCamera:FlxCamera; + + public function new() + { + super(); + + menuCamera = new FlxCamera(); + FlxG.cameras.add(menuCamera);// false); + if (FlxCamera.defaultCameras.indexOf(menuCamera) != -1) + { + FlxCamera.defaultCameras = FlxCamera.defaultCameras.copy(); + FlxCamera.defaultCameras.remove(menuCamera); + } + menuCamera.bgColor = 0x0; + + add(labels = new FlxTypedGroup()); + labels.camera = menuCamera; + + add(controlGrid = new TextMenuList(Columns(2))); + controlGrid.camera = menuCamera; + + // FlxG.debugger.drawDebug = true; + var controlList = Control.createAll(); + for (i in 0...controlList.length) + { + var control = controlList[i]; + var name = control.getName(); + var y = (70 * i) + 30; + var label = labels.add(new BoldText(0, y, name)); + label.x += 250; + createItem(label.x + 400, y, control, 0); + createItem(label.x + 600, y, control, 1); + } + + var selected = controlGrid.members[0]; + var camFollow = new FlxObject(FlxG.width / 2, selected.y, 70, 70); + menuCamera.follow(camFollow, null, 0.06); + var margin = 100; + menuCamera.deadzone.set(0, margin, menuCamera.width, menuCamera.height - margin * 2); + controlGrid.onChange.add(function (selected) camFollow.y = selected.y); + } + + function createItem(x = 0.0, y = 0.0, control:Control, index:Int) + { + var list = PlayerSettings.player1.controls.getInputsFor(control, Keys); + var name = "---"; + if (list.length > index) + { + if (list[index] == FlxKey.ESCAPE) + return createItem(x, y, control, 2); + + name = InputFormatter.format(list[index], Keys); + } + + trace(control.getName() + " " + index + ": " + name); + return controlGrid.createItem(x, y, name, Default, onSelect.bind(name, control, index)); + } + + function onSelect(name:String, control:Control, index:Int):Void + { + controlGrid.enabled = false; + // var prompt = new Prompt(); + } + + override function set_enabled(value:Bool) + { + controlGrid.enabled = value; + return super.set_enabled(value); + } } \ No newline at end of file diff --git a/source/ui/MenuList.hx b/source/ui/MenuList.hx index 050cbe666..f4df6066f 100644 --- a/source/ui/MenuList.hx +++ b/source/ui/MenuList.hx @@ -65,12 +65,12 @@ class MenuTypedList extends FlxTypedGroup var newIndex = switch(navControls) { - case Vertical : navList(controls.UP_P , controls.DOWN_P); - case Horizontal : navList(controls.LEFT_P, controls.RIGHT_P); - case Both : navList(controls.LEFT_P || controls.UP_P, controls.RIGHT_P || controls.DOWN_P); + case Vertical : navList(controls.UI_UP_P , controls.UI_DOWN_P); + case Horizontal : navList(controls.UI_LEFT_P, controls.UI_RIGHT_P); + case Both : navList(controls.UI_LEFT_P || controls.UI_UP_P, controls.UI_RIGHT_P || controls.UI_DOWN_P); - case Columns(num): navGrid(num, controls.LEFT_P, controls.RIGHT_P, controls.UP_P, controls.DOWN_P); - case Rows (num): navGrid(num, controls.UP_P, controls.DOWN_P, controls.LEFT_P, controls.RIGHT_P); + case Columns(num): navGrid(num, controls.UI_LEFT_P, controls.UI_RIGHT_P, controls.UI_UP_P , controls.UI_DOWN_P ); + case Rows (num): navGrid(num, controls.UI_UP_P , controls.UI_DOWN_P , controls.UI_LEFT_P, controls.UI_RIGHT_P); } if (newIndex != selectedIndex) diff --git a/source/ui/OptionsState.hx b/source/ui/OptionsState.hx new file mode 100644 index 000000000..6801b4270 --- /dev/null +++ b/source/ui/OptionsState.hx @@ -0,0 +1,258 @@ +package ui; + +import flixel.FlxSubState; +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.group.FlxGroup; +import flixel.util.FlxSignal; + +import flixel.addons.transition.FlxTransitionableState; + +// typedef OptionsState = OptionsMenu_old; + +// class OptionsState_new extends MusicBeatState +class OptionsState extends MusicBeatState +{ + var pages = new Map(); + var currentName:PageName = #if newgrounds Options #else Controls #end; + var currentPage(get, never):Page; + inline function get_currentPage() return pages[currentName]; + + override function create() + { + var menuBG = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + menuBG.color = 0xFFea71fd; + menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); + menuBG.updateHitbox(); + menuBG.screenCenter(); + add(menuBG); + + var options = addPage(Options, new OptionsMenu(false)); + var controls = addPage(Controls, new ControlsMenu()); + + if (options.hasMultipleOptions()) + { + options.onExit.add(exitToMainMenu); + controls.onExit.add(switchPage.bind(Options)); + } + else + { + // No need to show Options page + controls.onExit.add(exitToMainMenu); + setPage(Controls); + } + + // disable for intro transition + currentPage.enabled = false; + super.create(); + } + + function addPage(name:PageName, page:T) + { + page.onSwitch.add(switchPage); + pages[name] = page; + add(page); + page.exists = currentName == name; + return page; + } + + function setPage(name:PageName) + { + if (pages.exists(currentName)) + currentPage.exists = false; + + currentName = name; + + if (pages.exists(currentName)) + currentPage.exists = true; + } + + override function finishTransIn() + { + super.finishTransIn(); + + currentPage.enabled = true; + } + + function switchPage(name:PageName) + { + //Todo animate? + setPage(name); + } + + function exitToMainMenu() + { + currentPage.enabled = false; + //Todo animate? + FlxG.switchState(new MainMenuState()); + } +} + +class Page extends FlxGroup +{ + public var onSwitch(default, null) = new FlxTypedSignalVoid>(); + public var onExit(default, null) = new FlxSignal(); + + public var enabled(default, set) = true; + + var controls(get, never):Controls; + inline function get_controls() return PlayerSettings.player1.controls; + + var subState:FlxSubState; + + inline function switchPage(name:PageName) + { + onSwitch.dispatch(name); + } + + inline function exit() + { + onExit.dispatch(); + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (enabled) + updateEnabled(elapsed); + } + + function updateEnabled(elapsed:Float) + { + if (controls.BACK) + exit(); + } + + function set_enabled(value:Bool) + { + return this.enabled = value; + } + + function openPrompt(prompt:Prompt, onClose:Void->Void) + { + enabled = false; + prompt.closeCallback = function () + { + enabled = true; + if (onClose != null) + onClose(); + } + + FlxG.state.openSubState(prompt); + } + + override function destroy() + { + super.destroy(); + onSwitch.removeAll(); + } +} + +class OptionsMenu extends Page +{ + var items:TextMenuList; + + public function new (showDonate:Bool) + { + super(); + + add(items = new TextMenuList()); + createItem("controls", function() switchPage(Controls)); + #if CAN_OPEN_LINKS + if (showDonate) + { + var hasPopupBlocker = #if web true #else false #end; + createItem('donate', selectDonate, hasPopupBlocker); + } + #end + #if newgrounds + if (NGio.isLoggedIn) + createItem("logout", selectLogout); + else + createItem("login", selectLogin); + #end + createItem("exit", exit); + } + + function createItem(name:String, callback:Void->Void, fireInstantly = false) + { + var item = items.createItem(0, 100 + items.length * 100, name, Bold, callback); + item.fireInstantly = fireInstantly; + item.screenCenter(X); + return item; + } + + override function set_enabled(value:Bool) + { + items.enabled = value; + return super.set_enabled(value); + } + + /** + * True if this page has multiple options, ecluding the exit option. + * If false, there's no reason to ever show this page. + */ + public function hasMultipleOptions():Bool + { + return items.length > 2; + } + + #if CAN_OPEN_LINKS + function selectDonate() + { + #if linux + Sys.command('/usr/bin/xdg-open', ["https://ninja-muffin24.itch.io/funkin", "&"]); + #else + FlxG.openURL('https://ninja-muffin24.itch.io/funkin'); + #end + } + #end + + #if newgrounds + function selectLogin() + { + openNgPrompt(NgPrompt.showLogin()); + } + + function selectLogout() + { + openNgPrompt(NgPrompt.showLogout()); + } + + /** + * Calls openPrompt and redraws the login/logout button + * @param prompt + * @param onClose + */ + public function openNgPrompt(prompt:Prompt, ?onClose:Void->Void) + { + var onPromptClose = checkLoginStatus; + if (onClose != null) + { + onPromptClose = function () + { + checkLoginStatus(); + onClose(); + } + } + + openPrompt(prompt, onPromptClose); + } + + function checkLoginStatus() + { + var prevLoggedIn = items.has("logout"); + if (prevLoggedIn && !NGio.isLoggedIn) + items.resetItem("login", "logout", selectLogout); + else if (!prevLoggedIn && NGio.isLoggedIn) + items.resetItem("logout", "login", selectLogin); + } + #end +} + +enum PageName +{ + Options; + Controls; +} diff --git a/source/ui/TextMenuList.hx b/source/ui/TextMenuList.hx index bfc356c26..d3134a5c7 100644 --- a/source/ui/TextMenuList.hx +++ b/source/ui/TextMenuList.hx @@ -34,7 +34,7 @@ class TextTypedMenuItem extends MenuTypedItem super(x, y, label, name, callback); } - override function setItem(name:String, ?callback:() -> Void) + override function setItem(name:String, ?callback:Void -> Void) { if (label != null) {