Rework savestate / srm saving.

This commit is contained in:
Themaister 2011-01-18 15:34:37 +01:00
parent c7e6e73bcb
commit b381350bdc
3 changed files with 105 additions and 72 deletions

130
file.c
View File

@ -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
@ -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)
@ -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;
@ -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;
@ -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;
@ -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;
@ -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;
@ -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;
@ -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;

9
file.h
View File

@ -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);

38
ssnes.c
View File

@ -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:
@ -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:
@ -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
@ -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))
@ -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;