implement retro_serialize/unserialize

This commit is contained in:
aliaspider 2014-12-10 11:06:17 +01:00
parent 13d5e9c875
commit ad485d434a
15 changed files with 184 additions and 236 deletions

View File

@ -210,7 +210,7 @@ include Makefile.common
OBJECTS := $(SOURCES_C:.c=.o) $(SOURCES_ASM:.S=.o)
DEFINES = -DHAVE_STRINGS_H -DHAVE_STDINT_H -DHAVE_INTTYPES_H -D__LIBRETRO__ -DINLINE=inline -DPC_BUILD -Wall
DEFINES = -DHAVE_STRINGS_H -DHAVE_STDINT_H -DHAVE_INTTYPES_H -D__LIBRETRO__ -DINLINE=inline -DPC_BUILD -Wall -Werror=implicit-function-declaration
ifeq ($(CPU_ARCH), arm)
DEFINES += -DARM_ARCH

View File

@ -49,18 +49,6 @@
// Huge thanks to pollux for the heads up on using native file I/O
// functions on PSP for vastly improved memstick performance.
#define file_write_mem(filename_tag, buffer, size) \
{ \
memcpy(write_mem_ptr, buffer, size); \
write_mem_ptr += size; \
} \
#define file_write_mem_array(filename_tag, array) \
file_write_mem(filename_tag, array, sizeof(array)) \
#define file_write_mem_variable(filename_tag, variable) \
file_write_mem(filename_tag, &variable, sizeof(variable)) \
#ifdef PSP_BUILD
#define fastcall

19
cpu.c
View File

@ -4428,14 +4428,13 @@ void move_reg(u32 *new_reg)
}
#define cpu_savestate_builder(type) \
void cpu_##type##_savestate(file_tag_type savestate_file) \
{ \
file_##type(savestate_file, reg, 0x100); \
file_##type##_array(savestate_file, spsr); \
file_##type##_array(savestate_file, reg_mode); \
} \
cpu_savestate_builder(read);
cpu_savestate_builder(write_mem);
#define cpu_savestate_builder(type) \
void cpu_##type##_savestate(void) \
{ \
state_mem_##type(reg, 0x100); \
state_mem_##type##_array(spsr); \
state_mem_##type##_array(reg_mode); \
}
cpu_savestate_builder(read)
cpu_savestate_builder(write)

4
cpu.h
View File

@ -126,8 +126,8 @@ void function_cc execute_store_u16(u32 address, u32 source);
void function_cc execute_store_u32(u32 address, u32 source);
u32 function_cc execute_arm_translate(u32 cycles);
void init_translater();
void cpu_write_mem_savestate(file_tag_type savestate_file);
void cpu_read_savestate(file_tag_type savestate_file);
void cpu_write_savestate(void);
void cpu_read_savestate(void);
u8 function_cc *block_lookup_address_arm(u32 pc);
u8 function_cc *block_lookup_address_thumb(u32 pc);

View File

@ -3405,152 +3405,104 @@ void bios_region_read_protect()
}
#define savestate_block(type) \
cpu_##type##_savestate(savestate_file); \
input_##type##_savestate(savestate_file); \
main_##type##_savestate(savestate_file); \
memory_##type##_savestate(savestate_file); \
sound_##type##_savestate(savestate_file); \
video_##type##_savestate(savestate_file) \
#define savestate_block(type) \
cpu_##type##_savestate(); \
input_##type##_savestate(); \
main_##type##_savestate(); \
memory_##type##_savestate(); \
sound_##type##_savestate(); \
video_##type##_savestate()
void gba_load_state(char *savestate_filename)
const u8 *state_mem_read_ptr;
u8 *state_mem_write_ptr;
void gba_load_state(const void* src)
{
file_open(savestate_file, savestate_filename, read);
if(file_check_valid(savestate_file))
{
char current_gamepak_filename[512];
u32 i;
u32 current_color;
u32 i;
u32 current_color;
file_seek(savestate_file, (240 * 160 * 2) + sizeof(time_t), SEEK_SET);
state_mem_read_ptr = src;
savestate_block(read);
strcpy(current_gamepak_filename, gamepak_filename);
flush_translation_cache_ram();
flush_translation_cache_rom();
flush_translation_cache_bios();
savestate_block(read);
oam_update = 1;
gbc_sound_update = 1;
file_close(savestate_file);
flush_translation_cache_ram();
flush_translation_cache_rom();
flush_translation_cache_bios();
oam_update = 1;
gbc_sound_update = 1;
if(strcmp(current_gamepak_filename, gamepak_filename))
{
u32 dot_position = strcspn(current_gamepak_filename, ".");
// We'll let it slide if the filenames of the savestate and
// the gamepak are similar enough.
strcpy(gamepak_filename, current_gamepak_filename);
if(strncmp(savestate_filename, current_gamepak_filename, dot_position))
{
if(load_gamepak(gamepak_filename) != -1)
{
reset_gba();
// Okay, so this takes a while, but for now it works.
gba_load_state(savestate_filename);
}
else
{
quit();
}
return;
}
}
for(i = 0; i < 512; i++)
{
for(i = 0; i < 512; i++)
{
current_color = palette_ram[i];
palette_ram_converted[i] =
convert_palette(current_color);
}
}
// Oops, these contain raw pointers
for(i = 0; i < 4; i++)
{
// Oops, these contain raw pointers
for(i = 0; i < 4; i++)
gbc_sound_channel[i].sample_data = square_pattern_duty[2];
}
current_debug_state = STEP;
instruction_count = 0;
reg[CHANGED_PC_STATUS] = 1;
}
current_debug_state = STEP;
instruction_count = 0;
reg[CHANGED_PC_STATUS] = 1;
}
u8 savestate_write_buffer[506947];
u8 *write_mem_ptr;
void gba_save_state(char *savestate_filename, u16 *screen_capture)
void gba_save_state(void* dst)
{
write_mem_ptr = savestate_write_buffer;
file_open(savestate_file, savestate_filename, write);
if(file_check_valid(savestate_file))
{
time_t current_time;
file_write_mem(savestate_file, screen_capture, 240 * 160 * 2);
time(&current_time);
file_write_mem_variable(savestate_file, current_time);
savestate_block(write_mem);
file_write(savestate_file, savestate_write_buffer,
sizeof(savestate_write_buffer));
file_close(savestate_file);
}
state_mem_write_ptr = dst;
savestate_block(write);
}
#define memory_savestate_builder(type) \
void memory_##type##_savestate(file_tag_type savestate_file) \
{ \
u32 i; \
\
file_##type##_variable(savestate_file, backup_type); \
file_##type##_variable(savestate_file, sram_size); \
file_##type##_variable(savestate_file, flash_mode); \
file_##type##_variable(savestate_file, flash_command_position); \
file_##type##_variable(savestate_file, flash_bank_ptr); \
file_##type##_variable(savestate_file, flash_device_id); \
file_##type##_variable(savestate_file, flash_manufacturer_id); \
file_##type##_variable(savestate_file, flash_size); \
file_##type##_variable(savestate_file, eeprom_size); \
file_##type##_variable(savestate_file, eeprom_mode); \
file_##type##_variable(savestate_file, eeprom_address_length); \
file_##type##_variable(savestate_file, eeprom_address); \
file_##type##_variable(savestate_file, eeprom_counter); \
file_##type##_variable(savestate_file, rtc_state); \
file_##type##_variable(savestate_file, rtc_write_mode); \
file_##type##_array(savestate_file, rtc_registers); \
file_##type##_variable(savestate_file, rtc_command); \
file_##type##_array(savestate_file, rtc_data); \
file_##type##_variable(savestate_file, rtc_status); \
file_##type##_variable(savestate_file, rtc_data_bytes); \
file_##type##_variable(savestate_file, rtc_bit_count); \
file_##type##_array(savestate_file, eeprom_buffer); \
file_##type##_array(savestate_file, gamepak_filename); \
file_##type##_array(savestate_file, dma); \
\
file_##type(savestate_file, iwram + 0x8000, 0x8000); \
for(i = 0; i < 8; i++) \
{ \
file_##type(savestate_file, ewram + (i * 0x10000) + 0x8000, 0x8000); \
} \
file_##type(savestate_file, vram, 0x18000); \
file_##type(savestate_file, oam_ram, 0x400); \
file_##type(savestate_file, palette_ram, 0x400); \
file_##type(savestate_file, io_registers, 0x8000); \
\
/* This is a hack, for now. */ \
if((flash_bank_ptr < gamepak_backup) || \
(flash_bank_ptr > (gamepak_backup + (1024 * 64)))) \
{ \
flash_bank_ptr = gamepak_backup; \
} \
} \
#define memory_savestate_builder(type) \
void memory_##type##_savestate(void) \
{ \
u32 i; \
\
state_mem_##type##_variable(backup_type); \
state_mem_##type##_variable(sram_size); \
state_mem_##type##_variable(flash_mode); \
state_mem_##type##_variable(flash_command_position); \
state_mem_##type##_variable(flash_bank_ptr); \
state_mem_##type##_variable(flash_device_id); \
state_mem_##type##_variable(flash_manufacturer_id); \
state_mem_##type##_variable(flash_size); \
state_mem_##type##_variable(eeprom_size); \
state_mem_##type##_variable(eeprom_mode); \
state_mem_##type##_variable(eeprom_address_length); \
state_mem_##type##_variable(eeprom_address); \
state_mem_##type##_variable(eeprom_counter); \
state_mem_##type##_variable(rtc_state); \
state_mem_##type##_variable(rtc_write_mode); \
state_mem_##type##_array(rtc_registers); \
state_mem_##type##_variable(rtc_command); \
state_mem_##type##_array(rtc_data); \
state_mem_##type##_variable(rtc_status); \
state_mem_##type##_variable(rtc_data_bytes); \
state_mem_##type##_variable(rtc_bit_count); \
state_mem_##type##_array(eeprom_buffer); \
state_mem_##type##_array(dma); \
\
state_mem_##type(iwram + 0x8000, 0x8000); \
for(i = 0; i < 8; i++) \
{ \
state_mem_##type(ewram + (i * 0x10000) + 0x8000, 0x8000); \
} \
state_mem_##type(vram, 0x18000); \
state_mem_##type(oam_ram, 0x400); \
state_mem_##type(palette_ram, 0x400); \
state_mem_##type(io_registers, 0x8000); \
\
/* This is a hack, for now. */ \
if((flash_bank_ptr < gamepak_backup) || \
(flash_bank_ptr > (gamepak_backup + (1024 * 64)))) \
{ \
flash_bank_ptr = gamepak_backup; \
} \
}
memory_savestate_builder(read);
memory_savestate_builder(write_mem);
memory_savestate_builder(read)
memory_savestate_builder(write)

View File

@ -186,10 +186,6 @@ void memory_term(void);
void bios_region_read_allow();
void bios_region_read_protect();
u8 *load_gamepak_page(u32 physical_index);
void memory_write_mem_savestate(file_tag_type savestate_file);
void memory_read_savestate(file_tag_type savestate_file);
void gba_load_state(char *savestate_filename);
void gba_save_state(char *savestate_filename, u16 *screen_capture);
extern u8 *gamepak_rom;
extern u32 gamepak_ram_buffer_size;
@ -198,8 +194,6 @@ extern u32 gbc_sound_update;
extern u32 gbc_sound_wave_update;
extern dma_transfer_type dma[4];
extern u8 *write_mem_ptr;
extern u16 palette_ram[512];
extern u16 oam_ram[512];
extern u16 palette_ram_converted[512];
@ -217,4 +211,32 @@ extern u8 *memory_map_write[8 * 1024];
extern flash_device_id_type flash_device_id;
extern const u8 *state_mem_read_ptr;
extern u8 *state_mem_write_ptr;
static inline void state_mem_write(const void* src, size_t size)
{
memcpy(state_mem_write_ptr, src, size);
state_mem_write_ptr += size;
}
#define GBA_STATE_MEM_SIZE 429640
#define state_mem_write_array(array) state_mem_write(array, sizeof(array))
#define state_mem_write_variable(variable) state_mem_write(&variable, sizeof(variable))
static inline void state_mem_read(void* dst, size_t size)
{
memcpy(dst, state_mem_read_ptr, size);
state_mem_read_ptr += size;
}
#define state_mem_read_array(array) state_mem_read(array, sizeof(array))
#define state_mem_read_variable(variable) state_mem_read(&variable, sizeof(variable))
void memory_write_savestate(void);
void memory_read_savestate(void);
void gba_load_state(const void *src);
void gba_save_state(void *dst);
#endif

15
input.c
View File

@ -88,12 +88,11 @@ u32 update_input(void)
return 0;
}
#define input_savestate_builder(type) \
void input_##type##_savestate(file_tag_type savestate_file) \
{ \
file_##type##_variable(savestate_file, key); \
} \
input_savestate_builder(read);
input_savestate_builder(write_mem);
#define input_savestate_builder(type) \
void input_##type##_savestate(void) \
{ \
state_mem_##type##_variable(key); \
}
input_savestate_builder(read)
input_savestate_builder(write)

View File

@ -77,8 +77,8 @@ typedef enum
void init_input();
u32 update_input();
void input_write_mem_savestate(file_tag_type savestate_file);
void input_read_savestate(file_tag_type savestate_file);
void input_write_savestate(void);
void input_read_savestate(void);
#include "libretro.h"

View File

@ -21,15 +21,6 @@ struct retro_perf_callback perf_cb;
static cothread_t main_thread;
static cothread_t cpu_thread;
/* to be removed */
u32 savestate_slot = 0;
void get_savestate_filename_noshot(u32 slot, char* name_buffer)
{
(void) slot;
sprintf(name_buffer, "dummy.svs");
}
/* ------------ */
void switch_to_main_thread(void)
{
co_switch(main_thread);
@ -95,7 +86,7 @@ void retro_get_system_av_info(struct retro_system_av_info* info)
info->geometry.max_height = GBA_SCREEN_HEIGHT;
info->geometry.aspect_ratio = 0;
// 59.72750057 hz
info->timing.fps = ((float)(16 * 1024 * 1024)) / (308 * 228 * 4);
info->timing.fps = ((float) GBC_BASE_RATE) / (308 * 228 * 4);
info->timing.sample_rate = GBA_SOUND_FREQUENCY;
}
@ -167,28 +158,28 @@ void retro_reset()
size_t retro_serialize_size()
{
// return SAVESTATE_SIZE;
return 0;
return GBA_STATE_MEM_SIZE;
}
bool retro_serialize(void* data, size_t size)
{
// if (size < SAVESTATE_SIZE)
return false;
if (size != GBA_STATE_MEM_SIZE)
return false;
// gba_save_state(data);
memset (data,0, GBA_STATE_MEM_SIZE);
gba_save_state(data);
// return true;
return true;
}
bool retro_unserialize(const void* data, size_t size)
{
// if (size < SAVESTATE_SIZE)
return false;
if (size != GBA_STATE_MEM_SIZE)
return false;
// gba_load_state(data);
gba_load_state(data);
// return true;
return true;
}
void retro_cheat_reset() {}

20
main.c
View File

@ -600,17 +600,17 @@ void make_rpath(char *buff, size_t size, const char *ext)
strcpy(p, ext);
}
#define main_savestate_builder(type) \
void main_##type##_savestate(file_tag_type savestate_file) \
{ \
file_##type##_variable(savestate_file, cpu_ticks); \
file_##type##_variable(savestate_file, execute_cycles); \
file_##type##_variable(savestate_file, video_count); \
file_##type##_array(savestate_file, timer); \
} \
#define main_savestate_builder(type) \
void main_##type##_savestate(void) \
{ \
state_mem_##type##_variable(cpu_ticks); \
state_mem_##type##_variable(execute_cycles); \
state_mem_##type##_variable(video_count); \
state_mem_##type##_array(timer); \
}
main_savestate_builder(read);
main_savestate_builder(write_mem);
main_savestate_builder(read)
main_savestate_builder(write)
void printout(void *str, u32 val)

4
main.h
View File

@ -99,8 +99,8 @@ void quit();
void delay_us(u32 us_count);
void get_ticks_us(u64 *tick_return);
void game_name_ext(char *src, char *buffer, char *extension);
void main_write_mem_savestate(file_tag_type savestate_file);
void main_read_savestate(file_tag_type savestate_file);
void main_write_savestate(void);
void main_read_savestate(void);
#ifdef PSP_BUILD

36
sound.c
View File

@ -605,25 +605,25 @@ void init_sound(int need_reset)
reset_sound();
}
#define sound_savestate_builder(type) \
void sound_##type##_savestate(file_tag_type savestate_file) \
{ \
file_##type##_variable(savestate_file, sound_on); \
file_##type##_variable(savestate_file, sound_buffer_base); \
file_##type##_variable(savestate_file, sound_last_cpu_ticks); \
file_##type##_variable(savestate_file, gbc_sound_buffer_index); \
file_##type##_variable(savestate_file, gbc_sound_last_cpu_ticks); \
file_##type##_variable(savestate_file, gbc_sound_partial_ticks); \
file_##type##_variable(savestate_file, gbc_sound_master_volume_left); \
file_##type##_variable(savestate_file, gbc_sound_master_volume_right); \
file_##type##_variable(savestate_file, gbc_sound_master_volume); \
file_##type##_array(savestate_file, wave_samples); \
file_##type##_array(savestate_file, direct_sound_channel); \
file_##type##_array(savestate_file, gbc_sound_channel); \
} \
#define sound_savestate_builder(type) \
void sound_##type##_savestate(void) \
{ \
state_mem_##type##_variable(sound_on); \
state_mem_##type##_variable(sound_buffer_base); \
state_mem_##type##_variable(sound_last_cpu_ticks); \
state_mem_##type##_variable(gbc_sound_buffer_index); \
state_mem_##type##_variable(gbc_sound_last_cpu_ticks); \
state_mem_##type##_variable(gbc_sound_partial_ticks); \
state_mem_##type##_variable(gbc_sound_master_volume_left); \
state_mem_##type##_variable(gbc_sound_master_volume_right); \
state_mem_##type##_variable(gbc_sound_master_volume); \
state_mem_##type##_array(wave_samples); \
state_mem_##type##_array(direct_sound_channel); \
state_mem_##type##_array(gbc_sound_channel); \
}
sound_savestate_builder(read);
sound_savestate_builder(write_mem);
sound_savestate_builder(read)
sound_savestate_builder(write)
#include "libretro.h"

View File

@ -25,10 +25,7 @@
#define GBA_SOUND_FREQUENCY (64 * 1024)
#define GBA_XTAL 16777216.0f
#define GBC_BASE_RATE GBA_XTAL
#define GBC_BASE_RATE ((float)(16 * 1024 * 1024))
typedef enum
{
@ -120,8 +117,8 @@ void sound_timer(fixed8_24 frequency_step, u32 channel);
void sound_reset_fifo(u32 channel);
void update_gbc_sound(u32 cpu_ticks);
void init_sound(int need_reset);
void sound_write_mem_savestate(file_tag_type savestate_file);
void sound_read_savestate(file_tag_type savestate_file);
void sound_write_savestate(void);
void sound_read_savestate(void);
void render_audio(void);

16
video.c
View File

@ -3570,14 +3570,14 @@ void debug_screen_printl(const char *format, ...)
}
#define video_savestate_builder(type) \
void video_##type##_savestate(file_tag_type savestate_file) \
{ \
file_##type##_array(savestate_file, affine_reference_x); \
file_##type##_array(savestate_file, affine_reference_y); \
} \
#define video_savestate_builder(type) \
void video_##type##_savestate(void) \
{ \
state_mem_##type##_array(affine_reference_x); \
state_mem_##type##_array(affine_reference_y); \
}
video_savestate_builder(read);
video_savestate_builder(write_mem);
video_savestate_builder(read)
video_savestate_builder(write)

View File

@ -31,8 +31,8 @@ void clear_screen(u16 color);
void blit_to_screen(u16 *src, u32 w, u32 h, u32 x, u32 y);
u16 *copy_screen();
void flip_screen();
void video_write_mem_savestate(file_tag_type savestate_file);
void video_read_savestate(file_tag_type savestate_file);
void video_write_savestate(void);
void video_read_savestate(void);
void debug_screen_clear();
void debug_screen_start();