Files
pico-loader/arm9/source/patches/arm7/cheats/CheatEnginePatch.cpp

86 lines
2.7 KiB
C++

#include "common.h"
#include "thumbInstructions.h"
#include "CheatEnginePatchCode.h"
#include "CheatEnginePatch.h"
static const u32 sOSiIrqVBlankPattern0[] = { 0xE92D4008u, 0xE59F2038u, 0xE59F0038u, 0xE5921000u };
static const u32 sOSiIrqVBlankPattern1[] = { 0xE92D4000u, 0xE24DD004u, 0xE59F003Cu, 0xE5902060u };
static const u32 sOSiIrqVBlankPatternThumb0[] = { 0x4809B508u, 0x69024909u, 0x1C406808u, 0x2A006008u };
bool CheatEnginePatch::FindPatchTarget(PatchContext& patchContext)
{
_vblankIrqHandler = patchContext.FindPattern32(sOSiIrqVBlankPattern0, sizeof(sOSiIrqVBlankPattern0));
if (_vblankIrqHandler)
{
_foundPattern = sOSiIrqVBlankPattern0;
}
if (!_vblankIrqHandler)
{
_vblankIrqHandler = patchContext.FindPattern32(sOSiIrqVBlankPattern1, sizeof(sOSiIrqVBlankPattern1));
if (_vblankIrqHandler)
{
_foundPattern = sOSiIrqVBlankPattern1;
}
}
if (!_vblankIrqHandler)
{
_vblankIrqHandler = patchContext.FindPattern32(sOSiIrqVBlankPatternThumb0, sizeof(sOSiIrqVBlankPatternThumb0));
if (_vblankIrqHandler)
{
_foundPattern = sOSiIrqVBlankPatternThumb0;
_thumb = true;
}
}
if (_vblankIrqHandler)
{
LOG_DEBUG("ARM7 OSi_IrqVBlank found at 0x%p\n", _vblankIrqHandler);
}
return _vblankIrqHandler != nullptr;
}
void CheatEnginePatch::ApplyPatch(PatchContext& patchContext)
{
if (!_vblankIrqHandler || !_cheats)
return;
auto cheatEnginePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<CheatEnginePatchCode>
(
patchContext.GetPatchHeap(),
_cheats
);
int patchOffset;
if (_foundPattern == sOSiIrqVBlankPattern0)
{
patchOffset = 0x3C;
}
else if (_foundPattern == sOSiIrqVBlankPattern1)
{
patchOffset = 0x40;
}
else if (_foundPattern == sOSiIrqVBlankPatternThumb0)
{
patchOffset = 0x20;
}
else
{
LOG_ERROR("ARM7 OSi_IrqVBlank signature not implemented\n");
return;
}
if (_thumb)
{
*(u16*)((u8*)_vblankIrqHandler + patchOffset + 0) = THUMB_LDR_PC_IMM(THUMB_R1, 0); // ldr r1,= address
*(u16*)((u8*)_vblankIrqHandler + patchOffset + 2) = THUMB_BX(THUMB_R1); // bx r1
*(u32*)((u8*)_vblankIrqHandler + patchOffset + 4) = (u32)cheatEnginePatchCode->GetCheatEngineFunction(); // address
}
else
{
*(u32*)((u8*)_vblankIrqHandler + patchOffset + 0) = 0xE51FF004; // ldr pc,= address
*(u32*)((u8*)_vblankIrqHandler + patchOffset + 4) = (u32)cheatEnginePatchCode->GetCheatEngineFunctionArm(); // address
}
LOG_DEBUG("Cheats enabled\n");
}