diff --git a/libretro/libretro.c b/libretro/libretro.c index 29e60b7..59f4f9f 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -77,12 +77,6 @@ enum audio_out { GB_2 }; -enum mode{ - MODE_SINGLE_GAME, - MODE_SINGLE_GAME_DUAL, - MODE_DUAL_GAME -}; - static enum model model[2]; static enum model auto_model = MODEL_CGB; @@ -101,11 +95,7 @@ static bool initialized = false; static unsigned screen_layout = 0; static unsigned audio_out = 0; -static enum mode mode = MODE_SINGLE_GAME; - static bool geometry_updated = false; -static bool sameboy_dual = false; - static bool link_cable_emulation = false; /*static bool infrared_emulation = false;*/ @@ -132,28 +122,8 @@ static void fallback_log(enum retro_log_level level, const char *fmt, ...) static struct retro_rumble_interface rumble; -static void extract_basename(char *buf, const char *path, size_t size) -{ - const char *base = strrchr(path, '/'); - if (!base) - base = strrchr(path, '\\'); - if (!base) - base = path; - - if (*base == '\\' || *base == '/') - base++; - - strncpy(buf, base, size - 1); - buf[size - 1] = '\0'; - - char *ext = strrchr(buf, '.'); - if (ext) - *ext = '\0'; -} - static void GB_update_keys_status(GB_gameboy_t *gb, unsigned port) { - input_poll_cb(); GB_set_key_state(gb, GB_KEY_RIGHT,input_state_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT)); @@ -169,7 +139,6 @@ static void GB_update_keys_status(GB_gameboy_t *gb, unsigned port) rumble.set_rumble_state(port, RETRO_RUMBLE_STRONG, 65535); else rumble.set_rumble_state(port, RETRO_RUMBLE_STRONG, 0); - } @@ -238,26 +207,9 @@ static retro_environment_t environ_cb; /* variables for single cart mode */ static const struct retro_variable vars_single[] = { - { "sameboy_dual", "Single cart dual mode (reload); disabled|enabled" }, { "sameboy_color_correction_mode", "Color correction; off|correct curves|emulate hardware|preserve brightness" }, { "sameboy_high_pass_filter_mode", "High-pass filter; off|accurate|remove dc offset" }, - { "sameboy_model", "Emulated model; Game Boy Color|Game Boy Advance|Auto|Game Boy|Super Game Boy|Super Game Boy 2" }, - { NULL } -}; - -/* variables for single cart dual gameboy mode */ -static const struct retro_variable vars_single_dual[] = { - { "sameboy_dual", "Single cart dual mode (reload); disabled|enabled" }, - { "sameboy_link", "Link cable emulation; enabled|disabled" }, - /*{ "sameboy_ir", "Infrared Sensor Emulation; disabled|enabled" },*/ - { "sameboy_screen_layout", "Screen layout; top-down|left-right" }, - { "sameboy_audio_output", "Audio output; Game Boy #1|Game Boy #2" }, - { "sameboy_model_1", "Emulated model for Game Boy #1; Game Boy Color|Game Boy Advance|Auto|Game Boy" }, - { "sameboy_model_2", "Emulated model for Game Boy #2; Game Boy Color|Game Boy Advance|Auto|Game Boy" }, - { "sameboy_color_correction_mode_1", "Color correction for Game Boy #1; off|correct curves|emulate hardware|preserve brightness" }, - { "sameboy_color_correction_mode_2", "Color correction for Game Boy #2; off|correct curves|emulate hardware|preserve brightness" }, - { "sameboy_high_pass_filter_mode_1", "High-pass filter for Game Boy #1; off|accurate|remove dc offset" }, - { "sameboy_high_pass_filter_mode_2", "High-pass filter for Game Boy #2; off|accurate|remove dc offset" }, + { "sameboy_model", "Emulated model; Auto|Game Boy|Game Boy Color|Game Boy Advance|Super Game Boy|Super Game Boy 2" }, { NULL } }; @@ -267,8 +219,8 @@ static const struct retro_variable vars_dual[] = { /*{ "sameboy_ir", "Infrared Sensor Emulation; disabled|enabled" },*/ { "sameboy_screen_layout", "Screen layout; top-down|left-right" }, { "sameboy_audio_output", "Audio output; Game Boy #1|Game Boy #2" }, - { "sameboy_model_1", "Emulated model for Game Boy #1; Game Boy Color|Game Boy Advance|Auto|Game Boy" }, - { "sameboy_model_2", "Emulated model for Game Boy #2; Game Boy Color|Game Boy Advance|Auto|Game Boy" }, + { "sameboy_model_1", "Emulated model for Game Boy #1; Auto|Game Boy|Game Boy Color|Game Boy Advance" }, + { "sameboy_model_2", "Emulated model for Game Boy #2; Auto|Game Boy|Game Boy Color|Game Boy Advance" }, { "sameboy_color_correction_mode_1", "Color correction for Game Boy #1; off|correct curves|emulate hardware|preserve brightness" }, { "sameboy_color_correction_mode_2", "Color correction for Game Boy #2; off|correct curves|emulate hardware|preserve brightness" }, { "sameboy_high_pass_filter_mode_1", "High-pass filter for Game Boy #1; off|accurate|remove dc offset" }, @@ -291,9 +243,9 @@ static const struct retro_subsystem_rom_info gb_roms[] = { { "GameBoy #2", "gb|gbc", true, false, true, gb2_memory, 1 }, }; - static const struct retro_subsystem_info subsystems[] = { - { "2 Player Game Boy Link", "gb_link_2p", gb_roms, 2, RETRO_GAME_TYPE_GAMEBOY_LINK_2P }, - { NULL }, +static const struct retro_subsystem_info subsystems[] = { + { "2 Player Game Boy Link", "gb_link_2p", gb_roms, 2, RETRO_GAME_TYPE_GAMEBOY_LINK_2P }, + { NULL }, }; static const struct retro_controller_description controllers[] = { @@ -397,7 +349,7 @@ static void init_for_current_model(unsigned id) descs[6].ptr = GB_get_direct_access(&gameboy[i], GB_DIRECT_ACCESS_OAM, &size, &bank); descs[6].start = 0xFE00; descs[6].len = 0x00A0; - + descs[7].ptr = GB_get_direct_access(&gameboy[i], GB_DIRECT_ACCESS_RAM, &size, &bank) + 0x1000; descs[7].start = 0xD000; descs[7].len = 0x1000; @@ -408,10 +360,10 @@ static void init_for_current_model(unsigned id) environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &mmaps); } -static void check_variables(bool link) +static void check_variables() { struct retro_variable var = {0}; - if (!link) + if (emulated_devices == 1) { var.key = "sameboy_color_correction_mode"; var.value = NULL; @@ -569,53 +521,42 @@ static void check_variables(bool link) } } - } + var.key = "sameboy_screen_layout"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "top-down") == 0) + screen_layout = LAYOUT_TOP_DOWN; + else + screen_layout = LAYOUT_LEFT_RIGHT; - var.key = "sameboy_screen_layout"; - var.value = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "top-down") == 0) - screen_layout = LAYOUT_TOP_DOWN; - else - screen_layout = LAYOUT_LEFT_RIGHT; + geometry_updated = true; + } - geometry_updated = true; - } + var.key = "sameboy_link"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool tmp = link_cable_emulation; + if (strcmp(var.value, "enabled") == 0) + link_cable_emulation = true; + else + link_cable_emulation = false; + if (link_cable_emulation && link_cable_emulation != tmp) + set_link_cable_state(true); + else if (!link_cable_emulation && link_cable_emulation != tmp) + set_link_cable_state(false); + } - var.key = "sameboy_dual"; - var.value = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - sameboy_dual = true; - else - sameboy_dual = false; - } - - var.key = "sameboy_link"; - var.value = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - bool tmp = link_cable_emulation; - if (strcmp(var.value, "enabled") == 0) - link_cable_emulation = true; - else - link_cable_emulation = false; - if (link_cable_emulation && link_cable_emulation != tmp) - set_link_cable_state(true); - else if (!link_cable_emulation && link_cable_emulation != tmp) - set_link_cable_state(false); - } - - var.key = "sameboy_audio_output"; - var.value = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "Game Boy #1") == 0) - audio_out = GB_1; - else - audio_out = GB_2; + var.key = "sameboy_audio_output"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "Game Boy #1") == 0) + audio_out = GB_1; + else + audio_out = GB_2; + } } } @@ -701,7 +642,7 @@ 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 }; - if (sameboy_dual) + if (emulated_devices == 2) { if (screen_layout == LAYOUT_TOP_DOWN) { geom.base_width = VIDEO_WIDTH; @@ -799,7 +740,7 @@ void retro_run(void) return; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) - check_variables(emulated_devices == 2 ? true : false); + check_variables(); GB_update_keys_status(&gameboy[0], 0); if (emulated_devices == 2) @@ -824,7 +765,7 @@ void retro_run(void) log_cb(RETRO_LOG_DEBUG, "%d\n", x); } - if (sameboy_dual) + if (emulated_devices == 2) { if (screen_layout == LAYOUT_TOP_DOWN) { video_cb(frame_buf, VIDEO_WIDTH, VIDEO_HEIGHT * emulated_devices, VIDEO_WIDTH * sizeof(uint32_t)); @@ -856,17 +797,7 @@ void retro_run(void) bool retro_load_game(const struct retro_game_info *info) { environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars_single); - check_variables(false); - - if (sameboy_dual) - { - emulated_devices = 2; - mode = MODE_SINGLE_GAME_DUAL; - environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars_single_dual); - check_variables(true); - } - else - mode = MODE_SINGLE_GAME; + check_variables(); frame_buf = (uint32_t*)malloc(SGB_VIDEO_PIXELS* emulated_devices * sizeof(uint32_t)); memset(frame_buf, 0, SGB_VIDEO_PIXELS * emulated_devices * sizeof(uint32_t)); @@ -899,37 +830,12 @@ bool retro_load_game(const struct retro_game_info *info) else log_cb(RETRO_LOG_INFO, "Rumble environment not supported\n"); - check_variables(emulated_devices == 2 ? true : false); - - /* hack: use upstream's file based I/O for Game Boy 2 battery in single cart mode */ - if (mode == MODE_SINGLE_GAME_DUAL) - { - char path[PATH_MAX]; - char file[PATH_MAX]; - - extract_basename(file, retro_game_path, sizeof(file)); - snprintf (path, sizeof(path), "%s%c%s.srm.2", retro_save_directory, slash, file); - log_cb(RETRO_LOG_INFO, "Loading battery for Game Boy 2 from: %s\n", path); - GB_load_battery(&gameboy[1], path); - } - + check_variables(); return true; } void retro_unload_game(void) { - /* hack: use upstream's file based I/O for Game Boy 2 battery in single cart mode */ - if (mode == MODE_SINGLE_GAME_DUAL) - { - char path[PATH_MAX]; - char file[PATH_MAX]; - - extract_basename(file, retro_game_path, sizeof(file)); - snprintf (path, sizeof(path), "%s%c%s.srm.2", retro_save_directory, slash, file); - log_cb(RETRO_LOG_INFO, "Saving battery for Game Boy 2 to: %s\n", path); - GB_save_battery(&gameboy[1], path); - } - for (int i = 0; i < emulated_devices; i++) GB_free(&gameboy[i]); } @@ -943,15 +849,12 @@ bool retro_load_game_special(unsigned type, const struct retro_game_info *info, { if (type == RETRO_GAME_TYPE_GAMEBOY_LINK_2P) - { emulated_devices = 2; - mode = MODE_DUAL_GAME; - } else return false; /* all other types are unhandled for now */ environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars_dual); - check_variables(true); + 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)); @@ -987,7 +890,7 @@ bool retro_load_game_special(unsigned type, const struct retro_game_info *info, else log_cb(RETRO_LOG_INFO, "Rumble environment not supported\n"); - check_variables(emulated_devices == 2 ? true : false); + check_variables(); return true; } @@ -1050,139 +953,124 @@ bool retro_unserialize(const void *data, size_t size) void *retro_get_memory_data(unsigned type) { void *data = NULL; - switch(mode) + if (emulated_devices == 1) { - case MODE_SINGLE_GAME: - case MODE_SINGLE_GAME_DUAL: /* todo: hook this properly */ - { - switch(type) - { - case RETRO_MEMORY_SYSTEM_RAM: - data = gameboy[0].ram; - break; - case RETRO_MEMORY_SAVE_RAM: - if (gameboy[0].cartridge_type->has_battery && gameboy[0].mbc_ram_size != 0) - data = gameboy[0].mbc_ram; - else - data = NULL; - break; - case RETRO_MEMORY_VIDEO_RAM: - data = gameboy[0].vram; - break; - case RETRO_MEMORY_RTC: - if(gameboy[0].cartridge_type->has_battery) - data = GB_GET_SECTION(&gameboy[0], rtc); - else - data = NULL; - break; - default: - break; - } - } - break; - case MODE_DUAL_GAME: - { - switch (type) - { - case RETRO_MEMORY_GAMEBOY_1_SRAM: - if (gameboy[0].cartridge_type->has_battery && gameboy[0].mbc_ram_size != 0) - data = gameboy[0].mbc_ram; - else - data = NULL; - break; - case RETRO_MEMORY_GAMEBOY_2_SRAM: - if (gameboy[1].cartridge_type->has_battery && gameboy[1].mbc_ram_size != 0) - data = gameboy[1].mbc_ram; - else - data = NULL; - break; - case RETRO_MEMORY_GAMEBOY_1_RTC: - if(gameboy[0].cartridge_type->has_battery) - data = GB_GET_SECTION(&gameboy[0], rtc); - else - data = NULL; - break; - case RETRO_MEMORY_GAMEBOY_2_RTC: - if(gameboy[1].cartridge_type->has_battery) - data = GB_GET_SECTION(&gameboy[1], rtc); - else - data = NULL; - break; - default: - break; - } - } - break; - default: - break; + switch(type) + { + case RETRO_MEMORY_SYSTEM_RAM: + data = gameboy[0].ram; + break; + case RETRO_MEMORY_SAVE_RAM: + if (gameboy[0].cartridge_type->has_battery && gameboy[0].mbc_ram_size != 0) + data = gameboy[0].mbc_ram; + else + data = NULL; + break; + case RETRO_MEMORY_VIDEO_RAM: + data = gameboy[0].vram; + break; + case RETRO_MEMORY_RTC: + if(gameboy[0].cartridge_type->has_battery) + data = GB_GET_SECTION(&gameboy[0], rtc); + else + data = NULL; + break; + default: + break; + } } + else + { + switch (type) + { + case RETRO_MEMORY_GAMEBOY_1_SRAM: + if (gameboy[0].cartridge_type->has_battery && gameboy[0].mbc_ram_size != 0) + data = gameboy[0].mbc_ram; + else + data = NULL; + break; + case RETRO_MEMORY_GAMEBOY_2_SRAM: + if (gameboy[1].cartridge_type->has_battery && gameboy[1].mbc_ram_size != 0) + data = gameboy[1].mbc_ram; + else + data = NULL; + break; + case RETRO_MEMORY_GAMEBOY_1_RTC: + if(gameboy[0].cartridge_type->has_battery) + data = GB_GET_SECTION(&gameboy[0], rtc); + else + data = NULL; + break; + case RETRO_MEMORY_GAMEBOY_2_RTC: + if(gameboy[1].cartridge_type->has_battery) + data = GB_GET_SECTION(&gameboy[1], rtc); + else + data = NULL; + break; + default: + break; + } + } + return data; } size_t retro_get_memory_size(unsigned type) { size_t size = 0; - switch(mode) + if (emulated_devices == 1) { - case MODE_SINGLE_GAME: - case MODE_SINGLE_GAME_DUAL: /* todo: hook this properly */ - { - switch(type) - { - case RETRO_MEMORY_SYSTEM_RAM: - size = gameboy[0].ram_size; - break; - case RETRO_MEMORY_SAVE_RAM: - if (gameboy[0].cartridge_type->has_battery && gameboy[0].mbc_ram_size != 0) - size = gameboy[0].mbc_ram_size; - else - size = 0; - break; - case RETRO_MEMORY_VIDEO_RAM: - size = gameboy[0].vram_size; - break; - case RETRO_MEMORY_RTC: - if(gameboy[0].cartridge_type->has_battery) - size = GB_SECTION_SIZE(rtc); - else - size = 0; - break; - default: - break; - } - } - break; - case MODE_DUAL_GAME: - { - switch (type) - { - case RETRO_MEMORY_GAMEBOY_1_SRAM: - if (gameboy[0].cartridge_type->has_battery && gameboy[0].mbc_ram_size != 0) - size = gameboy[0].mbc_ram_size; - else - size = 0; - break; - case RETRO_MEMORY_GAMEBOY_2_SRAM: - if (gameboy[1].cartridge_type->has_battery && gameboy[1].mbc_ram_size != 0) - size = gameboy[1].mbc_ram_size; - else - size = 0; - break; - case RETRO_MEMORY_GAMEBOY_1_RTC: - if(gameboy[0].cartridge_type->has_battery) - size = GB_SECTION_SIZE(rtc); - break; - case RETRO_MEMORY_GAMEBOY_2_RTC: - if(gameboy[1].cartridge_type->has_battery) - size = GB_SECTION_SIZE(rtc); - break; - default: - break; - } - } - break; - default: - break; + switch(type) + { + case RETRO_MEMORY_SYSTEM_RAM: + size = gameboy[0].ram_size; + break; + case RETRO_MEMORY_SAVE_RAM: + if (gameboy[0].cartridge_type->has_battery && gameboy[0].mbc_ram_size != 0) + size = gameboy[0].mbc_ram_size; + else + size = 0; + break; + case RETRO_MEMORY_VIDEO_RAM: + size = gameboy[0].vram_size; + break; + case RETRO_MEMORY_RTC: + if(gameboy[0].cartridge_type->has_battery) + size = GB_SECTION_SIZE(rtc); + else + size = 0; + break; + default: + break; + } + } + else + { + switch (type) + { + case RETRO_MEMORY_GAMEBOY_1_SRAM: + if (gameboy[0].cartridge_type->has_battery && gameboy[0].mbc_ram_size != 0) + size = gameboy[0].mbc_ram_size; + else + size = 0; + break; + case RETRO_MEMORY_GAMEBOY_2_SRAM: + if (gameboy[1].cartridge_type->has_battery && gameboy[1].mbc_ram_size != 0) + size = gameboy[1].mbc_ram_size; + else + size = 0; + break; + case RETRO_MEMORY_GAMEBOY_1_RTC: + if(gameboy[0].cartridge_type->has_battery) + size = GB_SECTION_SIZE(rtc); + break; + case RETRO_MEMORY_GAMEBOY_2_RTC: + if(gameboy[1].cartridge_type->has_battery) + size = GB_SECTION_SIZE(rtc); + break; + default: + break; + } } return size;