diff --git a/libsnes/Makefile b/libretro/Makefile similarity index 93% rename from libsnes/Makefile rename to libretro/Makefile index 7ffce8bf..5958bd7e 100644 --- a/libsnes/Makefile +++ b/libretro/Makefile @@ -12,22 +12,22 @@ endif endif ifeq ($(platform), unix) - TARGET := libsnes.so + TARGET := libretro.so fpic := -fPIC SHARED := -shared -Wl,--version-script=link.T else ifeq ($(platform), osx) - TARGET := libsnes.dylib + TARGET := libretro.dylib fpic := -fPIC SHARED := -dynamiclib else - TARGET := snes.dll + TARGET := libretro.dll CC = gcc CXX = g++ SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=link.T CXXFLAGS += -D__WIN32__ -D__WIN32_LIBSNES__ endif -OBJECTS = ../apu/apu.o ../apu/bapu/dsp/sdsp.o ../apu/bapu/dsp/SPC_DSP.o ../apu/bapu/smp/smp.o ../apu/bapu/smp/smp_state.o ../bsx.o ../c4.o ../c4emu.o ../cheats.o ../cheats2.o ../clip.o ../conffile.o ../controls.o ../cpu.o ../cpuexec.o ../cpuops.o ../crosshairs.o ../dma.o ../dsp.o ../dsp1.o ../dsp2.o ../dsp3.o ../dsp4.o ../fxinst.o ../fxemu.o ../gfx.o ../globals.o ../logger.o ../memmap.o ../movie.o ../obc1.o ../ppu.o ../stream.o ../sa1.o ../sa1cpu.o ../screenshot.o ../sdd1.o ../sdd1emu.o ../seta.o ../seta010.o ../seta011.o ../seta018.o ../snapshot.o ../snes9x.o ../spc7110.o ../srtc.o ../tile.o libsnes.o +OBJECTS = ../apu/apu.o ../apu/bapu/dsp/sdsp.o ../apu/bapu/dsp/SPC_DSP.o ../apu/bapu/smp/smp.o ../apu/bapu/smp/smp_state.o ../bsx.o ../c4.o ../c4emu.o ../cheats.o ../cheats2.o ../clip.o ../conffile.o ../controls.o ../cpu.o ../cpuexec.o ../cpuops.o ../crosshairs.o ../dma.o ../dsp.o ../dsp1.o ../dsp2.o ../dsp3.o ../dsp4.o ../fxinst.o ../fxemu.o ../gfx.o ../globals.o ../logger.o ../memmap.o ../movie.o ../obc1.o ../ppu.o ../stream.o ../sa1.o ../sa1cpu.o ../screenshot.o ../sdd1.o ../sdd1emu.o ../seta.o ../seta010.o ../seta011.o ../seta018.o ../snapshot.o ../snes9x.o ../spc7110.o ../srtc.o ../tile.o libretro.o CXX = g++ CC = gcc diff --git a/libsnes/libsnes-win32.vcproj b/libretro/libretro-win32.vcproj similarity index 96% rename from libsnes/libsnes-win32.vcproj rename to libretro/libretro-win32.vcproj index ee4f1dff..3063f48c 100644 --- a/libsnes/libsnes-win32.vcproj +++ b/libretro/libretro-win32.vcproj @@ -2,7 +2,7 @@ diff --git a/libsnes/libsnes.cpp b/libretro/libretro.cpp similarity index 59% rename from libsnes/libsnes.cpp rename to libretro/libretro.cpp index 3cf5b2ce..50a6a875 100644 --- a/libsnes/libsnes.cpp +++ b/libretro/libretro.cpp @@ -1,4 +1,4 @@ -#include "libsnes.hpp" +#include "libretro.h" #include "snes9x.h" #include "memmap.h" @@ -22,53 +22,44 @@ #include -static snes_video_refresh_t s9x_video_cb = NULL; -static snes_audio_sample_t s9x_audio_cb = NULL; -static snes_input_poll_t s9x_poller_cb = NULL; -static snes_input_state_t s9x_input_state_cb = NULL; +static retro_video_refresh_t s9x_video_cb = NULL; +static retro_audio_sample_t s9x_audio_cb = NULL; +static retro_audio_sample_batch_t s9x_audio_batch_cb = NULL; +static retro_input_poll_t s9x_poller_cb = NULL; +static retro_input_state_t s9x_input_state_cb = NULL; -void snes_set_video_refresh(snes_video_refresh_t cb) +void retro_set_video_refresh(retro_video_refresh_t cb) { s9x_video_cb = cb; } -void snes_set_audio_sample(snes_audio_sample_t cb) +void retro_set_audio_sample(retro_audio_sample_t cb) { s9x_audio_cb = cb; } -void snes_set_input_poll(snes_input_poll_t cb) +void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) +{ + s9x_audio_batch_cb = cb; +} + +void retro_set_input_poll(retro_input_poll_t cb) { s9x_poller_cb = cb; } -void snes_set_input_state(snes_input_state_t cb) +void retro_set_input_state(retro_input_state_t cb) { s9x_input_state_cb = cb; } -static snes_environment_t environ_cb; +static retro_environment_t environ_cb; static bool use_overscan; -void snes_set_environment(snes_environment_t cb) +void retro_set_environment(retro_environment_t cb) { environ_cb = cb; } -static void set_environ_timing() -{ - if (environ_cb) - { - snes_system_timing timing; - timing.sample_rate = 32040.5; - if (!Settings.PAL) - timing.fps = 21477272.0 / 357366.0; - else - timing.fps = 21281370.0 / 425568.0; - - environ_cb(SNES_ENVIRONMENT_SET_TIMING, &timing); - } -} - static void S9xAudioCallback(void*) { // Just pick a big buffer. We won't use it all. @@ -77,154 +68,172 @@ static void S9xAudioCallback(void*) S9xFinalizeSamples(); size_t avail = S9xGetSampleCount(); S9xMixSamples((uint8*)audio_buf, avail); - for (size_t i = 0; i < avail; i+=2) - s9x_audio_cb((uint16_t)audio_buf[i], (uint16_t)audio_buf[i + 1]); + s9x_audio_batch_cb(audio_buf,avail >> 1); + + /*for (size_t i = 0; i < avail; i+=2) + s9x_audio_cb((uint16_t)audio_buf[i], (uint16_t)audio_buf[i + 1]);*/ } -const char *snes_library_id() +void retro_get_system_info(struct retro_system_info *info) +{ + memset(info,0,sizeof(retro_system_info)); + + info->library_name = "SNES9x"; + info->library_version = VERSION; + info->valid_extensions = "smc|sfc|zip|gz|swc|fig|jma"; + info->need_fullpath = false; + info->block_extract = false; +} + +void retro_get_system_av_info(struct retro_system_av_info *info) +{ + memset(info,0,sizeof(retro_system_av_info)); + + info->geometry.base_width = SNES_WIDTH; + info->geometry.base_height = SNES_HEIGHT; + info->geometry.max_width = MAX_SNES_WIDTH; + info->geometry.max_height = MAX_SNES_HEIGHT; + info->timing.sample_rate = 32040.5; + info->timing.fps = retro_get_region() == RETRO_REGION_NTSC ? 21477272.0 / 357366.0 : 21281370.0 / 425568.0; +} + +const char *retro_library_id() { return "SNES9x v" VERSION; } -unsigned snes_library_revision_major() +unsigned retro_api_version() { - return 1; + return RETRO_API_VERSION; } -unsigned snes_library_revision_minor() -{ - return 3; -} -void snes_power() +void retro_reset() { - S9xReset(); -} - -void snes_reset() -{ - S9xMovieUpdateOnReset(); - if (S9xMoviePlaying()) - { - S9xMovieStop(true); - } S9xSoftReset(); } static unsigned snes_devices[2]; -void snes_set_controller_port_device(bool in_port, unsigned device) +void retro_set_controller_port_device(unsigned port, unsigned device) { - int port = in_port == SNES_PORT_1 ? 0 : 1; switch (device) { - case SNES_DEVICE_JOYPAD: + case RETRO_DEVICE_JOYPAD: S9xSetController(port, CTL_JOYPAD, 0, 0, 0, 0); - snes_devices[port] = SNES_DEVICE_JOYPAD; + snes_devices[port] = RETRO_DEVICE_JOYPAD; break; - case SNES_DEVICE_MULTITAP: + case RETRO_DEVICE_JOYPAD_MULTITAP: S9xSetController(port, CTL_MP5, 1, 2, 3, 4); - snes_devices[port] = SNES_DEVICE_MULTITAP; + snes_devices[port] = RETRO_DEVICE_JOYPAD_MULTITAP; break; - case SNES_DEVICE_MOUSE: + case RETRO_DEVICE_MOUSE: S9xSetController(port, CTL_MOUSE, 0, 0, 0, 0); - snes_devices[port] = SNES_DEVICE_MOUSE; + snes_devices[port] = RETRO_DEVICE_MOUSE; break; - case SNES_DEVICE_SUPER_SCOPE: + case RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE: S9xSetController(port, CTL_SUPERSCOPE, 0, 0, 0, 0); - snes_devices[port] = SNES_DEVICE_SUPER_SCOPE; + snes_devices[port] = RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE; break; - case SNES_DEVICE_JUSTIFIER: + case RETRO_DEVICE_LIGHTGUN_JUSTIFIER: S9xSetController(port, CTL_JUSTIFIER, 0, 0, 0, 0); - snes_devices[port] = SNES_DEVICE_JUSTIFIER; + snes_devices[port] = RETRO_DEVICE_LIGHTGUN_JUSTIFIER; break; - case SNES_DEVICE_JUSTIFIERS: + case RETRO_DEVICE_LIGHTGUN_JUSTIFIERS: S9xSetController(port, CTL_JUSTIFIER, 1, 0, 0, 0); - snes_devices[port] = SNES_DEVICE_JUSTIFIERS; + snes_devices[port] = RETRO_DEVICE_LIGHTGUN_JUSTIFIERS; break; default: - fprintf(stderr, "[libsnes]: Invalid device!\n"); + fprintf(stderr, "[libretro]: Invalid device!\n"); } } -void snes_cheat_reset() +void retro_cheat_reset() {} -void snes_cheat_set(unsigned, bool, const char*) +void retro_cheat_set(unsigned, bool, const char*) {} -bool snes_load_cartridge_bsx_slotted( - const char *, const uint8_t *rom_data, unsigned rom_size, - const char *, const uint8_t *bsx_data, unsigned bsx_size - ) +bool retro_load_game(const struct retro_game_info *game) { - int loaded = Memory.LoadMultiCartMem(rom_data, rom_size, bsx_data, bsx_size, NULL, NULL); + int loaded = 0; + + if(game->data == NULL && game->size == NULL && game->path != NULL) + loaded = Memory.LoadROM(game->path); + else + loaded = Memory.LoadROMMem((const uint8_t*)game->data ,game->size); if (!loaded) { - fprintf(stderr, "[libsnes]: Sufami Turbo Rom loading failed...\n"); - return false; + fprintf(stderr, "[libretro]: Rom loading failed...\n"); } - - set_environ_timing(); - - return false; -} - -bool snes_load_cartridge_bsx( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size - ) -{ - if(bsx_data==NULL) - return snes_load_cartridge_normal(rom_xml,rom_data,rom_size); - memcpy(Memory.BIOSROM,rom_data,rom_size); - return snes_load_cartridge_normal(bsx_xml,bsx_data,bsx_size); -} - -bool snes_load_cartridge_sufami_turbo( - const char *, const uint8_t *rom_data, unsigned rom_size, - const char *, const uint8_t *sta_data, unsigned sta_size, - const char *, const uint8_t *stb_data, unsigned stb_size - ) -{ - int loaded = Memory.LoadMultiCartMem(sta_data, sta_size, stb_data, stb_size, rom_data, rom_size); - - if (!loaded) - { - fprintf(stderr, "[libsnes]: Sufami Turbo Rom loading failed...\n"); - return false; - } - - set_environ_timing(); - return true; + return loaded; } -bool snes_load_cartridge_super_game_boy( - const char *, const uint8_t *, unsigned, - const char *, const uint8_t *, unsigned - ) -{ - return false; +void retro_unload_game(void) +{} + +bool retro_load_game_special(unsigned game_type, + const struct retro_game_info *info, size_t num_info) { + + int loaded = 0; + switch (game_type) { + case RETRO_GAME_TYPE_BSX: + + if(num_info == 1) { + loaded = Memory.LoadROMMem((const uint8_t*)info[0].data,info[0].size); + } else if(num_info == 2) { + memcpy(Memory.BIOSROM,(const uint8_t*)info[0].data,info[0].size); + loaded = Memory.LoadROMMem((const uint8_t*)info[1].data,info[1].size); + } + + if (!loaded) + { + fprintf(stderr, "[libretro]: BSX Rom loading failed...\n"); + } + + return loaded; + + case RETRO_GAME_TYPE_BSX_SLOTTED: + + if(num_info == 2) + loaded = Memory.LoadMultiCartMem((const uint8_t*)info[0].data, info[0].size, + (const uint8_t*)info[1].data, info[1].size, NULL, NULL); + + if (!loaded) + { + fprintf(stderr, "[libretro]: Multirom loading failed...\n"); + } + + return loaded; + + case RETRO_GAME_TYPE_SUFAMI_TURBO: + + if(num_info == 3) + loaded = Memory.LoadMultiCartMem((const uint8_t*)info[1].data, info[1].size, + (const uint8_t*)info[2].data, info[2].size, (const uint8_t*)info[0].data, info[0].size); + + if (!loaded) + { + fprintf(stderr, "[libretro]: Sufami Turbo Rom loading failed...\n"); + } + + return loaded; + + default: + return false; + } } static void map_buttons(); -void snes_init() +void retro_init() { if (environ_cb) { - if (!environ_cb(SNES_ENVIRONMENT_GET_OVERSCAN, &use_overscan)) + if (!environ_cb(RETRO_ENVIRONMENT_GET_OVERSCAN, &use_overscan)) use_overscan = false; - - if (use_overscan) - { - snes_geometry geom = {256, 239, 512, 512}; - environ_cb(SNES_ENVIRONMENT_SET_GEOMETRY, &geom); - unsigned pitch = 1024; - environ_cb(SNES_ENVIRONMENT_SET_PITCH, &pitch); - } } memset(&Settings, 0, sizeof(Settings)); @@ -261,7 +270,7 @@ void snes_init() { Memory.Deinit(); S9xDeinitAPU(); - fprintf(stderr, "[libsnes]: Failed to init Memory or APU.\n"); + fprintf(stderr, "[libretro]: Failed to init Memory or APU.\n"); exit(1); } @@ -270,15 +279,15 @@ void snes_init() S9xSetSamplesAvailableCallback(S9xAudioCallback, NULL); S9xSetRenderPixelFormat(RGB555); - GFX.Pitch = use_overscan ? 1024 : 2048; - GFX.Screen = (uint16*) calloc(1, GFX.Pitch * 512 * sizeof(uint16)); + GFX.Pitch = MAX_SNES_WIDTH * sizeof(uint16); + GFX.Screen = (uint16*) calloc(1, GFX.Pitch * MAX_SNES_HEIGHT); S9xGraphicsInit(); S9xInitInputDevices(); for (int i = 0; i < 2; i++) { S9xSetController(i, CTL_JOYPAD, i, 0, 0, 0); - snes_devices[i] = SNES_DEVICE_JOYPAD; + snes_devices[i] = RETRO_DEVICE_JOYPAD; } S9xUnmapAllControls(); @@ -295,41 +304,41 @@ void snes_init() #define PAD_4 4 #define PAD_5 5 -#define BTN_B SNES_DEVICE_ID_JOYPAD_B -#define BTN_Y SNES_DEVICE_ID_JOYPAD_Y -#define BTN_SELECT SNES_DEVICE_ID_JOYPAD_SELECT -#define BTN_START SNES_DEVICE_ID_JOYPAD_START -#define BTN_UP SNES_DEVICE_ID_JOYPAD_UP -#define BTN_DOWN SNES_DEVICE_ID_JOYPAD_DOWN -#define BTN_LEFT SNES_DEVICE_ID_JOYPAD_LEFT -#define BTN_RIGHT SNES_DEVICE_ID_JOYPAD_RIGHT -#define BTN_A SNES_DEVICE_ID_JOYPAD_A -#define BTN_X SNES_DEVICE_ID_JOYPAD_X -#define BTN_L SNES_DEVICE_ID_JOYPAD_L -#define BTN_R SNES_DEVICE_ID_JOYPAD_R +#define BTN_B RETRO_DEVICE_ID_JOYPAD_B +#define BTN_Y RETRO_DEVICE_ID_JOYPAD_Y +#define BTN_SELECT RETRO_DEVICE_ID_JOYPAD_SELECT +#define BTN_START RETRO_DEVICE_ID_JOYPAD_START +#define BTN_UP RETRO_DEVICE_ID_JOYPAD_UP +#define BTN_DOWN RETRO_DEVICE_ID_JOYPAD_DOWN +#define BTN_LEFT RETRO_DEVICE_ID_JOYPAD_LEFT +#define BTN_RIGHT RETRO_DEVICE_ID_JOYPAD_RIGHT +#define BTN_A RETRO_DEVICE_ID_JOYPAD_A +#define BTN_X RETRO_DEVICE_ID_JOYPAD_X +#define BTN_L RETRO_DEVICE_ID_JOYPAD_L +#define BTN_R RETRO_DEVICE_ID_JOYPAD_R #define BTN_FIRST BTN_B #define BTN_LAST BTN_R -#define MOUSE_X SNES_DEVICE_ID_MOUSE_X -#define MOUSE_Y SNES_DEVICE_ID_MOUSE_Y -#define MOUSE_LEFT SNES_DEVICE_ID_MOUSE_LEFT -#define MOUSE_RIGHT SNES_DEVICE_ID_MOUSE_RIGHT +#define MOUSE_X RETRO_DEVICE_ID_MOUSE_X +#define MOUSE_Y RETRO_DEVICE_ID_MOUSE_Y +#define MOUSE_LEFT RETRO_DEVICE_ID_MOUSE_LEFT +#define MOUSE_RIGHT RETRO_DEVICE_ID_MOUSE_RIGHT #define MOUSE_FIRST MOUSE_X #define MOUSE_LAST MOUSE_RIGHT -#define SCOPE_X SNES_DEVICE_ID_SUPER_SCOPE_X -#define SCOPE_Y SNES_DEVICE_ID_SUPER_SCOPE_Y -#define SCOPE_TRIGGER SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER -#define SCOPE_CURSOR SNES_DEVICE_ID_SUPER_SCOPE_CURSOR -#define SCOPE_TURBO SNES_DEVICE_ID_SUPER_SCOPE_TURBO -#define SCOPE_PAUSE SNES_DEVICE_ID_SUPER_SCOPE_PAUSE +#define SCOPE_X RETRO_DEVICE_ID_SUPER_SCOPE_X +#define SCOPE_Y RETRO_DEVICE_ID_SUPER_SCOPE_Y +#define SCOPE_TRIGGER RETRO_DEVICE_ID_LIGHTGUN_TRIGGER +#define SCOPE_CURSOR RETRO_DEVICE_ID_LIGHTGUN_CURSOR +#define SCOPE_TURBO RETRO_DEVICE_ID_LIGHTGUN_TURBO +#define SCOPE_PAUSE RETRO_DEVICE_ID_LIGHTGUN_PAUSE #define SCOPE_FIRST SCOPE_X #define SCOPE_LAST SCOPE_PAUSE -#define JUSTIFIER_X SNES_DEVICE_ID_JUSTIFIER_X -#define JUSTIFIER_Y SNES_DEVICE_ID_JUSTIFIER_Y -#define JUSTIFIER_TRIGGER SNES_DEVICE_ID_JUSTIFIER_TRIGGER -#define JUSTIFIER_START SNES_DEVICE_ID_JUSTIFIER_START +#define JUSTIFIER_X RETRO_DEVICE_ID_JUSTIFIER_X +#define JUSTIFIER_Y RETRO_DEVICE_ID_JUSTIFIER_Y +#define JUSTIFIER_TRIGGER RETRO_DEVICE_ID_LIGHTGUN_TRIGGER +#define JUSTIFIER_START RETRO_DEVICE_ID_LIGHTGUN_PAUSE #define JUSTIFIER_FIRST JUSTIFIER_X #define JUSTIFIER_LAST JUSTIFIER_START @@ -407,7 +416,7 @@ static void map_buttons() } -// libsnes uses relative values for analogue devices. +// libretro uses relative values for analogue devices. // S9x seems to use absolute values, but do convert these into relative values in the core. (Why?!) // Hack around it. :) static int16_t snes_mouse_state[2][2] = {{0}, {0}}; @@ -416,77 +425,63 @@ static int16_t snes_justifier_state[2][2] = {{0}, {0}}; static void report_buttons() { int _x, _y; - for (int port = SNES_PORT_1; port <= SNES_PORT_2; port++) + for (int port = 0; port <= 1; port++) { switch (snes_devices[port]) { - case SNES_DEVICE_JOYPAD: + case RETRO_DEVICE_JOYPAD: for (int i = BTN_FIRST; i <= BTN_LAST; i++) - S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_JOYPAD, 0, i)); + S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port, RETRO_DEVICE_JOYPAD, 0, i)); break; - case SNES_DEVICE_MULTITAP: + case RETRO_DEVICE_JOYPAD_MULTITAP: for (int j = 0; j < 4; j++) for (int i = BTN_FIRST; i <= BTN_LAST; i++) - S9xReportButton(MAKE_BUTTON(j + 2, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_MULTITAP, j, i)); + S9xReportButton(MAKE_BUTTON(j + 2, i), s9x_input_state_cb(port, RETRO_DEVICE_JOYPAD_MULTITAP, j, i)); break; - case SNES_DEVICE_MOUSE: - _x = s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_MOUSE, 0, SNES_DEVICE_ID_MOUSE_X); - _y = s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_MOUSE, 0, SNES_DEVICE_ID_MOUSE_Y); + case RETRO_DEVICE_MOUSE: + _x = s9x_input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X); + _y = s9x_input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y); snes_mouse_state[port][0] += _x; snes_mouse_state[port][1] += _y; S9xReportPointer(BTN_POINTER + port, snes_mouse_state[port][0], snes_mouse_state[port][1]); for (int i = MOUSE_LEFT; i <= MOUSE_LAST; i++) - S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_MOUSE, 0, i)); + S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port, RETRO_DEVICE_MOUSE, 0, i)); break; - case SNES_DEVICE_SUPER_SCOPE: - snes_scope_state[0] += s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_SUPER_SCOPE, 0, SNES_DEVICE_ID_SUPER_SCOPE_X); - snes_scope_state[1] += s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_SUPER_SCOPE, 0, SNES_DEVICE_ID_SUPER_SCOPE_Y); + case RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE: + snes_scope_state[0] += s9x_input_state_cb(port, RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE, 0, RETRO_DEVICE_ID_LIGHTGUN_X); + snes_scope_state[1] += s9x_input_state_cb(port, RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE, 0, RETRO_DEVICE_ID_LIGHTGUN_Y); S9xReportPointer(BTN_POINTER, snes_scope_state[0], snes_scope_state[1]); for (int i = SCOPE_TRIGGER; i <= SCOPE_LAST; i++) - S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_SUPER_SCOPE, 0, i)); + S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port, RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE, 0, i)); break; - case SNES_DEVICE_JUSTIFIER: - case SNES_DEVICE_JUSTIFIERS: - snes_justifier_state[0][0] += s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_JUSTIFIER, 0, SNES_DEVICE_ID_JUSTIFIER_X); - snes_justifier_state[0][1] += s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_JUSTIFIER, 0, SNES_DEVICE_ID_JUSTIFIER_Y); + case RETRO_DEVICE_LIGHTGUN_JUSTIFIER: + case RETRO_DEVICE_LIGHTGUN_JUSTIFIERS: + snes_justifier_state[0][0] += s9x_input_state_cb(port, RETRO_DEVICE_LIGHTGUN_JUSTIFIER, 0, RETRO_DEVICE_ID_LIGHTGUN_X); + snes_justifier_state[0][1] += s9x_input_state_cb(port, RETRO_DEVICE_LIGHTGUN_JUSTIFIER, 0, RETRO_DEVICE_ID_LIGHTGUN_Y); S9xReportPointer(BTN_POINTER, snes_justifier_state[0][0], snes_justifier_state[0][1]); for (int i = JUSTIFIER_TRIGGER; i <= JUSTIFIER_LAST; i++) - S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_JUSTIFIER, 0, i)); + S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port, RETRO_DEVICE_LIGHTGUN_JUSTIFIER, 0, i)); break; default: - fprintf(stderr, "[libsnes]: Unknown device...\n"); + fprintf(stderr, "[libretro]: Unknown device...\n"); } } } -bool snes_load_cartridge_normal(const char *, const uint8_t *rom_data, unsigned rom_size) -{ - int loaded = Memory.LoadROMMem(rom_data,rom_size); - if (!loaded) - { - fprintf(stderr, "[libsnes]: Rom loading failed...\n"); - return false; - } - - set_environ_timing(); - - return true; -} - -void snes_run() +void retro_run() { s9x_poller_cb(); report_buttons(); S9xMainLoop(); } -void snes_term() +void retro_deinit() { S9xDeinitAPU(); Memory.Deinit(); @@ -495,30 +490,30 @@ void snes_term() } -bool snes_get_region() +unsigned retro_get_region() { - return Settings.PAL ? SNES_REGION_PAL : SNES_REGION_NTSC; + return Settings.PAL ? RETRO_REGION_PAL : RETRO_REGION_NTSC; } -uint8_t* snes_get_memory_data(unsigned type) +void* retro_get_memory_data(unsigned type) { - uint8_t* data; + void* data; switch(type) { - case SNES_MEMORY_SUFAMI_TURBO_A_RAM: - case SNES_MEMORY_CARTRIDGE_RAM: + case RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM: + case RETRO_MEMORY_SAVE_RAM: data = Memory.SRAM; break; - case SNES_MEMORY_SUFAMI_TURBO_B_RAM: + case RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM: data = Multi.sramB; break; - case SNES_MEMORY_CARTRIDGE_RTC: + case RETRO_MEMORY_RTC: data = RTCData.reg; break; - case SNES_MEMORY_WRAM: + case RETRO_MEMORY_SYSTEM_RAM: data = Memory.RAM; break; - case SNES_MEMORY_APURAM: + /*case SNES_MEMORY_APURAM: data = SNES::smp.apuram; break; case SNES_MEMORY_VRAM: @@ -529,7 +524,7 @@ uint8_t* snes_get_memory_data(unsigned type) break; case SNES_MEMORY_OAM: data = PPU.OAMData; - break; + break;*/ default: data = NULL; break; @@ -538,32 +533,32 @@ uint8_t* snes_get_memory_data(unsigned type) return data; } -void snes_unload_cartridge() +void retro_unload_cartridge() { } -unsigned snes_get_memory_size(unsigned type) +size_t retro_get_memory_size(unsigned type) { - unsigned size; + size_t size; switch(type) { - case SNES_MEMORY_SUFAMI_TURBO_A_RAM: - case SNES_MEMORY_CARTRIDGE_RAM: + case RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM: + case RETRO_MEMORY_SAVE_RAM: size = (unsigned) (Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0); if (size > 0x20000) size = 0x20000; break; - case SNES_MEMORY_SUFAMI_TURBO_B_RAM: + case RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM: size = (unsigned) (Multi.cartType && Multi.sramSizeB ? (1 << (Multi.sramSizeB + 3)) * 128 : 0); break; - case SNES_MEMORY_CARTRIDGE_RTC: + case RETRO_MEMORY_RTC: size = (Settings.SRTC || Settings.SPC7110RTC)?20:0; break; - case SNES_MEMORY_WRAM: + case RETRO_MEMORY_SYSTEM_RAM: size = 128 * 1024; break; - case SNES_MEMORY_VRAM: + /*case SNES_MEMORY_VRAM: case SNES_MEMORY_APURAM: size = 64 * 1024; break; @@ -572,7 +567,7 @@ unsigned snes_get_memory_size(unsigned type) break; case SNES_MEMORY_OAM: size = 512 + 32; - break; + break;*/ default: size = 0; break; @@ -581,15 +576,12 @@ unsigned snes_get_memory_size(unsigned type) return size; } -void snes_set_cartridge_basename(const char*) -{} - -unsigned snes_serialize_size() +size_t retro_serialize_size() { return S9xFreezeSize(); } -bool snes_serialize(uint8_t *data, unsigned size) +bool retro_serialize(uint8_t *data, unsigned size) { if (S9xFreezeGameMem(data,size) == FALSE) return false; @@ -597,73 +589,28 @@ bool snes_serialize(uint8_t *data, unsigned size) return true; } -bool snes_unserialize(const uint8_t* data, unsigned size) +bool retro_unserialize(const uint8_t* data, unsigned size) { if (S9xUnfreezeGameMem(data,size) != SUCCESS) return false; return true; } -// Pitch 2048 -> 1024, only done once per res-change. -static void pack_frame(uint16_t *frame, int width, int height) -{ - for (int y = 1; y < height; y++) - { - uint16_t *src = frame + y * 1024; - uint16_t *dst = frame + y * 512; - - memcpy(dst, src, width * sizeof(uint16_t)); - } -} - -// Pitch 1024 -> 2048, only done once per res-change. -static void stretch_frame(uint16_t *frame, int width, int height) -{ - for (int y = height - 1; y >= 0; y--) - { - uint16_t *src = frame + y * 512; - uint16_t *dst = frame + y * 1024; - - memcpy(dst, src, width * sizeof(uint16_t)); - } -} - bool8 S9xDeinitUpdate(int width, int height) { - if (use_overscan) + if (!use_overscan) { - if (height == 224) + if (height >= SNES_HEIGHT << 1) { - memmove(GFX.Screen + (GFX.Pitch / 2) * 7, GFX.Screen, GFX.Pitch * height); - memset(GFX.Screen, 0x00, GFX.Pitch * 7); - memset(GFX.Screen + (GFX.Pitch / 2) * (7 + 224), 0, GFX.Pitch * 8); - height = 239; - } - else if (height == 448) - { - memmove(GFX.Screen + (GFX.Pitch / 2) * 15, GFX.Screen, GFX.Pitch * height); - memset(GFX.Screen, 0x00, GFX.Pitch * 15); - memset(GFX.Screen + (GFX.Pitch / 2) * (15 + 224), 0x00, GFX.Pitch * 17); - height = 478; - } - } - else // libsnes classic behavior - { - if (height == 448 || height == 478) - { - if (GFX.Pitch == 2048) - pack_frame(GFX.Screen, width, height); - GFX.Pitch = 1024; + height = SNES_HEIGHT << 1; } else { - if (GFX.Pitch == 1024) - stretch_frame(GFX.Screen, width, height); - GFX.Pitch = 2048; + height = SNES_HEIGHT; } } - s9x_video_cb(GFX.Screen, width, height); + s9x_video_cb(GFX.Screen, width, height, GFX.Pitch); return TRUE; } diff --git a/libretro/libretro.def b/libretro/libretro.def new file mode 100644 index 00000000..aa6381b4 --- /dev/null +++ b/libretro/libretro.def @@ -0,0 +1,41 @@ +LIBRARY libretro + +EXPORTS + +retro_api_version + +retro_get_system_info +retro_get_system_av_info + +retro_set_video_refresh +retro_set_audio_sample +retro_set_audio_sample_batch +retro_set_input_poll +retro_set_input_state + +retro_set_environment + +retro_set_controller_port_device + +retro_init +retro_deinit + +retro_reset +retro_run + +retro_serialize_size +retro_serialize +retro_unserialize + +retro_cheat_reset +retro_cheat_set + +retro_load_game +retro_unload_game +retro_load_game_special + +retro_unload_cartridge + +retro_get_region +retro_get_memory_data +retro_get_memory_size \ No newline at end of file diff --git a/libretro/libretro.h b/libretro/libretro.h new file mode 100644 index 00000000..3a1599e1 --- /dev/null +++ b/libretro/libretro.h @@ -0,0 +1,218 @@ +#ifndef LIBRETRO_H__ +#define LIBRETRO_H__ + +#include "snes9x.h" +#include + +#ifdef __cplusplus +extern "C" { +#else +#include +#endif + +#define RETRO_API_VERSION 1 + +#define RETRO_DEVICE_MASK 0xff +#define RETRO_DEVICE_NONE 0 +#define RETRO_DEVICE_JOYPAD 1 +#define RETRO_DEVICE_MOUSE 2 +#define RETRO_DEVICE_KEYBOARD 3 +#define RETRO_DEVICE_LIGHTGUN 4 + +#define RETRO_DEVICE_JOYPAD_MULTITAP ((1 << 8) | RETRO_DEVICE_JOYPAD) +#define RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE ((1 << 8) | RETRO_DEVICE_LIGHTGUN) +#define RETRO_DEVICE_LIGHTGUN_JUSTIFIER ((2 << 8) | RETRO_DEVICE_LIGHTGUN) +#define RETRO_DEVICE_LIGHTGUN_JUSTIFIERS ((3 << 8) | RETRO_DEVICE_LIGHTGUN) + +#define RETRO_DEVICE_ID_JOYPAD_B 0 +#define RETRO_DEVICE_ID_JOYPAD_Y 1 +#define RETRO_DEVICE_ID_JOYPAD_SELECT 2 +#define RETRO_DEVICE_ID_JOYPAD_START 3 +#define RETRO_DEVICE_ID_JOYPAD_UP 4 +#define RETRO_DEVICE_ID_JOYPAD_DOWN 5 +#define RETRO_DEVICE_ID_JOYPAD_LEFT 6 +#define RETRO_DEVICE_ID_JOYPAD_RIGHT 7 +#define RETRO_DEVICE_ID_JOYPAD_A 8 +#define RETRO_DEVICE_ID_JOYPAD_X 9 +#define RETRO_DEVICE_ID_JOYPAD_L 10 +#define RETRO_DEVICE_ID_JOYPAD_R 11 + +#define RETRO_DEVICE_ID_MOUSE_X 0 +#define RETRO_DEVICE_ID_MOUSE_Y 1 +#define RETRO_DEVICE_ID_MOUSE_LEFT 2 +#define RETRO_DEVICE_ID_MOUSE_RIGHT 3 + +#define RETRO_DEVICE_ID_LIGHTGUN_X 0 +#define RETRO_DEVICE_ID_LIGHTGUN_Y 1 +#define RETRO_DEVICE_ID_LIGHTGUN_TRIGGER 2 +#define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3 +#define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4 +#define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5 +#define RETRO_DEVICE_ID_LIGHTGUN_START 6 + +#define RETRO_REGION_NTSC 0 +#define RETRO_REGION_PAL 1 + +#define RETRO_MEMORY_MASK 0xff +#define RETRO_MEMORY_SAVE_RAM 0 +#define RETRO_MEMORY_RTC 1 +#define RETRO_MEMORY_SYSTEM_RAM 2 + +#define RETRO_MEMORY_SNES_BSX_RAM ((1 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_BSX_PRAM ((2 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM ((3 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM ((4 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_GAME_BOY_RAM ((5 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_GAME_BOY_RTC ((6 << 8) | RETRO_MEMORY_RTC) + +#define RETRO_GAME_TYPE_BSX 0x101 +#define RETRO_GAME_TYPE_BSX_SLOTTED 0x102 +#define RETRO_GAME_TYPE_SUFAMI_TURBO 0x103 +#define RETRO_GAME_TYPE_SUPER_GAME_BOY 0x104 + + +// Environment commands. +#define RETRO_ENVIRONMENT_SET_ROTATION 1 // const unsigned * -- + // Sets screen rotation of graphics. + // Is only implemented if rotation can be accelerated by hardware. + // Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, 270 degrees + // counter-clockwise respectively. + // +#define RETRO_ENVIRONMENT_GET_OVERSCAN 2 // bool * -- + // Boolean value whether or not the implementation should use overscan, or crop away overscan. + // +#define RETRO_ENVIRONMENT_GET_CAN_DUPE 3 // bool * -- + // Boolean value whether or not SSNES supports frame duping, + // passing NULL to video frame callback. + // +#define RETRO_ENVIRONMENT_GET_VARIABLE 4 // struct retro_variable * -- + // Interface to aquire user-defined information from environment + // that cannot feasibly be supported in a multi-system way. + // Mostly used for obscure, + // specific features that the user can tap into when neseccary. + // +#define RETRO_ENVIRONMENT_SET_VARIABLES 5 // const struct retro_variable * -- + // Allows an implementation to signal the environment + // which variables it might want to check for later using GET_VARIABLE. + // 'data' points to an array of retro_variable structs terminated by a { NULL, NULL } element. + // retro_variable::value should contain a human readable description of the key. + // +#define RETRO_ENVIRONMENT_SET_MESSAGE 6 // const struct retro_message * -- + // Sets a message to be displayed in implementation-specific manner for a certain amount of 'frames'. + +struct retro_message +{ + const char *msg; + unsigned frames; +}; + +struct retro_system_info +{ + const char *library_name; + const char *library_version; + const char *valid_extensions; + bool need_fullpath; + bool block_extract; +}; + +struct retro_game_geometry +{ + unsigned base_width; // Nominal video width of game. + unsigned base_height; // Nominal video height of game. + unsigned max_width; // Maximum possible width of game. + unsigned max_height; // Maximum possible height of game. + + float aspect_ratio; // Nominal aspect ratio of game. If aspect_ratio is <= 0.0, + // an aspect ratio of base_width / base_height is assumed. + // A frontend could override this setting if desired. +}; + +struct retro_system_timing +{ + double fps; // FPS of video content. + double sample_rate; // Sampling rate of audio. +}; + +struct retro_system_av_info +{ + struct retro_game_geometry geometry; + struct retro_system_timing timing; +}; + +struct retro_variable +{ + const char *key; // Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE. + // If NULL, obtains the complete environment string if more complex parsing is necessary. + // The environment string is formatted as key-value pairs delimited by semicolons as so: + // "key1=value1;key2=value2;..." + const char *value; // Value to be obtained. If key does not exist, it is set to NULL. +}; + +struct retro_game_info +{ + 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. +}; + +typedef bool (*retro_environment_t)(unsigned cmd, void *data); +typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height, size_t pitch); +typedef void (*retro_audio_sample_t)(int16_t left, int16_t right); +typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t frames); + +typedef void (*retro_input_poll_t)(void); +typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id); + +void retro_init(void); +void retro_deinit(void); + +unsigned retro_api_version(void); + +void retro_get_system_info(struct retro_system_info *info); +void retro_get_system_av_info(struct retro_system_av_info *info); + +void retro_set_environment(retro_environment_t); +void retro_set_video_refresh(retro_video_refresh_t); +void retro_set_audio_sample(retro_audio_sample_t); +void retro_set_audio_sample_batch(retro_audio_sample_batch_t); +void retro_set_input_poll(retro_input_poll_t); +void retro_set_input_state(retro_input_state_t); + +void retro_set_controller_port_device(unsigned port, unsigned device); + +void retro_reset(void); +void retro_run(void); + +size_t retro_serialize_size(void); +bool retro_serialize(void *data, size_t size); +bool retro_unserialize(const void *data, size_t size); + +void retro_cheat_reset(void); +void retro_cheat_set(unsigned index, bool enabled, const char *code); + +bool retro_load_game(const struct retro_game_info *game); + +bool retro_load_game_special( + unsigned game_type, + const struct retro_game_info *info, size_t num_info +); + +void retro_unload_game(void); + +unsigned retro_get_region(void); + +void *retro_get_memory_data(unsigned id); +size_t retro_get_memory_size(unsigned id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libretro/link.T b/libretro/link.T new file mode 100644 index 00000000..9e82b5dd --- /dev/null +++ b/libretro/link.T @@ -0,0 +1,4 @@ +{ + global: retro_*; + local: *; +}; diff --git a/libsnes/libsnes.def b/libsnes/libsnes.def deleted file mode 100644 index c1017351..00000000 --- a/libsnes/libsnes.def +++ /dev/null @@ -1,47 +0,0 @@ -LIBRARY snes - -EXPORTS - -snes_library_id - -snes_library_revision_major -snes_library_revision_minor - -snes_set_video_refresh -snes_set_audio_sample -snes_set_input_poll -snes_set_input_state - -snes_set_environment - -snes_set_controller_port_device -snes_set_cartridge_basename - -snes_init -snes_term -snes_power -snes_reset -snes_run - -snes_serialize_size -snes_serialize -snes_unserialize - -snes_cheat_reset -snes_cheat_set - -snes_load_cartridge_normal - -snes_load_cartridge_bsx_slotted - -snes_load_cartridge_bsx - -snes_load_cartridge_sufami_turbo - -snes_load_cartridge_super_game_boy - -snes_unload_cartridge - -snes_get_region -snes_get_memory_data -snes_get_memory_size \ No newline at end of file diff --git a/libsnes/libsnes.hpp b/libsnes/libsnes.hpp deleted file mode 100644 index 78a49816..00000000 --- a/libsnes/libsnes.hpp +++ /dev/null @@ -1,1264 +0,0 @@ -#ifndef LIBSNES_HPP -#define LIBSNES_HPP - -#include "port.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/////////////////////////////////////////////////////////////////////////////// -// LIBSNES Super Nintendo emulation API -// -// Things you should know: -// - Linking against libsnes requires a C++ compiler. It can be compiled with -// a C99 compiler if you #include and if your C99 compiler's -// bool type is compatible with the bool type used by the C++ compiler used -// to compile libsnes. -// - libsnes supports exactly one emulated SNES; if you want to run two SNESes -// in a single process, you'll need to link against or dlopen() two -// different copies of the library. -// -// Typical usage of the libsnes API looks like this: -// -// 1. Call snes_init() to initialize the library. -// 2. Tell libsnes which callback should be called for each event (see the -// documentation on the individual callback types below. -// 3. Call one of the snes_load_cartridge_* functions to load cartridge data -// into the emulated SNES. -// 4. If the physical cart had any non-volatile storage, there may be data from -// a previous emulation run that needs to be loaded. Find the storage buffer -// by calling the snes_get_memory_* functions and load any saved data into -// it. -// 5. Call snes_set_controller_port_device() to connect appropriate controllers -// to the emulated SNES. -// 6. Call snes_get_region() to determine the intended screen refresh rate for -// this cartridge.. -// 7. Call snes_run() to emulate a single frame. Before snes_run() returns, the -// installed callbacks will be called - possibly multiple times. -// 8. When you're done, call snes_term() to free all memory allocated -// associated with the emulated SNES. -// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Constants {{{ - -// These constants represent the two controller ports on the front of the SNES, -// for use with the snes_set_controller_port_device() function and the -// snes_input_state_t callback. -#define SNES_PORT_1 0 -#define SNES_PORT_2 1 - -// These constants represent the different kinds of controllers that can be -// connected to a controller port, for use with the -// snes_set_controller_port_device() function and the snes_input_state_t -// callback. -#define SNES_DEVICE_NONE 0 -#define SNES_DEVICE_JOYPAD 1 -#define SNES_DEVICE_MULTITAP 2 -#define SNES_DEVICE_MOUSE 3 -#define SNES_DEVICE_SUPER_SCOPE 4 -#define SNES_DEVICE_JUSTIFIER 5 -#define SNES_DEVICE_JUSTIFIERS 6 - -// These constants represent the button and axis inputs on various controllers, -// for use with the snes_input_state_t callback. -#define SNES_DEVICE_ID_JOYPAD_B 0 -#define SNES_DEVICE_ID_JOYPAD_Y 1 -#define SNES_DEVICE_ID_JOYPAD_SELECT 2 -#define SNES_DEVICE_ID_JOYPAD_START 3 -#define SNES_DEVICE_ID_JOYPAD_UP 4 -#define SNES_DEVICE_ID_JOYPAD_DOWN 5 -#define SNES_DEVICE_ID_JOYPAD_LEFT 6 -#define SNES_DEVICE_ID_JOYPAD_RIGHT 7 -#define SNES_DEVICE_ID_JOYPAD_A 8 -#define SNES_DEVICE_ID_JOYPAD_X 9 -#define SNES_DEVICE_ID_JOYPAD_L 10 -#define SNES_DEVICE_ID_JOYPAD_R 11 - -#define SNES_DEVICE_ID_MOUSE_X 0 -#define SNES_DEVICE_ID_MOUSE_Y 1 -#define SNES_DEVICE_ID_MOUSE_LEFT 2 -#define SNES_DEVICE_ID_MOUSE_RIGHT 3 - -#define SNES_DEVICE_ID_SUPER_SCOPE_X 0 -#define SNES_DEVICE_ID_SUPER_SCOPE_Y 1 -#define SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER 2 -#define SNES_DEVICE_ID_SUPER_SCOPE_CURSOR 3 -#define SNES_DEVICE_ID_SUPER_SCOPE_TURBO 4 -#define SNES_DEVICE_ID_SUPER_SCOPE_PAUSE 5 - -#define SNES_DEVICE_ID_JUSTIFIER_X 0 -#define SNES_DEVICE_ID_JUSTIFIER_Y 1 -#define SNES_DEVICE_ID_JUSTIFIER_TRIGGER 2 -#define SNES_DEVICE_ID_JUSTIFIER_START 3 - -// These constants will be returned by snes_get_region(), representing the -// region of the last loaded cartridge. -#define SNES_REGION_NTSC 0 -#define SNES_REGION_PAL 1 - -// These constants represent the kinds of non-volatile memory a SNES cartridge -// might have, for use with the snes_get_memory_* functions. -#define SNES_MEMORY_CARTRIDGE_RAM 0 -#define SNES_MEMORY_CARTRIDGE_RTC 1 -#define SNES_MEMORY_BSX_RAM 2 -#define SNES_MEMORY_BSX_PRAM 3 -#define SNES_MEMORY_SUFAMI_TURBO_A_RAM 4 -#define SNES_MEMORY_SUFAMI_TURBO_B_RAM 5 -#define SNES_MEMORY_GAME_BOY_RAM 6 -#define SNES_MEMORY_GAME_BOY_RTC 7 - -// These constants represent the various kinds of volatile storage the SNES -// offers, to allow libsnes clients to implement things like cheat-searching -// and certain kinds of debugging. They are for use with the snes_get_memory_* -// functions. -#define SNES_MEMORY_WRAM 100 -#define SNES_MEMORY_APURAM 101 -#define SNES_MEMORY_VRAM 102 -#define SNES_MEMORY_OAM 103 -#define SNES_MEMORY_CGRAM 104 - -// SSNES extension. Not required to be implemented for a working implementation. -#define SNES_ENVIRONMENT_GET_FULLPATH 0 // const char ** -- Full path of game loaded. -#define SNES_ENVIRONMENT_SET_GEOMETRY 1 // const struct snes_geometry * -- Window geometry information for the system/game. -#define SNES_ENVIRONMENT_SET_PITCH 2 // const unsigned * -- Pitch of game image. -#define SNES_ENVIRONMENT_GET_OVERSCAN 3 // bool * -- Boolean value whether or not the implementation should use overscan. -#define SNES_ENVIRONMENT_SET_TIMING 4 // const struct snes_system_timing * -- Set exact timings of the system. - // Used primarily for video recording. - -struct snes_geometry -{ - unsigned base_width; // Nominal video width of system. - unsigned base_height; // Nominal video height of system. - unsigned max_width; // Maximum possible width of system. - unsigned max_height; // Maximum possible height of system. -}; - -struct snes_system_timing -{ - double fps; - double sample_rate; -}; - -typedef bool (*snes_environment_t)(unsigned cmd, void *data); - -// Must be called before calling snes_init(). -void snes_set_environment(snes_environment_t); -//// - - -////////////////////////////////////////////////////////////////////////////}}} - -/////////////////////////////////////////////////////////////////////////////// -// Callback types {{{ -// -// In order to deliver controller input to the emulated SNES, and retrieve -// video frames and audio samples, you will need to register callbacks. - -// snes_audio_sample_t: -// -// This callback delivers a stereo audio sample pair generated by the -// emulated SNES. -// -// This function is called once for every audio frame (one sample from left -// and right channels). The SNES generates audio samples at a rate of about -// 32040Hz (varies from unit to unit). -// -// Because the SNES generates video at exactly 59.94fps and most computer -// monitors only support a 60fps refresh rate, real-time emulation needs to -// run slightly fast so that each computer frame displays one emulated SNES -// frame. Because the emulation runs slightly fast, and because most -// consumer audio hardware does not play audio at precisely the requested -// sample rate, you'll likely need to let the end-user tweak the effective -// sample rate by 100Hz or so in either direction. -// -// Although the parameters are declared as unsigned for historical reasons, -// the data they contain is actually signed. To work with the audio (e.g. -// resample), you will need to reinterpret the sample value: -// -// int16_t real_left = *(int16_t*)(&left); -// -// Parameters: -// -// left: -// A signed 16-bit integer containing the next audio sample from the -// left audio channel. Yes, it's declared as unsigned for historical -// reasons. -// -// right: -// A signed 16-bit integer containing the next audio sample from the -// right audio channel. Yes, it's declared as unsigned for historical -// reasons. -// - -typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right); - - -// snes_video_refresh_t: -// -// This callback delivers a single SNES frame, generated by the emulated -// SNES. The same memory buffer may be re-used later, so take a copy of the -// data if you want to refer to it after your callback returns. -// -// The framebuffer is an array of unsigned 16-bit pixels, in a somewhat -// complicated format. A quick refresher on SNES video modes: -// - The basic SNES video-mode renders 256 pixels per scanline for a total -// of 224 scanlines. -// - When "overscan" mode is enabled, the SNES renders a few extra -// scanlines at the end of the frame, for a total of 239 scanlines. -// - When "hi-res" mode is enabled, the SNES speeds up its pixel rendering -// to fit 512 pixels per scanline. -// - Normally the SNES renders its pixels to one field of the interlaced -// NTSC signal, but if "interlaced" mode is enabled the SNES renders -// a second set of scanlines inbetween the regular set, for a total of -// 448 (normal) or 478 (overscan) scanlines. -// -// Thus, the framebuffer memory layout for a standard 256x240 frame looks -// something like this (note that 'height' has been reduced to 4 or 8 for -// these examples): -// -// 0 1024b -// ,---------------------------------------. -// |====== width ======|...................| -. -// |.......................................| | -// |===================|...................| | -// |.......................................| +- height = 4 -// |===================|...................| | -// |.......................................| | -// |===================|...................| | -// |.......................................| -' -// `---------------------------------------' -// -// A hi-res frame would look like this: -// -// 0 1024b -// ,---------------------------------------. -// |================ width ================| -. -// |.......................................| | -// |=======================================| | -// |.......................................| +- height = 4 -// |=======================================| | -// |.......................................| | -// |=======================================| | -// |.......................................| -' -// `---------------------------------------' -// -// An interlaced frame would look like this: -// -// 0 1024b -// ,---------------------------------------. -// |====== width ======|...................| -. -// |===================|...................| | -// |===================|...................| | -// |===================|...................| +- height = 8 -// |===================|...................| | -// |===================|...................| | -// |===================|...................| | -// |===================|...................| -' -// `---------------------------------------' -// -// And of course a hi-res, interlaced frame would look like this: -// -// 0 1024b -// ,---------------------------------------. -// |================ width ================| -. -// |=======================================| | -// |=======================================| | -// |=======================================| |+- height = 8 -// |=======================================| | -// |=======================================| | -// |=======================================| | -// |=======================================| -' -// `---------------------------------------' -// -// More succinctly: -// - the buffer begins at the top-left of the frame -// - the first "width" bytes contain the first scanline. -// - if the emulated SNES is in an interlaced video-mode (that is, if the -// "height" parameter" is 448 or 478) then the second scanline begins at -// an offset of 1024 bytes (512 pixels) after the first. -// - otherwise the second scanline begins at an offset of 2048 bytes (1024 -// pixels) after the first. -// - there are "height" scanlines in total. -// -// Each pixel contains a 15-bit RGB tuple: 0RRRRRGGGGGBBBBB (XRGB1555) -// -// Example code: -// -// void pack_frame (uint16_t * restrict out, const uint16_t * restrict in, -// unsigned width, unsigned height) -// { -// // Normally our pitch is 2048 bytes. -// int pitch_pixels = 1024; -// // If we have an interlaced mode, pitch is 1024 bytes. -// if ( height == 448 || height == 478 ) -// pitch_pixels = 512; -// -// for ( int y = 0; y < height; y++ ) -// { -// const uint16_t *src = in + y * pitch_pixels; -// uint16_t *dst = out + y * width; -// -// memcpy(dst, src, width * sizeof(uint16_t)); -// } -// } -// -// Parameters: -// -// data: -// a pointer to the beginning of the framebuffer described above. -// -// width: -// the width of the frame, in pixels. -// -// height: -// the number of scanlines in the frame. - -typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, - unsigned height); - -// snes_input_poll_t: -// -// This callback requests that you poll your input devices for events, if -// required. -// -// Generally called once per frame before the snes_input_state_t callback is -// called. -// - -typedef void (*snes_input_poll_t)(void); - -// snes_input_state_t: -// -// This callback asks for information about the state of a particular input. -// -// The callback may be called multiple times per frame with the same -// parameters. -// -// The callback might not be called at all, if the software running in the -// emulated SNES does not try to probe the controllers. -// -// The callback will not be called for a particular port if DEVICE_NONE is -// connected to it. -// -// If you wish to emulate any kind of turbo-fire, etc. then you will need to -// put that logic into this callback. -// -// Parameters: -// -// port: -// One of the constants SNES_PORT_1 or SNES_PORT_2, describing which -// controller port you should report. -// -// device: -// One of the SNES_DEVICE_* constants describing which type of device -// is currently connected to the given port. -// -// index: -// A number describing which of the devices connected to the port is -// being reported. It's only useful for SNES_DEVICE_MULTITAP and -// SNES_DEVICE_JUSTIFIERS - for other device types, this parameter is -// always 0. -// -// id: -// One of the SNES_DEVICE_ID_* constants for the given device, -// describing which button or axis is being reported (for -// SNES_DEVICE_MULTITAP, use the SNES_DEVICE_ID_JOYPAD_* IDs; for -// SNES_DEVICE_JUSTIFIERS use the SNES_DEVICE_ID_JUSTIFIER_* IDs.). -// -// Returns: -// -// An integer representing the state of the described button or axis. -// -// - If it represents a digital input such as SNES_DEVICE_ID_JOYPAD_B or -// SNES_DEVICE_ID_MOUSE_LEFT), return 1 if the button is pressed, and -// 0 otherwise. -// - If "id" is SNES_DEVICE_ID_MOUSE_X or SNES_DEVICE_ID_MOUSE_Y then -// return the relative movement of the mouse during the current frame; -// values outside the range -127 to +127 will be clamped. -// - If "id" is one of the light-gun axes (such as -// SNES_DEVICE_ID_JUSTIFIER_Y or SNES_DEVICE_ID_SUPER_SCOPE_X), you -// should return the relative movement of the pointing device during the -// current frame. - -typedef int16_t (*snes_input_state_t)(bool port, unsigned device, - unsigned index, unsigned id); - -////////////////////////////////////////////////////////////////////////////}}} - -/////////////////////////////////////////////////////////////////////////////// -// libsnes setup {{{ -// -// These functions are used to get information about and manipulate the libsnes -// library itself, not the emulated SNES it implements. - -// snes_library_id: -// -// Returns a human readable string describing this libsnes implementation. -// It is not supposed to be parsed or used in any other way than being -// printed to screen on request by user or otherwise. -// -// Returns: -// -// A human-readable string describing this implementation. - -const char* snes_library_id(void); - - -// snes_library_revision_major: -// -// Returns the major API version of this libsnes implementation. -// -// This number is increased every time there is a compatibility-breaking -// change to the libsnes API. At startup, your program should call this -// function and compare the return value to the major API version the -// program was designed to work with. If they are different, your program -// will (very likely) not work with this libsnes implementation. -// -// For example, if your program was designed to work with the libsnes API -// whose major.minor revision was 1.5, and this function returns a major -// version of 2, you have a problem. -// -// Returns: -// -// An integer, the major API version of this libsnes implementation. - -unsigned snes_library_revision_major(void); - -// snes_library_revision_minor: -// -// Returns the minor API version of this libsnes implementation. -// -// This number is increased every time there is a backwards-compatible -// change to the libsnes API. At startup, your program should call this -// function and compare the return value to the minor API version the -// program was designed to work with. If the return value is less than the -// expected minor version, your program will (very likely) not work with -// this libsnes implementation. -// -// For example, if your program was designed to work with the libsnes API -// whose major.minor revision was 1.5, and this libsnes implementation's -// major.minor version is 1.3, it's probably missing features you require. -// On the other hand, if this libsnes implementation's major.minor version -// is 1.9, it probably has extra fancy features you don't need to worry -// about. -// -// Returns: -// -// An integer, the minor API version of this libsnes implementation. - -unsigned snes_library_revision_minor(void); - -// snes_init: -// -// Initializes the libsnes implementation. -// -// This function must be called exactly once before any other library -// functions are called. - -void snes_init(void); - -// snes_term: -// -// Shuts down the libsnes implementation. -// -// This function must be called exactly once. Once called, you should not -// call any other libsnes functions besides (perhaps) snes_init(). - -void snes_term(void); - -////////////////////////////////////////////////////////////////////////////}}} - -/////////////////////////////////////////////////////////////////////////////// -// Callback registration {{{ -// -// Note that all callbacks should be set up before snes_run() is called for the -// first time. - -// snes_set_video_refresh: -// -// Sets the callback that will receive new video frames. -// -// See the documentation for snes_video_refresh_t for details. -// -// Parameters: -// -// A pointer to a function matching the snes_video_refresh_t call -// signature. - -void snes_set_video_refresh(snes_video_refresh_t); - -// snes_set_audio_sample -// -// Sets the callback that will receive new audio sample pairs. -// -// See the documentation for snes_audio_sample_t for details. -// -// Parameters: -// -// A pointer to a function matching the snes_audio_sample_t call -// signature. - -void snes_set_audio_sample(snes_audio_sample_t); - -// snes_set_input_poll: -// -// Sets the callback that will be notified to poll input devices. -// -// See the documentation for snes_input_poll_t for details. -// -// Parameters: -// -// A pointer to a function matching the snes_input_poll_t call signature. - -void snes_set_input_poll(snes_input_poll_t); - -// snes_set_input_state: -// -// Sets the callback that will be used to read input device state. -// -// See the documentation for snes_input_state_t for details. -// -// Parameters: -// -// A pointer to a function matching the snes_input_state_t call signature. - -void snes_set_input_state(snes_input_state_t); - -////////////////////////////////////////////////////////////////////////////}}} - -/////////////////////////////////////////////////////////////////////////////// -// SNES operation {{{ -// -// Functions for manipulating the emulated SNES. - -// snes_set_controller_port_device: -// -// Sets the input device connected to a given controller port. -// -// Connecting a device to a port implicitly removes any device previously -// connected to that port. To remove a device without connecting a new one, -// pass DEVICE_NONE as the device parameter. From this point onward, the -// callback passed to set_input_state_cb() will be called with the -// appropriate device, index and id parameters. -// -// If this function is never called, the default is to have a DEVICE_JOYPAD -// connected to both ports. -// -// Calling this callback from inside the set_input_state_cb() has undefined -// results, so don't do that. -// -// Parameters: -// -// port: -// One of the constants SNES_PORT_1 or SNES_PORT_2, describing which -// controller port is being configured. -// -// device: -// One of the SNES_DEVICE_* constants describing which type of device -// should be connected to the given port. Note that some devices can -// only be connected to SNES_PORT_2. Attempting to connect -// a port-2-only device to SNES_PORT_1 has undefined results. -// -// These devices work in either port: -// - SNES_DEVICE_NONE: No device is connected to this port. -// - SNES_DEVICE_JOYPAD: A standard SNES gamepad. -// - SNES_DEVICE_MULTITAP: A multitap controller, which acts like -// 4 SNES_DEVICE_JOYPADs. Your input state callback will be -// passed "id" parameters between 0 and 3, inclusive. -// - SNES_DEVICE_MOUSE: A SNES mouse controller, as shipped with -// Mario Paint. -// -// These devices only work properly when connected to port 2: -// - SNES_DEVICE_SUPER_SCOPE: A Nintendo Super Scope light-gun -// device. -// - SNES_DEVICE_JUSTIFIER: A Konami Justifier light-gun device. -// - SNES_DEVICE_JUSTIFIERS: Two Konami Justifier light-gun -// devices, daisy-chained together. Your input state callback -// will be passed "id" parameters 0 and 1. - -void snes_set_controller_port_device(bool port, unsigned device); - -// snes_power: -// -// Turns the emulated console off and back on. -// -// This functionality is sometimes called "hard reset" and guarantees that -// all hardware state is reset to a reasonable default. -// -// Before bsnes v070r07, this resets the controller ports to both contain -// SNES_DEVICE_JOYPADs. -// -// This requires that a cartridge is loaded. - -void snes_power(void); - -// snes_reset: -// -// Presses the "reset" button on the emulated SNES. -// -// This functionality is sometimes called "soft reset". Most hardware state -// is reset to a reasonable befault, but not all. -// -// As of bsnes v073r01, this function (as a side-effect) resets the -// controller ports to both contain SNES_DEVICE_JOYPADs. -// -// This requires that a cartridge is loaded. - -void snes_reset(void); - -// snes_run(): -// -// Runs the emulated SNES until the end of the next video frame. -// -// Usually causes each registered callback to be called before returning. -// -// This function will run as fast as possible. It is up to the caller to -// make sure that the game runs at the intended speed. -// -// For optimal A/V sync, make sure that the audio callback never blocks for -// longer than a frame (approx 16ms for NTSC, 20ms for PAL) -// -// Optimally, it should never block for more than a few ms at a time. - -void snes_run(void); - -// snes_get_region(): -// -// Determines the intended frame-rate of the loaded cartridge. -// -// The two main SNES hardware variants are the US/Japan variant, designed -// for NTSC output, and the European variant, designed for PAL output. -// However, the world is not quite so tidy as that, and there are countries -// like Brazil that use PAL output at NTSC frame-rates. -// -// For historical reasons this function is named snes_get_region(), but -// effectively the only information you can reliably infer is the -// frame-rate. -// -// Returns: -// -// One of the SNES_REGION_* constants. SNES_REGION_PAL means 50fps, -// SNES_REGION_NTSC means 60fps. - -bool snes_get_region(void); - -////////////////////////////////////////////////////////////////////////////}}} - -/////////////////////////////////////////////////////////////////////////////// -// Save state support {{{ -// -// libsnes has the ability to save the current emulation state and restore it -// at a later time. -// -// Note 1: It is impossible to reliably restore the *exact* state, although the -// difference is only a few cycles. If you demand the ability to reliably -// restore state, call snes_serialize() after each frame to ensure the emulated -// SNES is in a state that can be reliably restored. -// -// Note 2: The save state information is specific to a particular cartridge -// loaded into a particular version of a particular libsnes implementation. -// Unfortunately, there is not yet a way to determine whether a given save -// state is compatible with a given libsnes implementation, other than by -// loading it. However, if snes_serialize_size() does not match the size of an -// old save state, that's a strong hint that something has incompatibly -// changed. - -// snes_serialize_size: -// -// Determines the minimum size of a save state. -// -// This value can change depending on the features used by the loaded -// cartridge, and the version of the libsnes implementation used. -// -// Returns: -// -// An integer representing the number of bytes required to store the -// current emulation state. - -unsigned snes_serialize_size(void); - -// snes_serialize: -// -// Serialize the current emulation state to a buffer. -// -// If the allocated buffer is smaller than the size returned by -// snes_serialize_size(), serialization will fail. If the allocated buffer -// is larger, only the first snes_serialize_size() bytes will be written to. -// -// The resulting buffer may be stored, and later passed to -// snes_unserialize() to restore the saved emulation state. -// -// Parameters: -// -// data: -// A pointer to an allocated buffer of memory. -// -// size: -// The size of the buffer pointed to by "data". Should be greater than -// or equal to the value returned by snes_serialize_size(). -// -// Returns: -// -// A boolean; True means the emulation state was serialized successfully, -// False means a problem was encountered. - -bool snes_serialize(uint8_t *data, unsigned size); - -// snes_unserialize: -// -// Unserialize the emulation state from a buffer. -// -// If the serialization data in the buffer does not appear to be compatible -// with the current libsnes implementation, the function returns False and -// the current emulation state is not modified. -// -// Parameters: -// -// data: -// A pointer to an allocated buffer of memory. -// -// size: -// The size of the buffer pointed to by "data". Should be greater than -// or equal to the value returned by snes_serialize_size(). -// -// Returns: -// -// A boolean; True means the emulation state was loaded successfully, -// False means a problem was encountered. - -bool snes_unserialize(const uint8_t *data, unsigned size); - -////////////////////////////////////////////////////////////////////////////}}} - -/////////////////////////////////////////////////////////////////////////////// -// Cheat support {{{ -// -// libsnes does not include any kind of cheat management API; the intention is -// that any change to the set of applied cheats will cause the containing -// application to call snes_cheat_reset() then apply the new set of cheats with -// snes_cheat_set(). -// -// Any currently-applied cheats are discarded when a new cartridge is loaded. - -// snes_cheat_reset: -// -// Discards all cheat codes applied to the emulated SNES. - -void snes_cheat_reset(void); - -// snes_cheat_set: -// -// Apply a sequence of cheat codes to the emulated SNES. -// -// Since a "cheat code" is basically an instruction to override the value of -// a particular byte in the SNES' memory, more complex cheats may require -// several individual codes applied at once. There's no effective difference -// between applying these codes in a group with one call to -// snes_cheat_set(), or applying them one at a time with individual calls. -// However, most cheat databases will have a collection of available cheats -// for each game, where each item in the collection has a description and -// a sequence of codes to be applied as a unit. This API makes it easy to -// present the list of descriptions to the user, and apply each cheat the -// user selects. -// -// Parameters: -// -// index: -// The given cheat code will be stored at this index in the array of -// applied cheats. If a cheat already exists at this location, it will -// be replaced by the new cheat. If the index is larger than any -// previously specififed index, the array will be resized to -// accommodate. -// -// enabled: -// True means that the cheat will actually be applied, False means -// that the cheat will have no effect. There is no way to enable or -// disable a cheat after it has been added, other than to call -// snes_cheat_set() a second time with the same values for "index" and -// "code". -// -// code: -// A string containing a sequence of cheat codes separated by '+' -// characters. Any spaces in the string will be removed before -// parsing. -// -// Each code in the sequence must be in either GameGenie format -// ("1234-ABCD") or ProActionReplay format ("1234AB:CD" or -// "1234ABCD"). - -void snes_cheat_set(unsigned index, bool enabled, const char *code); - -////////////////////////////////////////////////////////////////////////////}}} - -/////////////////////////////////////////////////////////////////////////////// -// Cartridge loading and unloading {{{ -// -// Before calling snes_run(), a cartridge must be loaded into the emulated SNES -// so that it has code to run. -// -// Loading a cartridge of any kind calls snes_cheat_reset() as a side-effect. - -// snes_load_cartridge_normal: -// -// Load a normal ROM image into the emulated SNES. -// -// Parameters: -// -// rom_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes where the ROM image is mapped into the SNES address -// space, what special chips it uses (and where they're mapped), etc. -// -// If NULL, libsnes will guess a memory map. The guessed memory map -// should be correct for all licenced games in all regions. -// -// rom_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless ROM image. -// -// rom_size: -// The length of the rom_data array, in bytes. -// -// Returns: -// -// A boolean; True means the cartridge was loaded correctly, False means -// an error occurred. - -bool snes_load_cartridge_normal( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size -); - -// snes_load_cartridge_bsx: -// -// Load a BS-X base cart image, optionally with a memory pack. -// -// The Satellaview system, abbreviated "BS-X" for unclear reasons, was an -// addon for the Super Famicom that connected it to the St. GIGA satellite -// network. The network would broadcast games at a particular time, and -// users could download them to replaceable memory packs. -// -// For more information, see http://en.wikipedia.org/wiki/Satellaview -// -// Parameters: -// -// rom_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes where the BS-X base cartridge ROM image is mapped -// into the SNES address space. -// -// If NULL, libsnes will guess a memory map. The guessed memory map -// should be correct for all known BS-X base cartridge images. -// -// rom_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless ROM image of the BS-X base cartridge. -// -// The BS-X base cartridge is named "BS-X - Sore wa Namae o Nusumareta -// Machi no Monogatari" in some SNES game databases. -// -// rom_size: -// The length of the rom_data array, in bytes. -// -// bsx_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes the BS-X memory pack. -// -// This parameter is currently ignored and should be passed as NULL. -// -// bsx_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless image of the BS-X memory-pack. -// -// If NULL, libsnes will behave as though no memory-pack were inserted -// into the base cartridge. -// -// bsx_size: -// The length of the bsx_data array, in bytes. -// -// Returns: -// -// A boolean; True means the cartridge was loaded correctly, False means -// an error occurred. - -bool snes_load_cartridge_bsx( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -); - -// snes_load_cartridge_bsx_slotted: -// -// Load a BS-X slotted cartridge, optionally with a memory pack. -// -// A BS-X slotted cartridge is an ordinary SNES cartridge, with a slot in -// the top that accepts the same memory packs used by the BS-X base -// cartridge. -// -// Parameters: -// -// rom_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes where the ROM image is mapped into the SNES address -// space, what special chips it uses (and where they're mapped), etc. -// -// If NULL, libsnes will guess a memory map. The guessed memory map -// should be correct for all licenced games in all regions. -// -// rom_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless ROM image. -// -// rom_size: -// The length of the rom_data array, in bytes. -// -// bsx_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes the BS-X memory pack. -// -// This parameter is currently ignored and should be passed as NULL. -// -// bsx_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless image of the BS-X memory-pack. -// -// If NULL, libsnes will behave as though no memory-pack were inserted -// into the base cartridge. -// -// bsx_size: -// The length of the bsx_data array, in bytes. -// -// Returns: -// -// A boolean; True means the cartridge was loaded correctly, False means -// an error occurred. - -bool snes_load_cartridge_bsx_slotted( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -); - -// snes_load_cartridge_sufami_turbo: -// -// Load a SuFami Turbo base cart image, optionally with game packs. -// -// The SuFami Turbo was a cartridge available for the Super Famicom, created -// by Bandai, with two slots in the top designed to accept special -// mini-cartridges. The cartridge in Slot A was the cartridge that actually -// ran, while the cartridge in Slot B was made available to the Slot -// A cartridge, enabling sharing of save-game data or using characters from -// one game in another. -// -// For more information, see: http://en.wikipedia.org/wiki/Sufami_Turbo -// -// Parameters: -// -// rom_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes where the SuFami Turbo base cartridge ROM image is -// mapped into the SNES address space. -// -// If NULL, libsnes will guess a memory map. The guessed memory map -// should be correct for all known SuFami Turbo base cartridge images. -// -// rom_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless ROM image of the SuFami Turbo base -// cartridge. -// -// The SuFami Turbo base cartridge is named "Sufami Turbo" in some -// SNES game databases. -// -// rom_size: -// The length of the rom_data array, in bytes. -// -// sta_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes the Sufami Turbo cartridge in Slot A. -// -// This parameter is currently ignored and should be passed as NULL. -// -// sta_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless ROM image of the SuFami Turbo cartridge -// in Slot A. -// -// This is the cartridge that will be executed by the SNES. -// -// If NULL, libsnes will behave as though no cartridge were inserted -// into the Slot A. -// -// sta_size: -// The length of the sta_data array, in bytes. -// -// stb_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes the Sufami Turbo cartridge in Slot B. -// -// This parameter is currently ignored and should be passed as NULL. -// -// stb_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless ROM image of the SuFami Turbo cartridge -// in Slot B. -// -// The data in this cartridge will be made available to the cartridge -// in Slot A. -// -// If NULL, libsnes will behave as though no cartridge were inserted -// into Slot B. -// -// stb_size: -// The length of the stb_data array, in bytes. -// -// Returns: -// -// A boolean; True means the cartridge was loaded correctly, False means -// an error occurred. - -bool snes_load_cartridge_sufami_turbo( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *sta_xml, const uint8_t *sta_data, unsigned sta_size, - const char *stb_xml, const uint8_t *stb_data, unsigned stb_size -); - -// snes_load_cartridge_super_game_boy: -// -// Load a Super Game Boy base cart, optionally with a Gameboy cartridge. -// -// The Super Game Boy was a cartridge available for the Super Famicom and -// Super Nintendo that accepted ordinary (original) Gameboy cartridges and -// allowed the user to play them with a Super Nintendo controller, on a TV. -// It extended the orginal Gameboy hardware in a few ways, including the -// ability to display games in various palettes (rather than strictly -// monochrome), to display a full-colour border image around the Gameboy -// video output, or even run native SNES code to enhance the game. -// -// For more information, see: http://en.wikipedia.org/wiki/Super_Game_Boy -// -// Up until bsnes v073, loading Super Game Boy cartridges only works if the -// libsupergameboy library from the bsnes release is installed. bsnes v074 -// includes a custom Gameboy emulation core, and external code is no longer -// required. -// -// Parameters: -// -// rom_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes where the Super Game Boy base cartridge ROM image is -// mapped into the SNES address space. -// -// If NULL, libsnes will guess a memory map. The guessed memory map -// should be correct for all known Super Game Boy base cartridge -// images. -// -// rom_data: -// A pointer to a byte array containing the uncompressed, -// de-interleaved, headerless ROM image of the Super Game Boy base -// cartridge. -// -// Appropriate base cartridge images are named "Super Game Boy" or -// "Super Game Boy 2" in some SNES game databases. -// -// rom_size: -// The length of the rom_data array, in bytes. -// -// dmg_xml: -// A pointer to a null-terminated string containing an XML memory map -// that describes the inserted Gameboy cartridge. -// -// If NULL, libsnes will guess a memory map. The guesed memory map -// should be correct for all licensed original Gameboy games in all -// regions. -// -// dmg_data: -// A pointer to a byte array containing the uncompressed, headerless -// ROM image of the inserted Gameboy cartridge. -// -// If NULL, libsnes will behave as though no cartridge were inserted. -// -// dmg_size: -// The length of the dmg_size array, in bytes. -// -// Returns: -// -// A boolean; True means the cartridge was loaded correctly, False means -// an error occurred. - -bool snes_load_cartridge_super_game_boy( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size -); - -// snes_set_cartridge_basename: -// -// Set the location and name of the loaded cartridge. -// -// libsnes uses this information to locate additional resources the -// cartridge might require. Currently, these resources include: -// -// - The MSU-1 data pack and associated audio tracks, if the cartridge makes -// use of bsnes' MSU-1 special-chip. -// - The serial-port data receiving library, if the cartridge makes uses of -// bsnes' serial-data-over-controller-port feature. -// -// Parameters: -// -// basename: -// The path and basename of the loaded cartridge. For example, if the -// full path to the loaded cartridge is "/path/to/filename.sfc", this -// parameter should be set to "/path/to/filename". - -void snes_set_cartridge_basename(const char *basename); - -// snes_unload_cartridge: -// -// Unloads the currently loaded cartridge from the emulated SNES. -// -// You will be unable to call snes_run() until another cartridge is loaded. - -void snes_unload_cartridge(void); - -////////////////////////////////////////////////////////////////////////////}}} - -/////////////////////////////////////////////////////////////////////////////// -// Volatile and non-volatile storage {{{ -// -// Certain SNES cartridges include non-volatile storage or other kinds of data -// that would persist after the SNES is turned off. libsnes exposes this -// information via the snes_get_memory_data() and snes_get_memory_size() -// functions. Since version 1.2 of the libsnes API, libsnes also exposes the -// contents of volatile storage such as WRAM and VRAM. -// -// After a cartridge is loaded, call snes_get_memory_size() and -// snes_get_memory_data() with the various SNES_MEMORY_* constants to determine -// which kinds of non-volatile storage the cartridge supports - unsupported -// storage types will have a size of 0 and the data pointer NULL. -// -// If you have non-volatile storage data from a previous run, you can memcpy() -// the data from your storage into the buffer described by the data and size -// values before calling snes_run(). Do not load non-volatile storage data if -// the size of the data you have is different from the size returned by -// snes_get_memory_size(). -// -// Before calling snes_unload_cartridge(), you should copy the contents of the -// relevant storage buffers into a file (or some non-volatile storage of your -// own) so that you can load it the next time you load the same cartridge into -// the emulated SNES. Do not call free() on the storage buffers; they will be -// handled by libsnes. Note: It is not necessary to store the contents of -// volatile storage; the emulated SNES expects information in volatile storage -// to be lost (hence the name 'volatile'). -// -// Because non-volatile storage is read and written by the software running on -// the emulated SNES, it should be compatible between different versions of -// different emulators running on different platforms, unlike save states. -// -// The various kinds of non-volatile storage and their uses are: -// -// SNES_MEMORY_CARTRIDGE_RAM: -// Standard battery-backed static RAM (SRAM). Traditionally, the SRAM for -// a ROM image named "foo.sfc" is stored in a file named "foo.srm" beside -// it. -// -// SNES_MEMORY_CARTRIDGE_RTC: -// Real-time clock data. Traditionally, the RTC data for a ROM image named -// "foo.sfc" is stored in a file named "foo.rtc" beside it. -// -// SNES_MEMORY_BSX_RAM: -// RAM data used with the BS-X base cartridge. -// -// SNES_MEMORY_BSX_PRAM: -// PRAM data used with the BS-X base cartridge. -// -// SNES_MEMORY_SUFAMI_TURBO_A_RAM: -// RAM data stored in the mini-cartridge inserted into Slot A of the -// SuFami Turbo base cartridge. -// -// SNES_MEMORY_SUFAMI_TURBO_B_RAM: -// RAM data stored in the mini-cartridge inserted into Slot B of the -// SuFami Turbo base cartridge. -// -// SNES_MEMORY_GAME_BOY_RAM: -// Standard battery-backed static RAM (SRAM) in the Gameboy cartridge -// inserted into the Super Game Boy base cartridge. Not all Gameboy games -// have SRAM. -// -// SNES_MEMORY_GAME_BOY_RTC: -// Real-time clock data in the Gameboy cartridge inserted into the Super -// Game Boy base cartridge. Not all Gameboy games have an RTC. -// -// The various kinds of volatile storage are: -// -// SNES_MEMORY_WRAM: -// Working RAM, accessible by the CPU. SNES software tends to keep runtime -// information in here; games' life-bars and inventory contents and so -// forth are in here somewhere. -// -// SNES_MEMORY_APURAM: -// RAM accessible by the Audio Processing Unit. Contains audio samples, -// music data and the code responsible for feeding the right notes to the -// DSP at the right times. -// -// SNES_MEMORY_VRAM: -// Video RAM. Stores almost everything related to video output, including -// the patterns used for each tile and sprite, tilemaps for each -// background. The exact format used depends on the current video mode of -// the emulated SNES. -// -// SNES_MEMORY_OAM: -// Object Attribute Memory. Stores the location, orientation and priority -// of all the sprites the SNES displays. -// -// SNES_MEMORY_CGRAM: -// Color Generator RAM. Contains the colour palettes used by tiles and -// sprites. Each palette entry is stored in a 16-bit int, in the standard -// XBGR1555 format. - -// snes_get_memory_data: -// -// Returns a pointer to the given non-volatile storage buffer. -// -// This requires that a cartridge is loaded. -// -// Parameters: -// -// id: -// One of the SNES_MEMORY_* constants. -// -// Returns: -// -// A pointer to the memory buffer used for storing the given type of data. -// The size of the buffer can be obtained from snes_get_memory_size(). -// -// If NULL, the loaded cartridge does not store the given type of data. - -uint8_t* snes_get_memory_data(unsigned id); - -// snes_get_memory_size: -// -// Returns the size of the given non-volatile storage buffer. -// -// This requires that a cartridge is loaded. -// -// Parameters: -// -// id: -// One of the SNES_MEMORY_* constants. -// -// Returns: -// -// The size of the memory buffer used for storing the given type of data. -// A pointer to the buffer can be obtained from snes_get_memory_data(). -// -// If 0, the loaded cartridge does not store the given type of data. - -unsigned snes_get_memory_size(unsigned id); - -////////////////////////////////////////////////////////////////////////////}}} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libsnes/link.T b/libsnes/link.T deleted file mode 100644 index 432292c1..00000000 --- a/libsnes/link.T +++ /dev/null @@ -1,4 +0,0 @@ -{ - global: snes_*; - local: *; -};