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;
|
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_width(GB_gameboy_t *gb);
|
||||||
unsigned GB_get_screen_height(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);
|
unsigned GB_get_player_count(GB_gameboy_t *gb);
|
||||||
|
|
||||||
#endif /* GB_h */
|
#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)
|
void GB_sgb_render(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
if (gb->apu_output.sample_rate) {
|
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++;
|
if (gb->sgb->intro_animation < INTRO_ANIMATION_LENGTH) gb->sgb->intro_animation++;
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#define AUDIO_FREQUENCY 48000
|
#define AUDIO_FREQUENCY 48000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FRAME_RATE (0x400000 / 70224.0)
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <windows.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)
|
void retro_get_system_av_info(struct retro_system_av_info *info)
|
||||||
{
|
{
|
||||||
struct retro_game_geometry geom;
|
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)
|
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);
|
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars_dual);
|
||||||
check_variables();
|
check_variables();
|
||||||
|
|
||||||
frame_buf = (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 * 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, 0, emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
|
||||||
memset(frame_buf_copy, 0, emulated_devices * 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;
|
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
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)
|
size_t retro_serialize_size(void)
|
||||||
{
|
{
|
||||||
if (emulated_devices == 2)
|
static size_t maximum_save_size = 0;
|
||||||
return GB_get_save_state_size(&gameboy[0]) + GB_get_save_state_size(&gameboy[1]);
|
if (maximum_save_size) {
|
||||||
else
|
return maximum_save_size * 2;
|
||||||
return GB_get_save_state_size(&gameboy[0]);
|
}
|
||||||
|
|
||||||
|
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)
|
bool retro_serialize(void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!initialized)
|
if (!initialized || !data)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
void* save_data[2];
|
|
||||||
size_t state_size[2];
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
for (int i = 0; i < emulated_devices; i++)
|
for (int i = 0; i < emulated_devices; i++) {
|
||||||
{
|
size_t state_size = GB_get_save_state_size(&gameboy[i]);
|
||||||
state_size[i] = GB_get_save_state_size(&gameboy[i]);
|
if (state_size > size) {
|
||||||
save_data[i] = (uint8_t*)malloc(state_size[i]);
|
return false;
|
||||||
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];
|
GB_save_state_to_buffer(&gameboy[i], ((uint8_t *) data) + offset);
|
||||||
free(save_data[i]);
|
offset += state_size;
|
||||||
|
size -= state_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data)
|
|
||||||
return true;
|
return true;
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool retro_unserialize(const void *data, size_t size)
|
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++)
|
for (int i = 0; i < emulated_devices; i++)
|
||||||
{
|
{
|
||||||
state_size[i] = GB_get_save_state_size(&gameboy[i]);
|
size_t state_size = GB_get_save_state_size(&gameboy[i]);
|
||||||
save_data[i] = (uint8_t*)malloc(state_size[i]);
|
if (state_size > size) {
|
||||||
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)
|
|
||||||
return false;
|
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;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue