mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-03-22 09:59:25 +00:00
Additional controls (volume, cutscene skip)
This commit is contained in:
parent
506e4bf680
commit
1191fff913
|
@ -41,12 +41,18 @@ enum Control
|
|||
ACCEPT;
|
||||
BACK;
|
||||
PAUSE;
|
||||
CUTSCENE_ADVANCE;
|
||||
CUTSCENE_SKIP;
|
||||
VOLUME_UP;
|
||||
VOLUME_DOWN;
|
||||
VOLUME_MUTE;
|
||||
#if CAN_CHEAT
|
||||
CHEAT;
|
||||
#end
|
||||
}
|
||||
|
||||
enum abstract Action(String) to String from String
|
||||
@:enum
|
||||
abstract Action(String) to String from String
|
||||
{
|
||||
var UI_UP = "ui_up";
|
||||
var UI_LEFT = "ui_left";
|
||||
|
@ -75,6 +81,11 @@ enum abstract Action(String) to String from String
|
|||
var ACCEPT = "accept";
|
||||
var BACK = "back";
|
||||
var PAUSE = "pause";
|
||||
var CUTSCENE_ADVANCE = "cutscene_advance";
|
||||
var CUTSCENE_SKIP = "cutscene_skip";
|
||||
var VOLUME_UP = "volume_up";
|
||||
var VOLUME_DOWN = "volume_down";
|
||||
var VOLUME_MUTE = "volume_mute";
|
||||
var RESET = "reset";
|
||||
#if CAN_CHEAT
|
||||
var CHEAT = "cheat";
|
||||
|
@ -129,6 +140,11 @@ class Controls extends FlxActionSet
|
|||
var _back = new FlxActionDigital(Action.BACK);
|
||||
var _pause = new FlxActionDigital(Action.PAUSE);
|
||||
var _reset = new FlxActionDigital(Action.RESET);
|
||||
var _cutscene_advance = new FlxActionDigital(Action.CUTSCENE_ADVANCE);
|
||||
var _cutscene_skip = new FlxActionDigital(Action.CUTSCENE_SKIP);
|
||||
var _volume_up = new FlxActionDigital(Action.VOLUME_UP);
|
||||
var _volume_down = new FlxActionDigital(Action.VOLUME_DOWN);
|
||||
var _volume_mute = new FlxActionDigital(Action.VOLUME_MUTE);
|
||||
#if CAN_CHEAT
|
||||
var _cheat = new FlxActionDigital(Action.CHEAT);
|
||||
#end
|
||||
|
@ -273,6 +289,31 @@ class Controls extends FlxActionSet
|
|||
inline function get_PAUSE()
|
||||
return _pause.check();
|
||||
|
||||
public var CUTSCENE_ADVANCE(get, never):Bool;
|
||||
|
||||
inline function get_CUTSCENE_ADVANCE()
|
||||
return _cutscene_advance.check();
|
||||
|
||||
public var CUTSCENE_SKIP(get, never):Bool;
|
||||
|
||||
inline function get_CUTSCENE_SKIP()
|
||||
return _cutscene_skip.check();
|
||||
|
||||
public var VOLUME_UP(get, never):Bool;
|
||||
|
||||
inline function get_VOLUME_UP()
|
||||
return _volume_up.check();
|
||||
|
||||
public var VOLUME_DOWN(get, never):Bool;
|
||||
|
||||
inline function get_VOLUME_DOWN()
|
||||
return _volume_down.check();
|
||||
|
||||
public var VOLUME_MUTE(get, never):Bool;
|
||||
|
||||
inline function get_VOLUME_MUTE()
|
||||
return _volume_mute.check();
|
||||
|
||||
public var RESET(get, never):Bool;
|
||||
|
||||
inline function get_RESET()
|
||||
|
@ -316,6 +357,11 @@ class Controls extends FlxActionSet
|
|||
add(_accept);
|
||||
add(_back);
|
||||
add(_pause);
|
||||
add(_cutscene_advance);
|
||||
add(_cutscene_skip);
|
||||
add(_volume_up);
|
||||
add(_volume_down);
|
||||
add(_volume_mute);
|
||||
add(_reset);
|
||||
#if CAN_CHEAT
|
||||
add(_cheat);
|
||||
|
@ -377,6 +423,11 @@ class Controls extends FlxActionSet
|
|||
case BACK: _back;
|
||||
case PAUSE: _pause;
|
||||
case RESET: _reset;
|
||||
case CUTSCENE_ADVANCE: _cutscene_advance;
|
||||
case CUTSCENE_SKIP: _cutscene_skip;
|
||||
case VOLUME_UP: _volume_up;
|
||||
case VOLUME_DOWN: _volume_down;
|
||||
case VOLUME_MUTE: _volume_mute;
|
||||
#if CAN_CHEAT
|
||||
case CHEAT: _cheat;
|
||||
#end
|
||||
|
@ -437,6 +488,16 @@ class Controls extends FlxActionSet
|
|||
func(_back, JUST_PRESSED);
|
||||
case PAUSE:
|
||||
func(_pause, JUST_PRESSED);
|
||||
case CUTSCENE_ADVANCE:
|
||||
func(_cutscene_advance, JUST_PRESSED);
|
||||
case CUTSCENE_SKIP:
|
||||
func(_cutscene_skip, PRESSED);
|
||||
case VOLUME_UP:
|
||||
func(_volume_up, JUST_PRESSED);
|
||||
case VOLUME_DOWN:
|
||||
func(_volume_down, JUST_PRESSED);
|
||||
case VOLUME_MUTE:
|
||||
func(_volume_mute, JUST_PRESSED);
|
||||
case RESET:
|
||||
func(_reset, JUST_PRESSED);
|
||||
#if CAN_CHEAT
|
||||
|
@ -454,37 +515,70 @@ class Controls extends FlxActionSet
|
|||
switch(device)
|
||||
{
|
||||
case Keys:
|
||||
forEachBound(control, function(action, _) replaceKey(action, toAdd, toRemove));
|
||||
forEachBound(control, function(action, state) replaceKey(action, toAdd, toRemove, state));
|
||||
|
||||
case Gamepad(id):
|
||||
forEachBound(control, function(action, _) replaceButton(action, id, toAdd, toRemove));
|
||||
forEachBound(control, function(action, state) replaceButton(action, id, toAdd, toRemove, state));
|
||||
}
|
||||
}
|
||||
|
||||
function replaceKey(action:FlxActionDigital, toAdd:Int, toRemove:Int)
|
||||
function replaceKey(action:FlxActionDigital, toAdd:FlxKey, toRemove:FlxKey, state:FlxInputState)
|
||||
{
|
||||
if (action.inputs.length == 0) {
|
||||
// Add the keybind, don't replace.
|
||||
addKeys(action, [toAdd], state);
|
||||
return;
|
||||
}
|
||||
|
||||
var hasReplaced:Bool = false;
|
||||
for (i in 0...action.inputs.length)
|
||||
{
|
||||
var input = action.inputs[i];
|
||||
if (input == null) continue;
|
||||
|
||||
if (input.device == KEYBOARD && input.inputID == toRemove)
|
||||
{
|
||||
@:privateAccess
|
||||
action.inputs[i].inputID = toAdd;
|
||||
if (toAdd == FlxKey.NONE) {
|
||||
// Remove the keybind, don't replace.
|
||||
action.inputs.remove(input);
|
||||
} else {
|
||||
// Replace the keybind.
|
||||
@:privateAccess
|
||||
action.inputs[i].inputID = toAdd;
|
||||
}
|
||||
hasReplaced = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasReplaced) {
|
||||
addKeys(action, [toAdd], state);
|
||||
}
|
||||
}
|
||||
|
||||
function replaceButton(action:FlxActionDigital, deviceID:Int, toAdd:Int, toRemove:Int)
|
||||
function replaceButton(action:FlxActionDigital, deviceID:Int, toAdd:FlxGamepadInputID, toRemove:FlxGamepadInputID, state:FlxInputState)
|
||||
{
|
||||
if (action.inputs.length == 0) {
|
||||
addButtons(action, [toAdd], state, deviceID);
|
||||
return;
|
||||
}
|
||||
|
||||
var hasReplaced:Bool = false;
|
||||
for (i in 0...action.inputs.length)
|
||||
{
|
||||
var input = action.inputs[i];
|
||||
if (input == null) continue;
|
||||
|
||||
if (isGamepad(input, deviceID) && input.inputID == toRemove)
|
||||
{
|
||||
@:privateAccess
|
||||
action.inputs[i].inputID = toAdd;
|
||||
hasReplaced = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasReplaced) {
|
||||
addButtons(action, [toAdd], state, deviceID);
|
||||
}
|
||||
}
|
||||
|
||||
public function copyFrom(controls:Controls, ?device:Device)
|
||||
|
@ -558,10 +652,12 @@ class Controls extends FlxActionSet
|
|||
forEachBound(control, function(action, _) removeKeys(action, keys));
|
||||
}
|
||||
|
||||
inline static function addKeys(action:FlxActionDigital, keys:Array<FlxKey>, state:FlxInputState)
|
||||
static function addKeys(action:FlxActionDigital, keys:Array<FlxKey>, state:FlxInputState)
|
||||
{
|
||||
for (key in keys)
|
||||
for (key in keys) {
|
||||
if (key == FlxKey.NONE) continue; // Ignore unbound keys.
|
||||
action.addKey(key, state);
|
||||
}
|
||||
}
|
||||
|
||||
static function removeKeys(action:FlxActionDigital, keys:Array<FlxKey>)
|
||||
|
@ -582,54 +678,95 @@ class Controls extends FlxActionSet
|
|||
|
||||
keyboardScheme = scheme;
|
||||
|
||||
switch(scheme)
|
||||
{
|
||||
case Solo:
|
||||
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, [X, BACKSPACE, ESCAPE]);
|
||||
bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]);
|
||||
bindKeys(Control.RESET, [R]);
|
||||
case Duo(true):
|
||||
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.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]);
|
||||
bindKeys(Control.RESET, [BACKSPACE]);
|
||||
case None: // nothing
|
||||
case Custom: // nothing
|
||||
}
|
||||
bindKeys(Control.UI_UP, getDefaultKeybinds(scheme, Control.UI_UP));
|
||||
bindKeys(Control.UI_DOWN, getDefaultKeybinds(scheme, Control.UI_DOWN));
|
||||
bindKeys(Control.UI_LEFT, getDefaultKeybinds(scheme, Control.UI_LEFT));
|
||||
bindKeys(Control.UI_RIGHT, getDefaultKeybinds(scheme, Control.UI_RIGHT));
|
||||
bindKeys(Control.NOTE_UP, getDefaultKeybinds(scheme, Control.NOTE_UP));
|
||||
bindKeys(Control.NOTE_DOWN, getDefaultKeybinds(scheme, Control.NOTE_DOWN));
|
||||
bindKeys(Control.NOTE_LEFT, getDefaultKeybinds(scheme, Control.NOTE_LEFT));
|
||||
bindKeys(Control.NOTE_RIGHT, getDefaultKeybinds(scheme, Control.NOTE_RIGHT));
|
||||
bindKeys(Control.ACCEPT, getDefaultKeybinds(scheme, Control.ACCEPT));
|
||||
bindKeys(Control.BACK, getDefaultKeybinds(scheme, Control.BACK));
|
||||
bindKeys(Control.PAUSE, getDefaultKeybinds(scheme, Control.PAUSE));
|
||||
bindKeys(Control.CUTSCENE_ADVANCE, getDefaultKeybinds(scheme, Control.CUTSCENE_ADVANCE));
|
||||
bindKeys(Control.CUTSCENE_SKIP, getDefaultKeybinds(scheme, Control.CUTSCENE_SKIP));
|
||||
bindKeys(Control.VOLUME_UP, getDefaultKeybinds(scheme, Control.VOLUME_UP));
|
||||
bindKeys(Control.VOLUME_DOWN, getDefaultKeybinds(scheme, Control.VOLUME_DOWN));
|
||||
bindKeys(Control.VOLUME_MUTE, getDefaultKeybinds(scheme, Control.VOLUME_MUTE));
|
||||
|
||||
bindMobileLol();
|
||||
}
|
||||
|
||||
function getDefaultKeybinds(scheme:KeyboardScheme, control:Control):Array<FlxKey> {
|
||||
switch (scheme) {
|
||||
case Solo:
|
||||
switch (control) {
|
||||
case Control.UI_UP: return [W, FlxKey.UP];
|
||||
case Control.UI_DOWN: return [S, FlxKey.DOWN];
|
||||
case Control.UI_LEFT: return [A, FlxKey.LEFT];
|
||||
case Control.UI_RIGHT: return [D, FlxKey.RIGHT];
|
||||
case Control.NOTE_UP: return [W, FlxKey.UP];
|
||||
case Control.NOTE_DOWN: return [S, FlxKey.DOWN];
|
||||
case Control.NOTE_LEFT: return [A, FlxKey.LEFT];
|
||||
case Control.NOTE_RIGHT: return [D, FlxKey.RIGHT];
|
||||
case Control.ACCEPT: return [Z, SPACE, ENTER];
|
||||
case Control.BACK: return [X, BACKSPACE, ESCAPE];
|
||||
case Control.PAUSE: return [P, ENTER, ESCAPE];
|
||||
case Control.CUTSCENE_ADVANCE: return [Z, ENTER];
|
||||
case Control.CUTSCENE_SKIP: return [P, ESCAPE];
|
||||
case Control.VOLUME_UP: return [PLUS, NUMPADPLUS];
|
||||
case Control.VOLUME_DOWN: return [MINUS, NUMPADMINUS];
|
||||
case Control.VOLUME_MUTE: return [ZERO, NUMPADZERO];
|
||||
case Control.RESET: return [R];
|
||||
}
|
||||
case Duo(true):
|
||||
switch (control) {
|
||||
case Control.UI_UP: return [W];
|
||||
case Control.UI_DOWN: return [S];
|
||||
case Control.UI_LEFT: return [A];
|
||||
case Control.UI_RIGHT: return [D];
|
||||
case Control.NOTE_UP: return [W];
|
||||
case Control.NOTE_DOWN: return [S];
|
||||
case Control.NOTE_LEFT: return [A];
|
||||
case Control.NOTE_RIGHT: return [D];
|
||||
case Control.ACCEPT: return [G, Z];
|
||||
case Control.BACK: return [H, X];
|
||||
case Control.PAUSE: return [ONE];
|
||||
case Control.CUTSCENE_ADVANCE: return [G, Z];
|
||||
case Control.CUTSCENE_SKIP: return [ONE];
|
||||
case Control.VOLUME_UP: return [PLUS];
|
||||
case Control.VOLUME_DOWN: return [MINUS];
|
||||
case Control.VOLUME_MUTE: return [ZERO];
|
||||
case Control.RESET: return [R];
|
||||
}
|
||||
case Duo(false):
|
||||
switch (control) {
|
||||
case Control.UI_UP: return [FlxKey.UP];
|
||||
case Control.UI_DOWN: return [FlxKey.DOWN];
|
||||
case Control.UI_LEFT: return [FlxKey.LEFT];
|
||||
case Control.UI_RIGHT: return [FlxKey.RIGHT];
|
||||
case Control.NOTE_UP: return [FlxKey.UP];
|
||||
case Control.NOTE_DOWN: return [FlxKey.DOWN];
|
||||
case Control.NOTE_LEFT: return [FlxKey.LEFT];
|
||||
case Control.NOTE_RIGHT: return [FlxKey.RIGHT];
|
||||
case Control.ACCEPT: return [ENTER];
|
||||
case Control.BACK: return [ESCAPE];
|
||||
case Control.PAUSE: return [ONE];
|
||||
case Control.CUTSCENE_ADVANCE: return [ENTER];
|
||||
case Control.CUTSCENE_SKIP: return [ONE];
|
||||
case Control.VOLUME_UP: return [NUMPADPLUS];
|
||||
case Control.VOLUME_DOWN: return [NUMPADMINUS];
|
||||
case Control.VOLUME_MUTE: return [NUMPADZERO];
|
||||
case Control.RESET: return [R];
|
||||
}
|
||||
default:
|
||||
// Fallthrough.
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function bindMobileLol()
|
||||
{
|
||||
#if FLX_TOUCH
|
||||
|
@ -704,23 +841,51 @@ class Controls extends FlxActionSet
|
|||
{
|
||||
addGamepadLiteral(id, [
|
||||
|
||||
Control.ACCEPT => [#if switch B #else A #end],
|
||||
Control.BACK => [#if switch A #else B #end, FlxGamepadInputID.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],
|
||||
Control.UI_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT],
|
||||
Control.ACCEPT => getDefaultGamepadBinds(Control.ACCEPT),
|
||||
Control.BACK => getDefaultGamepadBinds(Control.BACK),
|
||||
Control.UI_UP => getDefaultGamepadBinds(Control.UI_UP),
|
||||
Control.UI_DOWN => getDefaultGamepadBinds(Control.UI_DOWN),
|
||||
Control.UI_LEFT => getDefaultGamepadBinds(Control.UI_LEFT),
|
||||
Control.UI_RIGHT => getDefaultGamepadBinds(Control.UI_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],
|
||||
Control.RESET => [RIGHT_SHOULDER]
|
||||
#if CAN_CHEAT, Control.CHEAT => [X] #end
|
||||
Control.NOTE_UP => getDefaultGamepadBinds(Control.NOTE_UP),
|
||||
Control.NOTE_DOWN => getDefaultGamepadBinds(Control.NOTE_DOWN),
|
||||
Control.NOTE_LEFT => getDefaultGamepadBinds(Control.NOTE_LEFT),
|
||||
Control.NOTE_RIGHT => getDefaultGamepadBinds(Control.NOTE_RIGHT),
|
||||
Control.PAUSE => getDefaultGamepadBinds(Control.PAUSE),
|
||||
// Control.VOLUME_UP => [RIGHT_SHOULDER],
|
||||
// Control.VOLUME_DOWN => [LEFT_SHOULDER],
|
||||
// Control.VOLUME_MUTE => [RIGHT_TRIGGER],
|
||||
Control.CUTSCENE_ADVANCE => getDefaultGamepadBinds(Control.CUTSCENE_ADVANCE),
|
||||
Control.CUTSCENE_SKIP => getDefaultGamepadBinds(Control.CUTSCENE_SKIP),
|
||||
Control.RESET => getDefaultGamepadBinds(Control.RESET),
|
||||
#if CAN_CHEAT, Control.CHEAT => getDefaultGamepadBinds(Control.CHEAT) #end
|
||||
]);
|
||||
}
|
||||
|
||||
function getDefaultGamepadBinds(control:Control):Array<FlxGamepadInputID> {
|
||||
switch(control) {
|
||||
case Control.ACCEPT: return [#if switch B #else A #end];
|
||||
case Control.BACK: return [#if switch A #else B #end, FlxGamepadInputID.BACK];
|
||||
case Control.UI_UP: return [DPAD_UP, LEFT_STICK_DIGITAL_UP];
|
||||
case Control.UI_DOWN: return [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN];
|
||||
case Control.UI_LEFT: return [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT];
|
||||
case Control.UI_RIGHT: return [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT];
|
||||
case Control.NOTE_UP: return [DPAD_UP, Y, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP];
|
||||
case Control.NOTE_DOWN: return [DPAD_DOWN, A, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN];
|
||||
case Control.NOTE_LEFT: return [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT];
|
||||
case Control.NOTE_RIGHT: return [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT];
|
||||
case Control.PAUSE: return [START];
|
||||
case Control.CUTSCENE_ADVANCE: return [A];
|
||||
case Control.CUTSCENE_SKIP: return [START];
|
||||
case Control.RESET: return [RIGHT_SHOULDER];
|
||||
#if CAN_CHEAT, Control.CHEAT: return [X]; #end
|
||||
default:
|
||||
// Fallthrough.
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all actions that pertain to the binder to trigger when the supplied keys are used.
|
||||
* If binder is a literal you can inline this
|
||||
|
@ -749,8 +914,10 @@ class Controls extends FlxActionSet
|
|||
|
||||
inline static function addButtons(action:FlxActionDigital, buttons:Array<FlxGamepadInputID>, state, id)
|
||||
{
|
||||
for (button in buttons)
|
||||
for (button in buttons) {
|
||||
if (button == FlxGamepadInputID.NONE) continue; // Ignore unbound keys.
|
||||
action.addGamepad(button, state, id);
|
||||
}
|
||||
}
|
||||
|
||||
static function removeButtons(action:FlxActionDigital, gamepadID:Int, buttons:Array<FlxGamepadInputID>)
|
||||
|
@ -798,6 +965,11 @@ class Controls extends FlxActionSet
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: When loading controls:
|
||||
* An EMPTY array means the control is uninitialized and needs to be reset to default.
|
||||
* An array with a single FlxKey.NONE means the control was intentionally unbound by the user.
|
||||
*/
|
||||
public function fromSaveData(data:Dynamic, device:Device)
|
||||
{
|
||||
for (control in Control.createAll())
|
||||
|
@ -805,17 +977,44 @@ class Controls extends FlxActionSet
|
|||
var inputs:Array<Int> = Reflect.field(data, control.getName());
|
||||
if (inputs != null)
|
||||
{
|
||||
if (inputs.length == 0) {
|
||||
trace('Control ${control} is missing bindings, resetting to default.');
|
||||
switch(device)
|
||||
{
|
||||
case Keys:
|
||||
bindKeys(control, getDefaultKeybinds(Solo, control));
|
||||
case Gamepad(id):
|
||||
bindButtons(control, id, getDefaultGamepadBinds(control));
|
||||
}
|
||||
} else if (inputs == [FlxKey.NONE]) {
|
||||
trace('Control ${control} is unbound, leaving it be.');
|
||||
} else {
|
||||
switch(device)
|
||||
{
|
||||
case Keys:
|
||||
bindKeys(control, inputs.copy());
|
||||
case Gamepad(id):
|
||||
bindButtons(control, id, inputs.copy());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trace('Control ${control} is missing bindings, resetting to default.');
|
||||
switch(device)
|
||||
{
|
||||
case Keys:
|
||||
bindKeys(control, inputs.copy());
|
||||
bindKeys(control, getDefaultKeybinds(Solo, control));
|
||||
case Gamepad(id):
|
||||
bindButtons(control, id, inputs.copy());
|
||||
bindButtons(control, id, getDefaultGamepadBinds(control));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: When saving controls:
|
||||
* An EMPTY array means the control is uninitialized and needs to be reset to default.
|
||||
* An array with a single FlxKey.NONE means the control was intentionally unbound by the user.
|
||||
*/
|
||||
public function createSaveData(device:Device):Dynamic
|
||||
{
|
||||
var isEmpty = true;
|
||||
|
@ -825,6 +1024,8 @@ class Controls extends FlxActionSet
|
|||
var inputs = getInputsFor(control, device);
|
||||
isEmpty = isEmpty && inputs.length == 0;
|
||||
|
||||
if (inputs.length == 0) inputs = [FlxKey.NONE];
|
||||
|
||||
Reflect.setField(data, control.getName(), inputs);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import funkin.ui.TextMenuList;
|
|||
|
||||
class ControlsMenu extends funkin.ui.OptionsState.Page
|
||||
{
|
||||
inline static public var COLUMNS = 2;
|
||||
public static inline final COLUMNS = 2;
|
||||
static var controlList = Control.createAll();
|
||||
/*
|
||||
* Defines groups of controls that cannot share inputs, like left and right. Say, if ACCEPT is Z, Back is X,
|
||||
|
@ -23,7 +23,9 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
*/
|
||||
static var controlGroups:Array<Array<Control>> = [
|
||||
[NOTE_UP, NOTE_DOWN, NOTE_LEFT, NOTE_RIGHT],
|
||||
[UI_UP, UI_DOWN, UI_LEFT, UI_RIGHT, ACCEPT, BACK]
|
||||
[UI_UP, UI_DOWN, UI_LEFT, UI_RIGHT, ACCEPT, BACK],
|
||||
[CUTSCENE_ADVANCE, CUTSCENE_SKIP],
|
||||
[VOLUME_UP, VOLUME_DOWN, VOLUME_MUTE]
|
||||
];
|
||||
|
||||
var itemGroups:Array<Array<InputItem>> = [for (i in 0...controlGroups.length) []];
|
||||
|
@ -36,7 +38,7 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
var labels:FlxTypedGroup<AtlasText>;
|
||||
|
||||
var currentDevice:Device = Keys;
|
||||
var deviceListSelected = false;
|
||||
var deviceListSelected:Bool = false;
|
||||
|
||||
public function new()
|
||||
{
|
||||
|
@ -48,7 +50,7 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
camera = menuCamera;
|
||||
|
||||
labels = new FlxTypedGroup<AtlasText>();
|
||||
var headers = new FlxTypedGroup<AtlasText>();
|
||||
var headers:FlxTypedGroup<AtlasText> = new FlxTypedGroup<AtlasText>();
|
||||
controlGrid = new MenuTypedList(Columns(COLUMNS), Vertical);
|
||||
|
||||
add(labels);
|
||||
|
@ -57,20 +59,20 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
|
||||
if (FlxG.gamepads.numActiveGamepads > 0)
|
||||
{
|
||||
var devicesBg = new FlxSprite();
|
||||
devicesBg.makeGraphic(FlxG.width, 100, 0xFFfafd6d);
|
||||
var devicesBg:FlxSprite = new FlxSprite();
|
||||
devicesBg.makeGraphic(FlxG.width, 100, 0xFFFAFD6D);
|
||||
add(devicesBg);
|
||||
deviceList = new TextMenuList(Horizontal, None);
|
||||
add(deviceList);
|
||||
deviceListSelected = true;
|
||||
|
||||
var item;
|
||||
var item:TextMenuItem;
|
||||
|
||||
item = deviceList.createItem("Keyboard", AtlasFont.BOLD, selectDevice.bind(Keys));
|
||||
item = deviceList.createItem('Keyboard', AtlasFont.BOLD, selectDevice.bind(Keys));
|
||||
item.x = FlxG.width / 2 - item.width - 30;
|
||||
item.y = (devicesBg.height - item.height) / 2;
|
||||
|
||||
item = deviceList.createItem("Gamepad", AtlasFont.BOLD, selectDevice.bind(Gamepad(FlxG.gamepads.firstActive.id)));
|
||||
item = deviceList.createItem('Gamepad', AtlasFont.BOLD, selectDevice.bind(Gamepad(FlxG.gamepads.firstActive.id)));
|
||||
item.x = FlxG.width / 2 + 30;
|
||||
item.y = (devicesBg.height - item.height) / 2;
|
||||
}
|
||||
|
@ -96,6 +98,18 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
headers.add(new AtlasText(0, y, "NOTES", AtlasFont.BOLD)).screenCenter(X);
|
||||
y += spacer;
|
||||
}
|
||||
else if (currentHeader != "CUTSCENE_" && name.indexOf("CUTSCENE_") == 0)
|
||||
{
|
||||
currentHeader = "CUTSCENE_";
|
||||
headers.add(new AtlasText(0, y, "CUTSCENE", AtlasFont.BOLD)).screenCenter(X);
|
||||
y += spacer;
|
||||
}
|
||||
else if (currentHeader != "VOLUME_" && name.indexOf("VOLUME_") == 0)
|
||||
{
|
||||
currentHeader = "VOLUME_";
|
||||
headers.add(new AtlasText(0, y, "VOLUME", AtlasFont.BOLD)).screenCenter(X);
|
||||
y += spacer;
|
||||
}
|
||||
|
||||
if (currentHeader != null && name.indexOf(currentHeader) == 0) name = name.substr(currentHeader.length);
|
||||
|
||||
|
@ -128,7 +142,7 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 1.0;
|
||||
});
|
||||
|
||||
prompt = new Prompt("\nPress any key to rebind\n\n\n\n Escape to cancel", None);
|
||||
prompt = new Prompt("\nPress any key to rebind\n\n\nBackspace to unbind\n Escape to cancel", None);
|
||||
prompt.create();
|
||||
prompt.createBgFromMargin(100, 0xFFfafd6d);
|
||||
prompt.back.scrollFactor.set(0, 0);
|
||||
|
@ -149,6 +163,8 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
|
||||
function onSelect():Void
|
||||
{
|
||||
keyUsedToEnterPrompt = FlxG.keys.firstJustPressed();
|
||||
|
||||
controlGrid.enabled = false;
|
||||
canExit = false;
|
||||
prompt.exists = true;
|
||||
|
@ -187,7 +203,9 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
canExit = false;
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
var keyUsedToEnterPrompt:Null<Int> = null;
|
||||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
|
@ -200,18 +218,35 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
{
|
||||
case Keys:
|
||||
{
|
||||
// check released otherwise bugs can happen when you change the BACK key
|
||||
// Um?
|
||||
// Checking pressed causes problems when you change the BACK key,
|
||||
// but checking released causes problems when the prompt is instant.
|
||||
|
||||
// keyUsedToEnterPrompt is my weird workaround.
|
||||
|
||||
var key = FlxG.keys.firstJustReleased();
|
||||
if (key != NONE)
|
||||
if (key != NONE && key != keyUsedToEnterPrompt)
|
||||
{
|
||||
if (key != ESCAPE) onInputSelect(key);
|
||||
closePrompt();
|
||||
if (key == ESCAPE)
|
||||
{
|
||||
closePrompt();
|
||||
}
|
||||
else if (key == BACKSPACE)
|
||||
{
|
||||
onInputSelect(NONE);
|
||||
closePrompt();
|
||||
}
|
||||
else
|
||||
{
|
||||
onInputSelect(key);
|
||||
closePrompt();
|
||||
}
|
||||
}
|
||||
}
|
||||
case Gamepad(id):
|
||||
{
|
||||
var button = FlxG.gamepads.getByID(id).firstJustReleasedID();
|
||||
if (button != NONE)
|
||||
if (button != NONE && button != keyUsedToEnterPrompt)
|
||||
{
|
||||
if (button != BACK) onInputSelect(button);
|
||||
closePrompt();
|
||||
|
@ -219,23 +254,32 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
var keyJustReleased:Int = FlxG.keys.firstJustReleased();
|
||||
if (keyJustReleased != NONE && keyJustReleased == keyUsedToEnterPrompt)
|
||||
{
|
||||
keyUsedToEnterPrompt = null;
|
||||
}
|
||||
}
|
||||
|
||||
function onInputSelect(input:Int)
|
||||
function onInputSelect(input:Int):Void
|
||||
{
|
||||
var item = controlGrid.selectedItem;
|
||||
|
||||
// check if that key is already set for this
|
||||
var column0 = Math.floor(controlGrid.selectedIndex / 2) * 2;
|
||||
for (i in 0...COLUMNS)
|
||||
if (input != FlxKey.NONE)
|
||||
{
|
||||
if (controlGrid.members[column0 + i].input == input) return;
|
||||
var column0 = Math.floor(controlGrid.selectedIndex / 2) * 2;
|
||||
for (i in 0...COLUMNS)
|
||||
{
|
||||
if (controlGrid.members[column0 + i].input == input) return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if items in the same group already have the new input
|
||||
for (group in itemGroups)
|
||||
{
|
||||
if (group.contains(item))
|
||||
if (input != FlxKey.NONE && group.contains(item))
|
||||
{
|
||||
for (otherItem in group)
|
||||
{
|
||||
|
@ -252,10 +296,45 @@ class ControlsMenu extends funkin.ui.OptionsState.Page
|
|||
}
|
||||
|
||||
PlayerSettings.player1.controls.replaceBinding(item.control, currentDevice, input, item.input);
|
||||
|
||||
// Don't use resetItem() since items share names/labels
|
||||
item.input = input;
|
||||
item.label.text = item.getLabel(input);
|
||||
|
||||
// Shift left on the grid if the item on the right is bound and the item on the left is unbound.
|
||||
if (controlGrid.selectedIndex % 2 == 1)
|
||||
{
|
||||
trace('Modified item on right side of grid');
|
||||
var leftItem = controlGrid.members[controlGrid.selectedIndex - 1];
|
||||
if (leftItem != null && input != FlxKey.NONE && leftItem.input == FlxKey.NONE)
|
||||
{
|
||||
trace('Left item is unbound and right item is not!');
|
||||
// Swap them.
|
||||
var temp = leftItem.input;
|
||||
leftItem.input = item.input;
|
||||
item.input = temp;
|
||||
|
||||
leftItem.label.text = leftItem.getLabel(leftItem.input);
|
||||
item.label.text = item.getLabel(item.input);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trace('Modified item on left side of grid');
|
||||
var rightItem = controlGrid.members[controlGrid.selectedIndex + 1];
|
||||
if (rightItem != null && input == FlxKey.NONE && rightItem.input != FlxKey.NONE)
|
||||
{
|
||||
trace('Left item is unbound and right item is not!');
|
||||
// Swap them.
|
||||
var temp = item.input;
|
||||
item.input = rightItem.input;
|
||||
rightItem.input = temp;
|
||||
|
||||
item.label.text = item.getLabel(item.input);
|
||||
rightItem.label.text = rightItem.getLabel(rightItem.input);
|
||||
}
|
||||
}
|
||||
|
||||
PlayerSettings.player1.saveControls();
|
||||
}
|
||||
|
||||
|
@ -306,6 +385,8 @@ class InputItem extends TextMenuItem
|
|||
this.input = getInput();
|
||||
|
||||
super(x, y, getLabel(input), DEFAULT, callback);
|
||||
|
||||
this.fireInstantly = true;
|
||||
}
|
||||
|
||||
public function updateDevice(device:Device)
|
||||
|
@ -334,6 +415,6 @@ class InputItem extends TextMenuItem
|
|||
|
||||
public function getLabel(input:Int)
|
||||
{
|
||||
return input == -1 ? "---" : InputFormatter.format(input, device);
|
||||
return input == FlxKey.NONE ? "---" : InputFormatter.format(input, device);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue