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 "between" the original ones to keep compatibility to vanilla savegames.
Defining the space
In include/save.h
, add:
#define ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT 116
#define ADDITIONAL_SAVE_PAYLOAD_SIZE (ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT*NUM_SECTORS_PER_SLOT)
extern u8 gAdditionalSaveData[];
In src/save.c
, add (before the gSaveDataBuffer
at the start):
EWRAM_DATA u8 gAdditionalSaveData[ADDITIONAL_SAVE_PAYLOAD_SIZE];
Saving the data
Then, still in src/save.c
, add this at the end of HandleWriteSector
(right before the return
line):
for (i = 0; i < ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT; i++)
gReadWriteSector->unused[i] = gAdditionalSaveData[i + ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT * sectorId];
Also, add the exact same code again in HandleReplaceSector
, right before the EraseFlashSector(sector);
line.
Loading the data
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 < ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT; j++)
gAdditionalSaveData[j + ADDITIONAL_SAVE_PAYLOAD_SIZE_PER_SLOT * id] = gReadWriteSector->unused[j];
Accessing Variables and Flags
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 (u16*)&gAdditionalSaveData[(id - 0xF000) * 2];
...and in GetFlagPointer
, again before the last else
:
else if (id >= 0xF000)
return &gAdditionalSaveData[(id - 0xF000) / 8];
Defining Variables and Flags
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
CAVEAT
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 16 bits long (so their ID gets multiplied by 2 to get the byte offset into
gAdditionalSaveData
) - Flags are 1 bit long (ID gets divided by 8).
So, the above examples would then internally look like this (do not actually put this code anywhere, it's just to show a comparison how the data would look like):
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 you had more flags instead, or a var with ID 0xF000
(which would be at bytes 0 and 1), this would clash and corrupt your data!