mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-06-02 09:16:49 +02:00
86 lines
2.7 KiB
C++
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");
|
|
}
|