From c3f7a4301cecbe773f0415bf41d5ea9c9eca868e Mon Sep 17 00:00:00 2001 From: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:21:01 +0100 Subject: [PATCH 1/3] Add basic mouse-to-touchpad emulation (#3842) --- src/common/config.cpp | 1 + src/input/input_handler.cpp | 4 ++++ src/input/input_handler.h | 11 +++++++---- src/input/input_mouse.cpp | 18 +++++++++++++++++- src/input/input_mouse.h | 1 + src/sdl_window.cpp | 5 +++++ 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index e79652b32..94d8b488c 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -1310,6 +1310,7 @@ hotkey_pause = f9 hotkey_reload_inputs = f8 hotkey_toggle_mouse_to_joystick = f7 hotkey_toggle_mouse_to_gyro = f6 +hotkey_toggle_mouse_to_touchpad = delete hotkey_quit = lctrl, lshift, end )"; } diff --git a/src/input/input_handler.cpp b/src/input/input_handler.cpp index d38b45ddd..01c6d1fa4 100644 --- a/src/input/input_handler.cpp +++ b/src/input/input_handler.cpp @@ -106,6 +106,7 @@ auto output_array = std::array{ ControllerOutput(HOTKEY_RELOAD_INPUTS), ControllerOutput(HOTKEY_TOGGLE_MOUSE_TO_JOYSTICK), ControllerOutput(HOTKEY_TOGGLE_MOUSE_TO_GYRO), + ControllerOutput(HOTKEY_TOGGLE_MOUSE_TO_TOUCHPAD), ControllerOutput(HOTKEY_RENDERDOC), ControllerOutput(SDL_GAMEPAD_BUTTON_INVALID, SDL_GAMEPAD_AXIS_INVALID), @@ -579,6 +580,9 @@ void ControllerOutput::FinalizeUpdate() { case HOTKEY_TOGGLE_MOUSE_TO_GYRO: PushSDLEvent(SDL_EVENT_MOUSE_TO_GYRO); break; + case HOTKEY_TOGGLE_MOUSE_TO_TOUCHPAD: + PushSDLEvent(SDL_EVENT_MOUSE_TO_TOUCHPAD); + break; case HOTKEY_RENDERDOC: PushSDLEvent(SDL_EVENT_RDOC_CAPTURE); break; diff --git a/src/input/input_handler.h b/src/input/input_handler.h index 0d95d1c4a..eaadd164e 100644 --- a/src/input/input_handler.h +++ b/src/input/input_handler.h @@ -34,9 +34,10 @@ #define SDL_EVENT_RELOAD_INPUTS SDL_EVENT_USER + 5 #define SDL_EVENT_MOUSE_TO_JOYSTICK SDL_EVENT_USER + 6 #define SDL_EVENT_MOUSE_TO_GYRO SDL_EVENT_USER + 7 -#define SDL_EVENT_RDOC_CAPTURE SDL_EVENT_USER + 8 -#define SDL_EVENT_QUIT_DIALOG SDL_EVENT_USER + 9 -#define SDL_EVENT_MOUSE_WHEEL_OFF SDL_EVENT_USER + 10 +#define SDL_EVENT_MOUSE_TO_TOUCHPAD SDL_EVENT_USER + 8 +#define SDL_EVENT_RDOC_CAPTURE SDL_EVENT_USER + 9 +#define SDL_EVENT_QUIT_DIALOG SDL_EVENT_USER + 10 +#define SDL_EVENT_MOUSE_WHEEL_OFF SDL_EVENT_USER + 11 #define LEFTJOYSTICK_HALFMODE 0x00010000 #define RIGHTJOYSTICK_HALFMODE 0x00020000 @@ -52,7 +53,8 @@ #define HOTKEY_RELOAD_INPUTS 0xf0000005 #define HOTKEY_TOGGLE_MOUSE_TO_JOYSTICK 0xf0000006 #define HOTKEY_TOGGLE_MOUSE_TO_GYRO 0xf0000007 -#define HOTKEY_RENDERDOC 0xf0000008 +#define HOTKEY_TOGGLE_MOUSE_TO_TOUCHPAD 0xf0000008 +#define HOTKEY_RENDERDOC 0xf0000009 #define SDL_UNMAPPED UINT32_MAX - 1 @@ -141,6 +143,7 @@ const std::map string_to_cbutton_map = { {"hotkey_reload_inputs", HOTKEY_RELOAD_INPUTS}, {"hotkey_toggle_mouse_to_joystick", HOTKEY_TOGGLE_MOUSE_TO_JOYSTICK}, {"hotkey_toggle_mouse_to_gyro", HOTKEY_TOGGLE_MOUSE_TO_GYRO}, + {"hotkey_toggle_mouse_to_touchpad", HOTKEY_TOGGLE_MOUSE_TO_TOUCHPAD}, {"hotkey_renderdoc_capture", HOTKEY_RENDERDOC}, }; diff --git a/src/input/input_mouse.cpp b/src/input/input_mouse.cpp index 3c718dbd5..55489283c 100644 --- a/src/input/input_mouse.cpp +++ b/src/input/input_mouse.cpp @@ -8,8 +8,12 @@ #include "input/controller.h" #include "input_mouse.h" +#include +#include #include "SDL3/SDL.h" +extern Frontend::WindowSDL* g_window; + namespace Input { int mouse_joystick_binding = 0; @@ -80,7 +84,6 @@ void EmulateJoystick(GameController* controller, u32 interval) { constexpr float constant_down_accel[3] = {0.0f, 10.0f, 0.0f}; void EmulateGyro(GameController* controller, u32 interval) { - // LOG_INFO(Input, "todo gyro"); float d_x = 0, d_y = 0; SDL_GetRelativeMouseState(&d_x, &d_y); controller->Acceleration(1, constant_down_accel); @@ -92,6 +95,16 @@ void EmulateGyro(GameController* controller, u32 interval) { controller->Gyro(1, gyro_from_mouse); } +void EmulateTouchpad(GameController* controller, u32 interval) { + float x, y; + SDL_MouseButtonFlags mouse_buttons = SDL_GetMouseState(&x, &y); + controller->SetTouchpadState(0, (mouse_buttons & SDL_BUTTON_LMASK) != 0, + std::clamp(x / g_window->GetWidth(), 0.0f, 1.0f), + std::clamp(y / g_window->GetHeight(), 0.0f, 1.0f)); + controller->CheckButton(0, Libraries::Pad::OrbisPadButtonDataOffset::TouchPad, + (mouse_buttons & SDL_BUTTON_RMASK) != 0); +} + Uint32 MousePolling(void* param, Uint32 id, Uint32 interval) { auto* controller = (GameController*)param; switch (mouse_mode) { @@ -101,6 +114,9 @@ Uint32 MousePolling(void* param, Uint32 id, Uint32 interval) { case MouseMode::Gyro: EmulateGyro(controller, interval); break; + case MouseMode::Touchpad: + EmulateTouchpad(controller, interval); + break; default: break; diff --git a/src/input/input_mouse.h b/src/input/input_mouse.h index a56ef2d8f..995f836f2 100644 --- a/src/input/input_mouse.h +++ b/src/input/input_mouse.h @@ -12,6 +12,7 @@ enum MouseMode { Off = 0, Joystick, Gyro, + Touchpad, }; bool ToggleMouseModeTo(MouseMode m); diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 449defdd1..476a56b52 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -457,6 +457,11 @@ void WindowSDL::WaitEvent() { SDL_SetWindowRelativeMouseMode(this->GetSDLWindow(), Input::ToggleMouseModeTo(Input::MouseMode::Gyro)); break; + case SDL_EVENT_MOUSE_TO_TOUCHPAD: + SDL_SetWindowRelativeMouseMode(this->GetSDLWindow(), + Input::ToggleMouseModeTo(Input::MouseMode::Touchpad)); + SDL_SetWindowRelativeMouseMode(this->GetSDLWindow(), false); + break; case SDL_EVENT_RDOC_CAPTURE: VideoCore::TriggerCapture(); break; From e5ea55e42588407e92a82dad47e84b83df5b4114 Mon Sep 17 00:00:00 2001 From: Pirky <92021796+Pirky10@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:22:41 +0100 Subject: [PATCH 2/3] np: Add dialog state tracking for NpCommerce (#3841) --- src/core/libraries/np/np_commerce.cpp | 63 ++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/src/core/libraries/np/np_commerce.cpp b/src/core/libraries/np/np_commerce.cpp index 1e8440ec0..99b03384a 100644 --- a/src/core/libraries/np/np_commerce.cpp +++ b/src/core/libraries/np/np_commerce.cpp @@ -4,46 +4,87 @@ #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" +#include "core/libraries/system/commondialog.h" namespace Libraries::Np::NpCommerce { + +using CommonDialog::Error; +using CommonDialog::Result; +using CommonDialog::Status; + +static Status g_dialog_status = Status::NONE; +static Result g_dialog_result = Result::OK; + s32 PS4_SYSV_ABI sceNpCommerceDialogClose() { - LOG_ERROR(Lib_NpCommerce, "(STUBBED) called"); + LOG_INFO(Lib_NpCommerce, "called"); + if (g_dialog_status == Status::NONE) { + return static_cast(Error::NOT_INITIALIZED); + } + if (g_dialog_status != Status::FINISHED) { + return static_cast(Error::NOT_FINISHED); + } + g_dialog_status = Status::INITIALIZED; return ORBIS_OK; } s32 PS4_SYSV_ABI sceNpCommerceDialogGetResult(s32* result) { - LOG_ERROR(Lib_NpCommerce, "(STUBBED) called"); + LOG_INFO(Lib_NpCommerce, "called"); + if (result == nullptr) { + return static_cast(Error::ARG_NULL); + } + if (g_dialog_status != Status::FINISHED) { + return static_cast(Error::NOT_FINISHED); + } + *result = static_cast(g_dialog_result); return ORBIS_OK; } s8 PS4_SYSV_ABI sceNpCommerceDialogGetStatus() { - LOG_ERROR(Lib_NpCommerce, "(STUBBED) called"); - return ORBIS_OK; + LOG_DEBUG(Lib_NpCommerce, "called, status = {}", static_cast(g_dialog_status)); + return static_cast(g_dialog_status); } s32 PS4_SYSV_ABI sceNpCommerceDialogInitialize() { - LOG_ERROR(Lib_NpCommerce, "(STUBBED) called"); + LOG_INFO(Lib_NpCommerce, "called"); + if (g_dialog_status != Status::NONE) { + return static_cast(Error::ALREADY_INITIALIZED); + } + g_dialog_status = Status::INITIALIZED; return ORBIS_OK; } s32 PS4_SYSV_ABI sceNpCommerceDialogInitializeInternal() { - LOG_ERROR(Lib_NpCommerce, "(STUBBED) called"); - return ORBIS_OK; + LOG_INFO(Lib_NpCommerce, "called"); + return sceNpCommerceDialogInitialize(); } s16 PS4_SYSV_ABI sceNpCommerceDialogOpen(s64 check) { - LOG_ERROR(Lib_NpCommerce, "(STUBBED) called"); + LOG_INFO(Lib_NpCommerce, "called, check = {}", check); + if (g_dialog_status != Status::INITIALIZED) { + LOG_WARNING(Lib_NpCommerce, "Dialog not initialized"); + return ORBIS_OK; + } + + g_dialog_status = Status::FINISHED; + g_dialog_result = Result::USER_CANCELED; return ORBIS_OK; } s32 PS4_SYSV_ABI sceNpCommerceDialogTerminate() { - LOG_ERROR(Lib_NpCommerce, "(STUBBED) called"); + LOG_INFO(Lib_NpCommerce, "called"); + if (g_dialog_status == Status::NONE) { + return static_cast(Error::NOT_INITIALIZED); + } + if (g_dialog_status == Status::RUNNING) { + return static_cast(Error::NOT_FINISHED); + } + g_dialog_status = Status::NONE; return ORBIS_OK; } s32 PS4_SYSV_ABI sceNpCommerceDialogUpdateStatus() { - LOG_ERROR(Lib_NpCommerce, "(STUBBED) called"); - return ORBIS_OK; + LOG_DEBUG(Lib_NpCommerce, "called, status = {}", static_cast(g_dialog_status)); + return static_cast(g_dialog_status); } s32 PS4_SYSV_ABI sceNpCommerceHidePsStoreIcon() { From dc6013cf0e19a66f489178da2235d2468fbb0186 Mon Sep 17 00:00:00 2001 From: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:41:06 +0100 Subject: [PATCH 3/3] Block normal mouse inputs in mouse-to-touchpad mode shadow sniped my PR. :( --- src/input/input_handler.cpp | 3 +++ src/input/input_mouse.cpp | 19 +++++++++++++++++++ src/input/input_mouse.h | 2 ++ 3 files changed, 24 insertions(+) diff --git a/src/input/input_handler.cpp b/src/input/input_handler.cpp index 01c6d1fa4..e74569737 100644 --- a/src/input/input_handler.cpp +++ b/src/input/input_handler.cpp @@ -777,6 +777,9 @@ void ActivateOutputsFromInputs() { it.ResetUpdate(); } + // Check for input blockers + ApplyMouseInputBlockers(); + // Iterate over all inputs, and update their respecive outputs accordingly for (auto& it : connections) { it.output->AddUpdate(it.ProcessBinding()); diff --git a/src/input/input_mouse.cpp b/src/input/input_mouse.cpp index 55489283c..cead87e53 100644 --- a/src/input/input_mouse.cpp +++ b/src/input/input_mouse.cpp @@ -6,6 +6,7 @@ #include "common/assert.h" #include "common/types.h" #include "input/controller.h" +#include "input/input_handler.h" #include "input_mouse.h" #include @@ -16,6 +17,8 @@ extern Frontend::WindowSDL* g_window; namespace Input { +extern std::list> pressed_keys; + int mouse_joystick_binding = 0; float mouse_deadzone_offset = 0.5, mouse_speed = 1, mouse_speed_offset = 0.1250; bool mouse_gyro_roll_mode = false; @@ -105,6 +108,22 @@ void EmulateTouchpad(GameController* controller, u32 interval) { (mouse_buttons & SDL_BUTTON_RMASK) != 0); } +void ApplyMouseInputBlockers() { + switch (mouse_mode) { + case MouseMode::Touchpad: + LOG_INFO(Input, "Blocking mouse inputs"); + for (auto& k : pressed_keys) { + if (k.first.input.sdl_id == SDL_BUTTON_LEFT || + k.first.input.sdl_id == SDL_BUTTON_RIGHT) { + k.second = true; + } + } + break; + default: + break; + } +} + Uint32 MousePolling(void* param, Uint32 id, Uint32 interval) { auto* controller = (GameController*)param; switch (mouse_mode) { diff --git a/src/input/input_mouse.h b/src/input/input_mouse.h index 995f836f2..da1d874ec 100644 --- a/src/input/input_mouse.h +++ b/src/input/input_mouse.h @@ -23,6 +23,8 @@ void SetMouseGyroRollMode(bool mode); void EmulateJoystick(GameController* controller, u32 interval); void EmulateGyro(GameController* controller, u32 interval); +void ApplyMouseInputBlockers(); + // Polls the mouse for changes Uint32 MousePolling(void* param, Uint32 id, Uint32 interval);