From df76d57c4752b9771f78a1b62a9d57341720bc1f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 3 Mar 2020 21:30:30 -0500 Subject: [PATCH] Experimentally attempts to tie together input and keypresses by timestamp. --- OSBindings/SDL/main.cpp | 75 +++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/OSBindings/SDL/main.cpp b/OSBindings/SDL/main.cpp index 2ffbeb13e..cd4e1fc6a 100644 --- a/OSBindings/SDL/main.cpp +++ b/OSBindings/SDL/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -611,10 +612,8 @@ int main(int argc, char *argv[]) { } // Check whether a 'logical' keyboard has been requested. - constexpr bool logical_keyboard = false; //arguments.selections.find("logical-keyboard") != arguments.selections.end(); - /* Logical keyboard entry is currently disabled; the attempt below to get logical input via SDL_GetKeyName is - too flawed — all letters are always capitals, shifted symbols are reported correctly on their first - press only, etc. I need to see whether other options are available. If not then SDL may not allow this feature.*/ + const bool logical_keyboard = arguments.selections.find("logical-keyboard") != arguments.selections.end(); + SDL_StartTextInput(); // Wire up the best-effort updater, its delegate, and the speaker delegate. machine_runner.machine = machine.get(); @@ -767,6 +766,15 @@ int main(int argc, char *argv[]) { activity_observer = std::make_unique(activity_source, 4.0f / 3.0f); } + // SDL 2.x delivers key up/down events and text inputs separately even when they're correlated; + // this struct and map is used to correlate them by time. + struct KeyPress { + bool is_down = true; + std::string input; + SDL_Keycode keycode = SDLK_UNKNOWN; + }; + std::unordered_map keypresses; + // Run the main event loop until the OS tells us to quit. const bool uses_mouse = !!machine->mouse_machine(); bool should_quit = false; @@ -813,6 +821,13 @@ int main(int argc, char *argv[]) { machine->media_target()->insert_media(media); } break; + case SDL_TEXTINPUT: { + const auto keyboard_machine = machine->keyboard_machine(); + if(keyboard_machine) { + keypresses[event.text.timestamp].input = event.text.text; + } + } break; + case SDL_KEYDOWN: case SDL_KEYUP: { const auto keyboard_machine = machine->keyboard_machine(); @@ -896,27 +911,8 @@ int main(int argc, char *argv[]) { const bool is_pressed = event.type == SDL_KEYDOWN; if(keyboard_machine) { - // Grab the key's symbol. - char key_value = '\0'; - const char *key_name = SDL_GetKeyName(event.key.keysym.sym); - if(key_name[0] >= 0 && key_name[1] == 0) key_value = key_name[0]; - - // If a logical mapping was selected and a symbol was found, type it. - if(logical_keyboard && key_value != '\0' && keyboard_machine->can_type(key_value)) { - if(is_pressed) { - char string[] = { key_value, 0 }; - keyboard_machine->type_string(string); - } - break; - } - - // Otherwise, supply as a normal keypress. - Inputs::Keyboard::Key key = Inputs::Keyboard::Key::Space; - if(!KeyboardKeyForSDLScancode(event.key.keysym.scancode, key)) break; - if(keyboard_machine->get_keyboard().observed_keys().find(key) != keyboard_machine->get_keyboard().observed_keys().end()) { - keyboard_machine->get_keyboard().set_key_pressed(key, key_value, is_pressed); - break; - } + keypresses[event.text.timestamp].keycode = event.key.keysym.sym; + keypresses[event.text.timestamp].is_down = is_pressed; } JoystickMachine::Machine *const joystick_machine = machine->joystick_machine(); @@ -969,6 +965,35 @@ int main(int argc, char *argv[]) { } } + // Handle accumulated key states. + for (const auto &keypress: keypresses) { + printf("Key: %d %d %s\n", keypress.second.keycode, keypress.second.is_down, keypress.second.input.c_str()); + } + keypresses.clear(); +// printf("Key down: %d", event.text.timestamp); +// +// // Grab the key's symbol. +// char key_value = '\0'; +// const char *key_name = SDL_GetKeyName(event.key.keysym.sym); +// if(key_name[0] >= 0 && key_name[1] == 0) key_value = key_name[0]; +// +// // If a logical mapping was selected and a symbol was found, type it. +// if(logical_keyboard && key_value != '\0' && keyboard_machine->can_type(key_value)) { +// if(is_pressed) { +// char string[] = { key_value, 0 }; +// keyboard_machine->type_string(string); +// } +// break; +// } +// +// // Otherwise, supply as a normal keypress. +// Inputs::Keyboard::Key key = Inputs::Keyboard::Key::Space; +// if(!KeyboardKeyForSDLScancode(event.key.keysym.scancode, key)) break; +// if(keyboard_machine->get_keyboard().observed_keys().find(key) != keyboard_machine->get_keyboard().observed_keys().end()) { +// keyboard_machine->get_keyboard().set_key_pressed(key, key_value, is_pressed); +// break; +// } + // Push new joystick state, if any. JoystickMachine::Machine *const joystick_machine = machine->joystick_machine(); if(joystick_machine) {