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 57%
rename from libsnes/libsnes.cpp
rename to libretro/libretro.cpp
index 3cf5b2ce..12f04ad8 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,170 @@ 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);
}
-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->geometry.aspect_ratio = 4.0 / 3.0;
+ 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 +268,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 +277,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 +302,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 +414,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 +423,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,40 +488,28 @@ 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:
- data = SNES::smp.apuram;
- break;
- case SNES_MEMORY_VRAM:
- data = Memory.VRAM;
- break;
- case SNES_MEMORY_CGRAM:
- data = (uint8_t*)PPU.CGDATA;
- break;
- case SNES_MEMORY_OAM:
- data = PPU.OAMData;
break;
default:
data = NULL;
@@ -538,40 +519,30 @@ 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_APURAM:
- size = 64 * 1024;
- break;
- case SNES_MEMORY_CGRAM:
- size = 512;
- break;
- case SNES_MEMORY_OAM:
- size = 512 + 32;
break;
default:
size = 0;
@@ -581,89 +552,56 @@ 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(void *data, size_t size)
{
- if (S9xFreezeGameMem(data,size) == FALSE)
+ if (S9xFreezeGameMem((uint8_t*)data,size) == FALSE)
return false;
return true;
}
-bool snes_unserialize(const uint8_t* data, unsigned size)
+bool retro_unserialize(const void* data, size_t size)
{
- if (S9xUnfreezeGameMem(data,size) != SUCCESS)
+ if (S9xUnfreezeGameMem((const uint8_t*)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;
+ }
+ }
+ else
+ {
+ if (height > SNES_HEIGHT_EXTENDED)
+ {
+ if (height < SNES_HEIGHT_EXTENDED << 1)
+ memset(GFX.Screen + (GFX.Pitch >> 1) * height,0,GFX.Pitch * ((SNES_HEIGHT_EXTENDED << 1) - height));
+ height = SNES_HEIGHT_EXTENDED << 1;
+ }
+ else
+ {
+ if (height < SNES_HEIGHT_EXTENDED)
+ memset(GFX.Screen + (GFX.Pitch >> 1) * height,0,GFX.Pitch * (SNES_HEIGHT_EXTENDED - height));
+ height = SNES_HEIGHT_EXTENDED;
}
}
- s9x_video_cb(GFX.Screen, width, height);
+ s9x_video_cb(GFX.Screen, width, height, GFX.Pitch);
return TRUE;
}
@@ -675,7 +613,6 @@ bool8 S9xContinueUpdate(int width, int height)
// Dummy functions that should probably be implemented correctly later.
void S9xParsePortConfig(ConfigFile&, int) {}
void S9xSyncSpeed() {}
-//void S9xPollPointer(int, short*, short*) {}
const char* S9xStringInput(const char* in) { return in; }
const char* S9xGetFilename(const char* in, s9x_getdirtype) { return in; }
const char* S9xGetDirectory(s9x_getdirtype) { return ""; }
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: *;
-};
diff --git a/memmap.cpp b/memmap.cpp
index 54f83587..72196bb1 100644
--- a/memmap.cpp
+++ b/memmap.cpp
@@ -2167,9 +2167,6 @@ bool8 CMemory::SaveSRAM (const char *filename)
size_t ignore;
ignore = fwrite((char *) Multi.sramB, size, 1, file);
fclose(file);
- #ifdef __linux
- ignore = chown(name, getuid(), getgid());
- #endif
}
strcpy(ROMFilename, temp);
@@ -2187,9 +2184,6 @@ bool8 CMemory::SaveSRAM (const char *filename)
size_t ignore;
ignore = fwrite((char *) SRAM, size, 1, file);
fclose(file);
- #ifdef __linux
- ignore = chown(sramName, getuid(), getgid());
- #endif
if (Settings.SRTC || Settings.SPC7110RTC)
SaveSRTC();
diff --git a/win32/zlib/zlib.vcproj b/win32/zlib/zlib.vcproj
index 979ff284..d14adf81 100644
--- a/win32/zlib/zlib.vcproj
+++ b/win32/zlib/zlib.vcproj
@@ -1,7 +1,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+