From b6176624aa2ff90c56b6ae29de541468f31e3b98 Mon Sep 17 00:00:00 2001 From: alfalfa-star Date: Tue, 6 Oct 2026 14:42:51 +0200 Subject: [PATCH] fix(pad): return INVALID_HANDLE from scePadReadState for an unknown handle PPSA14632 calls scePadReadState (eboot 0x4593a8) for the open pad and then for a second pad slot it never opened, whose handle is 0. The title skips only negative handles and ignores the result, but scePadReadState threw for any handle other than the open one. It now returns PAD_ERROR_INVALID_HANDLE (0x80920003), as the other pad functions do and as shadPS4's scePadRead does for an unknown handle; scePadRead passes it on. Co-Authored-By: Claude Opus 5.5 --- core/libs/prx/libScePad/Export.cpp | 2 +- core/libs/tests/GuestPad.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libScePad/Export.cpp b/core/libs/prx/libScePad/Export.cpp index adc42a6b7..92848cf95 100644 --- a/core/libs/prx/libScePad/Export.cpp +++ b/core/libs/prx/libScePad/Export.cpp @@ -150,7 +150,7 @@ int APS5_VABI scePadRead_nid_postfix(int handle, PadData* data, int num) { } int APS5_VABI scePadReadState(int handle, PadData* data) { - if (handle != 1) APS5_INVALID_ARG_EX; + if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (data == nullptr) APS5_INVALID_ARG_EX; *data = Pad::ReadState(); diff --git a/core/libs/tests/GuestPad.cpp b/core/libs/tests/GuestPad.cpp index 522d99171..866c44ba7 100644 --- a/core/libs/tests/GuestPad.cpp +++ b/core/libs/tests/GuestPad.cpp @@ -12,6 +12,8 @@ int APS5_VABI scePadClose_nid_postfix(int); int APS5_VABI scePadGetHandle(int, int, int); int APS5_VABI scePadSetVibrationTriggerEffectWeakWhileEmbeddedMicInUse(bool); int APS5_VABI scePadInit_nid_postfix(void); +int APS5_VABI scePadRead_nid_postfix(int, PadData*, int); +int APS5_VABI scePadReadState(int, PadData*); int APS5_VABI scePadSetTiltCorrectionState(int, bool); int APS5_VABI scePadResetOrientation(int); int APS5_VABI scePadSetAngularVelocityDeadbandState(int, bool); @@ -57,6 +59,14 @@ static void CheckTouchContact() { Pad::ReadState(); } +static void CheckReadStateHandle(int handle) { + PadData data{}; + Require(scePadReadState(0, &data) == PAD_ERROR_INVALID_HANDLE); + Require(scePadReadState(handle + 1, &data) == PAD_ERROR_INVALID_HANDLE); + Require(scePadRead_nid_postfix(0, &data, 1) == PAD_ERROR_INVALID_HANDLE); + Require(scePadReadState(handle, &data) == PAD_OK); +} + int main() { constexpr int noHandle = static_cast(0x80920008); constexpr int user = 0x10000000; @@ -71,6 +81,7 @@ int main() { Require(scePadGetHandle(user, 2, 0) == handle); CheckTiltCorrection(handle); CheckTouchContact(); + CheckReadStateHandle(handle); Require(scePadGetHandle(0xff, 16, 0) == handle); Require(scePadGetHandle(user, 16, 0) == noHandle); Require(scePadGetHandle(user, 0, 1) == noHandle);