From e19e72ea622fbff349b8d9c2b2858254ba42df36 Mon Sep 17 00:00:00 2001 From: thecozies <79979276+thecozies@users.noreply.github.com> Date: Mon, 4 Mar 2024 11:50:11 -0600 Subject: [PATCH] controller input in ui --- src/game/input.cpp | 9 ++++-- src/ui/ui_renderer.cpp | 63 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/game/input.cpp b/src/game/input.cpp index 39d3193..d649003 100644 --- a/src/game/input.cpp +++ b/src/game/input.cpp @@ -77,9 +77,10 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) { } if (scanning_device == recomp::InputDevice::Keyboard) { set_scanned_input({(uint32_t)InputType::Keyboard, keyevent->keysym.scancode}); + } else { + queue_if_enabled(event); } } - queue_if_enabled(event); break; case SDL_EventType::SDL_CONTROLLERDEVICEADDED: { @@ -119,8 +120,9 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) { if (scanning_device == recomp::InputDevice::Controller) { SDL_ControllerButtonEvent* button_event = &event->cbutton; set_scanned_input({(uint32_t)InputType::ControllerDigital, button_event->button}); + } else { + queue_if_enabled(event); } - queue_if_enabled(event); break; case SDL_EventType::SDL_CONTROLLERAXISMOTION: if (scanning_device == recomp::InputDevice::Controller) { @@ -132,8 +134,9 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) { else if (axis_value < -axis_threshold) { set_scanned_input({(uint32_t)InputType::ControllerAnalog, -axis_event->axis - 1}); } + } else { + queue_if_enabled(event); } - queue_if_enabled(event); break; case SDL_EventType::SDL_CONTROLLERSENSORUPDATE: if (event->csensor.sensor == SDL_SensorType::SDL_SENSOR_ACCEL) { diff --git a/src/ui/ui_renderer.cpp b/src/ui/ui_renderer.cpp index ab51c1a..62d6b4b 100644 --- a/src/ui/ui_renderer.cpp +++ b/src/ui/ui_renderer.cpp @@ -775,6 +775,8 @@ struct UIContext { public: bool mouse_is_active_initialized = false; bool mouse_is_active = false; + bool await_stick_return_x = false; + bool await_stick_return_y = false; std::unique_ptr system_interface; std::unique_ptr render_interface; std::unique_ptr font_interface; @@ -1044,6 +1046,36 @@ bool recomp::try_deque_event(SDL_Event& out) { std::atomic open_menu = recomp::Menu::Launcher; std::atomic open_config_submenu = recomp::ConfigSubmenu::Count; +int cont_button_to_key(SDL_ControllerButtonEvent& button) { + switch (button.button) { + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP: + return SDLK_UP; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN: + return SDLK_DOWN; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT: + return SDLK_LEFT; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + return SDLK_RIGHT; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A: + return SDLK_RETURN; + } + return 0; +} + + +int cont_axis_to_key(SDL_ControllerAxisEvent& axis, float value) { + switch (axis.axis) { + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY: + if (value < 0) return SDLK_UP; + return SDLK_DOWN; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX: + if (value >= 0) return SDLK_RIGHT; + return SDLK_LEFT; + } + return 0; +} + + void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* swap_chain_framebuffer) { std::lock_guard lock {ui_context_mutex}; @@ -1111,8 +1143,7 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s break; } - // Send events to RmlUi if a menu is open. - if (cur_menu != recomp::Menu::None) { + if (cur_menu != recomp::Menu::None && !recomp::all_input_disabled()) { // Implement some additional behavior for specific events on top of what RmlUi normally does with them. switch (cur_event.type) { case SDL_EventType::SDL_MOUSEMOTION: @@ -1124,16 +1155,40 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s mouse_moved = true; break; - case SDL_EventType::SDL_CONTROLLERBUTTONDOWN: + case SDL_EventType::SDL_CONTROLLERBUTTONDOWN: { + int rml_key = cont_button_to_key(cur_event.cbutton); + if (rml_key) { + ui_context->rml.context->ProcessKeyDown(RmlSDL::ConvertKey(rml_key), 0); + } + } + // fallthrough case SDL_EventType::SDL_KEYDOWN: non_mouse_interacted = true; break; case SDL_EventType::SDL_CONTROLLERAXISMOTION: SDL_ControllerAxisEvent* axis_event = &cur_event.caxis; + if (axis_event->axis != SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY && axis_event->axis != SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX) { + break; + } + float axis_value = axis_event->value * (1 / 32768.0f); - if (fabsf(axis_value) > 0.2f) { + bool* await_stick_return = axis_event->axis == SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY + ? &ui_context->rml.await_stick_return_y + : &ui_context->rml.await_stick_return_x; + if (fabsf(axis_value) > 0.5f) { + if (!*await_stick_return) { + *await_stick_return = true; + non_mouse_interacted = true; + int rml_key = cont_axis_to_key(cur_event.caxis, axis_value); + if (rml_key) { + ui_context->rml.context->ProcessKeyDown(RmlSDL::ConvertKey(rml_key), 0); + } + } non_mouse_interacted = true; } + else if (*await_stick_return && fabsf(axis_value) < 0.15f) { + *await_stick_return = false; + } break; }