fix gameboy synchronization thanks to @LIJI32

This commit is contained in:
radius 2018-01-31 15:33:46 -05:00
parent 45e0a75491
commit 91816c30b5
1 changed files with 87 additions and 70 deletions

View File

@ -66,6 +66,7 @@ GB_gameboy_t gb1;
GB_gameboy_t gb2; GB_gameboy_t gb2;
extern const unsigned char dmg_boot[], cgb_boot[], agb_boot[]; extern const unsigned char dmg_boot[], cgb_boot[], agb_boot[];
extern const unsigned dmg_boot_length, cgb_boot_length, agb_boot_length; extern const unsigned dmg_boot_length, cgb_boot_length, agb_boot_length;
bool vblank1_occurred = false, vblank2_occurred = false;
static void fallback_log(enum retro_log_level level, const char *fmt, ...) static void fallback_log(enum retro_log_level level, const char *fmt, ...)
{ {
@ -119,12 +120,14 @@ static void audio_callback(void *gb)
static void vblank1(GB_gameboy_t *gb) static void vblank1(GB_gameboy_t *gb)
{ {
vblank1_occurred = true;
GB_update_keys_status(gb, 0); GB_update_keys_status(gb, 0);
audio_callback(gb); audio_callback(gb);
} }
static void vblank2(GB_gameboy_t *gb) static void vblank2(GB_gameboy_t *gb)
{ {
vblank2_occurred = true;
GB_update_keys_status(gb, 1); GB_update_keys_status(gb, 1);
//audio_callback(gb); //audio_callback(gb);
} }
@ -241,24 +244,30 @@ void retro_reset(void)
GB_reset(&gb2); GB_reset(&gb2);
} }
static uint8_t byte_to_send1 = 0xFF, byte_to_send2 = 0xFF;
static void serial_start1(GB_gameboy_t *gb, uint8_t byte_received) static void serial_start1(GB_gameboy_t *gb, uint8_t byte_received)
{ {
GB_serial_set_data(&gb2, byte_received); byte_to_send1 = byte_received;
} }
static uint8_t serial_end1(GB_gameboy_t *gb) static uint8_t serial_end1(GB_gameboy_t *gb)
{ {
return GB_serial_get_data(&gb2); uint8_t ret = GB_serial_get_data(&gb2);
GB_serial_set_data(&gb2, byte_to_send1);
return ret;
} }
static void serial_start2(GB_gameboy_t *gb, uint8_t byte_received) static void serial_start2(GB_gameboy_t *gb, uint8_t byte_received)
{ {
GB_serial_set_data(&gb1, byte_received); byte_to_send2 = byte_received;
} }
static uint8_t serial_end2(GB_gameboy_t *gb) static uint8_t serial_end2(GB_gameboy_t *gb)
{ {
return GB_serial_get_data(&gb1); uint8_t ret = GB_serial_get_data(&gb1);
GB_serial_set_data(&gb1, byte_to_send2);
return ret;
} }
static void init_for_current_model(void) static void init_for_current_model(void)
@ -442,20 +451,28 @@ static void check_variables(void)
int frames = 0; int frames = 0;
void retro_run(void) void retro_run(void)
{ {
bool updated = false; bool updated = false;
if (!frame_buf) if (!frame_buf)
return; return;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
check_variables(); check_variables();
GB_run_frame(&gb1); vblank1_occurred = vblank2_occurred = false;
GB_run_frame(&gb2); signed delta = 0;
while (!vblank1_occurred || !vblank2_occurred) {
video_cb(frame_buf, VIDEO_WIDTH, VIDEO_HEIGHT * 2, VIDEO_WIDTH * sizeof(uint32_t)); if (delta >= 0) {
delta -= GB_run(&gb1);
frames++; }
else {
delta += GB_run(&gb2);
}
}
video_cb(frame_buf, VIDEO_WIDTH, VIDEO_HEIGHT * 2, VIDEO_WIDTH * sizeof(uint32_t));
frames++;
} }
bool retro_load_game(const struct retro_game_info *info) bool retro_load_game(const struct retro_game_info *info)
@ -555,66 +572,66 @@ bool retro_unserialize(const void *data, size_t size)
void *retro_get_memory_data(unsigned type) void *retro_get_memory_data(unsigned type)
{ {
void* data; void* data;
switch(type) switch(type)
{ {
case RETRO_MEMORY_SYSTEM_RAM: case RETRO_MEMORY_SYSTEM_RAM:
data = gb1.ram; data = gb1.ram;
break; break;
case RETRO_MEMORY_SAVE_RAM: case RETRO_MEMORY_SAVE_RAM:
if (gb1.cartridge_type->has_battery && gb1.mbc_ram_size != 0) if (gb1.cartridge_type->has_battery && gb1.mbc_ram_size != 0)
{ {
data = gb1.mbc_ram; data = gb1.mbc_ram;
/* let's copy the save to gb2 so it can save independently */ /* let's copy the save to gb2 so it can save independently */
memcpy(gb2.mbc_ram, gb1.mbc_ram, gb1.mbc_ram_size); memcpy(gb2.mbc_ram, gb1.mbc_ram, gb1.mbc_ram_size);
} }
else else
data = NULL;
break;
case RETRO_MEMORY_VIDEO_RAM:
data = gb1.vram;
break;
case RETRO_MEMORY_RTC:
if(gb1.cartridge_type->has_battery)
data = &gb1.rtc_real;
else
data = NULL;
break;
default:
data = NULL; data = NULL;
break;
case RETRO_MEMORY_VIDEO_RAM:
data = gb1.vram;
break;
case RETRO_MEMORY_RTC:
if(gb1.cartridge_type->has_battery)
data = &gb1.rtc_real;
else
data = NULL;
break;
default:
data = NULL;
} }
return data; return data;
} }
size_t retro_get_memory_size(unsigned type) size_t retro_get_memory_size(unsigned type)
{ {
size_t size; size_t size;
switch(type) switch(type)
{ {
case RETRO_MEMORY_SYSTEM_RAM: case RETRO_MEMORY_SYSTEM_RAM:
size = gb1.ram_size; size = gb1.ram_size;
break; break;
case RETRO_MEMORY_SAVE_RAM: case RETRO_MEMORY_SAVE_RAM:
if (gb1.cartridge_type->has_battery && gb1.mbc_ram_size != 0) if (gb1.cartridge_type->has_battery && gb1.mbc_ram_size != 0)
size = gb1.mbc_ram_size; size = gb1.mbc_ram_size;
else else
size = 0;
break;
case RETRO_MEMORY_VIDEO_RAM:
size = gb1.vram_size;
break;
case RETRO_MEMORY_RTC:
if(gb1.cartridge_type->has_battery)
size = sizeof (gb1.rtc_real);
else
size = 0;
break;
default:
size = 0; size = 0;
break; break;
case RETRO_MEMORY_VIDEO_RAM: }
size = gb1.vram_size;
break; return size;
case RETRO_MEMORY_RTC:
if(gb1.cartridge_type->has_battery)
size = sizeof (gb1.rtc_real);
else
size = 0;
break;
default:
size = 0;
break;
}
return size;
} }
void retro_cheat_reset(void) void retro_cheat_reset(void)