diff --git a/core/cheats.cpp b/core/cheats.cpp index 26cb97af5..e5777c917 100644 --- a/core/cheats.cpp +++ b/core/cheats.cpp @@ -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 } diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 1820d9c37..b006a9b20 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -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 { diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index 5d89c25b7..be4c987d3 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -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