Created Reuse filler save space for Variables and Flags (markdown)

Kyra Zimmer 2022-04-25 15:34:47 +02:00
parent 59539abda4
commit 71e035331a
1 changed files with 83 additions and 0 deletions

@ -0,0 +1,83 @@
This is an alternative to [Extra save space with two lines of code](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.
## Defining the space
in `include/save.h`, add:
```c
#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):
```c
#if NCHI__ADDITIONAL_SAVE_PAYLOAD
EWRAM_DATA u8 gnAdditionalSaveData[N_ADDITIONAL_SAVE_PAYLOAD_SIZE];
#endif
```
## Saving the data
then, still in `src/save.c`, add this at the end of `HandleWriteSector` (right before the `return` line):
```c
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.
## 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):
```c
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];
```
# Accessing Variables and Flags
in `src/event_data.c`, add this at the top to the includes:
```c
#include "save.h"
```
then, in the same file, in `GetVarPointer`, add this right before the last `else`:
```c
else if (id >= 0xF000)
return &gnAdditionalSaveData[(id - 0xF000)*2];
```
and in `GetFlagPointer`, again before the last `else`:
```c
else if (id >= 0xF000)
return &gnAdditionalSaveData[(id - 0xF000)/8];
```
# Defining Variables and Flags
define them as usual in `include/constants/flags.h` and `include/constants/vars.h`, starting from `0xF000`:
```c
#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 16bit long (so their ID gets multiplied by 2 to get the byte offset into `gnAdditionalSaveData`), and Flags are 1bit long (ID gets divided by 8).
so the above examples would then internally look like this:
```c
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!