From 31c2b9c6b7713357949eb65cb00233ac7eb5b548 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 11 Jun 2017 19:04:50 +0100 Subject: [PATCH 1/2] Move remaining SDL in input.c to openrct2ui --- src/openrct2-ui/WindowManager.cpp | 17 +-- src/openrct2-ui/input/input.c | 177 +++++++++++++++++++++++++ src/openrct2-ui/input/input.h | 26 ++++ src/openrct2-ui/libopenrct2ui.vcxproj | 2 + src/openrct2/Context.cpp | 10 +- src/openrct2/Context.h | 3 +- src/openrct2/input.c | 151 +-------------------- src/openrct2/input.h | 2 + src/openrct2/ui/DummyWindowManager.cpp | 3 +- src/openrct2/ui/WindowManager.h | 3 +- 10 files changed, 217 insertions(+), 177 deletions(-) create mode 100644 src/openrct2-ui/input/input.c create mode 100644 src/openrct2-ui/input/input.h diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index ec1b625f96..abb8aa0877 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -15,6 +15,7 @@ #pragma endregion #include +#include "input/input.h" #include "input/KeyboardShortcuts.h" #include "WindowManager.h" @@ -33,21 +34,9 @@ public: } } - void HandleKeyboardShortcut(sint32 key) override + void HandleKeyboard(bool isTitle) override { - rct_window * w = window_find_by_class(WC_CHANGE_KEYBOARD_SHORTCUT); - if (w != NULL) { - keyboard_shortcuts_set(key); - window_close_by_class(WC_CHANGE_KEYBOARD_SHORTCUT); - window_invalidate_by_class(WC_KEYBOARD_SHORTCUT_LIST); - } else { - keyboard_shortcut_handle(key); - } - } - - void GetKeyboardMapScroll(const uint8 * keysState, sint32 * x, sint32 * y) override - { - get_keyboard_map_scroll(keysState, x, y); + input_handle_keyboard(isTitle); } std::string GetKeyboardShortcutString(sint32 shortcut) override diff --git a/src/openrct2-ui/input/input.c b/src/openrct2-ui/input/input.c new file mode 100644 index 0000000000..088ebb1113 --- /dev/null +++ b/src/openrct2-ui/input/input.c @@ -0,0 +1,177 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "input.h" +#include "KeyboardShortcuts.h" + +static void input_handle_console(sint32 key) +{ + CONSOLE_INPUT input = CONSOLE_INPUT_NONE; + switch (key) { + case SDL_SCANCODE_ESCAPE: + input = CONSOLE_INPUT_LINE_CLEAR; + break; + case SDL_SCANCODE_RETURN: + input = CONSOLE_INPUT_LINE_EXECUTE; + break; + case SDL_SCANCODE_UP: + input = CONSOLE_INPUT_HISTORY_PREVIOUS; + break; + case SDL_SCANCODE_DOWN: + input = CONSOLE_INPUT_HISTORY_NEXT; + break; + } + if (input != CONSOLE_INPUT_NONE) { + console_input(input); + } +} + +static void input_handle_chat(sint32 key) +{ + CHAT_INPUT input = CHAT_INPUT_NONE; + switch (key) { + case SDL_SCANCODE_ESCAPE: + input = CHAT_INPUT_CLOSE; + break; + case SDL_SCANCODE_RETURN: + input = CHAT_INPUT_SEND; + break; + } + if (input != CHAT_INPUT_NONE) { + chat_input(input); + } +} + +static void game_handle_key_scroll() +{ + rct_window *mainWindow; + sint32 scrollX, scrollY; + + mainWindow = window_get_main(); + if (mainWindow == NULL) + return; + if ((mainWindow->flags & WF_NO_SCROLLING) || (gScreenFlags & (SCREEN_FLAGS_TRACK_MANAGER | SCREEN_FLAGS_TITLE_DEMO))) + return; + if (mainWindow->viewport == NULL) + return; + + rct_window *textWindow; + + textWindow = window_find_by_class(WC_TEXTINPUT); + if (textWindow || gUsingWidgetTextBox) return; + if (gChatOpen) return; + + scrollX = 0; + scrollY = 0; + const uint8 * keysState = context_get_keys_state(); + get_keyboard_map_scroll(keysState, &scrollX, &scrollY); + + // Scroll viewport + if (scrollX != 0) { + mainWindow->saved_view_x += scrollX * (12 << mainWindow->viewport->zoom); + input_set_flag(INPUT_FLAG_VIEWPORT_SCROLLING, true); + } + if (scrollY != 0) { + mainWindow->saved_view_y += scrollY * (12 << mainWindow->viewport->zoom); + input_set_flag(INPUT_FLAG_VIEWPORT_SCROLLING, true); + } +} + +void input_handle_keyboard(bool isTitle) +{ + if (gOpenRCT2Headless) { + return; + } + + if (!gConsoleOpen) { + if (!isTitle) { + // Handle mouse scrolling + if (input_get_state() == INPUT_STATE_NORMAL && gConfigGeneral.edge_scrolling) { + if (!(gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_SHIFT_Z | PLACE_OBJECT_MODIFIER_COPY_Z))) { + game_handle_edge_scroll(); + } + } + } + + // Handle modifier keys and key scrolling + gInputPlaceObjectModifier = PLACE_OBJECT_MODIFIER_NONE; + const uint8 * 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) { + game_handle_key_scroll(); + } + } + + // Handle key input + sint32 key; + while (!gOpenRCT2Headless && (key = get_next_key()) != 0) { + if (key == 255) + continue; + + // Reserve backtick for console + if (key == SDL_SCANCODE_GRAVE) { + if ((gConfigGeneral.debugging_tools && !context_is_input_active()) || gConsoleOpen) { + window_cancel_textbox(); + console_toggle(); + } + continue; + } else if (gConsoleOpen) { + input_handle_console(key); + continue; + } else if (!isTitle && gChatOpen) { + input_handle_chat(key); + continue; + } + + key |= gInputPlaceObjectModifier << 8; + + rct_window * w = window_find_by_class(WC_TEXTINPUT); + if (w != NULL) { + window_text_input_key(w, key); + } else if (!gUsingWidgetTextBox) { + w = window_find_by_class(WC_CHANGE_KEYBOARD_SHORTCUT); + if (w != NULL) { + keyboard_shortcuts_set(key); + window_close_by_class(WC_CHANGE_KEYBOARD_SHORTCUT); + window_invalidate_by_class(WC_KEYBOARD_SHORTCUT_LIST); + } else { + keyboard_shortcut_handle(key); + } + } + } +} \ No newline at end of file diff --git a/src/openrct2-ui/input/input.h b/src/openrct2-ui/input/input.h new file mode 100644 index 0000000000..0340d3a9b2 --- /dev/null +++ b/src/openrct2-ui/input/input.h @@ -0,0 +1,26 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + void input_handle_keyboard(bool isTitle); +#ifdef __cplusplus +} +#endif diff --git a/src/openrct2-ui/libopenrct2ui.vcxproj b/src/openrct2-ui/libopenrct2ui.vcxproj index 391cbe7109..407ceefcf9 100644 --- a/src/openrct2-ui/libopenrct2ui.vcxproj +++ b/src/openrct2-ui/libopenrct2ui.vcxproj @@ -41,6 +41,7 @@ + @@ -68,6 +69,7 @@ + diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 7766a9df51..bd4ed624c3 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -659,16 +659,10 @@ extern "C" return windowManager->OpenWindow(wc); } - void context_handle_keyboard_shortcut(sint32 key) + void context_input_handle_keyboard(bool isTitle) { auto windowManager = GetContext()->GetUiContext()->GetWindowManager(); - windowManager->HandleKeyboardShortcut(key); - } - - void context_get_keyboard_map_scroll(const uint8 * keysState, sint32 * x, sint32 * y) - { - auto windowManager = GetContext()->GetUiContext()->GetWindowManager(); - windowManager->GetKeyboardMapScroll(keysState, x, y); + windowManager->HandleKeyboard(isTitle); } bool platform_open_common_file_dialog(utf8 * outFilename, file_dialog_desc * desc, size_t outSize) diff --git a/src/openrct2/Context.h b/src/openrct2/Context.h index 45c52eca91..6e10a77e22 100644 --- a/src/openrct2/Context.h +++ b/src/openrct2/Context.h @@ -128,8 +128,7 @@ extern "C" bool context_has_focus(); void context_set_cursor_trap(bool value); rct_window * context_open_window(rct_windowclass wc); - void context_handle_keyboard_shortcut(sint32 key); - void context_get_keyboard_map_scroll(const uint8 * keysState, sint32 * x, sint32 * y); + void context_input_handle_keyboard(bool isTitle); #ifdef __cplusplus } #endif diff --git a/src/openrct2/input.c b/src/openrct2/input.c index 94d21de70d..121ed088d2 100644 --- a/src/openrct2/input.c +++ b/src/openrct2/input.c @@ -14,7 +14,6 @@ *****************************************************************************/ #pragma endregion -#include #include "audio/audio.h" #include "config/Config.h" #include "Context.h" @@ -88,10 +87,7 @@ void process_mouse_tool(sint32 x, sint32 y); void invalidate_scroll(); static rct_mouse_data* get_mouse_input(); void map_element_right_click(sint32 type, rct_map_element *mapElement, sint32 x, sint32 y); -sint32 get_next_key(); static void game_handle_input_mouse(sint32 x, sint32 y, sint32 state); -void game_handle_edge_scroll(); -void game_handle_key_scroll(); static void input_widget_left(sint32 x, sint32 y, rct_window *w, rct_widgetindex widgetIndex); void input_state_widget_pressed(sint32 x, sint32 y, sint32 state, rct_widgetindex widgetIndex, rct_window* w, rct_widget* widget); void set_cursor(uint8 cursor_id); @@ -1396,121 +1392,13 @@ static void input_update_tooltip(rct_window *w, rct_widgetindex widgetIndex, sin #pragma region Keyboard input -static void input_handle_console(sint32 key) -{ - CONSOLE_INPUT input = CONSOLE_INPUT_NONE; - switch (key) { - case SDL_SCANCODE_ESCAPE: - input = CONSOLE_INPUT_LINE_CLEAR; - break; - case SDL_SCANCODE_RETURN: - input = CONSOLE_INPUT_LINE_EXECUTE; - break; - case SDL_SCANCODE_UP: - input = CONSOLE_INPUT_HISTORY_PREVIOUS; - break; - case SDL_SCANCODE_DOWN: - input = CONSOLE_INPUT_HISTORY_NEXT; - break; - } - if (input != CONSOLE_INPUT_NONE) { - console_input(input); - } -} - -static void input_handle_chat(sint32 key) -{ - CHAT_INPUT input = CHAT_INPUT_NONE; - switch (key) { - case SDL_SCANCODE_ESCAPE: - input = CHAT_INPUT_CLOSE; - break; - case SDL_SCANCODE_RETURN: - input = CHAT_INPUT_SEND; - break; - } - if (input != CHAT_INPUT_NONE) { - chat_input(input); - } -} - -static void input_handle_keyboard(bool isTitle) -{ - if (gOpenRCT2Headless) { - return; - } - - if (!gConsoleOpen) { - if (!isTitle) { - // Handle mouse scrolling - if (_inputState == INPUT_STATE_NORMAL && gConfigGeneral.edge_scrolling) { - if (!(gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_SHIFT_Z | PLACE_OBJECT_MODIFIER_COPY_Z))) { - game_handle_edge_scroll(); - } - } - } - - // Handle modifier keys and key scrolling - gInputPlaceObjectModifier = PLACE_OBJECT_MODIFIER_NONE; - const uint8 * 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) { - game_handle_key_scroll(); - } - } - - // Handle key input - sint32 key; - while (!gOpenRCT2Headless && (key = get_next_key()) != 0) { - if (key == 255) - continue; - - // Reserve backtick for console - if (key == SDL_SCANCODE_GRAVE) { - if ((gConfigGeneral.debugging_tools && !context_is_input_active()) || gConsoleOpen) { - window_cancel_textbox(); - console_toggle(); - } - continue; - } else if (gConsoleOpen) { - input_handle_console(key); - continue; - } else if (!isTitle && gChatOpen) { - input_handle_chat(key); - continue; - } - - key |= gInputPlaceObjectModifier << 8; - - rct_window * w = window_find_by_class(WC_TEXTINPUT); - if (w != NULL) { - window_text_input_key(w, key); - } else if (!gUsingWidgetTextBox) { - context_handle_keyboard_shortcut(key); - } - } -} - /** * * rct2: 0x006E3B43 */ void title_handle_keyboard_input() { - input_handle_keyboard(true); + context_input_handle_keyboard(true); } /** @@ -1519,7 +1407,7 @@ void title_handle_keyboard_input() */ void game_handle_keyboard_input() { - input_handle_keyboard(false); + context_input_handle_keyboard(false); } /** @@ -1630,41 +1518,6 @@ void game_handle_edge_scroll() } } -void game_handle_key_scroll() -{ - rct_window *mainWindow; - sint32 scrollX, scrollY; - - mainWindow = window_get_main(); - if (mainWindow == NULL) - return; - if ((mainWindow->flags & WF_NO_SCROLLING) || (gScreenFlags & (SCREEN_FLAGS_TRACK_MANAGER | SCREEN_FLAGS_TITLE_DEMO))) - return; - if (mainWindow->viewport == NULL) - return; - - rct_window *textWindow; - - textWindow = window_find_by_class(WC_TEXTINPUT); - if (textWindow || gUsingWidgetTextBox) return; - if (gChatOpen) return; - - scrollX = 0; - scrollY = 0; - const uint8 * keysState = context_get_keys_state(); - context_get_keyboard_map_scroll(keysState, &scrollX, &scrollY); - - // Scroll viewport - if (scrollX != 0) { - mainWindow->saved_view_x += scrollX * (12 << mainWindow->viewport->zoom); - _inputFlags |= INPUT_FLAG_VIEWPORT_SCROLLING; - } - if (scrollY != 0) { - mainWindow->saved_view_y += scrollY * (12 << mainWindow->viewport->zoom); - _inputFlags |= INPUT_FLAG_VIEWPORT_SCROLLING; - } -} - void input_set_flag(INPUT_FLAGS flag, bool on) { if (on) { diff --git a/src/openrct2/input.h b/src/openrct2/input.h index 2d28423006..47c125f496 100644 --- a/src/openrct2/input.h +++ b/src/openrct2/input.h @@ -97,6 +97,8 @@ void input_window_position_begin(rct_window *w, rct_widgetindex widgetIndex, sin void title_handle_keyboard_input(); void game_handle_input(); void game_handle_keyboard_input(); +void game_handle_edge_scroll(); +sint32 get_next_key(); void store_mouse_input(sint32 state, sint32 x, sint32 y); diff --git a/src/openrct2/ui/DummyWindowManager.cpp b/src/openrct2/ui/DummyWindowManager.cpp index 3f6d8bfcf7..08a1078f23 100644 --- a/src/openrct2/ui/DummyWindowManager.cpp +++ b/src/openrct2/ui/DummyWindowManager.cpp @@ -21,8 +21,7 @@ namespace OpenRCT2 { namespace Ui class DummyWindowManager final : public IWindowManager { rct_window * OpenWindow(rct_windowclass wc) override { return nullptr; } - void HandleKeyboardShortcut(sint32 key) override { } - void GetKeyboardMapScroll(const uint8 * keysState, sint32 * x, sint32 * y) override { } + void HandleKeyboard(bool isTitle) override { } std::string GetKeyboardShortcutString(sint32 shortcut) override { return std::string(); } }; diff --git a/src/openrct2/ui/WindowManager.h b/src/openrct2/ui/WindowManager.h index d0984165b4..353e3a7a36 100644 --- a/src/openrct2/ui/WindowManager.h +++ b/src/openrct2/ui/WindowManager.h @@ -36,8 +36,7 @@ namespace OpenRCT2 virtual ~IWindowManager() = default; virtual rct_window * OpenWindow(rct_windowclass wc) abstract; - virtual void HandleKeyboardShortcut(sint32 key) abstract; - virtual void GetKeyboardMapScroll(const uint8 * keysState, sint32 * x, sint32 * y) abstract; + virtual void HandleKeyboard(bool isTitle) abstract; virtual std::string GetKeyboardShortcutString(sint32 shortcut) abstract; }; From 006d6b720909479996e1434a6b2796ae909ab0e3 Mon Sep 17 00:00:00 2001 From: Richard Jenkins Date: Sun, 11 Jun 2017 22:15:01 +0100 Subject: [PATCH 2/2] Xcode fix --- OpenRCT2.xcodeproj/project.pbxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 7f643076b4..f80ce9b70f 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -77,6 +77,7 @@ D4EC48E61C2637710024B507 /* g2.dat in Resources */ = {isa = PBXBuildFile; fileRef = D4EC48E31C2637710024B507 /* g2.dat */; }; D4EC48E71C2637710024B507 /* language in Resources */ = {isa = PBXBuildFile; fileRef = D4EC48E41C2637710024B507 /* language */; }; D4EC48E81C2637710024B507 /* title in Resources */ = {isa = PBXBuildFile; fileRef = D4EC48E51C2637710024B507 /* title */; }; + F74789551EEDEA0D009E50E7 /* input.c in Sources */ = {isa = PBXBuildFile; fileRef = F74789531EEDEA0D009E50E7 /* input.c */; }; F76C85B01EC4E88300FA49E2 /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C83571EC4E7CC00FA49E2 /* audio.cpp */; }; F76C85B41EC4E88300FA49E2 /* AudioMixer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C835B1EC4E7CC00FA49E2 /* AudioMixer.cpp */; }; F76C85B71EC4E88300FA49E2 /* NullAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C835E1EC4E7CC00FA49E2 /* NullAudioSource.cpp */; }; @@ -773,6 +774,8 @@ D4EC48E31C2637710024B507 /* g2.dat */ = {isa = PBXFileReference; lastKnownFileType = file; name = g2.dat; path = data/g2.dat; sourceTree = SOURCE_ROOT; }; D4EC48E41C2637710024B507 /* language */ = {isa = PBXFileReference; lastKnownFileType = folder; name = language; path = data/language; sourceTree = SOURCE_ROOT; }; D4EC48E51C2637710024B507 /* title */ = {isa = PBXFileReference; lastKnownFileType = folder; name = title; path = data/title; sourceTree = SOURCE_ROOT; }; + F74789531EEDEA0D009E50E7 /* input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input.c; path = input/input.c; sourceTree = ""; }; + F74789541EEDEA0D009E50E7 /* input.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = input.h; path = input/input.h; sourceTree = ""; }; F76C809A1EC4D9FA00FA49E2 /* libopenrct2.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libopenrct2.a; sourceTree = BUILT_PRODUCTS_DIR; }; F76C83571EC4E7CC00FA49E2 /* audio.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = audio.cpp; sourceTree = ""; }; F76C83581EC4E7CC00FA49E2 /* audio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = ""; }; @@ -2593,6 +2596,8 @@ F7CB86451EEDA1200030C877 /* input */ = { isa = PBXGroup; children = ( + F74789531EEDEA0D009E50E7 /* input.c */, + F74789541EEDEA0D009E50E7 /* input.h */, F7CB86461EEDA1330030C877 /* keyboard_shortcut.c */, F7CB86471EEDA1330030C877 /* KeyboardShortcuts.cpp */, F7CB86481EEDA1330030C877 /* KeyboardShortcuts.h */, @@ -2952,6 +2957,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F74789551EEDEA0D009E50E7 /* input.c in Sources */, 4C8B42741EEB1B6F00F015CA /* Screenshot.cpp in Sources */, F76C88781EC5324E00FA49E2 /* AudioChannel.cpp in Sources */, F76C88791EC5324E00FA49E2 /* AudioContext.cpp in Sources */,