-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Reuse filler save space for Variables and Flags
This is an alternative to Extra save space with two lines of code. The Tutorial linked above will increase the already existing SaveBlock areas, while this will instead add another one "in between" the original ones to keep compatibility to vanilla savegames.
in include/save.h
, add:
#define N_ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT 116
#define N_ADDITIONAL_SAVE_PAYLOAD_SIZE (N_ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT*NUM_SECTORS_PER_SLOT)
extern u8 gnAdditionalSaveData[];
in src/save.c
, add (before the gSaveDataBuffer
at the start):
#if NCHI__ADDITIONAL_SAVE_PAYLOAD
EWRAM_DATA u8 gnAdditionalSaveData[N_ADDITIONAL_SAVE_PAYLOAD_SIZE];
#endif
then, still in src/save.c
, add this at the end of HandleWriteSector
(right before the return
line):
for (i = 0; i < N_ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT; i++)
gReadWriteSector->unused[i] = gnAdditionalSaveData[i + N_ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT*sectorId];
also add the exact same code again in HandleReplaceSector
, right before the EraseFlashSector(sector);
line.
still in src/save.c
, add this in CopySaveSlotData
, right before the end of the if
block (and after the end of the inner for
loop):
for (j = 0; j < N_ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT; j++)
gnAdditionalSaveData[j + N_ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT*id] = gReadWriteSector->unused[j];
in src/event_data.c
, add this at the top to the includes:
#include "save.h"
then, in the same file, in GetVarPointer
, add this right before the last else
:
else if (id >= 0xF000)
return &gnAdditionalSaveData[(id - 0xF000)*2];
and in GetFlagPointer
, again before the last else
:
else if (id >= 0xF000)
return &gnAdditionalSaveData[(id - 0xF000)/8];
define them as usual in include/constants/flags.h
and include/constants/vars.h
, starting from 0xF000
:
#define FLAG_FOR_SOMETHING_SUPER_SPECIAL 0xF000
#define FLAG_FOR_SOMETHING_TOTALLY_BORING 0xF001
#define VAR_FOR_SOMETHING_SUPER_SPECIAL 0xF001
#define VAR_FOR_SOMETHING_TOTALLY_BORING 0xF002
To save on space (because I don't know what your game will need), variables and flags both share the same data space, so make sure they don't overlap.
-
Variables are 16bit long (so their ID gets multiplied by 2 to get the byte offset into
gnAdditionalSaveData
) - Flags are 1bit long (ID gets divided by 8).
so the above examples would then internally look like this:
struct{
u8 FLAG_FOR_SOMETHING_SUPER_SPECIAL : 1; // flag with ID 0xF000 at bit 0 of byte 0
u8 FLAG_FOR_SOMETHING_TOTALLY_BORING : 1; // flag with ID 0xF001 at bit 1 of byte 0
u8 filler; // an unused byte because none of the IDs maps to it
u16 VAR_FOR_SOMETHING_SUPER_SPECIAL; // var with ID 0xF001 at bytes 2 and 3
u16 VAR_FOR_SOMETHING_TOTALLY_BORING; // var with ID 0xF002 at bytes 4 and 5
};
if instead you would have more flags, or e.g. a var with ID 0xF000
(which would be at bytes 0 and 1), this would clash and corrupt your data!