Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save-compatible SaveBlock3 #4112

Merged
merged 4 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions data/scripts/debug.inc
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,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
Expand All @@ -137,6 +139,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.$"
Expand Down
6 changes: 6 additions & 0 deletions include/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ struct UCoords32
u32 y;
};

struct SaveBlock3
{
};

extern struct SaveBlock3 *gSaveBlock3Ptr;

struct Time
{
/*0x00*/ s16 days;
Expand Down
3 changes: 3 additions & 0 deletions include/load_save.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GUARD_LOAD_SAVE_H

#include "pokemon_storage_system.h"
#include "save.h"

#define SAVEBLOCK_MOVE_RANGE 128

Expand All @@ -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;
Expand All @@ -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);
Expand Down
10 changes: 5 additions & 5 deletions include/save.h
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions src/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -2071,6 +2071,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)
Expand All @@ -2082,6 +2083,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);
Expand Down
7 changes: 7 additions & 0 deletions src/load_save.c
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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
Expand All @@ -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));
Expand Down
1 change: 1 addition & 0 deletions src/new_game.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ void NewGameInitData(void)
ResetPokedex();
ClearFrontierRecord();
ClearSav1();
ClearSav3();
ClearAllMail();
gSaveBlock2Ptr->specialSaveWarpFlags = 0;
gSaveBlock2Ptr->gcnLinkFlags = 0;
Expand Down
27 changes: 27 additions & 0 deletions src/save.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions test/test_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ void CB2_TestRunner(void)
MoveSaveBlocks_ResetHeap();
ClearSav1();
ClearSav2();
ClearSav3();

gIntrTable[7] = Intr_Timer2;

Expand Down
Loading