using System;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
///
/// static bindings into libgambatte.dll
///
public static class LibGambatte
{
///
///
///
/// opaque state pointer
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr gambatte_create();
///
///
///
/// opaque state pointer
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_destroy(IntPtr core);
[Flags]
public enum LoadFlags : uint
{
/// Treat the ROM as not having CGB support regardless of what its header advertises
FORCE_DMG = 1,
/// Use GBA intial CPU register values when in CGB mode.
GBA_CGB = 2,
/// Use heuristics to detect and support some multicart MBCs disguised as MBC1.
MULTICART_COMPAT = 4
}
///
/// Load ROM image.
///
/// opaque state pointer
/// the rom data, can be disposed of once this function returns
/// length of romdata in bytes
/// RTC time when the rom is loaded
/// ORed combination of LoadFlags.
/// 0 on success, negative value on failure.
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, long now, LoadFlags flags);
///
/// Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,
/// or until a video frame has been drawn.
///
/// There are 35112 stereo sound samples in a video frame.
/// May run for up to 2064 stereo samples too long.
/// A stereo sample consists of two native endian 2s complement 16-bit PCM samples,
/// with the left sample preceding the right one.
///
/// Returns early when a new video frame has finished drawing in the video buffer,
/// such that the caller may update the video output before the frame is overwritten.
/// The return value indicates whether a new video frame has been drawn, and the
/// exact time (in number of samples) at which it was drawn.
///
/// opaque state pointer
/// buffer with space >= samples + 2064
/// in: number of stereo samples to produce, out: actual number of samples produced
/// sample number at which the video frame was produced. -1 means no frame was produced.
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_runfor(IntPtr core, short[] soundbuf, ref uint samples);
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe public static extern int gambatte_runfor(IntPtr core, short* soundbuf, ref uint samples);
///
/// blit from internal framebuffer to provided framebuffer
///
/// opaque state pointer
///
/// in pixels
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe public static extern void gambatte_blitto(IntPtr core, int* videobuf, int pitch);
///
/// blit from internal framebuffer to provided framebuffer
///
/// opaque state pointer
///
/// in pixels
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_blitto(IntPtr core, int[] videobuf, int pitch);
///
/// Reset to initial state.
/// Equivalent to reloading a ROM image, or turning a Game Boy Color off and on again.
///
/// opaque state pointer
/// RTC time when the reset occurs
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_reset(IntPtr core, long now);
///
/// palette type for gambatte_setdmgpalettecolor
///
public enum PalType : uint
{
BG_PALETTE = 0,
SP1_PALETTE = 1,
SP2_PALETTE = 2
};
///
///
///
/// opaque state pointer
/// in [0, 2]: One of BG_PALETTE, SP1_PALETTE and SP2_PALETTE.
/// in [0, 3]
///
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setdmgpalettecolor(IntPtr core, PalType palnum, uint colornum, uint rgb32);
///
/// set cgb palette lookup
///
/// opaque state pointer
/// uint32[32768], input color (r,g,b) is at lut[r | g << 5 | b << 10]
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setcgbpalette(IntPtr core, int[] lut);
///
/// combination of button flags used by the input callback
///
[Flags]
public enum Buttons
{
A = 0x01,
B = 0x02,
SELECT = 0x04,
START = 0x08,
RIGHT = 0x10,
LEFT = 0x20,
UP = 0x40,
DOWN = 0x80
}
///
/// type of the callback for input state
///
/// bitfield combination of pressed buttons
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate Buttons InputGetter();
///
/// Sets the callback used for getting input state.
///
/// opaque state pointer
///
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setinputgetter(IntPtr core, InputGetter getinput);
///
/// type of the read\write memory callbacks
///
/// the address which the cpu is read\writing
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void MemoryCallback(uint address);
///
/// set a callback to occur immediately BEFORE EVERY cpu read, except for opcode first byte fetches
///
/// opaque state pointer
/// null to clear
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setreadcallback(IntPtr core, MemoryCallback callback);
///
/// set a callback to occur immediately AFTER EVERY cpu write
///
/// opaque state pointer
/// null to clear
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setwritecallback(IntPtr core, MemoryCallback callback);
///
/// set a callback to occur immediately BEFORE EVERY cpu opcode (first byte) fetch
///
/// opaque state pointer
/// null to clear
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setexeccallback(IntPtr core, MemoryCallback callback);
///
/// type of the cpu trace callback
///
/// cpu state
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void TraceCallback(IntPtr state);
///
/// set a callback to occur immediately BEFORE each opcode is executed
///
/// opaque state pointer
/// null to clear
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_settracecallback(IntPtr core, TraceCallback callback);
///
/// type of the scanline callback
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ScanlineCallback();
///
/// set a callback to occur when ly reaches a particular scanline (so at the beginning of the scanline).
/// when the LCD is active, typically 145 will be the first callback after the beginning of frame advance,
/// and 144 will be the last callback right before frame advance returns
///
/// opaque state pointer
/// null to clear
/// 0-153 inclusive
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setscanlinecallback(IntPtr core, ScanlineCallback callback, int sl);
///
/// type of the RTC callback
///
/// what time is it, unixy
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint RTCCallback();
///
/// sets RTC callback. probably mandatory.
///
/// opaque state pointer
/// the callback
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setrtccallback(IntPtr core, RTCCallback callback);
///
/// Returns true if the currently loaded ROM image is treated as having CGB support.
///
/// opaque state pointer
///
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gambatte_iscgb(IntPtr core);
///
/// Returns true if a ROM image is loaded.
///
/// opaque state pointer
///
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gambatte_isloaded(IntPtr core);
///
/// Get persistant cart memory.
///
/// opaque state pointer
/// byte buffer to write into. gambatte_savesavedatalength() bytes will be written
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_savesavedata(IntPtr core, byte[] dest);
///
/// restore persistant cart memory.
///
/// opaque state pointer
/// byte buffer to read from. gambatte_savesavedatalength() bytes will be read
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_loadsavedata(IntPtr core, byte[] data);
///
/// get the size of the persistant cart memory block. this value DEPENDS ON THE PARTICULAR CART LOADED
///
/// opaque state pointer
/// length in bytes. 0 means no internal persistant cart memory
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_savesavedatalength(IntPtr core);
///
/// new savestate method
///
///
///
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_newstatelen(IntPtr core);
///
/// new savestate method
///
///
///
///
///
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gambatte_newstatesave(IntPtr core, byte[] data, int len);
///
/// new savestate method
///
///
///
///
///
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gambatte_newstateload(IntPtr core, byte[] data, int len);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DataFunction(IntPtr data, int length, string name);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SectionFunction(string name);
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_newstatesave_ex(IntPtr core, DataFunction Save, SectionFunction EnterSection, SectionFunction ExitSection);
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_newstateload_ex(IntPtr core, DataFunction Load, SectionFunction EnterSection, SectionFunction ExitSection);
///
/// ROM header title of currently loaded ROM image.
///
/// opaque state pointer
///
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern string gambatte_romtitle(IntPtr core);
///
/// memory areas that gambatte_getmemoryarea() can return
///
public enum MemoryAreas : int
{
vram = 0,
rom = 1,
wram = 2,
cartram = 3,
oam = 4,
hram = 5,
// these last two aren't returning native memory area data, but instead converted RGB32 colors
bgpal = 6,
sppal = 7
}
///
/// get pointer to internal memory areas, for debugging purposes
/// so long as you don't write to it, you should be completely sync-safe
///
/// opaque state pointer
/// which memory area to access
/// pointer to the start of the area
/// valid length of the area, in bytes
/// success
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gambatte_getmemoryarea(IntPtr core, MemoryAreas which, ref IntPtr data, ref int length);
///
/// read a single byte from the cpu bus. this includes all ram, rom, mmio, etc, as it is visible to the cpu (including mappers).
/// while there is no cycle cost to these reads, there may be other side effects! use at your own risk.
///
/// opaque state pointer
/// system bus address
/// byte read
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte gambatte_cpuread(IntPtr core, ushort addr);
///
/// write a single byte to the cpu bus. while there is no cycle cost to these writes, there can be quite a few side effects.
/// use at your own risk.
///
/// opaque state pointe
/// system bus address
/// byte to write
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_cpuwrite(IntPtr core, ushort addr, byte val);
///
/// link cable stuff; never touch for normal operation
///
/// opaque state pointe
/// todo
/// todo
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_linkstatus(IntPtr core, int which);
///
/// get reg and flag values
///
/// opaque state pointer
/// length of at least 10, please
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_getregs(IntPtr core, int[] dest);
public enum RegIndicies : int
{
PC, SP, A, B, C, D, E, F, H, L
}
}
}