Save-compatible SaveBlock3 (#4112)
* SaveBlock3 in sector footers * Update load_save.c Since mgriffin is currently not available I took the liberty to edit the file. Hope it's fine. * SaveBlock3 in debug menu (#3) --------- Co-authored-by: DizzyEggg <jajkodizzy@wp.pl> Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> Co-authored-by: psf <77138753+pkmnsnfrn@users.noreply.github.com>
This commit is contained in:
parent
81fdfdd90b
commit
311d732359
9 changed files with 66 additions and 5 deletions
|
@ -166,6 +166,8 @@ Debug_CheckSaveBlock::
|
|||
msgbox Debug_SaveBlock1Size, MSGBOX_DEFAULT
|
||||
callnative CheckSaveBlock2Size
|
||||
msgbox Debug_SaveBlock2Size, MSGBOX_DEFAULT
|
||||
callnative CheckSaveBlock3Size
|
||||
msgbox Debug_SaveBlock3Size, MSGBOX_DEFAULT
|
||||
callnative CheckPokemonStorageSize
|
||||
msgbox Debug_PokemonStorageSize, MSGBOX_DEFAULT
|
||||
release
|
||||
|
@ -179,6 +181,10 @@ Debug_SaveBlock2Size::
|
|||
.string "SaveBlock2 size: {STR_VAR_1}b/{STR_VAR_2}b.\n"
|
||||
.string "Free space: {STR_VAR_3}b.$"
|
||||
|
||||
Debug_SaveBlock3Size::
|
||||
.string "SaveBlock3 size: {STR_VAR_1}b/{STR_VAR_2}b.\n"
|
||||
.string "Free space: {STR_VAR_3}b.$"
|
||||
|
||||
Debug_PokemonStorageSize::
|
||||
.string "{PKMN}Storage size: {STR_VAR_1}b/{STR_VAR_2}b.\n"
|
||||
.string "Free space: {STR_VAR_3}b.$"
|
||||
|
|
|
@ -167,6 +167,12 @@ struct UCoords32
|
|||
u32 y;
|
||||
};
|
||||
|
||||
struct SaveBlock3
|
||||
{
|
||||
};
|
||||
|
||||
extern struct SaveBlock3 *gSaveBlock3Ptr;
|
||||
|
||||
struct Time
|
||||
{
|
||||
/*0x00*/ s16 days;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define GUARD_LOAD_SAVE_H
|
||||
|
||||
#include "pokemon_storage_system.h"
|
||||
#include "save.h"
|
||||
|
||||
#define SAVEBLOCK_MOVE_RANGE 128
|
||||
|
||||
|
@ -27,6 +28,7 @@ struct PokemonStorageASLR {
|
|||
|
||||
extern struct SaveBlock1ASLR gSaveblock1;
|
||||
extern struct SaveBlock2ASLR gSaveblock2;
|
||||
extern struct SaveBlock3 gSaveblock3;
|
||||
extern struct PokemonStorageASLR gPokemonStorage;
|
||||
|
||||
extern bool32 gFlashMemoryPresent;
|
||||
|
@ -35,6 +37,7 @@ extern struct SaveBlock2 *gSaveBlock2Ptr;
|
|||
extern struct PokemonStorage *gPokemonStoragePtr;
|
||||
|
||||
void CheckForFlashMemory(void);
|
||||
void ClearSav3(void);
|
||||
void ClearSav2(void);
|
||||
void ClearSav1(void);
|
||||
void SetSaveBlocksPointers(u16 offset);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#ifndef GUARD_SAVE_H
|
||||
#define GUARD_SAVE_H
|
||||
|
||||
// Each 4 KiB flash sector contains 3968 bytes of actual data followed by a 128 byte footer.
|
||||
// Only 12 bytes of the footer are used.
|
||||
// Each 4 KiB flash sector contains 3968 bytes of actual data followed by 116 bytes of SaveBlock3 and then 12 bytes of footer.
|
||||
#define SECTOR_DATA_SIZE 3968
|
||||
#define SECTOR_FOOTER_SIZE 128
|
||||
#define SECTOR_SIZE (SECTOR_DATA_SIZE + SECTOR_FOOTER_SIZE)
|
||||
#define SAVE_BLOCK_3_CHUNK_SIZE 116
|
||||
#define SECTOR_FOOTER_SIZE 12
|
||||
#define SECTOR_SIZE (SECTOR_DATA_SIZE + SAVE_BLOCK_3_CHUNK_SIZE + SECTOR_FOOTER_SIZE)
|
||||
|
||||
#define NUM_SAVE_SLOTS 2
|
||||
|
||||
|
@ -69,7 +69,7 @@ struct SaveSectorLocation
|
|||
struct SaveSector
|
||||
{
|
||||
u8 data[SECTOR_DATA_SIZE];
|
||||
u8 unused[SECTOR_FOOTER_SIZE - 12]; // Unused portion of the footer
|
||||
u8 saveBlock3Chunk[SAVE_BLOCK_3_CHUNK_SIZE];
|
||||
u16 id;
|
||||
u16 checksum;
|
||||
u32 signature;
|
||||
|
|
10
src/debug.c
10
src/debug.c
|
@ -2088,6 +2088,7 @@ void CheckSaveBlock1Size(struct ScriptContext *ctx)
|
|||
ConvertIntToDecimalStringN(gStringVar1, currSb1Size, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
ConvertIntToDecimalStringN(gStringVar2, maxSb1Size, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
ConvertIntToDecimalStringN(gStringVar3, maxSb1Size - currSb1Size, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
ConvertIntToDecimalStringN(gStringVar4, 1, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
}
|
||||
|
||||
void CheckSaveBlock2Size(struct ScriptContext *ctx)
|
||||
|
@ -2099,6 +2100,15 @@ void CheckSaveBlock2Size(struct ScriptContext *ctx)
|
|||
ConvertIntToDecimalStringN(gStringVar3, maxSb2Size - currSb2Size, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
}
|
||||
|
||||
void CheckSaveBlock3Size(struct ScriptContext *ctx)
|
||||
{
|
||||
u32 currSb3Size = (sizeof(struct SaveBlock3));
|
||||
u32 maxSb3Size = SAVE_BLOCK_3_CHUNK_SIZE * NUM_SECTORS_PER_SLOT;
|
||||
ConvertIntToDecimalStringN(gStringVar1, currSb3Size, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
ConvertIntToDecimalStringN(gStringVar2, maxSb3Size, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
ConvertIntToDecimalStringN(gStringVar3, maxSb3Size - currSb3Size, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
}
|
||||
|
||||
void CheckPokemonStorageSize(struct ScriptContext *ctx)
|
||||
{
|
||||
u32 currPkmnStorageSize = sizeof(struct PokemonStorage);
|
||||
|
|
|
@ -30,6 +30,7 @@ struct LoadedSaveData
|
|||
};
|
||||
|
||||
// EWRAM DATA
|
||||
EWRAM_DATA struct SaveBlock3 gSaveblock3 = {};
|
||||
EWRAM_DATA struct SaveBlock2ASLR gSaveblock2 = {0};
|
||||
EWRAM_DATA struct SaveBlock1ASLR gSaveblock1 = {0};
|
||||
EWRAM_DATA struct PokemonStorageASLR gPokemonStorage = {0};
|
||||
|
@ -41,6 +42,7 @@ EWRAM_DATA u32 gLastEncryptionKey = 0;
|
|||
bool32 gFlashMemoryPresent;
|
||||
struct SaveBlock1 *gSaveBlock1Ptr;
|
||||
struct SaveBlock2 *gSaveBlock2Ptr;
|
||||
IWRAM_INIT struct SaveBlock3 *gSaveBlock3Ptr = &gSaveblock3;
|
||||
struct PokemonStorage *gPokemonStoragePtr;
|
||||
|
||||
// code
|
||||
|
@ -57,6 +59,11 @@ void CheckForFlashMemory(void)
|
|||
}
|
||||
}
|
||||
|
||||
void ClearSav3(void)
|
||||
{
|
||||
CpuFill16(0, &gSaveblock3, sizeof(struct SaveBlock3));
|
||||
}
|
||||
|
||||
void ClearSav2(void)
|
||||
{
|
||||
CpuFill16(0, &gSaveblock2, sizeof(struct SaveBlock2ASLR));
|
||||
|
|
|
@ -158,6 +158,7 @@ void NewGameInitData(void)
|
|||
ResetPokedex();
|
||||
ClearFrontierRecord();
|
||||
ClearSav1();
|
||||
ClearSav3();
|
||||
ClearAllMail();
|
||||
gSaveBlock2Ptr->specialSaveWarpFlags = 0;
|
||||
gSaveBlock2Ptr->gcnLinkFlags = 0;
|
||||
|
|
27
src/save.c
27
src/save.c
|
@ -20,6 +20,8 @@ static u8 CopySaveSlotData(u16, struct SaveSectorLocation *);
|
|||
static u8 TryWriteSector(u8, u8 *);
|
||||
static u8 HandleWriteSector(u16, const struct SaveSectorLocation *);
|
||||
static u8 HandleReplaceSector(u16, const struct SaveSectorLocation *);
|
||||
static void CopyToSaveBlock3(u32, struct SaveSector *);
|
||||
static void CopyFromSaveBlock3(u32, struct SaveSector *);
|
||||
|
||||
// Divide save blocks into individual chunks to be written to flash sectors
|
||||
|
||||
|
@ -75,6 +77,7 @@ struct
|
|||
|
||||
// These will produce an error if a save struct is larger than the space
|
||||
// alloted for it in the flash.
|
||||
STATIC_ASSERT(sizeof(struct SaveBlock3) <= SAVE_BLOCK_3_CHUNK_SIZE * NUM_SECTORS_PER_SLOT, SaveBlock3FreeSpace);
|
||||
STATIC_ASSERT(sizeof(struct SaveBlock2) <= SECTOR_DATA_SIZE, SaveBlock2FreeSpace);
|
||||
STATIC_ASSERT(sizeof(struct SaveBlock1) <= SECTOR_DATA_SIZE * (SECTOR_ID_SAVEBLOCK1_END - SECTOR_ID_SAVEBLOCK1_START + 1), SaveBlock1FreeSpace);
|
||||
STATIC_ASSERT(sizeof(struct PokemonStorage) <= SECTOR_DATA_SIZE * (SECTOR_ID_PKMN_STORAGE_END - SECTOR_ID_PKMN_STORAGE_START + 1), PokemonStorageFreeSpace);
|
||||
|
@ -202,6 +205,8 @@ static u8 HandleWriteSector(u16 sectorId, const struct SaveSectorLocation *locat
|
|||
for (i = 0; i < size; i++)
|
||||
gReadWriteSector->data[i] = data[i];
|
||||
|
||||
CopyFromSaveBlock3(sectorId, gReadWriteSector);
|
||||
|
||||
gReadWriteSector->checksum = CalculateChecksum(data, size);
|
||||
|
||||
return TryWriteSector(sector, gReadWriteSector->data);
|
||||
|
@ -336,6 +341,8 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
|
|||
for (i = 0; i < size; i++)
|
||||
gReadWriteSector->data[i] = data[i];
|
||||
|
||||
CopyFromSaveBlock3(sectorId, gReadWriteSector);
|
||||
|
||||
gReadWriteSector->checksum = CalculateChecksum(data, size);
|
||||
|
||||
// Erase old save data
|
||||
|
@ -505,6 +512,7 @@ static u8 CopySaveSlotData(u16 sectorId, struct SaveSectorLocation *locations)
|
|||
u16 j;
|
||||
for (j = 0; j < locations[id].size; j++)
|
||||
((u8 *)locations[id].data)[j] = gReadWriteSector->data[j];
|
||||
CopyToSaveBlock3(id, gReadWriteSector);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1050,3 +1058,22 @@ void Task_LinkFullSave(u8 taskId)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 SaveBlock3Size(u32 sectorId)
|
||||
{
|
||||
s32 begin = sectorId * SAVE_BLOCK_3_CHUNK_SIZE;
|
||||
s32 end = (sectorId + 1) * SAVE_BLOCK_3_CHUNK_SIZE;
|
||||
return max(0, min(end, (s32)sizeof(gSaveblock3)) - begin);
|
||||
}
|
||||
|
||||
static void CopyToSaveBlock3(u32 sectorId, struct SaveSector *sector)
|
||||
{
|
||||
u32 size = SaveBlock3Size(sectorId);
|
||||
memcpy((u8 *)&gSaveblock3 + (sectorId * SAVE_BLOCK_3_CHUNK_SIZE), sector->saveBlock3Chunk, size);
|
||||
}
|
||||
|
||||
static void CopyFromSaveBlock3(u32 sectorId, struct SaveSector *sector)
|
||||
{
|
||||
u32 size = SaveBlock3Size(sectorId);
|
||||
memcpy(sector->saveBlock3Chunk, (u8 *)&gSaveblock3 + (sectorId * SAVE_BLOCK_3_CHUNK_SIZE), size);
|
||||
}
|
||||
|
|
|
@ -120,6 +120,7 @@ top:
|
|||
MoveSaveBlocks_ResetHeap();
|
||||
ClearSav1();
|
||||
ClearSav2();
|
||||
ClearSav3();
|
||||
|
||||
gIntrTable[7] = Intr_Timer2;
|
||||
|
||||
|
|
Loading…
Reference in a new issue