From 9d3345a6d69c38bf31014df69c52583c877eed24 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 13 Nov 2021 21:41:16 -0500 Subject: [PATCH] Enforce structs to enforce save block order for modern toolchains. --- include/load_save.h | 30 +++++++++++++++++++++++++++--- src/load_save.c | 15 +++++---------- src/main.c | 4 ++-- src/save.c | 28 ++++++++++++++-------------- 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/include/load_save.h b/include/load_save.h index 2f4a9ace6..9e7b1bc92 100644 --- a/include/load_save.h +++ b/include/load_save.h @@ -1,9 +1,33 @@ #ifndef GUARD_LOAD_SAVE_H #define GUARD_LOAD_SAVE_H -extern struct SaveBlock1 gSaveblock1; -extern struct SaveBlock2 gSaveblock2; -extern struct PokemonStorage gPokemonStorage; +#include "pokemon_storage_system.h" + +#define SAVEBLOCK_MOVE_RANGE 128 + +/** + * These structs are to prevent them from being reordered on newer or modern + * toolchains. If this is not done, the ClearSav functions will end up erasing + * the wrong memory leading to various glitches. + */ +struct SaveBlock2DMA { + struct SaveBlock2 block; + u8 dma[SAVEBLOCK_MOVE_RANGE]; +}; + +struct SaveBlock1DMA { + struct SaveBlock1 block; + u8 dma[SAVEBLOCK_MOVE_RANGE]; +}; + +struct PokemonStorageDMA { + struct PokemonStorage block; + u8 dma[SAVEBLOCK_MOVE_RANGE]; +}; + +extern struct SaveBlock1DMA gSaveblock1; +extern struct SaveBlock2DMA gSaveblock2; +extern struct PokemonStorageDMA gPokemonStorage; extern bool32 gFlashMemoryPresent; extern struct SaveBlock1 *gSaveBlock1Ptr; diff --git a/src/load_save.c b/src/load_save.c index 1ba5a1600..889f42b14 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -29,14 +29,9 @@ struct LoadedSaveData }; // EWRAM DATA -EWRAM_DATA struct SaveBlock2 gSaveblock2 = {0}; -EWRAM_DATA u8 gSaveblock2_DMA[SAVEBLOCK_MOVE_RANGE] = {0}; - -EWRAM_DATA struct SaveBlock1 gSaveblock1 = {0}; -EWRAM_DATA u8 gSaveblock1_DMA[SAVEBLOCK_MOVE_RANGE] = {0}; - -EWRAM_DATA struct PokemonStorage gPokemonStorage = {0}; -EWRAM_DATA u8 gSaveblock3_DMA[SAVEBLOCK_MOVE_RANGE] = {0}; +EWRAM_DATA struct SaveBlock2DMA gSaveblock2 = {0}; +EWRAM_DATA struct SaveBlock1DMA gSaveblock1 = {0}; +EWRAM_DATA struct PokemonStorageDMA gPokemonStorage = {0}; EWRAM_DATA struct LoadedSaveData gLoadedSaveData = {0}; EWRAM_DATA u32 gLastEncryptionKey = 0; @@ -63,12 +58,12 @@ void CheckForFlashMemory(void) void ClearSav2(void) { - CpuFill16(0, &gSaveblock2, sizeof(struct SaveBlock2) + sizeof(gSaveblock2_DMA)); + CpuFill16(0, &gSaveblock2, sizeof(struct SaveBlock2DMA)); } void ClearSav1(void) { - CpuFill16(0, &gSaveblock1, sizeof(struct SaveBlock1) + sizeof(gSaveblock1_DMA)); + CpuFill16(0, &gSaveblock1, sizeof(struct SaveBlock1DMA)); } // Offset is the sum of the trainer id bytes diff --git a/src/main.c b/src/main.c index 215f85c46..2b96a8698 100644 --- a/src/main.c +++ b/src/main.c @@ -172,8 +172,8 @@ static void InitMainCallbacks(void) gMain.vblankCounter2 = 0; gMain.callback1 = NULL; SetMainCallback2(CB2_InitCopyrightScreenAfterBootup); - gSaveBlock2Ptr = &gSaveblock2; - gPokemonStoragePtr = &gPokemonStorage; + gSaveBlock2Ptr = &gSaveblock2.block; + gPokemonStoragePtr = &gPokemonStorage.block; } static void CallCallbacks(void) diff --git a/src/save.c b/src/save.c index 3c8f4360d..253e7763d 100644 --- a/src/save.c +++ b/src/save.c @@ -52,22 +52,22 @@ static u8 HandleWriteSector(u16 a1, const struct SaveSectionLocation *location); static const struct SaveSectionOffsets sSaveSectionOffsets[] = { - SAVEBLOCK_CHUNK(gSaveblock2, 0), + SAVEBLOCK_CHUNK(struct SaveBlock2, 0), - SAVEBLOCK_CHUNK(gSaveblock1, 0), - SAVEBLOCK_CHUNK(gSaveblock1, 1), - SAVEBLOCK_CHUNK(gSaveblock1, 2), - SAVEBLOCK_CHUNK(gSaveblock1, 3), + SAVEBLOCK_CHUNK(struct SaveBlock1, 0), + SAVEBLOCK_CHUNK(struct SaveBlock1, 1), + SAVEBLOCK_CHUNK(struct SaveBlock1, 2), + SAVEBLOCK_CHUNK(struct SaveBlock1, 3), - SAVEBLOCK_CHUNK(gPokemonStorage, 0), - SAVEBLOCK_CHUNK(gPokemonStorage, 1), - SAVEBLOCK_CHUNK(gPokemonStorage, 2), - SAVEBLOCK_CHUNK(gPokemonStorage, 3), - SAVEBLOCK_CHUNK(gPokemonStorage, 4), - SAVEBLOCK_CHUNK(gPokemonStorage, 5), - SAVEBLOCK_CHUNK(gPokemonStorage, 6), - SAVEBLOCK_CHUNK(gPokemonStorage, 7), - SAVEBLOCK_CHUNK(gPokemonStorage, 8), + SAVEBLOCK_CHUNK(struct PokemonStorage, 0), + SAVEBLOCK_CHUNK(struct PokemonStorage, 1), + SAVEBLOCK_CHUNK(struct PokemonStorage, 2), + SAVEBLOCK_CHUNK(struct PokemonStorage, 3), + SAVEBLOCK_CHUNK(struct PokemonStorage, 4), + SAVEBLOCK_CHUNK(struct PokemonStorage, 5), + SAVEBLOCK_CHUNK(struct PokemonStorage, 6), + SAVEBLOCK_CHUNK(struct PokemonStorage, 7), + SAVEBLOCK_CHUNK(struct PokemonStorage, 8), }; // iwram common