Make bind mapping a bit less hardcoded

This commit is contained in:
UnknownShadow200 2024-07-13 08:18:31 +10:00
parent 2b0941bccd
commit dbab0091b2
5 changed files with 45 additions and 70 deletions

View File

@ -292,6 +292,8 @@ struct InputDevice NormDevice = {
CCKEY_PAGEUP, CCKEY_PAGEDOWN, CCKEY_PAGEUP, CCKEY_PAGEDOWN,
/* Launcher buttons */ /* Launcher buttons */
CCKEY_TAB, CCKEY_TAB,
/* Bindings */
"key-%c", NULL, NULL
}; };
struct InputDevice PadDevice = { struct InputDevice PadDevice = {
INPUT_DEVICE_GAMEPAD, 0, INPUT_DEVICE_GAMEPAD, 0,
@ -304,6 +306,8 @@ struct InputDevice PadDevice = {
0, 0, 0, 0,
/* Launcher buttons */ /* Launcher buttons */
CCPAD_3, CCPAD_3,
/* Bindings */
"pad-%c", NULL, NULL
}; };
struct InputDevice TouchDevice = { struct InputDevice TouchDevice = {
INPUT_DEVICE_TOUCH, 0, INPUT_DEVICE_TOUCH, 0,

View File

@ -92,7 +92,9 @@ void Input_SetNonRepeatable(int key, int pressed);
void Input_Clear(void); void Input_Clear(void);
struct InputDevice; struct InputDevice;
struct BindMapping_;
typedef cc_bool (*InputDevice_IsPressed)(struct InputDevice* device, int key); typedef cc_bool (*InputDevice_IsPressed)(struct InputDevice* device, int key);
struct InputDevice { struct InputDevice {
int type, index; /* Device type and index (e.g. controller port) */ int type, index; /* Device type and index (e.g. controller port) */
InputDevice_IsPressed IsPressed; InputDevice_IsPressed IsPressed;
@ -103,6 +105,10 @@ struct InputDevice {
int pageUpButton, pageDownButton; int pageUpButton, pageDownButton;
/* Buttons in launcher mode */ /* Buttons in launcher mode */
int tabLauncher; int tabLauncher;
/* Bindings */
const char* bindPrefix;
const struct BindMapping_* defaultBinds;
struct BindMapping_* currentBinds;
}; };
#define INPUT_SOURCE_NORMAL (1 << 0) #define INPUT_SOURCE_NORMAL (1 << 0)

View File

@ -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]; } 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]; cc_string name; char nameBuffer[STRING_SIZE + 1];
const BindMapping* defaults = device->defaultBinds;
BindMapping* keybinds = device->currentBinds;
BindMapping mapping; BindMapping mapping;
cc_string str, part1, part2; cc_string str, part1, part2;
int i; int i;
@ -141,7 +143,7 @@ static void KeyBind_Load(const char* prefix, BindMapping* keybinds, const BindMa
for (i = 0; i < BIND_COUNT; i++) for (i = 0; i < BIND_COUNT; i++)
{ {
name.length = 0; name.length = 0;
String_Format1(&name, prefix, bindNames[i]); String_Format1(&name, device->bindPrefix, bindNames[i]);
name.buffer[name.length] = '\0'; name.buffer[name.length] = '\0';
if (!Options_UNSAFE_Get(name.buffer, &str)) { 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.button1 = Utils_ParseEnum(&part1, defaults[i].button1, Input_StorageNames, INPUT_COUNT);
mapping.button2 = Utils_ParseEnum(&part2, defaults[i].button2, 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; 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 name; char nameBuffer[STRING_SIZE];
cc_string value; cc_string value;
String_InitArray(name, nameBuffer); String_InitArray(name, nameBuffer);
String_Format1(&name, fmt, bindNames[binding]); String_Format1(&name, device->bindPrefix, bindNames[binding]);
value = String_FromReadonly(Input_StorageNames[btn]); value = String_FromReadonly(Input_StorageNames[btn]);
Options_SetString(&name, &value); Options_SetString(&name, &value);
BindMapping_Set(&binds[binding], btn, 0); BindMapping_Set(&device->currentBinds[binding], btn, 0);
} }
void KeyBind_Set(InputBind binding, int btn) { void InputBind_Reset(InputBind binding, struct InputDevice* device) {
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) {
cc_string name; char nameBuffer[STRING_SIZE]; cc_string name; char nameBuffer[STRING_SIZE];
String_InitArray(name, nameBuffer); String_InitArray(name, nameBuffer);
String_Format1(&name, fmt, bindNames[binding]); String_Format1(&name, device->bindPrefix, bindNames[binding]);
Options_SetString(&name, &String_Empty); Options_SetString(&name, &String_Empty);
}
device->currentBinds[binding] = device->defaultBinds[binding];
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];
} }
/* Initialises and loads input bindings from options */ /* Initialises and loads input bindings from options */
static void KeyBind_Init(void) { static void KeyBind_Init(void) {
KeyBind_Load("key-%c", KeyBind_Mappings, KeyBind_Defaults); NormDevice.defaultBinds = KeyBind_Defaults;
KeyBind_Load("pad-%c", PadBind_Mappings, PadBind_Defaults); PadDevice.defaultBinds = PadBind_Defaults;
NormDevice.currentBinds = KeyBind_Mappings;
PadDevice.currentBinds = PadBind_Mappings;
KeyBind_Load(&NormDevice);
KeyBind_Load(&PadDevice);
} }

View File

@ -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 */ /* Gets whether the given input binding is currently being triggered */
CC_API cc_bool KeyBind_IsPressed(InputBind binding); CC_API cc_bool KeyBind_IsPressed(InputBind binding);
/* Sets the key/mouse button that the given input binding is bound to */ /* Sets the button that the given input binding is bound to */
void KeyBind_Set(InputBind binding, int btn); void InputBind_Set(InputBind binding, int btn, struct InputDevice* device);
/* Sets the gamepad button that the given input binding is bound to */ /* Resets the button that the given input binding is bound to */
void PadBind_Set(InputBind binding, int btn); void InputBind_Reset(InputBind binding, struct InputDevice* device);
/* 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);
/* whether to leave text input open for user to enter further input */ /* whether to leave text input open for user to enter further input */

View File

@ -1853,17 +1853,17 @@ static struct BindsSourceScreen {
Screen_Body Screen_Body
struct ButtonWidget btns[2], cancel; struct ButtonWidget btns[2], cancel;
} BindsSourceScreen; } BindsSourceScreen;
static int binds_gamepad; /* Default to Normal (Keyboard/Mouse) */ static struct InputDevice* bind_device;
static struct Widget* bindsSource_widgets[3]; static struct Widget* bindsSource_widgets[3];
static void BindsSourceScreen_ModeNormal(void* screen, void* b) { static void BindsSourceScreen_ModeNormal(void* screen, void* b) {
binds_gamepad = false; bind_device = &NormDevice;
NormalBindingsScreen_Show(); NormalBindingsScreen_Show();
} }
static void BindsSourceScreen_ModeGamepad(void* screen, void* b) { static void BindsSourceScreen_ModeGamepad(void* screen, void* b) {
binds_gamepad = true; bind_device = &PadDevice;
NormalBindingsScreen_Show(); NormalBindingsScreen_Show();
} }
@ -1921,10 +1921,10 @@ static void SwitchBindsMain(void* s, void* w) {
/* User needs to decide whether to configure mouse/keyboard or gamepad */ /* User needs to decide whether to configure mouse/keyboard or gamepad */
BindsSourceScreen_Show(); BindsSourceScreen_Show();
} else if (Input.Sources == INPUT_SOURCE_GAMEPAD) { } else if (Input.Sources == INPUT_SOURCE_GAMEPAD) {
binds_gamepad = true; bind_device = &PadDevice;
NormalBindingsScreen_Show(); NormalBindingsScreen_Show();
} else { } else {
binds_gamepad = false; bind_device = &NormDevice;
NormalBindingsScreen_Show(); NormalBindingsScreen_Show();
} }
} }
@ -1954,19 +1954,12 @@ static struct KeyBindsScreen {
static struct Widget* key_widgets[KEYBINDS_MAX_BTNS + 5]; 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) { static void KeyBindsScreen_Update(struct KeyBindsScreen* s, int i) {
cc_string text; char textBuffer[STRING_SIZE]; cc_string text; char textBuffer[STRING_SIZE];
BindMapping curBind; BindMapping curBind;
String_InitArray(text, textBuffer); 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", String_Format4(&text, s->curI == i ? "> %c: %c%c%c <" : "%c: %c%c%c",
s->descs[i], s->descs[i],
@ -1978,35 +1971,20 @@ static void KeyBindsScreen_Update(struct KeyBindsScreen* s, int i) {
s->dirty = true; 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) { static void KeyBindsScreen_TriggerBinding(int key, struct InputDevice* device) {
struct KeyBindsScreen* s = &KeyBindsScreen; struct KeyBindsScreen* s = &KeyBindsScreen;
InputBind bind; InputBind bind;
int idx; int idx;
if (device->type != bind_device->type) return;
Input.DownHook = NULL; Input.DownHook = NULL;
if (s->curI == -1) return; if (s->curI == -1) return;
bind = s->binds[s->curI]; bind = s->binds[s->curI];
if (key == device->escapeButton) { if (key == device->escapeButton) {
KeyBindsScreen_ResetBinding(bind); InputBind_Reset(bind, bind_device);
} else { } else {
KeyBindsScreen_UpdateBinding(bind, key, device); InputBind_Set(bind, key, bind_device);
} }
idx = s->curI; idx = s->curI;
@ -2153,7 +2131,7 @@ static void KeyBindsScreen_Show(int bindsCount, const cc_uint8* binds, const cha
void ClassicBindingsScreen_Show(void) { 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 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" }; 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) { if (Game_ClassicHacks) {
KeyBindsScreen_Reset(NULL, Menu_SwitchBindsClassicHacks, 260); KeyBindsScreen_Reset(NULL, Menu_SwitchBindsClassicHacks, 260);
@ -2172,7 +2150,7 @@ void ClassicBindingsScreen_Show(void) {
void ClassicHacksBindingsScreen_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 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" }; 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_Reset(Menu_SwitchBindsClassic, NULL, 260);
KeyBindsScreen_SetLayout(-90, -40, 3); KeyBindsScreen_SetLayout(-90, -40, 3);