GBAlatro
A Demake of Balatro for the GBA
Loading...
Searching...
No Matches
save.c File Reference
#include "save.h"
#include "audio_utils.h"
#include "bitset.h"
#include "card.h"
#include "game.h"
#include "game_variables.h"
#include "joker.h"
#include "list.h"
#include "util.h"
#include "version.h"
#include <stdlib.h>
#include <string.h>

Go to the source code of this file.

Data Structures

struct  SaveHeader
 SaveHeader for validation checks to be packed and written to SRAM for validation. Defined in this discussion as follows: https://github.com/GBALATRO/balatro-gba/discussions/450. More...
 
struct  SaveOptions
 SaveOptions will only contain options data set in the Options Menu. More...
 
struct  JokerObjectSaveData
 JokerObjectSaveData will hold the minimal amount of data necessary to reconstruct a Joker. The id is a u8 in the base Joker struct, but I made it a u32 here to keep a better aligment when looking at the save file in a hex viewer. More...
 
struct  SaveGame
 SaveGame will contain the data about the current run to be saved to SRAM. GameVariables was used for this purpose at first, but some data needed to be shared but not saved, so it couldn't be dumped "as is" anymore and this struct had to be created. More...
 

Macros

#define HEADER_ADDRESS   0x0
 
#define OPTIONS_ADDRESS   0x10
 
#define GAME_ADDRESS   0x30
 
#define SAVE_SECTION_FLAG_NONE   0
 
#define SAVE_SECTION_FLAG_OPTIONS   (1 << 0)
 
#define SAVE_SECTION_FLAG_GAME   (1 << 1)
 
#define CHECK_MAGIC   0x4C414247
 
#define CHECK_HASH_SIZE   7
 
#define GIT_HASH_START   17
 
#define SAVE_LABEL_SIZE   16
 

Typedefs

typedef struct SaveHeader SaveHeader
 SaveHeader for validation checks to be packed and written to SRAM for validation. Defined in this discussion as follows: https://github.com/GBALATRO/balatro-gba/discussions/450.
 
typedef struct SaveOptions SaveOptions
 SaveOptions will only contain options data set in the Options Menu.
 
typedef struct JokerObjectSaveData JokerObjectSaveData
 JokerObjectSaveData will hold the minimal amount of data necessary to reconstruct a Joker. The id is a u8 in the base Joker struct, but I made it a u32 here to keep a better aligment when looking at the save file in a hex viewer.
 
typedef struct SaveGame SaveGame
 SaveGame will contain the data about the current run to be saved to SRAM. GameVariables was used for this purpose at first, but some data needed to be shared but not saved, so it couldn't be dumped "as is" anymore and this struct had to be created.
 

Functions

static void write_sram (u32 sram_base, const u8 *bytes, u32 size)
 Write raw binary data to SRAM.
 
static void read_sram (u32 sram_base, u8 *bytes, u32 size)
 Read raw binary data from SRAM.
 
static bool check_hash (const char *prefix)
 Checks the 7 chars of gbalatro_version after the "GBALATRO_VERSION" prefix representing the git hash of the code the build is based on.
 
static bool is_version_dirty (void)
 Determines if the current build is considered "dirty" aka has uncommitted changes. This works because the gbalatro_version string has "-dirty" added at the end if it's dirty.
 
static bool get_save_header (SaveHeader *header)
 Reads whether the save data exists and is valid.
 
static void set_save_header (u32 section_flag)
 Writes a magic number and ROM version info to SRAM to signal that the save data exists and allow the game to determine if it is compatible.
 
void save_options (void)
 Save options values to SRAM.
 
void load_options (void)
 Load options values from SRAM.
 
bool is_game_data_valid (void)
 Checks whether the SaveGame section is present and valid.
 
void save_game (void)
 Save current run data to SRAM.
 
void load_game (void)
 Load previous run data from SRAM.
 

Variables

static const SaveHeader SaveHeader_default
 Default value for the SaveHeader struct.
 
static const SaveOptions SaveOptions_default
 Default value for the SaveOptions struct, with tags already set.
 
static const SaveGame SaveGame_default
 Default value for the SaveGame struct, with tags already set.
 

Macro Definition Documentation

◆ CHECK_HASH_SIZE

#define CHECK_HASH_SIZE   7

Definition at line 34 of file save.c.

◆ CHECK_MAGIC

#define CHECK_MAGIC   0x4C414247

Definition at line 33 of file save.c.

◆ GAME_ADDRESS

#define GAME_ADDRESS   0x30

Definition at line 27 of file save.c.

◆ GIT_HASH_START

#define GIT_HASH_START   17

Definition at line 35 of file save.c.

◆ HEADER_ADDRESS

#define HEADER_ADDRESS   0x0

Definition at line 25 of file save.c.

◆ OPTIONS_ADDRESS

#define OPTIONS_ADDRESS   0x10

Definition at line 26 of file save.c.

◆ SAVE_LABEL_SIZE

#define SAVE_LABEL_SIZE   16

Definition at line 37 of file save.c.

◆ SAVE_SECTION_FLAG_GAME

#define SAVE_SECTION_FLAG_GAME   (1 << 1)

Definition at line 31 of file save.c.

◆ SAVE_SECTION_FLAG_NONE

#define SAVE_SECTION_FLAG_NONE   0

Definition at line 29 of file save.c.

◆ SAVE_SECTION_FLAG_OPTIONS

#define SAVE_SECTION_FLAG_OPTIONS   (1 << 0)

Definition at line 30 of file save.c.

Typedef Documentation

◆ SaveGame

typedef struct SaveGame SaveGame

SaveGame will contain the data about the current run to be saved to SRAM. GameVariables was used for this purpose at first, but some data needed to be shared but not saved, so it couldn't be dumped "as is" anymore and this struct had to be created.

word Byte 0 Byte 1 Byte 2 Byte 3 name purpose
0 '-' 'I' 'N' 'T' TAG Spells "-INTERNAL DATA -"
1 'E' 'R' 'N' 'A' - -
2 'L' ' ' 'D' 'A' - -
3 'T' 'A' ' ' '-' - -
4 T[0] T[1] T[2] T[3] GLOB TIMER The global timer used for animations thoughout the game
5 RNG[0] RNG[1] RNG[2] RNG[3] RNG INFO RNG Info struct, containing the seed used for RNG, either randomly shuffled or chosen by the player
6 RNG[4] RNG[5] RNG[6] RNG[7] - at game start, and the current position in the RNG sequence for the given seed, since the start of the run
7 RND[0] RND[1] RND[2] RND[3] ROUND What Round we are about to start
8 ANT[0] ANT[1] ANT[2] ANT[3] ANTE What Ante we are on
9 MNY[0] MNY[1] MNY[2] MNY[3] MONEY How much money we currently have left
10 UNDEF UNDEF UNDEF UNDEF PADDING Some padding
11 UNDEF UNDEF UNDEF UNDEF - -
12 '-' ' ' 'O' 'W' TAG Spells "- OWNED JOKERS -"
13 'N' 'E' 'D' ' ' - -
14 'J' 'O' 'K' 'E' - -
15 'R' 'S' ' ' '-' - -
16 ID[0] ID[1] ID[2] ID[3] JOKER DATA 0 Minimal necessary data to reconstruct a JokerObject
17 STT[0] STT[1] STT[2] STT[3] - Contains the Joker's id and persistent_state
... ... ... ... ... ... ...
... ... ... ... ... ... ...
?? '_' 'E' 'N' 'D' END_TAG Spells "_END", marks the end of the savefile

◆ SaveHeader

typedef struct SaveHeader SaveHeader

SaveHeader for validation checks to be packed and written to SRAM for validation. Defined in this discussion as follows: https://github.com/GBALATRO/balatro-gba/discussions/450.

word Byte 0 Byte 1 Byte 2 Byte 3 name purpose
0 0x47 0x42 0x41 0x4C MAGIC Identify if proceeding data is valid and not junk, spells "GBAL"
1 Dirty H[0] H[1] H[2] GITHASH_LOW Dirty flag, followed by the first 3 bytes of shortened git hash H
2 H[3] H[4] H[5] H[6] GITHASH_HIGH Last 4 bytes of shortened git hash H, with a dirty flag
3 SEC[0] SEC[1] SEC[2] SEC[3] VALID_SCTNS Identifies whether each section of the save data is valid or not

◆ SaveOptions

typedef struct SaveOptions SaveOptions

SaveOptions will only contain options data set in the Options Menu.

word Byte 0 Byte 1 Byte 2 Byte 3 name purpose
0 '-' ' ' 'O' 'P' TAG Pretty tag to clearly visualize the Options section in a hex viewer
1 'T' 'I' 'O' 'N' - Spells "- OPTIONS DATA -"
2 'S' ' ' 'D' 'A' - -
3 'T' 'A' ' ' '-' - -
4 SPEED CNTRST READBL MUSIC OPTN_VALUES All 5 option values, followed by some padding,
5 SOUND UNDEF UNDEF UNDEF - so that the next section starts at the beginning of the
6 UNDEF UNDEF UNDEF UNDEF - next 4-word row in a hex viewer
7 UNDEF UNDEF UNDEF UNDEF - -

Function Documentation

◆ check_hash()

static bool check_hash ( const char *  prefix)
inlinestatic

Checks the 7 chars of gbalatro_version after the "GBALATRO_VERSION" prefix representing the git hash of the code the build is based on.

Returns
true if the git hash of the ROM is equal to the hash saved in SRAM. false if they are different.

Definition at line 234 of file save.c.

◆ get_save_header()

static bool get_save_header ( SaveHeader header)
inlinestatic

Reads whether the save data exists and is valid.

Parameters
headerpointer to the SaveHeader struct to fill
Returns
true if the save data is valid, false if not

Definition at line 265 of file save.c.

◆ is_game_data_valid()

bool is_game_data_valid ( void  )

Checks whether the SaveGame section is present and valid.

Returns
true if it is, false if not.

Definition at line 335 of file save.c.

◆ is_version_dirty()

static bool is_version_dirty ( void  )
inlinestatic

Determines if the current build is considered "dirty" aka has uncommitted changes. This works because the gbalatro_version string has "-dirty" added at the end if it's dirty.

Returns
true if version is dirty, false otherwise.

Definition at line 254 of file save.c.

◆ load_game()

void load_game ( void  )

Load previous run data from SRAM.

See also
save_game

Definition at line 378 of file save.c.

◆ load_options()

void load_options ( void  )

Load options values from SRAM.

See also
save_options

Definition at line 316 of file save.c.

◆ read_sram()

static void read_sram ( u32  sram_base,
u8 *  bytes,
u32  size 
)
inlinestatic

Read raw binary data from SRAM.

See also
write_sram

Definition at line 216 of file save.c.

◆ save_game()

void save_game ( void  )

Save current run data to SRAM.

Definition at line 341 of file save.c.

◆ save_options()

void save_options ( void  )

Save options values to SRAM.

Definition at line 302 of file save.c.

◆ set_save_header()

static void set_save_header ( u32  section_flag)
inlinestatic

Writes a magic number and ROM version info to SRAM to signal that the save data exists and allow the game to determine if it is compatible.

This will read the SaveHeader first and check if the data is valid. If yes, the valid_sections will be updated, if not, it will be overwritten and start from SAVE_SECTION_FLAG_NONE.

Parameters
section_flagThe section flag to be set to 1, corresponds to the section we're writing to SRAM.

Definition at line 283 of file save.c.

◆ write_sram()

static void write_sram ( u32  sram_base,
const u8 *  bytes,
u32  size 
)
inlinestatic

Write raw binary data to SRAM.

Parameters
sram_baseaddress written to in the SRAM
bytespointer to the written data
sizenumber of bytes written

Definition at line 200 of file save.c.

Variable Documentation

◆ SaveGame_default

const SaveGame SaveGame_default
static
Initial value:
= {
.tag_internal = "-INTERNAL DATA -",
.timer = 0,
.rng_info = {0, {0}},
.round = 0,
.ante = 0,
.money = 0,
.padding = {UNDEFINED, UNDEFINED},
.tag_jokers = "- OWNED JOKERS -",
.jokers_data = {},
.tag_end = "_END"
}

Default value for the SaveGame struct, with tags already set.

Definition at line 178 of file save.c.

◆ SaveHeader_default

const SaveHeader SaveHeader_default
static
Initial value:
= {
.magic = CHECK_MAGIC,
.dirty = false,
.githash = "fffffff",
.valid_sections = SAVE_SECTION_FLAG_NONE
}

Default value for the SaveHeader struct.

Definition at line 63 of file save.c.

◆ SaveOptions_default

const SaveOptions SaveOptions_default
static
Initial value:
= {
.tag_options = "- OPTIONS DATA -",
.game_speed = GAME_SPEED_MIN,
.cards_high_contrast = DEFAULT_HIGH_CONTRAST,
.cards_more_readable = DEFAULT_MORE_READABLE,
.music_volume = VOLUME_OPTION_MAX,
.sound_volume = VOLUME_OPTION_MAX,
.padding = {
UNDEFINED, UNDEFINED, UNDEFINED,
UNDEFINED, UNDEFINED, UNDEFINED,
UNDEFINED, UNDEFINED, UNDEFINED,
UNDEFINED, UNDEFINED
}
}

Default value for the SaveOptions struct, with tags already set.

Definition at line 101 of file save.c.