BizHawk/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs

299 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
public static class LibGPGX
{
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_video(ref int w, ref int h, ref int pitch, ref IntPtr buffer);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_audio(ref int n, ref IntPtr buffer);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int load_archive_cb(string filename, IntPtr buffer, int maxsize);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_advance();
public enum Region : int
{
Autodetect = 0,
USA = 1,
Europe = 2,
Japan_NTSC = 3,
Japan_PAL = 4
}
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gpgx_init(string feromextension, load_archive_cb feload_archive_cb, bool sixbutton, INPUT_SYSTEM system_a, INPUT_SYSTEM system_b, Region region);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_fps(ref int num, ref int den);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gpgx_state_max_size();
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gpgx_state_size(byte[] dest, int size);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gpgx_state_save(byte[] dest, int size);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gpgx_state_load(byte[] src, int size);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gpgx_get_control([Out]InputData dest, int bytes);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool gpgx_put_control([In]InputData src, int bytes);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_sram(ref IntPtr area, ref int size);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_clear_sram();
public const int MIN_MEM_DOMAIN = 0;
public const int MAX_MEM_DOMAIN = 13;
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
// apparently, if you use built in string marshalling, the interop will assume that
// the unmanaged char pointer was allocated in hglobal and try to free it that way
public static extern IntPtr gpgx_get_memdom(int which, ref IntPtr area, ref int size);
// call this before reading sram returned by gpgx_get_sram()
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_sram_prepread();
// call this after writing sram returned by gpgx_get_sram()
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_sram_commitwrite();
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_reset(bool hard);
public const int MAX_DEVICES = 8;
public enum INPUT_SYSTEM : byte
{
SYSTEM_NONE = 0, // unconnected port
SYSTEM_MD_GAMEPAD = 1, // single 3-buttons or 6-buttons Control Pad
SYSTEM_MOUSE = 2, // Sega Mouse
SYSTEM_MENACER = 3, // Sega Menacer -- port B only
SYSTEM_JUSTIFIER = 4, // Konami Justifiers -- port B only
SYSTEM_XE_A1P = 5, // XE-A1P analog controller -- port A only
SYSTEM_ACTIVATOR = 6, // Sega Activator
SYSTEM_MS_GAMEPAD = 7, // single 2-buttons Control Pad -- Master System
SYSTEM_LIGHTPHASER = 8, // Sega Light Phaser -- Master System
SYSTEM_PADDLE = 9, // Sega Paddle Control -- Master System
SYSTEM_SPORTSPAD = 10, // Sega Sports Pad -- Master System
SYSTEM_TEAMPLAYER = 11, // Multi Tap -- Sega TeamPlayer
SYSTEM_WAYPLAY = 12, // Multi Tap -- EA 4-Way Play -- use both ports
};
public enum INPUT_DEVICE : byte
{
DEVICE_NONE = 0xff, // unconnected device = fixed ID for Team Player)
DEVICE_PAD3B = 0x00, // 3-buttons Control Pad = fixed ID for Team Player)
DEVICE_PAD6B = 0x01, // 6-buttons Control Pad = fixed ID for Team Player)
DEVICE_PAD2B = 0x02, // 2-buttons Control Pad
DEVICE_MOUSE = 0x03, // Sega Mouse
DEVICE_LIGHTGUN = 0x04, // Sega Light Phaser, Menacer or Konami Justifiers
DEVICE_PADDLE = 0x05, // Sega Paddle Control
DEVICE_SPORTSPAD = 0x06,// Sega Sports Pad
DEVICE_PICO = 0x07, // PICO tablet
DEVICE_TEREBI = 0x08, // Terebi Oekaki tablet
DEVICE_XE_A1P = 0x09, // XE-A1P analog controller
DEVICE_ACTIVATOR = 0x0a,// Activator
};
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void input_cb();
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_input_callback(input_cb cb);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void mem_cb(uint addr);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_mem_callback(mem_cb read, mem_cb write, mem_cb exec);
/// <summary>
/// not every flag is valid for every device!
/// </summary>
[Flags]
public enum INPUT_KEYS : ushort
{
/* Default Input bitmasks */
INPUT_MODE = 0x0800,
INPUT_X = 0x0400,
INPUT_Y = 0x0200,
INPUT_Z = 0x0100,
INPUT_START = 0x0080,
INPUT_A = 0x0040,
INPUT_C = 0x0020,
INPUT_B = 0x0010,
INPUT_RIGHT = 0x0008,
INPUT_LEFT = 0x0004,
INPUT_DOWN = 0x0002,
INPUT_UP = 0x0001,
/* Master System specific bitmasks */
INPUT_BUTTON2 = 0x0020,
INPUT_BUTTON1 = 0x0010,
/* Mega Mouse specific bitmask */
INPUT_MOUSE_START = 0x0080,
INPUT_MOUSE_CENTER = 0x0040,
INPUT_MOUSE_RIGHT = 0x0020,
INPUT_MOUSE_LEFT = 0x0010,
/* Pico hardware specific bitmask */
INPUT_PICO_PEN = 0x0080,
INPUT_PICO_RED = 0x0010,
/* XE-1AP specific bitmask */
INPUT_XE_E1 = 0x0800,
INPUT_XE_E2 = 0x0400,
INPUT_XE_START = 0x0200,
INPUT_XE_SELECT = 0x0100,
INPUT_XE_A = 0x0080,
INPUT_XE_B = 0x0040,
INPUT_XE_C = 0x0020,
INPUT_XE_D = 0x0010,
/* Activator specific bitmasks */
INPUT_ACTIVATOR_8U = 0x8000,
INPUT_ACTIVATOR_8L = 0x4000,
INPUT_ACTIVATOR_7U = 0x2000,
INPUT_ACTIVATOR_7L = 0x1000,
INPUT_ACTIVATOR_6U = 0x0800,
INPUT_ACTIVATOR_6L = 0x0400,
INPUT_ACTIVATOR_5U = 0x0200,
INPUT_ACTIVATOR_5L = 0x0100,
INPUT_ACTIVATOR_4U = 0x0080,
INPUT_ACTIVATOR_4L = 0x0040,
INPUT_ACTIVATOR_3U = 0x0020,
INPUT_ACTIVATOR_3L = 0x0010,
INPUT_ACTIVATOR_2U = 0x0008,
INPUT_ACTIVATOR_2L = 0x0004,
INPUT_ACTIVATOR_1U = 0x0002,
INPUT_ACTIVATOR_1L = 0x0001,
/* Menacer */
INPUT_MENACER_TRIGGER = 0x0040,
INPUT_MENACER_START = 0x0080,
};
[StructLayout(LayoutKind.Sequential)]
public class InputData
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public readonly INPUT_SYSTEM[] system = new INPUT_SYSTEM[2];
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DEVICES)]
public readonly INPUT_DEVICE[] dev = new INPUT_DEVICE[MAX_DEVICES];
/// <summary>
/// digital inputs
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DEVICES)]
public readonly INPUT_KEYS[] pad = new INPUT_KEYS[MAX_DEVICES];
/// <summary>
/// analog (x/y)
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DEVICES * 2)]
public readonly short[] analog = new short[MAX_DEVICES * 2];
/// <summary>
/// gun horizontal offset
/// </summary>
public int x_offset;
/// <summary>
/// gun vertical offset
/// </summary>
public int y_offset;
public void ClearAllBools()
{
for (int i = 0; i < pad.Length; i++)
pad[i] = 0;
}
}
public const int CD_MAX_TRACKS = 100;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void cd_read_cb(int lba, IntPtr dest, bool audio);
[StructLayout(LayoutKind.Sequential)]
public struct CDTrack
{
public int start;
public int end;
}
[StructLayout(LayoutKind.Sequential)]
public class CDData
{
public int end;
public int last;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CD_MAX_TRACKS)]
public readonly CDTrack[] tracks = new CDTrack[CD_MAX_TRACKS];
public cd_read_cb readcallback;
}
[StructLayout(LayoutKind.Sequential)]
public struct VDPNameTable
{
public int Width; // in cells
public int Height; // in cells
public int Baseaddr;
}
[StructLayout(LayoutKind.Sequential)]
public class VDPView
{
public IntPtr VRAM;
public IntPtr PatternCache;
public IntPtr ColorCache;
public VDPNameTable NTA;
public VDPNameTable NTB;
public VDPNameTable NTW;
}
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_vdp_view([Out] VDPView view);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_poke_vram(int addr, byte value);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_flush_vram();
[StructLayout(LayoutKind.Sequential)]
public struct RegisterInfo
{
public int Value;
public IntPtr Name;
}
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gpgx_getmaxnumregs();
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gpgx_getregs([Out] RegisterInfo[] regs);
[Flags]
public enum DrawMask : int
{
BGA = 1,
BGB = 2,
BGW = 4
}
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_draw_mask(DrawMask mask);
}
}