From 1260b93ba514c7193c9d8025ac1e100785646a24 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Thu, 30 Sep 2021 11:08:38 +0200 Subject: [PATCH] Improve build distance by factoring keyboard code --- src-cg/keyboard.c => cgdoom/cgdoom-kbd.c | 154 +++++++---------------- cgdoom/cgdoom-kbd.h | 88 +++++++++++++ cgdoom/cgdoom.c | 4 + cgdoom/p_saveg.c | 20 +-- src-sdl2/keyboard.c | 144 +++++++++++---------- 5 files changed, 224 insertions(+), 186 deletions(-) rename src-cg/keyboard.c => cgdoom/cgdoom-kbd.c (59%) create mode 100644 cgdoom/cgdoom-kbd.h diff --git a/src-cg/keyboard.c b/cgdoom/cgdoom-kbd.c similarity index 59% rename from src-cg/keyboard.c rename to cgdoom/cgdoom-kbd.c index bc52d8c..27c3f38 100644 --- a/src-cg/keyboard.c +++ b/cgdoom/cgdoom-kbd.c @@ -1,114 +1,42 @@ -/////////////////////////////////////////////////////////////////////////////// -// Keyboard input -// -// Instead of using libfxcg functions which only provide single-key analysis -// (GetKey, GetKeyWait, and PRGM_GetKey mainly), the following code uses a -// simple KEYSC driver. This is indirectly taken from gint code. -/////////////////////////////////////////////////////////////////////////////// - #include "cgdoom.h" +#include "cgdoom-kbd.h" #include "doomdef.h" -/* Keyboard matrix codes */ - -#define KEYCODE_F1 0x91 -#define KEYCODE_F2 0x92 -#define KEYCODE_F3 0x93 -#define KEYCODE_F4 0x94 -#define KEYCODE_F5 0x95 -#define KEYCODE_F6 0x96 - -#define KEYCODE_SHIFT 0x81 -#define KEYCODE_OPTN 0x82 -#define KEYCODE_VARS 0x83 -#define KEYCODE_MENU 0x84 -#define KEYCODE_LEFT 0x85 -#define KEYCODE_UP 0x86 - -#define KEYCODE_ALPHA 0x71 -#define KEYCODE_SQUARE 0x72 -#define KEYCODE_POWER 0x73 -#define KEYCODE_EXIT 0x74 -#define KEYCODE_DOWN 0x75 -#define KEYCODE_RIGHT 0x76 - -#define KEYCODE_XOT 0x61 -#define KEYCODE_LOG 0x62 -#define KEYCODE_LN 0x63 -#define KEYCODE_SIN 0x64 -#define KEYCODE_COS 0x65 -#define KEYCODE_TAN 0x66 - -#define KEYCODE_FRAC 0x51 -#define KEYCODE_FD 0x52 -#define KEYCODE_LEFTP 0x53 -#define KEYCODE_RIGHTP 0x54 -#define KEYCODE_COMMA 0x55 -#define KEYCODE_ARROW 0x56 - -#define KEYCODE_7 0x41 -#define KEYCODE_8 0x42 -#define KEYCODE_9 0x43 -#define KEYCODE_DEL 0x44 - -#define KEYCODE_4 0x31 -#define KEYCODE_5 0x32 -#define KEYCODE_6 0x33 -#define KEYCODE_MUL 0x34 -#define KEYCODE_DIV 0x35 - -#define KEYCODE_1 0x21 -#define KEYCODE_2 0x22 -#define KEYCODE_3 0x23 -#define KEYCODE_PLUS 0x24 -#define KEYCODE_MINUS 0x25 - -#define KEYCODE_0 0x11 -#define KEYCODE_DOT 0x12 -#define KEYCODE_EXP 0x13 -#define KEYCODE_NEG 0x14 -#define KEYCODE_EXE 0x15 - -#define KEYCODE_ACON 0x07 - -/* Copy of the keyboard state, one byte per row */ -typedef uint8_t KeyboardState[12] __attribute__((aligned(2))); - -/* Keymap */ +/* Dynamic keymap */ static uint16_t Keymap[] = { - KEY_LEFTARROW, 0, - KEY_RIGHTARROW, 0, - KEY_UPARROW, 0, - KEY_DOWNARROW, 0, - ' ', 0, /* Open doors etc */ - KEY_RCTRL, 0, /* Shoot */ - '1', 0, - '2', 0, - '3', 0, - '4', 0, - '5', 0, - '6', 0, - '7', 0, - KEY_TAB, 0, - KEY_PAUSE, 0, - KEY_SLEFTARROW, 0, - KEY_SRIGHTARROW, 0, - KEY_RSHIFT, 0, /* Speed toggle */ + KEY_LEFTARROW, -1, + KEY_RIGHTARROW, -1, + KEY_UPARROW, -1, + KEY_DOWNARROW, -1, + ' ', -1, /* Open doors etc */ + KEY_RCTRL, -1, /* Shoot */ + '1', -1, + '2', -1, + '3', -1, + '4', -1, + '5', -1, + '6', -1, + '7', -1, + KEY_TAB, -1, + KEY_PAUSE, -1, + KEY_SLEFTARROW, -1, + KEY_SRIGHTARROW, -1, + KEY_RSHIFT, -1, /* Speed toggle */ /* Special CGDoom keys */ - SKEY_DECVP, 0, - SKEY_INCVP, 0, - SKEY_CHEAT, 0, - SKEY_NOCLIP, 0, - SKEY_GAMMA, 0, - SKEY_FREEMEM, 0, - SKEY_FPSCOUNTER, 0, - SKEY_FRAMESKIP, 0, - SKEY_PROFILER, 0, + SKEY_DECVP, -1, + SKEY_INCVP, -1, + SKEY_CHEAT, -1, + SKEY_NOCLIP, -1, + SKEY_GAMMA, -1, + SKEY_FREEMEM, -1, + SKEY_FPSCOUNTER, -1, + SKEY_FRAMESKIP, -1, + SKEY_PROFILER, -1, 0, }; /* Default keymap: CGDoom 0.3 */ -static const uint16_t KeyMap_CGDoom_0_3[] = { +const uint16_t CGD_Keymap_CGDoom_0_3[] = { KEYCODE_LEFT, KEYCODE_RIGHT, KEYCODE_UP, @@ -138,7 +66,7 @@ static const uint16_t KeyMap_CGDoom_0_3[] = { 0, }; /* Default keymap: thumbs only */ -static const uint16_t KeyMap_ThumbsOnly[] = { +const uint16_t CGD_Keymap_ThumbsOnly[] = { KEYCODE_LEFT, KEYCODE_RIGHT, KEYCODE_UP, @@ -169,7 +97,7 @@ static const uint16_t KeyMap_ThumbsOnly[] = { 0, }; /* Default keymap: full-hands */ -static const uint16_t KeyMap_FullHands[] = { +const uint16_t CGD_Keymap_FullHands[] = { KEYCODE_F5, KEYCODE_F6, KEYCODE_OPTN, @@ -201,19 +129,21 @@ static const uint16_t KeyMap_FullHands[] = { }; /* Current keyboard state. */ -static KeyboardState st_prev={0}, st_now={0}; +static CGD_KeyboardState st_prev={0}, st_now={0}; -static void ScanKeyboard(KeyboardState state) +#ifndef CG_EMULATOR +void CGD_ScanKeyboard(CGD_KeyboardState state) { volatile uint16_t *KEYSC = (void *)0xa44b0000; uint16_t *array = (void *)state; for(int i = 0; i < 6; i++) array[i] = KEYSC[i]; } +#endif -static void LoadKeymap(uint16_t *map, uint16_t *template) +void CGD_LoadKeymap(const uint16_t *template) { - for(int i = 0; map[2*i] != 0; i++) { - map[2*i+1] = template[i]; + for(int i = 0; Keymap[2*i] != 0; i++) { + Keymap[2*i+1] = template[i]; } } @@ -284,7 +214,7 @@ static int DoomKeyToKeycode(int key) } } -static int KeycodeDown(KeyboardState state, int code) +static int KeycodeDown(CGD_KeyboardState state, int code) { if(code < 0) return 0; int row = (code >> 4) ^ 1; @@ -292,7 +222,7 @@ static int KeycodeDown(KeyboardState state, int code) return (state[row] & col) != 0; } -static int KeyDown(KeyboardState state, int key) +static int KeyDown(CGD_KeyboardState state, int key) { int code = DoomKeyToKeycode(key); @@ -308,7 +238,7 @@ static int KeyDown(KeyboardState state, int key) void UpdateKeyboardState(void) { memcpy(st_prev, st_now, sizeof st_now); - ScanKeyboard(st_now); + CGD_ScanKeyboard(st_now); } int KeyWasJustPressed(int key) diff --git a/cgdoom/cgdoom-kbd.h b/cgdoom/cgdoom-kbd.h new file mode 100644 index 0000000..11f8907 --- /dev/null +++ b/cgdoom/cgdoom-kbd.h @@ -0,0 +1,88 @@ +#ifndef CGDOOM_KBD_H +#define CGDOOM_KBD_H + +/* CGDoom's keyboard abstraction + + Instead of using libfxcg functions which only provide single-key analysis + (GetKey, GetKeyWait, and PRGM_GetKey mainly), CGDoom uses a simple KEYSC + driver adapter from gint's. The following matrix codes identify all keys on + the keyboard. The PC build maps a subset of them to PC keys. */ + +/* Copy of the keyboard state, one byte per row */ +typedef uint8_t CGD_KeyboardState[12] __attribute__((aligned(2))); + +/* Keyboard scanning function (very short), uses either the KEYSC or SDL */ +void CGD_ScanKeyboard(CGD_KeyboardState state); + +/* Default keymaps for use in UI code */ +extern const uint16_t CGD_Keymap_CGDoom_0_3[]; +extern const uint16_t CGD_Keymap_ThumbsOnly[]; +extern const uint16_t CGD_Keymap_FullHands[]; + +/* Load a default keymap */ +void CGD_LoadKeymap(const uint16_t *template); + + +/* Keyboard matrix codes for the keyboard driver */ + +#define KEYCODE_F1 0x91 +#define KEYCODE_F2 0x92 +#define KEYCODE_F3 0x93 +#define KEYCODE_F4 0x94 +#define KEYCODE_F5 0x95 +#define KEYCODE_F6 0x96 + +#define KEYCODE_SHIFT 0x81 +#define KEYCODE_OPTN 0x82 +#define KEYCODE_VARS 0x83 +#define KEYCODE_MENU 0x84 +#define KEYCODE_LEFT 0x85 +#define KEYCODE_UP 0x86 + +#define KEYCODE_ALPHA 0x71 +#define KEYCODE_SQUARE 0x72 +#define KEYCODE_POWER 0x73 +#define KEYCODE_EXIT 0x74 +#define KEYCODE_DOWN 0x75 +#define KEYCODE_RIGHT 0x76 + +#define KEYCODE_XOT 0x61 +#define KEYCODE_LOG 0x62 +#define KEYCODE_LN 0x63 +#define KEYCODE_SIN 0x64 +#define KEYCODE_COS 0x65 +#define KEYCODE_TAN 0x66 + +#define KEYCODE_FRAC 0x51 +#define KEYCODE_FD 0x52 +#define KEYCODE_LEFTP 0x53 +#define KEYCODE_RIGHTP 0x54 +#define KEYCODE_COMMA 0x55 +#define KEYCODE_ARROW 0x56 + +#define KEYCODE_7 0x41 +#define KEYCODE_8 0x42 +#define KEYCODE_9 0x43 +#define KEYCODE_DEL 0x44 + +#define KEYCODE_4 0x31 +#define KEYCODE_5 0x32 +#define KEYCODE_6 0x33 +#define KEYCODE_MUL 0x34 +#define KEYCODE_DIV 0x35 + +#define KEYCODE_1 0x21 +#define KEYCODE_2 0x22 +#define KEYCODE_3 0x23 +#define KEYCODE_PLUS 0x24 +#define KEYCODE_MINUS 0x25 + +#define KEYCODE_0 0x11 +#define KEYCODE_DOT 0x12 +#define KEYCODE_EXP 0x13 +#define KEYCODE_NEG 0x14 +#define KEYCODE_EXE 0x15 + +#define KEYCODE_ACON 0x07 + +#endif /* CGDOOM_KBD_H */ diff --git a/cgdoom/cgdoom.c b/cgdoom/cgdoom.c index f7ea17f..8a3b0de 100644 --- a/cgdoom/cgdoom.c +++ b/cgdoom/cgdoom.c @@ -9,6 +9,7 @@ #include "d_main.h" #include "cgdoom-alloc.h" +#include "cgdoom-kbd.h" #include "cgdoom-ui.h" void *CGD_malloc(int size) @@ -510,6 +511,9 @@ int main(void) CGD_2MBLineMemory = 0; #endif + /* Load keyboard layout */ + CGD_LoadKeymap(CGD_Keymap_ThumbsOnly); + /* Override version detection for single-episode Ultimate Doom WADs */ if (!strcmp(wads[choice].name, "doomu1.wad")) CGD_SingleEpisodeUltimate = 1; diff --git a/cgdoom/p_saveg.c b/cgdoom/p_saveg.c index fb51f7d..1fe744d 100644 --- a/cgdoom/p_saveg.c +++ b/cgdoom/p_saveg.c @@ -99,7 +99,7 @@ void P_UnArchivePlayers (void) if (players[i]. psprites[j].state) { players[i]. psprites[j].state - = (state_t *)&states[ (int)players[i].psprites[j].state ]; + = (state_t *)&states[ (intptr_t)players[i].psprites[j].state ]; } } } @@ -296,11 +296,11 @@ void P_UnArchiveThinkers (void) mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); memcpy (mobj, save_p, sizeof(*mobj)); save_p += sizeof(*mobj); - mobj->state = (state_t *)&states[(int)mobj->state]; + mobj->state = (state_t *)&states[(intptr_t)mobj->state]; mobj->target = NULL; if (mobj->player) { - mobj->player = &players[(int)mobj->player-1]; + mobj->player = &players[(intptr_t)mobj->player-1]; mobj->player->mo = mobj; } P_SetThingPosition (mobj); @@ -494,7 +494,7 @@ void P_UnArchiveSpecials (void) ceiling = (ceiling_t*)Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); memcpy (ceiling, save_p, sizeof(*ceiling)); save_p += sizeof(*ceiling); - ceiling->sector = §ors[(int)ceiling->sector]; + ceiling->sector = §ors[(intptr_t)ceiling->sector]; ceiling->sector->specialdata = ceiling; if (ceiling->thinker.function) @@ -509,7 +509,7 @@ void P_UnArchiveSpecials (void) door = (vldoor_t*)Z_Malloc (sizeof(*door), PU_LEVEL, NULL); memcpy (door, save_p, sizeof(*door)); save_p += sizeof(*door); - door->sector = §ors[(int)door->sector]; + door->sector = §ors[(intptr_t)door->sector]; door->sector->specialdata = door; door->thinker.function = TT_VerticalDoor; P_AddThinker (&door->thinker,door); @@ -520,7 +520,7 @@ void P_UnArchiveSpecials (void) floor = (floormove_t*)Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); memcpy (floor, save_p, sizeof(*floor)); save_p += sizeof(*floor); - floor->sector = §ors[(int)floor->sector]; + floor->sector = §ors[(intptr_t)floor->sector]; floor->sector->specialdata = floor; floor->thinker.function = TT_MoveFloor; P_AddThinker (&floor->thinker,floor); @@ -531,7 +531,7 @@ void P_UnArchiveSpecials (void) plat = (plat_t*)Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); memcpy (plat, save_p, sizeof(*plat)); save_p += sizeof(*plat); - plat->sector = §ors[(int)plat->sector]; + plat->sector = §ors[(intptr_t)plat->sector]; plat->sector->specialdata = plat; if (plat->thinker.function) @@ -546,7 +546,7 @@ void P_UnArchiveSpecials (void) flash = (lightflash_t*)Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); memcpy (flash, save_p, sizeof(*flash)); save_p += sizeof(*flash); - flash->sector = §ors[(int)flash->sector]; + flash->sector = §ors[(intptr_t)flash->sector]; flash->thinker.function = TT_LightFlash; P_AddThinker (&flash->thinker,flash); break; @@ -556,7 +556,7 @@ void P_UnArchiveSpecials (void) strobe = (strobe_t*)Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); memcpy (strobe, save_p, sizeof(*strobe)); save_p += sizeof(*strobe); - strobe->sector = §ors[(int)strobe->sector]; + strobe->sector = §ors[(intptr_t)strobe->sector]; strobe->thinker.function = TT_StrobeFlash; P_AddThinker (&strobe->thinker,strobe); break; @@ -566,7 +566,7 @@ void P_UnArchiveSpecials (void) glow = (glow_t*)Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); memcpy (glow, save_p, sizeof(*glow)); save_p += sizeof(*glow); - glow->sector = §ors[(int)glow->sector]; + glow->sector = §ors[(intptr_t)glow->sector]; glow->thinker.function = TT_Glow; P_AddThinker (&glow->thinker,glow); break; diff --git a/src-sdl2/keyboard.c b/src-sdl2/keyboard.c index e4f663e..eb23243 100644 --- a/src-sdl2/keyboard.c +++ b/src-sdl2/keyboard.c @@ -2,82 +2,98 @@ #include #include "cgdoom.h" +#include "cgdoom-kbd.h" #include "doomdef.h" -/* Copy of the keyboard state. */ -static Uint8 *st_prev=NULL, *st_now=NULL; - -static Uint8 *ScanKeyboard(void) -{ - int length; - const Uint8 *state = SDL_GetKeyboardState(&length); - return memcpy(malloc(length), state, length); -} - -static int DoomKeyToKeycode(int key) +/* Mapping of calculator matrix codes on the PC keyboard */ +static int MatrixCodeToPCKey(int key) { switch(key) { - /* Normal Doom keys */ - case KEY_LEFTARROW: return SDL_SCANCODE_LEFT; - case KEY_RIGHTARROW: return SDL_SCANCODE_RIGHT; - case KEY_UPARROW: return SDL_SCANCODE_UP; - case KEY_DOWNARROW: return SDL_SCANCODE_DOWN; - case ' ': return SDL_SCANCODE_SPACE; -// case KEY_RCTRL: return KEYCODE_ALPHA; - case '1': return SDL_SCANCODE_1; - case '2': return SDL_SCANCODE_2; - case '3': return SDL_SCANCODE_3; - case '4': return SDL_SCANCODE_4; - case '5': return SDL_SCANCODE_5; - case '6': return SDL_SCANCODE_6; - case '7': return SDL_SCANCODE_7; - case KEY_TAB: return SDL_SCANCODE_TAB; -// case KEY_PAUSE: return KEYCODE_OPTN; -// case KEY_SLEFTARROW: return KEYCODE_0; -// case KEY_SRIGHTARROW: return KEYCODE_DOT; - case KEY_ESCAPE: return SDL_SCANCODE_ESCAPE; - case KEY_ENTER: return SDL_SCANCODE_RETURN; + case KEYCODE_F1: return SDL_SCANCODE_F1; + case KEYCODE_F2: return SDL_SCANCODE_F2; + case KEYCODE_F3: return SDL_SCANCODE_F3; + case KEYCODE_F4: return SDL_SCANCODE_F4; + case KEYCODE_F5: return SDL_SCANCODE_F5; + case KEYCODE_F6: return SDL_SCANCODE_F6; - /* Special CGDoom keys */ -/* case SKEY_CHEAT: return KEYCODE_POWER; - case SKEY_DECVP: return KEYCODE_MINUS; - case SKEY_INCVP: return KEYCODE_PLUS; - case SKEY_NOCLIP: return KEYCODE_ARROW; - case SKEY_GAMMA: return KEYCODE_FRAC; - case SKEY_FREEMEM: return KEYCODE_FD; - case SKEY_FPSCOUNTER: return KEYCODE_LEFTP; - case SKEY_FRAMESKIP: return KEYCODE_VARS; */ + case KEYCODE_UP: return SDL_SCANCODE_UP; + case KEYCODE_RIGHT: return SDL_SCANCODE_RIGHT; + case KEYCODE_DOWN: return SDL_SCANCODE_DOWN; + case KEYCODE_LEFT: return SDL_SCANCODE_LEFT; + + case KEYCODE_SHIFT: return SDL_SCANCODE_Q; + case KEYCODE_OPTN: return SDL_SCANCODE_W; + case KEYCODE_VARS: return SDL_SCANCODE_E; + case KEYCODE_MENU: return SDL_SCANCODE_R; + + case KEYCODE_ALPHA: return SDL_SCANCODE_A; + case KEYCODE_SQUARE: return SDL_SCANCODE_S; + case KEYCODE_POWER: return SDL_SCANCODE_D; + case KEYCODE_EXIT: return SDL_SCANCODE_F; + + case KEYCODE_XOT: return SDL_SCANCODE_T; + case KEYCODE_LOG: return SDL_SCANCODE_Y; + case KEYCODE_LN: return SDL_SCANCODE_U; + case KEYCODE_SIN: return SDL_SCANCODE_I; + case KEYCODE_COS: return SDL_SCANCODE_O; + case KEYCODE_TAN: return SDL_SCANCODE_P; + + case KEYCODE_FRAC: return SDL_SCANCODE_G; + case KEYCODE_FD: return SDL_SCANCODE_H; + case KEYCODE_LEFTP: return SDL_SCANCODE_J; + case KEYCODE_RIGHTP: return SDL_SCANCODE_K; + case KEYCODE_COMMA: return SDL_SCANCODE_L; + case KEYCODE_ARROW: return SDL_SCANCODE_SEMICOLON; + + case KEYCODE_1: return SDL_SCANCODE_1; + case KEYCODE_2: return SDL_SCANCODE_2; + case KEYCODE_3: return SDL_SCANCODE_3; + case KEYCODE_4: return SDL_SCANCODE_4; + case KEYCODE_5: return SDL_SCANCODE_5; + case KEYCODE_6: return SDL_SCANCODE_6; + case KEYCODE_7: return SDL_SCANCODE_7; + case KEYCODE_8: return SDL_SCANCODE_8; + case KEYCODE_9: return SDL_SCANCODE_9; + case KEYCODE_0: return SDL_SCANCODE_0; + + case KEYCODE_DEL: return SDL_SCANCODE_BACKSPACE; + case KEYCODE_ACON: return SDL_SCANCODE_ESCAPE; + + case KEYCODE_MUL: return SDL_SCANCODE_LEFTBRACKET; + case KEYCODE_DIV: return SDL_SCANCODE_RIGHTBRACKET; + + case KEYCODE_PLUS: return SDL_SCANCODE_MINUS; + case KEYCODE_MINUS: return SDL_SCANCODE_EQUALS; + + case KEYCODE_DOT: return -1; + case KEYCODE_EXP: return -1; + case KEYCODE_NEG: return -1; + + case KEYCODE_EXE: return SDL_SCANCODE_RETURN; default: return -1; } } -static int KeyDown(Uint8 *state, int key) -{ - int code = DoomKeyToKeycode(key); - return (code < 0 || state == NULL) ? 0 : state[code]; -} - -void UpdateKeyboardState(void) +void CGD_ScanKeyboard(CGD_KeyboardState state) { SDL_Event e; - while(SDL_PollEvent(&e)) { - if(e.type == SDL_QUIT) - exit(0); + while(SDL_PollEvent(&e)) {} + + int length; + const Uint8 *sdl_state = SDL_GetKeyboardState(&length); + + for(int row = 0; row < 12; row++) { + for(int col = 0; col < 8; col++) { + int matrix_code = (row << 4) | col; + int index = row ^ 1; + int pattern = (0x80 >> col); + + int scancode = MatrixCodeToPCKey(matrix_code); + state[index] &= ~pattern; + if(scancode >= 0 && scancode < length && sdl_state[scancode]) + state[index] |= pattern; + } } - - free(st_prev); - st_prev = st_now; - st_now = ScanKeyboard(); -} - -int KeyWasJustPressed(int key) -{ - return !KeyDown(st_prev, key) && KeyDown(st_now, key); -} - -int KeyWasJustReleased(int key) -{ - return KeyDown(st_prev, key) && !KeyDown(st_now, key); }