mirror of https://github.com/pret/pokeemerald.git
match MoveSaveBlocks_ResetHeap
This commit is contained in:
parent
e3585d7d66
commit
462a0030ae
162
src/load_save.c
162
src/load_save.c
|
@ -80,45 +80,15 @@ void SetSaveBlocksPointers(u16 offset)
|
||||||
SetDecorationInventoriesPointers();
|
SetDecorationInventoriesPointers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// stuff i used to try and match MoveSaveBlocks_ResetHeap
|
extern u8 gHeap[];
|
||||||
struct SaveBlocksInOne
|
|
||||||
{
|
|
||||||
struct SaveBlock2 sav2;
|
|
||||||
struct SaveBlock1 sav1;
|
|
||||||
struct PokemonStorage sav3;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct SaveBlocksInOne gHeap;
|
|
||||||
|
|
||||||
#define ewram_addr 0x02000000 // oh no...
|
|
||||||
#define ewram_addr2 0x02000f2c
|
|
||||||
#define ewram_addr3 0x02004cb4
|
|
||||||
|
|
||||||
#define eSaveBlockCopy (*(struct SaveBlocksInOne *)(ewram_addr + 0x0))
|
|
||||||
#define eSaveBlock2Copy (*(struct SaveBlock2 *)((void*)(ewram_addr + 0x0)))
|
|
||||||
#define eSaveBlock1Copy (*(struct SaveBlock1 *)((void*)(ewram_addr + sizeof(struct SaveBlock2))))
|
|
||||||
#define eSaveBlock3Copy (*(struct PokemonStorage *)((void*)(ewram_addr + sizeof(struct SaveBlock2) + sizeof(struct SaveBlock1))))
|
|
||||||
|
|
||||||
#ifdef NONMATCHING // this is one devil of a motherfucker
|
|
||||||
/*
|
|
||||||
The reason MoveSaveBlocks_ResetHeap mismatches is due to incorrect memcpys. Various
|
|
||||||
things have been tried, such as: direct struct copys, ewram casts, use of defining
|
|
||||||
the addresses manually, using memcpy anyway, delayed allocation of pointers at
|
|
||||||
the start of function, as seen above and below. Scope declaration has been used to try and
|
|
||||||
reproduce the correct macro thought to be used, but nothing has worked. It is worth
|
|
||||||
noting that at this point that the compiler will delay the allocation of the save block
|
|
||||||
pointers at the beginningto be allocated later: which might matter for matching this.
|
|
||||||
Due to loading shared ewram heap areas directly, it is very likely emerald used ewram
|
|
||||||
defines for this function, but there is no known example of a matching define.
|
|
||||||
In addition, dead code might be present in the form of a runtime variable used
|
|
||||||
to fix the address of the save blocks. This has been tested and is shown to affect
|
|
||||||
the registers as well.
|
|
||||||
*/
|
|
||||||
void MoveSaveBlocks_ResetHeap(void)
|
void MoveSaveBlocks_ResetHeap(void)
|
||||||
{
|
{
|
||||||
void *vblankCB, *hblankCB;
|
void *vblankCB, *hblankCB;
|
||||||
u32 encryptionKey;
|
u32 encryptionKey;
|
||||||
struct SaveBlock1 **sav1Copy = &gSaveBlock1Ptr; // r10;
|
struct SaveBlock2 *saveBlock2Copy;
|
||||||
|
struct SaveBlock1 *saveBlock1Copy;
|
||||||
|
struct PokemonStorage *pokemonStorageCopy;
|
||||||
|
|
||||||
// save interrupt functions and turn them off
|
// save interrupt functions and turn them off
|
||||||
vblankCB = gMain.vblankCallback;
|
vblankCB = gMain.vblankCallback;
|
||||||
|
@ -127,22 +97,30 @@ void MoveSaveBlocks_ResetHeap(void)
|
||||||
gMain.hblankCallback = NULL;
|
gMain.hblankCallback = NULL;
|
||||||
gUnknown_0203CF5C = NULL;
|
gUnknown_0203CF5C = NULL;
|
||||||
|
|
||||||
|
saveBlock2Copy = (struct SaveBlock2 *)(gHeap);
|
||||||
|
saveBlock1Copy = (struct SaveBlock1 *)(gHeap + sizeof(struct SaveBlock2));
|
||||||
|
pokemonStorageCopy = (struct PokemonStorage *)(gHeap + sizeof(struct SaveBlock2) + sizeof(struct SaveBlock1));
|
||||||
|
|
||||||
// backup the saves.
|
// backup the saves.
|
||||||
eSaveBlock1Copy = **sav1Copy;
|
*saveBlock2Copy = *gSaveBlock2Ptr;
|
||||||
eSaveBlock2Copy = *gSaveBlock2Ptr;
|
*saveBlock1Copy = *gSaveBlock1Ptr;
|
||||||
eSaveBlock3Copy = *gPokemonStoragePtr;
|
*pokemonStorageCopy = *gPokemonStoragePtr;
|
||||||
|
|
||||||
// change saveblocks' pointers
|
// change saveblocks' pointers
|
||||||
// argument is a sum of the individual trainerId bytes
|
// argument is a sum of the individual trainerId bytes
|
||||||
SetSaveBlocksPointers(eSaveBlock2Copy.playerTrainerId[0] + eSaveBlock2Copy.playerTrainerId[1] + eSaveBlock2Copy.playerTrainerId[2] + eSaveBlock2Copy.playerTrainerId[3]);
|
SetSaveBlocksPointers(
|
||||||
|
saveBlock2Copy->playerTrainerId[0] +
|
||||||
|
saveBlock2Copy->playerTrainerId[1] +
|
||||||
|
saveBlock2Copy->playerTrainerId[2] +
|
||||||
|
saveBlock2Copy->playerTrainerId[3]);
|
||||||
|
|
||||||
// restore saveblock data since the pointers changed
|
// restore saveblock data since the pointers changed
|
||||||
**sav1Copy = eSaveBlock1Copy;
|
memcpy(gSaveBlock2Ptr, saveBlock2Copy, sizeof(*gSaveBlock2Ptr));
|
||||||
*gSaveBlock2Ptr = eSaveBlock2Copy;
|
memcpy(gSaveBlock1Ptr, saveBlock1Copy, sizeof(*gSaveBlock1Ptr));
|
||||||
*gPokemonStoragePtr = eSaveBlock3Copy;
|
memcpy(gPokemonStoragePtr, pokemonStorageCopy, sizeof(*gPokemonStoragePtr));
|
||||||
|
|
||||||
// heap was destroyed in the copying process, so reset it
|
// heap was destroyed in the copying process, so reset it
|
||||||
InitHeap((void*)(0x02000000), 0x1C000);
|
InitHeap(gHeap, 0x1C000);
|
||||||
|
|
||||||
// restore interrupt functions
|
// restore interrupt functions
|
||||||
gMain.hblankCallback = hblankCB;
|
gMain.hblankCallback = hblankCB;
|
||||||
|
@ -153,105 +131,7 @@ void MoveSaveBlocks_ResetHeap(void)
|
||||||
ApplyNewEncryptionKeyToAllEncryptedData(encryptionKey);
|
ApplyNewEncryptionKeyToAllEncryptedData(encryptionKey);
|
||||||
gSaveBlock2Ptr->encryptionKey = encryptionKey;
|
gSaveBlock2Ptr->encryptionKey = encryptionKey;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
__attribute__((naked))
|
|
||||||
void MoveSaveBlocks_ResetHeap(void)
|
|
||||||
{
|
|
||||||
asm(".syntax unified\n\
|
|
||||||
push {r4-r7,lr}\n\
|
|
||||||
mov r7, r10\n\
|
|
||||||
mov r6, r9\n\
|
|
||||||
mov r5, r8\n\
|
|
||||||
push {r5-r7}\n\
|
|
||||||
sub sp, 0x8\n\
|
|
||||||
ldr r5, =gMain\n\
|
|
||||||
ldr r0, [r5, 0xC]\n\
|
|
||||||
str r0, [sp]\n\
|
|
||||||
ldr r1, [r5, 0x10]\n\
|
|
||||||
str r1, [sp, 0x4]\n\
|
|
||||||
movs r0, 0\n\
|
|
||||||
str r0, [r5, 0xC]\n\
|
|
||||||
str r0, [r5, 0x10]\n\
|
|
||||||
ldr r1, =gUnknown_0203CF5C\n\
|
|
||||||
str r0, [r1]\n\
|
|
||||||
ldr r4, =0x02000000\n\
|
|
||||||
ldr r0, =gSaveBlock2Ptr\n\
|
|
||||||
ldr r1, [r0]\n\
|
|
||||||
ldr r6, =0x00000f2c\n\
|
|
||||||
adds r0, r4, 0\n\
|
|
||||||
adds r2, r6, 0\n\
|
|
||||||
bl memcpy\n\
|
|
||||||
ldr r1, =gSaveBlock1Ptr\n\
|
|
||||||
mov r10, r1\n\
|
|
||||||
ldr r1, [r1]\n\
|
|
||||||
ldr r7, =0x00003d88\n\
|
|
||||||
ldr r0, =0x02000f2c\n\
|
|
||||||
adds r2, r7, 0\n\
|
|
||||||
bl memcpy\n\
|
|
||||||
ldr r0, =gPokemonStoragePtr\n\
|
|
||||||
mov r8, r0\n\
|
|
||||||
ldr r1, [r0]\n\
|
|
||||||
ldr r0, =0x000083d0\n\
|
|
||||||
mov r9, r0\n\
|
|
||||||
ldr r0, =0x02004cb4\n\
|
|
||||||
mov r2, r9\n\
|
|
||||||
bl memcpy\n\
|
|
||||||
ldrb r1, [r4, 0xA]\n\
|
|
||||||
ldrb r0, [r4, 0xB]\n\
|
|
||||||
adds r1, r0\n\
|
|
||||||
ldrb r0, [r4, 0xC]\n\
|
|
||||||
adds r1, r0\n\
|
|
||||||
ldrb r0, [r4, 0xD]\n\
|
|
||||||
adds r0, r1\n\
|
|
||||||
bl SetSaveBlocksPointers\n\
|
|
||||||
ldr r1, =gSaveBlock2Ptr\n\
|
|
||||||
ldr r0, [r1]\n\
|
|
||||||
adds r1, r4, 0\n\
|
|
||||||
adds r2, r6, 0\n\
|
|
||||||
bl memcpy\n\
|
|
||||||
mov r1, r10\n\
|
|
||||||
ldr r0, [r1]\n\
|
|
||||||
ldr r1, =0x02000f2c\n\
|
|
||||||
adds r2, r7, 0\n\
|
|
||||||
bl memcpy\n\
|
|
||||||
mov r1, r8\n\
|
|
||||||
ldr r0, [r1]\n\
|
|
||||||
ldr r1, =0x02004cb4\n\
|
|
||||||
mov r2, r9\n\
|
|
||||||
bl memcpy\n\
|
|
||||||
movs r1, 0xE0\n\
|
|
||||||
lsls r1, 9\n\
|
|
||||||
adds r0, r4, 0\n\
|
|
||||||
bl InitHeap\n\
|
|
||||||
ldr r0, [sp, 0x4]\n\
|
|
||||||
str r0, [r5, 0x10]\n\
|
|
||||||
ldr r1, [sp]\n\
|
|
||||||
str r1, [r5, 0xC]\n\
|
|
||||||
bl Random\n\
|
|
||||||
adds r4, r0, 0\n\
|
|
||||||
bl Random\n\
|
|
||||||
lsls r4, 16\n\
|
|
||||||
lsls r0, 16\n\
|
|
||||||
lsrs r0, 16\n\
|
|
||||||
adds r4, r0\n\
|
|
||||||
adds r0, r4, 0\n\
|
|
||||||
bl ApplyNewEncryptionKeyToAllEncryptedData\n\
|
|
||||||
ldr r1, =gSaveBlock2Ptr\n\
|
|
||||||
ldr r0, [r1]\n\
|
|
||||||
adds r0, 0xAC\n\
|
|
||||||
str r4, [r0]\n\
|
|
||||||
add sp, 0x8\n\
|
|
||||||
pop {r3-r5}\n\
|
|
||||||
mov r8, r3\n\
|
|
||||||
mov r9, r4\n\
|
|
||||||
mov r10, r5\n\
|
|
||||||
pop {r4-r7}\n\
|
|
||||||
pop {r0}\n\
|
|
||||||
bx r0\n\
|
|
||||||
.pool\n\
|
|
||||||
.syntax divided\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u8 sav2_x1_query_bit1(void)
|
u8 sav2_x1_query_bit1(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue