diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index e00c027608..25a58fb886 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -877,10 +877,7 @@ <DependentUpon>GPGX.cs</DependentUpon> </Compile> <Compile Include="Consoles\Sega\gpgx32\GPGXControlConverter.cs" /> - <Compile Include="Consoles\Sega\gpgx32\GPGXControlConverterDynamic.cs" /> - <Compile Include="Consoles\Sega\gpgx32\GPGXDynamic.cs" /> <Compile Include="Consoles\Sega\gpgx32\LibGPGX.cs" /> - <Compile Include="Consoles\Sega\gpgx32\LibGPGXDynamic.cs" /> <Compile Include="Consoles\Sega\gpgx\GenDbgHlp.cs" /> <Compile Include="Consoles\Sega\gpgx\GPGX.cs" /> <Compile Include="Consoles\Sega\gpgx\GPGX.ICodeDataLogger.cs"> diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXControlConverterDynamic.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXControlConverterDynamic.cs deleted file mode 100644 index f1827c0992..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXControlConverterDynamic.cs +++ /dev/null @@ -1,264 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using BizHawk.Common; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32 -{ - public class GPGXControlConverterDynamic - { - // this isn't all done - - struct CName - { - public string Name; - public LibGPGXDynamic.INPUT_KEYS Key; - public CName(string Name, LibGPGXDynamic.INPUT_KEYS Key) - { - this.Name = Name; - this.Key = Key; - } - } - - static CName[] Genesis3 = - { - new CName("Up", LibGPGXDynamic.INPUT_KEYS.INPUT_UP), - new CName("Down", LibGPGXDynamic.INPUT_KEYS.INPUT_DOWN), - new CName("Left", LibGPGXDynamic.INPUT_KEYS.INPUT_LEFT), - new CName("Right", LibGPGXDynamic.INPUT_KEYS.INPUT_RIGHT), - new CName("A", LibGPGXDynamic.INPUT_KEYS.INPUT_A), - new CName("B", LibGPGXDynamic.INPUT_KEYS.INPUT_B), - new CName("C", LibGPGXDynamic.INPUT_KEYS.INPUT_C), - new CName("Start", LibGPGXDynamic.INPUT_KEYS.INPUT_START), - }; - - static CName[] Genesis6 = - { - new CName("Up", LibGPGXDynamic.INPUT_KEYS.INPUT_UP), - new CName("Down", LibGPGXDynamic.INPUT_KEYS.INPUT_DOWN), - new CName("Left", LibGPGXDynamic.INPUT_KEYS.INPUT_LEFT), - new CName("Right", LibGPGXDynamic.INPUT_KEYS.INPUT_RIGHT), - new CName("A", LibGPGXDynamic.INPUT_KEYS.INPUT_A), - new CName("B", LibGPGXDynamic.INPUT_KEYS.INPUT_B), - new CName("C", LibGPGXDynamic.INPUT_KEYS.INPUT_C), - new CName("Start", LibGPGXDynamic.INPUT_KEYS.INPUT_START), - new CName("X", LibGPGXDynamic.INPUT_KEYS.INPUT_X), - new CName("Y", LibGPGXDynamic.INPUT_KEYS.INPUT_Y), - new CName("Z", LibGPGXDynamic.INPUT_KEYS.INPUT_Z), - new CName("Mode", LibGPGXDynamic.INPUT_KEYS.INPUT_MODE), - }; - - static CName[] Mouse = - { - new CName("Mouse Left", LibGPGXDynamic.INPUT_KEYS.INPUT_MOUSE_LEFT), - new CName("Mouse Center", LibGPGXDynamic.INPUT_KEYS.INPUT_MOUSE_CENTER), - new CName("Mouse Right", LibGPGXDynamic.INPUT_KEYS.INPUT_MOUSE_RIGHT), - new CName("Mouse Start", LibGPGXDynamic.INPUT_KEYS.INPUT_MOUSE_START), - }; - - static CName[] Lightgun = - { - new CName("Lightgun Trigger", LibGPGXDynamic.INPUT_KEYS.INPUT_MENACER_TRIGGER), - new CName("Lightgun Start", LibGPGXDynamic.INPUT_KEYS.INPUT_MENACER_START), - }; - - static CName[] Activator = - { - new CName("1L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_1L), - new CName("1U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_1U), - new CName("2L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_2L), - new CName("2U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_2U), - new CName("3L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_3L), - new CName("3U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_3U), - new CName("4L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_4L), - new CName("4U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_4U), - new CName("5L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_5L), - new CName("5U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_5U), - new CName("6L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_6L), - new CName("6U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_6U), - new CName("7L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_7L), - new CName("7U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_7U), - new CName("8L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_8L), - new CName("8U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_8U), - }; - - static CName[] XEA1P = - { - new CName("XE A", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_A), - new CName("XE B", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_B), - new CName("XE C", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_C), - new CName("XE D", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_D), - new CName("XE Start", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_START), - new CName("XE Select", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_SELECT), - new CName("XE E1", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_E1), - new CName("XE E2", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_E2), - }; - - static ControllerDefinition.FloatRange MouseRange = new ControllerDefinition.FloatRange(-256, 0, 255); - // lightgun needs to be transformed to match the current screen resolution - static ControllerDefinition.FloatRange LightgunRange = new ControllerDefinition.FloatRange(0, 5000, 10000); - - static ControllerDefinition.FloatRange XEA1PRange = new ControllerDefinition.FloatRange(-128, 0, 127); - - LibGPGXDynamic.InputData target = null; - IController source = null; - - List<Action> Converts = new List<Action>(); - - public ControllerDefinition ControllerDef { get; private set; } - - void AddToController(int idx, int player, IEnumerable<CName> Buttons) - { - foreach (var Button in Buttons) - { - string Name = string.Format("P{0} {1}", player, Button.Name); - ControllerDef.BoolButtons.Add(Name); - var ButtonFlag = Button.Key; - Converts.Add(delegate() - { - if (source.IsPressed(Name)) - target.pad[idx] |= ButtonFlag; - }); - } - } - - void DoMouseAnalog(int idx, int player) - { - string NX = string.Format("P{0} Mouse X", player); - string NY = string.Format("P{0} Mouse Y", player); - ControllerDef.FloatControls.Add(NX); - ControllerDef.FloatControls.Add(NY); - ControllerDef.FloatRanges.Add(MouseRange); - ControllerDef.FloatRanges.Add(MouseRange); - Converts.Add(delegate() - { - target.analog[(2 * idx) + 0] = (short)source.GetFloat(NX); - target.analog[(2 * idx) + 1] = (short)source.GetFloat(NY); - }); - } - - void DoLightgunAnalog(int idx, int player) - { - string NX = string.Format("P{0} Lightgun X", player); - string NY = string.Format("P{0} Lightgun Y", player); - ControllerDef.FloatControls.Add(NX); - ControllerDef.FloatControls.Add(NY); - ControllerDef.FloatRanges.Add(LightgunRange); - ControllerDef.FloatRanges.Add(LightgunRange); - Converts.Add(delegate() - { - target.analog[(2 * idx) + 0] = (short)(source.GetFloat(NX) / 10000.0f * (ScreenWidth - 1)); - target.analog[(2 * idx) + 1] = (short)(source.GetFloat(NY) / 10000.0f * (ScreenHeight - 1)); - }); - } - - void DoXEA1PAnalog(int idx, int player) - { - string NX = string.Format("P{0} Stick X", player); - string NY = string.Format("P{0} Stick Y", player); - string NZ = string.Format("P{0} Stick Z", player); - ControllerDef.FloatControls.Add(NX); - ControllerDef.FloatControls.Add(NY); - ControllerDef.FloatControls.Add(NZ); - ControllerDef.FloatRanges.Add(XEA1PRange); - ControllerDef.FloatRanges.Add(XEA1PRange); - ControllerDef.FloatRanges.Add(XEA1PRange); - Converts.Add(delegate() - { - target.analog[(2 * idx) + 0] = (short)(source.GetFloat(NX)); - target.analog[(2 * idx) + 1] = (short)(source.GetFloat(NY)); - // +2 is correct in how gpgx internally does this - target.analog[(2 * idx) + 2] = (short)(source.GetFloat(NZ)); - }); - } - - public GPGXControlConverterDynamic(LibGPGXDynamic.InputData input) - { - Console.WriteLine("Genesis Controller report:"); - foreach (var e in input.system) - Console.WriteLine("S:{0}", e); - foreach (var e in input.dev) - Console.WriteLine("D:{0}", e); - - int player = 1; - - ControllerDef = new ControllerDefinition(); - - ControllerDef.BoolButtons.Add("Power"); - ControllerDef.BoolButtons.Add("Reset"); - - for (int i = 0; i < LibGPGXDynamic.MAX_DEVICES; i++) - { - switch (input.dev[i]) - { - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PAD3B: - AddToController(i, player, Genesis3); - player++; - break; - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PAD6B: - AddToController(i, player, Genesis6); - player++; - break; - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_MOUSE: - AddToController(i, player, Mouse); - DoMouseAnalog(i, player); - player++; - break; - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_NONE: - break; - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_LIGHTGUN: - // supports menacers and justifiers - AddToController(i, player, Lightgun); - DoLightgunAnalog(i, player); - player++; - break; - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PAD2B: - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PADDLE: - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_SPORTSPAD: - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_TEREBI: - throw new Exception("Master System only device? Something went wrong."); - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_ACTIVATOR: - AddToController(i, player, Activator); - player++; - break; - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_XE_A1P: - AddToController(i, player, XEA1P); - DoXEA1PAnalog(i, player); - player++; - break; - case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PICO: - // PICO isn't finished on the unmanaged side either - throw new Exception("Sega PICO not implemented yet!"); - default: - throw new Exception("Unknown Genesis control device! Something went wrong."); - } - } - - ControllerDef.Name = "GPGX Genesis Controller"; - } - - public void Convert(IController source, LibGPGXDynamic.InputData target) - { - this.source = source; - this.target = target; - target.ClearAllBools(); - foreach (var f in Converts) - f(); - this.source = null; - this.target = null; - } - - /// <summary> - /// must be set for proper lightgun operation - /// </summary> - public int ScreenWidth { get; set; } - /// <summary> - /// must be set for proper lightgun operation - /// </summary> - public int ScreenHeight { get; set; } - - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXDynamic.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXDynamic.cs deleted file mode 100644 index ad89e4d6f2..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXDynamic.cs +++ /dev/null @@ -1,900 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using BizHawk.Common.BufferExtensions; -using BizHawk.Emulation.Common; -using BizHawk.Common; - -using System.Runtime.InteropServices; - -using System.IO; - -using System.ComponentModel; - - -namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32 -{ - [CoreAttributes( - "Genplus-gx", - "", - isPorted: true, - isReleased: true, - portedVersion: "r874", - portedUrl: "https://code.google.com/p/genplus-gx/", - singleInstance: false - )] - public class GPGXDynamic : IEmulator, ISyncSoundProvider, IVideoProvider, ISaveRam, IStatable, - IInputPollable, IDebuggable, ISettable<GPGXDynamic.GPGXSettings, GPGXDynamic.GPGXSyncSettings>, IDriveLight - { - DiscSystem.Disc CD; - byte[] romfile; - bool drivelight; - - bool disposed = false; - - LibGPGXDynamic gpgx; - ElfRunner elf; - - LibGPGXDynamic.load_archive_cb LoadCallback = null; - LibGPGXDynamic.input_cb InputCallback = null; - - LibGPGXDynamic.InputData input = new LibGPGXDynamic.InputData(); - - public enum ControlType - { - None, - OnePlayer, - Normal, - Xea1p, - Activator, - Teamplayer, - Wayplay, - Mouse - }; - - //[CoreConstructor("GEN")] - public GPGXDynamic(CoreComm comm, byte[] file, object Settings, object SyncSettings) - : this(comm, file, null, Settings, SyncSettings) - { - } - - public GPGXDynamic(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings) - { - ServiceProvider = new BasicServiceProvider(this); - (ServiceProvider as BasicServiceProvider).Register<ITraceable>(_tracer); - // this can influence some things internally - string romextension = "GEN"; - - // three or six button? - // http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds - - //hack, don't use - //romfile = File.ReadAllBytes(@"D:\encodes\bizhawksrc\output\SANIC CD\PierSolar (E).bin"); - if (rom != null && rom.Length > 16 * 1024 * 1024) - { - throw new InvalidOperationException("ROM too big! Did you try to load a CD as a ROM?"); - } - - elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf")); - try - { - gpgx = new LibGPGXDynamic(); - elf.PopulateInterface(gpgx); - - _SyncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings(); - - CoreComm = comm; - - LoadCallback = new LibGPGXDynamic.load_archive_cb(load_archive); - - this.romfile = rom; - this.CD = CD; - - LibGPGXDynamic.INPUT_SYSTEM system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_NONE; - LibGPGXDynamic.INPUT_SYSTEM system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_NONE; - - switch (this._SyncSettings.ControlType) - { - case ControlType.None: - default: - break; - case ControlType.Activator: - system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_ACTIVATOR; - system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_ACTIVATOR; - break; - case ControlType.Normal: - system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD; - system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD; - break; - case ControlType.OnePlayer: - system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD; - break; - case ControlType.Xea1p: - system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_XE_A1P; - break; - case ControlType.Teamplayer: - system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_TEAMPLAYER; - system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_TEAMPLAYER; - break; - case ControlType.Wayplay: - system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_WAYPLAY; - system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_WAYPLAY; - break; - case ControlType.Mouse: - system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD; - // seems like mouse in port 1 would be supported, but not both at the same time - system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MOUSE; - break; - } - - - if (!gpgx.gpgx_init(romextension, LoadCallback, this._SyncSettings.UseSixButton, system_a, system_b, this._SyncSettings.Region)) - throw new Exception("gpgx_init() failed"); - - { - int fpsnum = 60; - int fpsden = 1; - gpgx.gpgx_get_fps(ref fpsnum, ref fpsden); - CoreComm.VsyncNum = fpsnum; - CoreComm.VsyncDen = fpsden; - DisplayType = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL; - } - - // compute state size - { - byte[] tmp = new byte[gpgx.gpgx_state_max_size()]; - int size = gpgx.gpgx_state_size(tmp, tmp.Length); - if (size <= 0) - throw new Exception("Couldn't Determine GPGX internal state size!"); - savebuff = new byte[size]; - savebuff2 = new byte[savebuff.Length + 13]; - Console.WriteLine("GPGX Internal State Size: {0}", size); - } - - SetControllerDefinition(); - - // pull the default video size from the core - update_video_initial(); - - SetMemoryDomains(); - - InputCallback = new LibGPGXDynamic.input_cb(input_callback); - gpgx.gpgx_set_input_callback(InputCallback); - - if (CD != null) - DriveLightEnabled = true; - - PutSettings((GPGXSettings)Settings ?? new GPGXSettings()); - - InitMemCallbacks(); - KillMemCallbacks(); - } - catch - { - Dispose(); - throw; - } - } - - public IEmulatorServiceProvider ServiceProvider { get; private set; } - - public bool DriveLightEnabled { get; private set; } - public bool DriveLightOn { get; private set; } - - /// <summary> - /// core callback for file loading - /// </summary> - /// <param name="filename">string identifying file to be loaded</param> - /// <param name="buffer">buffer to load file to</param> - /// <param name="maxsize">maximum length buffer can hold</param> - /// <returns>actual size loaded, or 0 on failure</returns> - int load_archive(string filename, IntPtr buffer, int maxsize) - { - byte[] srcdata = null; - - if (buffer == IntPtr.Zero) - { - Console.WriteLine("Couldn't satisfy firmware request {0} because buffer == NULL", filename); - return 0; - } - - if (filename == "PRIMARY_ROM") - { - if (romfile == null) - { - Console.WriteLine("Couldn't satisfy firmware request PRIMARY_ROM because none was provided."); - return 0; - } - srcdata = romfile; - } - else if (filename == "PRIMARY_CD" || filename == "SECONDARY_CD") - { - if (filename == "PRIMARY_CD" && romfile != null) - { - Console.WriteLine("Declined to satisfy firmware request PRIMARY_CD because PRIMARY_ROM was provided."); - return 0; - } - else - { - if (CD == null) - { - Console.WriteLine("Couldn't satisfy firmware request {0} because none was provided.", filename); - return 0; - } - srcdata = GetCDData(); - if (srcdata.Length != maxsize) - { - Console.WriteLine("Couldn't satisfy firmware request {0} because of struct size.", filename); - return 0; - } - } - } - else - { - // use fromtend firmware interface - - string firmwareID = null; - switch (filename) - { - case "CD_BIOS_EU": firmwareID = "CD_BIOS_EU"; break; - case "CD_BIOS_JP": firmwareID = "CD_BIOS_JP"; break; - case "CD_BIOS_US": firmwareID = "CD_BIOS_US"; break; - default: - break; - } - if (firmwareID != null) - { - // this path will be the most common PEBKAC error, so be a bit more vocal about the problem - srcdata = CoreComm.CoreFileProvider.GetFirmware("GEN", firmwareID, false, "GPGX firmwares are usually required."); - if (srcdata == null) - { - Console.WriteLine("Frontend couldn't satisfy firmware request GEN:{0}", firmwareID); - return 0; - } - } - else - { - Console.WriteLine("Unrecognized firmware request {0}", filename); - return 0; - } - } - - if (srcdata != null) - { - if (srcdata.Length > maxsize) - { - Console.WriteLine("Couldn't satisfy firmware request {0} because {1} > {2}", filename, srcdata.Length, maxsize); - return 0; - } - else - { - Marshal.Copy(srcdata, 0, buffer, srcdata.Length); - Console.WriteLine("Firmware request {0} satisfied at size {1}", filename, srcdata.Length); - return srcdata.Length; - } - } - else - { - throw new Exception(); - //Console.WriteLine("Couldn't satisfy firmware request {0} for unknown reasons", filename); - //return 0; - } - - } - - void CDRead(int lba, IntPtr dest, bool audio) - { - if (audio) - { - byte[] data = new byte[2352]; - if (lba < CD.LBACount) - { - CD.ReadLBA_2352(lba, data, 0); - } - else - { - // audio seems to read slightly past the end of disks; probably innoculous - // just send back 0s. - // Console.WriteLine("!!{0} >= {1}", lba, CD.LBACount); - } - Marshal.Copy(data, 0, dest, 2352); - } - else - { - byte[] data = new byte[2048]; - CD.ReadLBA_2048(lba, data, 0); - Marshal.Copy(data, 0, dest, 2048); - drivelight = true; - } - } - - LibGPGXDynamic.cd_read_cb cd_callback_handle; - - unsafe byte[] GetCDData() - { - LibGPGXDynamic.CDData ret = new LibGPGXDynamic.CDData(); - int size = Marshal.SizeOf(ret); - - ret.readcallback = cd_callback_handle = new LibGPGXDynamic.cd_read_cb(CDRead); - - var ses = CD.Structure.Sessions[0]; - int ntrack = ses.Tracks.Count; - - // bet you a dollar this is all wrong - for (int i = 0; i < LibGPGXDynamic.CD_MAX_TRACKS; i++) - { - if (i < ntrack) - { - ret.tracks[i].start = ses.Tracks[i].Indexes[1].aba - 150; - ret.tracks[i].end = ses.Tracks[i].LengthInSectors + ret.tracks[i].start; - if (i == ntrack - 1) - { - ret.end = ret.tracks[i].end; - ret.last = ntrack; - } - } - else - { - ret.tracks[i].start = 0; - ret.tracks[i].end = 0; - } - } - - byte[] retdata = new byte[size]; - - fixed (byte* p = &retdata[0]) - { - Marshal.StructureToPtr(ret, (IntPtr)p, false); - } - return retdata; - } - - - #region controller - - /// <summary> - /// size of native input struct - /// </summary> - int inputsize; - - GPGXControlConverterDynamic ControlConverter; - - public ControllerDefinition ControllerDefinition { get; private set; } - public IController Controller { get; set; } - - void SetControllerDefinition() - { - inputsize = Marshal.SizeOf(typeof(LibGPGXDynamic.InputData)); - if (!gpgx.gpgx_get_control(input, inputsize)) - throw new Exception("gpgx_get_control() failed"); - - ControlConverter = new GPGXControlConverterDynamic(input); - ControllerDefinition = ControlConverter.ControllerDef; - } - - public LibGPGXDynamic.INPUT_DEVICE[] GetDevices() - { - return (LibGPGXDynamic.INPUT_DEVICE[])input.dev.Clone(); - } - - // core callback for input - void input_callback() - { - InputCallbacks.Call(); - IsLagFrame = false; - } - - private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); - - public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } } - - private readonly TraceBuffer _tracer = new TraceBuffer(); - - #endregion - - // TODO: use render and rendersound - public void FrameAdvance(bool render, bool rendersound = true) - { - if (Controller["Reset"]) - gpgx.gpgx_reset(false); - if (Controller["Power"]) - gpgx.gpgx_reset(true); - - // do we really have to get each time? nothing has changed - if (!gpgx.gpgx_get_control(input, inputsize)) - throw new Exception("gpgx_get_control() failed!"); - - ControlConverter.ScreenWidth = vwidth; - ControlConverter.ScreenHeight = vheight; - ControlConverter.Convert(Controller, input); - - if (!gpgx.gpgx_put_control(input, inputsize)) - throw new Exception("gpgx_put_control() failed!"); - - IsLagFrame = true; - Frame++; - drivelight = false; - - gpgx.gpgx_advance(); - update_video(); - update_audio(); - - if (IsLagFrame) - LagCount++; - - if (CD != null) - DriveLightOn = drivelight; - } - - public int Frame { get; private set; } - public int LagCount { get; set; } - public bool IsLagFrame { get; private set; } - - public string SystemId { get { return "GEN"; } } - public bool DeterministicEmulation { get { return true; } } - public string BoardName { get { return null; } } - - public CoreComm CoreComm { get; private set; } - - #region saveram - - byte[] DisposedSaveRam = null; - - public byte[] CloneSaveRam() - { - if (disposed) - { - if (DisposedSaveRam != null) - { - return (byte[])DisposedSaveRam.Clone(); - } - else - { - return new byte[0]; - } - } - else - { - int size = 0; - IntPtr area = IntPtr.Zero; - gpgx.gpgx_get_sram(ref area, ref size); - if (size <= 0 || area == IntPtr.Zero) - return new byte[0]; - gpgx.gpgx_sram_prepread(); - - byte[] ret = new byte[size]; - Marshal.Copy(area, ret, 0, size); - return ret; - } - } - - public void StoreSaveRam(byte[] data) - { - if (disposed) - { - throw new ObjectDisposedException(typeof(GPGX).ToString()); - } - else - { - int size = 0; - IntPtr area = IntPtr.Zero; - gpgx.gpgx_get_sram(ref area, ref size); - if (size <= 0 || area == IntPtr.Zero) - return; - if (size != data.Length) - throw new Exception("Unexpected saveram size"); - - Marshal.Copy(data, 0, area, size); - gpgx.gpgx_sram_commitwrite(); - } - } - - public bool SaveRamModified - { - get - { - if (disposed) - { - return DisposedSaveRam != null; - } - else - { - int size = 0; - IntPtr area = IntPtr.Zero; - gpgx.gpgx_get_sram(ref area, ref size); - return size > 0 && area != IntPtr.Zero; - } - } - } - - #endregion - - public void ResetCounters() - { - Frame = 0; - IsLagFrame = false; - LagCount = 0; - } - - #region savestates - - private byte[] savebuff; - private byte[] savebuff2; - - public void SaveStateText(System.IO.TextWriter writer) - { - var temp = SaveStateBinary(); - temp.SaveAsHexFast(writer); - // write extra copy of stuff we don't use - writer.WriteLine("Frame {0}", Frame); - } - - public void LoadStateText(System.IO.TextReader reader) - { - string hex = reader.ReadLine(); - byte[] state = new byte[hex.Length / 2]; - state.ReadFromHexFast(hex); - LoadStateBinary(new System.IO.BinaryReader(new System.IO.MemoryStream(state))); - } - - public void SaveStateBinary(System.IO.BinaryWriter writer) - { - if (!gpgx.gpgx_state_save(savebuff, savebuff.Length)) - throw new Exception("gpgx_state_save() returned false"); - - writer.Write(savebuff.Length); - writer.Write(savebuff); - // other variables - writer.Write(Frame); - writer.Write(LagCount); - writer.Write(IsLagFrame); - } - - public void LoadStateBinary(System.IO.BinaryReader reader) - { - int newlen = reader.ReadInt32(); - if (newlen != savebuff.Length) - throw new Exception("Unexpected state size"); - reader.Read(savebuff, 0, savebuff.Length); - if (!gpgx.gpgx_state_load(savebuff, savebuff.Length)) - throw new Exception("gpgx_state_load() returned false"); - // other variables - Frame = reader.ReadInt32(); - LagCount = reader.ReadInt32(); - IsLagFrame = reader.ReadBoolean(); - update_video(); - } - - public byte[] SaveStateBinary() - { - var ms = new System.IO.MemoryStream(savebuff2, true); - var bw = new System.IO.BinaryWriter(ms); - SaveStateBinary(bw); - bw.Flush(); - ms.Close(); - return savebuff2; - } - - public bool BinarySaveStatesPreferred { get { return true; } } - - #endregion - - #region debugging tools - - private IMemoryDomains MemoryDomains; - - unsafe void SetMemoryDomains() - { - var mm = new List<MemoryDomain>(); - for (int i = LibGPGXDynamic.MIN_MEM_DOMAIN; i <= LibGPGXDynamic.MAX_MEM_DOMAIN; i++) - { - IntPtr area = IntPtr.Zero; - int size = 0; - IntPtr pname = gpgx.gpgx_get_memdom(i, ref area, ref size); - if (area == IntPtr.Zero || pname == IntPtr.Zero || size == 0) - continue; - string name = Marshal.PtrToStringAnsi(pname); - if (name == "VRAM") - { - // vram pokes need to go through hook which invalidates cached tiles - byte* p = (byte*)area; - mm.Add(new MemoryDomain(name, size, MemoryDomain.Endian.Unknown, - delegate(long addr) - { - if (addr < 0 || addr >= 65536) - throw new ArgumentOutOfRangeException(); - return p[addr ^ 1]; - }, - delegate(long addr, byte val) - { - if (addr < 0 || addr >= 65536) - throw new ArgumentOutOfRangeException(); - gpgx.gpgx_poke_vram(((int)addr) ^ 1, val); - }, - byteSize: 2)); - } - - else - { - var byteSize = name.Contains("Z80") ? 1 : 2; - mm.Add(MemoryDomain.FromIntPtrSwap16(name, size, MemoryDomain.Endian.Big, area, writable: true, byteSize: byteSize)); - } - } - MemoryDomains = new MemoryDomainList(mm); - (ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains); - } - - public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters() - { - LibGPGXDynamic.RegisterInfo[] regs = new LibGPGXDynamic.RegisterInfo[gpgx.gpgx_getmaxnumregs()]; - - int n = gpgx.gpgx_getregs(regs); - if (n > regs.Length) - throw new InvalidOperationException("A buffer overrun has occured!"); - var ret = new Dictionary<string, RegisterValue>(); - for (int i = 0; i < n; i++) - { - // el hacko - string name = Marshal.PtrToStringAnsi(regs[i].Name); - byte size = 32; - if (name.Contains("68K SR") || name.StartsWith("Z80")) - size = 16; - ret[Marshal.PtrToStringAnsi(regs[i].Name)] = - new RegisterValue { BitSize = size, Value = (ulong)regs[i].Value }; - } - return ret; - } - - public bool CanStep(StepType type) { return false; } - - [FeatureNotImplemented] - public void Step(StepType type) { throw new NotImplementedException(); } - - [FeatureNotImplemented] - public void SetCpuRegister(string register, int value) - { - throw new NotImplementedException(); - } - - public void UpdateVDPViewContext(LibGPGXDynamic.VDPView view) - { - gpgx.gpgx_get_vdp_view(view); - gpgx.gpgx_flush_vram(); // fully regenerate internal caches as needed - } - - private readonly MemoryCallbackSystem _memoryCallbacks = new MemoryCallbackSystem(); - public IMemoryCallbackSystem MemoryCallbacks { get { return _memoryCallbacks; } } - - LibGPGXDynamic.mem_cb ExecCallback; - LibGPGXDynamic.mem_cb ReadCallback; - LibGPGXDynamic.mem_cb WriteCallback; - - void InitMemCallbacks() - { - ExecCallback = new LibGPGXDynamic.mem_cb(a => MemoryCallbacks.CallExecutes(a)); - ReadCallback = new LibGPGXDynamic.mem_cb(a => MemoryCallbacks.CallReads(a)); - WriteCallback = new LibGPGXDynamic.mem_cb(a => MemoryCallbacks.CallWrites(a)); - _memoryCallbacks.ActiveChanged += RefreshMemCallbacks; - } - - void RefreshMemCallbacks() - { - gpgx.gpgx_set_mem_callback( - MemoryCallbacks.HasReads ? ReadCallback : null, - MemoryCallbacks.HasWrites ? WriteCallback : null, - MemoryCallbacks.HasExecutes ? ExecCallback : null); - } - - void KillMemCallbacks() - { - gpgx.gpgx_set_mem_callback(null, null, null); - } - - #endregion - - public void Dispose() - { - if (!disposed) - { - // if (SaveRamModified) - // DisposedSaveRam = CloneSaveRam(); - // KillMemCallbacks(); - if (CD != null) - { - CD.Dispose(); - } - if (elf != null) - { - elf.Dispose(); - elf = null; - gpgx = null; - } - - disposed = true; - } - } - - #region SoundProvider - - short[] samples = new short[4096]; - int nsamp = 0; - - public ISoundProvider SoundProvider { get { return null; } } - public ISyncSoundProvider SyncSoundProvider { get { return this; } } - public bool StartAsyncSound() { return false; } - public void EndAsyncSound() { } - - public void GetSamples(out short[] samples, out int nsamp) - { - nsamp = this.nsamp; - samples = this.samples; - this.nsamp = 0; - } - - public void DiscardSamples() - { - this.nsamp = 0; - } - - void update_audio() - { - IntPtr src = IntPtr.Zero; - gpgx.gpgx_get_audio(ref nsamp, ref src); - if (src != IntPtr.Zero) - { - Marshal.Copy(src, samples, 0, nsamp * 2); - } - } - - #endregion - - #region VideoProvider - - public DisplayType DisplayType { get; private set; } - - int[] vidbuff = new int[0]; - int vwidth; - int vheight; - public int[] GetVideoBuffer() { return vidbuff; } - public int VirtualWidth { get { return BufferWidth; } } // TODO - public int VirtualHeight { get { return BufferHeight; } } // TODO - public int BufferWidth { get { return vwidth; } } - public int BufferHeight { get { return vheight; } } - public int BackgroundColor { get { return unchecked((int)0xff000000); } } - - void update_video_initial() - { - // hack: you should call update_video() here, but that gives you 256x192 on frame 0 - // and we know that we only use GPGX to emulate genesis games that will always be 320x224 immediately afterwards - - // so instead, just assume a 320x224 size now; if that happens to be wrong, it'll be fixed soon enough. - - vwidth = 320; - vheight = 224; - vidbuff = new int[vwidth * vheight]; - for (int i = 0; i < vidbuff.Length; i++) - vidbuff[i] = unchecked((int)0xff000000); - } - - unsafe void update_video() - { - int pitch = 0; - IntPtr src = IntPtr.Zero; - - gpgx.gpgx_get_video(ref vwidth, ref vheight, ref pitch, ref src); - - if (vidbuff.Length < vwidth * vheight) - vidbuff = new int[vwidth * vheight]; - - int rinc = (pitch / 4) - vwidth; - fixed (int* pdst_ = &vidbuff[0]) - { - int* pdst = pdst_; - int* psrc = (int*)src; - - for (int j = 0; j < vheight; j++) - { - for (int i = 0; i < vwidth; i++) - *pdst++ = *psrc++;// | unchecked((int)0xff000000); - psrc += rinc; - } - } - } - - #endregion - - #region Settings - - GPGXSyncSettings _SyncSettings; - GPGXSettings _Settings; - - public GPGXSettings GetSettings() { return _Settings.Clone(); } - public GPGXSyncSettings GetSyncSettings() { return _SyncSettings.Clone(); } - public bool PutSettings(GPGXSettings o) - { - _Settings = o; - gpgx.gpgx_set_draw_mask(_Settings.GetDrawMask()); - return false; - } - public bool PutSyncSettings(GPGXSyncSettings o) - { - bool ret = GPGXSyncSettings.NeedsReboot(_SyncSettings, o); - _SyncSettings = o; - return ret; - } - - public class GPGXSettings - { - [DisplayName("Background Layer A")] - [Description("True to draw BG layer A")] - [DefaultValue(true)] - public bool DrawBGA { get; set; } - - [DisplayName("Background Layer B")] - [Description("True to draw BG layer B")] - [DefaultValue(true)] - public bool DrawBGB { get; set; } - - [DisplayName("Background Layer W")] - [Description("True to draw BG layer W")] - [DefaultValue(true)] - public bool DrawBGW { get; set; } - - public GPGXSettings() - { - SettingsUtil.SetDefaultValues(this); - } - - public GPGXSettings Clone() - { - return (GPGXSettings)MemberwiseClone(); - } - - public LibGPGXDynamic.DrawMask GetDrawMask() - { - LibGPGXDynamic.DrawMask ret = 0; - if (DrawBGA) ret |= LibGPGXDynamic.DrawMask.BGA; - if (DrawBGB) ret |= LibGPGXDynamic.DrawMask.BGB; - if (DrawBGW) ret |= LibGPGXDynamic.DrawMask.BGW; - return ret; - } - } - - public class GPGXSyncSettings - { - [DisplayName("Use Six Button Controllers")] - [Description("Controls the type of any attached normal controllers; six button controllers are used if true, otherwise three button controllers. Some games don't work correctly with six button controllers. Not relevant if other controller types are connected.")] - [DefaultValue(true)] - public bool UseSixButton { get; set; } - - [DisplayName("Control Type")] - [Description("Sets the type of controls that are plugged into the console. Some games will automatically load with a different control type.")] - [DefaultValue(ControlType.Normal)] - public ControlType ControlType { get; set; } - - [DisplayName("Autodetect Region")] - [Description("Sets the region of the emulated console. Many games can run on multiple regions and will behave differently on different ones. Some games may require a particular region.")] - [DefaultValue(LibGPGXDynamic.Region.Autodetect)] - public LibGPGXDynamic.Region Region { get; set; } - - public GPGXSyncSettings() - { - SettingsUtil.SetDefaultValues(this); - } - - public GPGXSyncSettings Clone() - { - return (GPGXSyncSettings)MemberwiseClone(); - } - - public static bool NeedsReboot(GPGXSyncSettings x, GPGXSyncSettings y) - { - return !DeepEquality.DeepEquals(x, y); - } - } - - #endregion - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/LibGPGXDynamic.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/LibGPGXDynamic.cs deleted file mode 100644 index f538c6f6aa..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/LibGPGXDynamic.cs +++ /dev/null @@ -1,323 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.InteropServices; - -namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32 -{ - public class LibGPGXDynamic - { - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_get_video_t(ref int w, ref int h, ref int pitch, ref IntPtr buffer); - public gpgx_get_video_t gpgx_get_video; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_get_audio_t(ref int n, ref IntPtr buffer); - public gpgx_get_audio_t gpgx_get_audio; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int load_archive_cb(string filename, IntPtr buffer, int maxsize); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_advance_t(); - public gpgx_advance_t gpgx_advance; - - public enum Region : int - { - Autodetect = 0, - USA = 1, - Europe = 2, - Japan_NTSC = 3, - Japan_PAL = 4 - } - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool gpgx_init_t(string feromextension, load_archive_cb feload_archive_cb, bool sixbutton, INPUT_SYSTEM system_a, INPUT_SYSTEM system_b, Region region); - public gpgx_init_t gpgx_init; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_get_fps_t(ref int num, ref int den); - public gpgx_get_fps_t gpgx_get_fps; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int gpgx_state_max_size_t(); - public gpgx_state_max_size_t gpgx_state_max_size; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int gpgx_state_size_t(byte[] dest, int size); - public gpgx_state_size_t gpgx_state_size; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool gpgx_state_save_t(byte[] dest, int size); - public gpgx_state_save_t gpgx_state_save; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool gpgx_state_load_t(byte[] src, int size); - public gpgx_state_load_t gpgx_state_load; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool gpgx_get_control_t([Out]InputData dest, int bytes); - public gpgx_get_control_t gpgx_get_control; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool gpgx_put_control_t([In]InputData src, int bytes); - public gpgx_put_control_t gpgx_put_control; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_get_sram_t(ref IntPtr area, ref int size); - public gpgx_get_sram_t gpgx_get_sram; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_clear_sram_t(); - public gpgx_clear_sram_t gpgx_clear_sram; - - public const int MIN_MEM_DOMAIN = 0; - public const int MAX_MEM_DOMAIN = 13; - - [UnmanagedFunctionPointer(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 delegate IntPtr gpgx_get_memdom_t(int which, ref IntPtr area, ref int size); - public gpgx_get_memdom_t gpgx_get_memdom; - - // call this before reading sram returned by gpgx_get_sram() - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_sram_prepread_t(); - public gpgx_sram_prepread_t gpgx_sram_prepread; - - // call this after writing sram returned by gpgx_get_sram() - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_sram_commitwrite_t(); - public gpgx_sram_commitwrite_t gpgx_sram_commitwrite; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_reset_t(bool hard); - public gpgx_reset_t gpgx_reset; - - 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(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_set_input_callback_t(input_cb cb); - public gpgx_set_input_callback_t gpgx_set_input_callback; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void mem_cb(uint addr); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_set_mem_callback_t(mem_cb read, mem_cb write, mem_cb exec); - public gpgx_set_mem_callback_t gpgx_set_mem_callback; - - /// <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; - } - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_get_vdp_view_t([Out] VDPView view); - public gpgx_get_vdp_view_t gpgx_get_vdp_view; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_poke_vram_t(int addr, byte value); - public gpgx_poke_vram_t gpgx_poke_vram; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_flush_vram_t(); - public gpgx_flush_vram_t gpgx_flush_vram; - - [StructLayout(LayoutKind.Sequential)] - public struct RegisterInfo - { - public int Value; - public IntPtr Name; - } - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int gpgx_getmaxnumregs_t(); - public gpgx_getmaxnumregs_t gpgx_getmaxnumregs; - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int gpgx_getregs_t([Out] RegisterInfo[] regs); - public gpgx_getregs_t gpgx_getregs; - - [Flags] - public enum DrawMask : int - { - BGA = 1, - BGB = 2, - BGW = 4 - } - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void gpgx_set_draw_mask_t(DrawMask mask); - public gpgx_set_draw_mask_t gpgx_set_draw_mask; - } -}