diff --git a/src/Input.c b/src/Input.c index d88aa10c3..1b22b32dd 100644 --- a/src/Input.c +++ b/src/Input.c @@ -292,6 +292,8 @@ struct InputDevice NormDevice = { CCKEY_PAGEUP, CCKEY_PAGEDOWN, /* Launcher buttons */ CCKEY_TAB, + /* Bindings */ + "key-%c", NULL, NULL }; struct InputDevice PadDevice = { INPUT_DEVICE_GAMEPAD, 0, @@ -304,6 +306,8 @@ struct InputDevice PadDevice = { 0, 0, /* Launcher buttons */ CCPAD_3, + /* Bindings */ + "pad-%c", NULL, NULL }; struct InputDevice TouchDevice = { INPUT_DEVICE_TOUCH, 0, diff --git a/src/Input.h b/src/Input.h index 2c4f3a46d..126e5a835 100644 --- a/src/Input.h +++ b/src/Input.h @@ -92,7 +92,9 @@ void Input_SetNonRepeatable(int key, int pressed); void Input_Clear(void); struct InputDevice; +struct BindMapping_; typedef cc_bool (*InputDevice_IsPressed)(struct InputDevice* device, int key); + struct InputDevice { int type, index; /* Device type and index (e.g. controller port) */ InputDevice_IsPressed IsPressed; @@ -103,6 +105,10 @@ struct InputDevice { int pageUpButton, pageDownButton; /* Buttons in launcher mode */ int tabLauncher; + /* Bindings */ + const char* bindPrefix; + const struct BindMapping_* defaultBinds; + struct BindMapping_* currentBinds; }; #define INPUT_SOURCE_NORMAL (1 << 0) diff --git a/src/InputHandler.c b/src/InputHandler.c index fe132d5be..0b6bb8f7d 100644 --- a/src/InputHandler.c +++ b/src/InputHandler.c @@ -131,8 +131,10 @@ cc_bool InputBind_Claims(InputBind binding, int btn, struct InputDevice* device) cc_bool KeyBind_IsPressed(InputBind binding) { return Bind_IsTriggered[binding]; } -static void KeyBind_Load(const char* prefix, BindMapping* keybinds, const BindMapping* defaults) { +static void KeyBind_Load(struct InputDevice* device) { cc_string name; char nameBuffer[STRING_SIZE + 1]; + const BindMapping* defaults = device->defaultBinds; + BindMapping* keybinds = device->currentBinds; BindMapping mapping; cc_string str, part1, part2; int i; @@ -141,7 +143,7 @@ static void KeyBind_Load(const char* prefix, BindMapping* keybinds, const BindMa for (i = 0; i < BIND_COUNT; i++) { name.length = 0; - String_Format1(&name, prefix, bindNames[i]); + String_Format1(&name, device->bindPrefix, bindNames[i]); name.buffer[name.length] = '\0'; if (!Options_UNSAFE_Get(name.buffer, &str)) { @@ -153,53 +155,42 @@ static void KeyBind_Load(const char* prefix, BindMapping* keybinds, const BindMa mapping.button1 = Utils_ParseEnum(&part1, defaults[i].button1, Input_StorageNames, INPUT_COUNT); mapping.button2 = Utils_ParseEnum(&part2, defaults[i].button2, Input_StorageNames, INPUT_COUNT); - if (mapping.button1 == CCKEY_ESCAPE) mapping = defaults[i]; + if (mapping.button1 == CCKEY_ESCAPE) keybinds[i] = defaults[i]; keybinds[i] = mapping; } } -static void InputBind_Set(InputBind binding, int btn, BindMapping* binds, const char* fmt) { +void InputBind_Set(InputBind binding, int btn, struct InputDevice* device) { cc_string name; char nameBuffer[STRING_SIZE]; cc_string value; String_InitArray(name, nameBuffer); - String_Format1(&name, fmt, bindNames[binding]); + String_Format1(&name, device->bindPrefix, bindNames[binding]); value = String_FromReadonly(Input_StorageNames[btn]); Options_SetString(&name, &value); - BindMapping_Set(&binds[binding], btn, 0); + BindMapping_Set(&device->currentBinds[binding], btn, 0); } -void KeyBind_Set(InputBind binding, int btn) { - InputBind_Set(binding, btn, KeyBind_Mappings, "key-%c"); -} - -void PadBind_Set(InputBind binding, int btn) { - InputBind_Set(binding, btn, PadBind_Mappings, "pad-%c"); -} - -static void InputBind_ResetOption(InputBind binding, const char* fmt) { +void InputBind_Reset(InputBind binding, struct InputDevice* device) { cc_string name; char nameBuffer[STRING_SIZE]; String_InitArray(name, nameBuffer); - String_Format1(&name, fmt, bindNames[binding]); + String_Format1(&name, device->bindPrefix, bindNames[binding]); Options_SetString(&name, &String_Empty); -} - -void KeyBind_Reset(InputBind binding) { - InputBind_ResetOption(binding, "key-%c"); - KeyBind_Mappings[binding] = KeyBind_Defaults[binding]; -} - -void PadBind_Reset(InputBind binding) { - InputBind_ResetOption(binding, "pad-%c"); - PadBind_Mappings[binding] = PadBind_Defaults[binding]; + + device->currentBinds[binding] = device->defaultBinds[binding]; } /* Initialises and loads input bindings from options */ static void KeyBind_Init(void) { - KeyBind_Load("key-%c", KeyBind_Mappings, KeyBind_Defaults); - KeyBind_Load("pad-%c", PadBind_Mappings, PadBind_Defaults); + NormDevice.defaultBinds = KeyBind_Defaults; + PadDevice.defaultBinds = PadBind_Defaults; + NormDevice.currentBinds = KeyBind_Mappings; + PadDevice.currentBinds = PadBind_Mappings; + + KeyBind_Load(&NormDevice); + KeyBind_Load(&PadDevice); } diff --git a/src/InputHandler.h b/src/InputHandler.h index 87b34a4f2..fbaf24f69 100644 --- a/src/InputHandler.h +++ b/src/InputHandler.h @@ -55,14 +55,10 @@ cc_bool InputBind_Claims(InputBind binding, int btn, struct InputDevice* device) /* Gets whether the given input binding is currently being triggered */ CC_API cc_bool KeyBind_IsPressed(InputBind binding); -/* Sets the key/mouse button that the given input binding is bound to */ -void KeyBind_Set(InputBind binding, int btn); -/* Sets the gamepad button that the given input binding is bound to */ -void PadBind_Set(InputBind binding, int btn); -/* Resets the key/mouse button that the given input binding is bound to */ -void KeyBind_Reset(InputBind binding); -/* Resets the gamepad button that the given input binding is bound to */ -void PadBind_Reset(InputBind binding); +/* Sets the button that the given input binding is bound to */ +void InputBind_Set(InputBind binding, int btn, struct InputDevice* device); +/* Resets the button that the given input binding is bound to */ +void InputBind_Reset(InputBind binding, struct InputDevice* device); /* whether to leave text input open for user to enter further input */ diff --git a/src/Menus.c b/src/Menus.c index 3b6b3f6c0..2e50f0447 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -1853,17 +1853,17 @@ static struct BindsSourceScreen { Screen_Body struct ButtonWidget btns[2], cancel; } BindsSourceScreen; -static int binds_gamepad; /* Default to Normal (Keyboard/Mouse) */ +static struct InputDevice* bind_device; static struct Widget* bindsSource_widgets[3]; static void BindsSourceScreen_ModeNormal(void* screen, void* b) { - binds_gamepad = false; + bind_device = &NormDevice; NormalBindingsScreen_Show(); } static void BindsSourceScreen_ModeGamepad(void* screen, void* b) { - binds_gamepad = true; + bind_device = &PadDevice; NormalBindingsScreen_Show(); } @@ -1921,10 +1921,10 @@ static void SwitchBindsMain(void* s, void* w) { /* User needs to decide whether to configure mouse/keyboard or gamepad */ BindsSourceScreen_Show(); } else if (Input.Sources == INPUT_SOURCE_GAMEPAD) { - binds_gamepad = true; + bind_device = &PadDevice; NormalBindingsScreen_Show(); } else { - binds_gamepad = false; + bind_device = &NormDevice; NormalBindingsScreen_Show(); } } @@ -1954,19 +1954,12 @@ static struct KeyBindsScreen { static struct Widget* key_widgets[KEYBINDS_MAX_BTNS + 5]; -static BindMapping KeyBindsScreen_GetBinding(struct KeyBindsScreen* s, int i) { - const BindMapping* curBinds; - - curBinds = binds_gamepad ? PadBind_Mappings : KeyBind_Mappings; - return curBinds[s->binds[i]]; -} - static void KeyBindsScreen_Update(struct KeyBindsScreen* s, int i) { cc_string text; char textBuffer[STRING_SIZE]; BindMapping curBind; String_InitArray(text, textBuffer); - curBind = KeyBindsScreen_GetBinding(s, i); + curBind = bind_device->currentBinds[s->binds[i]]; String_Format4(&text, s->curI == i ? "> %c: %c%c%c <" : "%c: %c%c%c", s->descs[i], @@ -1978,35 +1971,20 @@ static void KeyBindsScreen_Update(struct KeyBindsScreen* s, int i) { s->dirty = true; } -static void KeyBindsScreen_ResetBinding(InputBind bind) { - if (binds_gamepad) { - PadBind_Reset(bind); - } else { - KeyBind_Reset(bind); - } -} - -static void KeyBindsScreen_UpdateBinding(InputBind bind, int key, struct InputDevice* device) { - if (binds_gamepad) { - PadBind_Set(bind, key); - } else { - KeyBind_Set(bind, key); - } -} - static void KeyBindsScreen_TriggerBinding(int key, struct InputDevice* device) { struct KeyBindsScreen* s = &KeyBindsScreen; InputBind bind; int idx; - + if (device->type != bind_device->type) return; + Input.DownHook = NULL; if (s->curI == -1) return; bind = s->binds[s->curI]; if (key == device->escapeButton) { - KeyBindsScreen_ResetBinding(bind); + InputBind_Reset(bind, bind_device); } else { - KeyBindsScreen_UpdateBinding(bind, key, device); + InputBind_Set(bind, key, bind_device); } idx = s->curI; @@ -2153,7 +2131,7 @@ static void KeyBindsScreen_Show(int bindsCount, const cc_uint8* binds, const cha void ClassicBindingsScreen_Show(void) { static const cc_uint8 binds[] = { BIND_FORWARD, BIND_BACK, BIND_JUMP, BIND_CHAT, BIND_SET_SPAWN, BIND_LEFT, BIND_RIGHT, BIND_INVENTORY, BIND_FOG, BIND_RESPAWN }; static const char* const descs[] = { "Forward", "Back", "Jump", "Chat", "Save location", "Left", "Right", "Build", "Toggle fog", "Load location" }; - binds_gamepad = false; + bind_device = Input.Sources == INPUT_SOURCE_GAMEPAD ? &PadDevice : &NormDevice; if (Game_ClassicHacks) { KeyBindsScreen_Reset(NULL, Menu_SwitchBindsClassicHacks, 260); @@ -2172,7 +2150,7 @@ void ClassicBindingsScreen_Show(void) { void ClassicHacksBindingsScreen_Show(void) { static const cc_uint8 binds[6] = { BIND_SPEED, BIND_NOCLIP, BIND_HALF_SPEED, BIND_FLY, BIND_FLY_UP, BIND_FLY_DOWN }; static const char* const descs[6] = { "Speed", "Noclip", "Half speed", "Fly", "Fly up", "Fly down" }; - binds_gamepad = false; + bind_device = Input.Sources == INPUT_SOURCE_GAMEPAD ? &PadDevice : &NormDevice; KeyBindsScreen_Reset(Menu_SwitchBindsClassic, NULL, 260); KeyBindsScreen_SetLayout(-90, -40, 3);