using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.WonderSwan { public static class BizSwan { const CallingConvention cc = CallingConvention.Cdecl; const string dd = "bizswan.dll"; /// /// create new instance /// /// [DllImport(dd, CallingConvention = cc)] public static extern IntPtr bizswan_new(); /// /// delete instance, freeing all associated memory /// /// [DllImport(dd, CallingConvention = cc)] public static extern void bizswan_delete(IntPtr core); /// /// hard reset /// /// [DllImport(dd, CallingConvention = cc)] public static extern void bizswan_reset(IntPtr core); /// /// frame advance /// /// /// input to use on this frame /// true to skip all video rendering /// uint32 video output buffer /// int16 sound output buffer /// [In] max hold size of soundbuff [Out] number of samples actually deposited /// (out) true if the screen is rotated left 90 /// true if lagged [DllImport(dd, CallingConvention = cc)] public static extern bool bizswan_advance(IntPtr core, Buttons buttons, bool novideo, int[] surface, short[] soundbuff, ref int soundbuffsize, ref bool IsRotated); /// /// load rom /// /// /// /// /// /// (out) true if screen is rotated left 90 /// [DllImport(dd, CallingConvention = cc)] public static extern bool bizswan_load(IntPtr core, byte[] data, int length, [In] ref SyncSettings settings, ref bool IsRotated); /// /// get size of saveram /// /// /// [DllImport(dd, CallingConvention = cc)] public static extern int bizswan_saveramsize(IntPtr core); /// /// load saveram into core /// /// /// /// should be same as bizswan_saveramsize() /// false if size mismatch [DllImport(dd, CallingConvention = cc)] public static extern bool bizswan_saveramload(IntPtr core, byte[] data, int size); /// /// save saveram from core /// /// /// /// should be same as bizswan_saveramsize() /// false if size mismatch [DllImport(dd, CallingConvention = cc)] public static extern bool bizswan_saveramsave(IntPtr core, byte[] data, int maxsize); /// /// bad function /// /// /// pass EXACTLY the same syncsettings you originally passed on core load, else DRAGONS [DllImport(dd, CallingConvention = cc)] public static extern void bizswan_saveramclearhacky(IntPtr core, [In] ref SyncSettings settings); /// /// put non-sync settings, can be done at any time /// /// /// [DllImport(dd, CallingConvention = cc)] public static extern void bizswan_putsettings(IntPtr core, [In] ref Settings settings); /// /// get a memory area /// /// /// start at 0, increment until return is false /// /// /// /// [DllImport(dd, CallingConvention = cc)] public static extern bool bizswan_getmemoryarea(IntPtr core, int index, out IntPtr name, out int size, out IntPtr data); [DllImport(dd, CallingConvention = cc)] public static extern int bizswan_binstatesize(IntPtr core); [DllImport(dd, CallingConvention = cc)] public static extern bool bizswan_binstatesave(IntPtr core, byte[] data, int length); [DllImport(dd, CallingConvention = cc)] public static extern bool bizswan_binstateload(IntPtr core, byte[] data, int length); [DllImport(dd, CallingConvention = cc)] public static extern void bizswan_txtstatesave(IntPtr core, [In]ref TextStateFPtrs ff); [DllImport(dd, CallingConvention = cc)] public static extern void bizswan_txtstateload(IntPtr core, [In]ref TextStateFPtrs ff); /// /// return a CPU register /// /// /// /// [DllImport(dd, CallingConvention = cc)] public static extern uint bizswan_getnecreg(IntPtr core, NecRegs which); public const NecRegs NecRegsMin = NecRegs.PC; public const NecRegs NecRegsMax = NecRegs.DS0; public enum NecRegs : int { PC = 1, AW = 2, CW = 3, DW = 4, BW = 5, SP = 6, BP = 7, IX = 8, IY = 9, FLAGS = 10, DS1 = 11, PS = 12, SS = 13, DS0 = 14 }; [Flags] public enum Buttons : uint { X1 = 0x00000001, X2 = 0x00000002, X3 = 0x00000004, X4 = 0x00000008, Y1 = 0x00000010, Y2 = 0x00000020, Y3 = 0x00000040, Y4 = 0x00000080, Start = 0x00000100, A = 0x00000200, B = 0x00000400, R_X1 = 0x00010000, R_X2 = 0x00020000, R_X3 = 0x00040000, R_X4 = 0x00080000, R_Y1 = 0x00100000, R_Y2 = 0x00200000, R_Y3 = 0x00400000, R_Y4 = 0x00800000, R_Start = 0x01000000, R_A = 0x02000000, R_B = 0x04000000, Rotate = 0x80000000, } public enum Language : uint { Japanese = 0, English = 1 } public enum Bloodtype : uint { A = 1, B = 2, O = 3, AB = 4 } public enum Gender : uint { Male = 1, Female = 2 } [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct SyncSettings { public ulong initialtime; // inital time in unix format; only used when userealtime = false public uint byear; public uint bmonth; public uint bday; [MarshalAs(UnmanagedType.Bool)] public bool color; // true for color system [MarshalAs(UnmanagedType.Bool)] public bool userealtime; // true for use real real RTC instead of emulation pegged time public Language language; public Gender sex; public Bloodtype blood; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] name; public void SetName(string newname) { byte[] data = Encoding.ASCII.GetBytes(newname); name = new byte[17]; Buffer.BlockCopy(data, 0, name, 0, Math.Min(data.Length, name.Length)); } } [Flags] public enum LayerFlags : uint { BG = 1, FG = 2, Sprite = 4 } [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct Settings { public LayerFlags LayerMask; // 1 = show } } }