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.
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user