gpgx32: flipped namespaces, added excplicit core picking

diff is messed up after folder renaming, but no file was changed except for namespaces and waterbox's core name
This commit is contained in:
feos 2016-08-10 22:27:46 +03:00
parent 7b26a6b573
commit 35282ba577
31 changed files with 2726 additions and 2722 deletions

View File

@ -802,6 +802,10 @@ namespace BizHawk.Client.Common
nextEmulator = new Octoshock(nextComm, null, null, rom.FileData, GetCoreSettings<Octoshock>(), GetCoreSyncSettings<Octoshock>());
nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
break;
case "GEN":
// discard "Genplus-gx64", auto-added due to implementing IEmulator
core = CoreInventory.Instance["GEN", "Genplus-gx"];
break;
}
if (core != null)

View File

@ -838,46 +838,6 @@
<Compile Include="Consoles\Sega\Genesis\Genesis.Input.cs" />
<Compile Include="Consoles\Sega\Genesis\Genesis.IO.cs" />
<Compile Include="Consoles\Sega\Genesis\Native68000\Musashi.cs" />
<Compile Include="Consoles\Sega\gpgx32\GenDbgHlp.cs" />
<Compile Include="Consoles\Sega\gpgx32\GPGX.cs" />
<Compile Include="Consoles\Sega\gpgx32\GPGX.ICodeDataLogger.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.IDebuggable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.IDisassembler.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.IDriveLight.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.IEmulator.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.IInputPollable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.IMemoryDomains.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.ISaveRam.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.ISettable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.IStatable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.ITraceable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGX.IVideoProvider.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx32\GPGXControlConverter.cs" />
<Compile Include="Consoles\Sega\gpgx32\LibGPGX.cs" />
<Compile Include="Consoles\Sega\gpgx\GenDbgHlp.cs" />
<Compile Include="Consoles\Sega\gpgx\GPGX.cs" />
<Compile Include="Consoles\Sega\gpgx\GPGX.ICodeDataLogger.cs">
@ -918,6 +878,46 @@
</Compile>
<Compile Include="Consoles\Sega\gpgx\GPGXControlConverter.cs" />
<Compile Include="Consoles\Sega\gpgx\LibGPGX.cs" />
<Compile Include="Consoles\Sega\gpgx64\GenDbgHlp.cs" />
<Compile Include="Consoles\Sega\gpgx64\GPGX.cs" />
<Compile Include="Consoles\Sega\gpgx64\GPGX.ICodeDataLogger.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.IDebuggable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.IDisassembler.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.IDriveLight.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.IEmulator.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.IInputPollable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.IMemoryDomains.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.ISaveRam.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.ISettable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.IStatable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.ITraceable.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGX.IVideoProvider.cs">
<DependentUpon>GPGX.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\gpgx64\GPGXControlConverter.cs" />
<Compile Include="Consoles\Sega\gpgx64\LibGPGX.cs" />
<Compile Include="Consoles\Sega\Saturn\FilePiping.cs" />
<Compile Include="Consoles\Sega\Saturn\LibYabause.cs" />
<Compile Include="Consoles\Sega\Saturn\Yabause.cs" />

View File

@ -10,8 +10,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public void SetCDL(CodeDataLog cdl)
{
CDL = cdl;
if (cdl == null) Core.gpgx_set_cd_callback(null);
else Core.gpgx_set_cd_callback(CDCallback);
if (cdl == null) LibGPGX.gpgx_set_cd_callback(null);
else LibGPGX.gpgx_set_cd_callback(CDCallback);
}
public void NewCDL(CodeDataLog cdl)

View File

@ -10,9 +10,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
LibGPGX.RegisterInfo[] regs = new LibGPGX.RegisterInfo[Core.gpgx_getmaxnumregs()];
LibGPGX.RegisterInfo[] regs = new LibGPGX.RegisterInfo[LibGPGX.gpgx_getmaxnumregs()];
int n = Core.gpgx_getregs(regs);
int n = LibGPGX.gpgx_getregs(regs);
if (n > regs.Length)
throw new InvalidOperationException("A buffer overrun has occured!");
var ret = new Dictionary<string, RegisterValue>();
@ -63,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
private void RefreshMemCallbacks()
{
Core.gpgx_set_mem_callback(
LibGPGX.gpgx_set_mem_callback(
MemoryCallbacks.HasReads ? ReadCallback : null,
MemoryCallbacks.HasWrites ? WriteCallback : null,
MemoryCallbacks.HasExecutes ? ExecCallback : null);
@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
private void KillMemCallbacks()
{
Core.gpgx_set_mem_callback(null, null, null);
LibGPGX.gpgx_set_mem_callback(null, null, null);
}
}
}

View File

@ -29,26 +29,26 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public void FrameAdvance(bool render, bool rendersound = true)
{
if (Controller["Reset"])
Core.gpgx_reset(false);
LibGPGX.gpgx_reset(false);
if (Controller["Power"])
Core.gpgx_reset(true);
LibGPGX.gpgx_reset(true);
// this shouldn't be needed, as nothing has changed
// if (!Core.gpgx_get_control(input, inputsize))
// throw new Exception("gpgx_get_control() failed!");
// do we really have to get each time? nothing has changed
if (!LibGPGX.gpgx_get_control(input, inputsize))
throw new Exception("gpgx_get_control() failed!");
ControlConverter.ScreenWidth = vwidth;
ControlConverter.ScreenHeight = vheight;
ControlConverter.Convert(Controller, input);
if (!Core.gpgx_put_control(input, inputsize))
if (!LibGPGX.gpgx_put_control(input, inputsize))
throw new Exception("gpgx_put_control() failed!");
IsLagFrame = true;
Frame++;
_drivelight = false;
Core.gpgx_advance();
LibGPGX.gpgx_advance();
UpdateVideo();
update_audio();
@ -89,10 +89,16 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
if (!disposed)
{
if (Elf != null)
Elf.Dispose();
if (AttachedCore != this)
throw new Exception();
if (SaveRamModified)
_disposedSaveRam = CloneSaveRam();
KillMemCallbacks();
if (CD != null)
{
CD.Dispose();
}
AttachedCore = null;
disposed = true;
}
}

View File

@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
IntPtr area = IntPtr.Zero;
int size = 0;
IntPtr pname = Core.gpgx_get_memdom(i, ref area, ref size);
IntPtr pname = LibGPGX.gpgx_get_memdom(i, ref area, ref size);
if (area == IntPtr.Zero || pname == IntPtr.Zero || size == 0)
continue;
string name = Marshal.PtrToStringAnsi(pname);
@ -26,17 +26,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
// vram pokes need to go through hook which invalidates cached tiles
byte* p = (byte*)area;
mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Unknown,
delegate(long addr)
delegate (long addr)
{
if (addr < 0 || addr >= 65536)
throw new ArgumentOutOfRangeException();
return p[addr ^ 1];
},
delegate(long addr, byte val)
delegate (long addr, byte val)
{
if (addr < 0 || addr >= 65536)
throw new ArgumentOutOfRangeException();
Core.gpgx_poke_vram(((int)addr) ^ 1, val);
LibGPGX.gpgx_poke_vram(((int)addr) ^ 1, val);
},
wordSize: 2));
}
@ -44,6 +44,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
else
{
// TODO: are the Z80 domains really Swap16 in the core? Check this
//var byteSize = name.Contains("Z80") ? 1 : 2;
mm.Add(MemoryDomain.FromIntPtrSwap16(name, size,
MemoryDomain.Endian.Big, area, name != "MD CART" && name != "CD BOOT ROM"));
}
@ -54,14 +55,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
var a = (uint)addr;
if (a >= 0x1000000)
throw new ArgumentOutOfRangeException();
return Core.gpgx_peek_m68k_bus(a);
return LibGPGX.gpgx_peek_m68k_bus(a);
},
delegate (long addr, byte val)
{
var a = (uint)addr;
if (a >= 0x1000000)
throw new ArgumentOutOfRangeException();
Core.gpgx_write_m68k_bus(a, val);
LibGPGX.gpgx_write_m68k_bus(a, val);
}, 2);
mm.Add(m68Bus);
@ -72,14 +73,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
var a = (uint)addr;
if (a >= 0x1000000)
throw new ArgumentOutOfRangeException();
return Core.gpgx_peek_s68k_bus(a);
return LibGPGX.gpgx_peek_s68k_bus(a);
},
delegate (long addr, byte val)
{
var a = (uint)addr;
if (a >= 0x1000000)
throw new ArgumentOutOfRangeException();
Core.gpgx_write_s68k_bus(a, val);
LibGPGX.gpgx_write_s68k_bus(a, val);
}, 2);
if (IsSegaCD)

View File

@ -11,30 +11,69 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
public byte[] CloneSaveRam()
{
int size = 0;
IntPtr area = Core.gpgx_get_sram(ref size);
if (size == 0 || area == IntPtr.Zero)
if (disposed)
{
if (_disposedSaveRam != null)
{
return (byte[])_disposedSaveRam.Clone();
}
return new byte[0];
}
else
{
int size = 0;
IntPtr area = IntPtr.Zero;
LibGPGX.gpgx_get_sram(ref area, ref size);
if (size <= 0 || area == IntPtr.Zero)
return new byte[0];
LibGPGX.gpgx_sram_prepread();
byte[] ret = new byte[size];
Marshal.Copy(area, ret, 0, size);
return ret;
}
}
public void StoreSaveRam(byte[] data)
{
if (!Core.gpgx_put_sram(data, data.Length))
throw new Exception("Core rejected saveram");
if (disposed)
{
throw new ObjectDisposedException(typeof(GPGX).ToString());
}
else
{
int size = 0;
IntPtr area = IntPtr.Zero;
LibGPGX.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);
LibGPGX.gpgx_sram_commitwrite();
}
}
public bool SaveRamModified
{
get
{
if (disposed)
{
return _disposedSaveRam != null;
}
else
{
int size = 0;
IntPtr area = Core.gpgx_get_sram(ref size);
IntPtr area = IntPtr.Zero;
LibGPGX.gpgx_get_sram(ref area, ref size);
return size > 0 && area != IntPtr.Zero;
}
}
}
private byte[] _disposedSaveRam = null;
}
}

View File

@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
bool ret = GPGXSettings.NeedsReboot(_settings, o);
_settings = o;
Core.gpgx_set_draw_mask(_settings.GetDrawMask());
LibGPGX.gpgx_set_draw_mask(_settings.GetDrawMask());
return ret;
}
@ -80,7 +80,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
private bool _PadScreen320;
[DisplayName("Pad screen to 320")]
[Description("When using 1:1 aspect ratio, enable to make screen width constant (320) between game modes")]
[Description("Set to True to pads the screen out to be 320 when in 256 wide video modes")]
[DefaultValue(false)]
public bool PadScreen320 { get { return _PadScreen320; } set { _PadScreen320 = value; } }

View File

@ -29,42 +29,51 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
LoadStateBinary(new BinaryReader(new MemoryStream(state)));
}
public byte[] SaveStateBinary()
{
var ms = new MemoryStream(_savebuff2, true);
var bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
ms.Close();
return _savebuff2;
}
public void LoadStateBinary(BinaryReader reader)
{
Elf.LoadStateBinary(reader);
int newlen = reader.ReadInt32();
if (newlen != _savebuff.Length)
{
throw new Exception("Unexpected state size");
}
reader.Read(_savebuff, 0, _savebuff.Length);
if (!LibGPGX.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();
// any managed pointers that we sent to the core need to be resent now!
Core.gpgx_set_input_callback(InputCallback);
RefreshMemCallbacks();
Core.gpgx_set_cdd_callback(cd_callback_handle);
Core.gpgx_invalidate_pattern_cache();
UpdateVideo();
}
public void SaveStateBinary(BinaryWriter writer)
{
Elf.SaveStateBinary(writer);
if (!LibGPGX.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 byte[] SaveStateBinary()
{
var ms = new MemoryStream();
var bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
ms.Close();
return ms.ToArray();
}
private void InitStateBuffers()
{
}
private byte[] _savebuff;
private byte[] _savebuff2;
}
}

View File

@ -40,7 +40,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
int gppitch, gpwidth, gpheight;
IntPtr src = IntPtr.Zero;
Core.gpgx_get_video(out gpwidth, out gpheight, out gppitch, ref src);
LibGPGX.gpgx_get_video(out gpwidth, out gpheight, out gppitch, ref src);
vwidth = gpwidth;
vheight = gpheight;

View File

@ -2,9 +2,6 @@
using System.Runtime.InteropServices;
using BizHawk.Emulation.Common;
using BizHawk.Common;
using System.IO;
using BizHawk.Emulation.Common.BizInvoke;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
@ -15,13 +12,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
isReleased: true,
portedVersion: "r874",
portedUrl: "https://code.google.com/p/genplus-gx/",
singleInstance: false
singleInstance: true
)]
public partial class GPGX : IEmulator, ISyncSoundProvider, IVideoProvider, ISaveRam, IStatable, IRegionable,
IInputPollable, IDebuggable, IDriveLight, ICodeDataLogger, IDisassemblable
{
LibGPGX Core;
ElfRunner Elf;
static GPGX AttachedCore = null;
DiscSystem.Disc CD;
DiscSystem.DiscSectorReader DiscSectorReader;
@ -54,7 +50,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public GPGX(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings)
{
ServiceProvider = new BasicServiceProvider(this);
// this can influence some things internally (autodetect romtype, etc)
// this can influence some things internally
string romextension = "GEN";
// three or six button?
@ -68,27 +64,22 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
try
{
Elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024);
if (Elf.ShouldMonitor)
Core = BizInvoker.GetInvoker<LibGPGX>(Elf, Elf);
else
Core = BizInvoker.GetInvoker<LibGPGX>(Elf);
_syncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings();
_settings = (GPGXSettings)Settings ?? new GPGXSettings();
CoreComm = comm;
if (AttachedCore != null)
{
AttachedCore.Dispose();
AttachedCore = null;
}
AttachedCore = this;
LoadCallback = new LibGPGX.load_archive_cb(load_archive);
this.romfile = rom;
this.CD = CD;
if (CD != null)
{
this.DiscSectorReader = new DiscSystem.DiscSectorReader(CD);
cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);
Core.gpgx_set_cdd_callback(cd_callback_handle);
}
LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
LibGPGX.INPUT_SYSTEM system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
@ -128,20 +119,28 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
}
if (!Core.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings()))
if (!LibGPGX.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings()))
throw new Exception("gpgx_init() failed");
{
int fpsnum = 60;
int fpsden = 1;
Core.gpgx_get_fps(ref fpsnum, ref fpsden);
LibGPGX.gpgx_get_fps(ref fpsnum, ref fpsden);
CoreComm.VsyncNum = fpsnum;
CoreComm.VsyncDen = fpsden;
Region = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL;
}
// compute state size
InitStateBuffers();
{
byte[] tmp = new byte[LibGPGX.gpgx_state_max_size()];
int size = LibGPGX.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();
@ -151,7 +150,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
SetMemoryDomains();
InputCallback = new LibGPGX.input_cb(input_callback);
Core.gpgx_set_input_callback(InputCallback);
LibGPGX.gpgx_set_input_callback(InputCallback);
if (CD != null)
DriveLightEnabled = true;
@ -167,8 +166,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
Tracer = new GPGXTraceBuffer(this, MemoryDomains, this);
(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);
Elf.Seal();
}
catch
{
@ -311,6 +308,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
LibGPGX.CDData ret = new LibGPGX.CDData();
int size = Marshal.SizeOf(ret);
ret.readcallback = cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);
var ses = CD.Session1;
int ntrack = ses.InformationTrackCount;
@ -354,7 +353,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
private void SetControllerDefinition()
{
inputsize = Marshal.SizeOf(typeof(LibGPGX.InputData));
if (!Core.gpgx_get_control(input, inputsize))
if (!LibGPGX.gpgx_get_control(input, inputsize))
throw new Exception("gpgx_get_control() failed");
ControlConverter = new GPGXControlConverter(input);
@ -370,8 +369,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public void UpdateVDPViewContext(LibGPGX.VDPView view)
{
Core.gpgx_get_vdp_view(view);
Core.gpgx_flush_vram(); // fully regenerate internal caches as needed
LibGPGX.gpgx_get_vdp_view(view);
LibGPGX.gpgx_flush_vram(); // fully regenerate internal caches as needed
}
short[] samples = new short[4096];
@ -392,7 +391,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
void update_audio()
{
IntPtr src = IntPtr.Zero;
Core.gpgx_get_audio(ref nsamp, ref src);
LibGPGX.gpgx_get_audio(ref nsamp, ref src);
if (src != IntPtr.Zero)
{
Marshal.Copy(src, samples, 0, nsamp * 2);

View File

@ -3,25 +3,22 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using BizHawk.Emulation.Common.BizInvoke;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
public abstract class LibGPGX
public static class LibGPGX
{
public const string DllName = "libgenplusgx.dll";
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_video(out int w, out int h, out int pitch, ref IntPtr buffer);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_get_video(out int w, out int h, out int pitch, ref IntPtr buffer);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_get_audio(ref int n, 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);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_advance();
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_advance();
public enum Region : int
{
@ -51,36 +48,50 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public uint BackdropColor;
}
[BizImport(CallingConvention.Cdecl, Compatibility=true)]
public abstract bool gpgx_init(string feromextension, load_archive_cb feload_archive_cb, bool sixbutton, INPUT_SYSTEM system_a, INPUT_SYSTEM system_b, Region region, [In]InitSettings settings);
[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, [In]InitSettings settings);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_get_fps(ref int num, ref int den);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_fps(ref int num, ref int den);
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract bool gpgx_get_control([Out]InputData dest, int bytes);
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract bool gpgx_put_control([In]InputData src, int bytes);
[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);
[BizImport(CallingConvention.Cdecl)]
public abstract IntPtr gpgx_get_sram(ref 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);
[BizImport(CallingConvention.Cdecl)]
public abstract bool gpgx_put_sram(byte[] data, int size);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_sram(ref IntPtr area, ref int size);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_clear_sram();
[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;
[BizImport(CallingConvention.Cdecl)]
[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 abstract IntPtr gpgx_get_memdom(int which, ref IntPtr area, ref int size);
public static extern IntPtr gpgx_get_memdom(int which, ref IntPtr area, ref int size);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_reset(bool hard);
// 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;
@ -138,8 +149,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void input_cb();
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_input_callback(input_cb 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);
@ -147,11 +158,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CDCallback(int addr, CDLog_AddrType addrtype, CDLog_Flags flags);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_mem_callback(mem_cb read, mem_cb write, mem_cb exec);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_mem_callback(mem_cb read, mem_cb write, mem_cb exec);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_cd_callback(CDCallback cd);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_cd_callback(CDCallback cd);
@ -274,11 +285,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public int last;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CD_MAX_TRACKS)]
public readonly CDTrack[] tracks = new CDTrack[CD_MAX_TRACKS];
public cd_read_cb readcallback;
}
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_cdd_callback(cd_read_cb cddcb);
[StructLayout(LayoutKind.Sequential)]
public struct VDPNameTable
{
@ -298,23 +307,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public VDPNameTable NTW;
}
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract void gpgx_get_vdp_view([Out] VDPView view);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_vdp_view([Out] VDPView view);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_poke_vram(int addr, byte value);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_poke_vram(int addr, byte value);
/// <summary>
/// regenerate whatever portions of the bg pattern cache are currently dirty.
/// </summary>
[BizImport(CallingConvention.Cdecl)] // the core will handle this itself; you only need to call this when using the cache for your own purposes
public abstract void gpgx_flush_vram();
/// <summary>
/// mark the bg pattern cache as dirty
/// </summary>
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_invalidate_pattern_cache();
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_flush_vram();
[StructLayout(LayoutKind.Sequential)]
public struct RegisterInfo
@ -323,11 +323,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public IntPtr Name;
}
[BizImport(CallingConvention.Cdecl)]
public abstract int gpgx_getmaxnumregs();
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gpgx_getmaxnumregs();
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract int gpgx_getregs([Out] RegisterInfo[] regs);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gpgx_getregs([Out] RegisterInfo[] regs);
[Flags]
public enum DrawMask : int
@ -339,16 +339,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
Backdrop = 16
}
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_draw_mask(DrawMask mask);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_draw_mask(DrawMask mask);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_write_m68k_bus(uint addr, byte data);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_write_s68k_bus(uint addr, byte data);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte gpgx_peek_m68k_bus(uint addr);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte gpgx_peek_s68k_bus(uint addr);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_write_m68k_bus(uint addr, byte data);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_write_s68k_bus(uint addr, byte data);
[BizImport(CallingConvention.Cdecl)]
public abstract byte gpgx_peek_m68k_bus(uint addr);
[BizImport(CallingConvention.Cdecl)]
public abstract byte gpgx_peek_s68k_bus(uint addr);
}
}

View File

@ -1,79 +0,0 @@
using System;
using System.IO;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
{
public partial class GPGX : ISaveRam
{
public byte[] CloneSaveRam()
{
if (disposed)
{
if (_disposedSaveRam != null)
{
return (byte[])_disposedSaveRam.Clone();
}
return new byte[0];
}
else
{
int size = 0;
IntPtr area = IntPtr.Zero;
LibGPGX.gpgx_get_sram(ref area, ref size);
if (size <= 0 || area == IntPtr.Zero)
return new byte[0];
LibGPGX.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;
LibGPGX.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);
LibGPGX.gpgx_sram_commitwrite();
}
}
public bool SaveRamModified
{
get
{
if (disposed)
{
return _disposedSaveRam != null;
}
else
{
int size = 0;
IntPtr area = IntPtr.Zero;
LibGPGX.gpgx_get_sram(ref area, ref size);
return size > 0 && area != IntPtr.Zero;
}
}
}
private byte[] _disposedSaveRam = null;
}
}

View File

@ -3,15 +3,15 @@ using System.IO;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : ICodeDataLogger
{
public void SetCDL(CodeDataLog cdl)
{
CDL = cdl;
if (cdl == null) LibGPGX.gpgx_set_cd_callback(null);
else LibGPGX.gpgx_set_cd_callback(CDCallback);
if (cdl == null) Core.gpgx_set_cd_callback(null);
else Core.gpgx_set_cd_callback(CDCallback);
}
public void NewCDL(CodeDataLog cdl)

View File

@ -4,15 +4,15 @@ using System.Runtime.InteropServices;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : IDebuggable
{
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
LibGPGX.RegisterInfo[] regs = new LibGPGX.RegisterInfo[LibGPGX.gpgx_getmaxnumregs()];
LibGPGX.RegisterInfo[] regs = new LibGPGX.RegisterInfo[Core.gpgx_getmaxnumregs()];
int n = LibGPGX.gpgx_getregs(regs);
int n = Core.gpgx_getregs(regs);
if (n > regs.Length)
throw new InvalidOperationException("A buffer overrun has occured!");
var ret = new Dictionary<string, RegisterValue>();
@ -63,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
private void RefreshMemCallbacks()
{
LibGPGX.gpgx_set_mem_callback(
Core.gpgx_set_mem_callback(
MemoryCallbacks.HasReads ? ReadCallback : null,
MemoryCallbacks.HasWrites ? WriteCallback : null,
MemoryCallbacks.HasExecutes ? ExecCallback : null);
@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
private void KillMemCallbacks()
{
LibGPGX.gpgx_set_mem_callback(null, null, null);
Core.gpgx_set_mem_callback(null, null, null);
}
}
}

View File

@ -2,7 +2,7 @@
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Components.M68000;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : IDisassemblable
{

View File

@ -1,6 +1,6 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : IDriveLight
{

View File

@ -1,7 +1,7 @@
using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : IEmulator
{
@ -29,26 +29,26 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
public void FrameAdvance(bool render, bool rendersound = true)
{
if (Controller["Reset"])
LibGPGX.gpgx_reset(false);
Core.gpgx_reset(false);
if (Controller["Power"])
LibGPGX.gpgx_reset(true);
Core.gpgx_reset(true);
// do we really have to get each time? nothing has changed
if (!LibGPGX.gpgx_get_control(input, inputsize))
throw new Exception("gpgx_get_control() failed!");
// this shouldn't be needed, as nothing has changed
// if (!Core.gpgx_get_control(input, inputsize))
// throw new Exception("gpgx_get_control() failed!");
ControlConverter.ScreenWidth = vwidth;
ControlConverter.ScreenHeight = vheight;
ControlConverter.Convert(Controller, input);
if (!LibGPGX.gpgx_put_control(input, inputsize))
if (!Core.gpgx_put_control(input, inputsize))
throw new Exception("gpgx_put_control() failed!");
IsLagFrame = true;
Frame++;
_drivelight = false;
LibGPGX.gpgx_advance();
Core.gpgx_advance();
UpdateVideo();
update_audio();
@ -89,16 +89,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
{
if (!disposed)
{
if (AttachedCore != this)
throw new Exception();
if (SaveRamModified)
_disposedSaveRam = CloneSaveRam();
KillMemCallbacks();
if (Elf != null)
Elf.Dispose();
if (CD != null)
{
CD.Dispose();
}
AttachedCore = null;
disposed = true;
}
}

View File

@ -1,6 +1,6 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : IInputPollable
{

View File

@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX
{
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
{
IntPtr area = IntPtr.Zero;
int size = 0;
IntPtr pname = LibGPGX.gpgx_get_memdom(i, ref area, ref size);
IntPtr pname = Core.gpgx_get_memdom(i, ref area, ref size);
if (area == IntPtr.Zero || pname == IntPtr.Zero || size == 0)
continue;
string name = Marshal.PtrToStringAnsi(pname);
@ -26,17 +26,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
// vram pokes need to go through hook which invalidates cached tiles
byte* p = (byte*)area;
mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Unknown,
delegate (long addr)
delegate(long addr)
{
if (addr < 0 || addr >= 65536)
throw new ArgumentOutOfRangeException();
return p[addr ^ 1];
},
delegate (long addr, byte val)
delegate(long addr, byte val)
{
if (addr < 0 || addr >= 65536)
throw new ArgumentOutOfRangeException();
LibGPGX.gpgx_poke_vram(((int)addr) ^ 1, val);
Core.gpgx_poke_vram(((int)addr) ^ 1, val);
},
wordSize: 2));
}
@ -44,7 +44,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
else
{
// TODO: are the Z80 domains really Swap16 in the core? Check this
//var byteSize = name.Contains("Z80") ? 1 : 2;
mm.Add(MemoryDomain.FromIntPtrSwap16(name, size,
MemoryDomain.Endian.Big, area, name != "MD CART" && name != "CD BOOT ROM"));
}
@ -55,14 +54,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
var a = (uint)addr;
if (a >= 0x1000000)
throw new ArgumentOutOfRangeException();
return LibGPGX.gpgx_peek_m68k_bus(a);
return Core.gpgx_peek_m68k_bus(a);
},
delegate (long addr, byte val)
{
var a = (uint)addr;
if (a >= 0x1000000)
throw new ArgumentOutOfRangeException();
LibGPGX.gpgx_write_m68k_bus(a, val);
Core.gpgx_write_m68k_bus(a, val);
}, 2);
mm.Add(m68Bus);
@ -73,14 +72,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
var a = (uint)addr;
if (a >= 0x1000000)
throw new ArgumentOutOfRangeException();
return LibGPGX.gpgx_peek_s68k_bus(a);
return Core.gpgx_peek_s68k_bus(a);
},
delegate (long addr, byte val)
{
var a = (uint)addr;
if (a >= 0x1000000)
throw new ArgumentOutOfRangeException();
LibGPGX.gpgx_write_s68k_bus(a, val);
Core.gpgx_write_s68k_bus(a, val);
}, 2);
if (IsSegaCD)

View File

@ -0,0 +1,40 @@
using System;
using System.IO;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : ISaveRam
{
public byte[] CloneSaveRam()
{
int size = 0;
IntPtr area = Core.gpgx_get_sram(ref size);
if (size == 0 || area == IntPtr.Zero)
return new byte[0];
byte[] ret = new byte[size];
Marshal.Copy(area, ret, 0, size);
return ret;
}
public void StoreSaveRam(byte[] data)
{
if (!Core.gpgx_put_sram(data, data.Length))
throw new Exception("Core rejected saveram");
}
public bool SaveRamModified
{
get
{
int size = 0;
IntPtr area = Core.gpgx_get_sram(ref size);
return size > 0 && area != IntPtr.Zero;
}
}
}
}

View File

@ -5,7 +5,7 @@ using BizHawk.Emulation.Common;
using Newtonsoft.Json;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : ISettable<GPGX.GPGXSettings, GPGX.GPGXSyncSettings>
{
@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
{
bool ret = GPGXSettings.NeedsReboot(_settings, o);
_settings = o;
LibGPGX.gpgx_set_draw_mask(_settings.GetDrawMask());
Core.gpgx_set_draw_mask(_settings.GetDrawMask());
return ret;
}
@ -80,7 +80,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
private bool _PadScreen320;
[DisplayName("Pad screen to 320")]
[Description("Set to True to pads the screen out to be 320 when in 256 wide video modes")]
[Description("When using 1:1 aspect ratio, enable to make screen width constant (320) between game modes")]
[DefaultValue(false)]
public bool PadScreen320 { get { return _PadScreen320; } set { _PadScreen320 = value; } }

View File

@ -4,7 +4,7 @@ using System.IO;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : IStatable
{
@ -29,51 +29,42 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
LoadStateBinary(new BinaryReader(new MemoryStream(state)));
}
public byte[] SaveStateBinary()
{
var ms = new MemoryStream(_savebuff2, true);
var bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
ms.Close();
return _savebuff2;
}
public void LoadStateBinary(BinaryReader reader)
{
int newlen = reader.ReadInt32();
if (newlen != _savebuff.Length)
{
throw new Exception("Unexpected state size");
}
reader.Read(_savebuff, 0, _savebuff.Length);
if (!LibGPGX.gpgx_state_load(_savebuff, _savebuff.Length))
{
throw new Exception("gpgx_state_load() returned false");
}
Elf.LoadStateBinary(reader);
// other variables
Frame = reader.ReadInt32();
LagCount = reader.ReadInt32();
IsLagFrame = reader.ReadBoolean();
// any managed pointers that we sent to the core need to be resent now!
Core.gpgx_set_input_callback(InputCallback);
RefreshMemCallbacks();
Core.gpgx_set_cdd_callback(cd_callback_handle);
Core.gpgx_invalidate_pattern_cache();
UpdateVideo();
}
public void SaveStateBinary(BinaryWriter writer)
{
if (!LibGPGX.gpgx_state_save(_savebuff, _savebuff.Length))
throw new Exception("gpgx_state_save() returned false");
writer.Write(_savebuff.Length);
writer.Write(_savebuff);
Elf.SaveStateBinary(writer);
// other variables
writer.Write(Frame);
writer.Write(LagCount);
writer.Write(IsLagFrame);
}
private byte[] _savebuff;
private byte[] _savebuff2;
public byte[] SaveStateBinary()
{
var ms = new MemoryStream();
var bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
ms.Close();
return ms.ToArray();
}
private void InitStateBuffers()
{
}
}
}

View File

@ -5,7 +5,7 @@ using System.Text;
using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX
{

View File

@ -1,7 +1,7 @@
using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public partial class GPGX : IVideoProvider
{
@ -40,7 +40,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
int gppitch, gpwidth, gpheight;
IntPtr src = IntPtr.Zero;
LibGPGX.gpgx_get_video(out gpwidth, out gpheight, out gppitch, ref src);
Core.gpgx_get_video(out gpwidth, out gpheight, out gppitch, ref src);
vwidth = gpwidth;
vheight = gpheight;

View File

@ -2,22 +2,26 @@
using System.Runtime.InteropServices;
using BizHawk.Emulation.Common;
using BizHawk.Common;
using System.IO;
using BizHawk.Emulation.Common.BizInvoke;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
[CoreAttributes(
"Genplus-gx",
"Genplus-gx64",
"",
isPorted: true,
isReleased: true,
portedVersion: "r874",
portedUrl: "https://code.google.com/p/genplus-gx/",
singleInstance: true
singleInstance: false
)]
public partial class GPGX : IEmulator, ISyncSoundProvider, IVideoProvider, ISaveRam, IStatable, IRegionable,
IInputPollable, IDebuggable, IDriveLight, ICodeDataLogger, IDisassemblable
{
static GPGX AttachedCore = null;
LibGPGX Core;
ElfRunner Elf;
DiscSystem.Disc CD;
DiscSystem.DiscSectorReader DiscSectorReader;
@ -50,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
public GPGX(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings)
{
ServiceProvider = new BasicServiceProvider(this);
// this can influence some things internally
// this can influence some things internally (autodetect romtype, etc)
string romextension = "GEN";
// three or six button?
@ -64,22 +68,27 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
try
{
Elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024);
if (Elf.ShouldMonitor)
Core = BizInvoker.GetInvoker<LibGPGX>(Elf, Elf);
else
Core = BizInvoker.GetInvoker<LibGPGX>(Elf);
_syncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings();
_settings = (GPGXSettings)Settings ?? new GPGXSettings();
CoreComm = comm;
if (AttachedCore != null)
{
AttachedCore.Dispose();
AttachedCore = null;
}
AttachedCore = this;
LoadCallback = new LibGPGX.load_archive_cb(load_archive);
this.romfile = rom;
this.CD = CD;
if (CD != null)
{
this.DiscSectorReader = new DiscSystem.DiscSectorReader(CD);
cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);
Core.gpgx_set_cdd_callback(cd_callback_handle);
}
LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
LibGPGX.INPUT_SYSTEM system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
@ -119,28 +128,20 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
}
if (!LibGPGX.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings()))
if (!Core.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings()))
throw new Exception("gpgx_init() failed");
{
int fpsnum = 60;
int fpsden = 1;
LibGPGX.gpgx_get_fps(ref fpsnum, ref fpsden);
Core.gpgx_get_fps(ref fpsnum, ref fpsden);
CoreComm.VsyncNum = fpsnum;
CoreComm.VsyncDen = fpsden;
Region = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL;
}
// compute state size
{
byte[] tmp = new byte[LibGPGX.gpgx_state_max_size()];
int size = LibGPGX.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);
}
InitStateBuffers();
SetControllerDefinition();
@ -150,7 +151,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
SetMemoryDomains();
InputCallback = new LibGPGX.input_cb(input_callback);
LibGPGX.gpgx_set_input_callback(InputCallback);
Core.gpgx_set_input_callback(InputCallback);
if (CD != null)
DriveLightEnabled = true;
@ -166,6 +167,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
Tracer = new GPGXTraceBuffer(this, MemoryDomains, this);
(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);
Elf.Seal();
}
catch
{
@ -308,8 +311,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
LibGPGX.CDData ret = new LibGPGX.CDData();
int size = Marshal.SizeOf(ret);
ret.readcallback = cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);
var ses = CD.Session1;
int ntrack = ses.InformationTrackCount;
@ -353,7 +354,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
private void SetControllerDefinition()
{
inputsize = Marshal.SizeOf(typeof(LibGPGX.InputData));
if (!LibGPGX.gpgx_get_control(input, inputsize))
if (!Core.gpgx_get_control(input, inputsize))
throw new Exception("gpgx_get_control() failed");
ControlConverter = new GPGXControlConverter(input);
@ -369,8 +370,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
public void UpdateVDPViewContext(LibGPGX.VDPView view)
{
LibGPGX.gpgx_get_vdp_view(view);
LibGPGX.gpgx_flush_vram(); // fully regenerate internal caches as needed
Core.gpgx_get_vdp_view(view);
Core.gpgx_flush_vram(); // fully regenerate internal caches as needed
}
short[] samples = new short[4096];
@ -391,7 +392,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
void update_audio()
{
IntPtr src = IntPtr.Zero;
LibGPGX.gpgx_get_audio(ref nsamp, ref src);
Core.gpgx_get_audio(ref nsamp, ref src);
if (src != IntPtr.Zero)
{
Marshal.Copy(src, samples, 0, nsamp * 2);

View File

@ -6,7 +6,7 @@ using System.Text;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public class GPGXControlConverter
{

View File

@ -5,7 +5,7 @@ using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
/*
* how to use:

View File

@ -3,22 +3,25 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using BizHawk.Emulation.Common.BizInvoke;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
public static class LibGPGX
public abstract class LibGPGX
{
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_video(out int w, out int h, out int pitch, ref IntPtr buffer);
public const string DllName = "libgenplusgx.dll";
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_audio(ref int n, ref IntPtr buffer);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_get_video(out int w, out int h, out int pitch, ref IntPtr buffer);
[BizImport(CallingConvention.Cdecl)]
public abstract 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();
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_advance();
public enum Region : int
{
@ -48,50 +51,36 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
public uint BackdropColor;
}
[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, [In]InitSettings settings);
[BizImport(CallingConvention.Cdecl, Compatibility=true)]
public abstract bool gpgx_init(string feromextension, load_archive_cb feload_archive_cb, bool sixbutton, INPUT_SYSTEM system_a, INPUT_SYSTEM system_b, Region region, [In]InitSettings settings);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_fps(ref int num, ref int den);
[BizImport(CallingConvention.Cdecl)]
public abstract 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);
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract bool gpgx_get_control([Out]InputData dest, int bytes);
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract bool gpgx_put_control([In]InputData src, int bytes);
[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);
[BizImport(CallingConvention.Cdecl)]
public abstract IntPtr gpgx_get_sram(ref int size);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_sram(ref IntPtr area, ref int size);
[BizImport(CallingConvention.Cdecl)]
public abstract bool gpgx_put_sram(byte[] data, int size);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_clear_sram();
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_clear_sram();
public const int MIN_MEM_DOMAIN = 0;
public const int MAX_MEM_DOMAIN = 13;
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
[BizImport(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);
public abstract 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);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_reset(bool hard);
public const int MAX_DEVICES = 8;
@ -149,8 +138,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
[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);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_input_callback(input_cb cb);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void mem_cb(uint addr);
@ -158,11 +147,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CDCallback(int addr, CDLog_AddrType addrtype, CDLog_Flags flags);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_mem_callback(mem_cb read, mem_cb write, mem_cb exec);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_mem_callback(mem_cb read, mem_cb write, mem_cb exec);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_cd_callback(CDCallback cd);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_cd_callback(CDCallback cd);
@ -285,9 +274,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
public int last;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CD_MAX_TRACKS)]
public readonly CDTrack[] tracks = new CDTrack[CD_MAX_TRACKS];
public cd_read_cb readcallback;
}
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_cdd_callback(cd_read_cb cddcb);
[StructLayout(LayoutKind.Sequential)]
public struct VDPNameTable
{
@ -307,14 +298,23 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
public VDPNameTable NTW;
}
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_vdp_view([Out] VDPView view);
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract 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);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_poke_vram(int addr, byte value);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_flush_vram();
/// <summary>
/// regenerate whatever portions of the bg pattern cache are currently dirty.
/// </summary>
[BizImport(CallingConvention.Cdecl)] // the core will handle this itself; you only need to call this when using the cache for your own purposes
public abstract void gpgx_flush_vram();
/// <summary>
/// mark the bg pattern cache as dirty
/// </summary>
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_invalidate_pattern_cache();
[StructLayout(LayoutKind.Sequential)]
public struct RegisterInfo
@ -323,11 +323,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
public IntPtr Name;
}
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gpgx_getmaxnumregs();
[BizImport(CallingConvention.Cdecl)]
public abstract int gpgx_getmaxnumregs();
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gpgx_getregs([Out] RegisterInfo[] regs);
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract int gpgx_getregs([Out] RegisterInfo[] regs);
[Flags]
public enum DrawMask : int
@ -339,17 +339,16 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
Backdrop = 16
}
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_draw_mask(DrawMask mask);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_write_m68k_bus(uint addr, byte data);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_write_s68k_bus(uint addr, byte data);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte gpgx_peek_m68k_bus(uint addr);
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte gpgx_peek_s68k_bus(uint addr);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_set_draw_mask(DrawMask mask);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_write_m68k_bus(uint addr, byte data);
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_write_s68k_bus(uint addr, byte data);
[BizImport(CallingConvention.Cdecl)]
public abstract byte gpgx_peek_m68k_bus(uint addr);
[BizImport(CallingConvention.Cdecl)]
public abstract byte gpgx_peek_s68k_bus(uint addr);
}
}