Skip to content

Commit

Permalink
Rework savestate / srm saving.
Browse files Browse the repository at this point in the history
  • Loading branch information
Themaister committed Jan 18, 2011
1 parent c7e6e73 commit b381350
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 72 deletions.
130 changes: 87 additions & 43 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
#include <string.h>
#include "dynamic.h"

ssize_t read_file(FILE* file, void** buf)
// Load SNES rom only. Applies a hack for headered ROMs.
static ssize_t read_rom_file(FILE* file, void** buf)
{
ssize_t ret;
if (file == NULL) // stdin
Expand Down Expand Up @@ -96,74 +97,117 @@ ssize_t read_file(FILE* file, void** buf)
return ret;
}

void write_file(const char* path, uint8_t* data, size_t size)
// Generic file loader.
static ssize_t read_file(const char *path, void **buf)
{
FILE *file = fopen(path, "wb");
if ( file != NULL )
void *rom_buf = NULL;
FILE *file = fopen(path, "rb");
if (!file)
{
SSNES_LOG("Saving state \"%s\". Size: %d bytes.\n", path, (int)size);
psnes_serialize(data, size);
if ( fwrite(data, 1, size, file) != size )
SSNES_ERR("Did not save state properly.\n");
fclose(file);
SSNES_ERR("Couldn't open file: \"%s\"\n", path);
goto error;
}

fseek(file, 0, SEEK_END);
long len = ftell(file);
ssize_t rc = 0;
rewind(file);
rom_buf = malloc(len);
if (!rom_buf)
{
SSNES_ERR("Couldn't allocate memory!\n");
goto error;
}

if ((rc = fread(rom_buf, 1, len, file)) < len)
SSNES_WARN("Didn't read whole file.\n");

*buf = rom_buf;
fclose(file);
return rc;

error:
if (file)
fclose(file);
free(rom_buf);
*buf = NULL;
return -1;
}

void load_state(const char* path, uint8_t* data, size_t size)
// Dump stuff to file.
static void dump_to_file(const char *path, const void *data, size_t size)
{
SSNES_LOG("Loading state: \"%s\".\n", path);
FILE *file = fopen(path, "rb");
if ( file != NULL )
FILE *file = fopen(path, "wb");
if (!file)
{
//fprintf(stderr, "SSNES: Loading state. Size: %d bytes.\n", (int)size);
if ( fread(data, 1, size, file) != size )
SSNES_ERR("Did not load state properly.\n");
fclose(file);
psnes_unserialize(data, size);
SSNES_ERR("Couldn't dump to file %s\n", path);
}
else
{
SSNES_LOG("No state file found. Will create new.\n");
fwrite(data, 1, size, file);
fclose(file);
}
}

void load_save_file(const char* path, int type)
void save_state(const char* path)
{
FILE *file;
SSNES_LOG("Saving state: \"%s\".\n", path);
size_t size = psnes_serialize_size();
if (size == 0)
return;

file = fopen(path, "rb");
if ( !file )
void *data = malloc(size);
if (!data)
{
SSNES_ERR("Failed to allocate memory for save state buffer.\n");
return;
}

SSNES_LOG("State size: %d bytes.\n", (int)size);
psnes_serialize(data, size);
dump_to_file(path, data, size);
free(data);
}

void load_state(const char* path)
{
SSNES_LOG("Loading state: \"%s\".\n", path);
void *buf = NULL;
ssize_t size = read_file(path, &buf);
if (size < 0)
SSNES_ERR("Failed to load state.\n");
else
{
SSNES_LOG("State size: %d bytes.\n", (int)size);
psnes_unserialize(buf, size);
}

free(buf);
}

void load_ram_file(const char* path, int type)
{
size_t size = psnes_get_memory_size(type);
uint8_t *data = psnes_get_memory_data(type);

if (size == 0 || !data)
{
fclose(file);
return;
}

int rc = fread(data, 1, size, file);
if ( rc != size )
{
SSNES_ERR("Couldn't load save file.\n");
}
void *buf = NULL;
ssize_t rc = read_file(path, &buf);
if (rc <= size)
memcpy(data, buf, size);

SSNES_LOG("Loaded save file: \"%s\"\n", path);

fclose(file);
free(buf);
}

void save_file(const char* path, int type)
void save_ram_file(const char* path, int type)
{
size_t size = psnes_get_memory_size(type);
uint8_t *data = psnes_get_memory_data(type);

if ( data && size > 0 )
write_file(path, data, size);
dump_to_file(path, data, size);
}

static bool load_sgb_rom(void)
Expand All @@ -175,7 +219,7 @@ static bool load_sgb_rom(void)
void *extra_rom_buf = NULL;
ssize_t extra_rom_len = 0;

if ((rom_len = read_file(g_extern.rom_file, &rom_buf)) == -1)
if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1)
{
SSNES_ERR("Could not read ROM file.\n");
goto error;
Expand All @@ -188,7 +232,7 @@ static bool load_sgb_rom(void)
goto error;
}

if ((extra_rom_len = read_file(extra_rom, &extra_rom_buf)) == -1)
if ((extra_rom_len = read_rom_file(extra_rom, &extra_rom_buf)) == -1)
{
SSNES_ERR("Cannot read GameBoy rom.\n");
goto error;
Expand Down Expand Up @@ -229,7 +273,7 @@ static bool load_bsx_rom(bool slotted)
void *extra_rom_buf = NULL;
ssize_t extra_rom_len = 0;

if ((rom_len = read_file(g_extern.rom_file, &rom_buf)) == -1)
if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1)
{
SSNES_ERR("Could not read ROM file.\n");
goto error;
Expand All @@ -242,7 +286,7 @@ static bool load_bsx_rom(bool slotted)
goto error;
}

if ((extra_rom_len = read_file(extra_rom, &extra_rom_buf)) == -1)
if ((extra_rom_len = read_rom_file(extra_rom, &extra_rom_buf)) == -1)
{
SSNES_ERR("Cannot read BSX game rom.\n");
goto error;
Expand Down Expand Up @@ -297,7 +341,7 @@ static bool load_sufami_rom(void)
void *extra_rom_buf[2] = {NULL};
ssize_t extra_rom_len[2] = {0};

if ((rom_len = read_file(g_extern.rom_file, &rom_buf)) == -1)
if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1)
{
SSNES_ERR("Could not read ROM file.\n");
goto error;
Expand All @@ -316,7 +360,7 @@ static bool load_sufami_rom(void)
goto error;
}

if ((extra_rom_len[i] = read_file(extra_rom[i], &extra_rom_buf[i])) == -1)
if ((extra_rom_len[i] = read_rom_file(extra_rom[i], &extra_rom_buf[i])) == -1)
{
SSNES_ERR("Cannot read BSX game rom.\n");
goto error;
Expand Down Expand Up @@ -363,7 +407,7 @@ static bool load_normal_rom(void)
void *rom_buf = NULL;
ssize_t rom_len = 0;

if ((rom_len = read_file(g_extern.rom_file, &rom_buf)) == -1)
if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1)
{
SSNES_ERR("Could not read ROM file.\n");
return false;
Expand Down
9 changes: 4 additions & 5 deletions file.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@
#include <sys/types.h>
#include "general.h"

ssize_t read_file(FILE *file, void **buf);
void load_state(const char* path);
void save_state(const char* path);

void load_state(const char* path, uint8_t* data, size_t size);
void write_file(const char* path, uint8_t* data, size_t size);
void load_save_file(const char* path, int type);
void save_file(const char* path, int type);
void load_ram_file(const char* path, int type);
void save_ram_file(const char* path, int type);

bool init_rom_file(enum ssnes_game_type type);

Expand Down
38 changes: 14 additions & 24 deletions ssnes.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,19 +489,19 @@ static inline void load_save_files(void)
{
case SSNES_CART_NORMAL:
case SSNES_CART_SGB:
load_save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
load_save_file(g_extern.savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
load_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
load_ram_file(g_extern.savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
break;

case SSNES_CART_BSX:
case SSNES_CART_BSX_SLOTTED:
load_save_file(g_extern.savefile_name_srm, SNES_MEMORY_BSX_RAM);
load_save_file(g_extern.savefile_name_psrm, SNES_MEMORY_BSX_PRAM);
load_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_BSX_RAM);
load_ram_file(g_extern.savefile_name_psrm, SNES_MEMORY_BSX_PRAM);
break;

case SSNES_CART_SUFAMI:
load_save_file(g_extern.savefile_name_asrm, SNES_MEMORY_SUFAMI_TURBO_A_RAM);
load_save_file(g_extern.savefile_name_bsrm, SNES_MEMORY_SUFAMI_TURBO_B_RAM);
load_ram_file(g_extern.savefile_name_asrm, SNES_MEMORY_SUFAMI_TURBO_A_RAM);
load_ram_file(g_extern.savefile_name_bsrm, SNES_MEMORY_SUFAMI_TURBO_B_RAM);
break;

default:
Expand All @@ -515,19 +515,19 @@ static inline void save_files(void)
{
case SSNES_CART_NORMAL:
case SSNES_CART_SGB:
save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
save_file(g_extern.savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
save_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
save_ram_file(g_extern.savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
break;

case SSNES_CART_BSX:
case SSNES_CART_BSX_SLOTTED:
save_file(g_extern.savefile_name_srm, SNES_MEMORY_BSX_RAM);
save_file(g_extern.savefile_name_psrm, SNES_MEMORY_BSX_PRAM);
save_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_BSX_RAM);
save_ram_file(g_extern.savefile_name_psrm, SNES_MEMORY_BSX_PRAM);
break;

case SSNES_CART_SUFAMI:
save_file(g_extern.savefile_name_asrm, SNES_MEMORY_SUFAMI_TURBO_A_RAM);
save_file(g_extern.savefile_name_bsrm, SNES_MEMORY_SUFAMI_TURBO_B_RAM);
save_ram_file(g_extern.savefile_name_asrm, SNES_MEMORY_SUFAMI_TURBO_A_RAM);
save_ram_file(g_extern.savefile_name_bsrm, SNES_MEMORY_SUFAMI_TURBO_B_RAM);
break;

default:
Expand Down Expand Up @@ -626,14 +626,6 @@ int main(int argc, char *argv[])

init_controllers();

unsigned serial_size = psnes_serialize_size();
uint8_t *serial_data = malloc(serial_size);
if (serial_data == NULL)
{
SSNES_ERR("Failed to allocate memory for states!\n");
goto error;
}

load_save_files();

#ifdef HAVE_FFMPEG
Expand All @@ -652,9 +644,9 @@ int main(int argc, char *argv[])

// Save or load state here.
if (driver.input->key_pressed(driver.input_data, SSNES_SAVE_STATE_KEY))
write_file(g_extern.savestate_name, serial_data, serial_size);
save_state(g_extern.savestate_name);
else if (driver.input->key_pressed(driver.input_data, SSNES_LOAD_STATE_KEY))
load_state(g_extern.savestate_name, serial_data, serial_size);
load_state(g_extern.savestate_name);

// If we go fullscreen we drop all drivers and reinit to be safe.
else if (driver.input->key_pressed(driver.input_data, SSNES_FULLSCREEN_TOGGLE_KEY))
Expand All @@ -672,13 +664,11 @@ int main(int argc, char *argv[])
deinit_recording();
#endif

// Flush out SRAM (and RTC)
save_files();

psnes_unload_cartridge();
psnes_term();
uninit_drivers();
free(serial_data);
uninit_dlsym();

return 0;
Expand Down

0 comments on commit b381350

Please sign in to comment.