diff --git a/arm9/source/Arm9Patcher.cpp b/arm9/source/Arm9Patcher.cpp index 422cd5d..b76c896 100644 --- a/arm9/source/Arm9Patcher.cpp +++ b/arm9/source/Arm9Patcher.cpp @@ -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; } } diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatch.cpp b/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatch.cpp deleted file mode 100644 index 27b2b3e..0000000 --- a/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatch.cpp +++ /dev/null @@ -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 - ( - patchContext.GetPatchHeap(), - next ? next->InsertPatch(patchContext) : nullptr - )->GetPatchFunction(); -} \ No newline at end of file diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatch.h b/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatch.h deleted file mode 100644 index e09af30..0000000 --- a/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatch.h +++ /dev/null @@ -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; -}; \ No newline at end of file diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatchAsm.h b/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatchAsm.h deleted file mode 100644 index 983c224..0000000 --- a/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatchAsm.h +++ /dev/null @@ -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); - } -}; diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatchAsm.s b/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatchAsm.s deleted file mode 100644 index 0c30bea..0000000 --- a/arm9/source/patches/arm9/OverlayPatches/PokemonBw1/PokemonBw1IrApPatchAsm.s +++ /dev/null @@ -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 diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatch.cpp b/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatch.cpp deleted file mode 100644 index 84d7204..0000000 --- a/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatch.cpp +++ /dev/null @@ -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 - ( - patchContext.GetPatchHeap(), - next ? next->InsertPatch(patchContext) : nullptr - )->GetPatchFunction(); -} \ No newline at end of file diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatch.h b/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatch.h deleted file mode 100644 index c013b4e..0000000 --- a/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatch.h +++ /dev/null @@ -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; -}; \ No newline at end of file diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatchAsm.h b/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatchAsm.h deleted file mode 100644 index cff2bd5..0000000 --- a/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatchAsm.h +++ /dev/null @@ -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); - } -}; diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatchAsm.s b/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatchAsm.s deleted file mode 100644 index 579f3e5..0000000 --- a/arm9/source/patches/arm9/OverlayPatches/PokemonBw2/PokemonBw2IrApPatchAsm.s +++ /dev/null @@ -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 diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatch.cpp b/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatch.cpp new file mode 100644 index 0000000..0d5ebda --- /dev/null +++ b/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatch.cpp @@ -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 + ( + 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; + } + } +} diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatch.h b/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatch.h new file mode 100644 index 0000000..2d6fe29 --- /dev/null +++ b/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatch.h @@ -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; +}; diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatchAsm.h b/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatchAsm.h new file mode 100644 index 0000000..9bcddaa --- /dev/null +++ b/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatchAsm.h @@ -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); + } +}; diff --git a/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatchAsm.s b/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatchAsm.s new file mode 100644 index 0000000..a966f8f --- /dev/null +++ b/arm9/source/patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatchAsm.s @@ -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 diff --git a/common/PokemonIrVersion.h b/common/PokemonIrVersion.h new file mode 100644 index 0000000..b663ee0 --- /dev/null +++ b/common/PokemonIrVersion.h @@ -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 +};