1265 lines
48 KiB
C++
1265 lines
48 KiB
C++
|
#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 <stdbool.h> 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
|