Merge pull request #1552 from ProjectRevoTPP/fix_saveblock_reorder

Enforce structs to enforce save block order for modern toolchains.
This commit is contained in:
GriffinR 2021-11-13 23:25:29 -05:00 committed by GitHub
commit 8d18d03c79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 29 deletions

View File

@ -1,9 +1,33 @@
#ifndef GUARD_LOAD_SAVE_H #ifndef GUARD_LOAD_SAVE_H
#define GUARD_LOAD_SAVE_H #define GUARD_LOAD_SAVE_H
extern struct SaveBlock1 gSaveblock1; #include "pokemon_storage_system.h"
extern struct SaveBlock2 gSaveblock2;
extern struct PokemonStorage gPokemonStorage; #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 bool32 gFlashMemoryPresent;
extern struct SaveBlock1 *gSaveBlock1Ptr; extern struct SaveBlock1 *gSaveBlock1Ptr;

View File

@ -29,14 +29,9 @@ struct LoadedSaveData
}; };
// EWRAM DATA // EWRAM DATA
EWRAM_DATA struct SaveBlock2 gSaveblock2 = {0}; EWRAM_DATA struct SaveBlock2DMA gSaveblock2 = {0};
EWRAM_DATA u8 gSaveblock2_DMA[SAVEBLOCK_MOVE_RANGE] = {0}; EWRAM_DATA struct SaveBlock1DMA gSaveblock1 = {0};
EWRAM_DATA struct PokemonStorageDMA gPokemonStorage = {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 LoadedSaveData gLoadedSaveData = {0}; EWRAM_DATA struct LoadedSaveData gLoadedSaveData = {0};
EWRAM_DATA u32 gLastEncryptionKey = 0; EWRAM_DATA u32 gLastEncryptionKey = 0;
@ -63,12 +58,12 @@ void CheckForFlashMemory(void)
void ClearSav2(void) void ClearSav2(void)
{ {
CpuFill16(0, &gSaveblock2, sizeof(struct SaveBlock2) + sizeof(gSaveblock2_DMA)); CpuFill16(0, &gSaveblock2, sizeof(struct SaveBlock2DMA));
} }
void ClearSav1(void) 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 // Offset is the sum of the trainer id bytes

View File

@ -172,8 +172,8 @@ static void InitMainCallbacks(void)
gMain.vblankCounter2 = 0; gMain.vblankCounter2 = 0;
gMain.callback1 = NULL; gMain.callback1 = NULL;
SetMainCallback2(CB2_InitCopyrightScreenAfterBootup); SetMainCallback2(CB2_InitCopyrightScreenAfterBootup);
gSaveBlock2Ptr = &gSaveblock2; gSaveBlock2Ptr = &gSaveblock2.block;
gPokemonStoragePtr = &gPokemonStorage; gPokemonStoragePtr = &gPokemonStorage.block;
} }
static void CallCallbacks(void) static void CallCallbacks(void)

View File

@ -55,22 +55,22 @@ struct
u16 size; u16 size;
} static const sSaveSlotLayout[NUM_SECTORS_PER_SLOT] = } static const sSaveSlotLayout[NUM_SECTORS_PER_SLOT] =
{ {
SAVEBLOCK_CHUNK(gSaveblock2, 0), // SECTOR_ID_SAVEBLOCK2 SAVEBLOCK_CHUNK(struct SaveBlock2, 0), // SECTOR_ID_SAVEBLOCK2
SAVEBLOCK_CHUNK(gSaveblock1, 0), // SECTOR_ID_SAVEBLOCK1_START SAVEBLOCK_CHUNK(struct SaveBlock1, 0), // SECTOR_ID_SAVEBLOCK1_START
SAVEBLOCK_CHUNK(gSaveblock1, 1), SAVEBLOCK_CHUNK(struct SaveBlock1, 1),
SAVEBLOCK_CHUNK(gSaveblock1, 2), SAVEBLOCK_CHUNK(struct SaveBlock1, 2),
SAVEBLOCK_CHUNK(gSaveblock1, 3), // SECTOR_ID_SAVEBLOCK1_END SAVEBLOCK_CHUNK(struct SaveBlock1, 3), // SECTOR_ID_SAVEBLOCK1_END
SAVEBLOCK_CHUNK(gPokemonStorage, 0), // SECTOR_ID_PKMN_STORAGE_START SAVEBLOCK_CHUNK(struct PokemonStorage, 0), // SECTOR_ID_PKMN_STORAGE_START
SAVEBLOCK_CHUNK(gPokemonStorage, 1), SAVEBLOCK_CHUNK(struct PokemonStorage, 1),
SAVEBLOCK_CHUNK(gPokemonStorage, 2), SAVEBLOCK_CHUNK(struct PokemonStorage, 2),
SAVEBLOCK_CHUNK(gPokemonStorage, 3), SAVEBLOCK_CHUNK(struct PokemonStorage, 3),
SAVEBLOCK_CHUNK(gPokemonStorage, 4), SAVEBLOCK_CHUNK(struct PokemonStorage, 4),
SAVEBLOCK_CHUNK(gPokemonStorage, 5), SAVEBLOCK_CHUNK(struct PokemonStorage, 5),
SAVEBLOCK_CHUNK(gPokemonStorage, 6), SAVEBLOCK_CHUNK(struct PokemonStorage, 6),
SAVEBLOCK_CHUNK(gPokemonStorage, 7), SAVEBLOCK_CHUNK(struct PokemonStorage, 7),
SAVEBLOCK_CHUNK(gPokemonStorage, 8), // SECTOR_ID_PKMN_STORAGE_END SAVEBLOCK_CHUNK(struct PokemonStorage, 8), // SECTOR_ID_PKMN_STORAGE_END
}; };
u16 gLastWrittenSector; u16 gLastWrittenSector;