From 2bfe9226501191a6ab355792b98b343816843830 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Mon, 15 Jul 2019 20:47:16 +0300 Subject: [PATCH] Allow emulating an SGB without SFC HLE --- Core/display.c | 4 ++-- Core/gb.c | 13 +++++++++---- Core/gb.h | 8 ++++++-- Core/save_state.c | 14 +++++++------- Core/sgb.c | 4 ++++ 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/Core/display.c b/Core/display.c index cf53216..cdcdeb2 100644 --- a/Core/display.c +++ b/Core/display.c @@ -123,8 +123,8 @@ static void display_vblank(GB_gameboy_t *gb) { gb->vblank_just_occured = true; - /* TODO: Slow in trubo mode! */ - if (GB_is_sgb(gb)) { + /* TODO: Slow in turbo mode! */ + if (GB_is_hle_sgb(gb)) { GB_sgb_render(gb); } diff --git a/Core/gb.c b/Core/gb.c index dec32a9..6f846ca 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -533,6 +533,11 @@ bool GB_is_cgb(GB_gameboy_t *gb) } bool GB_is_sgb(GB_gameboy_t *gb) +{ + return (gb->model & ~GB_MODEL_PAL_BIT & ~GB_MODEL_NO_SFC_BIT) == GB_MODEL_SGB || (gb->model & ~GB_MODEL_NO_SFC_BIT) == GB_MODEL_SGB2; +} + +bool GB_is_hle_sgb(GB_gameboy_t *gb) { return (gb->model & ~GB_MODEL_PAL_BIT) == GB_MODEL_SGB || gb->model == GB_MODEL_SGB2; } @@ -745,7 +750,7 @@ void GB_reset(GB_gameboy_t *gb) gb->accessed_oam_row = -1; - if (GB_is_sgb(gb)) { + if (GB_is_hle_sgb(gb)) { if (!gb->sgb) { gb->sgb = malloc(sizeof(*gb->sgb)); } @@ -879,17 +884,17 @@ uint32_t GB_get_clock_rate(GB_gameboy_t *gb) unsigned GB_get_screen_width(GB_gameboy_t *gb) { - return GB_is_sgb(gb)? 256 : 160; + return GB_is_hle_sgb(gb)? 256 : 160; } unsigned GB_get_screen_height(GB_gameboy_t *gb) { - return GB_is_sgb(gb)? 224 : 144; + return GB_is_hle_sgb(gb)? 224 : 144; } unsigned GB_get_player_count(GB_gameboy_t *gb) { - return GB_is_sgb(gb)? gb->sgb->player_count : 1; + return GB_is_hle_sgb(gb)? gb->sgb->player_count : 1; } void GB_set_update_input_hint_callback(GB_gameboy_t *gb, GB_update_input_hint_callback_t callback) diff --git a/Core/gb.h b/Core/gb.h index 7cebbce..6d10283 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -29,6 +29,7 @@ #define GB_MODEL_MGB_FAMILY 0x100 #define GB_MODEL_CGB_FAMILY 0x200 #define GB_MODEL_PAL_BIT 0x1000 +#define GB_MODEL_NO_SFC_BIT 0x2000 #if __clang__ #define UNROLL _Pragma("unroll") @@ -67,9 +68,11 @@ typedef enum { // GB_MODEL_DMG_C = 0x003, GB_MODEL_SGB = 0x004, GB_MODEL_SGB_NTSC = GB_MODEL_SGB, - GB_MODEL_SGB_PAL = 0x1004, + GB_MODEL_SGB_PAL = GB_MODEL_SGB | GB_MODEL_PAL_BIT, + GB_MODEL_SGB_NO_SFC = GB_MODEL_SGB | GB_MODEL_NO_SFC_BIT, // GB_MODEL_MGB = 0x100, GB_MODEL_SGB2 = 0x101, + GB_MODEL_SGB2_NO_SFC = GB_MODEL_SGB2 | GB_MODEL_NO_SFC_BIT, // GB_MODEL_CGB_0 = 0x200, // GB_MODEL_CGB_A = 0x201, // GB_MODEL_CGB_B = 0x202, @@ -617,7 +620,8 @@ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) void GB_init(GB_gameboy_t *gb, GB_model_t model); bool GB_is_inited(GB_gameboy_t *gb); bool GB_is_cgb(GB_gameboy_t *gb); -bool GB_is_sgb(GB_gameboy_t *gb); +bool GB_is_sgb(GB_gameboy_t *gb); // Returns true if the model is SGB or SGB2 +bool GB_is_hle_sgb(GB_gameboy_t *gb); // Returns true if the model is SGB or SGB2 and the SFC/SNES side is HLE'd GB_model_t GB_get_model(GB_gameboy_t *gb); void GB_free(GB_gameboy_t *gb); void GB_reset(GB_gameboy_t *gb); diff --git a/Core/save_state.c b/Core/save_state.c index 5a7d920..8ef99ae 100644 --- a/Core/save_state.c +++ b/Core/save_state.c @@ -36,7 +36,7 @@ int GB_save_state(GB_gameboy_t *gb, const char *path) if (!DUMP_SECTION(gb, f, rtc )) goto error; if (!DUMP_SECTION(gb, f, video )) goto error; - if (GB_is_sgb(gb)) { + if (GB_is_hle_sgb(gb)) { if (!dump_section(f, gb->sgb, sizeof(*gb->sgb))) goto error; } @@ -73,7 +73,7 @@ size_t GB_get_save_state_size(GB_gameboy_t *gb) + GB_SECTION_SIZE(apu ) + sizeof(uint32_t) + GB_SECTION_SIZE(rtc ) + sizeof(uint32_t) + GB_SECTION_SIZE(video ) + sizeof(uint32_t) - + (GB_is_sgb(gb)? sizeof(*gb->sgb) + sizeof(uint32_t) : 0) + + (GB_is_hle_sgb(gb)? sizeof(*gb->sgb) + sizeof(uint32_t) : 0) + gb->mbc_ram_size + gb->ram_size + gb->vram_size; @@ -105,7 +105,7 @@ void GB_save_state_to_buffer(GB_gameboy_t *gb, uint8_t *buffer) DUMP_SECTION(gb, buffer, rtc ); DUMP_SECTION(gb, buffer, video ); - if (GB_is_sgb(gb)) { + if (GB_is_hle_sgb(gb)) { buffer_dump_section(&buffer, gb->sgb, sizeof(*gb->sgb)); } @@ -161,8 +161,8 @@ static bool verify_state_compatibility(GB_gameboy_t *gb, GB_gameboy_t *save) return false; } - if (GB_is_sgb(gb) != GB_is_sgb(save)) { - GB_log(gb, "The save state is %sfor a Super Game Boy. Try changing the emulated model.\n", GB_is_sgb(save)? "" : "not "); + if (GB_is_hle_sgb(gb) != GB_is_hle_sgb(save)) { + GB_log(gb, "The save state is %sfor a Super Game Boy. Try changing the emulated model.\n", GB_is_hle_sgb(save)? "" : "not "); return false; } @@ -223,7 +223,7 @@ int GB_load_state(GB_gameboy_t *gb, const char *path) goto error; } - if (GB_is_sgb(gb)) { + if (GB_is_hle_sgb(gb)) { if (!read_section(f, gb->sgb, sizeof(*gb->sgb))) goto error; } @@ -334,7 +334,7 @@ int GB_load_state_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t le return -1; } - if (GB_is_sgb(gb)) { + if (GB_is_hle_sgb(gb)) { if (!buffer_read_section(&buffer, &length, gb->sgb, sizeof(*gb->sgb))) return -1; } diff --git a/Core/sgb.c b/Core/sgb.c index 5bcb72d..a422af0 100644 --- a/Core/sgb.c +++ b/Core/sgb.c @@ -296,6 +296,10 @@ static void command_ready(GB_gameboy_t *gb) void GB_sgb_write(GB_gameboy_t *gb, uint8_t value) { if (!GB_is_sgb(gb)) return; + if (!GB_is_hle_sgb(gb)) { + /* Notify via callback */ + return; + } if (gb->sgb->disable_commands) return; if (gb->sgb->command_write_index >= sizeof(gb->sgb->command) * 8) return;