From 40c60bc08a4b23ac814da2a5ed7c78ccf1a96bad Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sun, 11 Aug 2019 20:14:11 -0700 Subject: [PATCH] Generalize VControl to work with SDL1 and SDL2. SDL2's keycodes do not form a contiguous range the way SDL1's do, so we need to perform separate chaining of bindings. --- sc2/src/libs/input/sdl/keynames.c | 17 +++- sc2/src/libs/input/sdl/vcontrol.c | 137 +++++++++++++++--------------- sc2/src/libs/input/sdl/vcontrol.h | 16 ++-- 3 files changed, 94 insertions(+), 76 deletions(-) diff --git a/sc2/src/libs/input/sdl/keynames.c b/sc2/src/libs/input/sdl/keynames.c index c33338cd8..b3d197bef 100644 --- a/sc2/src/libs/input/sdl/keynames.c +++ b/sc2/src/libs/input/sdl/keynames.c @@ -109,6 +109,7 @@ static keyname keynames[] = { {"y", SDLK_y}, {"z", SDLK_z}, {"Delete", SDLK_DELETE}, +#if SDL_MAJOR_VERSION == 1 {"Keypad-0", SDLK_KP0}, {"Keypad-1", SDLK_KP1}, {"Keypad-2", SDLK_KP2}, @@ -119,6 +120,18 @@ static keyname keynames[] = { {"Keypad-7", SDLK_KP7}, {"Keypad-8", SDLK_KP8}, {"Keypad-9", SDLK_KP9}, +#else + {"Keypad-0", SDLK_KP_0}, + {"Keypad-1", SDLK_KP_1}, + {"Keypad-2", SDLK_KP_2}, + {"Keypad-3", SDLK_KP_3}, + {"Keypad-4", SDLK_KP_4}, + {"Keypad-5", SDLK_KP_5}, + {"Keypad-6", SDLK_KP_6}, + {"Keypad-7", SDLK_KP_7}, + {"Keypad-8", SDLK_KP_8}, + {"Keypad-9", SDLK_KP_9}, +#endif {"Keypad-.", SDLK_KP_PERIOD}, {"Keypad-/", SDLK_KP_DIVIDE}, {"Keypad-*", SDLK_KP_MULTIPLY}, @@ -156,6 +169,7 @@ static keyname keynames[] = { {"LeftControl", SDLK_LCTRL}, {"RightAlt", SDLK_RALT}, {"LeftAlt", SDLK_LALT}, +#if SDL_MAJOR_VERSION == 1 {"RightMeta", SDLK_RMETA}, {"LeftMeta", SDLK_LMETA}, {"RightSuper", SDLK_RSUPER}, @@ -177,7 +191,8 @@ static keyname keynames[] = { {"App4", SDLK_APP4}, {"App5", SDLK_APP5}, {"App6", SDLK_APP6}, -#endif +#endif /* _WIN32_WCE */ +#endif /* SDL_MAJOR_VERSION == 1 */ {"Unknown", 0}}; /* Last element must have code zero */ diff --git a/sc2/src/libs/input/sdl/vcontrol.c b/sc2/src/libs/input/sdl/vcontrol.c index 089cb1132..9dedbcc73 100644 --- a/sc2/src/libs/input/sdl/vcontrol.c +++ b/sc2/src/libs/input/sdl/vcontrol.c @@ -28,8 +28,15 @@ /* How many binding slots are allocated at once. */ #define POOL_CHUNK_SIZE 64 +/* Total number of key input buckets. SDL1 keys are a simple enum, + * but SDL2 scatters key symbols through the entire 32-bit space, + * so we do not rely on being able to declare an array with one + * entry per key. */ +#define KEYBOARD_INPUT_BUCKETS 512 + typedef struct vcontrol_keybinding { int *target; + sdl_key_t keycode; struct vcontrol_keypool *parent; struct vcontrol_keybinding *next; } keybinding; @@ -67,8 +74,7 @@ static joystick *joysticks; #endif /* HAVE_JOYSTICK */ static unsigned int joycount; -static unsigned int num_sdl_keys = 0; -static keybinding **bindings = NULL; +static keybinding *bindings[KEYBOARD_INPUT_BUCKETS]; static keypool *pool; @@ -88,6 +94,7 @@ allocate_key_chunk (void) for (i = 0; i < POOL_CHUNK_SIZE; i++) { x->pool[i].target = NULL; + x->pool[i].keycode = SDLK_UNKNOWN; x->pool[i].next = NULL; x->pool[i].parent = x; } @@ -127,7 +134,11 @@ create_joystick (int index) { joystick *x = &joysticks[index]; int j; +#if SDL_MAJOR_VERSION == 1 log_add (log_Info, "VControl opened joystick: %s", SDL_JoystickName (index)); +#else + log_add (log_Info, "VControl opened joystick: %s", SDL_JoystickName (stick)); +#endif axes = SDL_JoystickNumAxes (stick); buttons = SDL_JoystickNumButtons (stick); hats = SDL_JoystickNumHats (stick); @@ -185,9 +196,7 @@ key_init (void) { unsigned int i; pool = allocate_key_chunk (); - (void)SDL_GetKeyState (&num_sdl_keys); - bindings = (keybinding **) HMalloc (sizeof (keybinding *) * num_sdl_keys); - for (i = 0; i < num_sdl_keys; i++) + for (i = 0; i < KEYBOARD_INPUT_BUCKETS; i++) bindings[i] = NULL; #ifdef HAVE_JOYSTICK @@ -221,10 +230,8 @@ key_uninit (void) { unsigned int i; free_key_pool (pool); - for (i = 0; i < num_sdl_keys; i++) + for (i = 0; i < KEYBOARD_INPUT_BUCKETS; i++) bindings[i] = NULL; - HFree (bindings); - bindings = NULL; pool = NULL; #ifdef HAVE_JOYSTICK @@ -268,7 +275,7 @@ VControl_SetJoyThreshold (int port, int threshold) static void -add_binding (keybinding **newptr, int *target) +add_binding (keybinding **newptr, int *target, sdl_key_t keycode) { keybinding *newbinding; keypool *searchbase; @@ -279,7 +286,7 @@ add_binding (keybinding **newptr, int *target) * bound this symbol to this target. If we have, return.*/ while (*newptr != NULL) { - if ((*newptr)->target == target) + if (((*newptr)->target == target) && ((*newptr)->keycode == keycode)) { return; } @@ -321,24 +328,26 @@ add_binding (keybinding **newptr, int *target) } newbinding->target = target; + newbinding->keycode = keycode; newbinding->next = NULL; *newptr = newbinding; searchbase->remaining--; } static void -remove_binding (keybinding **ptr, int *target) +remove_binding (keybinding **ptr, int *target, sdl_key_t keycode) { if (!(*ptr)) { /* Nothing bound to symbol; return. */ return; } - else if ((*ptr)->target == target) + else if (((*ptr)->target == target) && ((*ptr)->keycode == keycode)) { keybinding *todel = *ptr; *ptr = todel->next; todel->target = NULL; + todel->keycode = SDLK_UNKNOWN; todel->next = NULL; todel->parent->remaining++; } @@ -352,6 +361,7 @@ remove_binding (keybinding **ptr, int *target) keybinding *todel = prev->next; prev->next = todel->next; todel->target = NULL; + todel->keycode = SDLK_UNKNOWN; todel->next = NULL; todel->parent->remaining++; } @@ -361,22 +371,25 @@ remove_binding (keybinding **ptr, int *target) } static void -activate (keybinding *i) +activate (keybinding *i, sdl_key_t keycode) { while (i != NULL) { - *(i->target) = (*(i->target)+1) | VCONTROL_STARTBIT; + if (i->keycode == keycode) + { + *(i->target) = (*(i->target)+1) | VCONTROL_STARTBIT; + } i = i->next; } } static void -deactivate (keybinding *i) +deactivate (keybinding *i, sdl_key_t keycode) { while (i != NULL) { int v = *(i->target) & VCONTROL_MASK; - if (v > 0) + if ((i->keycode == keycode) && (v > 0)) { *(i->target) = (v-1) | (*(i->target) & VCONTROL_STARTBIT); } @@ -487,24 +500,16 @@ VControl_RemoveGestureBinding (VCONTROL_GESTURE *g, int *target) } int -VControl_AddKeyBinding (SDLKey symbol, int *target) +VControl_AddKeyBinding (sdl_key_t symbol, int *target) { - if ((unsigned int) symbol >= num_sdl_keys) { - log_add (log_Warning, "VControl: Illegal key index %d", symbol); - return -1; - } - add_binding(&bindings[symbol], target); + add_binding(&bindings[symbol % KEYBOARD_INPUT_BUCKETS], target, symbol); return 0; } void -VControl_RemoveKeyBinding (SDLKey symbol, int *target) +VControl_RemoveKeyBinding (sdl_key_t symbol, int *target) { - if ((unsigned int) symbol >= num_sdl_keys) { - log_add (log_Warning, "VControl: Illegal key index %d", symbol); - return; - } - remove_binding (&bindings[symbol], target); + remove_binding (&bindings[symbol % KEYBOARD_INPUT_BUCKETS], target, symbol); } int @@ -520,11 +525,11 @@ VControl_AddJoyAxisBinding (int port, int axis, int polarity, int *target) { if (polarity < 0) { - add_binding(&joysticks[port].axes[axis].neg, target); + add_binding(&joysticks[port].axes[axis].neg, target, SDLK_UNKNOWN); } else if (polarity > 0) { - add_binding(&joysticks[port].axes[axis].pos, target); + add_binding(&joysticks[port].axes[axis].pos, target, SDLK_UNKNOWN); } else { @@ -565,11 +570,11 @@ VControl_RemoveJoyAxisBinding (int port, int axis, int polarity, int *target) { if (polarity < 0) { - remove_binding(&joysticks[port].axes[axis].neg, target); + remove_binding(&joysticks[port].axes[axis].neg, target, SDLK_UNKNOWN); } else if (polarity > 0) { - remove_binding(&joysticks[port].axes[axis].pos, target); + remove_binding(&joysticks[port].axes[axis].pos, target, SDLK_UNKNOWN); } else { @@ -604,7 +609,7 @@ VControl_AddJoyButtonBinding (int port, int button, int *target) create_joystick (port); if ((button >= 0) && (button < j->numbuttons)) { - add_binding(&joysticks[port].buttons[button], target); + add_binding(&joysticks[port].buttons[button], target, SDLK_UNKNOWN); return 0; } else @@ -636,7 +641,7 @@ VControl_RemoveJoyButtonBinding (int port, int button, int *target) create_joystick (port); if ((button >= 0) && (button < j->numbuttons)) { - remove_binding (&joysticks[port].buttons[button], target); + remove_binding (&joysticks[port].buttons[button], target, SDLK_UNKNOWN); } else { @@ -667,19 +672,19 @@ VControl_AddJoyHatBinding (int port, int which, Uint8 dir, int *target) { if (dir == SDL_HAT_LEFT) { - add_binding(&joysticks[port].hats[which].left, target); + add_binding(&joysticks[port].hats[which].left, target, SDLK_UNKNOWN); } else if (dir == SDL_HAT_RIGHT) { - add_binding(&joysticks[port].hats[which].right, target); + add_binding(&joysticks[port].hats[which].right, target, SDLK_UNKNOWN); } else if (dir == SDL_HAT_UP) { - add_binding(&joysticks[port].hats[which].up, target); + add_binding(&joysticks[port].hats[which].up, target, SDLK_UNKNOWN); } else if (dir == SDL_HAT_DOWN) { - add_binding(&joysticks[port].hats[which].down, target); + add_binding(&joysticks[port].hats[which].down, target, SDLK_UNKNOWN); } else { @@ -720,19 +725,19 @@ VControl_RemoveJoyHatBinding (int port, int which, Uint8 dir, int *target) { if (dir == SDL_HAT_LEFT) { - remove_binding(&joysticks[port].hats[which].left, target); + remove_binding(&joysticks[port].hats[which].left, target, SDLK_UNKNOWN); } else if (dir == SDL_HAT_RIGHT) { - remove_binding(&joysticks[port].hats[which].right, target); + remove_binding(&joysticks[port].hats[which].right, target, SDLK_UNKNOWN); } else if (dir == SDL_HAT_UP) { - remove_binding(&joysticks[port].hats[which].up, target); + remove_binding(&joysticks[port].hats[which].up, target, SDLK_UNKNOWN); } else if (dir == SDL_HAT_DOWN) { - remove_binding(&joysticks[port].hats[which].down, target); + remove_binding(&joysticks[port].hats[which].down, target, SDLK_UNKNOWN); } else { @@ -764,23 +769,15 @@ VControl_RemoveAllBindings (void) } void -VControl_ProcessKeyDown (SDLKey symbol) +VControl_ProcessKeyDown (sdl_key_t symbol) { - if (symbol >= num_sdl_keys) { - log_add (log_Warning, "VControl: Got unknown key index %d", symbol); - return; - } - - activate (bindings[symbol]); + activate (bindings[symbol % KEYBOARD_INPUT_BUCKETS], symbol); } void -VControl_ProcessKeyUp (SDLKey symbol) +VControl_ProcessKeyUp (sdl_key_t symbol) { - if (symbol >= num_sdl_keys) - return; - - deactivate (bindings[symbol]); + deactivate (bindings[symbol % KEYBOARD_INPUT_BUCKETS], symbol); } void @@ -789,7 +786,7 @@ VControl_ProcessJoyButtonDown (int port, int button) #ifdef HAVE_JOYSTICK if (!joysticks[port].stick) return; - activate (joysticks[port].buttons[button]); + activate (joysticks[port].buttons[button], SDLK_UNKNOWN); #else (void) port; (void) button; @@ -802,7 +799,7 @@ VControl_ProcessJoyButtonUp (int port, int button) #ifdef HAVE_JOYSTICK if (!joysticks[port].stick) return; - deactivate (joysticks[port].buttons[button]); + deactivate (joysticks[port].buttons[button], SDLK_UNKNOWN); #else (void) port; (void) button; @@ -823,10 +820,10 @@ VControl_ProcessJoyAxis (int port, int axis, int value) { if (joysticks[port].axes[axis].polarity == -1) { - deactivate (joysticks[port].axes[axis].neg); + deactivate (joysticks[port].axes[axis].neg, SDLK_UNKNOWN); } joysticks[port].axes[axis].polarity = 1; - activate (joysticks[port].axes[axis].pos); + activate (joysticks[port].axes[axis].pos, SDLK_UNKNOWN); } } else if (value < -t) @@ -835,21 +832,21 @@ VControl_ProcessJoyAxis (int port, int axis, int value) { if (joysticks[port].axes[axis].polarity == 1) { - deactivate (joysticks[port].axes[axis].pos); + deactivate (joysticks[port].axes[axis].pos, SDLK_UNKNOWN); } joysticks[port].axes[axis].polarity = -1; - activate (joysticks[port].axes[axis].neg); + activate (joysticks[port].axes[axis].neg, SDLK_UNKNOWN); } } else { if (joysticks[port].axes[axis].polarity == -1) { - deactivate (joysticks[port].axes[axis].neg); + deactivate (joysticks[port].axes[axis].neg, SDLK_UNKNOWN); } else if (joysticks[port].axes[axis].polarity == 1) { - deactivate (joysticks[port].axes[axis].pos); + deactivate (joysticks[port].axes[axis].pos, SDLK_UNKNOWN); } joysticks[port].axes[axis].polarity = 0; } @@ -869,21 +866,21 @@ VControl_ProcessJoyHat (int port, int which, Uint8 value) return; old = joysticks[port].hats[which].last; if (!(old & SDL_HAT_LEFT) && (value & SDL_HAT_LEFT)) - activate (joysticks[port].hats[which].left); + activate (joysticks[port].hats[which].left, SDLK_UNKNOWN); if (!(old & SDL_HAT_RIGHT) && (value & SDL_HAT_RIGHT)) - activate (joysticks[port].hats[which].right); + activate (joysticks[port].hats[which].right, SDLK_UNKNOWN); if (!(old & SDL_HAT_UP) && (value & SDL_HAT_UP)) - activate (joysticks[port].hats[which].up); + activate (joysticks[port].hats[which].up, SDLK_UNKNOWN); if (!(old & SDL_HAT_DOWN) && (value & SDL_HAT_DOWN)) - activate (joysticks[port].hats[which].down); + activate (joysticks[port].hats[which].down, SDLK_UNKNOWN); if ((old & SDL_HAT_LEFT) && !(value & SDL_HAT_LEFT)) - deactivate (joysticks[port].hats[which].left); + deactivate (joysticks[port].hats[which].left, SDLK_UNKNOWN); if ((old & SDL_HAT_RIGHT) && !(value & SDL_HAT_RIGHT)) - deactivate (joysticks[port].hats[which].right); + deactivate (joysticks[port].hats[which].right, SDLK_UNKNOWN); if ((old & SDL_HAT_UP) && !(value & SDL_HAT_UP)) - deactivate (joysticks[port].hats[which].up); + deactivate (joysticks[port].hats[which].up, SDLK_UNKNOWN); if ((old & SDL_HAT_DOWN) && !(value & SDL_HAT_DOWN)) - deactivate (joysticks[port].hats[which].down); + deactivate (joysticks[port].hats[which].down, SDLK_UNKNOWN); joysticks[port].hats[which].last = value; #else (void) port; diff --git a/sc2/src/libs/input/sdl/vcontrol.h b/sc2/src/libs/input/sdl/vcontrol.h index cc3b4652e..9c334451e 100644 --- a/sc2/src/libs/input/sdl/vcontrol.h +++ b/sc2/src/libs/input/sdl/vcontrol.h @@ -20,6 +20,12 @@ #include "port.h" #include SDL_INCLUDE(SDL.h) +#if SDL_MAJOR_VERSION == 1 +typedef SDLKey sdl_key_t; +#else +typedef SDL_Keycode sdl_key_t; +#endif + /* Initialization routines */ void VControl_Init (void); void VControl_Uninit (void); @@ -39,7 +45,7 @@ typedef enum { typedef struct { VCONTROL_GESTURE_TYPE type; union { - SDLKey key; + sdl_key_t key; struct { int port, index, polarity; } axis; struct { int port, index; } button; struct { int port, index; Uint8 dir; } hat; @@ -50,8 +56,8 @@ typedef struct { int VControl_AddGestureBinding (VCONTROL_GESTURE *g, int *target); void VControl_RemoveGestureBinding (VCONTROL_GESTURE *g, int *target); -int VControl_AddKeyBinding (SDLKey symbol, int *target); -void VControl_RemoveKeyBinding (SDLKey symbol, int *target); +int VControl_AddKeyBinding (sdl_key_t symbol, int *target); +void VControl_RemoveKeyBinding (sdl_key_t symbol, int *target); int VControl_AddJoyAxisBinding (int port, int axis, int polarity, int *target); void VControl_RemoveJoyAxisBinding (int port, int axis, int polarity, int *target); int VControl_SetJoyThreshold (int port, int threshold); @@ -69,8 +75,8 @@ void VControl_BeginFrame (void); * fabricating an SDL_Event. */ void VControl_HandleEvent (const SDL_Event *e); -void VControl_ProcessKeyDown (SDLKey symbol); -void VControl_ProcessKeyUp (SDLKey symbol); +void VControl_ProcessKeyDown (sdl_key_t symbol); +void VControl_ProcessKeyUp (sdl_key_t symbol); void VControl_ProcessJoyButtonDown (int port, int button); void VControl_ProcessJoyButtonUp (int port, int button); void VControl_ProcessJoyAxis (int port, int axis, int value);