fix(pad): keep partial L2/R2 values from a controller

An SDL controller sets the L2/R2 bit whenever its trigger axis is above
zero, and BuildData then reported 255 for any set bit, so a partly
pressed trigger read as fully pressed. Report the analog value whenever
there is one; 255 remains for an injected press and for a bit without
an analog value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Ori Shamir 2026-10-11 17:46:24 +03:00
parent a11c8f7f70
commit 3f4438dcca
2 changed files with 23 additions and 2 deletions

View File

@ -116,8 +116,11 @@ PadData BuildData(const PadInputState& state, std::uint64_t changeTime, std::uin
data.left_stick_y = state.sticks[1];
data.right_stick_x = state.sticks[2];
data.right_stick_y = state.sticks[3];
data.analog_buttons_l2 = std::max<std::uint8_t>(state.analogButtonsL2, (data.buttons & 0x100) != 0 ? 255 : 0);
data.analog_buttons_r2 = std::max<std::uint8_t>(state.analogButtonsR2, (data.buttons & 0x200) != 0 ? 255 : 0);
const auto trigger = [&](std::uint8_t analog, std::uint32_t bit) -> std::uint8_t {
return (injected & bit) != 0 || (analog == 0 && (state.buttons & bit) != 0) ? 255 : analog;
};
data.analog_buttons_l2 = trigger(state.analogButtonsL2, 0x100);
data.analog_buttons_r2 = trigger(state.analogButtonsR2, 0x200);
const bool live = state.hasMotion && output.motionEnabled;
const std::array<float, 3> rest{0.0f, 9.80665f, 0.0f};

View File

@ -101,6 +101,23 @@ static void CheckTouchContact() {
Pad::ReadState();
}
static void CheckPartialTrigger() {
PadInputState partial;
partial.buttons = static_cast<std::uint32_t>(Pad::PadButton::L2) | static_cast<std::uint32_t>(Pad::PadButton::R2);
partial.analogButtonsL2 = 1;
partial.analogButtonsR2 = 73;
PadPublishInput_nid_postfix(partial);
const auto data = Pad::ReadState();
Require(data.buttons == partial.buttons);
Require(data.analog_buttons_l2 == 1 && data.analog_buttons_r2 == 73);
PadInputState digital;
digital.buttons = static_cast<std::uint32_t>(Pad::PadButton::L2);
PadPublishInput_nid_postfix(digital);
Require(Pad::ReadState().analog_buttons_l2 == 255);
PadPublishInput_nid_postfix(PadInputState{});
Pad::ReadState();
}
static void CheckReadQueue(int handle) {
PadData drained[64]{};
scePadRead_nid_postfix(handle, drained, 64);
@ -189,6 +206,7 @@ int main() {
Require(scePadGetHandle(user, 2, 0) == handle);
CheckTiltCorrection(handle);
CheckTouchContact();
CheckPartialTrigger();
CheckReadQueue(handle);
CheckReadStateHandle(handle);
CheckRemoteController(handle);