Add overlay patch for hombrew AP in Rabbids Go Homeh (#82)

This commit is contained in:
Mow
2025-12-31 01:51:40 -05:00
committed by GitHub
parent 6fb34c75f8
commit d6080984d1
5 changed files with 100 additions and 0 deletions

View File

@@ -22,6 +22,7 @@
#include "patches/arm9/OverlayPatches/DSProtectPatches/DSProtectPuyoPuyo7Patch.h"
#include "patches/arm9/OverlayPatches/PokemonIr/PokemonIrApPatch.h"
#include "patches/arm9/OverlayPatches/KirbySuperStarUltra/KirbySuperStarUltraPatch.h"
#include "patches/arm9/OverlayPatches/RabbidsGoHome/RabbidsGoHomePatch.h"
#include "patches/arm9/OverlayPatches/GoldenSunDarkDawn/GoldenSunDarkDawnOverlayHookPatch.h"
#include "SecureSysCallsUnusedSpaceLocator.h"
#include "fastSearch.h"
@@ -405,6 +406,13 @@ void Arm9Patcher::AddGameSpecificPatches(
patchCollection.AddPatch(new NintendoDSGuideNandSavePatch());
break;
}
// Rabbids Go Home
case GAMECODE("VRGE"):
case GAMECODE("VRGV"):
{
overlayHookPatch->AddOverlayPatch(new RabbidsGoHomePatch());
break;
}
// Kirby Super Star Ultra
case GAMECODE("YKWE"):
case GAMECODE("YKWJ"):

View File

@@ -0,0 +1,31 @@
#include "common.h"
#include "gameCode.h"
#include "patches/PatchContext.h"
#include "RabbidsGoHomePatchAsm.h"
#include "RabbidsGoHomePatch.h"
const void* RabbidsGoHomePatch::InsertPatch(PatchContext& patchContext)
{
rabbidspatch_nextAddress = next ? (const void*)next->InsertPatch(patchContext) : nullptr;
switch (patchContext.GetGameCode())
{
case GAMECODE("VRGE"):
{
rabbidspatch_offset = 0x1465C + 0x1C;
break;
}
case GAMECODE("VRGV"):
{
rabbidspatch_offset = 0x146A4 + 0x1C;
break;
}
}
u32 patchSize = SECTION_SIZE(rabbidspatch);
void* patchAddress = patchContext.GetPatchHeap().Alloc(patchSize);
u32 entryAddress = (u32)&rabbidspatch_entry - (u32)SECTION_START(rabbidspatch) + (u32)patchAddress;
memcpy(patchAddress, SECTION_START(rabbidspatch), patchSize);
return (const void*)entryAddress;
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "../OverlayPatch.h"
/// @brief Arm9 overlay patch for Rabbids Go Home.
/// @details
/// This game has a homebrew AP method based on ROM read timings. Specifically, it will
/// run 100 ROM reads of 0x4000 bytes each, or 32 0x200-byte pages, and use ticks to time how
/// long it takes. It must take between 0x80000 and 0x88000 ticks, or 1.001 to 1.063 seconds,
/// or the game will hang prior to the title screen (after the publisher splash and language selection).
/// The actual contents of the ROM reads are not checked, and they are obtained using TWL SDK CARD_ReadRom.
///
/// To bypass this, most of the function that runs the AP check is skipped, as it has no other side effects.
class RabbidsGoHomePatch : public OverlayPatch
{
public:
const void* InsertPatch(PatchContext& patchContext) override;
};

View File

@@ -0,0 +1,10 @@
#pragma once
#include "sections.h"
DEFINE_SECTION_SYMBOLS(rabbidspatch);
extern "C" void rabbidspatch_entry();
extern u32 rabbidspatch_offset;
extern const void* rabbidspatch_nextAddress; // Next patch address

View File

@@ -0,0 +1,34 @@
.cpu arm946e-s
.syntax unified
.section "rabbidspatch", "ax"
.thumb
.global rabbidspatch_entry
.type rabbidspatch_entry, %function
rabbidspatch_entry:
push {r5,lr}
ldm r5!, {r0, r1} // ovy_id, ram_start
cmp r0, #1
bne continue_to_next
ldr r2, rabbidspatch_offset
ldr r0, =0xE3A00001 // mov r0, #1
str r0, [r1, r2]
continue_to_next:
ldr r0, rabbidspatch_nextAddress
pop {r5,pc}
.balign 4
.global rabbidspatch_offset
rabbidspatch_offset:
.word 0
.global rabbidspatch_nextAddress
rabbidspatch_nextAddress:
.word 0
.pool
.end