299 lines
10 KiB
C#
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);
|
|
}
|
|
}
|