From df738c6dc13d44cce0743535b3bd5650d4a9a96c Mon Sep 17 00:00:00 2001 From: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:20:46 +0100 Subject: [PATCH] Axis outputs work now --- src/input/input_handler.cpp | 129 ++++++++++++++++++++++++++++++------ src/input/input_handler.h | 23 +++---- src/sdl_window.cpp | 15 +++++ 3 files changed, 132 insertions(+), 35 deletions(-) diff --git a/src/input/input_handler.cpp b/src/input/input_handler.cpp index c72689c07..2655c110e 100644 --- a/src/input/input_handler.cpp +++ b/src/input/input_handler.cpp @@ -139,12 +139,10 @@ void parseInputConfig(const std::string game_id = "") { // todo // we reset these here so in case the user fucks up or doesn't include this we can fall back to // default + connections.clear(); mouse_deadzone_offset = 0.5; mouse_speed = 1; mouse_speed_offset = 0.125; - //old_button_map.clear(); - //old_axis_map.clear(); - //old_key_to_modkey_toggle_map.clear(); int lineCount = 0; std::ifstream file(config_file); @@ -187,7 +185,6 @@ void parseInputConfig(const std::string game_id = "") { if (before_equals == "modkey_toggle") { if (comma_pos != std::string::npos) { // handle key-to-key toggling (separate list?) - // todo LOG_ERROR(Input, "todo"); continue; } @@ -211,10 +208,10 @@ void parseInputConfig(const std::string game_id = "") { } if (button_it != string_to_cbutton_map.end()) { connection = BindingConnection(binding, getOutputPointer(ControllerOutput(button_it->second))); - connections.insert(connections.end(), connection); + connections.insert(connections.end(), connection); } else if (axis_it != string_to_axis_map.end()) { connection = BindingConnection(binding, getOutputPointer(ControllerOutput(0, axis_it->second.axis)), axis_it->second.value); - connections.insert(connections.end(), connection); + connections.insert(connections.end(), connection); } else { LOG_ERROR(Input, "Invalid format at line: {}, data: \"{}\", skipping line.", lineCount, line); continue; @@ -224,19 +221,43 @@ void parseInputConfig(const std::string game_id = "") { file.close(); } -// todo: add an init for this +Uint32 getMouseWheelEvent(const SDL_Event& event) { + if (event.type != SDL_EVENT_MOUSE_WHEEL || event.type != SDL_EVENT_MOUSE_WHEEL_OFF) + return 0; + if (event.wheel.y > 0) { + return SDL_MOUSE_WHEEL_UP; + } else if (event.wheel.y < 0) { + return SDL_MOUSE_WHEEL_DOWN; + } else if (event.wheel.x > 0) { + return SDL_MOUSE_WHEEL_RIGHT; + } else if (event.wheel.x < 0) { + return SDL_MOUSE_WHEEL_LEFT; + } + return 0; +} + +u32 InputBinding::getInputIDFromEvent(const SDL_Event& e) { + switch(e.type) { + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + return e.key.key; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + return (u32)e.button.button; + case SDL_EVENT_MOUSE_WHEEL: + case SDL_EVENT_MOUSE_WHEEL_OFF: + return getMouseWheelEvent(e); + default: + return (u32)-1; + } +} + GameController* ControllerOutput::controller = nullptr; void ControllerOutput::setControllerOutputController(GameController* c) { ControllerOutput::controller = c; } - - -void ControllerOutput::update(bool pressed, int axis_value) { - if(controller == nullptr) { - LOG_ERROR(Input, "No controller found!"); - return; - } +void ControllerOutput::update(bool pressed, int a_value) { float touchpad_x = 0; if(button != 0){ switch (button) { @@ -278,18 +299,77 @@ void ControllerOutput::update(bool pressed, int axis_value) { case Axis::TriggerLeft: case Axis::TriggerRight: // todo: verify this works - controller->Axis(0, axis, GetAxis(0, 0x80, pressed ? 128 : 0)); + //controller->Axis(0, axis, GetAxis(0, 0x80, pressed ? 128 : 0)); break; default: break; } - int output_value = (pressed ? axis_value : 0) * multiplier; - int ax = GetAxis(-0x80, 0x80, output_value); + axis_value = SDL_clamp((pressed ? a_value : 0) * multiplier, -127, 127); + int ax = GetAxis(-0x80, 0x80, axis_value); controller->Axis(0, axis, ax); } else { LOG_ERROR(Input, "Controller output with no values detected!"); } } +void ControllerOutput::addUpdate(bool pressed, int a_value) { + + float touchpad_x = 0; + if(button != 0){ + if(!pressed) { + return; + } + switch (button) { + // todo: check if l2 and r2 can be moved to the axis section + case OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2: + case OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2: + axis = (button == OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2) ? Axis::TriggerRight + : Axis::TriggerLeft; + controller->Axis(0, axis, GetAxis(0, 0x80, pressed ? 128 : 0)); + break; + case OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD: + touchpad_x = Config::getBackButtonBehavior() == "left" ? 0.25f + : Config::getBackButtonBehavior() == "right" ? 0.75f + : 0.5f; + controller->SetTouchpadState(0, true, touchpad_x, 0.5f); + controller->CheckButton(0, button, pressed); + break; + case LEFTJOYSTICK_HALFMODE: + leftjoystick_halfmode ^= pressed; // toggle if pressed, don't change otherwise + break; + case RIGHTJOYSTICK_HALFMODE: + rightjoystick_halfmode ^= pressed; + break; + default: // is a normal key (hopefully) + controller->CheckButton(0, button, pressed); + break; + } + } else if (axis != Axis::AxisMax) { + float multiplier = 1.0; + switch (axis) { + case Axis::LeftX: + case Axis::LeftY: + multiplier = leftjoystick_halfmode ? 0.5 : 1.0; + break; + case Axis::RightX: + case Axis::RightY: + multiplier = rightjoystick_halfmode ? 0.5 : 1.0; + break; + case Axis::TriggerLeft: + case Axis::TriggerRight: + // todo: verify this works + //controller->Axis(0, axis, GetAxis(0, 0x80, pressed ? 128 : 0)); + break; + default: + break; + } + axis_value = SDL_clamp((pressed ? a_value : 0) * multiplier + axis_value, -127, 127); + int ax = GetAxis(-0x80, 0x80, axis_value); + controller->Axis(0, axis, ax); + LOG_INFO(Input, "Axis value delta: {} final value: {}", a_value, axis_value); + } else { + LOG_ERROR(Input, "Controller output with no values detected!"); + } +} void updatePressedKeys(u32 value, bool is_pressed) { if (is_pressed) { @@ -344,15 +424,22 @@ bool isInputActive(const InputBinding& i) { } void activateOutputsFromInputs() { - // iterates over the connections, and updates them depending on whether the corresponding input trio is found + // reset everything for(auto it = connections.begin(); it != connections.end(); it++) { - if (it->output) { // Check if output is not nullptr - it->output->update(isInputActive(it->binding), it->axis_value); - LOG_INFO(Input, "Updating an output"); + if (it->output) { + it->output->update(false, 0); } else { LOG_ERROR(Input, "Null output in BindingConnection at position {}", std::distance(connections.begin(), it)); } } + // iterates over the connections, and updates them depending on whether the corresponding input trio is found + for(auto it = connections.begin(); it != connections.end(); it++) { + if (it->output) { + it->output->addUpdate(isInputActive(it->binding), it->axis_value); + } else { + //LOG_ERROR(Input, "Null output in BindingConnection at position {}", std::distance(connections.begin(), it)); + } + } } void updateMouse(GameController* controller) { diff --git a/src/input/input_handler.h b/src/input/input_handler.h index 73ad461cb..0f3291b96 100644 --- a/src/input/input_handler.h +++ b/src/input/input_handler.h @@ -21,6 +21,9 @@ #define SDL_MOUSE_WHEEL_LEFT SDL_EVENT_MOUSE_WHEEL + 5 #define SDL_MOUSE_WHEEL_RIGHT SDL_EVENT_MOUSE_WHEEL + 7 +// idk who already used what where so I just chose a big number +#define SDL_EVENT_MOUSE_WHEEL_OFF SDL_EVENT_USER + 10 + #define LEFTJOYSTICK_HALFMODE 0x00010000 #define RIGHTJOYSTICK_HALFMODE 0x00020000 @@ -219,19 +222,7 @@ public: } // returns a u32 based on the event type (keyboard, mouse buttons, or wheel) - static u32 getInputIDFromEvent(const SDL_Event& e) { - switch(e.type) { - case SDL_EVENT_KEY_DOWN: - case SDL_EVENT_KEY_UP: - return e.key.key; - case SDL_EVENT_MOUSE_BUTTON_DOWN: - case SDL_EVENT_MOUSE_BUTTON_UP: - return (u32)e.button.button; - default: - // todo: add the rest (wheel) - return 0; - } - } + static u32 getInputIDFromEvent(const SDL_Event& e); }; class ControllerOutput { @@ -241,10 +232,12 @@ public: u32 button; Axis axis; + int axis_value; ControllerOutput(const u32 b, Axis a = Axis::AxisMax) { button = b; axis = a; + axis_value = 0; } ControllerOutput(const ControllerOutput& o) : button(o.button), axis(o.axis) {} inline bool operator==(const ControllerOutput& o) const { // fucking consts everywhere @@ -254,6 +247,8 @@ public: return button != o.button || axis != o.axis; } void update(bool pressed, int axis_direction = 0); + // Off events are not counted + void addUpdate(bool pressed, int axis_direction = 0); }; class BindingConnection { public: @@ -262,7 +257,7 @@ public: int axis_value; BindingConnection(InputBinding b, ControllerOutput* out, int a_v = 0) { binding = b; - axis_value = 0; + axis_value = a_v; // bruh this accidentally set to be 0 no wonder it didn't do anything // todo: check if out is in the allowed array output = out; diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index e7dfbae07..8ff2f14f1 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -111,6 +111,7 @@ void WindowSDL::waitEvent() { case SDL_EVENT_MOUSE_BUTTON_DOWN: case SDL_EVENT_MOUSE_BUTTON_UP: case SDL_EVENT_MOUSE_WHEEL: + case SDL_EVENT_MOUSE_WHEEL_OFF: case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: onKeyboardMouseInput(&event); @@ -144,6 +145,14 @@ void WindowSDL::onResize() { ImGui::Core::OnResize(); } +Uint32 wheelOffCallback(void* og_event, Uint32 timer_id, Uint32 interval) { + SDL_Event off_event = *(SDL_Event*)og_event; + off_event.type = SDL_EVENT_MOUSE_WHEEL_OFF; + SDL_PushEvent(&off_event); + delete (SDL_Event*)og_event; + return 0; +} + void WindowSDL::onKeyboardMouseInput(const SDL_Event* event) { using Libraries::Pad::OrbisPadButtonDataOffset; @@ -176,6 +185,12 @@ void WindowSDL::onKeyboardMouseInput(const SDL_Event* event) { VideoCore::TriggerCapture(); } } + + // if it's a wheel event, make a timer that turns it off after a set time + if(event->type == SDL_EVENT_MOUSE_WHEEL) { + const SDL_Event* copy = new SDL_Event(*event); + SDL_AddTimer(33, wheelOffCallback, (void*)copy); + } // add/remove it from the list Input::updatePressedKeys(input_id, input_down);