From d8225bb313a19bc3b65e257401d3cf5f3eaa32e3 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sat, 5 Sep 2020 20:40:15 +0800 Subject: Add optional battery save using libretro save api - Adds core option to allow battery saves using the libretro api (retro_get_memory_data/size) - Initial save size set at 128KB and actual size is automatically determined internally by gba. - This will always assume that a save file is supported since save size or type cannot be determined until gba tries to write to backup memory. - A 128KB block of memory is used as buffer, similar method to VBA Next/Beetle GBA workarounds. Fix https://github.com/libretro/gpsp/issues/72 --- libretro.c | 102 ++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 31 deletions(-) (limited to 'libretro.c') diff --git a/libretro.c b/libretro.c index 3aacfec..b37a94e 100644 --- a/libretro.c +++ b/libretro.c @@ -8,6 +8,7 @@ #include "libretro.h" #include "memmap.h" +#include "gba_memory.h" #if defined(VITA) && defined(HAVE_DYNAREC) #include @@ -73,6 +74,7 @@ struct retro_perf_callback perf_cb; static cothread_t main_thread; static cothread_t cpu_thread; int dynarec_enable; +int use_libretro_save_method = 0; u32 idle_loop_target_pc = 0xFFFFFFFF; u32 iwram_stack_optimize = 1; @@ -332,6 +334,7 @@ void retro_set_environment(retro_environment_t cb) { "gpsp_frameskip_type", "Frameskip type; off|manual|automatic" }, { "gpsp_frameskip_value", "Frameskip value; 1|2|3|4|5|6|7|8|9" }, { "gpsp_frameskip_variation", "Frameskip variation; uniform|random" }, + { "gpsp_save_method", "Backup Save Method (Restart); gpSP|libretro" }, { NULL, NULL }, }; @@ -488,6 +491,19 @@ static void check_variables(int started_from_load) else if (!strcmp(var.value, "random")) random_skip = 1; } + + if (started_from_load) + { + var.key = "gpsp_save_method"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (!strcmp(var.value, "libretro")) + use_libretro_save_method = 1; + else + use_libretro_save_method = 0; + } + } } static void set_input_descriptors() @@ -540,6 +556,7 @@ bool retro_load_game(const struct retro_game_info* info) if (!info) return false; + use_libretro_save_method = 0; check_variables(1); set_input_descriptors(); @@ -614,6 +631,7 @@ bool retro_load_game(const struct retro_game_info* info) info_msg("It is strongly recommended that you obtain the correct BIOS file."); } + memset(gamepak_backup, -1, sizeof(gamepak_backup)); gamepak_filename[0] = 0; if (load_gamepak(info, info->path) != 0) { @@ -630,7 +648,6 @@ bool retro_load_game(const struct retro_game_info* info) return true; } - bool retro_load_game_special(unsigned game_type, const struct retro_game_info* info, size_t num_info) { @@ -650,43 +667,66 @@ unsigned retro_get_region(void) void* retro_get_memory_data(unsigned id) { - if ( id == RETRO_MEMORY_SYSTEM_RAM ) - return ewram ; - // switch (id) - // { - // case RETRO_MEMORY_SAVE_RAM: - // return gamepak_backup; - // } + switch (id) + { + case RETRO_MEMORY_SYSTEM_RAM: + return ewram; + case RETRO_MEMORY_SAVE_RAM: + if (use_libretro_save_method) + return gamepak_backup; + break; + default: + break; + } return 0; } size_t retro_get_memory_size(unsigned id) { + switch (id) + { + case RETRO_MEMORY_SYSTEM_RAM: + return 1024 * 256 * 2; - if ( id == RETRO_MEMORY_SYSTEM_RAM ) - return 1024 * 256 * 2 ; - // switch (id) - // { - // case RETRO_MEMORY_SAVE_RAM: - // switch(backup_type) - // { - // case BACKUP_SRAM: - // return sram_size; - - // case BACKUP_FLASH: - // return flash_size; - - // case BACKUP_EEPROM: - // return eeprom_size; - - // case BACKUP_NONE: - // return 0x0; - - // default: - // return 0x8000; - // } - // } + case RETRO_MEMORY_SAVE_RAM: + if (use_libretro_save_method) + { + switch(backup_type) + { + case BACKUP_SRAM: + if(sram_size == SRAM_SIZE_32KB) + return 0x8000; + else + return 0x10000; + break; + + case BACKUP_FLASH: + if(flash_size == FLASH_SIZE_64KB) + return 0x10000; + else + return 0x20000; + break; + + case BACKUP_EEPROM: + if(eeprom_size == EEPROM_512_BYTE) + return 0x200; + else + return 0x2000; + break; + // assume 128KB save, regardless if rom supports battery saves + // this is needed because gba cannot provide initially the backup save size + // until a few cycles has passed (unless provided by a database) + case BACKUP_NONE: + default: + return (1024 * 128); + break; + } + } + break; + default: + break; + } return 0; } -- cgit v1.2.3