From 0cab388f1c9b2a9c8a71d9f901af48fe4adb6ada Mon Sep 17 00:00:00 2001 From: omegadox Date: Tue, 14 Oct 2008 15:24:01 +0000 Subject: [PATCH] Fixed a bug in AR cheat system, codes starting with 0x00 to 0x07 should work now as I tested this in ZTP and SA2,and most of the codes worked. One code in SA2 breaks dolphin now, and 1 code in ZTP messed up the graphics and breaks the game if trying to load a save game, else most codes work. Also SSMB codes work for me, there are some that might break dolphin, but main codes work. I still recommend more testing of this fix. I will now work on the next fix. =). Also some code cleanup. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@864 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/PatchEngine.cpp | 309 +++++++++++++++------------ 1 file changed, 173 insertions(+), 136 deletions(-) diff --git a/Source/Core/Core/Src/PatchEngine.cpp b/Source/Core/Core/Src/PatchEngine.cpp index da5044ac0f..46d885cf22 100644 --- a/Source/Core/Core/Src/PatchEngine.cpp +++ b/Source/Core/Core/Src/PatchEngine.cpp @@ -235,7 +235,8 @@ void RunActionReplayCode(const ARCode &code, bool nowIsBootup) { for (std::vector::const_iterator iter = code.ops.begin(); iter != code.ops.end(); ++iter) { u32 cmd_addr = iter->cmd_addr; u8 cmd = iter->cmd_addr>>24; - u32 addr = (iter->cmd_addr & 0xFFFFFF); + /*u32 addr = (iter->cmd_addr & 0xFFFFFF);*/ // TODO:(Omega): remove this line if not needed anymore and everything works as is + u32 addr = (iter->cmd_addr & 0x01FFFFFF); u32 data = iter->value; if (addr >= 0x00002000 && addr < 0x00003000) { @@ -266,148 +267,184 @@ void RunActionReplayCode(const ARCode &code, bool nowIsBootup) { } // skip these weird init lines - if (iter == code.ops.begin() && cmd == 1) + if (iter == code.ops.begin() && cmd == 1) continue; + + // Ram write (and fill), this if for codes 0x00XXXXXXX - 0x07XXXXXXX + if((cmd & 0xFE) < 0x8) + { + //u32 new_addr = ((cmd_addr & 0x01FFFFFF) | 0x80000000); // TODO:(Omega): remove this line if not needed anymore and everything works as is + u32 new_addr = (addr | 0x80000000); + switch ((new_addr >> 25) & 0x03) + { + case 0x00: // Byte write + { + u8 repeat = data >> 8; + for (int i = 0; i <= repeat; i++) { + Memory::Write_U8(data & 0xFF, new_addr + i); + } + break; + } + + case 0x01: // Short write + { + u16 repeat = data >> 16; + for (int i = 0; i <= repeat; i++) { + Memory::Write_U16(data & 0xFFFF, new_addr + i * 2); + } + break; + } + + + case 0x02: // Dword write + { + Memory::Write_U32(data, new_addr); + break; + } + default: break; // TODO(Omega): maybe add a PanicAlert here? + } continue; + } - switch (cmd & 0xFE) { - case 0x00: // Byte write - { - u8 repeat = data >> 8; - for (int i = 0; i <= repeat; i++) { - Memory::Write_U8(data & 0xFF, addr + i); - } + // TODO(Omega): This commented code is here for my next fix + //case 0x40: // Write byte to pointer. + //{ + // u32 ptr = Memory::Read_U32(addr); + // u8 thebyte = data & 0xFF; + // u32 offset = data >> 8; + // Memory::Write_U8(thebyte, ptr + offset); + // break; + //} + + //case 0x42: // Write short to pointer. + //{ + // u32 ptr = Memory::Read_U32(addr); + // u16 theshort = data & 0xFFFF; + // u32 offset = (data >> 16) << 1; + // Memory::Write_U16(theshort, ptr + offset); + // break; + //} + + //case 0x44: // Write dword to pointer. + //{ + // u32 ptr = Memory::Read_U32(addr); + // Memory::Write_U32(data, ptr); + // break; + //} + + switch (cmd & 0xFE) + { + case 0x80: // Byte add + Memory::Write_U8(Memory::Read_U8(addr) + (data & 0xFF), addr); break; - } - - case 0x02: // Short write - { - u16 repeat = data >> 16; - for (int i = 0; i <= repeat; i++) { - Memory::Write_U16(data & 0xFFFF, addr + i * 2); - } + case 0x82: // Short add + Memory::Write_U16(Memory::Read_U16(addr) + (data & 0xFFFF), addr); break; - } - - case 0x04: // Dword write - Memory::Write_U32(data, addr); - break; - - case 0x80: // Byte add - Memory::Write_U8(Memory::Read_U8(addr) + (data & 0xFF), addr); - break; - case 0x82: // Short add - Memory::Write_U16(Memory::Read_U16(addr) + (data & 0xFFFF), addr); - break; - case 0x84: // DWord add - Memory::Write_U32(Memory::Read_U32(addr) + data, addr); - break; - case 0x86: // Float add (not working?) - { - union { - u32 u; - float f; - } fu, d; - fu.u = Memory::Read_U32(addr); - d.u = data; - fu.f += data; - Memory::Write_U32(fu.u, addr); - } - break; - - case 0x90: // IF 32 bit equal, exit - if (Memory::Read_U32(addr) == data) - return; - - case 0x08: // IF 8 bit equal, execute next opcode - case 0x48: // (double) - if (Memory::Read_U16(addr) != (data & 0xFFFF)) { - if (++iter == code.ops.end()) return; - if (cmd == 0x48) if (++iter == code.ops.end()) return; - } - break; - - case 0x0A: // IF 16 bit equal, execute next opcode - case 0x4A: // (double) - if (Memory::Read_U16(addr) != (data & 0xFFFF)) { - if (++iter == code.ops.end()) return; - if (cmd == 0x4A) if (++iter == code.ops.end()) return; - } - break; - - case 0x0C: // IF 32 bit equal, execute next opcode - case 0x4C: // (double) - if (Memory::Read_U32(addr) != data) { - if (++iter == code.ops.end()) return; - if (cmd == 0x4C) if (++iter == code.ops.end()) return; - } - break; - - case 0x10: // IF NOT 8 bit equal, execute next opcode - case 0x50: // (double) - if (Memory::Read_U8(addr) == (data & 0xFF)) { - if (++iter == code.ops.end()) return; - if (cmd == 0x50) if (++iter == code.ops.end()) return; - } - break; - - case 0x12: // IF NOT 16 bit equal, execute next opcode - case 0x52: // (double) - if (Memory::Read_U16(addr) == (data & 0xFFFF)) { - if (++iter == code.ops.end()) return; - if (cmd == 0x52) if (++iter == code.ops.end()) return; - } - break; - - case 0x14: // IF NOT 32 bit equal, execute next opcode - case 0x54: // (double) - if (Memory::Read_U32(addr) == data) { - if (++iter == code.ops.end()) return; - if (cmd == 0x54) if (++iter == code.ops.end()) return; - } - break; - - case 0x40: // Write byte to pointer. - { - u32 ptr = Memory::Read_U32(addr); - u8 thebyte = data & 0xFF; - u32 offset = data >> 8; - Memory::Write_U8(thebyte, ptr + offset); + case 0x84: // DWord add + Memory::Write_U32(Memory::Read_U32(addr) + data, addr); break; - } - - case 0x42: // Write short to pointer. - { - u32 ptr = Memory::Read_U32(addr); - u16 theshort = data & 0xFFFF; - u32 offset = (data >> 16) << 1; - Memory::Write_U16(theshort, ptr + offset); - break; - } - - case 0x44: // Write dword to pointer. - { - u32 ptr = Memory::Read_U32(addr); - Memory::Write_U32(data, ptr); - break; - } - - case 0xC4: - // "Master Code" - configure the AR - { - u8 number = data & 0xFF; - if (number == 0) + case 0x86: // Float add (not working?) { - // Normal master code - execute once. - } else { - // PanicAlert("Not supporting multiple master codes."); + union { + u32 u; + float f; + } fu, d; + fu.u = Memory::Read_U32(addr); + d.u = data; + fu.f += data; + Memory::Write_U32(fu.u, addr); + break; } - // u8 numOpsPerFrame = (data >> 8) & 0xFF; - // Blah, we generally ignore master codes. - } - break; - default: - PanicAlert("Unknown Action Replay command %02x (%08x %08x)", cmd, iter->cmd_addr, iter->value); - break; + case 0x90: if (Memory::Read_U32(addr) == data) return; // IF 32 bit equal, exit + case 0x08: // IF 8 bit equal, execute next opcode + case 0x48: // (double) + { + if (Memory::Read_U16(addr) != (data & 0xFFFF)) { + if (++iter == code.ops.end()) return; + if (cmd == 0x48) if (++iter == code.ops.end()) return; + } + break; + } + case 0x0A: // IF 16 bit equal, execute next opcode + case 0x4A: // (double) + { + if (Memory::Read_U16(addr) != (data & 0xFFFF)) { + if (++iter == code.ops.end()) return; + if (cmd == 0x4A) if (++iter == code.ops.end()) return; + } + break; + } + case 0x0C: // IF 32 bit equal, execute next opcode + case 0x4C: // (double) + { + if (Memory::Read_U32(addr) != data) { + if (++iter == code.ops.end()) return; + if (cmd == 0x4C) if (++iter == code.ops.end()) return; + } + break; + } + case 0x10: // IF NOT 8 bit equal, execute next opcode + case 0x50: // (double) + { + if (Memory::Read_U8(addr) == (data & 0xFF)) { + if (++iter == code.ops.end()) return; + if (cmd == 0x50) if (++iter == code.ops.end()) return; + } + break; + } + case 0x12: // IF NOT 16 bit equal, execute next opcode + case 0x52: // (double) + { + if (Memory::Read_U16(addr) == (data & 0xFFFF)) { + if (++iter == code.ops.end()) return; + if (cmd == 0x52) if (++iter == code.ops.end()) return; + } + break; + } + case 0x14: // IF NOT 32 bit equal, execute next opcode + case 0x54: // (double) + { + if (Memory::Read_U32(addr) == data) { + if (++iter == code.ops.end()) return; + if (cmd == 0x54) if (++iter == code.ops.end()) return; + } + break; + } + case 0x40: // Write byte to pointer. + { + u32 ptr = Memory::Read_U32(addr); + u8 thebyte = data & 0xFF; + u32 offset = data >> 8; + Memory::Write_U8(thebyte, ptr + offset); + break; + } + case 0x42: // Write short to pointer. + { + u32 ptr = Memory::Read_U32(addr); + u16 theshort = data & 0xFFFF; + u32 offset = (data >> 16) << 1; + Memory::Write_U16(theshort, ptr + offset); + break; + } + case 0x44: // Write dword to pointer. + { + u32 ptr = Memory::Read_U32(addr); + Memory::Write_U32(data, ptr); + break; + } + case 0xC4: // "Master Code" - configure the AR + { + u8 number = data & 0xFF; + if (number == 0) + { + // Normal master code - execute once. + } else { + // PanicAlert("Not supporting multiple master codes."); + } + // u8 numOpsPerFrame = (data >> 8) & 0xFF; + // Blah, we generally ignore master codes. + break; + } + default: PanicAlert("Unknown Action Replay command %02x (%08x %08x)", cmd, iter->cmd_addr, iter->value); break; } } }