From c87079fff5c4fc16e18617212af26b3487cb6dc1 Mon Sep 17 00:00:00 2001 From: George FunBook Date: Mon, 22 Mar 2021 21:39:35 -0500 Subject: [PATCH] finalize options menu --- Project.xml | 2 + source/Controls.hx | 96 ++++++++++--- source/OptionsMenu_old.hx | 2 +- source/PlayerSettings.hx | 284 ++++++++++++++++++++++++++------------ source/TitleState.hx | 3 +- source/ui/ControlsMenu.hx | 14 +- 6 files changed, 281 insertions(+), 120 deletions(-) diff --git a/Project.xml b/Project.xml index 85284f76c..3055cf457 100644 --- a/Project.xml +++ b/Project.xml @@ -180,6 +180,8 @@ + +
diff --git a/source/Controls.hx b/source/Controls.hx index 6e49c5387..95748946f 100644 --- a/source/Controls.hx +++ b/source/Controls.hx @@ -18,10 +18,11 @@ import flixel.input.keyboard.FlxKey; */ enum Control { - NOTE_UP; + // List notes in order from left to right on gameplay screen. NOTE_LEFT; - NOTE_RIGHT; NOTE_DOWN; + NOTE_UP; + NOTE_RIGHT; UI_UP; UI_LEFT; UI_RIGHT; @@ -327,7 +328,7 @@ class Controls extends FlxActionSet } } - public function replaceBinding(control:Control, device:Device, ?toAdd:Int, ?toRemove:Int) + public function replaceBinding(control:Control, device:Device, toAdd:Int, toRemove:Int) { if (toAdd == toRemove) return; @@ -335,16 +336,36 @@ class Controls extends FlxActionSet switch (device) { case Keys: - if (toRemove != null) - unbindKeys(control, [toRemove]); - if (toAdd != null) - bindKeys(control, [toAdd]); + forEachBound(control, function(action, _) replaceKey(action, toAdd, toRemove)); case Gamepad(id): - if (toRemove != null) - unbindButtons(control, id, [toRemove]); - if (toAdd != null) - bindButtons(control, id, [toAdd]); + forEachBound(control, function(action, _) replaceButton(action, id, toAdd, toRemove)); + } + } + + function replaceKey(action:FlxActionDigital, toAdd:Int, toRemove:Int) + { + for (i in 0...action.inputs.length) + { + var input = action.inputs[i]; + if (input.device == KEYBOARD && input.inputID == toRemove) + { + @:privateAccess + action.inputs[i].inputID = toAdd; + } + } + } + + function replaceButton(action:FlxActionDigital, deviceID:Int, toAdd:Int, toRemove:Int) + { + for (i in 0...action.inputs.length) + { + var input = action.inputs[i]; + if (isGamepad(input, deviceID) && input.inputID == toRemove) + { + @:privateAccess + action.inputs[i].inputID = toAdd; + } } } @@ -498,12 +519,11 @@ class Controls extends FlxActionSet } } - public function addGamepad(id:Int, ?buttonMap:Map>):Void + public function addGamepadWithSaveData(id:Int, ?padData:Dynamic):Void { gamepadsAdded.push(id); - for (control in buttonMap.keys()) - bindButtons(control, id, buttonMap[control]); + fromSaveData(padData, Gamepad(id)); } inline function addGamepadLiteral(id:Int, ?buttonMap:Map>):Void @@ -522,7 +542,7 @@ class Controls extends FlxActionSet while (i-- > 0) { var input = action.inputs[i]; - if (input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID)) + if (isGamepad(input, deviceID)) action.remove(input); } } @@ -533,13 +553,9 @@ class Controls extends FlxActionSet public function addDefaultGamepad(id):Void { addGamepadLiteral(id, [ - #if switch - Control.ACCEPT => [B], - Control.BACK => [A], - #else - Control.ACCEPT => [A], - Control.BACK => [B], - #end + + Control.ACCEPT => [#if switch B #else A #end], + Control.BACK => [#if switch A #else B #end, BACK], 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], @@ -608,7 +624,7 @@ class Controls extends FlxActionSet case Gamepad(id): for (input in getActionFromControl(control).inputs) { - if (input.deviceID == id) + if (isGamepad(input, id)) list.push(input.inputID); } } @@ -626,6 +642,37 @@ class Controls extends FlxActionSet } } + public function fromSaveData(data:Dynamic, device:Device) + { + for (control in Control.createAll()) + { + var inputs:Array = Reflect.field(data, control.getName()); + if (inputs != null) + { + switch(device) + { + case Keys: bindKeys(control, inputs.copy()); + case Gamepad(id): bindButtons(control, id, inputs.copy()); + } + } + } + } + + public function createSaveData(device:Device):Dynamic + { + var isEmpty = true; + var data = {}; + for (control in Control.createAll()) + { + var inputs = getInputsFor(control, device); + isEmpty = isEmpty && inputs.length == 0; + + Reflect.setField(data, control.getName(), inputs); + } + + return isEmpty ? null : data; + } + static function isDevice(input:FlxActionInput, device:Device) { return switch device @@ -640,3 +687,6 @@ class Controls extends FlxActionSet return input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID); } } + + +typedef SaveInputLists = {?keys:Array, ?pad:Array}; \ No newline at end of file diff --git a/source/OptionsMenu_old.hx b/source/OptionsMenu_old.hx index 3acd212a3..4ec844323 100644 --- a/source/OptionsMenu_old.hx +++ b/source/OptionsMenu_old.hx @@ -82,7 +82,7 @@ class OptionsMenu_old extends MusicBeatState { if (FlxG.keys.getIsDown().length > 0) { - PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxG.keys.getIsDown()[0].ID, null); + // PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxG.keys.getIsDown()[0].ID, null); } // PlayerSettings.player1.controls.replaceBinding(Control) } diff --git a/source/PlayerSettings.hx b/source/PlayerSettings.hx index df7586c44..a0ed2429a 100644 --- a/source/PlayerSettings.hx +++ b/source/PlayerSettings.hx @@ -1,8 +1,11 @@ package; import Controls; + import flixel.FlxCamera; import flixel.FlxG; +import flixel.input.actions.FlxActionInput; +import flixel.input.gamepad.FlxGamepad; import flixel.util.FlxSignal; // import ui.DeviceManager; @@ -24,124 +27,223 @@ class PlayerSettings // public var avatar:Player; // public var camera(get, never):PlayCamera; - function new(id, scheme) + function new(id) { this.id = id; - this.controls = new Controls('player$id', scheme); + this.controls = new Controls('player$id', None); + + #if CLEAR_INPUT_SAVE + FlxG.save.data.controls = null; + FlxG.save.flush(); + #end + + var useDefault = true; + var controlData = FlxG.save.data.controls; + if (controlData != null) + { + var keyData:Dynamic = null; + if (id == 0 && controlData.p1 != null && controlData.p1.keys != null) + keyData = controlData.p1.keys; + else if (id == 1 && controlData.p2 != null && controlData.p2.keys != null) + keyData = controlData.p2.keys; + + if (keyData != null) + { + useDefault = false; + trace("loaded key data: " + haxe.Json.stringify(keyData)); + controls.fromSaveData(keyData, Keys); + } + } + + if (useDefault) + controls.setKeyboardScheme(Solo); } + + function addGamepad(gamepad:FlxGamepad) + { + var useDefault = true; + var controlData = FlxG.save.data.controls; + if (controlData != null) + { + var padData:Dynamic = null; + if (id == 0 && controlData.p1 != null && controlData.p1.pad != null) + padData = controlData.p1.pad; + else if (id == 1 && controlData.p2 != null && controlData.p2.pad != null) + padData = controlData.p2.pad; + + if (padData != null) + { + useDefault = false; + trace("loaded pad data: " + haxe.Json.stringify(padData)); + controls.addGamepadWithSaveData(gamepad.id, padData); + } + } + + if (useDefault) + controls.addDefaultGamepad(gamepad.id); + } + + public function saveControls() + { + if (FlxG.save.data.controls == null) + FlxG.save.data.controls = {}; + + var playerData:{ ?keys:Dynamic, ?pad:Dynamic } + if (id == 0) + { + if (FlxG.save.data.controls.p1 == null) + FlxG.save.data.controls.p1 = {}; + playerData = FlxG.save.data.controls.p1; + } + else + { + if (FlxG.save.data.controls.p2 == null) + FlxG.save.data.controls.p2 = {}; + playerData = FlxG.save.data.controls.p2; + } + + var keyData = controls.createSaveData(Keys); + if (keyData != null) + { + playerData.keys = keyData; + trace("saving key data: " + haxe.Json.stringify(keyData)); + } + + if (controls.gamepadsAdded.length > 0) + { + var padData = controls.createSaveData(Gamepad(controls.gamepadsAdded[0])); + if (padData != null) + { + trace("saving pad data: " + haxe.Json.stringify(padData)); + playerData.pad = padData; + } + } + + FlxG.save.flush(); + } + + static public function init():Void + { + if (player1 == null) + { + player1 = new PlayerSettings(0); + ++numPlayers; + } + + FlxG.gamepads.deviceConnected.add(onGamepadAdded); + var numGamepads = FlxG.gamepads.numActiveGamepads; + for (i in 0...numGamepads) + { + var gamepad = FlxG.gamepads.getByID(i); + if (gamepad != null) + onGamepadAdded(gamepad); + } + + // player1.controls.addDefaultGamepad(0); + // } + + // if (numGamepads > 1) + // { + // if (player2 == null) + // { + // player2 = new PlayerSettings(1, None); + // ++numPlayers; + // } + + // var gamepad = FlxG.gamepads.getByID(1); + // if (gamepad == null) + // throw 'Unexpected null gamepad. id:0'; + + // player2.controls.addDefaultGamepad(1); + // } + + // DeviceManager.init(); + } + + static function onGamepadAdded(gamepad:FlxGamepad) + { + player1.addGamepad(gamepad); + } + + + /* public function setKeyboardScheme(scheme) { controls.setKeyboardScheme(scheme); } - /* - static public function addAvatar(avatar:Player):PlayerSettings - { - var settings:PlayerSettings; - - if (player1 == null) - { - player1 = new PlayerSettings(0, Solo); - ++numPlayers; - } - - if (player1.avatar == null) - settings = player1; - else - { - if (player2 == null) - { - if (player1.controls.keyboardScheme.match(Duo(true))) - player2 = new PlayerSettings(1, Duo(false)); - else - player2 = new PlayerSettings(1, None); - ++numPlayers; - } - - if (player2.avatar == null) - settings = player2; - else - throw throw 'Invalid number of players: ${numPlayers + 1}'; - } - ++numAvatars; - settings.avatar = avatar; - avatar.settings = settings; - - splitCameras(); - - onAvatarAdd.dispatch(settings); - - return settings; - } - - static public function removeAvatar(avatar:Player):Void - { - var settings:PlayerSettings; - - if (player1 != null && player1.avatar == avatar) - settings = player1; - else if (player2 != null && player2.avatar == avatar) - { - settings = player2; - if (player1.controls.keyboardScheme.match(Duo(_))) - player1.setKeyboardScheme(Solo); - } - else - throw "Cannot remove avatar that is not for a player"; - - settings.avatar = null; - while (settings.controls.gamepadsAdded.length > 0) - { - final id = settings.controls.gamepadsAdded.shift(); - settings.controls.removeGamepad(id); - DeviceManager.releaseGamepad(FlxG.gamepads.getByID(id)); - } - - --numAvatars; - - splitCameras(); - - onAvatarRemove.dispatch(avatar.settings); - } - - */ - static public function init():Void + static public function addAvatar(avatar:Player):PlayerSettings { + var settings:PlayerSettings; + if (player1 == null) { player1 = new PlayerSettings(0, Solo); ++numPlayers; } - var numGamepads = FlxG.gamepads.numActiveGamepads; - if (numGamepads > 0) - { - var gamepad = FlxG.gamepads.getByID(0); - if (gamepad == null) - throw 'Unexpected null gamepad. id:0'; - - player1.controls.addDefaultGamepad(0); - } - - if (numGamepads > 1) + if (player1.avatar == null) + settings = player1; + else { if (player2 == null) { - player2 = new PlayerSettings(1, None); + if (player1.controls.keyboardScheme.match(Duo(true))) + player2 = new PlayerSettings(1, Duo(false)); + else + player2 = new PlayerSettings(1, None); ++numPlayers; } - var gamepad = FlxG.gamepads.getByID(1); - if (gamepad == null) - throw 'Unexpected null gamepad. id:0'; + if (player2.avatar == null) + settings = player2; + else + throw throw 'Invalid number of players: ${numPlayers + 1}'; + } + ++numAvatars; + settings.avatar = avatar; + avatar.settings = settings; - player2.controls.addDefaultGamepad(1); + splitCameras(); + + onAvatarAdd.dispatch(settings); + + return settings; + } + + static public function removeAvatar(avatar:Player):Void + { + var settings:PlayerSettings; + + if (player1 != null && player1.avatar == avatar) + settings = player1; + else if (player2 != null && player2.avatar == avatar) + { + settings = player2; + if (player1.controls.keyboardScheme.match(Duo(_))) + player1.setKeyboardScheme(Solo); + } + else + throw "Cannot remove avatar that is not for a player"; + + settings.avatar = null; + while (settings.controls.gamepadsAdded.length > 0) + { + final id = settings.controls.gamepadsAdded.shift(); + settings.controls.removeGamepad(id); + DeviceManager.releaseGamepad(FlxG.gamepads.getByID(id)); } - // DeviceManager.init(); + --numAvatars; + + splitCameras(); + + onAvatarRemove.dispatch(avatar.settings); } + */ + static public function reset() { player1 = null; diff --git a/source/TitleState.hx b/source/TitleState.hx index 01668d72c..eff43f823 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -41,8 +41,6 @@ class TitleState extends MusicBeatState FlxG.sound.muteKeys = [ZERO]; - PlayerSettings.init(); - curWacky = FlxG.random.getObject(getIntroTextShit()); // DEBUG BULLSHIT @@ -50,6 +48,7 @@ class TitleState extends MusicBeatState super.create(); FlxG.save.bind('funkin', 'ninjamuffin99'); + PlayerSettings.init(); Highscore.load(); #if newgrounds diff --git a/source/ui/ControlsMenu.hx b/source/ui/ControlsMenu.hx index ca923af29..629a89914 100644 --- a/source/ui/ControlsMenu.hx +++ b/source/ui/ControlsMenu.hx @@ -184,7 +184,12 @@ class ControlsMenu extends ui.OptionsState.Page var inputName = device == Keys ? "key" : "button"; var cancel = device == Keys ? "Escape" : "Back"; - prompt.setText('\nPress any $inputName to rebind\n\n\n\n $cancel to cancel'); + //todo: alignment + if (device == Keys) + prompt.setText('\nPress any key to rebind\n\n\n\n $cancel to cancel'); + else + prompt.setText('\nPress any button\n to rebind\n\n\n $cancel to cancel'); + controlGrid.selectedItem.select(); labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 1.0; @@ -265,13 +270,16 @@ class ControlsMenu extends ui.OptionsState.Page // Don't use resetItem() since items share names/labels item.input = input; item.label.text = item.getLabel(input); + + PlayerSettings.player1.saveControls(); } function closePrompt() { - controlGrid.enabled = true; - canExit = true; prompt.exists = false; + controlGrid.enabled = true; + if (deviceList == null) + canExit = true; } override function destroy()