From 1e3a9345f0b5c013201e5e37154a68a6a51a9f01 Mon Sep 17 00:00:00 2001 From: mariusyo07 Date: Sun, 11 Oct 2026 18:02:39 +0200 Subject: [PATCH 1/2] fix(pad): accept vibration mode 3 Broken Sword Reforged (PPSA21480) calls scePadSetVibrationMode(handle, 3) after scePadOpen and treats a failure as fatal (ps5_controls.cpp:19 "Sony call failed with code 80920001"). Modes up to 3 are accepted, 4 and above stay invalid. Co-Authored-By: xXPBSXx <20614131+xXPBSXx@users.noreply.github.com> --- core/libs/prx/libScePad/Export.cpp | 2 +- core/libs/tests/GuestPad.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/libs/prx/libScePad/Export.cpp b/core/libs/prx/libScePad/Export.cpp index 38bb59ca5..59328e95f 100644 --- a/core/libs/prx/libScePad/Export.cpp +++ b/core/libs/prx/libScePad/Export.cpp @@ -236,7 +236,7 @@ int APS5_VABI scePadSetVibration(int handle, const PadVibrationParam* param) { int APS5_VABI scePadSetVibrationMode(int handle, int mode) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; - if (mode < 0 || mode > 2) return PAD_ERROR_INVALID_ARG; + if (mode < 0 || mode > 3) return PAD_ERROR_INVALID_ARG; Pad::SetVibrationMode(mode); return PAD_OK; } diff --git a/core/libs/tests/GuestPad.cpp b/core/libs/tests/GuestPad.cpp index 992f0f7b9..70c716026 100644 --- a/core/libs/tests/GuestPad.cpp +++ b/core/libs/tests/GuestPad.cpp @@ -195,7 +195,8 @@ int main() { CheckInjectedState(path); Require(scePadSetVibrationMode(handle, 1) == 0); Require(scePadSetVibrationMode(handle, 2) == 0); - Require(scePadSetVibrationMode(handle, 3) == PAD_ERROR_INVALID_ARG); + Require(scePadSetVibrationMode(handle, 3) == 0); + Require(scePadSetVibrationMode(handle, 4) == PAD_ERROR_INVALID_ARG); Require(scePadSetVibrationMode(handle, -1) == PAD_ERROR_INVALID_ARG); Require(scePadGetHandle(0xff, 16, 0) == handle); Require(scePadGetHandle(user, 16, 0) == noHandle); From 4f013785dd7233f3f20a7cf6bba261479d8556be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Franch?= Date: Sun, 11 Oct 2026 18:06:39 +0200 Subject: [PATCH 2/2] docs(debt): record unverified scePadSetVibrationMode mode 3 Co-Authored-By: Claude --- docs/dev/TechnicalDebt.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/dev/TechnicalDebt.md b/docs/dev/TechnicalDebt.md index 0c72b62a7..f08a8f8b0 100644 --- a/docs/dev/TechnicalDebt.md +++ b/docs/dev/TechnicalDebt.md @@ -85,6 +85,7 @@ Throughout the project, every function at every stage either **does exactly what - [sceAgcDcbSetCfRegisterDirect, sceAgcDcbSetCfRegisterRangeDirect](../../core/libs/prx/libSceAgc/DcbState/src/Registers.cpp) (libSceAgc) - signatures follow [OpenAGC](https://github.com/OpenAGC/OpenAGC/blob/main/src/game_compat.c) and [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/Agc/SceAgc.cs), which agree; the SET_CONFIG_REG (0x68) packet is OpenAGC's. The driver does not execute SET_CONFIG_REG, so a submitted packet throws - [scePadOpenExt](../../core/libs/prx/libScePad/Export.cpp) (libScePad) - only special ports (type 2) are handled, and they return `DEVICE_NOT_CONNECTED` (0x80920007) because the host has no special controller; whether the console opens a handle and reports the device as disconnected later is unknown. PPSA01317 passes a 16-byte param that names the device by vendor and product id (`b7 0e 04 0e ...` for 0x0eb7:0x0e04) and skips the user on any negative result. Other port types throw - [scePadVrControllerReadState](../../core/libs/prx/libScePad/Export.cpp) (libScePad, NID `iA-DdobUen8`) - the name hashes to the imported NID; the `(int handle, void* state)` signature follows [PS5VR](https://github.com/theghostonline/PS5VR/blob/0e408909ce7a39891a2e06eee3438d07a09e11e3/app/src/app_vr.c#L326-L369) (PPSA99177), which passes a PS VR2 Sense controller handle from `scePadOpen` type 3 or 4 and a 0x68-byte state it reads as buttons at 0, stick bytes at 4 and a connected byte at 0x40. The title calls it only after `sceHmd2Initialize` succeeds, which it does not here, so every call throws; the state layout is otherwise unknown +- [scePadSetVibrationMode](../../core/libs/prx/libScePad/Export.cpp) (libScePad) - modes 0 to 3 are accepted and stored; the meaning of mode 3 is unknown (PPSA21480 calls it with 3 right after `scePadOpen` and aborts on failure; [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/Pad/Pad.cs) names only 1 and 2). The stored mode has no other effect - PPSA23566 imports declared without parameters, signatures unknown: [sceAudioOut2UserGetSupportedAttributes](../../core/libs/prx/libSceAudioOut/src/AudioOut2System.cpp), [sceConvertKeycodeGetCharacterFromKeyboardData](../../core/libs/prx/libSceConvertKeycode/Export.cpp), [sce::Json::MemAllocator::notifyError](../../core/libs/prx/libSceJson2/Export.cpp), [sceNetResolverAbort](../../core/libs/prx/libSceNet/Export.cpp), [sceNpCommerceDialogOpen2](../../core/libs/prx/libSceNpCommerce/Export.cpp), [sceNpEntitlementAccessGetPftFlag](../../core/libs/prx/libSceNpEntitlementAccess/Export.cpp), [sceProprietaryVoiceChatHelper{Initialize,Terminate,SetVoiceChatState,GetVoiceChatUsageState}](../../core/libs/prx/libSceProprietaryVoiceChatHelperPrx/Export.cpp), [sceVoice{GetResourceInfo,ResetPort,EnableChat,DisableChat}](../../core/libs/prx/libSceVoice/Export.cpp). Names from the shadPS4 aerolib NID list - PPSA28416 imports declared without parameters, signatures unknown: [sceAudioOut2EnableChat](../../core/libs/prx/libSceAudioOut/src/AudioOut2System.cpp), imported by its bundled `party-ps5-shipping.prx`. Name from the shadPS4 aerolib NID list - PPSA08427 imports declared without parameters, signatures unknown: [sceNpEntitlementAccessGetGameTrialsFlag](../../core/libs/prx/libSceNpEntitlementAccess/Export.cpp), imported by its bundled `pros.sdk.Prospero.prx` and not called before the main menu. Name from the aerolib NID list