diff --git a/lang/system/en-gb.xml b/lang/system/en-gb.xml index 0b40c2f83..7a553c2bf 100644 --- a/lang/system/en-gb.xml +++ b/lang/system/en-gb.xml @@ -323,7 +323,7 @@ Connect a controller that is compatible with SDL3. PS button L1 button R1 button - Only in PS TV mode. + Only in PS TV mode L2 button R2 button L3 button diff --git a/lang/system/en.xml b/lang/system/en.xml index 77545ea23..1e64208a1 100644 --- a/lang/system/en.xml +++ b/lang/system/en.xml @@ -323,7 +323,7 @@ Connect a controller that is compatible with SDL3. PS button L1 button R1 button - Only in PS TV mode. + Only in PS TV mode L2 button R2 button L3 button diff --git a/vita3k/config/include/config/config.h b/vita3k/config/include/config/config.h index 2ae5775b7..8970acdc9 100644 --- a/vita3k/config/include/config/config.h +++ b/vita3k/config/include/config/config.h @@ -111,6 +111,7 @@ enum ScreenshotFormat { code(int, "performance-overlay-position", static_cast(TOP_LEFT), performance_overlay_position) \ code(int, "screenshot-format", static_cast(JPEG), screenshot_format) \ code(bool, "disable-motion", false, disable_motion) \ + code(float, "controller-analog-multiplier", 1.0f, controller_analog_multiplier) \ code(int, "keyboard-button-select", 229, keyboard_button_select) \ code(int, "keyboard-button-start", 40, keyboard_button_start) \ code(int, "keyboard-button-up", 82, keyboard_button_up) \ diff --git a/vita3k/ctrl/include/ctrl/state.h b/vita3k/ctrl/include/ctrl/state.h index 642a88e32..43678203c 100644 --- a/vita3k/ctrl/include/ctrl/state.h +++ b/vita3k/ctrl/include/ctrl/state.h @@ -56,6 +56,7 @@ struct CtrlState { std::mutex mutex; ControllerList controllers; int controllers_num = 0; + float analog_multiplier = 1.0f; bool has_motion_support = false; bool free_ports[SCE_CTRL_MAX_WIRELESS_NUM] = { true, true, true, true }; SceCtrlPadInputMode input_mode = SCE_CTRL_MODE_DIGITAL; diff --git a/vita3k/ctrl/src/ctrl.cpp b/vita3k/ctrl/src/ctrl.cpp index 010408ab0..489e624e6 100644 --- a/vita3k/ctrl/src/ctrl.cpp +++ b/vita3k/ctrl/src/ctrl.cpp @@ -179,29 +179,6 @@ static void apply_keyboard(uint32_t *buttons, float axes[4], bool ext, EmuEnvSta axes[3] += keys_to_axis(keys, static_cast(emuenv.cfg.keyboard_rightstick_up), static_cast(emuenv.cfg.keyboard_rightstick_down)); } -static float axis_to_axis(int16_t axis) { - const auto unsigned_axis = static_cast(axis - INT16_MIN); - assert(unsigned_axis >= 0); - assert(unsigned_axis <= UINT16_MAX); - - const float f = unsigned_axis / UINT16_MAX; - - const float output = (f * 2) - 1; - assert(output >= -1); - assert(output <= 1); - - return output; -} - -static uint8_t float_to_byte(float f) { - const float mapped = (f * 0.5f) + 0.5f; - const float clamped = std::max(0.0f, std::min(mapped, 1.0f)); - assert(clamped >= 0); - assert(clamped <= 1); - - return static_cast(clamped * 255); -} - static std::array get_controller_bindings(EmuEnvState &emuenv) { return { { { static_cast(emuenv.cfg.controller_binds[SDL_GAMEPAD_BUTTON_BACK]), SCE_CTRL_SELECT }, @@ -240,6 +217,25 @@ std::array get_controller_bindings_ext(EmuEnvState &emuen } }; } +static float axis_to_axis(int16_t axis, const auto &mult) { + const auto unsigned_axis = static_cast(axis - INT16_MIN); + assert(unsigned_axis >= 0); + assert(unsigned_axis <= UINT16_MAX); + + const auto f = unsigned_axis / UINT16_MAX; + + const auto output = std::clamp(((f * 2) - 1) * mult, -1.0f, 1.f); + + return output; +} + +static uint8_t float_to_byte(float f) { + const auto clamped_f = std::clamp(f, -1.0f, 1.0f); + const auto mapped = (clamped_f * 0.5f) + 0.5f; + + return static_cast(mapped * 255); +} + static void apply_controller(EmuEnvState &emuenv, uint32_t *buttons, float axes[4], SDL_Gamepad *controller, bool ext) { if (ext) { for (const auto &binding : get_controller_bindings_ext(emuenv)) { @@ -262,10 +258,11 @@ static void apply_controller(EmuEnvState &emuenv, uint32_t *buttons, float axes[ } } - axes[0] += axis_to_axis(SDL_GetGamepadAxis(controller, SDL_GAMEPAD_AXIS_LEFTX)); - axes[1] += axis_to_axis(SDL_GetGamepadAxis(controller, SDL_GAMEPAD_AXIS_LEFTY)); - axes[2] += axis_to_axis(SDL_GetGamepadAxis(controller, SDL_GAMEPAD_AXIS_RIGHTX)); - axes[3] += axis_to_axis(SDL_GetGamepadAxis(controller, SDL_GAMEPAD_AXIS_RIGHTY)); + auto &analog_multiplier = emuenv.cfg.controller_analog_multiplier; + axes[0] += axis_to_axis(SDL_GetGamepadAxis(controller, SDL_GAMEPAD_AXIS_LEFTX), analog_multiplier); + axes[1] += axis_to_axis(SDL_GetGamepadAxis(controller, SDL_GAMEPAD_AXIS_LEFTY), analog_multiplier); + axes[2] += axis_to_axis(SDL_GetGamepadAxis(controller, SDL_GAMEPAD_AXIS_RIGHTX), analog_multiplier); + axes[3] += axis_to_axis(SDL_GetGamepadAxis(controller, SDL_GAMEPAD_AXIS_RIGHTY), analog_multiplier); } static void retrieve_ctrl_data(EmuEnvState &emuenv, int port, bool is_v2, bool negative, bool from_ext_function, SceUInt32 &buttons, SceUInt8 &lx, SceUInt8 &ly, SceUInt8 &rx, SceUInt8 &ry) { @@ -276,7 +273,7 @@ static void retrieve_ctrl_data(EmuEnvState &emuenv, int port, bool is_v2, bool n } CtrlState &state = emuenv.ctrl; - std::array axes; + std::array axes{}; axes.fill(0); const auto reset_axes = [&]() { diff --git a/vita3k/gui/src/controllers_dialog.cpp b/vita3k/gui/src/controllers_dialog.cpp index fe1ac7820..85573e5e2 100644 --- a/vita3k/gui/src/controllers_dialog.cpp +++ b/vita3k/gui/src/controllers_dialog.cpp @@ -334,7 +334,7 @@ void draw_controllers_dialog(GuiState &gui, EmuEnvState &emuenv) { ImGui::Separator(); ImGui::Spacing(); - ImGui::TextColored(GUI_COLOR_TEXT_TITLE, "%s", controls["ps_tv_mode"].c_str()); + TextColoredCentered(GUI_COLOR_TEXT_TITLE, controls["ps_tv_mode"].c_str()); if (ImGui::BeginTable("rebindExt", 2, ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_BordersInnerV)) { ImGui::TableSetupColumn("leftButtons"); ImGui::TableSetupColumn("rightButtons"); @@ -355,7 +355,18 @@ void draw_controllers_dialog(GuiState &gui, EmuEnvState &emuenv) { } ImGui::EndTable(); } - + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + TextColoredCentered(GUI_COLOR_TEXT_TITLE, "Analog Stick Multiplier"); + ImGui::Spacing(); + auto &mult = emuenv.cfg.controller_analog_multiplier; + if (ImGui::SliderFloat("##analog_multiplier", &mult, 0.1f, 2.f, "%.1fx", ImGuiSliderFlags_AlwaysClamp)) + config::serialize_config(emuenv.cfg, emuenv.cfg.config_path); + SetTooltipEx("Analog multipiler can be used to change the sensitivity of your stick movements."); + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); if (ctrl.controllers[guid].has_led) { const auto set_led_color = [&](const std::vector &led) { SDL_SetGamepadLED(ctrl.controllers[guid].controller.get(), led[0], led[1], led[2]); diff --git a/vita3k/lang/include/lang/state.h b/vita3k/lang/include/lang/state.h index c130e82b0..6492691df 100644 --- a/vita3k/lang/include/lang/state.h +++ b/vita3k/lang/include/lang/state.h @@ -294,7 +294,7 @@ struct LangState { { "ps_button", "PS button" }, { "l1_button", "L1 button" }, { "r1_button", "R1 button" }, - { "ps_tv_mode", "Only in PS TV mode." }, + { "ps_tv_mode", "Only in PS TV mode" }, { "l2_button", "L2 button" }, { "r2_button", "R2 button" }, { "l3_button", "L3 button" },