From ea975f88fceef8192d5327112ddcd6e00dcf7a3a Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 14 Dec 2020 23:12:19 +0000 Subject: [PATCH] Implement more InputManager --- src/openrct2-ui/input/Input.cpp | 110 -------------- src/openrct2-ui/input/InputManager.cpp | 160 ++++++++++++++++++++- src/openrct2-ui/input/InputManager.h | 5 + src/openrct2-ui/input/KeyboardShortcut.cpp | 18 +++ src/openrct2-ui/input/ShortcutManager.cpp | 11 ++ src/openrct2-ui/input/ShortcutManager.h | 3 + 6 files changed, 196 insertions(+), 111 deletions(-) diff --git a/src/openrct2-ui/input/Input.cpp b/src/openrct2-ui/input/Input.cpp index a05db1fce1..7e9a770d7d 100644 --- a/src/openrct2-ui/input/Input.cpp +++ b/src/openrct2-ui/input/Input.cpp @@ -124,113 +124,3 @@ static int32_t InputScancodeToRCTKeycode(int32_t sdl_key) void InputHandleKeyboard(bool isTitle) { } - -void InputHandleKeyboard2(bool isTitle) -{ - if (gOpenRCT2Headless) - { - return; - } - - auto& console = GetInGameConsole(); - if (!console.IsOpen()) - { - if (!isTitle) - { - // Handle mouse scrolling - if (input_get_state() == InputState::Normal && gConfigGeneral.edge_scrolling) - { - if (!(gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_SHIFT_Z | PLACE_OBJECT_MODIFIER_COPY_Z))) - { - GameHandleEdgeScroll(); - } - } - } - - // Handle modifier keys and key scrolling - gInputPlaceObjectModifier = PLACE_OBJECT_MODIFIER_NONE; - const uint8_t* keysState = context_get_keys_state(); - if (keysState[SDL_SCANCODE_LSHIFT] || keysState[SDL_SCANCODE_RSHIFT]) - { - gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_SHIFT_Z; - } - if (keysState[SDL_SCANCODE_LCTRL] || keysState[SDL_SCANCODE_RCTRL]) - { - gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_COPY_Z; - } - if (keysState[SDL_SCANCODE_LALT] || keysState[SDL_SCANCODE_RALT]) - { - gInputPlaceObjectModifier |= 4; - } -#ifdef __MACOSX__ - if (keysState[SDL_SCANCODE_LGUI] || keysState[SDL_SCANCODE_RGUI]) - { - gInputPlaceObjectModifier |= 8; - } -#endif - if (!isTitle) - { - GameHandleKeyScroll(); - } - } - - if (gConfigGeneral.virtual_floor_style != VirtualFloorStyles::Off) - { - if (gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_COPY_Z | PLACE_OBJECT_MODIFIER_SHIFT_Z)) - virtual_floor_enable(); - else - virtual_floor_disable(); - } - - // Handle key input - int32_t key; - while (!gOpenRCT2Headless && (key = GetNextKey()) != 0) - { - if (key == 255) - continue; - - // Reserve backtick for console - if (key == SDL_SCANCODE_GRAVE) - { - if ((gConfigGeneral.debugging_tools && !context_is_input_active()) || console.IsOpen()) - { - window_cancel_textbox(); - console.Toggle(); - } - continue; - } - else if (console.IsOpen()) - { - InputHandleConsole(key); - continue; - } - else if (!isTitle && gChatOpen) - { - InputHandleChat(key); - continue; - } - - key |= gInputPlaceObjectModifier << 8; - - rct_window* w = window_find_by_class(WC_TEXTINPUT); - if (w != nullptr) - { - char keychar = InputScancodeToRCTKeycode(key & 0xFF); - window_text_input_key(w, keychar); - } - else if (!gUsingWidgetTextBox) - { - w = window_find_by_class(WC_CHANGE_KEYBOARD_SHORTCUT); - if (w != nullptr) - { - KeyboardShortcutsSet(key); - window_close_by_class(WC_CHANGE_KEYBOARD_SHORTCUT); - window_invalidate_by_class(WC_KEYBOARD_SHORTCUT_LIST); - } - else - { - // KeyboardShortcutHandle(key); - } - } - } -} diff --git a/src/openrct2-ui/input/InputManager.cpp b/src/openrct2-ui/input/InputManager.cpp index 104901ef13..7ba102866e 100644 --- a/src/openrct2-ui/input/InputManager.cpp +++ b/src/openrct2-ui/input/InputManager.cpp @@ -9,7 +9,17 @@ #include "InputManager.h" +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include using namespace OpenRCT2::Ui; @@ -19,6 +29,66 @@ void InputManager::QueueInputEvent(InputEvent&& e) } void InputManager::Process() +{ + HandleModifiers(); + HandleMouseEdgeScrolling(); + ProcessEvents(); +} + +void InputManager::HandleMouseEdgeScrolling() +{ + if (!gConfigGeneral.edge_scrolling) + return; + + if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) + return; + + auto& console = GetInGameConsole(); + if (console.IsOpen()) + return; + + if (input_get_state() != InputState::Normal) + return; + + if (gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_SHIFT_Z | PLACE_OBJECT_MODIFIER_COPY_Z)) + return; + + GameHandleEdgeScroll(); +} + +void InputManager::HandleModifiers() +{ + auto modifiers = SDL_GetModState(); + gInputPlaceObjectModifier = PLACE_OBJECT_MODIFIER_NONE; + if (modifiers & KMOD_SHIFT) + { + gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_SHIFT_Z; + } + if (modifiers & KMOD_CTRL) + { + gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_COPY_Z; + } + if (modifiers & KMOD_ALT) + { + gInputPlaceObjectModifier |= 4; + } +#ifdef __MACOSX__ + if (modifiers & KMOD_GUI) + { + gInputPlaceObjectModifier |= 8; + } +#endif + + if (gConfigGeneral.virtual_floor_style != VirtualFloorStyles::Off) + { + if (gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_COPY_Z | PLACE_OBJECT_MODIFIER_SHIFT_Z)) + virtual_floor_enable(); + else + virtual_floor_disable(); + } +} + +void InputManager::ProcessEvents() { while (!_events.empty()) { @@ -31,7 +101,95 @@ void InputManager::Process() void InputManager::Process(const InputEvent& e) { auto& shortcutManager = GetShortcutManager(); - shortcutManager.ProcessEvent(e); + auto& console = GetInGameConsole(); + if (console.IsOpen()) + { + if (!shortcutManager.ProcessEventForSpecificShortcut(e, SHORTCUT_ID_DEBUG_CONSOLE)) + { + ProcessInGameConsole(e); + } + } + else if (gChatOpen) + { + ProcessChat(e); + } + else + { + if (e.DeviceKind == InputDeviceKind::Keyboard) + { + auto w = window_find_by_class(WC_TEXTINPUT); + if (w != nullptr) + { + if (e.State == InputEventState::Release) + { + window_text_input_key(w, e.Button); + } + return; + } + else if (!gUsingWidgetTextBox) + { + return; + } + } + shortcutManager.ProcessEvent(e); + } +} + +void InputManager::ProcessInGameConsole(const InputEvent& e) +{ + if (e.DeviceKind == InputDeviceKind::Keyboard && e.State == InputEventState::Release) + { + auto input = ConsoleInput::None; + switch (e.Button) + { + case SDLK_ESCAPE: + input = ConsoleInput::LineClear; + break; + case SDLK_RETURN: + case SDLK_KP_ENTER: + input = ConsoleInput::LineExecute; + break; + case SDLK_UP: + input = ConsoleInput::HistoryPrevious; + break; + case SDLK_DOWN: + input = ConsoleInput::HistoryNext; + break; + case SDLK_PAGEUP: + input = ConsoleInput::ScrollPrevious; + break; + case SDLK_PAGEDOWN: + input = ConsoleInput::ScrollNext; + break; + } + if (input != ConsoleInput::None) + { + auto& console = GetInGameConsole(); + console.Input(input); + } + } +} + +void InputManager::ProcessChat(const InputEvent& e) +{ + if (e.DeviceKind == InputDeviceKind::Keyboard && e.State == InputEventState::Release) + { + auto input = ChatInput::None; + switch (e.Button) + { + case SDLK_ESCAPE: + input = ChatInput::Close; + break; + case SDLK_RETURN: + case SDLK_KP_ENTER: + input = ChatInput::Send; + break; + } + if (input != ChatInput::None) + { + chat_input(input); + } + } } static InputManager _inputManager; diff --git a/src/openrct2-ui/input/InputManager.h b/src/openrct2-ui/input/InputManager.h index b101c1f573..8700ffb8cd 100644 --- a/src/openrct2-ui/input/InputManager.h +++ b/src/openrct2-ui/input/InputManager.h @@ -39,7 +39,12 @@ namespace OpenRCT2::Ui private: std::queue _events; + void HandleMouseEdgeScrolling(); + void HandleModifiers(); + void ProcessEvents(); void Process(const InputEvent& e); + void ProcessInGameConsole(const InputEvent& e); + void ProcessChat(const InputEvent& e); public: void QueueInputEvent(InputEvent&& e); diff --git a/src/openrct2-ui/input/KeyboardShortcut.cpp b/src/openrct2-ui/input/KeyboardShortcut.cpp index 3ab40f65da..e11e71b71d 100644 --- a/src/openrct2-ui/input/KeyboardShortcut.cpp +++ b/src/openrct2-ui/input/KeyboardShortcut.cpp @@ -11,6 +11,8 @@ #include "ShortcutManager.h" #include +#include +#include #include #include #include @@ -41,6 +43,7 @@ extern bool gWindowSceneryEyedropperEnabled; using namespace OpenRCT2; +using namespace OpenRCT2::Ui; #pragma region Shortcut Commands @@ -594,6 +597,20 @@ static void ShortcutToggleClearanceChecks() GameActions::Execute(&setCheatAction); } +static void ShortcutToggleConsole() +{ + auto& console = GetInGameConsole(); + if (console.IsOpen()) + { + console.Toggle(); + } + else if (gConfigGeneral.debugging_tools && !context_is_input_active()) + { + window_cancel_textbox(); + console.Toggle(); + } +} + #pragma endregion using namespace OpenRCT2::Ui; @@ -762,6 +779,7 @@ void ShortcutManager::RegisterDefaultShortcuts() RegisterShortcut("tileinspector.decrease_height", STR_SHORTCUT_DECREASE_ELEM_HEIGHT, []() { ShortcutDecreaseElementHeight(); }); // Debug + RegisterShortcut(SHORTCUT_ID_DEBUG_CONSOLE, STR_CONSOLE, "`", []() { ShortcutToggleConsole(); }); RegisterShortcut("debug.advance_tick", STR_ADVANCE_TO_NEXT_TICK, []() { if (!(gScreenFlags & (SCREEN_FLAGS_TITLE_DEMO | SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_MANAGER))) { diff --git a/src/openrct2-ui/input/ShortcutManager.cpp b/src/openrct2-ui/input/ShortcutManager.cpp index 20244581fa..4574d9346f 100644 --- a/src/openrct2-ui/input/ShortcutManager.cpp +++ b/src/openrct2-ui/input/ShortcutManager.cpp @@ -420,6 +420,17 @@ void ShortcutManager::ProcessEvent(const InputEvent& e) } } +bool ShortcutManager::ProcessEventForSpecificShortcut(const InputEvent& e, std::string_view id) +{ + auto shortcut = GetShortcut(id); + if (shortcut != nullptr && shortcut->Matches(e)) + { + shortcut->Action(); + return true; + } + return false; +} + static ShortcutManager _shortcutManager; ShortcutManager& OpenRCT2::Ui::GetShortcutManager() diff --git a/src/openrct2-ui/input/ShortcutManager.h b/src/openrct2-ui/input/ShortcutManager.h index baf5427485..53f9da87b9 100644 --- a/src/openrct2-ui/input/ShortcutManager.h +++ b/src/openrct2-ui/input/ShortcutManager.h @@ -113,8 +113,11 @@ namespace OpenRCT2::Ui RegisteredShortcut* GetShortcut(std::string_view id); void SetPendingShortcutChange(std::string_view id); void ProcessEvent(const InputEvent& e); + bool ProcessEventForSpecificShortcut(const InputEvent& e, std::string_view id); }; ShortcutManager& GetShortcutManager(); + constexpr const char* SHORTCUT_ID_DEBUG_CONSOLE = "debug.console"; + } // namespace OpenRCT2::Ui