You've already forked pico-loader
mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-01-09 16:28:35 -08:00
Merge pull request #27 from taxicat1/generalize-pokemon-ir-patch
Generalize Pokemon IR sensor AP patching
This commit is contained in:
@@ -14,8 +14,7 @@
|
||||
#include "patches/arm9/PokemonDownloaderArm9Patch.h"
|
||||
#include "patches/arm9/OverlayPatches/FsStartOverlayHookPatch.h"
|
||||
#include "patches/arm9/OverlayPatches/DSProtectPatches/DSProtectOverlayPatch.h"
|
||||
#include "patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatch.h"
|
||||
#include "patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatch.h"
|
||||
#include "patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatch.h"
|
||||
#include "patches/arm9/OverlayPatches/GoldenSunDarkDawn/GoldenSunDarkDawnOverlayHookPatch.h"
|
||||
#include "SecureSysCallsUnusedSpaceLocator.h"
|
||||
#include "fastSearch.h"
|
||||
@@ -234,6 +233,25 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
||||
}
|
||||
switch (romHeader->gameCode)
|
||||
{
|
||||
// Pokemon HeartGold & SoulSilver
|
||||
case GAMECODE("IPGD"):
|
||||
case GAMECODE("IPGE"):
|
||||
case GAMECODE("IPGF"):
|
||||
case GAMECODE("IPGI"):
|
||||
case GAMECODE("IPGJ"):
|
||||
case GAMECODE("IPGK"):
|
||||
case GAMECODE("IPGS"):
|
||||
case GAMECODE("IPKD"):
|
||||
case GAMECODE("IPKE"):
|
||||
case GAMECODE("IPKF"):
|
||||
case GAMECODE("IPKI"):
|
||||
case GAMECODE("IPKJ"):
|
||||
case GAMECODE("IPKK"):
|
||||
case GAMECODE("IPKS"):
|
||||
{
|
||||
overlayHookPatch->AddOverlayPatch(new PokemonIrApPatch(PokemonIrVersion::Hgss));
|
||||
break;
|
||||
}
|
||||
// Pokemon Black & White
|
||||
case GAMECODE("IRAD"):
|
||||
case GAMECODE("IRAF"):
|
||||
@@ -250,25 +268,26 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
||||
case GAMECODE("IRBO"):
|
||||
case GAMECODE("IRBS"):
|
||||
{
|
||||
overlayHookPatch->AddOverlayPatch(new PokemonBw1IrApPatch());
|
||||
overlayHookPatch->AddOverlayPatch(new PokemonIrApPatch(PokemonIrVersion::Bw1));
|
||||
break;
|
||||
}
|
||||
// Pokemon Black & White 2
|
||||
// todo: IRDJ and IREJ have two revisions and the first one seems to be different
|
||||
case GAMECODE("IRDD"):
|
||||
case GAMECODE("IRDF"):
|
||||
case GAMECODE("IRDI"):
|
||||
case GAMECODE("IRDJ"):
|
||||
case GAMECODE("IRDK"):
|
||||
case GAMECODE("IRDO"):
|
||||
case GAMECODE("IRDS"):
|
||||
case GAMECODE("IRED"):
|
||||
case GAMECODE("IREF"):
|
||||
case GAMECODE("IREI"):
|
||||
case GAMECODE("IREJ"):
|
||||
case GAMECODE("IREK"):
|
||||
case GAMECODE("IREO"):
|
||||
case GAMECODE("IRES"):
|
||||
{
|
||||
overlayHookPatch->AddOverlayPatch(new PokemonBw2IrApPatch());
|
||||
overlayHookPatch->AddOverlayPatch(new PokemonIrApPatch(PokemonIrVersion::Bw2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#include "common.h"
|
||||
#include "../../../PatchContext.h"
|
||||
#include "PokemonBw1IrApPatchAsm.h"
|
||||
#include "PokemonBw1IrApPatch.h"
|
||||
|
||||
const void* PokemonBw1IrApPatch::InsertPatch(PatchContext& patchContext)
|
||||
{
|
||||
return patchContext.GetPatchCodeCollection().AddUniquePatchCode<PokemonBw1IrApPatchCode>
|
||||
(
|
||||
patchContext.GetPatchHeap(),
|
||||
next ? next->InsertPatch(patchContext) : nullptr
|
||||
)->GetPatchFunction();
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
#include "../OverlayPatch.h"
|
||||
|
||||
/// @brief Arm9 overlay patch to disable the Pokemon Black & White IR-sensor anti-piracy.
|
||||
class PokemonBw1IrApPatch : public OverlayPatch
|
||||
{
|
||||
public:
|
||||
const void* InsertPatch(PatchContext& patchContext) override;
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include "sections.h"
|
||||
#include "../../../PatchCode.h"
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(pokemonbw1irappatch);
|
||||
|
||||
extern "C" void pokemonbw1irappatch_entry();
|
||||
|
||||
extern u32 pokemonbw1irappatch_nextAddress;
|
||||
|
||||
class PokemonBw1IrApPatchCode : public PatchCode
|
||||
{
|
||||
public:
|
||||
PokemonBw1IrApPatchCode(PatchHeap& patchHeap, const void* nextPatch)
|
||||
: PatchCode(SECTION_START(pokemonbw1irappatch), SECTION_SIZE(pokemonbw1irappatch), patchHeap)
|
||||
{
|
||||
pokemonbw1irappatch_nextAddress = (u32)nextPatch;
|
||||
}
|
||||
|
||||
const void* GetPatchFunction() const
|
||||
{
|
||||
return GetAddressAtTarget((void*)pokemonbw1irappatch_entry);
|
||||
}
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
.cpu arm946e-s
|
||||
.syntax unified
|
||||
.section "pokemonbw1irappatch", "ax"
|
||||
.thumb
|
||||
|
||||
.global pokemonbw1irappatch_entry
|
||||
.type pokemonbw1irappatch_entry, %function
|
||||
pokemonbw1irappatch_entry:
|
||||
push {r5,lr}
|
||||
|
||||
ldmia r5!, {r1, r2} // id, ram address
|
||||
ldr r0,= 231 // target overlay id
|
||||
cmp r0, r1
|
||||
bne continue_to_next
|
||||
ldr r1,= 0x1CA // patch offset in overlay
|
||||
movs r0, #1 // force return value of function to 1 instead of 0
|
||||
adds r2, r1
|
||||
strb r0, [r2]
|
||||
|
||||
continue_to_next:
|
||||
ldr r0, pokemonbw1irappatch_nextAddress
|
||||
pop {r5,pc}
|
||||
|
||||
.balign 4
|
||||
|
||||
.global pokemonbw1irappatch_nextAddress
|
||||
pokemonbw1irappatch_nextAddress:
|
||||
.word 0
|
||||
|
||||
.pool
|
||||
|
||||
.end
|
||||
@@ -1,13 +0,0 @@
|
||||
#include "common.h"
|
||||
#include "../../../PatchContext.h"
|
||||
#include "PokemonBw2IrApPatchAsm.h"
|
||||
#include "PokemonBw2IrApPatch.h"
|
||||
|
||||
const void* PokemonBw2IrApPatch::InsertPatch(PatchContext& patchContext)
|
||||
{
|
||||
return patchContext.GetPatchCodeCollection().AddUniquePatchCode<PokemonBw2IrApPatchCode>
|
||||
(
|
||||
patchContext.GetPatchHeap(),
|
||||
next ? next->InsertPatch(patchContext) : nullptr
|
||||
)->GetPatchFunction();
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
#include "../OverlayPatch.h"
|
||||
|
||||
/// @brief Arm9 overlay patch to disable the Pokemon Black & White 2 IR-sensor anti-piracy.
|
||||
class PokemonBw2IrApPatch : public OverlayPatch
|
||||
{
|
||||
public:
|
||||
const void* InsertPatch(PatchContext& patchContext) override;
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include "sections.h"
|
||||
#include "../../../PatchCode.h"
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(pokemonbw2irappatch);
|
||||
|
||||
extern "C" void pokemonbw2irappatch_entry();
|
||||
|
||||
extern u32 pokemonbw2irappatch_nextAddress;
|
||||
|
||||
class PokemonBw2IrApPatchCode : public PatchCode
|
||||
{
|
||||
public:
|
||||
PokemonBw2IrApPatchCode(PatchHeap& patchHeap, const void* nextPatch)
|
||||
: PatchCode(SECTION_START(pokemonbw2irappatch), SECTION_SIZE(pokemonbw2irappatch), patchHeap)
|
||||
{
|
||||
pokemonbw2irappatch_nextAddress = (u32)nextPatch;
|
||||
}
|
||||
|
||||
const void* GetPatchFunction() const
|
||||
{
|
||||
return GetAddressAtTarget((void*)pokemonbw2irappatch_entry);
|
||||
}
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
.cpu arm946e-s
|
||||
.syntax unified
|
||||
.section "pokemonbw2irappatch", "ax"
|
||||
.thumb
|
||||
|
||||
.global pokemonbw2irappatch_entry
|
||||
.type pokemonbw2irappatch_entry, %function
|
||||
pokemonbw2irappatch_entry:
|
||||
push {r5,lr}
|
||||
|
||||
ldmia r5!, {r1, r2} // id, ram address
|
||||
ldr r0,= 338 // target overlay id
|
||||
cmp r0, r1
|
||||
bne continue_to_next
|
||||
movs r0, #0
|
||||
adds r2, #0xEC
|
||||
strh r0, [r2]
|
||||
adds r2, #(0x1B8 - 0xEC)
|
||||
ldr r0,= 0x47702001
|
||||
str r0, [r2]
|
||||
movs r0, #1
|
||||
strb r0, [r2, #(0x1CA - 0x1B8)]
|
||||
|
||||
continue_to_next:
|
||||
ldr r0, pokemonbw2irappatch_nextAddress
|
||||
pop {r5,pc}
|
||||
|
||||
.balign 4
|
||||
|
||||
.global pokemonbw2irappatch_nextAddress
|
||||
pokemonbw2irappatch_nextAddress:
|
||||
.word 0
|
||||
|
||||
.pool
|
||||
|
||||
.end
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "common.h"
|
||||
#include "../../../PatchContext.h"
|
||||
#include "PokemonIrApPatchAsm.h"
|
||||
#include "PokemonIrApPatch.h"
|
||||
|
||||
const void* PokemonIrApPatch::InsertPatch(PatchContext& patchContext)
|
||||
{
|
||||
ConfigurePatch();
|
||||
return patchContext.GetPatchCodeCollection().AddUniquePatchCode<PokemonIrApPatchCode>
|
||||
(
|
||||
patchContext.GetPatchHeap(),
|
||||
next ? next->InsertPatch(patchContext) : nullptr
|
||||
)->GetPatchFunction();
|
||||
}
|
||||
|
||||
void PokemonIrApPatch::ConfigurePatch() const {
|
||||
switch (_version)
|
||||
{
|
||||
// All of these offsets are luckily region-independent
|
||||
case PokemonIrVersion::Hgss:
|
||||
{
|
||||
pokemonirappatch_overlayId = 1;
|
||||
pokemonirappatch_offset = 0xD2C + 0x12;
|
||||
break;
|
||||
}
|
||||
case PokemonIrVersion::Bw1:
|
||||
{
|
||||
pokemonirappatch_overlayId = 231;
|
||||
pokemonirappatch_offset = 0x1B8 + 0x12;
|
||||
break;
|
||||
}
|
||||
case PokemonIrVersion::Bw2:
|
||||
{
|
||||
pokemonirappatch_overlayId = 338;
|
||||
pokemonirappatch_offset = 0x1B8 + 0x12;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG_WARNING("Unsupported Pokemon IR version\n");
|
||||
pokemonirappatch_overlayId = 0xFFFFFFFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "../OverlayPatch.h"
|
||||
#include "PokemonIrVersion.h"
|
||||
|
||||
/// @brief Arm9 overlay patch to disable the IR-sensor anti-piracy in Pokemon HeartGold, SoulSilver, Black, White, Black 2, and White 2.
|
||||
class PokemonIrApPatch : public OverlayPatch
|
||||
{
|
||||
public:
|
||||
PokemonIrApPatch(PokemonIrVersion version) : _version(version) { }
|
||||
const void* InsertPatch(PatchContext& patchContext) override;
|
||||
|
||||
private:
|
||||
PokemonIrVersion _version;
|
||||
|
||||
void ConfigurePatch() const;
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "sections.h"
|
||||
#include "../../../PatchCode.h"
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(pokemonirappatch);
|
||||
|
||||
extern "C" void pokemonirappatch_entry();
|
||||
|
||||
extern u32 pokemonirappatch_overlayId;
|
||||
extern u32 pokemonirappatch_offset;
|
||||
extern u32 pokemonirappatch_nextAddress;
|
||||
|
||||
class PokemonIrApPatchCode : public PatchCode
|
||||
{
|
||||
public:
|
||||
PokemonIrApPatchCode(PatchHeap& patchHeap, const void* nextPatch)
|
||||
: PatchCode(SECTION_START(pokemonirappatch), SECTION_SIZE(pokemonirappatch), patchHeap)
|
||||
{
|
||||
pokemonirappatch_nextAddress = (u32)nextPatch;
|
||||
}
|
||||
|
||||
const void* GetPatchFunction() const
|
||||
{
|
||||
return GetAddressAtTarget((void*)pokemonirappatch_entry);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
.cpu arm946e-s
|
||||
.syntax unified
|
||||
.section "pokemonirappatch", "ax"
|
||||
.thumb
|
||||
|
||||
.global pokemonirappatch_entry
|
||||
.type pokemonirappatch_entry, %function
|
||||
pokemonirappatch_entry:
|
||||
push {r5,lr}
|
||||
|
||||
ldmia r5!, {r1, r2} // overlay id, ram address
|
||||
ldr r0, pokemonirappatch_overlayId
|
||||
cmp r0, r1
|
||||
bne continue_to_next
|
||||
|
||||
ldr r1, pokemonirappatch_offset
|
||||
movs r0, #1 // force return value of function to 1 instead of 0
|
||||
strb r0, [r2, r1]
|
||||
|
||||
continue_to_next:
|
||||
ldr r0, pokemonirappatch_nextAddress
|
||||
pop {r5,pc}
|
||||
|
||||
.balign 4
|
||||
|
||||
.global pokemonirappatch_overlayId
|
||||
pokemonirappatch_overlayId:
|
||||
.word 0
|
||||
|
||||
.global pokemonirappatch_offset
|
||||
pokemonirappatch_offset:
|
||||
.word 0
|
||||
|
||||
.global pokemonirappatch_nextAddress
|
||||
pokemonirappatch_nextAddress:
|
||||
.word 0
|
||||
|
||||
.pool
|
||||
|
||||
.end
|
||||
9
common/PokemonIrVersion.h
Normal file
9
common/PokemonIrVersion.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
/// @brief Enum representing a Pokemon game version with IR-sensor based anti-piracy
|
||||
enum class PokemonIrVersion : u32
|
||||
{
|
||||
Hgss,
|
||||
Bw1,
|
||||
Bw2
|
||||
};
|
||||
Reference in New Issue
Block a user