diff --git a/config.def.h b/config.def.h index 63109909c4..eaa2f2abc3 100644 --- a/config.def.h +++ b/config.def.h @@ -23,7 +23,7 @@ #define __CONFIG_DEF_H #include "boolean.h" -#include "libsnes.hpp" +#include "libretro.h" #include "driver.h" #ifdef HAVE_CONFIG_H @@ -293,18 +293,18 @@ static const float axis_threshold = 0.5; // Player 1 static const struct snes_keybind snes_keybinds_1[] = { // SNES button | keyboard key | js btn | js axis | - { true, SNES_DEVICE_ID_JOYPAD_B, SK_z, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_Y, SK_a, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_SELECT, SK_RSHIFT, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_START, SK_RETURN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_UP, SK_UP, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_DOWN, SK_DOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_LEFT, SK_LEFT, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_RIGHT, SK_RIGHT, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_A, SK_x, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_X, SK_s, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_L, SK_q, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_R, SK_w, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_B, SK_z, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_Y, SK_a, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_SELECT, SK_RSHIFT, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_START, SK_RETURN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_UP, SK_UP, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_DOWN, SK_DOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_LEFT, SK_LEFT, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_RIGHT, SK_RIGHT, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_A, SK_x, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_X, SK_s, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_L, SK_q, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_R, SK_w, NO_BTN, AXIS_NONE }, { true, SSNES_FAST_FORWARD_KEY, SK_SPACE, NO_BTN, AXIS_NONE }, { true, SSNES_FAST_FORWARD_HOLD_KEY, SK_l, NO_BTN, AXIS_NONE }, @@ -335,18 +335,18 @@ static const struct snes_keybind snes_keybinds_1[] = { // Player 2-5 static const struct snes_keybind snes_keybinds_rest[] = { - { true, SNES_DEVICE_ID_JOYPAD_B, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_Y, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_SELECT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_START, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_UP, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_DOWN, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_LEFT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_RIGHT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_A, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_X, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_L, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { true, SNES_DEVICE_ID_JOYPAD_R, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_B, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_Y, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_SELECT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_START, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_UP, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_DOWN, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_LEFT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_RIGHT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_A, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_X, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_L, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, RETRO_DEVICE_ID_JOYPAD_R, SK_UNKNOWN, NO_BTN, AXIS_NONE }, }; #endif diff --git a/driver.c b/driver.c index a0fc4c6389..6cf4ca69cb 100644 --- a/driver.c +++ b/driver.c @@ -265,29 +265,20 @@ static void deinit_dsp_plugin(void) static void adjust_audio_input_rate(void) { - if (g_extern.system.timing_set) - { - float timing_skew = fabs(1.0f - g_extern.system.timing.fps / g_settings.video.refresh_rate); - if (timing_skew > 0.05f) // We don't want to adjust pitch too much. If we have extreme cases, just don't readjust at all. - { - SSNES_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n", - g_settings.video.refresh_rate, - (float)g_extern.system.timing.fps); + const struct retro_system_timing *info = &g_extern.system.av_info.timing; - g_settings.video.refresh_rate = g_extern.system.timing.fps; - } + float timing_skew = fabs(1.0f - info->fps / g_settings.video.refresh_rate); + if (timing_skew > 0.05f) // We don't want to adjust pitch too much. If we have extreme cases, just don't readjust at all. + { + SSNES_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n", + g_settings.video.refresh_rate, + (float)info->fps); + + g_settings.video.refresh_rate = info->fps; } - if (g_extern.system.timing_set) - { - g_settings.audio.in_rate = g_extern.system.timing.sample_rate * - (g_settings.video.refresh_rate / g_extern.system.timing.fps); - } - else - { - g_settings.audio.in_rate = 32040.5 * - (g_settings.video.refresh_rate / (21477272.0 / 357366.0)); // SNES metrics. - } + g_settings.audio.in_rate = info->sample_rate * + (g_settings.video.refresh_rate / info->fps); SSNES_LOG("Set audio input rate to: %.2f Hz.\n", g_settings.audio.in_rate); } @@ -426,8 +417,9 @@ static void init_filter(void) g_extern.filter.active = true; - unsigned width = g_extern.system.geom.max_width; - unsigned height = g_extern.system.geom.max_height; + struct retro_game_geometry *geom = &g_extern.system.av_info.geometry; + unsigned width = geom->max_width; + unsigned height = geom->max_height; g_extern.filter.psize(&width, &height); unsigned pow2_x = next_pow2(width); @@ -508,7 +500,8 @@ void init_video_input(void) init_shader_dir(); #endif - unsigned max_dim = max(g_extern.system.geom.max_width, g_extern.system.geom.max_height); + struct retro_game_geometry *geom = &g_extern.system.av_info.geometry; + unsigned max_dim = max(geom->max_width, geom->max_height); unsigned scale = max_dim / SSNES_SCALE_BASE; scale = max(scale, 1); @@ -526,19 +519,19 @@ void init_video_input(void) { if (g_settings.video.force_aspect && (g_settings.video.aspect_ratio > 0.0f)) { - width = roundf(g_extern.system.geom.base_height * g_settings.video.xscale * g_settings.video.aspect_ratio); - height = roundf(g_extern.system.geom.base_height * g_settings.video.yscale); + width = roundf(geom->base_height * g_settings.video.xscale * g_settings.video.aspect_ratio); + height = roundf(geom->base_height * g_settings.video.yscale); } else { - width = roundf(g_extern.system.geom.base_width * g_settings.video.xscale); - height = roundf(g_extern.system.geom.base_height * g_settings.video.yscale); + width = roundf(geom->base_width * g_settings.video.xscale); + height = roundf(geom->base_height * g_settings.video.yscale); } } if (g_settings.video.aspect_ratio < 0.0f) { - g_settings.video.aspect_ratio = (float)g_extern.system.geom.base_width / g_extern.system.geom.base_height; + g_settings.video.aspect_ratio = (float)geom->base_width / geom->base_height; SSNES_LOG("Adjusting aspect ratio to %.2f\n", g_settings.video.aspect_ratio); } diff --git a/dynamic.c b/dynamic.c index 98e722c6f9..71a707e083 100644 --- a/dynamic.c +++ b/dynamic.c @@ -29,7 +29,7 @@ #endif #include "boolean.h" -#include "libsnes.hpp" +#include "libretro.h" #ifdef NEED_DYNAMIC #ifdef _WIN32 @@ -41,7 +41,7 @@ #ifdef HAVE_DYNAMIC #define SYM(x) do { \ - function_t func = dylib_proc(lib, #x); \ + function_t func = dylib_proc(lib_handle, #x); \ memcpy(&p##x, &func, sizeof(func)); \ if (p##x == NULL) { SSNES_ERR("Failed to load symbol: \"%s\"\n", #x); ssnes_fail(1, "init_libsnes_sym()"); } \ } while (0) @@ -78,8 +78,8 @@ bool (*pretro_unserialize)(const void*, size_t); void (*pretro_cheat_reset)(void); void (*pretro_cheat_set)(unsigned, bool, const char*); -bool (*pretro_load_game)(const retro_game_info*); -bool (*pretro_load_game_special)(unsigned, const retro_game_info*, size_t); +bool (*pretro_load_game)(const struct retro_game_info*); +bool (*pretro_load_game_special)(unsigned, const struct retro_game_info*, size_t); void (*pretro_unload_game)(void); @@ -236,12 +236,12 @@ static bool environment_cb(unsigned cmd, void *data) { switch (cmd) { - case SNES_ENVIRONMENT_GET_OVERSCAN: + case RETRO_ENVIRONMENT_GET_OVERSCAN: *(bool*)data = !g_settings.video.crop_overscan; SSNES_LOG("Environ GET_OVERSCAN: %u\n", (unsigned)!g_settings.video.crop_overscan); break; - case SNES_ENVIRONMENT_GET_CAN_DUPE: + case RETRO_ENVIRONMENT_GET_CAN_DUPE: #ifdef HAVE_FFMPEG *(bool*)data = true; SSNES_LOG("Environ GET_CAN_DUPE: true\n"); @@ -251,9 +251,9 @@ static bool environment_cb(unsigned cmd, void *data) #endif break; - case SNES_ENVIRONMENT_GET_VARIABLE: + case RETRO_ENVIRONMENT_GET_VARIABLE: { - struct snes_variable *var = (struct snes_variable*)data; + struct retro_variable *var = (struct retro_variable*)data; if (var->key) { // Split string has '\0' delimiters so we have to find the position in original string, @@ -278,11 +278,11 @@ static bool environment_cb(unsigned cmd, void *data) break; } - case SNES_ENVIRONMENT_SET_VARIABLES: + case RETRO_ENVIRONMENT_SET_VARIABLES: { SSNES_LOG("Environ SET_VARIABLES:\n"); SSNES_LOG("=======================\n"); - const struct snes_variable *vars = (const struct snes_variable*)data; + const struct retro_variable *vars = (const struct retro_variable*)data; while (vars->key) { SSNES_LOG("\t%s :: %s\n", @@ -295,16 +295,16 @@ static bool environment_cb(unsigned cmd, void *data) break; } - case SNES_ENVIRONMENT_SET_MESSAGE: + case RETRO_ENVIRONMENT_SET_MESSAGE: { - const struct snes_message *msg = (const struct snes_message*)data; + const struct retro_message *msg = (const struct retro_message*)data; SSNES_LOG("Environ SET_MESSAGE: %s\n", msg->msg); if (g_extern.msg_queue) msg_queue_push(g_extern.msg_queue, msg->msg, 1, msg->frames); break; } - case SNES_ENVIRONMENT_SET_ROTATION: + case RETRO_ENVIRONMENT_SET_ROTATION: { unsigned rotation = *(const unsigned*)data; SSNES_LOG("Environ SET_ROTATION: %u\n", rotation); @@ -330,7 +330,6 @@ static bool environment_cb(unsigned cmd, void *data) return true; } -#endif static void set_environment(void) { diff --git a/file.c b/file.c index 0eafbbc02a..3d5517ab61 100644 --- a/file.c +++ b/file.c @@ -19,7 +19,7 @@ #include "general.h" #include #include "boolean.h" -#include "libsnes.hpp" +#include "libretro.h" #include #include #include "dynamic.h" @@ -325,21 +325,21 @@ static const char *ramtype2str(int type) { switch (type) { - case SNES_MEMORY_CARTRIDGE_RAM: - case SNES_MEMORY_GAME_BOY_RAM: - case SNES_MEMORY_BSX_RAM: + case RETRO_MEMORY_SAVE_RAM: + case RETRO_MEMORY_SNES_GAME_BOY_RAM: + case RETRO_MEMORY_SNES_BSX_RAM: return ".srm"; - case SNES_MEMORY_CARTRIDGE_RTC: - case SNES_MEMORY_GAME_BOY_RTC: + case RETRO_MEMORY_RTC: + case RETRO_MEMORY_SNES_GAME_BOY_RTC: return ".rtc"; - case SNES_MEMORY_BSX_PRAM: + case RETRO_MEMORY_SNES_BSX_PRAM: return ".pram"; - case SNES_MEMORY_SUFAMI_TURBO_A_RAM: + case RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM: return ".aram"; - case SNES_MEMORY_SUFAMI_TURBO_B_RAM: + case RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM: return ".bram"; default: @@ -385,7 +385,7 @@ error: bool save_state(const char *path) { SSNES_LOG("Saving state: \"%s\".\n", path); - size_t size = psnes_serialize_size(); + size_t size = pretro_serialize_size(); if (size == 0) return false; @@ -397,7 +397,7 @@ bool save_state(const char *path) } SSNES_LOG("State size: %d bytes.\n", (int)size); - bool ret = psnes_serialize((uint8_t*)data, size); + bool ret = pretro_serialize(data, size); if (ret) ret = dump_to_file(path, data, size); @@ -421,11 +421,11 @@ bool load_state(const char *path) } bool ret = true; - SSNES_LOG("State size: %d bytes.\n", (int)size); + SSNES_LOG("State size: %u bytes.\n", (unsigned)size); - uint8_t *block_buf[2] = {NULL, NULL}; + void *block_buf[2] = {NULL, NULL}; int block_type[2] = {-1, -1}; - unsigned block_size[2] = {0}; + size_t block_size[2] = {0}; if (g_settings.block_sram_overwrite) { @@ -433,55 +433,55 @@ bool load_state(const char *path) switch (g_extern.game_type) { case SSNES_CART_NORMAL: - block_type[0] = SNES_MEMORY_CARTRIDGE_RAM; - block_type[1] = SNES_MEMORY_CARTRIDGE_RTC; + block_type[0] = RETRO_MEMORY_SAVE_RAM; + block_type[1] = RETRO_MEMORY_RTC; break; case SSNES_CART_BSX: case SSNES_CART_BSX_SLOTTED: - block_type[0] = SNES_MEMORY_BSX_RAM; - block_type[1] = SNES_MEMORY_BSX_PRAM; + block_type[0] = RETRO_MEMORY_SNES_BSX_RAM; + block_type[1] = RETRO_MEMORY_SNES_BSX_PRAM; break; case SSNES_CART_SUFAMI: - block_type[0] = SNES_MEMORY_SUFAMI_TURBO_A_RAM; - block_type[1] = SNES_MEMORY_SUFAMI_TURBO_B_RAM; + block_type[0] = RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM; + block_type[1] = RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM; break; case SSNES_CART_SGB: - block_type[0] = SNES_MEMORY_GAME_BOY_RAM; - block_type[1] = SNES_MEMORY_GAME_BOY_RTC; + block_type[0] = RETRO_MEMORY_SNES_GAME_BOY_RAM; + block_type[1] = RETRO_MEMORY_SNES_GAME_BOY_RTC; break; } } for (unsigned i = 0; i < 2; i++) if (block_type[i] != -1) - block_size[i] = psnes_get_memory_size(block_type[i]); + block_size[i] = pretro_get_memory_size(block_type[i]); for (unsigned i = 0; i < 2; i++) if (block_size[i]) - block_buf[i] = (uint8_t*)malloc(block_size[i]); + block_buf[i] = malloc(block_size[i]); // Backup current SRAM which is overwritten by unserialize. for (unsigned i = 0; i < 2; i++) { if (block_buf[i]) { - const uint8_t *ptr = psnes_get_memory_data(block_type[i]); + const void *ptr = pretro_get_memory_data(block_type[i]); if (ptr) memcpy(block_buf[i], ptr, block_size[i]); } } - ret = psnes_unserialize((uint8_t*)buf, size); + ret = pretro_unserialize(buf, size); // Flush back :D for (unsigned i = 0; i < 2 && ret; i++) { if (block_buf[i]) { - uint8_t *ptr = psnes_get_memory_data(block_type[i]); + void *ptr = pretro_get_memory_data(block_type[i]); if (ptr) memcpy(ptr, block_buf[i], block_size[i]); } @@ -497,8 +497,8 @@ bool load_state(const char *path) void load_ram_file(const char *path, int type) { - size_t size = psnes_get_memory_size(type); - uint8_t *data = psnes_get_memory_data(type); + size_t size = pretro_get_memory_size(type); + uint8_t *data = pretro_get_memory_data(type); if (size == 0 || !data) return; @@ -513,14 +513,14 @@ void load_ram_file(const char *path, int type) void save_ram_file(const char *path, int type) { - size_t size = psnes_get_memory_size(type); - uint8_t *data = psnes_get_memory_data(type); + size_t size = pretro_get_memory_size(type); + uint8_t *data = pretro_get_memory_data(type); if (data && size > 0) { if (!dump_to_file(path, data, size)) { - SSNES_ERR("Failed to save SNES RAM.\n"); + SSNES_ERR("Failed to save SRAM.\n"); SSNES_WARN("Attempting to recover ...\n"); dump_to_file_desperate(data, size, type); } @@ -539,190 +539,25 @@ static char *load_xml_map(const char *path) return xml_buf; } -static bool load_sgb_rom(void) -{ - void *rom_buf = NULL; - ssize_t rom_len = 0; +#define MAX_ROMS 4 - FILE *extra_rom = NULL; - void *extra_rom_buf = NULL; - ssize_t extra_rom_len = 0; - char *xml_buf = 0; +static bool load_roms(unsigned rom_type, const char **rom_paths, size_t roms) +{ bool ret = true; - if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1) + if (roms == 0) + return false; + + if (roms > MAX_ROMS) + return false; + + void *rom_buf[MAX_ROMS] = {NULL}; + ssize_t rom_len[MAX_ROMS] = {0}; + struct retro_game_info info[MAX_ROMS] = {{NULL}}; + + if (!g_extern.system.info.need_fullpath) { - SSNES_ERR("Could not read ROM file.\n"); - ret = false; - goto end; - } - - if ((extra_rom_len = read_file(g_extern.gb_rom_path, &extra_rom_buf)) == -1) - { - SSNES_ERR("Cannot read GameBoy rom.\n"); - ret = false; - goto end; - } - - xml_buf = load_xml_map(g_extern.xml_name); - - if (!psnes_load_cartridge_super_game_boy( - xml_buf, (const uint8_t*)rom_buf, rom_len, - NULL, (const uint8_t*)extra_rom_buf, extra_rom_len)) - { - SSNES_ERR("Cannot load SGB/GameBoy rom.\n"); - ret = false; - goto end; - } - - if (xml_buf) - free(xml_buf); - -end: - if (g_extern.rom_file) - fclose(g_extern.rom_file); - if (extra_rom) - fclose(extra_rom); - free(rom_buf); - free(extra_rom_buf); - return ret; -} - -static bool load_bsx_rom(bool slotted) -{ - void *rom_buf = NULL; - ssize_t rom_len = 0; - - FILE *extra_rom = NULL; - void *extra_rom_buf = NULL; - ssize_t extra_rom_len = 0; - char *xml_buf = 0; - bool ret = true; - - if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1) - { - SSNES_ERR("Could not read ROM file.\n"); - ret = false; - goto end; - } - - if ((extra_rom_len = read_file(g_extern.bsx_rom_path, &extra_rom_buf)) == -1) - { - SSNES_ERR("Cannot read BSX game rom.\n"); - ret = false; - goto end; - } - - xml_buf = load_xml_map(g_extern.xml_name); - - if (slotted) - { - if (!psnes_load_cartridge_bsx_slotted( - xml_buf, (const uint8_t*)rom_buf, rom_len, - NULL, (const uint8_t*)extra_rom_buf, extra_rom_len)) - { - SSNES_ERR("Cannot load BSX slotted rom.\n"); - ret = false; - goto end; - } - - } - else - { - if (!psnes_load_cartridge_bsx( - NULL, (const uint8_t*)rom_buf, rom_len, - NULL, (const uint8_t*)extra_rom_buf, extra_rom_len)) - { - SSNES_ERR("Cannot load BSX rom.\n"); - ret = false; - goto end; - } - } - - if (xml_buf) - free(xml_buf); - -end: - if (g_extern.rom_file) - fclose(g_extern.rom_file); - if (extra_rom) - fclose(extra_rom); - free(rom_buf); - free(extra_rom_buf); - return ret; -} - -static bool load_sufami_rom(void) -{ - void *rom_buf = NULL; - ssize_t rom_len = 0; - - FILE *extra_rom[2] = {NULL}; - void *extra_rom_buf[2] = {NULL}; - ssize_t extra_rom_len[2] = {0}; - char *xml_buf = 0; - const char *roms[2] = {0}; - bool ret = true; - - if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1) - { - SSNES_ERR("Could not read ROM file.\n"); - ret = false; - goto end; - } - - roms[0] = g_extern.sufami_rom_path[0]; - roms[1] = g_extern.sufami_rom_path[1]; - - for (unsigned i = 0; i < 2; i++) - { - if (*(roms[i])) - { - if ((extra_rom_len[i] = read_file(roms[i], &extra_rom_buf[i])) == -1) - { - SSNES_ERR("Cannot read Sufami game rom.\n"); - ret = false; - goto end; - } - } - } - - xml_buf = load_xml_map(g_extern.xml_name); - - if (!psnes_load_cartridge_sufami_turbo( - xml_buf, (const uint8_t*)rom_buf, rom_len, - NULL, (const uint8_t*)extra_rom_buf[0], extra_rom_len[0], - NULL, (const uint8_t*)extra_rom_buf[1], extra_rom_len[1])) - { - SSNES_ERR("Cannot load Sufami Turbo rom.\n"); - ret = false; - goto end; - } - - if (xml_buf) - free(xml_buf); - -end: - if (g_extern.rom_file) - fclose(g_extern.rom_file); - for (unsigned i = 0; i < 2; i++) - { - if (extra_rom[i]) - fclose(extra_rom[i]); - free(extra_rom_buf[i]); - } - free(rom_buf); - return ret; -} - -static bool load_normal_rom(void) -{ - void *rom_buf = NULL; - ssize_t rom_len = 0; - - if (!g_extern.system.need_fullpath) - { - if ((rom_len = read_rom_file(g_extern.rom_file, &rom_buf)) == -1) + if ((rom_len[0] = read_rom_file(g_extern.rom_file, &rom_buf[0])) == -1) { SSNES_ERR("Could not read ROM file.\n"); return false; @@ -731,7 +566,7 @@ static bool load_normal_rom(void) if (g_extern.rom_file) fclose(g_extern.rom_file); - SSNES_LOG("ROM size: %d bytes\n", (int)rom_len); + SSNES_LOG("ROM size: %u bytes.\n", (unsigned)rom_len[0]); } else { @@ -744,20 +579,81 @@ static bool load_normal_rom(void) fclose(g_extern.rom_file); SSNES_LOG("ROM loading skipped. Implementation will load it on its own.\n"); } - + char *xml_buf = load_xml_map(g_extern.xml_name); - if (!psnes_load_cartridge_normal(xml_buf, (const uint8_t*)rom_buf, rom_len)) + info[0].path = rom_paths[0]; + info[0].data = rom_buf[0]; + info[0].size = rom_len[0]; + info[0].meta = xml_buf; + + for (size_t i = 1; i < roms; i++) { - SSNES_ERR("ROM file is not valid.\n"); - free(rom_buf); - free(xml_buf); - return false; + if (rom_paths[i] && + !g_extern.system.info.need_fullpath && + (rom_len[i] = read_file(rom_paths[i], &rom_buf[i])) == -1) + { + SSNES_ERR("Could not read ROM file: \"%s\".\n", rom_paths[i]); + ret = false; + goto end; + } + + info[i].path = rom_paths[i]; + info[i].data = rom_buf[i]; + info[i].size = rom_len[i]; } + if (rom_type == 0) + ret = retro_load_game(&info[0]); + else + ret = retro_load_game_special(rom_type, info, roms); + + if (!ret) + SSNES_ERR("Failed to load game.\n"); + +end: + for (unsigned i = 0; i < MAX_ROMS; i++) + free(rom_buf[i]); free(xml_buf); - free(rom_buf); - return true; + + return ret; +} + +static bool load_normal_rom(void) +{ + const char *path = *g_extern.fullpath ? g_extern.fullpath : NULL; + return load_roms(0, &path, 1); +} + +static bool load_sgb_rom(void) +{ + const char *path[2] = { + *g_extern.fullpath ? g_extern.fullpath : NULL, + g_extern.gb_rom_path + }; + + return load_roms(RETRO_GAME_TYPE_SUPER_GAME_BOY, path, 2); +} + +static bool load_bsx_rom(bool slotted) +{ + const char *path[2] = { + *g_extern.fullpath ? g_extern.fullpath : NULL, + g_extern.bsx_rom_path + }; + + return load_roms(slotted ? RETRO_GAME_TYPE_BSX_SLOTTED : RETRO_GAME_TYPE_BSX, path, 2); +} + +static bool load_sufami_rom(void) +{ + const char *path[3] = { + *g_extern.fullpath ? g_extern.fullpath : NULL, + g_extern.sufami_rom_path[0] ? g_extern.sufami_rom_path[0] : NULL, + g_extern.sufami_rom_path[1] ? g_extern.sufami_rom_path[1] : NULL, + }; + + return load_roms(RETRO_GAME_TYPE_SUFAMI_TURBO, path, 3); } bool init_rom_file(enum ssnes_game_type type) diff --git a/general.h b/general.h index 6f566ede51..56c8d184ec 100644 --- a/general.h +++ b/general.h @@ -278,6 +278,7 @@ struct global #endif char basename[PATH_MAX]; + char fullpath[PATH_MAX]; char savefile_name_srm[PATH_MAX]; char savefile_name_rtc[PATH_MAX]; // Make sure that fill_pathname has space. char savefile_name_psrm[PATH_MAX]; @@ -298,11 +299,8 @@ struct global struct { - struct retro_game_geometry geom; - struct retro_system_timing timing; struct retro_system_info info; - - char fullpath[PATH_MAX]; + struct retro_system_av_info av_info; char *environment; char *environment_split; diff --git a/gfx/gl.c b/gfx/gl.c index a6d2dc076d..b3c221a63b 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -19,7 +19,7 @@ #include "../driver.h" #include -#include "../libsnes.hpp" +#include "../libretro.h" #include #include #include "../general.h" diff --git a/gfx/xvideo.c b/gfx/xvideo.c index 483ae951aa..b0060d9a7b 100644 --- a/gfx/xvideo.c +++ b/gfx/xvideo.c @@ -467,8 +467,9 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo attributes.border_pixel = 0; attributes.event_mask = StructureNotifyMask | DestroyNotify | ClientMessage; - width = video->fullscreen ? ((video->width == 0) ? g_extern.system.geom.base_width : video->width) : video->width; - height = video->fullscreen ? ((video->height == 0) ? g_extern.system.geom.base_height : video->height) : video->height; + const struct retro_game_geometry *geom = &g_extern.system.av_info.geometry; + width = video->fullscreen ? ((video->width == 0) ? geom->base_width : video->width) : video->width; + height = video->fullscreen ? ((video->height == 0) ? geom->base_height : video->height) : video->height; xv->window = XCreateWindow(xv->display, DefaultRootWindow(xv->display), 0, 0, width, height, 0, xv->depth, InputOutput, visualinfo->visual, @@ -492,8 +493,8 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo atom = XInternAtom(xv->display, "XV_AUTOPAINT_COLORKEY", true); if (atom != None) XvSetPortAttribute(xv->display, xv->port, atom, 1); - xv->width = g_extern.system.geom.max_width; - xv->height = g_extern.system.geom.max_height; + xv->width = geom->max_width; + xv->height = geom->max_height; xv->image = XvShmCreateImage(xv->display, xv->port, xv->fourcc, NULL, xv->width, xv->height, &xv->shminfo); if (!xv->image) diff --git a/input/sdl_input.c b/input/sdl_input.c index de7183a0bf..d1210aeb0d 100644 --- a/input/sdl_input.c +++ b/input/sdl_input.c @@ -22,7 +22,7 @@ #include "../general.h" #include #include -#include "../libsnes.hpp" +#include "../libretro.h" #include "ssnes_sdl_input.h" #include "keysym.h" @@ -293,78 +293,51 @@ static int16_t sdl_mouse_device_state(sdl_input_t *sdl, unsigned id) { switch (id) { - case SNES_DEVICE_ID_MOUSE_LEFT: + case RETRO_DEVICE_ID_MOUSE_LEFT: return sdl->mouse_l; - case SNES_DEVICE_ID_MOUSE_RIGHT: + case RETRO_DEVICE_ID_MOUSE_RIGHT: return sdl->mouse_r; - case SNES_DEVICE_ID_MOUSE_X: + case RETRO_DEVICE_ID_MOUSE_X: return sdl->mouse_x; - case SNES_DEVICE_ID_MOUSE_Y: + case RETRO_DEVICE_ID_MOUSE_Y: return sdl->mouse_y; default: return 0; } } -// TODO: Missing some controllers, but hey :) -static int16_t sdl_scope_device_state(sdl_input_t *sdl, unsigned id) +static int16_t sdl_lightgun_device_state(sdl_input_t *sdl, unsigned id) { switch (id) { - case SNES_DEVICE_ID_SUPER_SCOPE_X: + case RETRO_DEVICE_ID_LIGHTGUN_X: return sdl->mouse_x; - case SNES_DEVICE_ID_SUPER_SCOPE_Y: + case RETRO_DEVICE_ID_LIGHTGUN_Y: return sdl->mouse_y; - case SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER: + case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: return sdl->mouse_l; - case SNES_DEVICE_ID_SUPER_SCOPE_CURSOR: + case RETRO_DEVICE_ID_LIGHTGUN_CURSOR: return sdl->mouse_m; - case SNES_DEVICE_ID_SUPER_SCOPE_TURBO: + case RETRO_DEVICE_ID_LIGHTGUN_TURBO: return sdl->mouse_r; default: return 0; } } -// TODO: Support two players. -static int16_t sdl_justifier_device_state(sdl_input_t *sdl, unsigned index, unsigned id) -{ - if (index == 0) - { - switch (id) - { - case SNES_DEVICE_ID_JUSTIFIER_X: - return sdl->mouse_x; - case SNES_DEVICE_ID_JUSTIFIER_Y: - return sdl->mouse_y; - case SNES_DEVICE_ID_JUSTIFIER_TRIGGER: - return sdl->mouse_l; - case SNES_DEVICE_ID_JUSTIFIER_START: - return sdl->mouse_r; - default: - return 0; - } - } - else - return 0; -} - static int16_t sdl_input_state(void *data_, const struct snes_keybind **binds, bool port, unsigned device, unsigned index, unsigned id) { sdl_input_t *data = (sdl_input_t*)data_; switch (device) { - case SNES_DEVICE_JOYPAD: - return sdl_joypad_device_state(data, binds, (port == SNES_PORT_1) ? 0 : 1, id); - case SNES_DEVICE_MULTITAP: - return sdl_joypad_device_state(data, binds, (port == SNES_PORT_2) ? 1 + index : 0, id); - case SNES_DEVICE_MOUSE: + case RETRO_DEVICE_JOYPAD: + return sdl_joypad_device_state(data, binds, port, id); + case RETRO_DEVICE_JOYPAD_MULTITAP: + return sdl_joypad_device_state(data, binds, (port == 1) ? 1 + index : 0, id); + case RETRO_DEVICE_MOUSE: return sdl_mouse_device_state(data, id); - case SNES_DEVICE_SUPER_SCOPE: - return sdl_scope_device_state(data, id); - case SNES_DEVICE_JUSTIFIER: - case SNES_DEVICE_JUSTIFIERS: - return sdl_justifier_device_state(data, index, id); + case RETRO_DEVICE_LIGHTGUN: + return sdl_lightgun_device_state(data, id); default: return 0; diff --git a/input/x11_input.c b/input/x11_input.c index 68a024763e..f1b2f9d2ba 100644 --- a/input/x11_input.c +++ b/input/x11_input.c @@ -191,12 +191,12 @@ static int16_t x_input_state(void *data, const struct snes_keybind **binds, bool switch (device) { - case SNES_DEVICE_JOYPAD: - return x_is_pressed(x11, binds[(port == SNES_PORT_1) ? 0 : 1], id) || + case RETRO_DEVICE_JOYPAD: + return x_is_pressed(x11, binds[port], id) || input_sdl.input_state(x11->sdl, binds, port, device, index, id); - case SNES_DEVICE_MULTITAP: - return x_is_pressed(x11, binds[(port == SNES_PORT_2) ? 1 + index : 0], id) || + case RETRO_DEVICE_JOYPAD_MULTITAP: + return x_is_pressed(x11, binds[(port == 1) ? 1 + index : 0], id) || input_sdl.input_state(x11->sdl, binds, port, device, index, id); default: diff --git a/libretro.h b/libretro.h index 67c90e9aba..88bc5e1119 100755 --- a/libretro.h +++ b/libretro.h @@ -144,9 +144,14 @@ struct retro_variable struct retro_game_info { - const char *path; // Path to game. Usually used as a reference. - const void *data; // Memory buffer of loaded game. If the game is too big to load in one go. SET_NEED_FULLPATH should be used. - // In this case, data and size will be 0, and game can be loaded from path. + const char *path; // Path to game, UTF-8 encoded. Usually used as a reference. + // May be NULL if rom was loaded from stdin or similar. + // SET_NEED_FULLPATH path guaranteed that this path is valid. + const void *data; // Memory buffer of loaded game. + // If the game is too big to load in one go. + // SET_NEED_FULLPATH should be used. + // In this case, data and size will be 0, + // and game can be loaded from path. size_t size; // Size of memory buffer. const char *meta; // String of implementation specific meta-data. }; diff --git a/movie.c b/movie.c index 7063c308a4..425a1ab9b6 100644 --- a/movie.c +++ b/movie.c @@ -82,8 +82,8 @@ static bool init_playback(bsv_movie_t *handle, const char *path) return false; } - if (psnes_serialize_size() == state_size) - psnes_unserialize(handle->state, state_size); + if (pretro_serialize_size() == state_size) + pretro_unserialize(handle->state, state_size); else SSNES_WARN("Movie format seems to have a different serializer version. Will most likely fail.\n"); } @@ -109,7 +109,7 @@ static bool init_record(bsv_movie_t *handle, const char *path) header[CRC_INDEX] = swap_if_big32(g_extern.cart_crc); - uint32_t state_size = psnes_serialize_size(); + uint32_t state_size = pretro_serialize_size(); header[STATE_SIZE_INDEX] = swap_if_big32(state_size); fwrite(header, 4, sizeof(uint32_t), handle->file); @@ -123,7 +123,7 @@ static bool init_record(bsv_movie_t *handle, const char *path) if (!handle->state) return false; - psnes_serialize(handle->state, state_size); + pretro_serialize(handle->state, state_size); fwrite(handle->state, 1, state_size, handle->file); } @@ -224,7 +224,7 @@ void bsv_movie_frame_rewind(bsv_movie_t *handle) if (!handle->playback) { fseek(handle->file, 4 * sizeof(uint32_t), SEEK_SET); - psnes_serialize(handle->state, handle->state_size); + pretro_serialize(handle->state, handle->state_size); fwrite(handle->state, 1, handle->state_size, handle->file); } else diff --git a/netplay.c b/netplay.c index e1584643c7..67f1e9d276 100644 --- a/netplay.c +++ b/netplay.c @@ -63,7 +63,6 @@ static int16_t netplay_input_state(netplay_t *handle, bool port, unsigned device // If we're fast-forward replaying to resync, check if we should actually show frame. static bool netplay_should_skip(netplay_t *handle); static bool netplay_can_poll(netplay_t *handle); -static const struct snes_callbacks* netplay_callbacks(netplay_t *handle); static void netplay_set_spectate_input(netplay_t *handle, int16_t input); static bool netplay_send_cmd(netplay_t *handle, uint32_t cmd, const void *data, size_t size); @@ -74,7 +73,7 @@ static bool netplay_get_cmd(netplay_t *handle); struct delta_frame { - uint8_t *state; + void *state; uint16_t real_input_state; uint16_t simulated_input_state; @@ -96,7 +95,7 @@ struct netplay char other_nick[32]; struct sockaddr_storage other_addr; - struct snes_callbacks cbs; + struct retro_callbacks cbs; int fd; // TCP connection for state sending, etc. Also used for commands. int udp_fd; // UDP connection for game state updates. unsigned port; // Which port is governed by netplay (other player)? @@ -188,24 +187,32 @@ void input_poll_net(void) netplay_poll(g_extern.netplay); } -void video_frame_net(const uint16_t *data, unsigned width, unsigned height) +void video_frame_net(const void *data, unsigned width, unsigned height, size_t pitch) { if (!netplay_should_skip(g_extern.netplay)) - netplay_callbacks(g_extern.netplay)->frame_cb(data, width, height); + g_extern.netplay->cbs.frame_cb(data, width, height, pitch); } -void audio_sample_net(uint16_t left, uint16_t right) +void audio_sample_net(int16_t left, int16_t right) { if (!netplay_should_skip(g_extern.netplay)) - netplay_callbacks(g_extern.netplay)->sample_cb(left, right); + g_extern.netplay->cbs.sample_cb(left, right); } -int16_t input_state_net(bool port, unsigned device, unsigned index, unsigned id) +size_t audio_sample_batch_net(const int16_t *data, size_t frames) +{ + if (!netplay_should_skip(g_extern.netplay)) + return g_extern.netplay->cbs.sample_batch_cb(data, frames); + else + return frames; +} + +int16_t input_state_net(unsigned port, unsigned device, unsigned index, unsigned id) { if (netplay_is_alive(g_extern.netplay)) return netplay_input_state(g_extern.netplay, port, device, index, id); else - return netplay_callbacks(g_extern.netplay)->state_cb(port, device, index, id); + return g_extern.netplay->cbs.state_cb(port, device, index, id); } #ifndef HAVE_SOCKET_LEGACY @@ -447,18 +454,20 @@ bool netplay_can_poll(netplay_t *handle) static uint32_t implementation_magic_value(void) { uint32_t res = 0; - unsigned major = psnes_library_revision_major(); - unsigned minor = psnes_library_revision_minor(); + unsigned api = pretro_api_version(); - res |= (major & 0xf) << 0; - res |= (minor & 0xf) << 4; + res |= api; - // Shouldn't really use this, but oh well :) It'll do the job. - const char *lib = psnes_library_id(); + const char *lib = g_extern.system.info.library_name; size_t len = strlen(lib); for (size_t i = 0; i < len; i++) res ^= lib[i] << (i & 0xf); + lib = g_extern.system.info.library_version; + len = strlen(lib); + for (size_t i = 0; i < len; i++) + res ^= lib[i] << (i & 0xf); + const char *ver = PACKAGE_VERSION; len = strlen(ver); for (size_t i = 0; i < len; i++) @@ -516,7 +525,7 @@ static bool send_info(netplay_t *handle) uint32_t header[3] = { htonl(g_extern.cart_crc), htonl(implementation_magic_value()), - htonl(psnes_get_memory_size(SNES_MEMORY_CARTRIDGE_RAM)) + htonl(pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM)) }; if (!send_all(handle->fd, header, sizeof(header))) @@ -528,9 +537,9 @@ static bool send_info(netplay_t *handle) return false; } - // Get SRAM data from Player 1 :) - uint8_t *sram = psnes_get_memory_data(SNES_MEMORY_CARTRIDGE_RAM); - unsigned sram_size = psnes_get_memory_size(SNES_MEMORY_CARTRIDGE_RAM); + // Get SRAM data from Player 1. + void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM); + unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM); if (!recv_all(handle->fd, sram, sram_size)) { @@ -574,7 +583,7 @@ static bool get_info(netplay_t *handle) return false; } - if (psnes_get_memory_size(SNES_MEMORY_CARTRIDGE_RAM) != ntohl(header[2])) + if (pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM) != ntohl(header[2])) { SSNES_ERR("Cartridge SRAM sizes do not correspond.\n"); return false; @@ -586,9 +595,9 @@ static bool get_info(netplay_t *handle) return false; } - // Send SRAM data to our Player 2 :) - const uint8_t *sram = psnes_get_memory_data(SNES_MEMORY_CARTRIDGE_RAM); - unsigned sram_size = psnes_get_memory_size(SNES_MEMORY_CARTRIDGE_RAM); + // Send SRAM data to our Player 2. + const void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM); + unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM); if (!send_all(handle->fd, sram, sram_size)) { SSNES_ERR("Failed to send SRAM data to client.\n"); @@ -611,7 +620,7 @@ static bool get_info(netplay_t *handle) static uint32_t *bsv_header_generate(size_t *size, uint32_t magic) { uint32_t bsv_header[4] = {0}; - unsigned serialize_size = psnes_serialize_size(); + size_t serialize_size = pretro_serialize_size(); size_t header_size = sizeof(bsv_header) + serialize_size; *size = header_size; @@ -624,7 +633,7 @@ static uint32_t *bsv_header_generate(size_t *size, uint32_t magic) bsv_header[CRC_INDEX] = swap_if_big32(g_extern.cart_crc); bsv_header[STATE_SIZE_INDEX] = swap_if_big32(serialize_size); - if (serialize_size && !psnes_serialize((uint8_t*)header + sizeof(bsv_header), serialize_size)) + if (serialize_size && !pretro_serialize(header + sizeof(bsv_header), serialize_size)) { free(header); return NULL; @@ -659,10 +668,10 @@ static bool bsv_parse_header(const uint32_t *header, uint32_t magic) } uint32_t in_state_size = swap_if_big32(header[STATE_SIZE_INDEX]); - if (in_state_size != psnes_serialize_size()) + if (in_state_size != pretro_serialize_size()) { SSNES_ERR("Serialization size mismatch, got 0x%x, expected 0x%x.\n", - in_state_size, psnes_serialize_size()); + (unsigned)in_state_size, (unsigned)pretro_serialize_size()); return false; } @@ -696,30 +705,29 @@ static bool get_info_spectate(netplay_t *handle) return false; } - unsigned save_state_size = psnes_serialize_size(); + size_t save_state_size = pretro_serialize_size(); if (!bsv_parse_header(header, implementation_magic_value())) { SSNES_ERR("Received invalid BSV header from host.\n"); return false; } - uint8_t *buf = (uint8_t*)malloc(save_state_size); + void *buf = malloc(save_state_size); if (!buf) return false; size_t size = save_state_size; - uint8_t *tmp_buf = buf; - if (!recv_all(handle->fd, tmp_buf, size)) + if (!recv_all(handle->fd, buf, size)) { SSNES_ERR("Failed to receive save state from host.\n"); - free(tmp_buf); + free(buf); return false; } bool ret = true; if (save_state_size) - ret = psnes_unserialize(buf, save_state_size); + ret = pretro_unserialize(buf, save_state_size); free(buf); return ret; @@ -728,16 +736,16 @@ static bool get_info_spectate(netplay_t *handle) static void init_buffers(netplay_t *handle) { handle->buffer = (struct delta_frame*)calloc(handle->buffer_size, sizeof(*handle->buffer)); - handle->state_size = psnes_serialize_size(); + handle->state_size = pretro_serialize_size(); for (unsigned i = 0; i < handle->buffer_size; i++) { - handle->buffer[i].state = (uint8_t*)malloc(handle->state_size); + handle->buffer[i].state = malloc(handle->state_size); handle->buffer[i].is_simulated = true; } } netplay_t *netplay_new(const char *server, uint16_t port, - unsigned frames, const struct snes_callbacks *cb, + unsigned frames, const struct retro_callbacks *cb, bool spectate, const char *nick) { @@ -896,11 +904,11 @@ static bool get_self_input_state(netplay_t *handle) uint32_t state = 0; if (handle->frame_count > 0) // First frame we always give zero input since relying on input from first frame screws up when we use -F 0. { - snes_input_state_t cb = handle->cbs.state_cb; + retro_input_state_t cb = handle->cbs.state_cb; for (unsigned i = 0; i < SSNES_FIRST_META_KEY; i++) { int16_t tmp = cb(g_settings.input.netplay_client_swap_input ? 0 : !handle->port, - SNES_DEVICE_JOYPAD, 0, i); + RETRO_DEVICE_JOYPAD, 0, i); state |= tmp ? 1 << i : 0; } } @@ -1221,11 +1229,6 @@ void netplay_free(netplay_t *handle) free(handle); } -static const struct snes_callbacks* netplay_callbacks(netplay_t *handle) -{ - return &handle->cbs; -} - static bool netplay_should_skip(netplay_t *handle) { return handle->is_replay && handle->has_connection; @@ -1233,7 +1236,7 @@ static bool netplay_should_skip(netplay_t *handle) static void netplay_pre_frame_net(netplay_t *handle) { - psnes_serialize(handle->buffer[handle->self_ptr].state, handle->state_size); + pretro_serialize(handle->buffer[handle->self_ptr].state, handle->state_size); handle->can_poll = true; input_poll_net(); @@ -1252,9 +1255,9 @@ static void netplay_set_spectate_input(netplay_t *handle, int16_t input) handle->spectate_input[handle->spectate_input_ptr++] = swap_if_big16(input); } -int16_t input_state_spectate(bool port, unsigned device, unsigned index, unsigned id) +int16_t input_state_spectate(unsigned port, unsigned device, unsigned index, unsigned id) { - int16_t res = netplay_callbacks(g_extern.netplay)->state_cb(port, device, index, id); + int16_t res = g_extern.netplay->cbs.state_cb(port, device, index, id); netplay_set_spectate_input(g_extern.netplay, res); return res; } @@ -1270,12 +1273,12 @@ static int16_t netplay_get_spectate_input(netplay_t *handle, bool port, unsigned msg_queue_clear(g_extern.msg_queue); msg_queue_push(g_extern.msg_queue, "Connection with host was cut.", 1, 180); - psnes_set_input_state(netplay_callbacks(g_extern.netplay)->state_cb); - return netplay_callbacks(g_extern.netplay)->state_cb(port, device, index, id); + pretro_set_input_state(g_extern.netplay->cbs.state_cb); + return g_extern.netplay->cbs.state_cb(port, device, index, id); } } -int16_t input_state_spectate_client(bool port, unsigned device, unsigned index, unsigned id) +int16_t input_state_spectate_client(unsigned port, unsigned device, unsigned index, unsigned id) { return netplay_get_spectate_input(g_extern.netplay, port, device, index, id); } @@ -1397,15 +1400,15 @@ static void netplay_post_frame_net(netplay_t *handle) handle->tmp_ptr = handle->other_ptr; handle->tmp_frame_count = handle->other_frame_count; - psnes_unserialize(handle->buffer[handle->other_ptr].state, handle->state_size); + pretro_unserialize(handle->buffer[handle->other_ptr].state, handle->state_size); bool first = true; while (first || (handle->tmp_ptr != handle->self_ptr)) { - psnes_serialize(handle->buffer[handle->tmp_ptr].state, handle->state_size); + pretro_serialize(handle->buffer[handle->tmp_ptr].state, handle->state_size); #ifdef HAVE_THREADS lock_autosave(); #endif - psnes_run(); + pretro_run(); #ifdef HAVE_THREADS unlock_autosave(); #endif diff --git a/netplay.h b/netplay.h index ae3be470e5..9f14bb23d4 100644 --- a/netplay.h +++ b/netplay.h @@ -26,9 +26,9 @@ void input_poll_net(void); int16_t input_state_net(unsigned port, unsigned device, unsigned index, unsigned id); -void video_frame_net(const uint16_t *data, unsigned width, unsigned height, size_t pitch); +void video_frame_net(const void *data, unsigned width, unsigned height, size_t pitch); void audio_sample_net(int16_t left, int16_t right); -void audio_sample_batch_net(const int16_t *data, size_t frames); +size_t audio_sample_batch_net(const int16_t *data, size_t frames); int16_t input_state_spectate(unsigned port, unsigned device, unsigned index, unsigned id); int16_t input_state_spectate_client(unsigned port, unsigned device, unsigned index, unsigned id); diff --git a/settings.c b/settings.c index 87e18b19a4..7f93c4321d 100644 --- a/settings.c +++ b/settings.c @@ -525,35 +525,35 @@ struct bind_map #define DECLARE_BIND(x, bind) { true, "input_" #x, "input_" #x "_btn", "input_" #x "_axis", bind } #define DECL_PLAYER(P) \ { \ - DECLARE_BIND(player##P##_b, SNES_DEVICE_ID_JOYPAD_B), \ - DECLARE_BIND(player##P##_y, SNES_DEVICE_ID_JOYPAD_Y), \ - DECLARE_BIND(player##P##_select, SNES_DEVICE_ID_JOYPAD_SELECT), \ - DECLARE_BIND(player##P##_start, SNES_DEVICE_ID_JOYPAD_START), \ - DECLARE_BIND(player##P##_up, SNES_DEVICE_ID_JOYPAD_UP), \ - DECLARE_BIND(player##P##_down, SNES_DEVICE_ID_JOYPAD_DOWN), \ - DECLARE_BIND(player##P##_left, SNES_DEVICE_ID_JOYPAD_LEFT), \ - DECLARE_BIND(player##P##_right, SNES_DEVICE_ID_JOYPAD_RIGHT), \ - DECLARE_BIND(player##P##_a, SNES_DEVICE_ID_JOYPAD_A), \ - DECLARE_BIND(player##P##_x, SNES_DEVICE_ID_JOYPAD_X), \ - DECLARE_BIND(player##P##_l, SNES_DEVICE_ID_JOYPAD_L), \ - DECLARE_BIND(player##P##_r, SNES_DEVICE_ID_JOYPAD_R), \ + DECLARE_BIND(player##P##_b, RETRO_DEVICE_ID_JOYPAD_B), \ + DECLARE_BIND(player##P##_y, RETRO_DEVICE_ID_JOYPAD_Y), \ + DECLARE_BIND(player##P##_select, RETRO_DEVICE_ID_JOYPAD_SELECT), \ + DECLARE_BIND(player##P##_start, RETRO_DEVICE_ID_JOYPAD_START), \ + DECLARE_BIND(player##P##_up, RETRO_DEVICE_ID_JOYPAD_UP), \ + DECLARE_BIND(player##P##_down, RETRO_DEVICE_ID_JOYPAD_DOWN), \ + DECLARE_BIND(player##P##_left, RETRO_DEVICE_ID_JOYPAD_LEFT), \ + DECLARE_BIND(player##P##_right, RETRO_DEVICE_ID_JOYPAD_RIGHT), \ + DECLARE_BIND(player##P##_a, RETRO_DEVICE_ID_JOYPAD_A), \ + DECLARE_BIND(player##P##_x, RETRO_DEVICE_ID_JOYPAD_X), \ + DECLARE_BIND(player##P##_l, RETRO_DEVICE_ID_JOYPAD_L), \ + DECLARE_BIND(player##P##_r, RETRO_DEVICE_ID_JOYPAD_R), \ } // Big and nasty bind map... :) static const struct bind_map bind_maps[MAX_PLAYERS][SSNES_BIND_LIST_END] = { { - DECLARE_BIND(player1_b, SNES_DEVICE_ID_JOYPAD_B), - DECLARE_BIND(player1_y, SNES_DEVICE_ID_JOYPAD_Y), - DECLARE_BIND(player1_select, SNES_DEVICE_ID_JOYPAD_SELECT), - DECLARE_BIND(player1_start, SNES_DEVICE_ID_JOYPAD_START), - DECLARE_BIND(player1_up, SNES_DEVICE_ID_JOYPAD_UP), - DECLARE_BIND(player1_down, SNES_DEVICE_ID_JOYPAD_DOWN), - DECLARE_BIND(player1_left, SNES_DEVICE_ID_JOYPAD_LEFT), - DECLARE_BIND(player1_right, SNES_DEVICE_ID_JOYPAD_RIGHT), - DECLARE_BIND(player1_a, SNES_DEVICE_ID_JOYPAD_A), - DECLARE_BIND(player1_x, SNES_DEVICE_ID_JOYPAD_X), - DECLARE_BIND(player1_l, SNES_DEVICE_ID_JOYPAD_L), - DECLARE_BIND(player1_r, SNES_DEVICE_ID_JOYPAD_R), + DECLARE_BIND(player1_b, RETRO_DEVICE_ID_JOYPAD_B), + DECLARE_BIND(player1_y, RETRO_DEVICE_ID_JOYPAD_Y), + DECLARE_BIND(player1_select, RETRO_DEVICE_ID_JOYPAD_SELECT), + DECLARE_BIND(player1_start, RETRO_DEVICE_ID_JOYPAD_START), + DECLARE_BIND(player1_up, RETRO_DEVICE_ID_JOYPAD_UP), + DECLARE_BIND(player1_down, RETRO_DEVICE_ID_JOYPAD_DOWN), + DECLARE_BIND(player1_left, RETRO_DEVICE_ID_JOYPAD_LEFT), + DECLARE_BIND(player1_right, RETRO_DEVICE_ID_JOYPAD_RIGHT), + DECLARE_BIND(player1_a, RETRO_DEVICE_ID_JOYPAD_A), + DECLARE_BIND(player1_x, RETRO_DEVICE_ID_JOYPAD_X), + DECLARE_BIND(player1_l, RETRO_DEVICE_ID_JOYPAD_L), + DECLARE_BIND(player1_r, RETRO_DEVICE_ID_JOYPAD_R), DECLARE_BIND(toggle_fast_forward, SSNES_FAST_FORWARD_KEY), DECLARE_BIND(hold_fast_forward, SSNES_FAST_FORWARD_HOLD_KEY), diff --git a/ssnes.c b/ssnes.c index e91904ee09..3e72353f62 100644 --- a/ssnes.c +++ b/ssnes.c @@ -341,13 +341,22 @@ static bool audio_flush(const int16_t *data, size_t samples) } #endif -static void audio_sample_rewind(uint16_t left, uint16_t right) +static void audio_sample_rewind(int16_t left, int16_t right) { g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = right; g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = left; } -static void audio_sample(uint16_t left, uint16_t right) +size_t audio_sample_batch_rewind(const int16_t *data, size_t frames) +{ + size_t samples = frames << 1; + for (size_t i = 0; i < samples; i++) + g_extern.audio_data.rewind_buf[--g_extern.audio_data.rewind_ptr] = data[i]; + + return frames; +} + +static void audio_sample(int16_t left, int16_t right) { g_extern.audio_data.conv_outsamples[g_extern.audio_data.data_ptr++] = left; g_extern.audio_data.conv_outsamples[g_extern.audio_data.data_ptr++] = right; @@ -361,9 +370,7 @@ static void audio_sample(uint16_t left, uint16_t right) g_extern.audio_data.data_ptr = 0; } -// Non-standard, alternative callback better suited for systems that process audio in batch. -// Avoids tons of calls to audio_sample() ... -unsigned audio_sample_batch(const int16_t *data, unsigned frames) +size_t audio_sample_batch(const int16_t *data, size_t frames) { if (frames > (AUDIO_CHUNK_SIZE_NONBLOCKING >> 1)) frames = AUDIO_CHUNK_SIZE_NONBLOCKING >> 1; @@ -377,8 +384,10 @@ static void input_poll(void) input_poll_func(); } -static int16_t input_state(bool port, unsigned device, unsigned index, unsigned id) +static int16_t input_state(unsigned port, unsigned device, unsigned index, unsigned id) { + device &= RETRO_DEVICE_MASK; + #ifdef HAVE_BSV_MOVIE if (g_extern.bsv.movie && g_extern.bsv.movie_playback) { @@ -544,7 +553,7 @@ static void print_help(void) static void set_basename(const char *path) { - strlcpy(g_extern.system.fullpath, path, sizeof(g_extern.system.fullpath)); + strlcpy(g_extern.fullpath, path, sizeof(g_extern.fullpath)); strlcpy(g_extern.basename, path, sizeof(g_extern.basename)); char *dst = strrchr(g_extern.basename, '.'); @@ -1027,24 +1036,24 @@ static inline void load_save_files(void) switch (g_extern.game_type) { case SSNES_CART_NORMAL: - load_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM); - load_ram_file(g_extern.savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC); + load_ram_file(g_extern.savefile_name_srm, RETRO_MEMORY_SAVE_RAM); + load_ram_file(g_extern.savefile_name_rtc, RETRO_MEMORY_RTC); break; case SSNES_CART_SGB: - save_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_GAME_BOY_RAM); - save_ram_file(g_extern.savefile_name_rtc, SNES_MEMORY_GAME_BOY_RTC); + save_ram_file(g_extern.savefile_name_srm, RETRO_MEMORY_SNES_GAME_BOY_RAM); + save_ram_file(g_extern.savefile_name_rtc, RETRO_MEMORY_SNES_GAME_BOY_RTC); break; case SSNES_CART_BSX: case SSNES_CART_BSX_SLOTTED: - load_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_BSX_RAM); - load_ram_file(g_extern.savefile_name_psrm, SNES_MEMORY_BSX_PRAM); + load_ram_file(g_extern.savefile_name_srm, RETRO_MEMORY_SNES_BSX_RAM); + load_ram_file(g_extern.savefile_name_psrm, RETRO_MEMORY_SNES_BSX_PRAM); break; case SSNES_CART_SUFAMI: - load_ram_file(g_extern.savefile_name_asrm, SNES_MEMORY_SUFAMI_TURBO_A_RAM); - load_ram_file(g_extern.savefile_name_bsrm, SNES_MEMORY_SUFAMI_TURBO_B_RAM); + load_ram_file(g_extern.savefile_name_asrm, RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM); + load_ram_file(g_extern.savefile_name_bsrm, RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM); break; default: @@ -1058,27 +1067,27 @@ static inline void save_files(void) { case SSNES_CART_NORMAL: SSNES_LOG("Saving regular SRAM.\n"); - save_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM); - save_ram_file(g_extern.savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC); + save_ram_file(g_extern.savefile_name_srm, RETRO_MEMORY_SAVE_RAM); + save_ram_file(g_extern.savefile_name_rtc, RETRO_MEMORY_RTC); break; case SSNES_CART_SGB: SSNES_LOG("Saving Gameboy SRAM.\n"); - save_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_GAME_BOY_RAM); - save_ram_file(g_extern.savefile_name_rtc, SNES_MEMORY_GAME_BOY_RTC); + save_ram_file(g_extern.savefile_name_srm, RETRO_MEMORY_SNES_GAME_BOY_RAM); + save_ram_file(g_extern.savefile_name_rtc, RETRO_MEMORY_SNES_GAME_BOY_RTC); break; case SSNES_CART_BSX: case SSNES_CART_BSX_SLOTTED: SSNES_LOG("Saving BSX (P)RAM.\n"); - save_ram_file(g_extern.savefile_name_srm, SNES_MEMORY_BSX_RAM); - save_ram_file(g_extern.savefile_name_psrm, SNES_MEMORY_BSX_PRAM); + save_ram_file(g_extern.savefile_name_srm, RETRO_MEMORY_SNES_BSX_RAM); + save_ram_file(g_extern.savefile_name_psrm, RETRO_MEMORY_SNES_BSX_PRAM); break; case SSNES_CART_SUFAMI: SSNES_LOG("Saving Sufami turbo A/B RAM.\n"); - save_ram_file(g_extern.savefile_name_asrm, SNES_MEMORY_SUFAMI_TURBO_A_RAM); - save_ram_file(g_extern.savefile_name_bsrm, SNES_MEMORY_SUFAMI_TURBO_B_RAM); + save_ram_file(g_extern.savefile_name_asrm, RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM); + save_ram_file(g_extern.savefile_name_bsrm, RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM); break; default: @@ -1093,26 +1102,21 @@ static void init_recording(void) if (!g_extern.recording) return; - // Canonical values. - double fps = psnes_get_region() == SNES_REGION_NTSC ? 60.00 : 50.00; - double samplerate = 32000.0; - if (g_extern.system.timing_set) - { - fps = g_extern.system.timing.fps; - samplerate = g_extern.system.timing.sample_rate; - SSNES_LOG("Custom timing given: FPS: %.4f, Sample rate: %.4f\n", (float)fps, (float)samplerate); - } + double fps = g_extern.system.av_info.timing.fps; + double samplerate = g_extern.system.av_info.timing.sample_rate; + SSNES_LOG("Custom timing given: FPS: %.4f, Sample rate: %.4f\n", (float)fps, (float)samplerate); struct ffemu_params params = {0}; - params.out_width = g_extern.system.geom.base_width; - params.out_height = g_extern.system.geom.base_height; - params.fb_width = g_extern.system.geom.max_width; - params.fb_height = g_extern.system.geom.max_height; - params.channels = 2; - params.filename = g_extern.record_path; - params.fps = fps; + const struct retro_system_av_info *info = &g_extern.system.av_info; + params.out_width = info->geometry.base_width; + params.out_height = info->geometry.base_height; + params.fb_width = info->geometry.max_width; + params.fb_height = info->geometry.max_height; + params.channels = 2; + params.filename = g_extern.record_path; + params.fps = fps; params.samplerate = samplerate; - params.rgb32 = false; + params.rgb32 = false; if (g_extern.record_width || g_extern.record_height) { @@ -1191,7 +1195,7 @@ static void init_rewind(void) if (!g_settings.rewind_enable) return; - g_extern.state_size = psnes_serialize_size(); + g_extern.state_size = pretro_serialize_size(); // Make sure we allocate at least 4-byte multiple. size_t aligned_state_size = (g_extern.state_size + 3) & ~3; @@ -1203,7 +1207,7 @@ static void init_rewind(void) return; } - if (!psnes_serialize((uint8_t*)g_extern.state_buf, g_extern.state_size)) + if (!pretro_serialize(g_extern.state_buf, g_extern.state_size)) { SSNES_ERR("Failed to perform initial serialization for rewind.\n"); free(g_extern.state_buf); @@ -1279,9 +1283,10 @@ static void init_netplay(void) if (!g_extern.netplay_enable) return; - struct snes_callbacks cbs = {0}; + struct retro_callbacks cbs = {0}; cbs.frame_cb = video_frame; cbs.sample_cb = audio_sample; + cbs.sample_batch_cb = audio_sample_batch; cbs.state_cb = input_state; if (*g_extern.netplay_server) @@ -1318,32 +1323,37 @@ static void deinit_netplay(void) } #endif +static void init_libsnes_cbs_plain(void) +{ + pretro_set_video_refresh(video_frame); + pretro_set_audio_sample(audio_sample); + pretro_set_audio_sample_batch(audio_sample_batch); + pretro_set_input_state(input_state); + pretro_set_input_poll(input_poll); +} + static void init_libsnes_cbs(void) { #ifdef HAVE_NETPLAY if (g_extern.netplay) { - psnes_set_video_refresh(g_extern.netplay_is_spectate ? + pretro_set_video_refresh(g_extern.netplay_is_spectate ? video_frame : video_frame_net); - psnes_set_audio_sample(g_extern.netplay_is_spectate ? - audio_sample : audio_sample_net); - psnes_set_input_state(g_extern.netplay_is_spectate ? + pretro_set_audio_sample(g_extern.netplay_is_spectate ? + audio_sample : audio_sample_net); + pretro_set_audio_sample_batch(g_extern.netplay_is_spectate ? + audio_sample_batch : audio_sample_batch_net); + + pretro_set_input_state(g_extern.netplay_is_spectate ? (g_extern.netplay_is_client ? input_state_spectate_client : input_state_spectate) : input_state_net); } else - { - psnes_set_video_refresh(video_frame); - psnes_set_audio_sample(audio_sample); - psnes_set_input_state(input_state); - } + init_libsnes_cbs_plain(); #else - psnes_set_video_refresh(video_frame); - psnes_set_audio_sample(audio_sample); - psnes_set_input_state(input_state); + init_libsnes_cbs_plain(); #endif - psnes_set_input_poll(input_poll); } #ifdef HAVE_THREADS @@ -1356,42 +1366,42 @@ static void init_autosave(void) { case SSNES_CART_BSX: case SSNES_CART_BSX_SLOTTED: - ram_types[0] = SNES_MEMORY_BSX_RAM; - ram_types[1] = SNES_MEMORY_BSX_PRAM; + ram_types[0] = RETRO_MEMORY_SNES_BSX_RAM; + ram_types[1] = RETRO_MEMORY_SNES_BSX_PRAM; ram_paths[0] = g_extern.savefile_name_srm; ram_paths[1] = g_extern.savefile_name_psrm; break; case SSNES_CART_SUFAMI: - ram_types[0] = SNES_MEMORY_SUFAMI_TURBO_A_RAM; - ram_types[1] = SNES_MEMORY_SUFAMI_TURBO_B_RAM; + ram_types[0] = RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM; + ram_types[1] = RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM; ram_paths[0] = g_extern.savefile_name_asrm; ram_paths[1] = g_extern.savefile_name_bsrm; break; case SSNES_CART_SGB: - ram_types[0] = SNES_MEMORY_GAME_BOY_RAM; - ram_types[1] = SNES_MEMORY_GAME_BOY_RTC; + ram_types[0] = RETRO_MEMORY_SNES_GAME_BOY_RAM; + ram_types[1] = RETRO_MEMORY_SNES_GAME_BOY_RTC; ram_paths[0] = g_extern.savefile_name_srm; ram_paths[1] = g_extern.savefile_name_rtc; break; default: - ram_types[0] = SNES_MEMORY_CARTRIDGE_RAM; - ram_types[1] = SNES_MEMORY_CARTRIDGE_RTC; + ram_types[0] = RETRO_MEMORY_SAVE_RAM; + ram_types[1] = RETRO_MEMORY_RTC; ram_paths[0] = g_extern.savefile_name_srm; ram_paths[1] = g_extern.savefile_name_rtc; } if (g_settings.autosave_interval > 0) { - for (unsigned i = 0; i < sizeof(g_extern.autosave)/sizeof(g_extern.autosave[0]); i++) + for (unsigned i = 0; i < sizeof(g_extern.autosave) / sizeof(g_extern.autosave[0]); i++) { - if (ram_paths[i] && strlen(ram_paths[i]) > 0 && psnes_get_memory_size(ram_types[i]) > 0) + if (ram_paths[i] && *ram_paths[i] && pretro_get_memory_size(ram_types[i]) > 0) { g_extern.autosave[i] = autosave_new(ram_paths[i], - psnes_get_memory_data(ram_types[i]), - psnes_get_memory_size(ram_types[i]), + pretro_get_memory_data(ram_types[i]), + pretro_get_memory_size(ram_types[i]), g_settings.autosave_interval); if (!g_extern.autosave[i]) SSNES_WARN("Could not initialize autosave.\n"); @@ -1402,7 +1412,7 @@ static void init_autosave(void) static void deinit_autosave(void) { - for (unsigned i = 0; i < sizeof(g_extern.autosave)/sizeof(g_extern.autosave[0]); i++) + for (unsigned i = 0; i < sizeof(g_extern.autosave) / sizeof(g_extern.autosave[0]); i++) { if (g_extern.autosave[i]) autosave_free(g_extern.autosave[i]); @@ -1786,7 +1796,7 @@ static void check_rewind(void) setup_rewind_audio(); msg_queue_push(g_extern.msg_queue, "Rewinding.", 0, g_extern.is_paused ? 1 : 30); - psnes_unserialize((uint8_t*)buf, g_extern.state_size); + pretro_unserialize(buf, g_extern.state_size); #ifdef HAVE_BSV_MOVIE if (g_extern.bsv.movie) @@ -1806,12 +1816,15 @@ static void check_rewind(void) if (cnt == 0) #endif { - psnes_serialize((uint8_t*)g_extern.state_buf, g_extern.state_size); + pretro_serialize(g_extern.state_buf, g_extern.state_size); state_manager_push(g_extern.state_manager, g_extern.state_buf); } } - psnes_set_audio_sample(g_extern.frame_is_reverse ? audio_sample_rewind : audio_sample); + pretro_set_audio_sample(g_extern.frame_is_reverse ? + audio_sample_rewind : audio_sample); + pretro_set_audio_sample_batch(g_extern.frame_is_reverse ? + audio_sample_batch_rewind : audio_sample_batch); } static void check_slowmotion(void) @@ -1980,7 +1993,7 @@ void ssnes_game_reset(void) SSNES_LOG("Resetting game.\n"); msg_queue_clear(g_extern.msg_queue); msg_queue_push(g_extern.msg_queue, "Reset.", 1, 120); - psnes_reset(); + pretro_reset(); init_controllers(); // bSNES since v073r01 resets controllers to JOYPAD after a reset, so just enforce it here. } @@ -2206,11 +2219,6 @@ static void do_state_checks(void) check_input_rate(); } -static void fill_title_buf(void) -{ - snprintf(g_extern.title_buf, sizeof(g_extern.title_buf), "SSNES : %s", psnes_library_id()); -} - static void init_state(void) { g_extern.video_active = true; @@ -2233,6 +2241,33 @@ void ssnes_main_clear_state(void) init_state(); } +static void init_system_info(void) +{ + struct retro_system_info *info = &g_extern.system.info; + retro_get_system_info(info); + + if (!info->library_name) + info->library_name = "Unknown"; + if (!info->library_version) + info->library_version = "v0"; + + snprintf(g_extern.title_buf, sizeof(g_extern.title_buf), "SSNES : %s %s", + info->library_name, info->library_version); +} + +static void init_system_av_info(void) +{ + retro_get_system_av_info(&g_extern.system.av_info); +} + +static void verify_api_version(void) +{ + SSNES_LOG("Version of libretro API: %u\n", pretro_api_version()); + SSNES_LOG("Compiled against API: %u\n", RETRO_API_VERSION); + if (pretro_api_version() != RETRO_API_VERSION) + SSNES_WARN("SSNES is compiled against a different version of libretro than this libretro implementation.\n"); +} + int ssnes_main_init(int argc, char *argv[]) { init_state(); @@ -2254,16 +2289,14 @@ int ssnes_main_init(int argc, char *argv[]) } config_load(); - init_libsnes_sym(); - fill_title_buf(); + + init_libretro_sym(); + init_system_info(); + init_drivers_pre(); - psnes_init(); - if (*g_extern.basename) - psnes_set_cartridge_basename(g_extern.basename); - - SSNES_LOG("Version of libretro API: %u.%u\n", - psnes_library_revision_major(), psnes_library_revision_minor()); + verify_api_version(); + pretro_init(); g_extern.use_sram = true; #ifdef HAVE_XML @@ -2276,6 +2309,7 @@ int ssnes_main_init(int argc, char *argv[]) if (!init_rom_file(g_extern.game_type)) goto error; + init_system_av_info(); init_msg_queue(); if (!g_extern.sram_load_disable) @@ -2335,10 +2369,10 @@ int ssnes_main_init(int argc, char *argv[]) return 0; error: - psnes_unload_cartridge(); - psnes_term(); + pretro_unload_game(); + pretro_deinit(); uninit_drivers(); - uninit_libsnes_sym(); + uninit_libretro_sym(); return 1; } @@ -2378,7 +2412,7 @@ bool ssnes_main_iterate(void) bsv_movie_set_frame_start(g_extern.bsv.movie); #endif - psnes_run(); + pretro_run(); #ifdef HAVE_BSV_MOVIE if (g_extern.bsv.movie) @@ -2437,10 +2471,10 @@ void ssnes_main_deinit(void) #endif deinit_msg_queue(); - psnes_unload_cartridge(); - psnes_term(); + pretro_unload_game(); + pretro_deinit(); uninit_drivers(); - uninit_libsnes_sym(); + uninit_libretro_sym(); } #ifndef SSNES_CONSOLE