From 1915be5aead8089e086e3b24a6c25b429512f86a Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 7 Feb 2011 11:15:32 +0100 Subject: [PATCH] Add libsnes.hpp to the build so dynamic build doesn't require libsnes per se. --- libsnes.hpp | 1222 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1222 insertions(+) create mode 100755 libsnes.hpp diff --git a/libsnes.hpp b/libsnes.hpp new file mode 100755 index 0000000000..cd613f05f4 --- /dev/null +++ b/libsnes.hpp @@ -0,0 +1,1222 @@ +#ifndef LIBSNES_HPP +#define LIBSNES_HPP + +#include + +#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 + +////////////////////////////////////////////////////////////////////////////}}} + +/////////////////////////////////////////////////////////////////////////////// +// 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_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