From 5597a5e575cca4d0957a768484345ddb01562295 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Mon, 17 May 2010 05:18:11 +0000 Subject: [PATCH] Cleanup patch.cpp... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3032 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/DataBase_Loader.h | 3 +- pcsx2/Patch.cpp | 598 ++------------------- pcsx2/Patch.h | 19 +- pcsx2/Patch_Memory.cpp | 381 +++++++++++++ pcsx2/Patch_Obsolete.h | 93 ++++ pcsx2/R5900.cpp | 1 + pcsx2/System/SysCoreThread.cpp | 1 + pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 28 +- 8 files changed, 566 insertions(+), 558 deletions(-) create mode 100644 pcsx2/Patch_Memory.cpp create mode 100644 pcsx2/Patch_Obsolete.h diff --git a/pcsx2/DataBase_Loader.h b/pcsx2/DataBase_Loader.h index e978635914..64b8ca4fc3 100644 --- a/pcsx2/DataBase_Loader.h +++ b/pcsx2/DataBase_Loader.h @@ -15,7 +15,6 @@ #pragma once #include "File_Reader.h" -#include "Patch.h" struct key_pair { string key; @@ -386,7 +385,7 @@ static void loadGameSettings(DataBase_Loader* gameDB) { if (gameDB->keyExists("vuRoundMode")) { vuRM = gameDB->getInt("vuRoundMode"); rm=1; } if (rm && eeRM<4 && vuRM<4) { Console.WriteLn("Game DataBase: Changing roundmodes!"); - SetRoundMode((SSE_RoundMode)eeRM, (SSE_RoundMode)vuRM); + SetCPUState(eeMX.SetRoundMode((SSE_RoundMode)eeRM), vuMX.SetRoundMode((SSE_RoundMode)vuRM)); } } } diff --git a/pcsx2/Patch.cpp b/pcsx2/Patch.cpp index a25f75558b..1ebcd0ec5b 100644 --- a/pcsx2/Patch.cpp +++ b/pcsx2/Patch.cpp @@ -23,12 +23,10 @@ #include IniPatch Patch[ MAX_PATCH ]; - -u32 SkipCount = 0, IterationCount = 0; -u32 IterationIncrement = 0, ValueIncrement = 0; -u32 PrevCheatType = 0, PrevCheatAddr = 0,LastType = 0; +IniPatch Cheat[ MAX_CHEAT ]; int patchnumber; +int cheatnumber; wxString strgametitle; @@ -39,17 +37,18 @@ struct PatchTextTable PATCHTABLEFUNC* func; }; -static const PatchTextTable commands[] = +static const PatchTextTable commands_patch[] = { - { 1, L"comment", PatchFunc::comment }, - { 2, L"gametitle", PatchFunc::gametitle }, - { 3, L"patch", PatchFunc::patch }, - { 4, L"roundmode", PatchFunc::roundmode }, // changes rounding mode for floating point - // syntax: roundmode=X,Y - // possible values for X,Y: NEAR, DOWN, UP, CHOP - // X - EE rounding mode (default is NEAR) - // Y - VU rounding mode (default is CHOP) - { 0, wxEmptyString, NULL } // Array Terminator + { 1, L"comment", PatchFunc::comment }, + { 2, L"patch", PatchFunc::patch }, + { 0, wxEmptyString, NULL } // Array Terminator +}; + +static const PatchTextTable commands_cheat[] = +{ + { 1, L"comment", PatchFunc::comment }, + { 2, L"patch", PatchFunc::cheat }, + { 0, wxEmptyString, NULL } // Array Terminator }; static const PatchTextTable dataType[] = @@ -69,297 +68,6 @@ static const PatchTextTable cpuCore[] = { 0, wxEmptyString, NULL } }; -void writeCheat() -{ - switch (LastType) - { - case 0x0: - memWrite8(PrevCheatAddr,IterationIncrement & 0xFF); - break; - case 0x1: - memWrite16(PrevCheatAddr,IterationIncrement & 0xFFFF); - break; - case 0x2: - memWrite32(PrevCheatAddr,IterationIncrement); - break; - default: - break; - } -} - -void handle_extended_t( IniPatch *p) -{ - if (SkipCount > 0) - { - SkipCount--; - } - else switch (PrevCheatType) - { - case 0x3040: // vvvvvvvv 00000000 Inc - { - u32 mem = memRead32(PrevCheatAddr); - memWrite32(PrevCheatAddr, mem + (p->addr)); - PrevCheatType = 0; - break; - } - - case 0x3050: // vvvvvvvv 00000000 Dec - { - u32 mem = memRead32(PrevCheatAddr); - memWrite32(PrevCheatAddr, mem - (p->addr)); - PrevCheatType = 0; - break; - } - - case 0x4000: // vvvvvvvv iiiiiiii - for(u32 i = 0; i < IterationCount; i++) - { - memWrite32((u32)(PrevCheatAddr + (i * IterationIncrement)),(u32)(p->addr + ((u32)p->data * i))); - } - PrevCheatType = 0; - break; - - case 0x5000: // dddddddd iiiiiiii - for(u32 i = 0; i < IterationCount; i++) - { - u8 mem = memRead8(PrevCheatAddr + i); - memWrite8(((u32)p->data) + i, mem); - } - PrevCheatType = 0; - break; - - case 0x6000: // 000Xnnnn iiiiiiii - if (IterationIncrement == 0x0) - { - //LastType = ((u32)p->addr & 0x000F0000) >> 16; - u32 mem = memRead32(PrevCheatAddr); - if ((u32)p->addr < 0x100) - { - LastType = 0x0; - PrevCheatAddr = mem + ((u32)p->addr); - } - else if ((u32)p->addr < 0x1000) - { - LastType = 0x1; - PrevCheatAddr = mem + ((u32)p->addr * 2); - } - else - { - LastType = 0x2; - PrevCheatAddr = mem + ((u32)p->addr * 4); - } - - // Check if needed to read another pointer - PrevCheatType = 0; - if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) - { - switch(LastType) - { - case 0x0: - memWrite8(PrevCheatAddr,(u8)p->data & 0xFF); - break; - case 0x1: - memWrite16(PrevCheatAddr,(u16)p->data & 0x0FFFF); - break; - case 0x2: - memWrite32(PrevCheatAddr,(u32)p->data); - break; - default: - break; - } - } - } - else - { - // Get Number of pointers - if (((u32)p->addr & 0x0000FFFF) == 0) - IterationCount = 1; - else - IterationCount = (u32)p->addr & 0x0000FFFF; - - // Read first pointer - LastType = ((u32)p->addr & 0x000F0000) >> 16; - u32 mem = memRead32(PrevCheatAddr); - - PrevCheatAddr = mem + (u32)p->data; - IterationCount--; - - // Check if needed to read another pointer - if (IterationCount == 0) - { - PrevCheatType = 0; - if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) writeCheat(); - } - else - { - if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) - PrevCheatType = 0; - else - PrevCheatType = 0x6001; - } - } - break; - - case 0x6001: // 000Xnnnn iiiiiiii - { - // Read first pointer - u32 mem = memRead32(PrevCheatAddr & 0x0FFFFFFF); - - PrevCheatAddr = mem + (u32)p->addr; - IterationCount--; - - // Check if needed to read another pointer - if (IterationCount == 0) - { - PrevCheatType = 0; - if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) writeCheat(); - } - else - { - mem = memRead32(PrevCheatAddr); - - PrevCheatAddr = mem + (u32)p->data; - IterationCount--; - if (IterationCount == 0) - { - PrevCheatType = 0; - if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) writeCheat(); - } - } - } - break; - - default: - if ((p->addr & 0xF0000000) == 0x00000000) // 0aaaaaaa 0000000vv - { - memWrite8(p->addr & 0x0FFFFFFF, (u8)p->data & 0x000000FF); - PrevCheatType = 0; - } - else if ((p->addr & 0xF0000000) == 0x10000000) // 0aaaaaaa 0000vvvv - { - memWrite16(p->addr & 0x0FFFFFFF, (u16)p->data & 0x0000FFFF); - PrevCheatType = 0; - } - else if ((p->addr & 0xF0000000) == 0x20000000) // 0aaaaaaa vvvvvvvv - { - memWrite32(p->addr & 0x0FFFFFFF, (u32)p->data); - PrevCheatType = 0; - } - else if ((p->addr & 0xFFFF0000) == 0x30000000) // 300000vv 0aaaaaaa Inc - { - u8 mem = memRead8((u32)p->data); - memWrite8((u32)p->data, mem + (p->addr & 0x000000FF)); - PrevCheatType = 0; - } - else if ((p->addr & 0xFFFF0000) == 0x30100000) // 301000vv 0aaaaaaa Dec - { - u8 mem = memRead8((u32)p->data); - memWrite8((u32)p->data, mem - (p->addr & 0x000000FF)); - PrevCheatType = 0; - } - else if ((p->addr & 0xFFFF0000) == 0x30200000) // 3020vvvv 0aaaaaaa Inc - { - u16 mem = memRead16((u32)p->data); - memWrite16((u32)p->data, mem + (p->addr & 0x0000FFFF)); - PrevCheatType = 0; - } - else if ((p->addr & 0xFFFF0000) == 0x30300000) // 3030vvvv 0aaaaaaa Dec - { - u16 mem = memRead16((u32)p->data); - memWrite16((u32)p->data, mem - (p->addr & 0x0000FFFF)); - PrevCheatType = 0; - } - else if ((p->addr & 0xFFFF0000) == 0x30400000) // 30400000 0aaaaaaa Inc + Another line - { - PrevCheatType = 0x3040; - PrevCheatAddr = (u32)p->data; - } - else if ((p->addr & 0xFFFF0000) == 0x30500000) // 30500000 0aaaaaaa Inc + Another line - { - PrevCheatType = 0x3050; - PrevCheatAddr = (u32)p->data; - } - else if ((p->addr & 0xF0000000) == 0x40000000) // 4aaaaaaa nnnnssss + Another line - { - IterationCount = ((u32)p->data & 0xFFFF0000) / 0x10000; - IterationIncrement = ((u32)p->data & 0x0000FFFF) * 4; - PrevCheatAddr = (u32)p->addr & 0x0FFFFFFF; - PrevCheatType = 0x4000; - } - else if ((p->addr & 0xF0000000) == 0x50000000) // 5sssssss nnnnnnnn + Another line - { - PrevCheatAddr = (u32)p->addr & 0x0FFFFFFF; - IterationCount = ((u32)p->data); - PrevCheatType = 0x5000; - } - else if ((p->addr & 0xF0000000) == 0x60000000) // 6aaaaaaa 000000vv + Another line/s - { - PrevCheatAddr = (u32)p->addr & 0x0FFFFFFF; - IterationIncrement = ((u32)p->data); - IterationCount = 0; - PrevCheatType = 0x6000; - } - else if ((p->addr & 0xF0000000) == 0x70000000) - { - if ((p->data & 0x00F00000) == 0x00000000) // 7aaaaaaa 000000vv - { - u8 mem = memRead8((u32)p->addr & 0x0FFFFFFF); - memWrite8((u32)p->addr & 0x0FFFFFFF,(u8)(mem | (p->data & 0x000000FF))); - } - else if ((p->data & 0x00F00000) == 0x00100000) // 7aaaaaaa 0010vvvv - { - u16 mem = memRead16((u32)p->addr & 0x0FFFFFFF); - memWrite16((u32)p->addr & 0x0FFFFFFF,(u16)(mem | (p->data & 0x0000FFFF))); - } - else if ((p->data & 0x00F00000) == 0x00200000) // 7aaaaaaa 002000vv - { - u8 mem = memRead8((u32)p->addr&0x0FFFFFFF); - memWrite8((u32)p->addr & 0x0FFFFFFF,(u8)(mem & (p->data & 0x000000FF))); - } - else if ((p->data & 0x00F00000) == 0x00300000) // 7aaaaaaa 0030vvvv - { - u16 mem = memRead16((u32)p->addr & 0x0FFFFFFF); - memWrite16((u32)p->addr & 0x0FFFFFFF,(u16)(mem & (p->data & 0x0000FFFF))); - } - else if ((p->data & 0x00F00000) == 0x00400000) // 7aaaaaaa 004000vv - { - u8 mem = memRead8((u32)p->addr & 0x0FFFFFFF); - memWrite8((u32)p->addr & 0x0FFFFFFF,(u8)(mem ^ (p->data & 0x000000FF))); - } - else if ((p->data & 0x00F00000) == 0x00500000) // 7aaaaaaa 0050vvvv - { - u16 mem = memRead16((u32)p->addr & 0x0FFFFFFF); - memWrite16((u32)p->addr & 0x0FFFFFFF,(u16)(mem ^ (p->data & 0x0000FFFF))); - } - } - else if (p->addr < 0xE0000000) - { - if ((((u32)p->data & 0xFFFF0000) == 0x00000000) || - (((u32)p->data & 0xFFFF0000) == 0x00100000) || - (((u32)p->data & 0xFFFF0000) == 0x00200000) || - (((u32)p->data & 0xFFFF0000) == 0x00300000)) - { - u16 mem = memRead16((u32)p->addr & 0x0FFFFFFF); - if (mem != (0x0000FFFF & (u32)p->data)) SkipCount = 1; - PrevCheatType = 0; - } - } - else if (p->addr < 0xF0000000) - { - if (((u32)p->data & 0xC0000000) == 0x00000000) - if ((((u32)p->data & 0xF0000000) == 0x00000000) || - (((u32)p->data & 0xF0000000) == 0x10000000) || - (((u32)p->data & 0xF0000000) == 0x20000000) || - (((u32)p->data & 0xF0000000) == 0x30000000)) - { - u16 mem = memRead16((u32)p->data & 0x0FFFFFFF); - if (mem != (0x0000FFFF & (u32)p->addr)) SkipCount = ((u32)p->addr & 0xFFF0000) / 0x10000; - PrevCheatType = 0; - } - } - } -} - // IniFile Functions. void inifile_trim( wxString& buffer ) @@ -399,7 +107,7 @@ static int PatchTableExecute( const ParsedAssignmentString& set, const PatchText } // This routine is for executing the commands of the ini file. -void inifile_command( const wxString& cmd ) +void inifile_command(bool isCheat, const wxString& cmd) { ParsedAssignmentString set( cmd ); @@ -407,7 +115,7 @@ void inifile_command( const wxString& cmd ) // would make more sense... --air if (set.rvalue.IsEmpty()) set.rvalue = set.lvalue; - int code = PatchTableExecute( set, commands ); + int code = PatchTableExecute(set, isCheat ? commands_cheat : commands_patch); } // This routine receives a string containing patches, trims it, @@ -419,7 +127,7 @@ void TrimPatches(string& s) while (!ss.finished()) { buff = ss.getLineWX(); inifile_trim(buff); - if (!buff.IsEmpty()) inifile_command(buff); + if (!buff.IsEmpty()) inifile_command(0, buff); } } @@ -460,7 +168,7 @@ void inifile_process(wxTextFile &f1 ) for (uint i = 0; i < f1.GetLineCount(); i++) { inifile_trim(f1[i]); - if (!f1[i].IsEmpty()) inifile_command(f1[i]); + if (!f1[i].IsEmpty()) inifile_command(1, f1[i]); } } @@ -471,7 +179,7 @@ int InitCheats(const wxString& name) { wxTextFile f1; wxString buffer; - int cheatsNumber = patchnumber; + cheatnumber = 0; // FIXME : We need to add a 'cheats' folder to the AppConfig, and use that instead. --air @@ -491,138 +199,8 @@ int InitCheats(const wxString& name) Console.WriteLn( Color_Green, "Cheats found!"); inifile_process( f1 ); - cheatsNumber = patchnumber - cheatsNumber; - Console.WriteLn("Cheats Loaded: %d", cheatsNumber); - return cheatsNumber; -} - -void _ApplyPatch(IniPatch *p) -{ - if (p->enabled == 0) return; - - switch (p->cpu) - { - case CPU_EE: - switch (p->type) - { - case BYTE_T: - if (memRead8(p->addr) != (u8)p->data) - memWrite8(p->addr, (u8)p->data); - break; - - case SHORT_T: - if (memRead16(p->addr) != (u16)p->data) - memWrite16(p->addr, (u16)p->data); - break; - - case WORD_T: - if (memRead32(p->addr) != (u32)p->data) - memWrite32(p->addr, (u32)p->data); - break; - - case DOUBLE_T: - u64 mem; - memRead64(p->addr, &mem); - if (mem != p->data) - memWrite64(p->addr, &p->data); - break; - - case EXTENDED_T: - handle_extended_t(p); - break; - - default: - break; - } - break; - - case CPU_IOP: - switch (p->type) - { - case BYTE_T: - if (iopMemRead8(p->addr) != (u8)p->data) - iopMemWrite8(p->addr, (u8)p->data); - break; - case SHORT_T: - if (iopMemRead16(p->addr) != (u16)p->data) - iopMemWrite16(p->addr, (u16)p->data); - break; - case WORD_T: - if (iopMemRead32(p->addr) != (u32)p->data) - iopMemWrite32(p->addr, (u32)p->data); - break; - default: - break; - } - break; - - default: - break; - } -} - -//this is for applying patches directly to memory -void ApplyPatch(int place) -{ - for (int i = 0; i < patchnumber; i++) - { - if (Patch[i].placetopatch == place) - _ApplyPatch(&Patch[i]); - } -} - -void ResetPatch( void ) -{ - patchnumber = 0; -} - -int AddPatch(int Mode, int Place, int Address, int Size, u64 data) -{ - if ( patchnumber >= MAX_PATCH ) - { - Console.Error( "Patch ERROR: Maximum number of patches reached."); - return -1; - } - - Patch[patchnumber].placetopatch = Mode; - Patch[patchnumber].cpu = (patch_cpu_type)Place; - Patch[patchnumber].addr = Address; - Patch[patchnumber].type = (patch_data_type)Size; - Patch[patchnumber].data = data; - return patchnumber++; -} - -void PrintPatch(int i) -{ - Console.WriteLn("Patch[%d]:", i); - if (Patch[i].enabled == 0) - Console.WriteLn("Disabled."); - else - Console.WriteLn("Enabled."); - - Console.WriteLn("PlaceToPatch:%d", Patch[i].placetopatch); - - switch(Patch[i].cpu) - { - case CPU_EE: Console.WriteLn("Cpu: EE"); break; - case CPU_IOP: Console.WriteLn("Cpu: IOP"); break; - default: Console.WriteLn("Cpu: None"); break; - } - - Console.WriteLn("Address: %X", Patch[i].addr); - - switch (Patch[i].type) - { - case BYTE_T: Console.WriteLn("Type: Byte"); break; - case SHORT_T: Console.WriteLn("Type: Short"); break; - case WORD_T: Console.WriteLn("Type: Word"); break; - case DOUBLE_T: Console.WriteLn("Type: Double"); break; - case EXTENDED_T: Console.WriteLn("Type: Extended"); break; - - default: Console.WriteLn("Type: None"); break; - } - - Console.WriteLn("Data: %I64X", Patch[i].data); + Console.WriteLn("Cheats Loaded: %d", cheatnumber); + return cheatnumber; } static u32 StrToU32(const wxString& str, int base = 10) @@ -647,15 +225,6 @@ namespace PatchFunc Console.WriteLn( L"comment: " + text2 ); } - void gametitle( const wxString& text1, const wxString& text2 ) - { - // Setting Game Title through patches is obsolete now - // Use database instead! - //Console.WriteLn( L"gametitle: " + text2 ); - //strgametitle = text2; - //Console.SetTitle( strgametitle ); - } - struct PatchPieces { wxArrayString m_pieces; @@ -674,8 +243,8 @@ namespace PatchFunc const wxString& WriteValue() const { return m_pieces[4]; } }; - void patch( const wxString& cmd, const wxString& param ) - { + template + void patchHelper(const wxString& cmd, const wxString& param) { // Error Handling Note: I just throw simple wxStrings here, and then catch them below and // format them into more detailed cmd+data+error printouts. If we want to add user-friendly // (translated) messages for display in a popup window then we'll have to upgrade the @@ -685,108 +254,59 @@ namespace PatchFunc try { - if ( patchnumber >= MAX_PATCH ) + if (isCheat && cheatnumber >= MAX_CHEAT) + throw wxString( L"Maximum number of cheats reached" ); + if(!isCheat && patchnumber >= MAX_PATCH) throw wxString( L"Maximum number of patches reached" ); - Patch[patchnumber].enabled = 0; - PatchPieces pieces( param ); + IniPatch& iPatch = isCheat ? Cheat[cheatnumber] : Patch[patchnumber]; + PatchPieces pieces(param); - Patch[patchnumber].placetopatch = StrToU32(pieces.PlaceToPatch(), 10); - Patch[patchnumber].cpu = (patch_cpu_type)PatchTableExecute( pieces.CpuType(), cpuCore ); - Patch[patchnumber].addr = StrToU32(pieces.MemAddr(), 16); - Patch[patchnumber].type = (patch_data_type)PatchTableExecute( pieces.OperandSize(), dataType ); - Patch[patchnumber].data = StrToU64( pieces.WriteValue(), 16 ); + iPatch.enabled = 0; - if (Patch[patchnumber].cpu == 0) - throw wxsFormat( L"Unrecognized CPU Target: '%s'", pieces.CpuType().c_str() ); + iPatch.placetopatch = StrToU32(pieces.PlaceToPatch(), 10); + iPatch.cpu = (patch_cpu_type)PatchTableExecute(pieces.CpuType(), cpuCore); + iPatch.addr = StrToU32(pieces.MemAddr(), 16); + iPatch.type = (patch_data_type)PatchTableExecute(pieces.OperandSize(), dataType); + iPatch.data = StrToU64(pieces.WriteValue(), 16); - if (Patch[patchnumber].type == 0) - throw wxsFormat( L"Unrecognized Operand Size: '%s'", pieces.OperandSize().c_str() ); + if (iPatch.cpu == 0) + throw wxsFormat(L"Unrecognized CPU Target: '%s'", pieces.CpuType().c_str()); - Patch[patchnumber].enabled = 1; // omg success!! + if (iPatch.type == 0) + throw wxsFormat(L"Unrecognized Operand Size: '%s'", pieces.OperandSize().c_str()); - //PrintPatch(patchnumber); - patchnumber++; + iPatch.enabled = 1; // omg success!! + + if (isCheat) cheatnumber++; + else patchnumber++; } catch( wxString& exmsg ) { - Console.Error( L"(Patch) Error Parsing: %s=%s", cmd.c_str(), param.c_str() ); + Console.Error(L"(Patch) Error Parsing: %s=%s", cmd.c_str(), param.c_str()); Console.Indent().Error( exmsg ); } - } - - void roundmode( const wxString& cmd, const wxString& param ) - { - DevCon.WriteLn(cmd + L" " + param); - - int index; - wxString pText; - - SSE_RoundMode eetype = EmuConfig.Cpu.sseMXCSR.GetRoundMode(); - SSE_RoundMode vutype = EmuConfig.Cpu.sseVUMXCSR.GetRoundMode(); - - index = 0; - pText = param.Lower().BeforeFirst(L','); - while(pText != wxEmptyString) - { - SSE_RoundMode type; - - if (pText.Contains(L"near")) - type = SSEround_Nearest; - else if (pText.Contains(L"down")) - type = SSEround_NegInf; - else if (pText.Contains(L"up")) - type = SSEround_PosInf; - else if (pText.Contains(L"chop")) - type = SSEround_Chop; - else - { - Console.WriteLn(L"bad argument (" + pText + L") to round mode! skipping...\n"); - break; - } - - if( index == 0 ) - eetype = type; - else - vutype = type; - - if( index == 1 ) - break; - - index++; - pText = param.AfterFirst(L','); - } - - SetRoundMode(eetype,vutype); - } + } + void patch(const wxString& cmd, const wxString& param) { patchHelper<0>(cmd, param); } + void cheat(const wxString& cmd, const wxString& param) { patchHelper<1>(cmd, param); } } -void PrintRoundMode(SSE_RoundMode ee, SSE_RoundMode vu) +// This is for applying patches directly to memory +void ApplyPatch(int place) { - switch(ee) - { - case SSEround_Nearest: DevCon.WriteLn("EE: Near"); break; - case SSEround_NegInf: DevCon.WriteLn("EE: Down"); break; - case SSEround_PosInf: DevCon.WriteLn("EE: Up"); break; - case SSEround_Chop: DevCon.WriteLn("EE: Chop"); break; - default: DevCon.WriteLn("EE: ?"); break; - } - - switch(vu) - { - case SSEround_Nearest: DevCon.WriteLn("VU: Near"); break; - case SSEround_NegInf: DevCon.WriteLn("VU: Down"); break; - case SSEround_PosInf: DevCon.WriteLn("VU: Up"); break; - case SSEround_Chop: DevCon.WriteLn("VU: Chop"); break; - default: DevCon.WriteLn("VU: ?"); break; - } + for (int i = 0; i < patchnumber; i++) + { + if (Patch[i].placetopatch == place) + _ApplyPatch(&Patch[i]); + } } -void SetRoundMode(SSE_RoundMode ee, SSE_RoundMode vu) +// This is for applying cheats directly to memory +void ApplyCheat(int place) { - SSE_MXCSR mxfpu = EmuConfig.Cpu.sseMXCSR; - SSE_MXCSR mxvu = EmuConfig.Cpu.sseVUMXCSR; - - //PrintRoundMode(ee,vu); - SetCPUState( mxfpu.SetRoundMode( ee ), mxvu.SetRoundMode( vu ) ); + for (int i = 0; i < cheatnumber; i++) + { + if (Cheat[i].placetopatch == place) + _ApplyPatch(&Cheat[i]); + } } diff --git a/pcsx2/Patch.h b/pcsx2/Patch.h index 422b67fa1e..c75a368fe2 100644 --- a/pcsx2/Patch.h +++ b/pcsx2/Patch.h @@ -17,7 +17,8 @@ #include "Pcsx2Defs.h" -#define MAX_PATCH 1024 +#define MAX_PATCH 512 +#define MAX_CHEAT 1024 enum patch_cpu_type { NO_CPU, @@ -50,21 +51,21 @@ struct IniPatch namespace PatchFunc { PATCHTABLEFUNC comment; - PATCHTABLEFUNC gametitle; - PATCHTABLEFUNC patch; - PATCHTABLEFUNC roundmode; + PATCHTABLEFUNC gametitle; + PATCHTABLEFUNC patch; + PATCHTABLEFUNC cheat; } int InitCheats(const wxString& name); -void inifile_command(const wxString& cmd); +void inifile_command(bool isCheat, const wxString& cmd); void inifile_trim(wxString& buffer); int InitPatches(const wxString& name); int AddPatch(int Mode, int Place, int Address, int Size, u64 data); -void ApplyPatch( int place = 1); -void ResetPatch( void ); - -void SetRoundMode(SSE_RoundMode ee, SSE_RoundMode vu); +void ResetPatch(void); +void ApplyPatch(int place = 1); +void ApplyCheat(int place = 1); +void _ApplyPatch(IniPatch *p); #endif /* __PATCH_H__ */ diff --git a/pcsx2/Patch_Memory.cpp b/pcsx2/Patch_Memory.cpp new file mode 100644 index 0000000000..1eafa2f064 --- /dev/null +++ b/pcsx2/Patch_Memory.cpp @@ -0,0 +1,381 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" + +#define _PC_ // disables MIPS opcode macros. + +#include "IopCommon.h" +#include "Patch.h" + +u32 SkipCount = 0, IterationCount = 0; +u32 IterationIncrement = 0, ValueIncrement = 0; +u32 PrevCheatType = 0, PrevCheatAddr = 0,LastType = 0; + +void writeCheat() +{ + switch (LastType) + { + case 0x0: + memWrite8(PrevCheatAddr,IterationIncrement & 0xFF); + break; + case 0x1: + memWrite16(PrevCheatAddr,IterationIncrement & 0xFFFF); + break; + case 0x2: + memWrite32(PrevCheatAddr,IterationIncrement); + break; + default: + break; + } +} + +void handle_extended_t( IniPatch *p) +{ + if (SkipCount > 0) + { + SkipCount--; + } + else switch (PrevCheatType) + { + case 0x3040: // vvvvvvvv 00000000 Inc + { + u32 mem = memRead32(PrevCheatAddr); + memWrite32(PrevCheatAddr, mem + (p->addr)); + PrevCheatType = 0; + break; + } + + case 0x3050: // vvvvvvvv 00000000 Dec + { + u32 mem = memRead32(PrevCheatAddr); + memWrite32(PrevCheatAddr, mem - (p->addr)); + PrevCheatType = 0; + break; + } + + case 0x4000: // vvvvvvvv iiiiiiii + for(u32 i = 0; i < IterationCount; i++) + { + memWrite32((u32)(PrevCheatAddr + (i * IterationIncrement)),(u32)(p->addr + ((u32)p->data * i))); + } + PrevCheatType = 0; + break; + + case 0x5000: // dddddddd iiiiiiii + for(u32 i = 0; i < IterationCount; i++) + { + u8 mem = memRead8(PrevCheatAddr + i); + memWrite8(((u32)p->data) + i, mem); + } + PrevCheatType = 0; + break; + + case 0x6000: // 000Xnnnn iiiiiiii + if (IterationIncrement == 0x0) + { + //LastType = ((u32)p->addr & 0x000F0000) >> 16; + u32 mem = memRead32(PrevCheatAddr); + if ((u32)p->addr < 0x100) + { + LastType = 0x0; + PrevCheatAddr = mem + ((u32)p->addr); + } + else if ((u32)p->addr < 0x1000) + { + LastType = 0x1; + PrevCheatAddr = mem + ((u32)p->addr * 2); + } + else + { + LastType = 0x2; + PrevCheatAddr = mem + ((u32)p->addr * 4); + } + + // Check if needed to read another pointer + PrevCheatType = 0; + if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) + { + switch(LastType) + { + case 0x0: + memWrite8(PrevCheatAddr,(u8)p->data & 0xFF); + break; + case 0x1: + memWrite16(PrevCheatAddr,(u16)p->data & 0x0FFFF); + break; + case 0x2: + memWrite32(PrevCheatAddr,(u32)p->data); + break; + default: + break; + } + } + } + else + { + // Get Number of pointers + if (((u32)p->addr & 0x0000FFFF) == 0) + IterationCount = 1; + else + IterationCount = (u32)p->addr & 0x0000FFFF; + + // Read first pointer + LastType = ((u32)p->addr & 0x000F0000) >> 16; + u32 mem = memRead32(PrevCheatAddr); + + PrevCheatAddr = mem + (u32)p->data; + IterationCount--; + + // Check if needed to read another pointer + if (IterationCount == 0) + { + PrevCheatType = 0; + if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) writeCheat(); + } + else + { + if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) + PrevCheatType = 0; + else + PrevCheatType = 0x6001; + } + } + break; + + case 0x6001: // 000Xnnnn iiiiiiii + { + // Read first pointer + u32 mem = memRead32(PrevCheatAddr & 0x0FFFFFFF); + + PrevCheatAddr = mem + (u32)p->addr; + IterationCount--; + + // Check if needed to read another pointer + if (IterationCount == 0) + { + PrevCheatType = 0; + if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) writeCheat(); + } + else + { + mem = memRead32(PrevCheatAddr); + + PrevCheatAddr = mem + (u32)p->data; + IterationCount--; + if (IterationCount == 0) + { + PrevCheatType = 0; + if (((mem & 0x0FFFFFFF) & 0x3FFFFFFC) != 0) writeCheat(); + } + } + } + break; + + default: + if ((p->addr & 0xF0000000) == 0x00000000) // 0aaaaaaa 0000000vv + { + memWrite8(p->addr & 0x0FFFFFFF, (u8)p->data & 0x000000FF); + PrevCheatType = 0; + } + else if ((p->addr & 0xF0000000) == 0x10000000) // 0aaaaaaa 0000vvvv + { + memWrite16(p->addr & 0x0FFFFFFF, (u16)p->data & 0x0000FFFF); + PrevCheatType = 0; + } + else if ((p->addr & 0xF0000000) == 0x20000000) // 0aaaaaaa vvvvvvvv + { + memWrite32(p->addr & 0x0FFFFFFF, (u32)p->data); + PrevCheatType = 0; + } + else if ((p->addr & 0xFFFF0000) == 0x30000000) // 300000vv 0aaaaaaa Inc + { + u8 mem = memRead8((u32)p->data); + memWrite8((u32)p->data, mem + (p->addr & 0x000000FF)); + PrevCheatType = 0; + } + else if ((p->addr & 0xFFFF0000) == 0x30100000) // 301000vv 0aaaaaaa Dec + { + u8 mem = memRead8((u32)p->data); + memWrite8((u32)p->data, mem - (p->addr & 0x000000FF)); + PrevCheatType = 0; + } + else if ((p->addr & 0xFFFF0000) == 0x30200000) // 3020vvvv 0aaaaaaa Inc + { + u16 mem = memRead16((u32)p->data); + memWrite16((u32)p->data, mem + (p->addr & 0x0000FFFF)); + PrevCheatType = 0; + } + else if ((p->addr & 0xFFFF0000) == 0x30300000) // 3030vvvv 0aaaaaaa Dec + { + u16 mem = memRead16((u32)p->data); + memWrite16((u32)p->data, mem - (p->addr & 0x0000FFFF)); + PrevCheatType = 0; + } + else if ((p->addr & 0xFFFF0000) == 0x30400000) // 30400000 0aaaaaaa Inc + Another line + { + PrevCheatType = 0x3040; + PrevCheatAddr = (u32)p->data; + } + else if ((p->addr & 0xFFFF0000) == 0x30500000) // 30500000 0aaaaaaa Inc + Another line + { + PrevCheatType = 0x3050; + PrevCheatAddr = (u32)p->data; + } + else if ((p->addr & 0xF0000000) == 0x40000000) // 4aaaaaaa nnnnssss + Another line + { + IterationCount = ((u32)p->data & 0xFFFF0000) / 0x10000; + IterationIncrement = ((u32)p->data & 0x0000FFFF) * 4; + PrevCheatAddr = (u32)p->addr & 0x0FFFFFFF; + PrevCheatType = 0x4000; + } + else if ((p->addr & 0xF0000000) == 0x50000000) // 5sssssss nnnnnnnn + Another line + { + PrevCheatAddr = (u32)p->addr & 0x0FFFFFFF; + IterationCount = ((u32)p->data); + PrevCheatType = 0x5000; + } + else if ((p->addr & 0xF0000000) == 0x60000000) // 6aaaaaaa 000000vv + Another line/s + { + PrevCheatAddr = (u32)p->addr & 0x0FFFFFFF; + IterationIncrement = ((u32)p->data); + IterationCount = 0; + PrevCheatType = 0x6000; + } + else if ((p->addr & 0xF0000000) == 0x70000000) + { + if ((p->data & 0x00F00000) == 0x00000000) // 7aaaaaaa 000000vv + { + u8 mem = memRead8((u32)p->addr & 0x0FFFFFFF); + memWrite8((u32)p->addr & 0x0FFFFFFF,(u8)(mem | (p->data & 0x000000FF))); + } + else if ((p->data & 0x00F00000) == 0x00100000) // 7aaaaaaa 0010vvvv + { + u16 mem = memRead16((u32)p->addr & 0x0FFFFFFF); + memWrite16((u32)p->addr & 0x0FFFFFFF,(u16)(mem | (p->data & 0x0000FFFF))); + } + else if ((p->data & 0x00F00000) == 0x00200000) // 7aaaaaaa 002000vv + { + u8 mem = memRead8((u32)p->addr&0x0FFFFFFF); + memWrite8((u32)p->addr & 0x0FFFFFFF,(u8)(mem & (p->data & 0x000000FF))); + } + else if ((p->data & 0x00F00000) == 0x00300000) // 7aaaaaaa 0030vvvv + { + u16 mem = memRead16((u32)p->addr & 0x0FFFFFFF); + memWrite16((u32)p->addr & 0x0FFFFFFF,(u16)(mem & (p->data & 0x0000FFFF))); + } + else if ((p->data & 0x00F00000) == 0x00400000) // 7aaaaaaa 004000vv + { + u8 mem = memRead8((u32)p->addr & 0x0FFFFFFF); + memWrite8((u32)p->addr & 0x0FFFFFFF,(u8)(mem ^ (p->data & 0x000000FF))); + } + else if ((p->data & 0x00F00000) == 0x00500000) // 7aaaaaaa 0050vvvv + { + u16 mem = memRead16((u32)p->addr & 0x0FFFFFFF); + memWrite16((u32)p->addr & 0x0FFFFFFF,(u16)(mem ^ (p->data & 0x0000FFFF))); + } + } + else if (p->addr < 0xE0000000) + { + if ((((u32)p->data & 0xFFFF0000) == 0x00000000) || + (((u32)p->data & 0xFFFF0000) == 0x00100000) || + (((u32)p->data & 0xFFFF0000) == 0x00200000) || + (((u32)p->data & 0xFFFF0000) == 0x00300000)) + { + u16 mem = memRead16((u32)p->addr & 0x0FFFFFFF); + if (mem != (0x0000FFFF & (u32)p->data)) SkipCount = 1; + PrevCheatType = 0; + } + } + else if (p->addr < 0xF0000000) + { + if (((u32)p->data & 0xC0000000) == 0x00000000) + if ((((u32)p->data & 0xF0000000) == 0x00000000) || + (((u32)p->data & 0xF0000000) == 0x10000000) || + (((u32)p->data & 0xF0000000) == 0x20000000) || + (((u32)p->data & 0xF0000000) == 0x30000000)) + { + u16 mem = memRead16((u32)p->data & 0x0FFFFFFF); + if (mem != (0x0000FFFF & (u32)p->addr)) SkipCount = ((u32)p->addr & 0xFFF0000) / 0x10000; + PrevCheatType = 0; + } + } + } +} + +void _ApplyPatch(IniPatch *p) +{ + if (p->enabled == 0) return; + + switch (p->cpu) + { + case CPU_EE: + switch (p->type) + { + case BYTE_T: + if (memRead8(p->addr) != (u8)p->data) + memWrite8(p->addr, (u8)p->data); + break; + + case SHORT_T: + if (memRead16(p->addr) != (u16)p->data) + memWrite16(p->addr, (u16)p->data); + break; + + case WORD_T: + if (memRead32(p->addr) != (u32)p->data) + memWrite32(p->addr, (u32)p->data); + break; + + case DOUBLE_T: + u64 mem; + memRead64(p->addr, &mem); + if (mem != p->data) + memWrite64(p->addr, &p->data); + break; + + case EXTENDED_T: + handle_extended_t(p); + break; + + default: + break; + } + break; + + case CPU_IOP: + switch (p->type) + { + case BYTE_T: + if (iopMemRead8(p->addr) != (u8)p->data) + iopMemWrite8(p->addr, (u8)p->data); + break; + case SHORT_T: + if (iopMemRead16(p->addr) != (u16)p->data) + iopMemWrite16(p->addr, (u16)p->data); + break; + case WORD_T: + if (iopMemRead32(p->addr) != (u32)p->data) + iopMemWrite32(p->addr, (u32)p->data); + break; + default: + break; + } + break; + + default: + break; + } +} diff --git a/pcsx2/Patch_Obsolete.h b/pcsx2/Patch_Obsolete.h new file mode 100644 index 0000000000..916640a5ca --- /dev/null +++ b/pcsx2/Patch_Obsolete.h @@ -0,0 +1,93 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +// Old Patching functions that are currently not used +// so out-sourced them to this header file that isn't referenced... + +// Obsolete code used by old cheats-gui code... +int AddPatch(int Mode, int Place, int Address, int Size, u64 data) +{ + if ( patchnumber >= MAX_PATCH ) + { + Console.Error( "Patch ERROR: Maximum number of patches reached."); + return -1; + } + + Patch[patchnumber].placetopatch = Mode; + Patch[patchnumber].cpu = (patch_cpu_type)Place; + Patch[patchnumber].addr = Address; + Patch[patchnumber].type = (patch_data_type)Size; + Patch[patchnumber].data = data; + return patchnumber++; +} + +void PrintPatch(int i) +{ + Console.WriteLn("Patch[%d]:", i); + if (Patch[i].enabled == 0) + Console.WriteLn("Disabled."); + else + Console.WriteLn("Enabled."); + + Console.WriteLn("PlaceToPatch:%d", Patch[i].placetopatch); + + switch(Patch[i].cpu) + { + case CPU_EE: Console.WriteLn("Cpu: EE"); break; + case CPU_IOP: Console.WriteLn("Cpu: IOP"); break; + default: Console.WriteLn("Cpu: None"); break; + } + + Console.WriteLn("Address: %X", Patch[i].addr); + + switch (Patch[i].type) + { + case BYTE_T: Console.WriteLn("Type: Byte"); break; + case SHORT_T: Console.WriteLn("Type: Short"); break; + case WORD_T: Console.WriteLn("Type: Word"); break; + case DOUBLE_T: Console.WriteLn("Type: Double"); break; + case EXTENDED_T: Console.WriteLn("Type: Extended"); break; + + default: Console.WriteLn("Type: None"); break; + } + + Console.WriteLn("Data: %I64X", Patch[i].data); +} + +void ResetPatch( void ) +{ + patchnumber = 0; +} + +void PrintRoundMode(SSE_RoundMode ee, SSE_RoundMode vu) +{ + switch(ee) + { + case SSEround_Nearest: DevCon.WriteLn("EE: Near"); break; + case SSEround_NegInf: DevCon.WriteLn("EE: Down"); break; + case SSEround_PosInf: DevCon.WriteLn("EE: Up"); break; + case SSEround_Chop: DevCon.WriteLn("EE: Chop"); break; + default: DevCon.WriteLn("EE: ?"); break; + } + + switch(vu) + { + case SSEround_Nearest: DevCon.WriteLn("VU: Near"); break; + case SSEround_NegInf: DevCon.WriteLn("VU: Down"); break; + case SSEround_PosInf: DevCon.WriteLn("VU: Up"); break; + case SSEround_Chop: DevCon.WriteLn("VU: Chop"); break; + default: DevCon.WriteLn("VU: ?"); break; + } +} diff --git a/pcsx2/R5900.cpp b/pcsx2/R5900.cpp index 52ce32ee90..9679d2fde7 100644 --- a/pcsx2/R5900.cpp +++ b/pcsx2/R5900.cpp @@ -616,6 +616,7 @@ void __fastcall eeGameStarting() } ApplyPatch(0); + ApplyCheat(0); } void __fastcall eeloadReplaceOSDSYS() diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp index 63259ab691..c9a00d2ddb 100644 --- a/pcsx2/System/SysCoreThread.cpp +++ b/pcsx2/System/SysCoreThread.cpp @@ -199,6 +199,7 @@ void SysCoreThread::VsyncInThread() { PostVsyncToUI(); if (EmuConfig.EnablePatches) ApplyPatch(); + if (EmuConfig.EnablePatches) ApplyCheat(); // ToDo: EnableCheats Option... } void SysCoreThread::StateCheckInThread() diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index 48ea47bc81..01eda5e273 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -260,14 +260,6 @@ RelativePath="..\..\Utilities\folderdesc.txt" > - - - - @@ -332,6 +324,26 @@ > + + + + + + + + + +