naomi: full rfid chip emulation for mushiking series
Fixes hang after playing 3 games. Issue #1626
This commit is contained in:
parent
f039a809da
commit
7174ef1194
|
@ -454,33 +454,6 @@ void CheatManager::reset(const std::string& gameId)
|
|||
else if (gameId == "THE KING OF ROUTE66") {
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore drive error", true, 32, 0x00023ee0, 0x0009000B, true); // rts, nop
|
||||
}
|
||||
else if (gameId.substr(0, 8) == "MKG TKOB")
|
||||
{
|
||||
const auto& setMushikingCheats = [this](u32 addr) {
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid1 error", true, 32, addr, 0, true); // rfid[0].error = 0
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid2 error", true, 32, addr + 0x48, 0, true); // rfid[1].error = 0
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid1 status", true, 32, addr + 8, 0, true); // rfid[0].data18 = 0
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid2 status", true, 32, addr + 0x50, 0, true); // rfid[1].data18 = 0
|
||||
};
|
||||
if (gameId == "MKG TKOB 2 EXP VER1.001-") // mushi2eo
|
||||
setMushikingCheats(0x6fe1bc);
|
||||
else if (gameId == "MKG TKOB 2 JPN VER2.001-") // mushik2e
|
||||
setMushikingCheats(0x6ffe54);
|
||||
else if (gameId == "MKG TKOB 2K3 2ND VER1.003-")// mushike
|
||||
setMushikingCheats(0x4ad7ec);
|
||||
else if (gameId == "MKG TKOB 4 JPN VER2.000-") // mushik4e
|
||||
setMushikingCheats(0xb0e538);
|
||||
else if (gameId == "MKG TKOB 4 TWN VER1.000-") // mushik4t
|
||||
setMushikingCheats(0xb198f0);
|
||||
else if (gameId == "MKG TKOB 2K3 2ND VER1.002-")// mushikeo
|
||||
setMushikingCheats(0x4ad56c);
|
||||
else if (gameId == "MKG TKOB 2K3 2ND KOR VER1.000-") // mushikk
|
||||
setMushikingCheats(0x4ac9b8);
|
||||
else if (gameId == "MKG TKOB 2K3 2ND CHN VER1.000-") // mushikc
|
||||
setMushikingCheats(0x4aa9b8);
|
||||
else if (gameId == "MKG TKOB 2 KOR VER1.000-") // mushik2k
|
||||
setMushikingCheats(0x706084);
|
||||
}
|
||||
else if (gameId == "T-8120N") { // Dave Mirra BMX (US)
|
||||
cheats.emplace_back(Cheat::Type::setValue, "fix main loop time", true, 32, 0x0030b8cc, 0x42040000, true); // 33.0 ms
|
||||
}
|
||||
|
|
|
@ -241,6 +241,10 @@ static void createNaomiDevices()
|
|||
{
|
||||
mcfg_Create(MDT_RFIDReaderWriter, 1, 5, 0);
|
||||
mcfg_Create(MDT_RFIDReaderWriter, 2, 5, 1);
|
||||
if (gameId.substr(0, 8) == "MKG TKOB") {
|
||||
insertRfidCard(0);
|
||||
insertRfidCard(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1729,21 +1729,22 @@ struct RFIDReaderWriter : maple_base
|
|||
DEBUG_LOG(MAPLE, "RFID card read (data? %d)", d4Seen);
|
||||
w32(getStatus());
|
||||
if (!d4Seen)
|
||||
w32(0x12345678); // arbitrary value (unknown)
|
||||
// serial0 and serial1 only
|
||||
wptr(cardData, 8);
|
||||
else
|
||||
wptr(cardData, sizeof(cardData));
|
||||
return (MapleDeviceRV)0xfe;
|
||||
|
||||
case 0xD9: // lock card
|
||||
w32(getStatus());
|
||||
cardLocked = true;
|
||||
w32(getStatus());
|
||||
INFO_LOG(MAPLE, "RFID card %d locked", player_num);
|
||||
return (MapleDeviceRV)0xfe;
|
||||
|
||||
case 0xDA: // unlock card
|
||||
w32(getStatus());
|
||||
cardLocked = false;
|
||||
cardInserted = false;
|
||||
w32(getStatus());
|
||||
NOTICE_LOG(MAPLE, "RFID card %d unlocked", player_num);
|
||||
os_notify("Card ejected", 2000);
|
||||
return (MapleDeviceRV)0xfe;
|
||||
|
@ -1760,6 +1761,33 @@ struct RFIDReaderWriter : maple_base
|
|||
return (MapleDeviceRV)0xfe;
|
||||
}
|
||||
|
||||
case 0xD1: // decrement counter
|
||||
{
|
||||
int counter = r8();
|
||||
switch (counter) {
|
||||
case 0x03:
|
||||
counter = 0;
|
||||
break;
|
||||
case 0x0c:
|
||||
counter = 1;
|
||||
break;
|
||||
case 0x30:
|
||||
counter = 2;
|
||||
break;
|
||||
case 0xc0:
|
||||
counter = 3;
|
||||
break;
|
||||
default:
|
||||
WARN_LOG(MAPLE, "Unknown counter selector %x", counter);
|
||||
counter = 0;
|
||||
break;
|
||||
}
|
||||
DEBUG_LOG(MAPLE, "RFID decrement %d", counter);
|
||||
cardData[19 - counter]--;
|
||||
w32(getStatus());
|
||||
return (MapleDeviceRV)0xfe;
|
||||
}
|
||||
|
||||
default:
|
||||
INFO_LOG(MAPLE, "RFIDReaderWriter: unknown MAPLE COMMAND %d", cmd);
|
||||
return MDRE_UnknownCmd;
|
||||
|
@ -1795,24 +1823,62 @@ struct RFIDReaderWriter : maple_base
|
|||
FILE *fp = nowide::fopen(path.c_str(), "rb");
|
||||
if (fp == nullptr)
|
||||
{
|
||||
static u8 blankCard[128] = {
|
||||
0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,0x6c, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xff
|
||||
};
|
||||
// Generate random bytes used by vf4 vanilla to make the card id
|
||||
srand(time(0));
|
||||
blankCard[2] = rand() & 0xff;
|
||||
blankCard[4] = rand() & 0xff;
|
||||
blankCard[5] = rand() & 0xff;
|
||||
blankCard[6] = rand() & 0xff;
|
||||
blankCard[7] = rand() & 0xff;
|
||||
memcpy(cardData, blankCard, sizeof(blankCard));
|
||||
if (settings.content.gameId.substr(0, 8) == "MKG TKOB")
|
||||
{
|
||||
constexpr u8 MUSHIKING_CHIP_DATA[128] = {
|
||||
0x12, 0x34, 0x56, 0x78, // Serial No.0
|
||||
0x31, 0x00, 0x86, 0x07, // Serial No.1
|
||||
0x00, 0x00, 0x00, 0x00, // Key
|
||||
0x04, 0xf6, 0x00, 0xAA, // Extend Extend Access Mode
|
||||
0x23, 0xFF, 0xFF, 0xFF, // Counter4 Counter3 Counter2 Counter1
|
||||
0x00, 0x00, 0x00, 0x00, // User Data (first set date: day bits 0-4, month bits 5-8, year bits 9-... + 2000)
|
||||
0x00, 0x00, 0x00, 0x00, // User Data
|
||||
0x00, 0x00, 0x00, 0x00, // User Data
|
||||
0x00, 0x00, 0x00, 0x00, // User Data
|
||||
0x00, 0x00, 0x00, 0x00, // User Data
|
||||
0x00, 0x00, 0x00, 0x00, // User Data
|
||||
0x23, 0xFF, 0xFF, 0xFF, // User Data (max counters)
|
||||
};
|
||||
memcpy(cardData, MUSHIKING_CHIP_DATA, sizeof(MUSHIKING_CHIP_DATA));
|
||||
for (int i = 0; i < 8; i++)
|
||||
cardData[i] = rand() & 0xff;
|
||||
u32 mask = 0;
|
||||
if (settings.content.gameId == "MKG TKOB 2 JPN VER2.001-" // mushik2e
|
||||
|| settings.content.gameId == "MKG TKOB 4 JPN VER2.000-") // mushik4e
|
||||
mask = 0x40;
|
||||
cardData[4] &= ~0xc0;
|
||||
cardData[4] |= mask;
|
||||
|
||||
u32 serial1 = (cardData[4] << 24) | (cardData[5] << 16) | (cardData[6] << 8) | cardData[7];
|
||||
u32 key = ~serial1;
|
||||
key = ((key >> 4) & 0x0f0f0f0f)
|
||||
| ((key << 4) & 0xf0f0f0f0);
|
||||
cardData[8] = key >> 24;
|
||||
cardData[9] = key >> 16;
|
||||
cardData[10] = key >> 8;
|
||||
cardData[11] = key;
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr u8 VF4_CARD_DATA[128] = {
|
||||
0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,0x6c, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xff
|
||||
};
|
||||
memcpy(cardData, VF4_CARD_DATA, sizeof(VF4_CARD_DATA));
|
||||
// Generate random bytes used by vf4 vanilla to make the card id
|
||||
srand(time(0));
|
||||
cardData[2] = rand() & 0xff;
|
||||
cardData[4] = rand() & 0xff;
|
||||
cardData[5] = rand() & 0xff;
|
||||
cardData[6] = rand() & 0xff;
|
||||
cardData[7] = rand() & 0xff;
|
||||
}
|
||||
INFO_LOG(NAOMI, "Card P%d initialized", player_num + 1);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue