summaryrefslogtreecommitdiff
path: root/src/setup/txt_joybinput.c
diff options
context:
space:
mode:
authorSimon Howard2014-05-01 00:19:51 -0400
committerSimon Howard2014-05-01 00:19:51 -0400
commit05f22d03aa25c55f5b7251d474eee16054f37e9e (patch)
tree93f5313511e47674e8ed3403966d40d079ac6caa /src/setup/txt_joybinput.c
parent4890591ba50bfc8b11cda684b223cb7c551e6dd3 (diff)
downloadchocolate-doom-05f22d03aa25c55f5b7251d474eee16054f37e9e.tar.gz
chocolate-doom-05f22d03aa25c55f5b7251d474eee16054f37e9e.tar.bz2
chocolate-doom-05f22d03aa25c55f5b7251d474eee16054f37e9e.zip
setup: Configure joystick buttons with virtual mapping.
Refactor how joystick buttons are reassigned. Define a fixed mapping from joyb* variables to virtual buttons, and change the button assignments at the virtual->physical mapping level.
Diffstat (limited to 'src/setup/txt_joybinput.c')
-rw-r--r--src/setup/txt_joybinput.c135
1 files changed, 128 insertions, 7 deletions
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)