diff --git a/source/lib/input.cpp b/source/lib/input.cpp index 30c5812dc3..e8965ae596 100644 --- a/source/lib/input.cpp +++ b/source/lib/input.cpp @@ -36,6 +36,8 @@ const size_t MAX_HANDLERS = 8; static InHandler handler_stack[MAX_HANDLERS]; static size_t handler_stack_top = 0; +static std::list priority_events; + void in_add_handler(InHandler handler) { ENSURE(handler); @@ -69,3 +71,20 @@ void in_dispatch_event(const SDL_Event_* ev) DEBUG_WARN_ERR(ERR::LOGIC); // invalid handler return value } } + +void in_push_priority_event(const SDL_Event_* event) +{ + priority_events.push_back(*event); +} + +int in_poll_event(SDL_Event_* event) +{ + if (!priority_events.empty()) + { + *event = priority_events.front(); + priority_events.pop_front(); + return 1; + } + + return SDL_PollEvent(&event->ev); +} diff --git a/source/lib/input.h b/source/lib/input.h index 6d55f8649b..fd3ac11a3e 100644 --- a/source/lib/input.h +++ b/source/lib/input.h @@ -55,4 +55,13 @@ extern void in_reset_handlers(); // send event to each handler (newest first) until one returns true extern void in_dispatch_event(const SDL_Event_* event); +// push an event onto the back of a high-priority queue - the new event will +// be returned by in_poll_event before any standard SDL events +extern void in_push_priority_event(const SDL_Event_* event); + +// reads events that were pushed by in_push_priority_event, or (if there are +// no high-priority events) reads from the SDL event queue with SDL_PollEvent. +// returns 1 if an event was read, 0 otherwise. +extern int in_poll_event(SDL_Event_* event); + #endif // #ifndef INCLUDED_INPUT diff --git a/source/main.cpp b/source/main.cpp index 30ffa0e0f6..e07fe41a9c 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -180,7 +180,7 @@ static void PumpEvents() PROFILE3("dispatch events"); SDL_Event_ ev; - while (SDL_PollEvent(&ev.ev)) + while (in_poll_event(&ev)) { PROFILE2("event"); if (g_GUI) diff --git a/source/ps/Hotkey.cpp b/source/ps/Hotkey.cpp index 4828de57e9..b89133d422 100644 --- a/source/ps/Hotkey.cpp +++ b/source/ps/Hotkey.cpp @@ -213,6 +213,14 @@ InReaction HotkeyInputHandler( const SDL_Event_* ev ) return IN_PASS; #endif + case SDL_HOTKEYDOWN: + g_HotkeyStatus[static_cast(ev->ev.user.data1)] = true; + return IN_PASS; + + case SDL_HOTKEYUP: + g_HotkeyStatus[static_cast(ev->ev.user.data1)] = false; + return IN_PASS; + default: return IN_PASS; } @@ -321,10 +329,6 @@ InReaction HotkeyInputHandler( const SDL_Event_* ev ) if( accept && !( consoleCapture && it->name != "console.toggle" ) ) { - // Tentatively set status to un-pressed, since it may be overridden by - // a closer match. (The closest matches will be set to pressed later.) - g_HotkeyStatus[it->name] = false; - // Check if this is an equally precise or more precise match if( it->requires.size() + 1 >= closestMapMatch ) { @@ -343,12 +347,10 @@ InReaction HotkeyInputHandler( const SDL_Event_* ev ) for (size_t i = 0; i < closestMapNames.size(); ++i) { - g_HotkeyStatus[closestMapNames[i]] = true; - - SDL_Event hotkeyNotification; - hotkeyNotification.type = SDL_HOTKEYDOWN; - hotkeyNotification.user.data1 = const_cast(closestMapNames[i]); - SDL_PushEvent(&hotkeyNotification); + SDL_Event_ hotkeyNotification; + hotkeyNotification.ev.type = SDL_HOTKEYDOWN; + hotkeyNotification.ev.user.data1 = const_cast(closestMapNames[i]); + in_push_priority_event(&hotkeyNotification); } // -- KEYUP SECTION -- @@ -386,11 +388,10 @@ InReaction HotkeyInputHandler( const SDL_Event_* ev ) if( accept ) { - g_HotkeyStatus[it->name] = false; - SDL_Event hotkeyNotification; - hotkeyNotification.type = SDL_HOTKEYUP; - hotkeyNotification.user.data1 = const_cast(it->name.c_str()); - SDL_PushEvent( &hotkeyNotification ); + SDL_Event_ hotkeyNotification; + hotkeyNotification.ev.type = SDL_HOTKEYUP; + hotkeyNotification.ev.user.data1 = const_cast(it->name.c_str()); + in_push_priority_event(&hotkeyNotification); } } diff --git a/source/tools/atlas/GameInterface/GameLoop.cpp b/source/tools/atlas/GameInterface/GameLoop.cpp index ebb27bccf4..d227aa28b8 100644 --- a/source/tools/atlas/GameInterface/GameLoop.cpp +++ b/source/tools/atlas/GameInterface/GameLoop.cpp @@ -219,7 +219,7 @@ static void* RunEngine(void* data) // Pump SDL events (e.g. hotkeys) SDL_Event_ ev; - while (SDL_PollEvent(&ev.ev)) + while (in_poll_event(&ev)) in_dispatch_event(&ev); if (g_GUI)