diff options
Diffstat (limited to 'src/setup')
-rw-r--r-- | src/setup/joystick.c | 32 | ||||
-rw-r--r-- | src/setup/txt_joybinput.c | 135 |
2 files changed, 130 insertions, 37 deletions
diff --git a/src/setup/joystick.c b/src/setup/joystick.c index cc5c4a8e..3eedda1e 100644 --- a/src/setup/joystick.c +++ b/src/setup/joystick.c @@ -90,18 +90,12 @@ static int joystick_strafe_axis = -1; static int joystick_strafe_invert = 0; // Virtual to physical mapping. -static int joystick_physical_buttons[NUM_VIRTUAL_BUTTONS] = { +int joystick_physical_buttons[NUM_VIRTUAL_BUTTONS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; static txt_button_t *joystick_button; -static int *all_joystick_buttons[] = { - &joybstraferight, &joybstrafeleft, &joybfire, &joybspeed, - &joybuse, &joybstrafe, &joybprevweapon, &joybnextweapon, &joybjump, - &joybmenu, -}; - // // Calibration // @@ -580,27 +574,7 @@ static void CalibrateJoystick(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused)) SetCalibrationLabel(); } -void JoyButtonSetCallback(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(variable)) -{ - TXT_CAST_ARG(int, variable); - unsigned int i; - - // Only allow a button to be bound to one action at a time. If - // we assign a key that another action is using, set that other action - // to -1. - - for (i=0; i<arrlen(all_joystick_buttons); ++i) - { - if (variable != all_joystick_buttons[i] - && *variable == *all_joystick_buttons[i]) - { - *all_joystick_buttons[i] = -1; - } - } -} - - -// +// // GUI // @@ -621,8 +595,6 @@ static void AddJoystickControl(txt_table_t *table, char *label, int *var) TXT_AddWidget(table, TXT_NewLabel(label)); TXT_AddWidget(table, joy_input); - - TXT_SignalConnect(joy_input, "set", JoyButtonSetCallback, var); } void ConfigJoystick(void) diff --git a/src/setup/txt_joybinput.c b/src/setup/txt_joybinput.c index f431690b..ab56e229 100644 --- a/src/setup/txt_joybinput.c +++ b/src/setup/txt_joybinput.c @@ -27,6 +27,9 @@ #include "doomkeys.h" #include "joystick.h" +#include "i_joystick.h" +#include "i_system.h" +#include "m_controls.h" #include "m_misc.h" #include "txt_joybinput.h" @@ -38,6 +41,111 @@ #define JOYSTICK_INPUT_WIDTH 10 +extern int joystick_physical_buttons[NUM_VIRTUAL_BUTTONS]; + +// Joystick button variables. +// The ordering of this array is important. We will always try to map +// each variable to the virtual button with the same array index. For +// example: joybfire should always be 0, and then we change +// joystick_physical_buttons[0] to point to the physical joystick +// button that the user wants to use for firing. We do this so that +// the menus work (the game code is hard coded to interpret +// button #0 = select menu item, button #1 = go back to previous menu). +static int *all_joystick_buttons[] = +{ + &joybfire, + &joybuse, + &joybstrafe, + &joybspeed, + &joybstrafeleft, + &joybstraferight, + &joybprevweapon, + &joybnextweapon, + &joybjump, + &joybmenu, +}; + +static int PhysicalForVirtualButton(int vbutton) +{ + if (vbutton < NUM_VIRTUAL_BUTTONS) + { + return joystick_physical_buttons[vbutton]; + } + else + { + return vbutton; + } +} + +// Get the virtual button number for the given variable, ie. the +// variable's index in all_joystick_buttons[]. +static int VirtualButtonForVariable(int *variable) +{ + int i; + + for (i = 0; i < arrlen(all_joystick_buttons); ++i) + { + if (variable == all_joystick_buttons[i]) + { + return i; + } + } + + I_Error("Couldn't find virtual button"); + return -1; +} + +// Rearrange joystick button configuration to be in "canonical" form: +// each joyb* variable should have a value equal to its index in +// all_joystick_buttons[] above. +static void CanonicalizeButtons(void) +{ + int new_mapping[NUM_VIRTUAL_BUTTONS]; + int vbutton; + int i; + + for (i = 0; i < arrlen(all_joystick_buttons); ++i) + { + vbutton = *all_joystick_buttons[i]; + + // Don't remap the speed key if it's bound to "always run". + // Also preserve "unbound" variables. + if ((all_joystick_buttons[i] == &joybspeed && vbutton >= 20) + || vbutton < 0) + { + new_mapping[i] = i; + } + else + { + new_mapping[i] = PhysicalForVirtualButton(vbutton); + *all_joystick_buttons[i] = i; + } + } + + for (i = 0; i < NUM_VIRTUAL_BUTTONS; ++i) + { + joystick_physical_buttons[i] = new_mapping[i]; + } +} + +// Check all existing buttons and clear any using the specified physical +// button. +static void ClearVariablesUsingButton(int physbutton) +{ + int vbutton; + int i; + + for (i = 0; i < arrlen(all_joystick_buttons); ++i) + { + vbutton = *all_joystick_buttons[i]; + + if (vbutton >= 0 && physbutton == PhysicalForVirtualButton(vbutton)) + { + *all_joystick_buttons[i] = -1; + } + } +} + // Called in response to SDL events when the prompt window is open: static int EventCallback(SDL_Event *event, TXT_UNCAST_ARG(joystick_input)) @@ -48,13 +156,24 @@ static int EventCallback(SDL_Event *event, TXT_UNCAST_ARG(joystick_input)) if (event->type == SDL_JOYBUTTONDOWN) { - *joystick_input->variable = event->jbutton.button; + int vbutton, physbutton; + + // Before changing anything, remap button configuration into + // canonical form, to avoid conflicts. + CanonicalizeButtons(); + + vbutton = VirtualButtonForVariable(joystick_input->variable); + physbutton = event->jbutton.button; if (joystick_input->check_conflicts) { - TXT_EmitSignal(joystick_input, "set"); + ClearVariablesUsingButton(physbutton); } + // Set mapping. + *joystick_input->variable = vbutton; + joystick_physical_buttons[vbutton] = physbutton; + TXT_CloseWindow(joystick_input->prompt_window); return 1; } @@ -125,9 +244,11 @@ static void TXT_JoystickInputSizeCalc(TXT_UNCAST_ARG(joystick_input)) joystick_input->widget.h = 1; } -static void GetJoystickButtonDescription(int button, char *buf, size_t buf_len) +static void GetJoystickButtonDescription(int vbutton, char *buf, + size_t buf_len) { - M_snprintf(buf, buf_len, "BUTTON #%i", button + 1); + M_snprintf(buf, buf_len, "BUTTON #%i", + PhysicalForVirtualButton(vbutton) + 1); } static void TXT_JoystickInputDrawer(TXT_UNCAST_ARG(joystick_input)) @@ -148,9 +269,9 @@ static void TXT_JoystickInputDrawer(TXT_UNCAST_ARG(joystick_input)) TXT_SetWidgetBG(joystick_input); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); - + TXT_DrawString(buf); - + for (i=strlen(buf); i<JOYSTICK_INPUT_WIDTH; ++i) { TXT_DrawString(" "); @@ -185,7 +306,7 @@ static int TXT_JoystickInputKeyPress(TXT_UNCAST_ARG(joystick_input), int key) static void TXT_JoystickInputMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b) { TXT_CAST_ARG(txt_joystick_input_t, widget); - + // Clicking is like pressing enter if (b == TXT_MOUSE_LEFT) |