mirror of https://github.com/pret/pokeemerald.git
Created Reuse filler save space for Variables and Flags (markdown)
parent
59539abda4
commit
71e035331a
|
@ -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!
|
Loading…
Reference in New Issue