ctrl: add analog stick multiplier

This commit is contained in:
nishinji
2025-09-25 20:20:18 +09:00
committed by Pedro Montes Alcalde
parent 3cd116a8b2
commit 9aa969151f
7 changed files with 43 additions and 33 deletions
+1 -1
View File
@@ -323,7 +323,7 @@ Connect a controller that is compatible with SDL3.</not_connected>
<ps_button>PS button</ps_button>
<l1_button>L1 button</l1_button>
<r1_button>R1 button</r1_button>
<ps_tv_mode>Only in PS TV mode.</ps_tv_mode>
<ps_tv_mode>Only in PS TV mode</ps_tv_mode>
<l2_button>L2 button</l2_button>
<r2_button>R2 button</r2_button>
<l3_button>L3 button</l3_button>
+1 -1
View File
@@ -323,7 +323,7 @@ Connect a controller that is compatible with SDL3.</not_connected>
<ps_button>PS button</ps_button>
<l1_button>L1 button</l1_button>
<r1_button>R1 button</r1_button>
<ps_tv_mode>Only in PS TV mode.</ps_tv_mode>
<ps_tv_mode>Only in PS TV mode</ps_tv_mode>
<l2_button>L2 button</l2_button>
<r2_button>R2 button</r2_button>
<l3_button>L3 button</l3_button>
+1
View File
@@ -111,6 +111,7 @@ enum ScreenshotFormat {
code(int, "performance-overlay-position", static_cast<int>(TOP_LEFT), performance_overlay_position) \
code(int, "screenshot-format", static_cast<int>(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) \
+1
View File
@@ -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;
+25 -28
View File
@@ -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<SDL_Scancode>(emuenv.cfg.keyboard_rightstick_up), static_cast<SDL_Scancode>(emuenv.cfg.keyboard_rightstick_down));
}
static float axis_to_axis(int16_t axis) {
const auto unsigned_axis = static_cast<float>(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<float>(0.0f, std::min<float>(mapped, 1.0f));
assert(clamped >= 0);
assert(clamped <= 1);
return static_cast<uint8_t>(clamped * 255);
}
static std::array<ControllerBinding, 13> get_controller_bindings(EmuEnvState &emuenv) {
return { {
{ static_cast<SDL_GamepadButton>(emuenv.cfg.controller_binds[SDL_GAMEPAD_BUTTON_BACK]), SCE_CTRL_SELECT },
@@ -240,6 +217,25 @@ std::array<ControllerBinding, 15> get_controller_bindings_ext(EmuEnvState &emuen
} };
}
static float axis_to_axis(int16_t axis, const auto &mult) {
const auto unsigned_axis = static_cast<float>(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<uint8_t>(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<float, 4> axes;
std::array<float, 4> axes{};
axes.fill(0);
const auto reset_axes = [&]() {
+13 -2
View File
@@ -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<int> &led) {
SDL_SetGamepadLED(ctrl.controllers[guid].controller.get(), led[0], led[1], led[2]);
+1 -1
View File
@@ -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" },