mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
Implement more InputManager
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,17 @@
|
||||
|
||||
#include "InputManager.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <openrct2-ui/UiContext.h>
|
||||
#include <openrct2-ui/input/ShortcutManager.h>
|
||||
#include <openrct2-ui/interface/InGameConsole.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/interface/Chat.h>
|
||||
#include <openrct2/interface/Window.h>
|
||||
#include <openrct2/paint/VirtualFloor.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -39,7 +39,12 @@ namespace OpenRCT2::Ui
|
||||
private:
|
||||
std::queue<InputEvent> _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);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "ShortcutManager.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <openrct2-ui/UiContext.h>
|
||||
#include <openrct2-ui/interface/InGameConsole.h>
|
||||
#include <openrct2-ui/interface/Viewport.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/interface/Window.h>
|
||||
@@ -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)))
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user