Merge pull request #75 from negativeExponent/use_libretro_save_api

add optional support for backup saves using libretro api
This commit is contained in:
Autechre 2020-09-09 01:54:33 +02:00 committed by GitHub
commit 4a2848af48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 80 deletions

View File

@ -367,40 +367,11 @@ u32 gbc_sound_update = 0;
// If the GBC audio waveform is modified: // If the GBC audio waveform is modified:
u32 gbc_sound_wave_update = 0; u32 gbc_sound_wave_update = 0;
typedef enum
{
BACKUP_SRAM,
BACKUP_FLASH,
BACKUP_EEPROM,
BACKUP_NONE
} backup_type_type;
typedef enum
{
SRAM_SIZE_32KB,
SRAM_SIZE_64KB
} sram_size_type;
// Keep it 32KB until the upper 64KB is accessed, then make it 64KB. // Keep it 32KB until the upper 64KB is accessed, then make it 64KB.
backup_type_type backup_type = BACKUP_NONE; backup_type_type backup_type = BACKUP_NONE;
sram_size_type sram_size = SRAM_SIZE_32KB; sram_size_type sram_size = SRAM_SIZE_32KB;
typedef enum
{
FLASH_BASE_MODE,
FLASH_ERASE_MODE,
FLASH_ID_MODE,
FLASH_WRITE_MODE,
FLASH_BANKSWITCH_MODE
} flash_mode_type;
typedef enum
{
FLASH_SIZE_64KB,
FLASH_SIZE_128KB
} flash_size_type;
flash_mode_type flash_mode = FLASH_BASE_MODE; flash_mode_type flash_mode = FLASH_BASE_MODE;
u32 flash_command_position = 0; u32 flash_command_position = 0;
u8 *flash_bank_ptr = gamepak_backup; u8 *flash_bank_ptr = gamepak_backup;
@ -459,25 +430,6 @@ u8 read_backup(u32 address)
// EEPROM is 512 bytes by default; it is autodetecte as 8KB if // EEPROM is 512 bytes by default; it is autodetecte as 8KB if
// 14bit address DMAs are made (this is done in the DMA handler). // 14bit address DMAs are made (this is done in the DMA handler).
typedef enum
{
EEPROM_512_BYTE,
EEPROM_8_KBYTE
} eeprom_size_type;
typedef enum
{
EEPROM_BASE_MODE,
EEPROM_READ_MODE,
EEPROM_READ_HEADER_MODE,
EEPROM_ADDRESS_MODE,
EEPROM_WRITE_MODE,
EEPROM_WRITE_ADDRESS_MODE,
EEPROM_ADDRESS_FOOTER_MODE,
EEPROM_WRITE_FOOTER_MODE
} eeprom_mode_type;
eeprom_size_type eeprom_size = EEPROM_512_BYTE; eeprom_size_type eeprom_size = EEPROM_512_BYTE;
eeprom_mode_type eeprom_mode = EEPROM_BASE_MODE; eeprom_mode_type eeprom_mode = EEPROM_BASE_MODE;
u32 eeprom_address_length; u32 eeprom_address_length;
@ -2197,7 +2149,8 @@ u32 save_backup(char *name)
void update_backup(void) void update_backup(void)
{ {
save_backup(backup_filename); if (!use_libretro_save_method)
save_backup(backup_filename);
} }
#define CONFIG_FILENAME "game_config.txt" #define CONFIG_FILENAME "game_config.txt"
@ -2480,7 +2433,8 @@ u32 load_gamepak(const struct retro_game_info* info, const char *name)
if (p) if (p)
strcpy(p, ".sav"); strcpy(p, ".sav");
load_backup(backup_filename); if (!use_libretro_save_method)
load_backup(backup_filename);
memcpy(gamepak_title, gamepak_rom + 0xA0, 12); memcpy(gamepak_title, gamepak_rom + 0xA0, 12);
memcpy(gamepak_code, gamepak_rom + 0xAC, 4); memcpy(gamepak_code, gamepak_rom + 0xAC, 4);

View File

@ -21,6 +21,7 @@
#define MEMORY_H #define MEMORY_H
#include "libretro.h" #include "libretro.h"
extern int use_libretro_save_method;
typedef enum typedef enum
{ {
@ -215,6 +216,62 @@ extern flash_device_id_type flash_device_id;
extern const u8 *state_mem_read_ptr; extern const u8 *state_mem_read_ptr;
extern u8 *state_mem_write_ptr; extern u8 *state_mem_write_ptr;
typedef enum
{
BACKUP_SRAM,
BACKUP_FLASH,
BACKUP_EEPROM,
BACKUP_NONE
} backup_type_type;
typedef enum
{
SRAM_SIZE_32KB,
SRAM_SIZE_64KB
} sram_size_type;
typedef enum
{
FLASH_BASE_MODE,
FLASH_ERASE_MODE,
FLASH_ID_MODE,
FLASH_WRITE_MODE,
FLASH_BANKSWITCH_MODE
} flash_mode_type;
typedef enum
{
FLASH_SIZE_64KB,
FLASH_SIZE_128KB
} flash_size_type;
extern backup_type_type backup_type;
extern sram_size_type sram_size;
extern flash_size_type flash_size;
typedef enum
{
EEPROM_512_BYTE,
EEPROM_8_KBYTE
} eeprom_size_type;
typedef enum
{
EEPROM_BASE_MODE,
EEPROM_READ_MODE,
EEPROM_READ_HEADER_MODE,
EEPROM_ADDRESS_MODE,
EEPROM_WRITE_MODE,
EEPROM_WRITE_ADDRESS_MODE,
EEPROM_ADDRESS_FOOTER_MODE,
EEPROM_WRITE_FOOTER_MODE
} eeprom_mode_type;
extern eeprom_size_type eeprom_size;
extern u8 gamepak_backup[1024 * 128];
static inline void state_mem_write(const void* src, size_t size) static inline void state_mem_write(const void* src, size_t size)
{ {
memcpy(state_mem_write_ptr, src, size); memcpy(state_mem_write_ptr, src, size);

View File

@ -8,6 +8,7 @@
#include "libretro.h" #include "libretro.h"
#include "memmap.h" #include "memmap.h"
#include "gba_memory.h"
#if defined(VITA) && defined(HAVE_DYNAREC) #if defined(VITA) && defined(HAVE_DYNAREC)
#include <psp2/kernel/sysmem.h> #include <psp2/kernel/sysmem.h>
@ -73,6 +74,7 @@ struct retro_perf_callback perf_cb;
static cothread_t main_thread; static cothread_t main_thread;
static cothread_t cpu_thread; static cothread_t cpu_thread;
int dynarec_enable; int dynarec_enable;
int use_libretro_save_method = 0;
u32 idle_loop_target_pc = 0xFFFFFFFF; u32 idle_loop_target_pc = 0xFFFFFFFF;
u32 iwram_stack_optimize = 1; 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_type", "Frameskip type; off|manual|automatic" },
{ "gpsp_frameskip_value", "Frameskip value; 1|2|3|4|5|6|7|8|9" }, { "gpsp_frameskip_value", "Frameskip value; 1|2|3|4|5|6|7|8|9" },
{ "gpsp_frameskip_variation", "Frameskip variation; uniform|random" }, { "gpsp_frameskip_variation", "Frameskip variation; uniform|random" },
{ "gpsp_save_method", "Backup Save Method (Restart); gpSP|libretro" },
{ NULL, NULL }, { NULL, NULL },
}; };
@ -488,6 +491,19 @@ static void check_variables(int started_from_load)
else if (!strcmp(var.value, "random")) else if (!strcmp(var.value, "random"))
random_skip = 1; 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() static void set_input_descriptors()
@ -540,6 +556,7 @@ bool retro_load_game(const struct retro_game_info* info)
if (!info) if (!info)
return false; return false;
use_libretro_save_method = 0;
check_variables(1); check_variables(1);
set_input_descriptors(); 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."); info_msg("It is strongly recommended that you obtain the correct BIOS file.");
} }
memset(gamepak_backup, -1, sizeof(gamepak_backup));
gamepak_filename[0] = 0; gamepak_filename[0] = 0;
if (load_gamepak(info, info->path) != 0) if (load_gamepak(info, info->path) != 0)
{ {
@ -630,7 +648,6 @@ bool retro_load_game(const struct retro_game_info* info)
return true; return true;
} }
bool retro_load_game_special(unsigned game_type, bool retro_load_game_special(unsigned game_type,
const struct retro_game_info* info, size_t num_info) const struct retro_game_info* info, size_t num_info)
{ {
@ -650,43 +667,61 @@ unsigned retro_get_region(void)
void* retro_get_memory_data(unsigned id) void* retro_get_memory_data(unsigned id)
{ {
if ( id == RETRO_MEMORY_SYSTEM_RAM ) switch (id)
return ewram ; {
// switch (id) case RETRO_MEMORY_SAVE_RAM:
// { if (use_libretro_save_method)
// case RETRO_MEMORY_SAVE_RAM: return gamepak_backup;
// return gamepak_backup; break;
// } default:
break;
}
return 0; return 0;
} }
size_t retro_get_memory_size(unsigned id) size_t retro_get_memory_size(unsigned id)
{ {
switch (id)
{
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;
if ( id == RETRO_MEMORY_SYSTEM_RAM ) case BACKUP_FLASH:
return 1024 * 256 * 2 ; if(flash_size == FLASH_SIZE_64KB)
// switch (id) return 0x10000;
// { else
// case RETRO_MEMORY_SAVE_RAM: return 0x20000;
// switch(backup_type) break;
// {
// case BACKUP_SRAM:
// return sram_size;
// case BACKUP_FLASH: case BACKUP_EEPROM:
// return flash_size; if(eeprom_size == EEPROM_512_BYTE)
return 0x200;
// case BACKUP_EEPROM: else
// return eeprom_size; return 0x2000;
break;
// case BACKUP_NONE: // assume 128KB save, regardless if rom supports battery saves
// return 0x0; // this is needed because gba cannot provide initially the backup save size
// until a few cycles has passed (unless provided by a database)
// default: case BACKUP_NONE:
// return 0x8000; default:
// } return (1024 * 128);
// } break;
}
}
break;
default:
break;
}
return 0; return 0;
} }