diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs
index a4484202f8..3984667641 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs
@@ -12,487 +12,11 @@ using System.Linq;
using System.Diagnostics;
using System.Globalization;
using System.IO;
-using System.IO.Pipes;
using System.Collections.Generic;
using System.Runtime.InteropServices;
-using System.IO.MemoryMappedFiles;
namespace BizHawk.Emulation.Consoles.Nintendo.SNES
{
- public unsafe class LibsnesApi : IDisposable
- {
- //this wouldve been the ideal situation to learn protocol buffers, but since the number of messages here is so limited, it took less time to roll it by hand.
- //todo - could optimize a lot of the apis once we decide to commit to this. will we? then we wont be able to debug bsnes as well
- // well, we could refactor it a lot and let the debuggable static dll version be the one that does annoying workarounds
- //todo - more intelligent use of buffers to avoid so many copies (especially framebuffer from bsnes? supply framebuffer to-be-used to libsnes? same for audiobuffer)
- //todo - refactor to use a smarter set of pipe reader and pipe writer classes
- //todo - combine messages / tracecallbacks into one system with a channel number enum additionally
- //todo - consider refactoring bsnes to allocate memory blocks through the interface, and set ours up to allocate from a large arena of shared memory.
- // this is a lot of work, but it will be some decent speedups. who wouldve ever thought to make an emulator this way? I will, from now on...
- //todo - use a reader/writer ring buffer for communication instead of pipe
- //todo - when exe wrapper is fully baked, put it into mingw so we can just have libsneshawk.exe without a separate dll. it hardly needs any debugging presently, it should be easy to maintain.
-
- Process process;
- NamedPipeServerStream pipe;
- BinaryWriter bwPipe;
- BinaryReader brPipe;
- MemoryMappedFile mmf;
- MemoryMappedViewAccessor mmva;
- byte* mmvaPtr;
-
- public enum eMessage : int
- {
- eMessage_Complete,
-
- eMessage_snes_library_id,
- eMessage_snes_library_revision_major,
- eMessage_snes_library_revision_minor,
-
- eMessage_snes_init,
- eMessage_snes_power,
- eMessage_snes_reset,
- eMessage_snes_run,
- eMessage_snes_term,
- eMessage_snes_unload_cartridge,
-
- //snes_set_cartridge_basename, //not used
-
- eMessage_snes_load_cartridge_normal,
-
- //incoming from bsnes
- eMessage_snes_cb_video_refresh,
- eMessage_snes_cb_input_poll,
- eMessage_snes_cb_input_state,
- eMessage_snes_cb_input_notify,
- eMessage_snes_cb_audio_sample,
- eMessage_snes_cb_scanlineStart,
- eMessage_snes_cb_path_request,
- eMessage_snes_cb_trace_callback,
-
- eMessage_snes_get_region,
-
- eMessage_snes_get_memory_size,
- eMessage_snes_get_memory_data,
- eMessage_peek,
- eMessage_poke,
-
- eMessage_snes_serialize_size,
-
- eMessage_snes_serialize,
- eMessage_snes_unserialize,
-
- eMessage_snes_poll_message,
- eMessage_snes_dequeue_message,
-
- eMessage_snes_set_color_lut,
-
- eMessage_snes_enable_trace,
- eMessage_snes_enable_scanline,
- eMessage_snes_enable_audio,
- eMessage_snes_set_layer_enable,
- eMessage_snes_set_backdropColor,
- eMessage_snes_peek_logical_register
- };
-
- static bool DryRun(string exePath)
- {
- ProcessStartInfo oInfo = new ProcessStartInfo(exePath, "Bongizong");
- oInfo.WorkingDirectory = Path.GetDirectoryName(exePath);
- oInfo.UseShellExecute = false;
- oInfo.CreateNoWindow = true;
- oInfo.RedirectStandardOutput = true;
- oInfo.RedirectStandardError = true;
-
- Process proc = System.Diagnostics.Process.Start(oInfo);
- string result = proc.StandardError.ReadToEnd();
- proc.WaitForExit();
-
- if (result == "Honga Wongkong" && proc.ExitCode == 0x16817)
- return true;
-
- return false;
- }
-
- static bool Initialized;
- static string exePath;
-
- void StaticInit()
- {
- if (Initialized) return;
-
- string thisDir = System.Reflection.Assembly.GetExecutingAssembly().GetDirectory();
- exePath = Path.Combine(thisDir, "libsnes_pwrap.exe");
- if (!File.Exists(exePath))
- exePath = Path.Combine(Path.Combine(thisDir, "dll"), "libsnes_pwrap.exe");
-
- if (!File.Exists(exePath))
- throw new InvalidOperationException("Can't find libsnes_pwrap.exe to run libsneshawk core");
-
- if (!DryRun(exePath))
- {
- throw new InvalidOperationException("Can't launch libsnes_pwrap.exe to run libsneshawk core. Missing a libsneshawk.dll?");
- }
-
- Initialized = true;
- }
-
- public LibsnesApi()
- {
- StaticInit();
-
- var pipeName = "libsnespwrap_" + Guid.NewGuid().ToString();
-
- mmf = MemoryMappedFile.CreateNew(pipeName, 1024 * 1024);
- mmva = mmf.CreateViewAccessor();
- mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref mmvaPtr);
-
- pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None, 1024 * 1024, 1024);
-
- process = new Process();
- process.StartInfo.WorkingDirectory = Path.GetDirectoryName(exePath);
- process.StartInfo.FileName = exePath;
- process.StartInfo.Arguments = pipeName;
- process.StartInfo.ErrorDialog = true;
- process.Start();
-
- //TODO - start a thread to wait for process to exit and gracefully handle errors? how about the pipe?
-
- pipe.WaitForConnection();
- bwPipe = new BinaryWriter(pipe);
- brPipe = new BinaryReader(pipe);
- }
-
- public void Dispose()
- {
- process.Kill();
- process.Dispose();
- process = null;
- pipe.Dispose();
- mmva.Dispose();
- mmf.Dispose();
- }
-
- void WritePipeString(string str)
- {
- WritePipeBlob(System.Text.Encoding.ASCII.GetBytes(str));
- }
-
- byte[] ReadPipeBlob()
- {
- int len = brPipe.ReadInt32();
- var ret = new byte[len];
- brPipe.Read(ret, 0, len);
- return ret;
- }
-
- void WritePipeBlob(byte[] blob)
- {
- bwPipe.Write(blob.Length);
- bwPipe.Write(blob);
- }
-
- public int MessageCounter;
-
- void WritePipeMessage(eMessage msg)
- {
- MessageCounter++;
- bwPipe.Write((int)msg);
- }
-
- eMessage ReadPipeMessage()
- {
- return (eMessage)brPipe.ReadInt32();
- }
-
- public string snes_library_id()
- {
- WritePipeMessage(eMessage.eMessage_snes_library_id);
- return brPipe.ReadStringAsciiZ();
- }
-
-
- public uint snes_library_revision_major()
- {
- WritePipeMessage(eMessage.eMessage_snes_library_revision_major);
- return brPipe.ReadUInt32();
- }
-
- public uint snes_library_revision_minor()
- {
- WritePipeMessage(eMessage.eMessage_snes_library_revision_minor);
- return brPipe.ReadUInt32();
- }
-
- public void snes_init() { WritePipeMessage(eMessage.eMessage_snes_init); }
- public void snes_power() { WritePipeMessage(eMessage.eMessage_snes_power); }
- public void snes_reset() { WritePipeMessage(eMessage.eMessage_snes_reset); }
- public void snes_run()
- {
- WritePipeMessage(eMessage.eMessage_snes_run);
- WaitForCompletion();
- }
- public void snes_term() { WritePipeMessage(eMessage.eMessage_snes_term); }
- public void snes_unload_cartridge() { WritePipeMessage(eMessage.eMessage_snes_unload_cartridge); }
-
-
- public bool snes_load_cartridge_normal(string rom_xml, byte[] rom_data)
- {
- WritePipeMessage(eMessage.eMessage_snes_load_cartridge_normal);
- WritePipeString(rom_xml ?? "");
- WritePipeBlob(rom_data);
- WaitForCompletion();
- return brPipe.ReadBoolean();
- }
-
- public LibsnesDll.SNES_REGION snes_get_region()
- {
- WritePipeMessage(eMessage.eMessage_snes_get_region);
- return (LibsnesDll.SNES_REGION)brPipe.ReadByte();
- }
-
- public int snes_get_memory_size(LibsnesDll.SNES_MEMORY id)
- {
- WritePipeMessage(eMessage.eMessage_snes_get_memory_size);
- bwPipe.Write((int)id);
- return brPipe.ReadInt32();
- }
- public byte[] snes_get_memory_data(LibsnesDll.SNES_MEMORY id)
- {
- int size = snes_get_memory_size(id);
- WritePipeMessage(eMessage.eMessage_snes_get_memory_data);
- bwPipe.Write((int)id);
- bwPipe.Write(0);
- var ret = new byte[size];
- WaitForCompletion();
- Marshal.Copy(new IntPtr(mmvaPtr), ret, 0, size);
- return ret;
- }
-
- public byte peek(LibsnesDll.SNES_MEMORY id, uint addr)
- {
- WritePipeMessage(eMessage.eMessage_peek);
- bwPipe.Write((uint)id);
- bwPipe.Write(addr);
- return brPipe.ReadByte();
- }
- public void poke(LibsnesDll.SNES_MEMORY id, uint addr, byte val)
- {
- WritePipeMessage(eMessage.eMessage_poke);
- bwPipe.Write((uint)id);
- bwPipe.Write(addr);
- bwPipe.Write(val);
- }
-
- public int snes_serialize_size()
- {
- WritePipeMessage(eMessage.eMessage_snes_serialize_size);
- return brPipe.ReadInt32();
- }
-
- [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
- public static unsafe extern void* CopyMemory(void* dest, void* src, ulong count);
-
-
-
- public bool snes_serialize(IntPtr data, int size)
- {
- WritePipeMessage(eMessage.eMessage_snes_serialize);
- bwPipe.Write(size);
- bwPipe.Write(0); //mapped memory location to serialize to
- WaitForCompletion(); //serialize/unserialize can cause traces to get called (because serialize can cause execution?)
- bool ret = brPipe.ReadBoolean();
- if(ret)
- {
- CopyMemory(data.ToPointer(), mmvaPtr, (ulong)size);
- }
- return ret;
- }
-
- public bool snes_unserialize(IntPtr data, int size)
- {
- WritePipeMessage(eMessage.eMessage_snes_unserialize);
- CopyMemory(mmvaPtr, data.ToPointer(), (ulong)size);
- bwPipe.Write(size);
- bwPipe.Write(0); //mapped memory location to serialize from
- WaitForCompletion(); //serialize/unserialize can cause traces to get called (because serialize can cause execution?)
- bool ret = brPipe.ReadBoolean();
- return ret;
- }
-
- int snes_poll_message()
- {
- WritePipeMessage(eMessage.eMessage_snes_poll_message);
- return brPipe.ReadInt32();
- }
-
- public bool HasMessage { get { return snes_poll_message() != -1; } }
-
-
- public string DequeueMessage()
- {
- WritePipeMessage(eMessage.eMessage_snes_dequeue_message);
- return brPipe.ReadStringAsciiZ();
- }
-
- public void snes_set_color_lut(IntPtr colors)
- {
- int len = 4 * 16 * 32768;
- byte[] buf = new byte[len];
- Marshal.Copy(colors, buf, 0, len);
-
- WritePipeMessage(eMessage.eMessage_snes_set_color_lut);
- WritePipeBlob(buf);
- }
-
- public void snes_set_layer_enable(int layer, int priority, bool enable)
- {
- WritePipeMessage(eMessage.eMessage_snes_set_layer_enable);
- bwPipe.Write(layer);
- bwPipe.Write(priority);
- bwPipe.Write(enable);
- }
-
- public void snes_set_backdropColor(int backdropColor)
- {
- WritePipeMessage(eMessage.eMessage_snes_set_backdropColor);
- bwPipe.Write(backdropColor);
- }
-
- public int snes_peek_logical_register(LibsnesDll.SNES_REG reg)
- {
- WritePipeMessage(eMessage.eMessage_snes_peek_logical_register);
- bwPipe.Write((int)reg);
- return brPipe.ReadInt32();
- }
-
- void WaitForCompletion()
- {
- for (; ; )
- {
- var msg = ReadPipeMessage();
- MessageCounter++;
- switch (msg)
- {
- case eMessage.eMessage_Complete:
- return;
-
- case eMessage.eMessage_snes_cb_video_refresh:
- {
- int width = brPipe.ReadInt32();
- int height = brPipe.ReadInt32();
- bwPipe.Write(0); //offset in mapped memory buffer
- brPipe.ReadBoolean(); //dummy synchronization
- if (video_refresh != null)
- {
- video_refresh((int*)mmvaPtr, width, height);
- }
- break;
- }
- case eMessage.eMessage_snes_cb_input_poll:
- break;
- case eMessage.eMessage_snes_cb_input_state:
- {
- int port = brPipe.ReadInt32();
- int device = brPipe.ReadInt32();
- int index = brPipe.ReadInt32();
- int id = brPipe.ReadInt32();
- ushort ret = 0;
- if (input_state != null)
- ret = input_state(port, device, index, id);
- bwPipe.Write(ret);
- break;
- }
- case eMessage.eMessage_snes_cb_input_notify:
- {
- int index = brPipe.ReadInt32();
- if (input_notify != null)
- input_notify(index);
- break;
- }
- case eMessage.eMessage_snes_cb_audio_sample:
- {
- int nsamples = brPipe.ReadInt32();
- bwPipe.Write(0); //location to store audio buffer in
- brPipe.ReadInt32(); //dummy synchronization
-
- if (audio_sample != null)
- {
- ushort* audiobuffer = ((ushort*)mmvaPtr);
- for (int i = 0; i < nsamples;)
- {
- ushort left = audiobuffer[i++];
- ushort right = audiobuffer[i++];
- audio_sample(left, right);
- }
- }
-
- bwPipe.Write(0); //dummy synchronization
- brPipe.ReadInt32(); //dummy synchronization
- break;
- }
- case eMessage.eMessage_snes_cb_scanlineStart:
- {
- int line = brPipe.ReadInt32();
- if (scanlineStart != null)
- scanlineStart(line);
- break;
- }
- case eMessage.eMessage_snes_cb_path_request:
- {
- int slot = brPipe.ReadInt32();
- string hint = brPipe.ReadStringAsciiZ();
- string ret = hint;
- if(pathRequest != null)
- hint = pathRequest(slot, hint);
- WritePipeString(hint);
- break;
- }
- case eMessage.eMessage_snes_cb_trace_callback:
- {
- var trace = brPipe.ReadStringAsciiZ();
- if (traceCallback != null)
- traceCallback(trace);
- break;
- }
- }
- }
- }
-
-
- LibsnesDll.snes_video_refresh_t video_refresh;
- LibsnesDll.snes_input_poll_t input_poll;
- LibsnesDll.snes_input_state_t input_state;
- LibsnesDll.snes_input_notify_t input_notify;
- LibsnesDll.snes_audio_sample_t audio_sample;
- LibsnesDll.snes_scanlineStart_t scanlineStart;
- LibsnesDll.snes_path_request_t pathRequest;
- LibsnesDll.snes_trace_t traceCallback;
-
- public void snes_set_video_refresh(LibsnesDll.snes_video_refresh_t video_refresh) { this.video_refresh = video_refresh; }
- public void snes_set_input_poll(LibsnesDll.snes_input_poll_t input_poll) { this.input_poll = input_poll; }
- public void snes_set_input_state(LibsnesDll.snes_input_state_t input_state) { this.input_state = input_state; }
- public void snes_set_input_notify(LibsnesDll.snes_input_notify_t input_notify) { this.input_notify = input_notify; }
- public void snes_set_audio_sample(LibsnesDll.snes_audio_sample_t audio_sample)
- {
- this.audio_sample = audio_sample;
- WritePipeMessage(eMessage.eMessage_snes_enable_audio);
- bwPipe.Write(audio_sample != null);
- }
- public void snes_set_path_request(LibsnesDll.snes_path_request_t pathRequest) { this.pathRequest = pathRequest; }
- public void snes_set_scanlineStart(LibsnesDll.snes_scanlineStart_t scanlineStart)
- {
- this.scanlineStart = scanlineStart;
- WritePipeMessage(eMessage.eMessage_snes_enable_scanline);
- bwPipe.Write(scanlineStart != null);
- }
- public void snes_set_trace_callback(LibsnesDll.snes_trace_t callback)
- {
- this.traceCallback = callback;
- WritePipeMessage(eMessage.eMessage_snes_enable_trace);
- bwPipe.Write(callback != null);
- }
- }
-
public unsafe static class LibsnesDll
{
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
@@ -571,7 +95,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void snes_set_scanlineStart(snes_scanlineStart_t scanlineStart);
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void snes_set_path_request(snes_path_request_t pathRequest);
+ public static extern void snes_set_path_request(snes_path_request_t scanlineStart);
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
@@ -741,9 +265,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
VRAM = 102,
OAM = 103,
CGRAM = 104,
-
- SYSBUS = 200,
- LOGICAL_REGS = 201
}
public enum SNES_REGION : byte
@@ -833,11 +354,16 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
disposedSaveRam = ReadSaveRam();
- api.snes_unload_cartridge();
- api.snes_term();
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_video_refresh(null);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_poll(null);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_state(null);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_audio_sample(null);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_scanlineStart(null);
+
+ LibsnesDll.snes_unload_cartridge();
+ LibsnesDll.snes_term();
resampler.Dispose();
- api.Dispose();
}
//save the save memory before disposing the core, so we can pull from it in the future after the core is terminated
//that will be necessary to get it saving to disk
@@ -864,8 +390,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
void OnScanlineHooksChanged()
{
if (disposed) return;
- if (ScanlineHookManager.HookCount == 0) api.snes_set_scanlineStart(null);
- else api.snes_set_scanlineStart(scanlineStart_cb);
+ if (ScanlineHookManager.HookCount == 0) LibsnesDll.snes_set_scanlineStart(null);
+ else LibsnesDll.snes_set_scanlineStart(scanlineStart_cb);
}
void snes_scanlineStart(int line)
@@ -906,16 +432,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
CurrPalette = pal;
int[] tmp = SnesColors.GetLUT(pal);
fixed (int* p = &tmp[0])
- api.snes_set_color_lut((IntPtr)p);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_color_lut((IntPtr)p);
}
- public LibsnesApi api;
-
public LibsnesCore(CoreComm comm)
{
CoreComm = comm;
- api = new LibsnesApi();
- api.snes_init();
}
public void Load(GameInfo game, byte[] romData, byte[] sgbRomData, bool DeterministicEmulation)
@@ -927,25 +449,27 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
ScanlineHookManager = new MyScanlineHookManager(this);
- api.snes_init();
+ LibsnesDll.snes_init();
+
+ //LibsnesDll.snes_set_cartridge_basename(@);
vidcb = new LibsnesDll.snes_video_refresh_t(snes_video_refresh);
- api.snes_set_video_refresh(vidcb);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_video_refresh(vidcb);
pollcb = new LibsnesDll.snes_input_poll_t(snes_input_poll);
- api.snes_set_input_poll(pollcb);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_poll(pollcb);
inputcb = new LibsnesDll.snes_input_state_t(snes_input_state);
- api.snes_set_input_state(inputcb);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_state(inputcb);
notifycb = new LibsnesDll.snes_input_notify_t(snes_input_notify);
- api.snes_set_input_notify(notifycb);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_notify(notifycb);
soundcb = new LibsnesDll.snes_audio_sample_t(snes_audio_sample);
- api.snes_set_audio_sample(soundcb);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_audio_sample(soundcb);
pathRequest_cb = new LibsnesDll.snes_path_request_t(snes_path_request);
- api.snes_set_path_request(pathRequest_cb);
+ BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_path_request(pathRequest_cb);
scanlineStart_cb = new LibsnesDll.snes_scanlineStart_t(snes_scanlineStart);
@@ -976,11 +500,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
else
{
SystemId = "SNES";
- if (!api.snes_load_cartridge_normal(null, romData))
+ if (!LibsnesDll.snes_load_cartridge_normal(null, romData, (uint)romData.Length))
throw new Exception("snes_load_cartridge_normal() failed");
}
- if (api.snes_get_region() == LibsnesDll.SNES_REGION.NTSC)
+ if (LibsnesDll.snes_get_region() == LibsnesDll.SNES_REGION.NTSC)
{
//similar to what aviout reports from snes9x and seems logical from bsnes first principles. bsnes uses that numerator (ntsc master clockrate) for sure.
CoreComm.VsyncNum = 21477272;
@@ -994,7 +518,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
CoreComm.CpuTraceAvailable = true;
- api.snes_power();
+ LibsnesDll.snes_power();
SetupMemoryDomains(romData);
@@ -1125,8 +649,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public void FrameAdvance(bool render, bool rendersound)
{
- api.MessageCounter = 0;
-
// for deterministic emulation, save the state we're going to use before frame advance
// don't do this during nocallbacks though, since it's already been done
if (!nocallbacks && DeterministicEmulation)
@@ -1143,58 +665,55 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
}
if (!nocallbacks && CoreComm.Tracer.Enabled)
- api.snes_set_trace_callback(tracecb);
+ LibsnesDll.snes_set_trace_callback(tracecb);
else
- api.snes_set_trace_callback(null);
+ LibsnesDll.snes_set_trace_callback(null);
// speedup when sound rendering is not needed
if (!rendersound)
- api.snes_set_audio_sample(null);
+ LibsnesDll.snes_set_audio_sample(null);
else
- api.snes_set_audio_sample(soundcb);
+ LibsnesDll.snes_set_audio_sample(soundcb);
bool resetSignal = Controller["Reset"];
- if (resetSignal) api.snes_reset();
+ if (resetSignal) LibsnesDll.snes_reset();
bool powerSignal = Controller["Power"];
- if (powerSignal) api.snes_power();
+ if (powerSignal) LibsnesDll.snes_power();
- //too many messages
- api.snes_set_layer_enable(0, 0, CoreComm.SNES_ShowBG1_0);
- api.snes_set_layer_enable(0, 1, CoreComm.SNES_ShowBG1_1);
- api.snes_set_layer_enable(1, 0, CoreComm.SNES_ShowBG2_0);
- api.snes_set_layer_enable(1, 1, CoreComm.SNES_ShowBG2_1);
- api.snes_set_layer_enable(2, 0, CoreComm.SNES_ShowBG3_0);
- api.snes_set_layer_enable(2, 1, CoreComm.SNES_ShowBG3_1);
- api.snes_set_layer_enable(3, 0, CoreComm.SNES_ShowBG4_0);
- api.snes_set_layer_enable(3, 1, CoreComm.SNES_ShowBG4_1);
- api.snes_set_layer_enable(4, 0, CoreComm.SNES_ShowOBJ_0);
- api.snes_set_layer_enable(4, 1, CoreComm.SNES_ShowOBJ_1);
- api.snes_set_layer_enable(4, 2, CoreComm.SNES_ShowOBJ_2);
- api.snes_set_layer_enable(4, 3, CoreComm.SNES_ShowOBJ_3);
+ LibsnesDll.snes_set_layer_enable(0, 0, CoreComm.SNES_ShowBG1_0);
+ LibsnesDll.snes_set_layer_enable(0, 1, CoreComm.SNES_ShowBG1_1);
+ LibsnesDll.snes_set_layer_enable(1, 0, CoreComm.SNES_ShowBG2_0);
+ LibsnesDll.snes_set_layer_enable(1, 1, CoreComm.SNES_ShowBG2_1);
+ LibsnesDll.snes_set_layer_enable(2, 0, CoreComm.SNES_ShowBG3_0);
+ LibsnesDll.snes_set_layer_enable(2, 1, CoreComm.SNES_ShowBG3_1);
+ LibsnesDll.snes_set_layer_enable(3, 0, CoreComm.SNES_ShowBG4_0);
+ LibsnesDll.snes_set_layer_enable(3, 1, CoreComm.SNES_ShowBG4_1);
+ LibsnesDll.snes_set_layer_enable(4, 0, CoreComm.SNES_ShowOBJ_0);
+ LibsnesDll.snes_set_layer_enable(4, 1, CoreComm.SNES_ShowOBJ_1);
+ LibsnesDll.snes_set_layer_enable(4, 2, CoreComm.SNES_ShowOBJ_2);
+ LibsnesDll.snes_set_layer_enable(4, 3, CoreComm.SNES_ShowOBJ_3);
// if the input poll callback is called, it will set this to false
IsLagFrame = true;
//apparently this is one frame?
timeFrameCounter++;
- api.snes_run();
+ LibsnesDll.snes_run();
- while (api.HasMessage)
- Console.WriteLine(api.DequeueMessage());
+ while (LibsnesDll.HasMessage)
+ Console.WriteLine(LibsnesDll.DequeueMessage());
if (IsLagFrame)
LagCount++;
- //diagnostics for IPC traffic
- //Console.WriteLine(api.MessageCounter);
}
public DisplayType DisplayType
{
get
{
- if (api.snes_get_region() == LibsnesDll.SNES_REGION.NTSC)
+ if (LibsnesDll.snes_get_region() == LibsnesDll.SNES_REGION.NTSC)
return BizHawk.DisplayType.NTSC;
else
return BizHawk.DisplayType.PAL;
@@ -1420,7 +939,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
}
public void LoadStateBinary(BinaryReader reader)
{
- int size = api.snes_serialize_size();
+ int size = LibsnesDll.snes_serialize_size();
byte[] buf = reader.ReadBytes(size);
CoreLoadState(buf);
@@ -1471,22 +990,22 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
///
void CoreLoadState(byte[] data)
{
- int size = api.snes_serialize_size();
+ int size = LibsnesDll.snes_serialize_size();
if (data.Length != size)
throw new Exception("Libsnes internal savestate size mismatch!");
- api.snes_init();
+ LibsnesDll.snes_init();
fixed (byte* pbuf = &data[0])
- api.snes_unserialize(new IntPtr(pbuf), size);
+ LibsnesDll.snes_unserialize(new IntPtr(pbuf), size);
}
///
/// handle the unmanaged part of savestating
///
byte[] CoreSaveState()
{
- int size = api.snes_serialize_size();
+ int size = LibsnesDll.snes_serialize_size();
byte[] buf = new byte[size];
fixed (byte* pbuf = &buf[0])
- api.snes_serialize(new IntPtr(pbuf), size);
+ LibsnesDll.snes_serialize(new IntPtr(pbuf), size);
return buf;
}
@@ -1502,50 +1021,36 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
// ----- Client Debugging API stuff -----
unsafe MemoryDomain MakeMemoryDomain(string name, LibsnesDll.SNES_MEMORY id, Endian endian)
{
- int size = api.snes_get_memory_size(id);
+ IntPtr block = LibsnesDll.snes_get_memory_data(id);
+ int size = LibsnesDll.snes_get_memory_size(id);
int mask = size - 1;
+ byte* blockptr = (byte*)block.ToPointer();
MemoryDomain md;
- ////have to bitmask these somehow because it's unmanaged memory and we would hate to clobber things or make them nondeterministic
- //if (Util.IsPowerOfTwo(size))
- //{
- // //can &mask for speed
- // md = new MemoryDomain(name, size, endian,
- // (addr) => blockptr[addr & mask],
- // (addr, value) => blockptr[addr & mask] = value);
- //}
- //else
- //{
- // //have to use % (only OAM needs this, it seems)
- // //(OAM is actually two differently sized banks of memory which arent truly considered adjacent. maybe a better way to visualize it would be with an empty bus and adjacent banks)
- // md = new MemoryDomain(name, size, endian,
- // (addr) => blockptr[addr % size],
- // (addr, value) => blockptr[addr % size] = value);
- //}
-
- //EXTERNAL PROCESS CONVERSION: MUST MAKE THIS SAFE
- //speed it up later
+ //have to bitmask these somehow because it's unmanaged memory and we would hate to clobber things or make them nondeterministic
if (Util.IsPowerOfTwo(size))
{
//can &mask for speed
md = new MemoryDomain(name, size, endian,
- (addr) => api.peek(id, (uint)(addr & mask)),
- (addr, value) => api.poke(id, (uint)(addr & mask), value));
+ (addr) => blockptr[addr & mask],
+ (addr, value) => blockptr[addr & mask] = value);
}
else
{
//have to use % (only OAM needs this, it seems)
- //(OAM is actually two differently sized banks of memory which arent truly considered adjacent. maybe a better way to visualize it would be with an empty bus and adjacent banks)
md = new MemoryDomain(name, size, endian,
- (addr) => api.peek(id, (uint)(addr % size)),
- (addr, value) => api.poke(id, (uint)(addr % size), value));
+ (addr) => blockptr[addr % size],
+ (addr, value) => blockptr[addr % size] = value);
}
MemoryDomains.Add(md);
return md;
-
+ //doesnt cache the addresses. safer. slower. necessary? don't know
+ //return new MemoryDomain(name, size, endian,
+ // (addr) => Peek(LibsnesDll.SNES_MEMORY.WRAM, addr & mask),
+ // (addr, value) => Poke(LibsnesDll.SNES_MEMORY.WRAM, addr & mask, value));
}
void SetupMemoryDomains(byte[] romData)
@@ -1566,8 +1071,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
if (!DeterministicEmulation)
MemoryDomains.Add(new MemoryDomain("BUS", 0x1000000, Endian.Little,
- (addr) => api.peek(LibsnesDll.SNES_MEMORY.SYSBUS, (uint)addr),
- (addr, val) => api.poke(LibsnesDll.SNES_MEMORY.SYSBUS, (uint)addr, val)));
+ (addr) => LibsnesDll.bus_read((uint)addr),
+ (addr, val) => LibsnesDll.bus_write((uint)addr, val)));
}
public IList MemoryDomains { get; private set; }
public MemoryDomain MainMemory { get; private set; }
diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs
index 7953a7bee4..43404a382e 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs
@@ -10,14 +10,14 @@ using System.Linq;
using System.Diagnostics;
using System.Globalization;
using System.IO;
-using System.Runtime.InteropServices;
using System.Collections.Generic;
namespace BizHawk.Emulation.Consoles.Nintendo.SNES
{
- public unsafe class SNESGraphicsDecoder : IDisposable
+ public unsafe class SNESGraphicsDecoder
{
+
public class PaletteSelection
{
public PaletteSelection() { }
@@ -332,15 +332,15 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public bool M7SEL_HFLIP { private set; get; }
public bool M7SEL_VFLIP { private set; get; }
- public static ScreenInfo GetScreenInfo(LibsnesApi api)
+ public static ScreenInfo GetScreenInfo()
{
var si = new ScreenInfo();
- si.Mode1_BG3_Priority = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_PRIORITY) == 1;
+ si.Mode1_BG3_Priority = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_PRIORITY) == 1;
- si.OBSEL_Size = api.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_SIZE);
- si.OBSEL_NameSel = api.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_NAMESEL);
- si.OBSEL_NameBase = api.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_NAMEBASE);
+ si.OBSEL_Size = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_SIZE);
+ si.OBSEL_NameSel = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_NAMESEL);
+ si.OBSEL_NameBase = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_NAMEBASE);
si.ObjSizeBounds = ObjSizes[si.OBSEL_Size,1];
int square = Math.Max(si.ObjSizeBounds.Width, si.ObjSizeBounds.Height);
@@ -350,26 +350,26 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
si.OBJTable0Addr = si.OBSEL_NameBase << 14;
si.OBJTable1Addr = (si.OBJTable0Addr + ((si.OBSEL_NameSel + 1) << 13)) & 0xFFFF;
- si.SETINI_Mode7ExtBG = api.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_MODE7_EXTBG) == 1;
- si.SETINI_HiRes = api.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_HIRES) == 1;
- si.SETINI_Overscan = api.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_OVERSCAN) == 1;
- si.SETINI_ObjInterlace = api.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_OBJ_INTERLACE) == 1;
- si.SETINI_ScreenInterlace = api.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_SCREEN_INTERLACE) == 1;
+ si.SETINI_Mode7ExtBG = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_MODE7_EXTBG) == 1;
+ si.SETINI_HiRes = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_HIRES) == 1;
+ si.SETINI_Overscan = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_OVERSCAN) == 1;
+ si.SETINI_ObjInterlace = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_OBJ_INTERLACE) == 1;
+ si.SETINI_ScreenInterlace = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_SCREEN_INTERLACE) == 1;
- si.CGWSEL_ColorMask = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGWSEL_COLORMASK);
- si.CGWSEL_ColorSubMask = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGWSEL_COLORSUBMASK);
- si.CGWSEL_AddSubMode = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGWSEL_ADDSUBMODE);
- si.CGWSEL_DirectColor = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGWSEL_DIRECTCOLOR) == 1;
+ si.CGWSEL_ColorMask = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGWSEL_COLORMASK);
+ si.CGWSEL_ColorSubMask = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGWSEL_COLORSUBMASK);
+ si.CGWSEL_AddSubMode = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGWSEL_ADDSUBMODE);
+ si.CGWSEL_DirectColor = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGWSEL_DIRECTCOLOR) == 1;
- si.CGADSUB_AddSub = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_MODE);
- si.CGADSUB_Half = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_HALF) == 1;
+ si.CGADSUB_AddSub = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_MODE);
+ si.CGADSUB_Half = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_HALF) == 1;
- si.OBJ_MainEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_OBJ) == 1;
- si.OBJ_SubEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_OBJ) == 1;
- si.OBJ_MathEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_OBJ) == 1;
- si.BK_MathEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BACKDROP) == 1;
+ si.OBJ_MainEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_OBJ) == 1;
+ si.OBJ_SubEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_OBJ) == 1;
+ si.OBJ_MathEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_OBJ) == 1;
+ si.BK_MathEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BACKDROP) == 1;
- si.Mode.MODE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG_MODE);
+ si.Mode.MODE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG_MODE);
si.BG.BG1.Bpp = ModeBpps[si.Mode.MODE, 0];
si.BG.BG2.Bpp = ModeBpps[si.Mode.MODE, 1];
si.BG.BG3.Bpp = ModeBpps[si.Mode.MODE, 2];
@@ -379,58 +379,58 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
for(int i=1;i<=4;i++)
si.BG[i].BGMode = si.BG[i].Bpp == 0 ? BGMode.Unavailable : BGMode.Text;
- si.BG.BG1.TILESIZE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TILESIZE);
- si.BG.BG2.TILESIZE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TILESIZE);
- si.BG.BG3.TILESIZE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_TILESIZE);
- si.BG.BG4.TILESIZE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_TILESIZE);
+ si.BG.BG1.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TILESIZE);
+ si.BG.BG2.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TILESIZE);
+ si.BG.BG3.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_TILESIZE);
+ si.BG.BG4.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_TILESIZE);
- si.BG.BG1.SCSIZE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_SCSIZE);
- si.BG.BG2.SCSIZE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_SCSIZE);
- si.BG.BG3.SCSIZE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_SCSIZE);
- si.BG.BG4.SCSIZE = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_SCSIZE);
- si.BG.BG1.SCADDR = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_SCADDR);
- si.BG.BG2.SCADDR = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_SCADDR);
- si.BG.BG3.SCADDR = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_SCADDR);
- si.BG.BG4.SCADDR = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_SCADDR);
- si.BG.BG1.TDADDR = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TDADDR);
- si.BG.BG2.TDADDR = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TDADDR);
- si.BG.BG3.TDADDR = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_TDADDR);
- si.BG.BG4.TDADDR = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_TDADDR);
+ si.BG.BG1.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_SCSIZE);
+ si.BG.BG2.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_SCSIZE);
+ si.BG.BG3.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_SCSIZE);
+ si.BG.BG4.SCSIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_SCSIZE);
+ si.BG.BG1.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_SCADDR);
+ si.BG.BG2.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_SCADDR);
+ si.BG.BG3.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_SCADDR);
+ si.BG.BG4.SCADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_SCADDR);
+ si.BG.BG1.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TDADDR);
+ si.BG.BG2.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TDADDR);
+ si.BG.BG3.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3_TDADDR);
+ si.BG.BG4.TDADDR = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4_TDADDR);
- si.BG.BG1.MainEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_BG1) == 1;
- si.BG.BG2.MainEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_BG2) == 1;
- si.BG.BG3.MainEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_BG3) == 1;
- si.BG.BG4.MainEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_BG4) == 1;
- si.BG.BG1.SubEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_BG1) == 1;
- si.BG.BG2.SubEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_BG2) == 1;
- si.BG.BG3.SubEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_BG3) == 1;
- si.BG.BG4.SubEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_BG4) == 1;
- si.BG.BG1.MathEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG1) == 1;
- si.BG.BG2.MathEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG2) == 1;
- si.BG.BG3.MathEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG3) == 1;
- si.BG.BG4.MathEnabled = api.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG4) == 1;
+ si.BG.BG1.MainEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_BG1) == 1;
+ si.BG.BG2.MainEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_BG2) == 1;
+ si.BG.BG3.MainEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_BG3) == 1;
+ si.BG.BG4.MainEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TM_BG4) == 1;
+ si.BG.BG1.SubEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_BG1) == 1;
+ si.BG.BG2.SubEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_BG2) == 1;
+ si.BG.BG3.SubEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_BG3) == 1;
+ si.BG.BG4.SubEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.TS_BG4) == 1;
+ si.BG.BG1.MathEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG1) == 1;
+ si.BG.BG2.MathEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG2) == 1;
+ si.BG.BG3.MathEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG3) == 1;
+ si.BG.BG4.MathEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG4) == 1;
- si.BG.BG1.HOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1HOFS);
- si.BG.BG1.VOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1VOFS);
- si.BG.BG2.HOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2HOFS);
- si.BG.BG2.VOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2VOFS);
- si.BG.BG3.HOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3HOFS);
- si.BG.BG3.VOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3VOFS);
- si.BG.BG4.HOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4HOFS);
- si.BG.BG4.VOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4VOFS);
+ si.BG.BG1.HOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1HOFS);
+ si.BG.BG1.VOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1VOFS);
+ si.BG.BG2.HOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2HOFS);
+ si.BG.BG2.VOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2VOFS);
+ si.BG.BG3.HOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3HOFS);
+ si.BG.BG3.VOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG3VOFS);
+ si.BG.BG4.HOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4HOFS);
+ si.BG.BG4.VOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG4VOFS);
- si.M7HOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7HOFS);
- si.M7VOFS = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7VOFS);
- si.M7A = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7A);
- si.M7B = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7B);
- si.M7C = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7C);
- si.M7D = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7D);
- si.M7X = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7X);
- si.M7Y = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7Y);
- si.M7Y = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7Y);
- si.M7SEL_REPEAT = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7SEL_REPEAT);
- si.M7SEL_HFLIP = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7SEL_HFLIP)!=0;
- si.M7SEL_VFLIP = api.snes_peek_logical_register(LibsnesDll.SNES_REG.M7SEL_VFLIP)!=0;
+ si.M7HOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7HOFS);
+ si.M7VOFS = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7VOFS);
+ si.M7A = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7A);
+ si.M7B = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7B);
+ si.M7C = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7C);
+ si.M7D = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7D);
+ si.M7X = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7X);
+ si.M7Y = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7Y);
+ si.M7Y = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7Y);
+ si.M7SEL_REPEAT = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7SEL_REPEAT);
+ si.M7SEL_HFLIP = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7SEL_HFLIP)!=0;
+ si.M7SEL_VFLIP = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.M7SEL_VFLIP)!=0;
for (int i = 1; i <= 4; i++)
{
@@ -534,7 +534,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public ScreenInfo ScanScreenInfo()
{
- return ScreenInfo.GetScreenInfo(api);
+ return ScreenInfo.GetScreenInfo();
}
//the same basic color table that libsnes uses to convert from snes 555 to rgba32
@@ -558,39 +558,15 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
int[] colortable;
public byte* vram, oam;
public ushort* cgram, vram16;
-
- LibsnesApi api;
- byte[] memVram, memCgram, memOam;
- GCHandle gcVram, gcCgram, gcOam;
-
- public void Dispose()
+ public SNESGraphicsDecoder(SnesColors.ColorType pal)
{
- gcVram.Free();
- gcCgram.Free();
- gcOam.Free();
- }
-
- public SNESGraphicsDecoder(LibsnesApi api, SnesColors.ColorType pal)
- {
- this.api = api;
colortable = SnesColors.GetLUT(pal);
-
- memVram = api.snes_get_memory_data(LibsnesDll.SNES_MEMORY.VRAM);
- gcVram = GCHandle.Alloc(memVram, GCHandleType.Pinned);
- IntPtr block = gcVram.AddrOfPinnedObject();
+ IntPtr block = LibsnesDll.snes_get_memory_data(LibsnesDll.SNES_MEMORY.VRAM);
vram = (byte*)block;
vram16 = (ushort*)block;
-
- //would probably be faster to copy, anyway.. well, its annoying. one day we'll have this memory mapped.
-
- memCgram = api.snes_get_memory_data(LibsnesDll.SNES_MEMORY.CGRAM);
- gcCgram = GCHandle.Alloc(memCgram, GCHandleType.Pinned);
- block = gcCgram.AddrOfPinnedObject();
+ block = LibsnesDll.snes_get_memory_data(LibsnesDll.SNES_MEMORY.CGRAM);
cgram = (ushort*)block;
-
- memOam = api.snes_get_memory_data(LibsnesDll.SNES_MEMORY.OAM);
- gcOam = GCHandle.Alloc(memOam, GCHandleType.Pinned);
- block = gcOam.AddrOfPinnedObject();
+ block = LibsnesDll.snes_get_memory_data(LibsnesDll.SNES_MEMORY.OAM);
oam = (byte*)block;
}
@@ -807,7 +783,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public void CacheTiles()
{
//generate 2bpp tiles
- int numtiles = 65536/8/2;
+ int numtiles = 8192;
int[] tiles = new int[8 * 8 * numtiles];
_tileCache[2] = tiles;
for (int i = 0; i < numtiles; i++)
diff --git a/BizHawk.Emulation/Util.cs b/BizHawk.Emulation/Util.cs
index e15c4f47ca..cc97ad68a7 100644
--- a/BizHawk.Emulation/Util.cs
+++ b/BizHawk.Emulation/Util.cs
@@ -12,14 +12,6 @@ namespace BizHawk
{
public static class Extensions
{
- public static string GetDirectory(this Assembly asm)
- {
- string codeBase = asm.CodeBase;
- UriBuilder uri = new UriBuilder(codeBase);
- string path = Uri.UnescapeDataString(uri.Path);
- return Path.GetDirectoryName(path);
- }
-
public static int LowerBoundBinarySearch(this IList list, Func keySelector, TKey key) where TKey : IComparable
{
int min = 0;
@@ -499,18 +491,6 @@ namespace BizHawk
return System.Text.Encoding.UTF8.GetString(read);
}
- public static string ReadStringAsciiZ(this BinaryReader r)
- {
- StringBuilder sb = new StringBuilder();
- for(;;)
- {
- int b = r.ReadByte();
- if(b <= 0) break;
- sb.Append((char)b);
- }
- return sb.ToString();
- }
-
///
/// conerts bytes to an uppercase string of hex numbers in upper case without any spacing or anything
/// //could be extension method
diff --git a/BizHawk.MultiClient/BizHawk.MultiClient.csproj b/BizHawk.MultiClient/BizHawk.MultiClient.csproj
index 4485008110..1304f7da34 100644
--- a/BizHawk.MultiClient/BizHawk.MultiClient.csproj
+++ b/BizHawk.MultiClient/BizHawk.MultiClient.csproj
@@ -83,6 +83,7 @@
+
3.5
diff --git a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs
index 5f568b0f32..add3dd3138 100644
--- a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs
+++ b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs
@@ -191,7 +191,7 @@ namespace BizHawk.MultiClient
}
}
- SNESGraphicsDecoder gd;
+ SNESGraphicsDecoder gd = new SNESGraphicsDecoder(SnesColors.ColorType.BizHawk);
SNESGraphicsDecoder.ScreenInfo si;
SNESGraphicsDecoder.TileEntry[] map;
byte[,] spriteMap = new byte[256, 224];
@@ -199,7 +199,6 @@ namespace BizHawk.MultiClient
void RegenerateData()
{
- if (gd != null) gd.Dispose();
gd = null;
if (currentSnesCore == null) return;
gd = NewDecoder();
@@ -664,15 +663,14 @@ namespace BizHawk.MultiClient
SNESGraphicsDecoder NewDecoder()
{
- //wtf to do? now we need an api all the time
if (currentSnesCore != null)
- return new SNESGraphicsDecoder(currentSnesCore.api, currentSnesCore.CurrPalette);
- else return new SNESGraphicsDecoder(currentSnesCore.api, SnesColors.ColorType.BizHawk);
+ return new SNESGraphicsDecoder(currentSnesCore.CurrPalette);
+ else return new SNESGraphicsDecoder(SnesColors.ColorType.BizHawk);
}
void RenderPalette()
{
- //var gd = NewDecoder(); //??
+ var gd = NewDecoder();
lastPalette = gd.GetPalette();
int pixsize = paletteCellSize * 16 + paletteCellSpacing * 17;
@@ -794,7 +792,7 @@ namespace BizHawk.MultiClient
if (lastPalette == null) return;
int rgb555 = lastPalette[lastColorNum];
- //var gd = NewDecoder(); //??
+ var gd = NewDecoder();
int color = gd.Colorize(rgb555);
pnDetailsPaletteColor.BackColor = Color.FromArgb(color);
diff --git a/BizHawk.MultiClient/config/PathManager.cs b/BizHawk.MultiClient/config/PathManager.cs
index 53d351c581..1dd7e08c3a 100644
--- a/BizHawk.MultiClient/config/PathManager.cs
+++ b/BizHawk.MultiClient/config/PathManager.cs
@@ -11,19 +11,9 @@ namespace BizHawk.MultiClient
{
public static string GetExeDirectoryAbsolute()
{
- //var uri = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
- //string module = uri.LocalPath + System.Web.HttpUtility.UrlDecode(uri.Fragment);
- //return Path.GetDirectoryName(module);
- //zero 21-dec-2012 - reuse code elsewhere and remove system.web dependency
- //return Assembly.GetEntryAssembly().GetDirectory();
-
- // no no no
- // this must be available entirely with multiclient code, as it's used to set up the AssemblyResolve event that loads util and emulation
- var asm = Assembly.GetEntryAssembly();
- string codeBase = asm.CodeBase;
- UriBuilder uri = new UriBuilder(codeBase);
- string path = Uri.UnescapeDataString(uri.Path);
- return Path.GetDirectoryName(path);
+ var uri = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
+ string module = uri.LocalPath + System.Web.HttpUtility.UrlDecode(uri.Fragment);
+ return Path.GetDirectoryName(module);
}
///
diff --git a/BizHawk.MultiClient/output/dll/libco_msvc_win32.dll b/BizHawk.MultiClient/output/dll/libco_msvc_win32.dll
new file mode 100644
index 0000000000..6bd497731e
Binary files /dev/null and b/BizHawk.MultiClient/output/dll/libco_msvc_win32.dll differ
diff --git a/BizHawk.MultiClient/output/dll/libsnes_pwrap.exe b/BizHawk.MultiClient/output/dll/libsnes_pwrap.exe
deleted file mode 100644
index a11d776e9a..0000000000
Binary files a/BizHawk.MultiClient/output/dll/libsnes_pwrap.exe and /dev/null differ
diff --git a/BizHawk.MultiClient/output/dll/libsneshawk.dll b/BizHawk.MultiClient/output/dll/libsneshawk.dll
index a03fb1021c..dd69137d28 100644
Binary files a/BizHawk.MultiClient/output/dll/libsneshawk.dll and b/BizHawk.MultiClient/output/dll/libsneshawk.dll differ
diff --git a/libsnes/bizwinmake.sh b/libsnes/bizwinmake.sh
index 70d4948463..cc380379c9 100644
--- a/libsnes/bizwinmake.sh
+++ b/libsnes/bizwinmake.sh
@@ -1,8 +1,9 @@
-#this is for using the fast libco, hand-coded by byuu. the dll isnt used, and so the threads implementation wont be useful, so it cant be debugged easily
cd bsnes
mkdir obj
mkdir out
-export BIZWINCFLAGS="-I. -O3 -masm=intel -static-libgcc -static-libstdc++"
+export BIZWINCFLAGS="-I. -O3 -masm=intel -DLIBCO_IMPORT -DLIBCO_MSVC -static-libgcc -static-libstdc++"
+#for gdb debugging
+#export BIZWINCFLAGS="-I. -O0 -g -masm=intel -DLIBCO_IMPORT -DLIBCO_MSVC -static-libgcc -static-libstdc++"
export TARGET_LIBSNES_LIBDEPS="-L ../libco_msvc_win32/release/ -llibco_msvc_win32 -static-libgcc -static-libstdc++"
profile=compatibility platform=win target=libsnes make -e -j 4
cd ..
diff --git a/libsnes/bizwinmake_debug.sh b/libsnes/bizwinmake_debug.sh
deleted file mode 100644
index d592f8ff85..0000000000
--- a/libsnes/bizwinmake_debug.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#this is for using the dll libco, and so the threads implementation can be used, for easier debugging
-cd bsnes
-mkdir obj
-mkdir out
-export BIZWINCFLAGS="-I. -O3 -masm=intel -DLIBCO_IMPORT -DLIBCO_MSVC -static-libgcc -static-libstdc++"
-#for gdb debugging
-#export BIZWINCFLAGS="-I. -O0 -g -masm=intel -DLIBCO_IMPORT -DLIBCO_MSVC -static-libgcc -static-libstdc++"
-export TARGET_LIBSNES_LIBDEPS="-L ../libco_msvc_win32/release/ -llibco_msvc_win32 -static-libgcc -static-libstdc++"
-profile=compatibility platform=win target=libsnes make -e -j 4
-cd ..
-cp bsnes/out/snes.dll ../BizHawk.MultiClient/output/dll/libsneshawk.dll
diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp b/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp
index 849c4426f5..d2711e4af4 100644
--- a/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp
+++ b/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp
@@ -156,7 +156,6 @@ void PPU::serialize(serializer &s) {
s.integer(pixel_cache[n].pri_sub);
}
- //zero TODO - only on load
//better to just take a small speed hit than store all of bg_tiledata[3][] ...
flush_tiledata_cache();
diff --git a/libsnes/bsnes/target-libsnes/Makefile b/libsnes/bsnes/target-libsnes/Makefile
index 48f3b69a07..b799afaa61 100644
--- a/libsnes/bsnes/target-libsnes/Makefile
+++ b/libsnes/bsnes/target-libsnes/Makefile
@@ -24,7 +24,7 @@ else ifeq ($(platform),osx)
ar rcs out/libsnes.a $(objects)
$(cpp) -o out/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(objects)
else ifeq ($(platform),win)
- $(cpp) -o out/snes.dll -shared -Wl,--output-def,libsneshawk.def,--out-implib,libsnes.a $(objects) $(TARGET_LIBSNES_LIBDEPS)
+ $(cpp) -o out/snes.dll -shared -Wl,--out-implib,libsnes.a $(objects) $(TARGET_LIBSNES_LIBDEPS)
endif
install:
diff --git a/libsnes/bsnes/target-libsnes/libsnes.cpp b/libsnes/bsnes/target-libsnes/libsnes.cpp
index a4e6aadaa1..94f7e2d585 100644
--- a/libsnes/bsnes/target-libsnes/libsnes.cpp
+++ b/libsnes/bsnes/target-libsnes/libsnes.cpp
@@ -99,7 +99,6 @@ struct Interface : public SNES::Interface {
pinput_state(0),
pinput_notify(0),
ppath_request(0),
- pScanlineStart(0),
backdropColor(-1),
ptrace(0)
{
@@ -600,7 +599,7 @@ void bus_write(unsigned addr, uint8_t val) {
int snes_poll_message()
{
- if(interface.messages.empty()) return -1;
+ if(interface.messages.size() == 0) return -1;
return interface.messages.front().length();
}
void snes_dequeue_message(char* buffer)
@@ -627,4 +626,4 @@ void snes_set_trace_callback(snes_trace_t callback)
interface.wanttrace = false;
interface.ptrace = 0;
}
-}
\ No newline at end of file
+}
diff --git a/libsnes/bsnes/target-libsnes/libsnes.hpp b/libsnes/bsnes/target-libsnes/libsnes.hpp
index d8482ebe84..49394f1186 100644
--- a/libsnes/bsnes/target-libsnes/libsnes.hpp
+++ b/libsnes/bsnes/target-libsnes/libsnes.hpp
@@ -3,14 +3,6 @@
#include
-#if defined(LIBSNES_IMPORT)
-#define LIBSNES_IMPORTDECL __declspec(dllimport)
-#elif defined(LIBSNES_EXPORT)
-#define LIBSNES_IMPORTDECL __declspec(dllexport)
-#else
-#define LIBSNES_IMPORTDECL
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -75,9 +67,6 @@ extern "C" {
#define SNES_MEMORY_OAM 103
#define SNES_MEMORY_CGRAM 104
-#define SNES_MEMORY_SYSBUS 200
-#define SNES_MEMORY_LOGICAL_REGS 201
-
typedef void (*snes_video_refresh_t)(const uint32_t *data, unsigned width, unsigned height);
typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right);
typedef void (*snes_input_poll_t)(void);
diff --git a/libsnes/libco_debugging/build.sh b/libsnes/libco_debugging/build.sh
deleted file mode 100644
index a499104d22..0000000000
--- a/libsnes/libco_debugging/build.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-gcc libco_win32threads.c -o libco.dll -Wall -shared -O0 -g
-mv libco.dll ../../BizHawk.MultiClient/output/dll/libco_msvc_win32.dll
\ No newline at end of file
diff --git a/libsnes/libsnes_pwrap/libsnes_pwrap.cpp b/libsnes/libsnes_pwrap/libsnes_pwrap.cpp
index ccbe99475b..ef7ea216da 100644
--- a/libsnes/libsnes_pwrap/libsnes_pwrap.cpp
+++ b/libsnes/libsnes_pwrap/libsnes_pwrap.cpp
@@ -164,15 +164,13 @@ void FlushAudio()
WritePipe(eMessage_snes_cb_audio_sample);
- int nsamples = audiobuffer_idx;
+ int nsamples = audiobuffer_idx/2;
WritePipe(nsamples);
- char* buf = ReadPipeSharedPtr();
- memcpy(buf,audiobuffer,nsamples*2);
+ int destOfs = ReadPipe();
+ char* buf = (char*)hMapFilePtr + destOfs;
+ memcpy(buf,audiobuffer,nsamples*4);
//extra just in case we had to unexpectedly flush audio and then carry on with some other process... yeah, its rickety.
WritePipe(0); //dummy synchronization
-
- //wait for frontend to consume data
-
ReadPipe(); //dummy synchronization
WritePipe(0); //dummy synchronization
audiobuffer_idx = 0;