mirror of https://github.com/bsnes-emu/bsnes.git
Fix libretro SGB1 FPS, fix un/serialization memory corruptions in libretro
This commit is contained in:
parent
91b0e491c5
commit
50a6a3e35c
|
@ -896,3 +896,8 @@ void GB_set_update_input_hint_callback(GB_gameboy_t *gb, GB_update_input_hint_ca
|
|||
{
|
||||
gb->update_input_hint_callback = callback;
|
||||
}
|
||||
|
||||
double GB_get_usual_frame_rate(GB_gameboy_t *gb)
|
||||
{
|
||||
return GB_get_clock_rate(gb) / (double)LCDC_PERIOD;
|
||||
}
|
||||
|
|
|
@ -695,7 +695,7 @@ void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier);
|
|||
|
||||
unsigned GB_get_screen_width(GB_gameboy_t *gb);
|
||||
unsigned GB_get_screen_height(GB_gameboy_t *gb);
|
||||
|
||||
double GB_get_usual_frame_rate(GB_gameboy_t *gb);
|
||||
unsigned GB_get_player_count(GB_gameboy_t *gb);
|
||||
|
||||
#endif /* GB_h */
|
||||
|
|
|
@ -466,7 +466,7 @@ static void render_jingle(GB_gameboy_t *gb, size_t count);
|
|||
void GB_sgb_render(GB_gameboy_t *gb)
|
||||
{
|
||||
if (gb->apu_output.sample_rate) {
|
||||
render_jingle(gb, gb->apu_output.sample_rate / (GB_get_clock_rate(gb) / (double)LCDC_PERIOD));
|
||||
render_jingle(gb, gb->apu_output.sample_rate / GB_get_usual_frame_rate(gb));
|
||||
}
|
||||
|
||||
if (gb->sgb->intro_animation < INTRO_ANIMATION_LENGTH) gb->sgb->intro_animation++;
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#define AUDIO_FREQUENCY 48000
|
||||
#endif
|
||||
|
||||
#define FRAME_RATE (0x400000 / 70224.0)
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
|
@ -727,7 +725,7 @@ void retro_get_system_info(struct retro_system_info *info)
|
|||
void retro_get_system_av_info(struct retro_system_av_info *info)
|
||||
{
|
||||
struct retro_game_geometry geom;
|
||||
struct retro_system_timing timing = { FRAME_RATE, AUDIO_FREQUENCY };
|
||||
struct retro_system_timing timing = { GB_get_usual_frame_rate(&gameboy[0]), AUDIO_FREQUENCY };
|
||||
|
||||
if (emulated_devices == 2)
|
||||
{
|
||||
|
@ -947,11 +945,11 @@ bool retro_load_game_special(unsigned type, const struct retro_game_info *info,
|
|||
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars_dual);
|
||||
check_variables();
|
||||
|
||||
frame_buf = (uint32_t*)malloc(emulated_devices * VIDEO_PIXELS * sizeof(uint32_t));
|
||||
frame_buf_copy = (uint32_t*)malloc(emulated_devices * VIDEO_PIXELS * sizeof(uint32_t));
|
||||
frame_buf = (uint32_t*)malloc(emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
|
||||
frame_buf_copy = (uint32_t*)malloc(emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
|
||||
|
||||
memset(frame_buf, 0, emulated_devices * VIDEO_PIXELS * sizeof(uint32_t));
|
||||
memset(frame_buf_copy, 0, emulated_devices * VIDEO_PIXELS * sizeof(uint32_t));
|
||||
memset(frame_buf, 0, emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
|
||||
memset(frame_buf_copy, 0, emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
|
||||
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
|
@ -987,56 +985,67 @@ bool retro_load_game_special(unsigned type, const struct retro_game_info *info,
|
|||
|
||||
size_t retro_serialize_size(void)
|
||||
{
|
||||
if (emulated_devices == 2)
|
||||
return GB_get_save_state_size(&gameboy[0]) + GB_get_save_state_size(&gameboy[1]);
|
||||
else
|
||||
return GB_get_save_state_size(&gameboy[0]);
|
||||
static size_t maximum_save_size = 0;
|
||||
if (maximum_save_size) {
|
||||
return maximum_save_size * 2;
|
||||
}
|
||||
|
||||
GB_gameboy_t temp;
|
||||
|
||||
GB_init(&temp, GB_MODEL_DMG_B);
|
||||
maximum_save_size = GB_get_save_state_size(&temp);
|
||||
GB_free(&temp);
|
||||
|
||||
GB_init(&temp, GB_MODEL_CGB_E);
|
||||
maximum_save_size = MAX(maximum_save_size, GB_get_save_state_size(&temp));
|
||||
GB_free(&temp);
|
||||
|
||||
GB_init(&temp, GB_MODEL_SGB2);
|
||||
maximum_save_size = MAX(maximum_save_size, GB_get_save_state_size(&temp));
|
||||
GB_free(&temp);
|
||||
|
||||
return maximum_save_size * 2;
|
||||
}
|
||||
|
||||
bool retro_serialize(void *data, size_t size)
|
||||
{
|
||||
|
||||
if (!initialized)
|
||||
if (!initialized || !data)
|
||||
return false;
|
||||
|
||||
void* save_data[2];
|
||||
size_t state_size[2];
|
||||
size_t offset = 0;
|
||||
|
||||
for (int i = 0; i < emulated_devices; i++)
|
||||
{
|
||||
state_size[i] = GB_get_save_state_size(&gameboy[i]);
|
||||
save_data[i] = (uint8_t*)malloc(state_size[i]);
|
||||
GB_save_state_to_buffer(&gameboy[i], (uint8_t*) save_data[i]);
|
||||
memcpy(data + offset, save_data[i], state_size[i]);
|
||||
offset += state_size[i];
|
||||
free(save_data[i]);
|
||||
for (int i = 0; i < emulated_devices; i++) {
|
||||
size_t state_size = GB_get_save_state_size(&gameboy[i]);
|
||||
if (state_size > size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GB_save_state_to_buffer(&gameboy[i], ((uint8_t *) data) + offset);
|
||||
offset += state_size;
|
||||
size -= state_size;
|
||||
}
|
||||
|
||||
if (data)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool retro_unserialize(const void *data, size_t size)
|
||||
{
|
||||
void* save_data[2];
|
||||
size_t state_size[2];
|
||||
int ret;
|
||||
|
||||
for (int i = 0; i < emulated_devices; i++)
|
||||
{
|
||||
state_size[i] = GB_get_save_state_size(&gameboy[i]);
|
||||
save_data[i] = (uint8_t*)malloc(state_size[i]);
|
||||
memcpy (save_data[i], data + (state_size[i] * i), state_size[i]);
|
||||
ret = GB_load_state_from_buffer(&gameboy[i], save_data[i], state_size[i]);
|
||||
free(save_data[i]);
|
||||
|
||||
if (ret != 0)
|
||||
size_t state_size = GB_get_save_state_size(&gameboy[i]);
|
||||
if (state_size > size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GB_load_state_from_buffer(&gameboy[i], data, state_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size -= state_size;
|
||||
data = ((uint8_t *)data) + state_size;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue