mirror of https://github.com/PCSX2/pcsx2.git
Cleanup patch.cpp...
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3032 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
b6bc57b9e6
commit
5597a5e575
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "File_Reader.h"
|
#include "File_Reader.h"
|
||||||
#include "Patch.h"
|
|
||||||
|
|
||||||
struct key_pair {
|
struct key_pair {
|
||||||
string key;
|
string key;
|
||||||
|
@ -386,7 +385,7 @@ static void loadGameSettings(DataBase_Loader* gameDB) {
|
||||||
if (gameDB->keyExists("vuRoundMode")) { vuRM = gameDB->getInt("vuRoundMode"); rm=1; }
|
if (gameDB->keyExists("vuRoundMode")) { vuRM = gameDB->getInt("vuRoundMode"); rm=1; }
|
||||||
if (rm && eeRM<4 && vuRM<4) {
|
if (rm && eeRM<4 && vuRM<4) {
|
||||||
Console.WriteLn("Game DataBase: Changing roundmodes!");
|
Console.WriteLn("Game DataBase: Changing roundmodes!");
|
||||||
SetRoundMode((SSE_RoundMode)eeRM, (SSE_RoundMode)vuRM);
|
SetCPUState(eeMX.SetRoundMode((SSE_RoundMode)eeRM), vuMX.SetRoundMode((SSE_RoundMode)vuRM));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
582
pcsx2/Patch.cpp
582
pcsx2/Patch.cpp
|
@ -23,12 +23,10 @@
|
||||||
#include <wx/textfile.h>
|
#include <wx/textfile.h>
|
||||||
|
|
||||||
IniPatch Patch[ MAX_PATCH ];
|
IniPatch Patch[ MAX_PATCH ];
|
||||||
|
IniPatch Cheat[ MAX_CHEAT ];
|
||||||
u32 SkipCount = 0, IterationCount = 0;
|
|
||||||
u32 IterationIncrement = 0, ValueIncrement = 0;
|
|
||||||
u32 PrevCheatType = 0, PrevCheatAddr = 0,LastType = 0;
|
|
||||||
|
|
||||||
int patchnumber;
|
int patchnumber;
|
||||||
|
int cheatnumber;
|
||||||
|
|
||||||
wxString strgametitle;
|
wxString strgametitle;
|
||||||
|
|
||||||
|
@ -39,16 +37,17 @@ struct PatchTextTable
|
||||||
PATCHTABLEFUNC* func;
|
PATCHTABLEFUNC* func;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const PatchTextTable commands[] =
|
static const PatchTextTable commands_patch[] =
|
||||||
{
|
{
|
||||||
{ 1, L"comment", PatchFunc::comment },
|
{ 1, L"comment", PatchFunc::comment },
|
||||||
{ 2, L"gametitle", PatchFunc::gametitle },
|
{ 2, L"patch", PatchFunc::patch },
|
||||||
{ 3, L"patch", PatchFunc::patch },
|
{ 0, wxEmptyString, NULL } // Array Terminator
|
||||||
{ 4, L"roundmode", PatchFunc::roundmode }, // changes rounding mode for floating point
|
};
|
||||||
// syntax: roundmode=X,Y
|
|
||||||
// possible values for X,Y: NEAR, DOWN, UP, CHOP
|
static const PatchTextTable commands_cheat[] =
|
||||||
// X - EE rounding mode (default is NEAR)
|
{
|
||||||
// Y - VU rounding mode (default is CHOP)
|
{ 1, L"comment", PatchFunc::comment },
|
||||||
|
{ 2, L"patch", PatchFunc::cheat },
|
||||||
{ 0, wxEmptyString, NULL } // Array Terminator
|
{ 0, wxEmptyString, NULL } // Array Terminator
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,297 +68,6 @@ static const PatchTextTable cpuCore[] =
|
||||||
{ 0, wxEmptyString, NULL }
|
{ 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.
|
// IniFile Functions.
|
||||||
|
|
||||||
void inifile_trim( wxString& buffer )
|
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.
|
// 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 );
|
ParsedAssignmentString set( cmd );
|
||||||
|
|
||||||
|
@ -407,7 +115,7 @@ void inifile_command( const wxString& cmd )
|
||||||
// would make more sense... --air
|
// would make more sense... --air
|
||||||
if (set.rvalue.IsEmpty()) set.rvalue = set.lvalue;
|
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,
|
// This routine receives a string containing patches, trims it,
|
||||||
|
@ -419,7 +127,7 @@ void TrimPatches(string& s)
|
||||||
while (!ss.finished()) {
|
while (!ss.finished()) {
|
||||||
buff = ss.getLineWX();
|
buff = ss.getLineWX();
|
||||||
inifile_trim(buff);
|
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++)
|
for (uint i = 0; i < f1.GetLineCount(); i++)
|
||||||
{
|
{
|
||||||
inifile_trim(f1[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;
|
wxTextFile f1;
|
||||||
wxString buffer;
|
wxString buffer;
|
||||||
int cheatsNumber = patchnumber;
|
cheatnumber = 0;
|
||||||
|
|
||||||
// FIXME : We need to add a 'cheats' folder to the AppConfig, and use that instead. --air
|
// 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!");
|
Console.WriteLn( Color_Green, "Cheats found!");
|
||||||
inifile_process( f1 );
|
inifile_process( f1 );
|
||||||
|
|
||||||
cheatsNumber = patchnumber - cheatsNumber;
|
Console.WriteLn("Cheats Loaded: %d", cheatnumber);
|
||||||
Console.WriteLn("Cheats Loaded: %d", cheatsNumber);
|
return cheatnumber;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 StrToU32(const wxString& str, int base = 10)
|
static u32 StrToU32(const wxString& str, int base = 10)
|
||||||
|
@ -647,15 +225,6 @@ namespace PatchFunc
|
||||||
Console.WriteLn( L"comment: " + text2 );
|
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
|
struct PatchPieces
|
||||||
{
|
{
|
||||||
wxArrayString m_pieces;
|
wxArrayString m_pieces;
|
||||||
|
@ -674,8 +243,8 @@ namespace PatchFunc
|
||||||
const wxString& WriteValue() const { return m_pieces[4]; }
|
const wxString& WriteValue() const { return m_pieces[4]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void patch( const wxString& cmd, const wxString& param )
|
template<bool isCheat>
|
||||||
{
|
void patchHelper(const wxString& cmd, const wxString& param) {
|
||||||
// Error Handling Note: I just throw simple wxStrings here, and then catch them below and
|
// 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
|
// 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
|
// (translated) messages for display in a popup window then we'll have to upgrade the
|
||||||
|
@ -685,28 +254,32 @@ namespace PatchFunc
|
||||||
|
|
||||||
try
|
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" );
|
throw wxString( L"Maximum number of patches reached" );
|
||||||
|
|
||||||
Patch[patchnumber].enabled = 0;
|
IniPatch& iPatch = isCheat ? Cheat[cheatnumber] : Patch[patchnumber];
|
||||||
PatchPieces pieces(param);
|
PatchPieces pieces(param);
|
||||||
|
|
||||||
Patch[patchnumber].placetopatch = StrToU32(pieces.PlaceToPatch(), 10);
|
iPatch.enabled = 0;
|
||||||
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 );
|
|
||||||
|
|
||||||
if (Patch[patchnumber].cpu == 0)
|
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 (iPatch.cpu == 0)
|
||||||
throw wxsFormat(L"Unrecognized CPU Target: '%s'", pieces.CpuType().c_str());
|
throw wxsFormat(L"Unrecognized CPU Target: '%s'", pieces.CpuType().c_str());
|
||||||
|
|
||||||
if (Patch[patchnumber].type == 0)
|
if (iPatch.type == 0)
|
||||||
throw wxsFormat(L"Unrecognized Operand Size: '%s'", pieces.OperandSize().c_str());
|
throw wxsFormat(L"Unrecognized Operand Size: '%s'", pieces.OperandSize().c_str());
|
||||||
|
|
||||||
Patch[patchnumber].enabled = 1; // omg success!!
|
iPatch.enabled = 1; // omg success!!
|
||||||
|
|
||||||
//PrintPatch(patchnumber);
|
if (isCheat) cheatnumber++;
|
||||||
patchnumber++;
|
else patchnumber++;
|
||||||
}
|
}
|
||||||
catch( wxString& exmsg )
|
catch( wxString& exmsg )
|
||||||
{
|
{
|
||||||
|
@ -714,79 +287,26 @@ namespace PatchFunc
|
||||||
Console.Indent().Error( exmsg );
|
Console.Indent().Error( exmsg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 roundmode( const wxString& cmd, const wxString& param )
|
// This is for applying patches directly to memory
|
||||||
|
void ApplyPatch(int place)
|
||||||
{
|
{
|
||||||
DevCon.WriteLn(cmd + L" " + param);
|
for (int i = 0; i < patchnumber; i++)
|
||||||
|
|
||||||
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 (Patch[i].placetopatch == place)
|
||||||
|
_ApplyPatch(&Patch[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pText.Contains(L"near"))
|
// This is for applying cheats directly to memory
|
||||||
type = SSEround_Nearest;
|
void ApplyCheat(int place)
|
||||||
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");
|
for (int i = 0; i < cheatnumber; i++)
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( index == 0 )
|
|
||||||
eetype = type;
|
|
||||||
else
|
|
||||||
vutype = type;
|
|
||||||
|
|
||||||
if( index == 1 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
index++;
|
|
||||||
pText = param.AfterFirst(L',');
|
|
||||||
}
|
|
||||||
|
|
||||||
SetRoundMode(eetype,vutype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintRoundMode(SSE_RoundMode ee, SSE_RoundMode vu)
|
|
||||||
{
|
{
|
||||||
switch(ee)
|
if (Cheat[i].placetopatch == place)
|
||||||
{
|
_ApplyPatch(&Cheat[i]);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRoundMode(SSE_RoundMode ee, SSE_RoundMode vu)
|
|
||||||
{
|
|
||||||
SSE_MXCSR mxfpu = EmuConfig.Cpu.sseMXCSR;
|
|
||||||
SSE_MXCSR mxvu = EmuConfig.Cpu.sseVUMXCSR;
|
|
||||||
|
|
||||||
//PrintRoundMode(ee,vu);
|
|
||||||
SetCPUState( mxfpu.SetRoundMode( ee ), mxvu.SetRoundMode( vu ) );
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
|
|
||||||
#include "Pcsx2Defs.h"
|
#include "Pcsx2Defs.h"
|
||||||
|
|
||||||
#define MAX_PATCH 1024
|
#define MAX_PATCH 512
|
||||||
|
#define MAX_CHEAT 1024
|
||||||
|
|
||||||
enum patch_cpu_type {
|
enum patch_cpu_type {
|
||||||
NO_CPU,
|
NO_CPU,
|
||||||
|
@ -52,19 +53,19 @@ namespace PatchFunc
|
||||||
PATCHTABLEFUNC comment;
|
PATCHTABLEFUNC comment;
|
||||||
PATCHTABLEFUNC gametitle;
|
PATCHTABLEFUNC gametitle;
|
||||||
PATCHTABLEFUNC patch;
|
PATCHTABLEFUNC patch;
|
||||||
PATCHTABLEFUNC roundmode;
|
PATCHTABLEFUNC cheat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InitCheats(const wxString& name);
|
int InitCheats(const wxString& name);
|
||||||
void inifile_command(const wxString& cmd);
|
void inifile_command(bool isCheat, const wxString& cmd);
|
||||||
void inifile_trim(wxString& buffer);
|
void inifile_trim(wxString& buffer);
|
||||||
|
|
||||||
int InitPatches(const wxString& name);
|
int InitPatches(const wxString& name);
|
||||||
int AddPatch(int Mode, int Place, int Address, int Size, u64 data);
|
int AddPatch(int Mode, int Place, int Address, int Size, u64 data);
|
||||||
void ApplyPatch( int place = 1);
|
|
||||||
void ResetPatch(void);
|
void ResetPatch(void);
|
||||||
|
void ApplyPatch(int place = 1);
|
||||||
void SetRoundMode(SSE_RoundMode ee, SSE_RoundMode vu);
|
void ApplyCheat(int place = 1);
|
||||||
|
void _ApplyPatch(IniPatch *p);
|
||||||
|
|
||||||
#endif /* __PATCH_H__ */
|
#endif /* __PATCH_H__ */
|
||||||
|
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -616,6 +616,7 @@ void __fastcall eeGameStarting()
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyPatch(0);
|
ApplyPatch(0);
|
||||||
|
ApplyCheat(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __fastcall eeloadReplaceOSDSYS()
|
void __fastcall eeloadReplaceOSDSYS()
|
||||||
|
|
|
@ -199,6 +199,7 @@ void SysCoreThread::VsyncInThread()
|
||||||
{
|
{
|
||||||
PostVsyncToUI();
|
PostVsyncToUI();
|
||||||
if (EmuConfig.EnablePatches) ApplyPatch();
|
if (EmuConfig.EnablePatches) ApplyPatch();
|
||||||
|
if (EmuConfig.EnablePatches) ApplyCheat(); // ToDo: EnableCheats Option...
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysCoreThread::StateCheckInThread()
|
void SysCoreThread::StateCheckInThread()
|
||||||
|
|
|
@ -260,14 +260,6 @@
|
||||||
RelativePath="..\..\Utilities\folderdesc.txt"
|
RelativePath="..\..\Utilities\folderdesc.txt"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\Patch.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\Patch.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\PrecompiledHeader.cpp"
|
RelativePath="..\..\PrecompiledHeader.cpp"
|
||||||
>
|
>
|
||||||
|
@ -332,6 +324,26 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Patch"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\Patch.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\Patch.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\Patch_Memory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\Patch_Obsolete.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Docs"
|
Name="Docs"
|
||||||
|
|
Loading…
Reference in New Issue