From 0c0f9eb93a362b451e1c9891d506db610ead4715 Mon Sep 17 00:00:00 2001 From: goyuken Date: Mon, 28 Jul 2014 20:45:21 +0000 Subject: [PATCH] snes9x rough-in --- BizHawk.Client.Common/RomLoader.cs | 6 + BizHawk.Client.EmuHawk/MainForm.cs | 16 +- .../BizHawk.Emulation.Cores.csproj | 2 + .../Consoles/Nintendo/SNES9X/LibSnes9x.cs | 20 ++ .../Consoles/Nintendo/SNES9X/Snes9x.cs | 196 ++++++++++++++++++ 5 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/LibSnes9x.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs diff --git a/BizHawk.Client.Common/RomLoader.cs b/BizHawk.Client.Common/RomLoader.cs index 0cf375fd71..16b6f3d867 100644 --- a/BizHawk.Client.Common/RomLoader.cs +++ b/BizHawk.Client.Common/RomLoader.cs @@ -305,6 +305,7 @@ namespace BizHawk.Client.Common switch (game.System) { case "SNES": + if (true) { // need to get rid of this hack at some point ((CoreFileProvider)nextComm.CoreFileProvider).SubfileDirectory = Path.GetDirectoryName(path.Replace("|", String.Empty)); // Dirty hack to get around archive filenames (since we are just getting the directory path, it is safe to mangle the filename @@ -314,6 +315,11 @@ namespace BizHawk.Client.Common var xmlData = isXml ? rom.FileData : null; snes.Load(game, romData, Deterministic, xmlData); } + else + { + var snes = new Emulation.Cores.Nintendo.SNES9X.Snes9x(nextComm, rom.FileData); + nextEmulator = snes; + } break; case "SMS": diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 7fcd081f29..540e27cd45 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -1507,15 +1507,23 @@ namespace BizHawk.Client.EmuHawk break; case "SNES": case "SGB": - if ((Global.Emulator as LibsnesCore).IsSGB) + // TODO: fix SNES9x here + if (Global.Emulator is LibsnesCore) { - SNESSubMenu.Text = "&SGB"; + if ((Global.Emulator as LibsnesCore).IsSGB) + { + SNESSubMenu.Text = "&SGB"; + } + else + { + SNESSubMenu.Text = "&SNES"; + } + SNESSubMenu.Visible = true; } else { - SNESSubMenu.Text = "&SNES"; + SNESSubMenu.Visible = false; } - SNESSubMenu.Visible = true; break; case "Coleco": ColecoSubMenu.Visible = true; diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 26974085f1..54e3e4a741 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -433,6 +433,8 @@ + + diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/LibSnes9x.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/LibSnes9x.cs new file mode 100644 index 0000000000..6146d1e4d5 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/LibSnes9x.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +namespace BizHawk.Emulation.Cores.Nintendo.SNES9X +{ + public class LibSnes9x + { + const string DllName = "libbizsnes.dll"; + const CallingConvention CC = CallingConvention.Cdecl; + + [DllImport(DllName, CallingConvention = CC)] + public static extern bool debug_init(byte[] data, int length); + + [DllImport(DllName, CallingConvention = CC)] + public static extern void debug_advance(int[] data); + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs new file mode 100644 index 0000000000..8b5946fc72 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using BizHawk.Common; +using BizHawk.Common.BufferExtensions; +using BizHawk.Emulation.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.SNES9X +{ + [CoreAttributes("Snes9x", "FIXME", true, false, "5e0319ab3ef9611250efb18255186d0dc0d7e125", "https://github.com/snes9xgit/snes9x")] + public class Snes9x : IEmulator, IVideoProvider, ISyncSoundProvider + { + #region controller + + public ControllerDefinition ControllerDefinition + { + get { return NullEmulator.NullController; } + } + + public IController Controller { get; set; } + + #endregion + + public void Dispose() + { + } + + public Snes9x(CoreComm NextComm, byte[] rom) + { + if (!LibSnes9x.debug_init(rom, rom.Length)) + throw new Exception(); + + CoreComm = NextComm; + } + + public void FrameAdvance(bool render, bool rendersound = true) + { + Frame++; + + LibSnes9x.debug_advance(_vbuff); + + if (IsLagFrame) + LagCount++; + } + + public int Frame { get; private set; } + public int LagCount { get; set; } + public bool IsLagFrame { get { return true; } } + + public void ResetCounters() + { + Frame = 0; + LagCount = 0; + } + + public string SystemId { get { return "SNES"; } } + public bool DeterministicEmulation { get { return true; } } + public string BoardName { get { return null; } } + public CoreComm CoreComm { get; private set; } + + #region saveram + + public byte[] ReadSaveRam() + { + return new byte[0]; + } + + public void StoreSaveRam(byte[] data) + { + } + + public void ClearSaveRam() + { + } + + public bool SaveRamModified + { + get + { + return false; + } + set + { + throw new NotImplementedException(); + } + } + + #endregion + + #region savestates + + public void SaveStateText(System.IO.TextWriter writer) + { + } + + public void LoadStateText(System.IO.TextReader reader) + { + } + + public void SaveStateBinary(System.IO.BinaryWriter writer) + { + } + + public void LoadStateBinary(System.IO.BinaryReader reader) + { + } + + public byte[] SaveStateBinary() + { + return new byte[0]; + } + + public bool BinarySaveStatesPreferred { get { return true; } } + + #endregion + + #region debugging + + public MemoryDomainList MemoryDomains + { + get { throw new NotImplementedException(); } + } + + public Dictionary GetCpuFlagsAndRegisters() + { + throw new NotImplementedException(); + } + + public void SetCpuRegister(string register, int value) + { + throw new NotImplementedException(); + } + + #endregion + + #region settings + + public object GetSettings() + { + return null; + } + + public object GetSyncSettings() + { + return null; + } + + public bool PutSettings(object o) + { + return false; + } + + public bool PutSyncSettings(object o) + { + return false; + } + + #endregion + + #region IVideoProvider + + private int[] _vbuff = new int[512 * 480]; + public IVideoProvider VideoProvider { get { return this; } } + public int[] GetVideoBuffer() { return _vbuff; } + public int VirtualWidth + { get { return BufferWidth; } } + public int VirtualHeight { get { return BufferHeight; } } + public int BufferWidth { get { return 256; } } + public int BufferHeight { get { return 224; } } + public int BackgroundColor { get { return unchecked((int)0xff000000); } } + + #endregion + + #region ISyncSoundProvider + + private short[] _sbuff = new short[2048]; + 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) + { + samples = _sbuff; + nsamp = 735; + } + + public void DiscardSamples() + { + } + + #endregion + } +}