[PATCH 02/13] Switch to using KeyMapping struct and KeysDown array |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
- Subject: [PATCH 02/13] Switch to using KeyMapping struct and KeysDown array
- From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
- Date: Tue, 12 Oct 2021 01:34:26 +0300
* New SDLKey STKey types will be expanded in future commits
* KeyMapping type is used in LoadedKeymap[] array, for PC -> ST key
mappings loaded from external keymap file
* KeysDown[] array (indexed by PC / SDL scancode) items are set
when a key is pressed, and used when it is released
Inspired by Vincent Barilliot's patch.
---
src/keymap.c | 140 +++++++++++++++++++++++++++++++++++++--------------
1 file changed, 101 insertions(+), 39 deletions(-)
diff --git a/src/keymap.c b/src/keymap.c
index a0407d81..d39bccef 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -10,6 +10,7 @@
*/
const char Keymap_fileid[] = "Hatari keymap.c";
+#include <assert.h>
#include <ctype.h>
#include "main.h"
#include "keymap.h"
@@ -26,9 +27,6 @@ const char Keymap_fileid[] = "Hatari keymap.c";
/* if not able to map */
#define ST_NO_SCANCODE 0xff
-/* Table for loaded keys: */
-static int LoadedKeymap[KBD_MAX_SCANCODE][2];
-
/* List of ST scan codes to NOT de-bounce when running in maximum speed */
static const uint8_t DebounceExtendedKeys[] =
{
@@ -40,6 +38,30 @@ static const uint8_t DebounceExtendedKeys[] =
0 /* term */
};
+typedef struct
+{
+ SDL_Scancode scancode;
+} SDLKey;
+
+typedef struct
+{
+ uint8_t scancode;
+} ST_Key;
+
+/* Key mappings: pair SDL key definition with ST key */
+typedef struct
+{
+ /* Input on PC keyboard */
+ SDLKey pc;
+ /* Output on the ST keyboard */
+ ST_Key st;
+} KeyMapping;
+
+/* Loaded PC->ST key mappings */
+static KeyMapping LoadedKeymap[KBD_MAX_SCANCODE];
+
+/* ST keys being kept down, indexed by SDL scancode */
+static ST_Key KeysDown[SDL_NUM_SCANCODES];
/*-----------------------------------------------------------------------*/
@@ -385,49 +407,82 @@ static uint8_t Keymap_GetKeyPadScanCode(const SDL_Keysym* pKeySym)
return ST_NO_SCANCODE;
}
+/**
+ * If given ST scancode is not set, return NULL, otherwise add scancode
+ * to pressed keys array, output trace of the SDL->ST key mapping and
+ * return pointer to the mapping
+ */
+static ST_Key* UpdateMapping(const char *maptype, SDL_Scancode pcscan, uint8_t stscan)
+{
+ ST_Key *key = &(KeysDown[pcscan]);
+
+ if (stscan == ST_NO_SCANCODE)
+ return NULL;
+ key->scancode = stscan;
+
+ LOG_TRACE(TRACE_KEYMAP, "key mapping: %02x (%s)\n", stscan, maptype);
+ return key;
+}
/**
- * Remap SDL Key to ST Scan code
+ * Remap SDL Key to ST Key (when key is pressed).
+ * Receives the pressed key from SDL, and returns matching ST_Key,
+ * or NULL if no mapping could be found
*/
-static uint8_t Keymap_RemapKeyToSTScanCode(const SDL_Keysym* pKeySym)
+static ST_Key* Keymap_RemapKeyToSTKey(const SDL_Keysym* pKeySym)
{
+ const SDL_Keycode sym = pKeySym->sym;
+ const SDL_Scancode scancode = pKeySym->scancode;
+
+ /* check for UpdateMapping() */
+ assert(scancode < ARRAY_SIZE(KeysDown));
+
/* Check for keypad first so we can handle numlock */
- if (ConfigureParams.Keyboard.nKeymapType != KEYMAP_LOADED)
+ if (ConfigureParams.Keyboard.nKeymapType != KEYMAP_LOADED &&
+ sym >= SDLK_KP_1 && sym <= SDLK_KP_9)
{
- if (pKeySym->sym >= SDLK_KP_1 && pKeySym->sym <= SDLK_KP_9)
- {
- return Keymap_GetKeyPadScanCode(pKeySym);
- }
+ return UpdateMapping("keypad/symbolic", scancode,
+ Keymap_GetKeyPadScanCode(pKeySym));
}
/* Remap from PC scancodes? */
if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_SCANCODE)
{
- return Keymap_PcToStScanCode(pKeySym);
+ return UpdateMapping("scancode/symbolic", scancode,
+ Keymap_PcToStScanCode(pKeySym));
}
/* Use loaded keymap? */
if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
{
int i;
- for (i = 0; i < KBD_MAX_SCANCODE && LoadedKeymap[i][1] != 0; i++)
+ for (i = 0; i < ARRAY_SIZE(LoadedKeymap); i++)
{
- if (pKeySym->sym == (SDL_Keycode)LoadedKeymap[i][0])
- return LoadedKeymap[i][1];
+ KeyMapping *mapping = &LoadedKeymap[i];
+
+ if (mapping->pc.scancode == 0)
+ break; /* End of table */
+
+ if (mapping->pc.scancode != scancode)
+ continue;
+
+ return UpdateMapping("keymap", scancode,
+ mapping->st.scancode);
}
}
- /* Use symbolic mapping */
- return Keymap_SymbolicToStScanCode(pKeySym);
+ /* Fall back to symbolic mapping */
+ return UpdateMapping("symbolic", scancode,
+ Keymap_SymbolicToStScanCode(pKeySym));
}
/*-----------------------------------------------------------------------*/
/**
- * Fill host (PC) key based on host "spec" string.
+ * Fill "mapping" KeyMapping host part based on host "spec" string.
* Return true on success
*/
-static bool HostSpecToKeymap(const char *spec, int *scancode)
+static bool HostSpecToKeymap(const char *spec, KeyMapping* mapping)
{
int key;
if (!spec)
@@ -451,17 +506,17 @@ static bool HostSpecToKeymap(const char *spec, int *scancode)
spec, key);
return false;
}
- *scancode = key;
+ mapping->pc.scancode = key;
return true;
}
/*-----------------------------------------------------------------------*/
/**
- * Fill guest (ST) key based on guest "spec" string.
+ * Fill "mapping" KeyMapping guest (ST) part based on guest "spec" string.
* Return true on success
*/
-static bool GuestSpecToKeymap(const char *spec, int *scancode)
+static bool GuestSpecToKeymap(const char *spec, KeyMapping* mapping)
{
int key;
if (!spec)
@@ -474,7 +529,7 @@ static bool GuestSpecToKeymap(const char *spec, int *scancode)
spec, key, KBD_MAX_SCANCODE);
return false;
}
- *scancode = key;
+ mapping->st.scancode = key;
return true;
}
@@ -539,7 +594,7 @@ void Keymap_LoadRemapFile(const char *pszFileName)
/* get the host (PC) key spec */
host = Str_Trim(strtok_r(line, ",", &saveptr));
- if (!HostSpecToKeymap(host, &LoadedKeymap[idx][0]))
+ if (!HostSpecToKeymap(host, &LoadedKeymap[idx]))
{
Log_Printf(LOG_WARN, "Failed to parse host (PC/SDL) part '%s' of line %d in: %s\n",
host, linenro, pszFileName);
@@ -549,7 +604,7 @@ void Keymap_LoadRemapFile(const char *pszFileName)
/* Get the guest (ST) key spec */
guest = Str_Trim(strtok_r(NULL, "\n", &saveptr));
- if (!GuestSpecToKeymap(guest, &LoadedKeymap[idx][1]))
+ if (!GuestSpecToKeymap(guest, &LoadedKeymap[idx]))
{
Log_Printf(LOG_WARN, "Failed to parse guest (ST) part '%s' of line %d in: %s\n",
guest, linenro, pszFileName);
@@ -659,6 +714,7 @@ static bool IsKeyTranslatable(SDL_Keycode symkey)
void Keymap_KeyDown(const SDL_Keysym *sdlkey)
{
uint8_t STScanCode;
+ ST_Key* stkey;
int symkey = sdlkey->sym;
int modkey = sdlkey->mod;
@@ -677,16 +733,17 @@ void Keymap_KeyDown(const SDL_Keysym *sdlkey)
if (!IsKeyTranslatable(symkey))
return;
- STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
+ stkey = Keymap_RemapKeyToSTKey(sdlkey);
+ if (stkey == NULL)
+ return;
+
+ STScanCode = stkey->scancode;
LOG_TRACE(TRACE_KEYMAP, "key map: sym=0x%x to ST-scan=0x%02x\n", symkey, STScanCode);
- if (STScanCode != ST_NO_SCANCODE)
+ if (!Keyboard.KeyStates[STScanCode])
{
- if (!Keyboard.KeyStates[STScanCode])
- {
- /* Set down */
- Keyboard.KeyStates[STScanCode] = true;
- IKBD_PressSTKey(STScanCode, true);
- }
+ /* Set down */
+ Keyboard.KeyStates[STScanCode] = true;
+ IKBD_PressSTKey(STScanCode, true);
}
}
@@ -698,6 +755,7 @@ void Keymap_KeyDown(const SDL_Keysym *sdlkey)
void Keymap_KeyUp(const SDL_Keysym *sdlkey)
{
uint8_t STScanCode;
+ ST_Key* stkey;
int symkey = sdlkey->sym;
int modkey = sdlkey->mod;
@@ -717,15 +775,19 @@ void Keymap_KeyUp(const SDL_Keysym *sdlkey)
if (!IsKeyTranslatable(symkey))
return;
- STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
+ stkey = &KeysDown[sdlkey->scancode];
+ if (stkey == NULL)
+ {
+ Log_Printf(LOG_ERROR, "No mapping for key %d found!\n", sdlkey->scancode);
+ return;
+ }
+
/* Release key (only if was pressed) */
- if (STScanCode != ST_NO_SCANCODE)
+ STScanCode = stkey->scancode;
+ if (Keyboard.KeyStates[STScanCode])
{
- if (Keyboard.KeyStates[STScanCode])
- {
- IKBD_PressSTKey(STScanCode, false);
- Keyboard.KeyStates[STScanCode] = false;
- }
+ IKBD_PressSTKey(STScanCode, false);
+ Keyboard.KeyStates[STScanCode] = false;
}
}
--
2.30.2
--------------6125158E9D8E923B9ED57408
Content-Type: text/x-patch; charset=UTF-8;
name="0001-Keymap_LoadRemapFile-refactor-rewrite.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="0001-Keymap_LoadRemapFile-refactor-rewrite.patch"