Skip to content

Commit

Permalink
SDL: don't ignore briefly pressed keys (#2553)
Browse files Browse the repository at this point in the history
Some keyboards send KEY_DOWN/KEY_UP immediately in
sequence to support things like dual-purpose keys.
This change updates the SDL key handler to detect
when a key is pressed and released within a single
frame, and to propagate that key's state as down
for the duration of the frame, rather than just
drop the event entirely.
  • Loading branch information
dharrington committed May 2, 2024
1 parent a3823b3 commit deae9c6
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions src/system/sdl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ static struct
struct
{
bool state[tic_keys_count];
bool pressed[tic_keys_count];
char text;

#if defined(TOUCH_INPUT_SUPPORT)
Expand Down Expand Up @@ -710,6 +711,12 @@ static void processKeyboard()

for(s32 i = 0, c = 0; i < COUNT_OF(platform.keyboard.state) && c < TIC80_KEY_BUFFER; i++)
if(platform.keyboard.state[i]
// Some programmable keyboards will send key down and up events immediately.
// If the key was pressed and released in the same frame, report it as
// down for this frame so that it isn't missed. Lying about the key being
// currently down is the only way to communicate a key press without
// adding keyboard events to tic80_input.
|| platform.keyboard.pressed[i]
#if defined(TOUCH_INPUT_SUPPORT)
|| platform.keyboard.touch.state[i]
#endif
Expand All @@ -724,6 +731,10 @@ static void processKeyboard()
SDL_StartTextInput();
}
#endif

for(s32 i = 0, c = 0; i < COUNT_OF(platform.keyboard.state) && c < TIC80_KEY_BUFFER; i++) {
platform.keyboard.pressed[i] = false;
}
}

#if defined(TOUCH_INPUT_SUPPORT)
Expand Down Expand Up @@ -1015,12 +1026,15 @@ static const u32 KeyboardCodes[tic_keys_count] =
#include "keycodes.inl"
};

static void handleKeydown(SDL_Keycode keycode, bool down, bool* state)
static void handleKeydown(SDL_Keycode keycode, bool down, bool* state, bool* pressed)
{
for(tic_key i = 0; i < COUNT_OF(KeyboardCodes); i++)
{
if(KeyboardCodes[i] == keycode)
{
if (down && pressed) {
pressed[i] = true;
}
state[i] = down;
break;
}
Expand Down Expand Up @@ -1155,17 +1169,17 @@ static void pollEvents()

#if defined(TOUCH_INPUT_SUPPORT)
platform.keyboard.touch.useText = false;
handleKeydown(event.key.keysym.sym, true, platform.keyboard.touch.state);
handleKeydown(event.key.keysym.sym, true, platform.keyboard.touch.state, NULL);

if(event.key.keysym.sym != SDLK_AC_BACK)
if(!SDL_IsTextInputActive())
SDL_StartTextInput();
#endif

handleKeydown(event.key.keysym.sym, true, platform.keyboard.state);
handleKeydown(event.key.keysym.sym, true, platform.keyboard.state, platform.keyboard.pressed);
break;
case SDL_KEYUP:
handleKeydown(event.key.keysym.sym, false, platform.keyboard.state);
handleKeydown(event.key.keysym.sym, false, platform.keyboard.state, platform.keyboard.pressed);
break;
case SDL_TEXTINPUT:
if(strlen(event.text.text) == 1)
Expand Down

0 comments on commit deae9c6

Please sign in to comment.