Browse Source

Add SRAM load/save support

v2
Nathaniel Walizer 7 months ago
parent
commit
1ff9634a9b
4 changed files with 79 additions and 50 deletions
  1. +1
    -0
      src/cartinfo.c
  2. +5
    -3
      src/linux/port.c
  3. +70
    -47
      src/save.c
  4. +3
    -0
      src/save.h

+ 1
- 0
src/cartinfo.c View File

@@ -1,6 +1,7 @@
#include "cart.h"
#include "cartinfo.h"
#include "port.h"
#include "save.h"


void unload_cart(Cart_Info* cart) {


+ 5
- 3
src/linux/port.c View File

@@ -320,7 +320,6 @@ int nese_frame_ready(void* plat_data) {
nese_Action action = process_events(plat->sys);
switch (action) {
case Action_Quit:
// TODO: Save SRAM
status = -1;
break;

@@ -494,7 +493,9 @@ static nese_Action nese_load_cart(platform_data* plat, const char* filename) {
unload_cart(&plat->cart);
plat->sys->cart_header = NULL;
int status = load_cart(&plat->cart, filename, plat->sys);
if (0 != status) {
if (0 == status) {
load_sram(plat->sys, filename);
} else {
char message[1024];
snprintf(message, sizeof(message), "Failed to load\n%s", filename);
action = modal_popup(plat, message, color_error);
@@ -507,7 +508,7 @@ static nese_Action select_rom(platform_data* plat, char* file, int sz_file) {
nese_Action action = Action_OK;
Menu_State menu = {0};

// TODO: Save SRAM
save_sram(plat->sys, plat->filename);

while (Action_OK == action || NULL == plat->sys->cart_header) {
action = run_rom_menu(plat, &menu, file, sz_file);
@@ -658,6 +659,7 @@ int main(int argc, char* argv[]) {
// This shall invoke menus as needed
if (0 == status) {
status = nese_start(&sys, &plat);
save_sram(&sys, plat.filename);
}

unload_cart(&plat.cart);


+ 70
- 47
src/save.c View File

@@ -26,13 +26,13 @@ static int make_filename(char* filename, int max_len,
const char* orig_base = basename(orig_name);
const char* orig_dot = strrchr(orig_base, '.');

int orig_path_len = orig_base - orig_name;

int orig_base_len = (NULL == orig_dot) ?
strlen(orig_base) :
(orig_dot - orig_base);

// Part 1/4: Leading path
/*
int orig_path_len = orig_base - orig_name;
if (0 == status && orig_path_len <= remain) {
memcpy(filename, orig_name, orig_path_len);
remain -= orig_path_len;
@@ -40,6 +40,7 @@ static int make_filename(char* filename, int max_len,
} else {
status = -1;
}
*/

// Part 2/4: Subdirectory
if (0 == status && NULL != subdir) {
@@ -56,7 +57,7 @@ static int make_filename(char* filename, int max_len,

// Part 3/4: Basename
if (0 == status && orig_base_len <= remain) {
memcpy(filename, orig_name, orig_base_len);
memcpy(filename, orig_base, orig_base_len);
remain -= orig_base_len;
filename += orig_base_len;
} else {
@@ -80,35 +81,16 @@ static int make_filename(char* filename, int max_len,
}


/* System State */

static int make_state_filename(char* save_filename, int max_len,
const char* cart_filename) {
return make_filename( save_filename, max_len,
basename(cart_filename),
"save", "nese");
}

static int state_write_size(const nes* sys) {
return serialize_size(sys, nes_serdes);
}

static int state_read(nes* sys, const void* mem, int size) {
return deserialize(sys, mem, size, nes_serdes);
}

static int state_write(const nes* sys, void* mem, int size) {
return serialize(mem, sys, size, nes_serdes);
}
/* Generic */

int load_state(nes* sys, const char* cart_filename) {
static int load( void* comp, const char* cart_filename,
const Serdes_Item* serdes, const char* dir, const char* ext) {
int size = -1;

char state_filename[FILENAME_MAX] = {0};
make_state_filename(state_filename, FILENAME_MAX - 1,
cart_filename);
char filename[FILENAME_MAX] = {0};
make_filename(filename, FILENAME_MAX - 1, cart_filename, dir, ext);

FILE* file = fopen(state_filename, "rb");
FILE* file = fopen(filename, "rb");

if (NULL != file) {
fseek(file, 0L, SEEK_END);
@@ -118,40 +100,31 @@ int load_state(nes* sys, const char* cart_filename) {
Filemap_Mode_Read);

if (NULL != mem) {
size = state_read(sys, mem, file_size);
size = deserialize(comp, mem, file_size, serdes);
nese_unmap_file(mem, file_size);
}

fclose(file);

if (file_size == size) {
nes_Mapper* mapper = &sys->core.memory.mapper;
if (mapper->init) {
size =mapper->init(mapper, NULL, &sys->core.memory);
} else {
size = 0;
}
} else {
size = -1;
}
size = (size == file_size ? 0 : -1);
}

return size;
}

int save_state(const nes* sys, const char* cart_filename) {
static int save( const void* comp, const char* cart_filename,
const Serdes_Item* serdes, const char* dir, const char* ext) {
int size = -1;

nese_mkdir("save");
nese_mkdir(dir);

char state_filename[FILENAME_MAX] = {0};
make_state_filename(state_filename, FILENAME_MAX - 1,
cart_filename);
char filename[FILENAME_MAX] = {0};
make_filename(filename, FILENAME_MAX - 1, cart_filename, dir, ext);

FILE* file = fopen(state_filename, "w+b");
FILE* file = fopen(filename, "w+b");

if (NULL != file) {
int file_size = state_write_size(sys);
int file_size = serialize_size(comp, serdes);

fseek(file, file_size - 1, SEEK_SET);
fwrite("", 1, 1, file);
@@ -161,7 +134,7 @@ int save_state(const nes* sys, const char* cart_filename) {
Filemap_Mode_Write);

if (NULL != mem) {
size = state_write(sys, mem, file_size);
size = serialize(mem, comp, file_size, serdes);
nese_unmap_file(mem, file_size);
}

@@ -172,3 +145,53 @@ int save_state(const nes* sys, const char* cart_filename) {

return size;
}


/* System State */

int load_state(nes* sys, const char* cart_filename) {
int status = load(sys, cart_filename, nes_serdes, "save", "nese");

if (0 == status) {
nes_Mapper* mapper = &sys->core.memory.mapper;
if (mapper->init) {
status = mapper->init(mapper, NULL, &sys->core.memory);
}
}

return status;
}

int save_state(const nes* sys, const char* cart_filename) {
return save(sys, cart_filename, nes_serdes, "save", "nese");
}


/* SRAM */

static const Serdes_Item sram_serdes[] = {
{"SRAM", 0, &serdes_mem, (void*)NES_SRAM_SIZE},
{0},
};

int load_sram(nes* sys, const char* cart_filename) {
int status = 0;

if (sys->cart_header && (sys->cart_header->flags_6 & ines_Flag_Battery)) {
status = load( sys->core.memory.sram, cart_filename,
sram_serdes, "sram", "sram");
}

return status;
}

int save_sram(const nes* sys, const char* cart_filename) {
int status = 0;

if (sys->cart_header && (sys->cart_header->flags_6 & ines_Flag_Battery)) {
status = save( sys->core.memory.sram, cart_filename,
sram_serdes, "sram", "sram");
}

return status;
}

+ 3
- 0
src/save.h View File

@@ -7,5 +7,8 @@
int load_state(nes*, const char* filename);
int save_state(const nes*, const char* filename);

int load_sram(nes*, const char* filename);
int save_sram(const nes*, const char* filename);


#endif // NESE_SAVE_H_

Loading…
Cancel
Save