mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-09-26 08:51:05 -04:00
Pads open in DIGITAL mode, not analog (spec 06) (#153)
Real PS2 pads power up in DIGITAL mode (CURID 4, mode byte 0x41) and only switch to analog (CURID 7, 0x73) when the game calls scePadSetMainMode. The three open-time sites in Pad.cpp incorrectly set analogMode=true, so scePadInfoMode(PAD_MODECURID) reported analog from frame 0. Games that gate logic on the analog transition (e.g. DQ8 fn_165b20) saw an impossible state. - PadPortState default, initializePadPortLocked, scePadPortOpen: analogMode=false - scePadSetMainMode remains the only path into analog mode (unchanged) - Updated the existing pad-info test's at-open CURID expectation (7 -> 4) - Added a regression test: open reports digital (CURID 4, 0x41), then scePadSetMainMode(mode=1) switches to analog (CURID 7, 0x73)
This commit is contained in:
committed by
GitHub
parent
d50ed4e300
commit
c4355c8cda
@@ -45,7 +45,7 @@ namespace ps2_stubs
|
||||
struct PadPortState
|
||||
{
|
||||
bool open = false;
|
||||
bool analogMode = true;
|
||||
bool analogMode = false; // real pads power up DIGITAL (CURID=4, mode 0x41)
|
||||
bool pressureEnabled = false;
|
||||
bool lastUsedOverride = false;
|
||||
bool lastUsedBackend = false;
|
||||
@@ -216,7 +216,7 @@ namespace ps2_stubs
|
||||
void initializePadPortLocked(PadPortState &portState, uint32_t dmaAddr)
|
||||
{
|
||||
portState.open = true;
|
||||
portState.analogMode = true;
|
||||
portState.analogMode = false; // real pads open DIGITAL
|
||||
portState.pressureEnabled = false;
|
||||
portState.buttonMask = 0xFFFFu;
|
||||
portState.dmaAddr = dmaAddr;
|
||||
@@ -610,7 +610,7 @@ namespace ps2_stubs
|
||||
}
|
||||
|
||||
portState->open = true;
|
||||
portState->analogMode = true;
|
||||
portState->analogMode = false; // real pads open DIGITAL
|
||||
portState->pressureEnabled = false;
|
||||
portState->buttonMask = 0xFFFFu;
|
||||
portState->dmaAddr = dmaAddr;
|
||||
|
||||
@@ -258,7 +258,7 @@ void register_pad_input_tests()
|
||||
setRegU32(ctx, 6, 1);
|
||||
setRegU32(ctx, 7, 0);
|
||||
ps2_stubs::scePadInfoMode(rdram.data(), &ctx, nullptr);
|
||||
t.Equals(static_cast<uint32_t>(getRegU32(&ctx, 2)), static_cast<uint32_t>(7), "scePadInfoMode CURID should return DualShock");
|
||||
t.Equals(static_cast<uint32_t>(getRegU32(&ctx, 2)), static_cast<uint32_t>(4), "scePadInfoMode CURID should return digital at open");
|
||||
|
||||
setRegU32(ctx, 4, 0u);
|
||||
setRegU32(ctx, 5, 0u);
|
||||
@@ -303,6 +303,57 @@ void register_pad_input_tests()
|
||||
closePadPort(ctx, rdram);
|
||||
});
|
||||
|
||||
tc.Run("pads open in digital mode and switch to analog on scePadSetMainMode", [](TestCase &t)
|
||||
{
|
||||
std::vector<uint8_t> rdram(PS2_RAM_SIZE, 0);
|
||||
R5900Context ctx;
|
||||
|
||||
ps2_stubs::scePadInit(rdram.data(), &ctx, nullptr);
|
||||
openPadPort(ctx, rdram);
|
||||
|
||||
setRegU32(ctx, 4, 0u);
|
||||
setRegU32(ctx, 5, 0u);
|
||||
ps2_stubs::scePadGetState(rdram.data(), &ctx, nullptr);
|
||||
t.Equals(static_cast<uint32_t>(getRegU32(&ctx, 2)), static_cast<uint32_t>(6), "freshly opened port should report STABLE");
|
||||
|
||||
setRegU32(ctx, 4, 0u);
|
||||
setRegU32(ctx, 5, 0u);
|
||||
setRegU32(ctx, 6, 1);
|
||||
setRegU32(ctx, 7, 0);
|
||||
ps2_stubs::scePadInfoMode(rdram.data(), &ctx, nullptr);
|
||||
t.Equals(static_cast<uint32_t>(getRegU32(&ctx, 2)), static_cast<uint32_t>(4), "scePadInfoMode CURID should return digital at open");
|
||||
|
||||
runPadRead(ctx, rdram);
|
||||
const uint8_t *data = rdram.data() + kPadDataAddr;
|
||||
t.Equals(data[1], static_cast<uint8_t>(0x41), "mode byte should be 0x41 (digital) at open");
|
||||
|
||||
setRegU32(ctx, 4, 0u);
|
||||
setRegU32(ctx, 5, 0u);
|
||||
setRegU32(ctx, 6, 1);
|
||||
setRegU32(ctx, 7, 3);
|
||||
ps2_stubs::scePadSetMainMode(rdram.data(), &ctx, nullptr);
|
||||
t.Equals(static_cast<uint32_t>(getRegU32(&ctx, 2)), static_cast<uint32_t>(1), "scePadSetMainMode should succeed switching to analog");
|
||||
|
||||
setRegU32(ctx, 4, 0u);
|
||||
setRegU32(ctx, 5, 0u);
|
||||
setRegU32(ctx, 6, 1);
|
||||
setRegU32(ctx, 7, 0);
|
||||
ps2_stubs::scePadInfoMode(rdram.data(), &ctx, nullptr);
|
||||
t.Equals(static_cast<uint32_t>(getRegU32(&ctx, 2)), static_cast<uint32_t>(7), "scePadInfoMode CURID should return analog after SetMainMode");
|
||||
|
||||
// scePadSetMainMode queues a one-shot EXECCMD transient state; pump scePadGetState
|
||||
// once so the port settles back to STABLE before reading, mirroring the existing
|
||||
// "pad command state reports EXECCMD once before returning STABLE" test.
|
||||
setRegU32(ctx, 4, 0u);
|
||||
setRegU32(ctx, 5, 0u);
|
||||
ps2_stubs::scePadGetState(rdram.data(), &ctx, nullptr);
|
||||
|
||||
runPadRead(ctx, rdram);
|
||||
t.Equals(data[1], static_cast<uint8_t>(0x73), "mode byte should be 0x73 (analog) after SetMainMode");
|
||||
|
||||
closePadPort(ctx, rdram);
|
||||
});
|
||||
|
||||
tc.Run("pad setters return success", [](TestCase &t)
|
||||
{
|
||||
std::vector<uint8_t> rdram(PS2_RAM_SIZE, 0);
|
||||
|
||||
Reference in New Issue
Block a user