summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gba_memory.c54
-rw-r--r--gba_memory.h57
-rw-r--r--libretro.c102
3 files changed, 132 insertions, 81 deletions
diff --git a/gba_memory.c b/gba_memory.c
index a2d2a93..567010b 100644
--- a/gba_memory.c
+++ b/gba_memory.c
@@ -367,40 +367,11 @@ u32 gbc_sound_update = 0;
// If the GBC audio waveform is modified:
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.
backup_type_type backup_type = BACKUP_NONE;
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;
u32 flash_command_position = 0;
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
// 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_mode_type eeprom_mode = EEPROM_BASE_MODE;
u32 eeprom_address_length;
@@ -2197,7 +2149,8 @@ u32 save_backup(char *name)
void update_backup(void)
{
- save_backup(backup_filename);
+ if (!use_libretro_save_method)
+ save_backup(backup_filename);
}
#define CONFIG_FILENAME "game_config.txt"
@@ -2480,7 +2433,8 @@ u32 load_gamepak(const struct retro_game_info* info, const char *name)
if (p)
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_code, gamepak_rom + 0xAC, 4);
diff --git a/gba_memory.h b/gba_memory.h
index 630c622..f1243b5 100644
--- a/gba_memory.h
+++ b/gba_memory.h
@@ -21,6 +21,7 @@
#define MEMORY_H
#include "libretro.h"
+extern int use_libretro_save_method;
typedef enum
{
@@ -215,6 +216,62 @@ extern flash_device_id_type flash_device_id;
extern const u8 *state_mem_read_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)
{
memcpy(state_mem_write_ptr, src, size);
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 <psp2/kernel/sysmem.h>
@@ -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;
}