This commit is contained in:
upthorn 2019-01-04 04:58:58 -08:00
commit 71215adf0d
71 changed files with 3722 additions and 2052 deletions

18
Assets/EmuHawkMono.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/sh
cd "$(dirname "$0")"
if [ "$(ps -C "mono" -o "cmd" --no-headers | grep "EmuHawk.exe")" ]; then
echo "EmuHawk is already running, exiting..."
exit 0
fi
libpath=""
if [ "$(command -v lsb_release)" ]; then
case "$(lsb_release -i | cut -c17- | tr -d "\n")" in
"Arch"|"ManjaroLinux") libpath="/usr/lib/wine";;
"Ubuntu"|"LinuxMint") libpath="/usr/lib/x86_64-linux-gnu/wine";;
esac
fi
if [ -z "$libpath" ]; then
printf "%s\n" "Unknown distro, assuming WINE library location is /usr/lib/wine..."
libpath="/usr/lib/wine"
fi
LD_LIBRARY_PATH="$libpath" mono ./EmuHawk.exe

File diff suppressed because it is too large Load Diff

BIN
Assets/libblip_buf.so Executable file

Binary file not shown.

View File

@ -14,6 +14,8 @@
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>. along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
*/ */
using BizHawk.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
#if !WINCE && !MONO #if !WINCE && !MONO
@ -87,6 +89,8 @@ namespace SevenZip
// private static string _LibraryVersion; // private static string _LibraryVersion;
private static bool? _modifyCapabale; private static bool? _modifyCapabale;
private static readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager;
private static void InitUserInFormat(object user, InArchiveFormat format) private static void InitUserInFormat(object user, InArchiveFormat format)
{ {
if (!_inArchives.ContainsKey(user)) if (!_inArchives.ContainsKey(user))
@ -148,16 +152,16 @@ namespace SevenZip
//{ //{
// throw new SevenZipLibraryException("DLL file does not exist."); // throw new SevenZipLibraryException("DLL file does not exist.");
//} //}
if ((_modulePtr = NativeMethods.LoadLibrary(_libraryFileName)) == IntPtr.Zero) if ((_modulePtr = libLoader.LoadPlatformSpecific(_libraryFileName)) == IntPtr.Zero)
{ {
//try a different directory //try a different directory
string alternateFilename = Path.Combine(Path.Combine(Path.GetDirectoryName(_libraryFileName),"dll"),"7z.dll"); string alternateFilename = Path.Combine(Path.Combine(Path.GetDirectoryName(_libraryFileName),"dll"),"7z.dll");
if ((_modulePtr = NativeMethods.LoadLibrary(alternateFilename)) == IntPtr.Zero) if ((_modulePtr = libLoader.LoadPlatformSpecific(alternateFilename)) == IntPtr.Zero)
throw new SevenZipLibraryException("failed to load library."); throw new SevenZipLibraryException("failed to load library.");
} }
if (NativeMethods.GetProcAddress(_modulePtr, "GetHandlerProperty") == IntPtr.Zero) if (libLoader.GetProcAddr(_modulePtr, "GetHandlerProperty") == IntPtr.Zero)
{ {
NativeMethods.FreeLibrary(_modulePtr); libLoader.FreePlatformSpecific(_modulePtr);
throw new SevenZipLibraryException("library is invalid."); throw new SevenZipLibraryException("library is invalid.");
} }
} }
@ -431,7 +435,7 @@ namespace SevenZip
if (_totalUsers == 0) if (_totalUsers == 0)
{ {
#if !WINCE && !MONO #if !WINCE && !MONO
NativeMethods.FreeLibrary(_modulePtr); libLoader.FreePlatformSpecific(_modulePtr);
#endif #endif
_modulePtr = IntPtr.Zero; _modulePtr = IntPtr.Zero;
@ -466,7 +470,7 @@ namespace SevenZip
} }
var createObject = (NativeMethods.CreateObjectDelegate) var createObject = (NativeMethods.CreateObjectDelegate)
Marshal.GetDelegateForFunctionPointer( Marshal.GetDelegateForFunctionPointer(
NativeMethods.GetProcAddress(_modulePtr, "CreateObject"), libLoader.GetProcAddr(_modulePtr, "CreateObject"),
typeof(NativeMethods.CreateObjectDelegate)); typeof(NativeMethods.CreateObjectDelegate));
if (createObject == null) if (createObject == null)
{ {
@ -525,7 +529,7 @@ namespace SevenZip
} }
var createObject = (NativeMethods.CreateObjectDelegate) var createObject = (NativeMethods.CreateObjectDelegate)
Marshal.GetDelegateForFunctionPointer( Marshal.GetDelegateForFunctionPointer(
NativeMethods.GetProcAddress(_modulePtr, "CreateObject"), libLoader.GetProcAddr(_modulePtr, "CreateObject"),
typeof(NativeMethods.CreateObjectDelegate)); typeof(NativeMethods.CreateObjectDelegate));
if (createObject == null) if (createObject == null)
{ {

View File

@ -35,18 +35,8 @@ namespace SevenZip
[MarshalAs(UnmanagedType.Interface)] out object outObject); [MarshalAs(UnmanagedType.Interface)] out object outObject);
#endregion #endregion
[DllImport("kernel32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true)]
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string fileName);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName);
#endif #endif
#if WINCE #if WINCE
[DllImport("7z.dll", EntryPoint="CreateObject")] [DllImport("7z.dll", EntryPoint="CreateObject")]
public static extern int CreateCOMObject( public static extern int CreateCOMObject(

View File

@ -159,7 +159,5 @@ namespace BizHawk.Client.Common
} }
public static Dictionary<string, object> UserBag = new Dictionary<string, object>(); public static Dictionary<string, object> UserBag = new Dictionary<string, object>();
public static bool RunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX;
} }
} }

View File

@ -14,6 +14,7 @@ using BizHawk.Emulation.Cores.Computers.Commodore64;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
using BizHawk.Emulation.Cores.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Nintendo.Gameboy;
using BizHawk.Emulation.Cores.Nintendo.GBHawk; using BizHawk.Emulation.Cores.Nintendo.GBHawk;
using BizHawk.Emulation.Cores.Nintendo.GBHawkLink;
using BizHawk.Emulation.Cores.Nintendo.SNES; using BizHawk.Emulation.Cores.Nintendo.SNES;
using BizHawk.Emulation.Cores.PCEngine; using BizHawk.Emulation.Cores.PCEngine;
using BizHawk.Emulation.Cores.Sega.Saturn; using BizHawk.Emulation.Cores.Sega.Saturn;
@ -630,7 +631,20 @@ namespace BizHawk.Client.Common
var left = Database.GetGameInfo(leftBytes, "left.gb"); var left = Database.GetGameInfo(leftBytes, "left.gb");
var right = Database.GetGameInfo(rightBytes, "right.gb"); var right = Database.GetGameInfo(rightBytes, "right.gb");
nextEmulator = new GambatteLink( if (Global.Config.GB_UseGBHawk)
{
nextEmulator = new GBHawkLink(
nextComm,
left,
leftBytes,
right,
rightBytes,
GetCoreSettings<GBHawkLink>(),
GetCoreSyncSettings<GBHawkLink>());
}
else
{
nextEmulator = new GambatteLink(
nextComm, nextComm,
left, left,
leftBytes, leftBytes,
@ -639,7 +653,8 @@ namespace BizHawk.Client.Common
GetCoreSettings<GambatteLink>(), GetCoreSettings<GambatteLink>(),
GetCoreSyncSettings<GambatteLink>(), GetCoreSyncSettings<GambatteLink>(),
Deterministic); Deterministic);
}
// other stuff todo // other stuff todo
break; break;
case "AppleII": case "AppleII":

View File

@ -950,6 +950,8 @@
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Input.cs" /> <Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Input.cs" />
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Savestate.cs" /> <Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Savestate.cs" />
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Tastudio.cs" /> <Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Tastudio.cs" />
<Compile Include="tools\Lua\Libraries\NotReallyLuaLibrary.cs" />
<Compile Include="tools\Lua\Libraries\PlatformEmuLuaLibrary.cs" />
<Compile Include="tools\Lua\LuaAutocompleteInstaller.cs" /> <Compile Include="tools\Lua\LuaAutocompleteInstaller.cs" />
<Compile Include="tools\Lua\LuaCanvas.cs"> <Compile Include="tools\Lua\LuaCanvas.cs">
<SubType>Form</SubType> <SubType>Form</SubType>

View File

@ -2,11 +2,8 @@
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
#if WINDOWS
using SlimDX.DirectInput; using SlimDX.DirectInput;
#else
using OpenTK.Input;
#endif
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
@ -116,19 +113,17 @@ namespace BizHawk.Client.EmuHawk
private Input() private Input()
{ {
#if WINDOWS
UpdateThread = new Thread(UpdateThreadProc) UpdateThread = new Thread(UpdateThreadProc)
{ {
IsBackground = true, IsBackground = true,
Priority = ThreadPriority.AboveNormal //why not? this thread shouldn't be very heavy duty, and we want it to be responsive Priority = ThreadPriority.AboveNormal //why not? this thread shouldn't be very heavy duty, and we want it to be responsive
}; };
UpdateThread.Start(); UpdateThread.Start();
#endif
} }
public static void Initialize() public static void Initialize()
{ {
if (Global.RunningOnUnix) if (PlatformLinkedLibSingleton.RunningOnUnix)
{ {
OTK_Keyboard.Initialize(); OTK_Keyboard.Initialize();
// OTK_Gamepad.Initialize(); // OTK_Gamepad.Initialize();
@ -145,10 +140,11 @@ namespace BizHawk.Client.EmuHawk
public static void Cleanup() public static void Cleanup()
{ {
#if WINDOWS if (!PlatformLinkedLibSingleton.RunningOnUnix)
KeyInput.Cleanup(); {
GamePad.Cleanup(); KeyInput.Cleanup();
#endif GamePad.Cleanup();
}
} }
public enum InputEventType public enum InputEventType
@ -331,14 +327,22 @@ namespace BizHawk.Client.EmuHawk
return FloatValuesCopy; return FloatValuesCopy;
} }
#if WINDOWS
void UpdateThreadProc() void UpdateThreadProc()
{ {
for (; ; ) while (true)
{ {
var keyEvents = KeyInput.Update().Concat(IPCKeyInput.Update()); var keyEvents = PlatformLinkedLibSingleton.RunningOnUnix
GamePad.UpdateAll(); ? OTK_Keyboard.Update()
GamePad360.UpdateAll(); : KeyInput.Update().Concat(IPCKeyInput.Update());
if (PlatformLinkedLibSingleton.RunningOnUnix)
{
//TODO
}
else
{
GamePad.UpdateAll();
GamePad360.UpdateAll();
}
//this block is going to massively modify data structures that the binding method uses, so we have to lock it all //this block is going to massively modify data structures that the binding method uses, so we have to lock it all
lock (this) lock (this)
@ -441,7 +445,6 @@ namespace BizHawk.Client.EmuHawk
Thread.Sleep(10); Thread.Sleep(10);
} }
} }
#endif
public void StartListeningForFloatEvents() public void StartListeningForFloatEvents()
{ {

View File

@ -6,18 +6,47 @@ namespace BizHawk.Client.EmuHawk
{ {
public static class OTK_Keyboard public static class OTK_Keyboard
{ {
private static OpenTK.Input.KeyboardState _kbState; private static readonly Dictionary<Key, SlimDX.DirectInput.Key> KeyEnumMap = new Dictionary<Key, SlimDX.DirectInput.Key>
{
// A-Z
{Key.A, SlimDX.DirectInput.Key.A}, {Key.B, SlimDX.DirectInput.Key.B}, {Key.C, SlimDX.DirectInput.Key.C}, {Key.D, SlimDX.DirectInput.Key.D}, {Key.E, SlimDX.DirectInput.Key.E}, {Key.F, SlimDX.DirectInput.Key.F}, {Key.G, SlimDX.DirectInput.Key.G}, {Key.H, SlimDX.DirectInput.Key.H}, {Key.I, SlimDX.DirectInput.Key.I}, {Key.J, SlimDX.DirectInput.Key.J}, {Key.K, SlimDX.DirectInput.Key.K}, {Key.L, SlimDX.DirectInput.Key.L}, {Key.M, SlimDX.DirectInput.Key.M}, {Key.N, SlimDX.DirectInput.Key.N}, {Key.O, SlimDX.DirectInput.Key.O}, {Key.P, SlimDX.DirectInput.Key.P}, {Key.Q, SlimDX.DirectInput.Key.Q}, {Key.R, SlimDX.DirectInput.Key.R}, {Key.S, SlimDX.DirectInput.Key.S}, {Key.T, SlimDX.DirectInput.Key.T}, {Key.U, SlimDX.DirectInput.Key.U}, {Key.V, SlimDX.DirectInput.Key.V}, {Key.W, SlimDX.DirectInput.Key.W}, {Key.X, SlimDX.DirectInput.Key.X}, {Key.Y, SlimDX.DirectInput.Key.Y}, {Key.Z, SlimDX.DirectInput.Key.Z},
// 0-9
{Key.Number1, SlimDX.DirectInput.Key.D1}, {Key.Number2, SlimDX.DirectInput.Key.D2}, {Key.Number3, SlimDX.DirectInput.Key.D3}, {Key.Number4, SlimDX.DirectInput.Key.D4}, {Key.Number5, SlimDX.DirectInput.Key.D5}, {Key.Number6, SlimDX.DirectInput.Key.D6}, {Key.Number7, SlimDX.DirectInput.Key.D7}, {Key.Number8, SlimDX.DirectInput.Key.D8}, {Key.Number9, SlimDX.DirectInput.Key.D9}, {Key.Number0, SlimDX.DirectInput.Key.D0},
// misc. printables (ASCII order)
{Key.Space, SlimDX.DirectInput.Key.Space}, {Key.Quote, SlimDX.DirectInput.Key.Apostrophe}, {Key.Comma, SlimDX.DirectInput.Key.Comma}, {Key.Minus, SlimDX.DirectInput.Key.Minus}, {Key.Period, SlimDX.DirectInput.Key.Period}, {Key.Slash, SlimDX.DirectInput.Key.Slash}, {Key.Semicolon, SlimDX.DirectInput.Key.Semicolon}, {Key.Plus, SlimDX.DirectInput.Key.Equals}, {Key.BracketLeft, SlimDX.DirectInput.Key.LeftBracket}, {Key.BackSlash, SlimDX.DirectInput.Key.Backslash}, {Key.BracketRight, SlimDX.DirectInput.Key.RightBracket}, {Key.Tilde, SlimDX.DirectInput.Key.Grave},
// misc. (alphabetically)
{Key.BackSpace, SlimDX.DirectInput.Key.Backspace}, {Key.CapsLock, SlimDX.DirectInput.Key.CapsLock}, {Key.Delete, SlimDX.DirectInput.Key.Delete}, {Key.Down, SlimDX.DirectInput.Key.DownArrow}, {Key.End, SlimDX.DirectInput.Key.End}, {Key.Enter, SlimDX.DirectInput.Key.Return}, {Key.Escape, SlimDX.DirectInput.Key.Escape}, {Key.Home, SlimDX.DirectInput.Key.Home}, {Key.Insert, SlimDX.DirectInput.Key.Insert}, {Key.Left, SlimDX.DirectInput.Key.LeftArrow}, {Key.PageDown, SlimDX.DirectInput.Key.PageDown}, {Key.PageUp, SlimDX.DirectInput.Key.PageUp}, {Key.Pause, SlimDX.DirectInput.Key.Pause}, {Key.Right, SlimDX.DirectInput.Key.RightArrow}, {Key.ScrollLock, SlimDX.DirectInput.Key.ScrollLock}, {Key.Tab, SlimDX.DirectInput.Key.Tab}, {Key.Up, SlimDX.DirectInput.Key.UpArrow},
// modifier
{Key.WinLeft, SlimDX.DirectInput.Key.LeftWindowsKey}, {Key.WinRight, SlimDX.DirectInput.Key.RightWindowsKey}, {Key.ControlLeft, SlimDX.DirectInput.Key.LeftControl}, {Key.ControlRight, SlimDX.DirectInput.Key.RightControl}, {Key.AltLeft, SlimDX.DirectInput.Key.LeftAlt}, {Key.AltRight, SlimDX.DirectInput.Key.RightAlt}, {Key.ShiftLeft, SlimDX.DirectInput.Key.LeftShift}, {Key.ShiftRight, SlimDX.DirectInput.Key.RightShift},
// function
{Key.F1, SlimDX.DirectInput.Key.F1}, {Key.F2, SlimDX.DirectInput.Key.F2}, {Key.F3, SlimDX.DirectInput.Key.F3}, {Key.F4, SlimDX.DirectInput.Key.F4}, {Key.F5, SlimDX.DirectInput.Key.F5}, {Key.F6, SlimDX.DirectInput.Key.F6}, {Key.F7, SlimDX.DirectInput.Key.F7}, {Key.F8, SlimDX.DirectInput.Key.F8}, {Key.F9, SlimDX.DirectInput.Key.F9}, {Key.F10, SlimDX.DirectInput.Key.F10}, {Key.F11, SlimDX.DirectInput.Key.F11}, {Key.F12, SlimDX.DirectInput.Key.F12},
// keypad (alphabetically)
{Key.Keypad0, SlimDX.DirectInput.Key.NumberPad0}, {Key.Keypad1, SlimDX.DirectInput.Key.NumberPad1}, {Key.Keypad2, SlimDX.DirectInput.Key.NumberPad2}, {Key.Keypad3, SlimDX.DirectInput.Key.NumberPad3}, {Key.Keypad4, SlimDX.DirectInput.Key.NumberPad4}, {Key.Keypad5, SlimDX.DirectInput.Key.NumberPad5}, {Key.Keypad6, SlimDX.DirectInput.Key.NumberPad6}, {Key.Keypad7, SlimDX.DirectInput.Key.NumberPad7}, {Key.Keypad8, SlimDX.DirectInput.Key.NumberPad8}, {Key.Keypad9, SlimDX.DirectInput.Key.NumberPad9}, {Key.KeypadAdd, SlimDX.DirectInput.Key.NumberPadPlus}, {Key.KeypadDecimal, SlimDX.DirectInput.Key.NumberPadPeriod}, {Key.KeypadDivide, SlimDX.DirectInput.Key.NumberPadSlash}, {Key.KeypadEnter, SlimDX.DirectInput.Key.NumberPadEnter}, {Key.KeypadMultiply, SlimDX.DirectInput.Key.NumberPadStar}, {Key.KeypadSubtract, SlimDX.DirectInput.Key.NumberPadMinus}
};
private static readonly List<KeyInput.KeyEvent> _eventList = new List<KeyInput.KeyEvent>();
private static KeyboardState _kbState;
public static void Initialize () public static void Initialize ()
{ {
_kbState = OpenTK.Input.Keyboard.GetState(); _kbState = Keyboard.GetState();
} }
public static void Update () public static IEnumerable<KeyInput.KeyEvent> Update ()
{ {
_eventList.Clear();
var lastState = _kbState;
try try
{ {
_kbState = OpenTK.Input.Keyboard.GetState(); _kbState = Keyboard.GetState();
foreach (KeyValuePair<Key, SlimDX.DirectInput.Key> entry in KeyEnumMap)
{
if (lastState.IsKeyUp(entry.Key) && _kbState.IsKeyDown(entry.Key))
_eventList.Add(new KeyInput.KeyEvent { Key = entry.Value, Pressed = true });
else if (lastState.IsKeyDown(entry.Key) && _kbState.IsKeyUp(entry.Key))
_eventList.Add(new KeyInput.KeyEvent { Key = entry.Value, Pressed = false });
}
} }
catch catch
{ {
@ -30,6 +59,7 @@ namespace BizHawk.Client.EmuHawk
System.Console.WriteLine("OpenTK Keyboard thread is angry."); System.Console.WriteLine("OpenTK Keyboard thread is angry.");
} }
} }
return _eventList;
} }
public static bool IsPressed (Key key) public static bool IsPressed (Key key)

View File

@ -351,7 +351,9 @@
this.SaturnPreferencesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.SaturnPreferencesMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.DGBSubMenu = new System.Windows.Forms.ToolStripMenuItem(); this.DGBSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.DGBsettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.DGBsettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.GenesisSubMenu = new System.Windows.Forms.ToolStripMenuItem(); this.DGBHawkSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.DGBHawksettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.GenesisSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.vDPViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.vDPViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.GenesisGameGenieECDC = new System.Windows.Forms.ToolStripMenuItem(); this.GenesisGameGenieECDC = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator26 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripSeparator26 = new System.Windows.Forms.ToolStripSeparator();
@ -503,7 +505,8 @@
this.N64SubMenu, this.N64SubMenu,
this.SaturnSubMenu, this.SaturnSubMenu,
this.DGBSubMenu, this.DGBSubMenu,
this.GenesisSubMenu, this.DGBHawkSubMenu,
this.GenesisSubMenu,
this.wonderSwanToolStripMenuItem, this.wonderSwanToolStripMenuItem,
this.AppleSubMenu, this.AppleSubMenu,
this.C64SubMenu, this.C64SubMenu,
@ -3177,10 +3180,25 @@
this.DGBsettingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22); this.DGBsettingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.DGBsettingsToolStripMenuItem.Text = "Settings..."; this.DGBsettingsToolStripMenuItem.Text = "Settings...";
this.DGBsettingsToolStripMenuItem.Click += new System.EventHandler(this.DgbSettingsMenuItem_Click); this.DGBsettingsToolStripMenuItem.Click += new System.EventHandler(this.DgbSettingsMenuItem_Click);
// //
// GenesisSubMenu // DGBHawkSubMenu
// //
this.GenesisSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.DGBHawkSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.DGBHawksettingsToolStripMenuItem});
this.DGBHawkSubMenu.Name = "DGBHawkSubMenu";
this.DGBHawkSubMenu.Size = new System.Drawing.Size(59, 19);
this.DGBHawkSubMenu.Text = "&GB Link";
//
// DGBHawksettingsToolStripMenuItem
//
this.DGBHawksettingsToolStripMenuItem.Name = "DGBHawksettingsToolStripMenuItem";
this.DGBHawksettingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.DGBHawksettingsToolStripMenuItem.Text = "Settings...";
this.DGBHawksettingsToolStripMenuItem.Click += new System.EventHandler(this.DgbHawkSettingsMenuItem_Click);
//
// GenesisSubMenu
//
this.GenesisSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.vDPViewerToolStripMenuItem, this.vDPViewerToolStripMenuItem,
this.GenesisGameGenieECDC, this.GenesisGameGenieECDC,
this.toolStripSeparator26, this.toolStripSeparator26,
@ -4504,6 +4522,8 @@
private System.Windows.Forms.ToolStripMenuItem FdsEjectDiskMenuItem; private System.Windows.Forms.ToolStripMenuItem FdsEjectDiskMenuItem;
private System.Windows.Forms.ToolStripMenuItem DGBSubMenu; private System.Windows.Forms.ToolStripMenuItem DGBSubMenu;
private System.Windows.Forms.ToolStripMenuItem DGBsettingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem DGBsettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem DGBHawkSubMenu;
private System.Windows.Forms.ToolStripMenuItem DGBHawksettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem GenesisSubMenu; private System.Windows.Forms.ToolStripMenuItem GenesisSubMenu;
private System.Windows.Forms.ToolStripMenuItem GenesisSettingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem GenesisSettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem AtariSettingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem AtariSettingsToolStripMenuItem;

View File

@ -1386,6 +1386,7 @@ namespace BizHawk.Client.EmuHawk
RamSearchMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["RAM Search"].Bindings; RamSearchMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["RAM Search"].Bindings;
HexEditorMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Hex Editor"].Bindings; HexEditorMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Hex Editor"].Bindings;
LuaConsoleMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Lua Console"].Bindings; LuaConsoleMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Lua Console"].Bindings;
LuaConsoleMenuItem.Enabled = GlobalWin.Tools.IsAvailable<LuaConsole>();
CheatsMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Cheats"].Bindings; CheatsMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Cheats"].Bindings;
TAStudioMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["TAStudio"].Bindings; TAStudioMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["TAStudio"].Bindings;
VirtualPadMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Virtual Pad"].Bindings; VirtualPadMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Virtual Pad"].Bindings;
@ -2349,6 +2350,11 @@ namespace BizHawk.Client.EmuHawk
DGBPrefs.DoDGBPrefsDialog(this); DGBPrefs.DoDGBPrefsDialog(this);
} }
private void DgbHawkSettingsMenuItem_Click(object sender, EventArgs e)
{
GenericCoreConfig.DoDialog(this, "Gameboy Settings");
}
#endregion #endregion
#region GEN #region GEN

View File

@ -24,6 +24,7 @@ using BizHawk.Emulation.Cores.Nintendo.GBA;
using BizHawk.Emulation.Cores.Nintendo.NES; using BizHawk.Emulation.Cores.Nintendo.NES;
using BizHawk.Emulation.Cores.Nintendo.SNES; using BizHawk.Emulation.Cores.Nintendo.SNES;
using BizHawk.Emulation.Cores.Nintendo.N64; using BizHawk.Emulation.Cores.Nintendo.N64;
using BizHawk.Emulation.Cores.Nintendo.GBHawkLink;
using BizHawk.Client.EmuHawk.WinFormExtensions; using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
@ -1118,11 +1119,7 @@ namespace BizHawk.Client.EmuHawk
private void OpenLuaConsole() private void OpenLuaConsole()
{ {
#if WINDOWS
GlobalWin.Tools.Load<LuaConsole>(); GlobalWin.Tools.Load<LuaConsole>();
#else
MessageBox.Show("Sorry, Lua is not supported on this platform.", "Lua not supported", MessageBoxButtons.OK, MessageBoxIcon.Error);
#endif
} }
public void NotifyLogWindowClosing() public void NotifyLogWindowClosing()
@ -1724,6 +1721,7 @@ namespace BizHawk.Client.EmuHawk
N64SubMenu.Visible = false; N64SubMenu.Visible = false;
SaturnSubMenu.Visible = false; SaturnSubMenu.Visible = false;
DGBSubMenu.Visible = false; DGBSubMenu.Visible = false;
DGBHawkSubMenu.Visible = false;
GenesisSubMenu.Visible = false; GenesisSubMenu.Visible = false;
wonderSwanToolStripMenuItem.Visible = false; wonderSwanToolStripMenuItem.Visible = false;
AppleSubMenu.Visible = false; AppleSubMenu.Visible = false;
@ -1806,7 +1804,14 @@ namespace BizHawk.Client.EmuHawk
SaturnSubMenu.Visible = true; SaturnSubMenu.Visible = true;
break; break;
case "DGB": case "DGB":
DGBSubMenu.Visible = true; if (Emulator is GBHawkLink)
{
DGBHawkSubMenu.Visible = true;
}
else
{
DGBSubMenu.Visible = true;
}
break; break;
case "WSWAN": case "WSWAN":
wonderSwanToolStripMenuItem.Visible = true; wonderSwanToolStripMenuItem.Visible = true;

View File

@ -17,26 +17,25 @@ namespace BizHawk.Client.EmuHawk
{ {
static class Program static class Program
{ {
static bool RunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX;
static Program() static Program()
{ {
//this needs to be done before the warnings/errors show up //this needs to be done before the warnings/errors show up
Application.EnableVisualStyles(); Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Application.SetCompatibleTextRenderingDefault(false);
PlatformSpecificLinkedLibs libLoader = RunningOnUnix ? (PlatformSpecificLinkedLibs) new UnixMono() : (PlatformSpecificLinkedLibs) new Win32(); var libLoader = PlatformLinkedLibSingleton.LinkedLibManager;
//http://www.codeproject.com/Articles/310675/AppDomain-AssemblyResolve-Event-Tips //http://www.codeproject.com/Articles/310675/AppDomain-AssemblyResolve-Event-Tips
//try loading libraries we know we'll need //try loading libraries we know we'll need
//something in the winforms, etc. code below will cause .net to popup a missing msvcr100.dll in case that one's missing //something in the winforms, etc. code below will cause .net to popup a missing msvcr100.dll in case that one's missing
//but oddly it lets us proceed and we'll then catch it here //but oddly it lets us proceed and we'll then catch it here
var d3dx9 = libLoader.LoadPlatformSpecific("d3dx9_43.dll"); var libExt = PlatformLinkedLibSingleton.RunningOnUnix ? ".dll.so" : ".dll";
var vc2015 = libLoader.LoadPlatformSpecific("vcruntime140.dll"); var d3dx9 = libLoader.LoadPlatformSpecific($"d3dx9_43{libExt}");
var vc2012 = libLoader.LoadPlatformSpecific("msvcr120.dll"); //TODO - check version? var vc2015 = libLoader.LoadPlatformSpecific($"vcruntime140{libExt}");
var vc2010 = libLoader.LoadPlatformSpecific("msvcr100.dll"); //TODO - check version? var vc2012 = libLoader.LoadPlatformSpecific($"msvcr120{libExt}"); //TODO - check version?
var vc2010p = libLoader.LoadPlatformSpecific("msvcp100.dll"); var vc2010 = libLoader.LoadPlatformSpecific($"msvcr100{libExt}"); //TODO - check version?
var vc2010p = libLoader.LoadPlatformSpecific($"msvcp100{libExt}");
bool fail = false, warn = false; bool fail = false, warn = false;
warn |= d3dx9 == IntPtr.Zero; warn |= d3dx9 == IntPtr.Zero;
fail |= vc2015 == IntPtr.Zero; fail |= vc2015 == IntPtr.Zero;
@ -66,7 +65,7 @@ namespace BizHawk.Client.EmuHawk
libLoader.FreePlatformSpecific(vc2010); libLoader.FreePlatformSpecific(vc2010);
libLoader.FreePlatformSpecific(vc2010p); libLoader.FreePlatformSpecific(vc2010p);
if (!RunningOnUnix) if (!PlatformLinkedLibSingleton.RunningOnUnix)
{ {
// this will look in subdirectory "dll" to load pinvoked stuff // this will look in subdirectory "dll" to load pinvoked stuff
string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll"); string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll");
@ -90,63 +89,6 @@ namespace BizHawk.Client.EmuHawk
return SubMain(args); return SubMain(args);
} }
private interface PlatformSpecificLinkedLibs
{
IntPtr LoadPlatformSpecific(string dllToLoad);
IntPtr GetProcAddr(IntPtr hModule, string procName);
void FreePlatformSpecific(IntPtr hModule);
}
private class Win32 : PlatformSpecificLinkedLibs
{
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll")]
private static extern void FreeLibrary(IntPtr hModule);
public IntPtr LoadPlatformSpecific(string dllToLoad)
{
return LoadLibrary(dllToLoad);
}
public IntPtr GetProcAddr(IntPtr hModule, string procName)
{
return GetProcAddress(hModule, procName);
}
public void FreePlatformSpecific(IntPtr hModule)
{
FreeLibrary(hModule);
}
}
private class UnixMono : PlatformSpecificLinkedLibs
{
// This class is copied from a tutorial, so don't git blame and then email me expecting insight.
const int RTLD_NOW = 2;
[DllImport("libdl.so")]
private static extern IntPtr dlopen(String fileName, int flags);
[DllImport("libdl.so")]
private static extern IntPtr dlerror();
[DllImport("libdl.so")]
private static extern IntPtr dlsym(IntPtr handle, String symbol);
[DllImport("libdl.so")]
private static extern int dlclose(IntPtr handle);
public IntPtr LoadPlatformSpecific(string dllToLoad)
{
return dlopen(dllToLoad + ".so", RTLD_NOW);
}
public IntPtr GetProcAddr(IntPtr hModule, string procName)
{
dlerror();
var res = dlsym(hModule, procName);
var errPtr = dlerror();
if (errPtr != IntPtr.Zero) throw new Exception("dlsym: " + Marshal.PtrToStringAnsi(errPtr));
return res;
}
public void FreePlatformSpecific(IntPtr hModule)
{
dlclose(hModule);
}
}
private interface PlatformSpecificMainLoopCrashHandler private interface PlatformSpecificMainLoopCrashHandler
{ {
void TryCatchFinally(string[] args); void TryCatchFinally(string[] args);
@ -258,7 +200,7 @@ namespace BizHawk.Client.EmuHawk
} }
} }
} }
private static PlatformSpecificMainLoopCrashHandler mainLoopCrashHandler = RunningOnUnix private static PlatformSpecificMainLoopCrashHandler mainLoopCrashHandler = PlatformLinkedLibSingleton.RunningOnUnix
? (PlatformSpecificMainLoopCrashHandler) new UnixMonoMainLoopCrashHandler() ? (PlatformSpecificMainLoopCrashHandler) new UnixMonoMainLoopCrashHandler()
: (PlatformSpecificMainLoopCrashHandler) new Win32MainLoopCrashHandler(); : (PlatformSpecificMainLoopCrashHandler) new Win32MainLoopCrashHandler();
@ -323,7 +265,7 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.GLManager = GLManager.Instance; GlobalWin.GLManager = GLManager.Instance;
//now create the "GL" context for the display method. we can reuse the IGL_TK context if opengl display method is chosen //now create the "GL" context for the display method. we can reuse the IGL_TK context if opengl display method is chosen
if (RunningOnUnix) Global.Config.DispMethod = Config.EDispMethod.GdiPlus; if (PlatformLinkedLibSingleton.RunningOnUnix) Global.Config.DispMethod = Config.EDispMethod.GdiPlus;
REDO_DISPMETHOD: REDO_DISPMETHOD:
if (Global.Config.DispMethod == Config.EDispMethod.GdiPlus) if (Global.Config.DispMethod == Config.EDispMethod.GdiPlus)
GlobalWin.GL = new Bizware.BizwareGL.Drivers.GdiPlus.IGL_GdiPlus(); GlobalWin.GL = new Bizware.BizwareGL.Drivers.GdiPlus.IGL_GdiPlus();
@ -371,7 +313,7 @@ namespace BizHawk.Client.EmuHawk
goto REDO_DISPMETHOD; goto REDO_DISPMETHOD;
} }
if (!RunningOnUnix) if (!PlatformLinkedLibSingleton.RunningOnUnix)
{ {
//WHY do we have to do this? some intel graphics drivers (ig7icd64.dll 10.18.10.3304 on an unknown chip on win8.1) are calling SetDllDirectory() for the process, which ruins stuff. //WHY do we have to do this? some intel graphics drivers (ig7icd64.dll 10.18.10.3304 on an unknown chip on win8.1) are calling SetDllDirectory() for the process, which ruins stuff.
//The relevant initialization happened just before in "create IGL context". //The relevant initialization happened just before in "create IGL context".

View File

@ -2,6 +2,7 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -40,7 +41,7 @@ namespace BizHawk.Client.EmuHawk
//TODO implement //TODO implement
} }
} }
private static PlatformSpecificScreenBlankInterface screenBlankInterface = Global.RunningOnUnix private static PlatformSpecificScreenBlankInterface screenBlankInterface = PlatformLinkedLibSingleton.RunningOnUnix
? (PlatformSpecificScreenBlankInterface) new MiscUnixScreenBlankInterface() ? (PlatformSpecificScreenBlankInterface) new MiscUnixScreenBlankInterface()
: (PlatformSpecificScreenBlankInterface) new WinScreenBlankInterface(); : (PlatformSpecificScreenBlankInterface) new WinScreenBlankInterface();

View File

@ -4,6 +4,7 @@ using System.Threading;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions; using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -26,7 +27,7 @@ namespace BizHawk.Client.EmuHawk
{ {
if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL) if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL)
_outputDevice = new OpenALSoundOutput(this); _outputDevice = new OpenALSoundOutput(this);
if (!Global.RunningOnUnix) if (!PlatformLinkedLibSingleton.RunningOnUnix)
{ {
if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound) if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound)
_outputDevice = new DirectSoundSoundOutput(this, mainWindowHandle); _outputDevice = new DirectSoundSoundOutput(this, mainWindowHandle);

View File

@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common;
//this throttle is nitsuja's fine-tuned techniques from desmume //this throttle is nitsuja's fine-tuned techniques from desmume
@ -159,7 +160,7 @@ namespace BizHawk.Client.EmuHawk
return timeBeginPeriod(ms); return timeBeginPeriod(ms);
} }
} }
static PlatformSpecificSysTimer sysTimer = Global.RunningOnUnix ? (PlatformSpecificSysTimer) new UnixMonoSysTimer() : (PlatformSpecificSysTimer) new WinSysTimer(); static PlatformSpecificSysTimer sysTimer = PlatformLinkedLibSingleton.RunningOnUnix ? (PlatformSpecificSysTimer) new UnixMonoSysTimer() : (PlatformSpecificSysTimer) new WinSysTimer();
static uint TimeBeginPeriod(uint ms) static uint TimeBeginPeriod(uint ms)
{ {
return sysTimer.TimeBeginPeriod(ms); return sysTimer.TimeBeginPeriod(ms);

View File

@ -24,6 +24,8 @@ namespace BizHawk.Client.EmuHawk
ControllerImages.Add("SNES Controller", Properties.Resources.SNES_Controller); ControllerImages.Add("SNES Controller", Properties.Resources.SNES_Controller);
ControllerImages.Add("Nintento 64 Controller", Properties.Resources.N64); ControllerImages.Add("Nintento 64 Controller", Properties.Resources.N64);
ControllerImages.Add("Gameboy Controller", Properties.Resources.GBController); ControllerImages.Add("Gameboy Controller", Properties.Resources.GBController);
ControllerImages.Add("Gameboy Controller H", Properties.Resources.GBController);
ControllerImages.Add("Gameboy Controller + Tilt", Properties.Resources.GBController);
ControllerImages.Add("GBA Controller", Properties.Resources.GBA_Controller); ControllerImages.Add("GBA Controller", Properties.Resources.GBA_Controller);
ControllerImages.Add("Dual Gameboy Controller", Properties.Resources.GBController); ControllerImages.Add("Dual Gameboy Controller", Properties.Resources.GBController);

View File

@ -5,6 +5,8 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public sealed class InputWidget : TextBox public sealed class InputWidget : TextBox
@ -69,7 +71,7 @@ namespace BizHawk.Client.EmuHawk
protected override void OnMouseClick(MouseEventArgs e) protected override void OnMouseClick(MouseEventArgs e)
{ {
HideCaret(Handle); if (!PlatformLinkedLibSingleton.RunningOnUnix) HideCaret(Handle);
base.OnMouseClick(e); base.OnMouseClick(e);
} }
@ -262,7 +264,7 @@ namespace BizHawk.Client.EmuHawk
protected override void OnGotFocus(EventArgs e) protected override void OnGotFocus(EventArgs e)
{ {
HideCaret(Handle); if (!PlatformLinkedLibSingleton.RunningOnUnix) HideCaret(Handle);
} }
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) protected override bool ProcessCmdKey(ref Message msg, Keys keyData)

View File

@ -13,7 +13,7 @@ using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public class EmuLuaLibrary public class EmuLuaLibrary : PlatformEmuLuaLibrary
{ {
public EmuLuaLibrary() public EmuLuaLibrary()
{ {
@ -82,16 +82,6 @@ namespace BizHawk.Client.EmuHawk
} }
} }
public bool IsRebootingCore { get; set; } // pretty hacky.. we dont want a lua script to be able to restart itself by rebooting the core
private readonly Dictionary<Type, LuaLibraryBase> Libraries = new Dictionary<Type, LuaLibraryBase>();
public LuaFileList ScriptList { get; } = new LuaFileList();
public IEnumerable<LuaFile> RunningScripts
{
get { return ScriptList.Where(lf => lf.Enabled); }
}
private Lua _lua = new Lua(); private Lua _lua = new Lua();
private Lua _currThread; private Lua _currThread;
@ -101,9 +91,7 @@ namespace BizHawk.Client.EmuHawk
private EmulatorLuaLibrary EmulatorLuaLibrary => (EmulatorLuaLibrary)Libraries[typeof(EmulatorLuaLibrary)]; private EmulatorLuaLibrary EmulatorLuaLibrary => (EmulatorLuaLibrary)Libraries[typeof(EmulatorLuaLibrary)];
public GuiLuaLibrary GuiLibrary => (GuiLuaLibrary)Libraries[typeof(GuiLuaLibrary)]; public override void Restart(IEmulatorServiceProvider newServiceProvider)
public void Restart(IEmulatorServiceProvider newServiceProvider)
{ {
foreach (var lib in Libraries) foreach (var lib in Libraries)
{ {
@ -111,7 +99,7 @@ namespace BizHawk.Client.EmuHawk
} }
} }
public void StartLuaDrawing() public override void StartLuaDrawing()
{ {
if (ScriptList.Any() && GuiLibrary.SurfaceIsNull) if (ScriptList.Any() && GuiLibrary.SurfaceIsNull)
{ {
@ -119,7 +107,7 @@ namespace BizHawk.Client.EmuHawk
} }
} }
public void EndLuaDrawing() public override void EndLuaDrawing()
{ {
if (ScriptList.Any()) if (ScriptList.Any())
{ {
@ -127,34 +115,35 @@ namespace BizHawk.Client.EmuHawk
} }
} }
public LuaDocumentation Docs { get; }
public bool IsRunning { get; set; } public bool IsRunning { get; set; }
public EventWaitHandle LuaWait { get; private set; }
public bool FrameAdvanceRequested { get; private set; } public bool FrameAdvanceRequested { get; private set; }
public LuaFunctionList RegisteredFunctions => EventsLibrary.RegisteredFunctions; public override LuaFunctionList GetRegisteredFunctions()
{
return EventsLibrary.RegisteredFunctions;
}
public void WindowClosed(IntPtr handle) public override void WindowClosed(IntPtr handle)
{ {
FormsLibrary.WindowClosed(handle); FormsLibrary.WindowClosed(handle);
} }
public void CallSaveStateEvent(string name) public override void CallSaveStateEvent(string name)
{ {
EventsLibrary.CallSaveStateEvent(name); EventsLibrary.CallSaveStateEvent(name);
} }
public void CallLoadStateEvent(string name) public override void CallLoadStateEvent(string name)
{ {
EventsLibrary.CallLoadStateEvent(name); EventsLibrary.CallLoadStateEvent(name);
} }
public void CallFrameBeforeEvent() public override void CallFrameBeforeEvent()
{ {
EventsLibrary.CallFrameBeforeEvent(); EventsLibrary.CallFrameBeforeEvent();
} }
public void CallFrameAfterEvent() public override void CallFrameAfterEvent()
{ {
EventsLibrary.CallFrameAfterEvent(); EventsLibrary.CallFrameAfterEvent();
} }
@ -164,7 +153,12 @@ namespace BizHawk.Client.EmuHawk
EventsLibrary.CallExitEvent(thread); EventsLibrary.CallExitEvent(thread);
} }
public void Close() public override void CallExitEvent(LuaFile lf)
{
CallExitEvent(lf.Thread);
}
public override void Close()
{ {
FormsLibrary.DestroyAll(); FormsLibrary.DestroyAll();
_lua.Close(); _lua.Close();
@ -187,7 +181,12 @@ namespace BizHawk.Client.EmuHawk
return lua; return lua;
} }
public void ExecuteString(string command) public override void SpawnAndSetFileThread(string pathToLoad, LuaFile lf)
{
lf.Thread = SpawnCoroutine(pathToLoad);
}
public override void ExecuteString(string command)
{ {
_currThread = _lua.NewThread(); _currThread = _lua.NewThread();
_currThread.DoString(command); _currThread.DoString(command);
@ -232,6 +231,11 @@ namespace BizHawk.Client.EmuHawk
} }
} }
public override ResumeResult ResumeScriptFromThreadOf(LuaFile lf)
{
return ResumeScript(lf.Thread);
}
public static void Print(params object[] outputs) public static void Print(params object[] outputs)
{ {
ConsoleLuaLibrary.Log(outputs); ConsoleLuaLibrary.Log(outputs);

View File

@ -0,0 +1,60 @@
using System;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// Methods intentionally blank.
/// </summary>
public sealed class NotReallyLuaLibrary : PlatformEmuLuaLibrary
{
public override void CallExitEvent(LuaFile lf)
{
}
public override void CallFrameAfterEvent()
{
}
public override void CallFrameBeforeEvent()
{
}
public override void CallLoadStateEvent(string name)
{
}
public override void CallSaveStateEvent(string name)
{
}
public override void Close()
{
}
public override void EndLuaDrawing()
{
}
public override void ExecuteString(string command)
{
}
private static readonly LuaFunctionList EmptyLuaFunList = new LuaFunctionList();
public override LuaFunctionList GetRegisteredFunctions()
{
return EmptyLuaFunList;
}
public override void Restart(IEmulatorServiceProvider newServiceProvider)
{
}
private static readonly EmuLuaLibrary.ResumeResult EmptyResumeResult = new EmuLuaLibrary.ResumeResult();
public override EmuLuaLibrary.ResumeResult ResumeScriptFromThreadOf(LuaFile lf)
{
return EmptyResumeResult;
}
public override void SpawnAndSetFileThread(string pathToLoad, LuaFile lf)
{
}
public override void StartLuaDrawing()
{
}
public override void WindowClosed(IntPtr handle)
{
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
public abstract class PlatformEmuLuaLibrary
{
public LuaDocumentation Docs { get; protected set; }
public GuiLuaLibrary GuiLibrary => (GuiLuaLibrary) Libraries[typeof(GuiLuaLibrary)];
public bool IsRebootingCore { get; set; } // pretty hacky.. we dont want a lua script to be able to restart itself by rebooting the core
protected readonly Dictionary<Type, LuaLibraryBase> Libraries = new Dictionary<Type, LuaLibraryBase>();
public EventWaitHandle LuaWait { get; protected set; }
public IEnumerable<LuaFile> RunningScripts
{
get { return ScriptList.Where(lf => lf.Enabled); }
}
public readonly LuaFileList ScriptList = new LuaFileList();
public abstract void CallExitEvent(LuaFile lf);
public abstract void CallFrameAfterEvent();
public abstract void CallFrameBeforeEvent();
public abstract void CallLoadStateEvent(string name);
public abstract void CallSaveStateEvent(string name);
public abstract void Close();
public abstract void EndLuaDrawing();
public abstract void ExecuteString(string command);
public abstract LuaFunctionList GetRegisteredFunctions();
public abstract void Restart(IEmulatorServiceProvider newServiceProvider);
public abstract EmuLuaLibrary.ResumeResult ResumeScriptFromThreadOf(LuaFile lf);
public abstract void SpawnAndSetFileThread(string pathToLoad, LuaFile lf);
public abstract void StartLuaDrawing();
public abstract void WindowClosed(IntPtr handle);
}
}

View File

@ -7,10 +7,11 @@ using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -78,7 +79,7 @@ namespace BizHawk.Client.EmuHawk
LuaSandbox.DefaultLogger = ConsoleLog; LuaSandbox.DefaultLogger = ConsoleLog;
} }
public EmuLuaLibrary LuaImp { get; private set; } public PlatformEmuLuaLibrary LuaImp { get; private set; }
public bool UpdateBefore => true; public bool UpdateBefore => true;
@ -154,15 +155,15 @@ namespace BizHawk.Client.EmuHawk
foreach (var file in runningScripts) foreach (var file in runningScripts)
{ {
LuaImp.CallExitEvent(file.Thread); LuaImp.CallExitEvent(file);
var functions = LuaImp.RegisteredFunctions var functions = LuaImp.GetRegisteredFunctions()
.Where(lf => lf.Lua == file.Thread) .Where(lf => lf.Lua == file.Thread)
.ToList(); .ToList();
foreach (var function in functions) foreach (var function in functions)
{ {
LuaImp.RegisteredFunctions.Remove(function); LuaImp.GetRegisteredFunctions().Remove(function);
} }
UpdateRegisteredFunctionsDialog(); UpdateRegisteredFunctionsDialog();
@ -172,7 +173,9 @@ namespace BizHawk.Client.EmuHawk
} }
var currentScripts = LuaImp?.ScriptList; // Temp fix for now var currentScripts = LuaImp?.ScriptList; // Temp fix for now
LuaImp = new EmuLuaLibrary(Emulator.ServiceProvider); LuaImp = PlatformLinkedLibSingleton.RunningOnUnix
? (PlatformEmuLuaLibrary) new NotReallyLuaLibrary()
: (PlatformEmuLuaLibrary) new EmuLuaLibrary(Emulator.ServiceProvider);
if (currentScripts != null) if (currentScripts != null)
{ {
LuaImp.ScriptList.AddRange(currentScripts); LuaImp.ScriptList.AddRange(currentScripts);
@ -188,7 +191,7 @@ namespace BizHawk.Client.EmuHawk
{ {
LuaSandbox.Sandbox(file.Thread, () => LuaSandbox.Sandbox(file.Thread, () =>
{ {
file.Thread = LuaImp.SpawnCoroutine(pathToLoad); LuaImp.SpawnAndSetFileThread(pathToLoad, file);
LuaSandbox.CreateSandbox(file.Thread, Path.GetDirectoryName(pathToLoad)); LuaSandbox.CreateSandbox(file.Thread, Path.GetDirectoryName(pathToLoad));
file.State = LuaFile.RunState.Running; file.State = LuaFile.RunState.Running;
}, () => }, () =>
@ -306,7 +309,7 @@ namespace BizHawk.Client.EmuHawk
LuaSandbox.Sandbox(null, () => LuaSandbox.Sandbox(null, () =>
{ {
string pathToLoad = ProcessPath(file.Path); string pathToLoad = ProcessPath(file.Path);
file.Thread = LuaImp.SpawnCoroutine(file.Path); LuaImp.SpawnAndSetFileThread(file.Path, file);
LuaSandbox.CreateSandbox(file.Thread, Path.GetDirectoryName(pathToLoad)); LuaSandbox.CreateSandbox(file.Thread, Path.GetDirectoryName(pathToLoad));
}, () => }, () =>
{ {
@ -552,10 +555,10 @@ namespace BizHawk.Client.EmuHawk
var prohibit = lf.FrameWaiting && !includeFrameWaiters; var prohibit = lf.FrameWaiting && !includeFrameWaiters;
if (!prohibit) if (!prohibit)
{ {
var result = LuaImp.ResumeScript(lf.Thread); var result = LuaImp.ResumeScriptFromThreadOf(lf);
if (result.Terminated) if (result.Terminated)
{ {
LuaImp.CallExitEvent(lf.Thread); LuaImp.CallExitEvent(lf);
lf.Stop(); lf.Stop();
UpdateDialog(); UpdateDialog();
} }
@ -786,7 +789,7 @@ namespace BizHawk.Client.EmuHawk
SelectAllMenuItem.Enabled = LuaImp.ScriptList.Any(); SelectAllMenuItem.Enabled = LuaImp.ScriptList.Any();
StopAllScriptsMenuItem.Enabled = LuaImp.ScriptList.Any(script => script.Enabled); StopAllScriptsMenuItem.Enabled = LuaImp.ScriptList.Any(script => script.Enabled);
RegisteredFunctionsMenuItem.Enabled = LuaImp.RegisteredFunctions.Any(); RegisteredFunctionsMenuItem.Enabled = LuaImp.GetRegisteredFunctions().Any();
} }
private void NewScriptMenuItem_Click(object sender, EventArgs e) private void NewScriptMenuItem_Click(object sender, EventArgs e)
@ -840,26 +843,26 @@ namespace BizHawk.Client.EmuHawk
else if (!file.Enabled && file.Thread != null) else if (!file.Enabled && file.Thread != null)
{ {
LuaImp.CallExitEvent(file.Thread); LuaImp.CallExitEvent(file);
var items = SelectedItems.ToList(); var items = SelectedItems.ToList();
foreach (var sitem in items) foreach (var sitem in items)
{ {
var temp = sitem; var temp = sitem;
var functions = LuaImp.RegisteredFunctions.Where(lf => lf.Lua == temp.Thread).ToList(); var functions = LuaImp.GetRegisteredFunctions().Where(lf => lf.Lua == temp.Thread).ToList();
foreach (var function in functions) foreach (var function in functions)
{ {
LuaImp.RegisteredFunctions.Remove(function); LuaImp.GetRegisteredFunctions().Remove(function);
} }
UpdateRegisteredFunctionsDialog(); UpdateRegisteredFunctionsDialog();
} }
LuaImp.CallExitEvent(file.Thread); LuaImp.CallExitEvent(file);
file.Stop(); file.Stop();
if (Global.Config.RemoveRegisteredFunctionsOnToggle) if (Global.Config.RemoveRegisteredFunctionsOnToggle)
{ {
LuaImp.RegisteredFunctions.ClearAll(); LuaImp.GetRegisteredFunctions().ClearAll();
} }
} }
} }
@ -879,7 +882,7 @@ namespace BizHawk.Client.EmuHawk
? item.Path ? item.Path
: PathManager.MakeProgramRelativePath(item.Path); : PathManager.MakeProgramRelativePath(item.Path);
item.Thread = LuaImp.SpawnCoroutine(pathToLoad); LuaImp.SpawnAndSetFileThread(pathToLoad, item);
LuaSandbox.CreateSandbox(item.Thread, Path.GetDirectoryName(pathToLoad)); LuaSandbox.CreateSandbox(item.Thread, Path.GetDirectoryName(pathToLoad));
}, () => }, () =>
{ {
@ -933,10 +936,10 @@ namespace BizHawk.Client.EmuHawk
foreach (var item in items) foreach (var item in items)
{ {
var temp = item; var temp = item;
var functions = LuaImp.RegisteredFunctions.Where(x => x.Lua == temp.Thread).ToList(); var functions = LuaImp.GetRegisteredFunctions().Where(x => x.Lua == temp.Thread).ToList();
foreach (var function in functions) foreach (var function in functions)
{ {
LuaImp.RegisteredFunctions.Remove(function); LuaImp.GetRegisteredFunctions().Remove(function);
} }
LuaImp.ScriptList.Remove(item); LuaImp.ScriptList.Remove(item);
@ -1052,7 +1055,7 @@ namespace BizHawk.Client.EmuHawk
private void RegisteredFunctionsMenuItem_Click(object sender, EventArgs e) private void RegisteredFunctionsMenuItem_Click(object sender, EventArgs e)
{ {
if (LuaImp.RegisteredFunctions.Any()) if (LuaImp.GetRegisteredFunctions().Any())
{ {
var alreadyOpen = false; var alreadyOpen = false;
foreach (Form form in Application.OpenForms) foreach (Form form in Application.OpenForms)
@ -1209,7 +1212,7 @@ namespace BizHawk.Client.EmuHawk
private void ConsoleContextMenu_Opening(object sender, CancelEventArgs e) private void ConsoleContextMenu_Opening(object sender, CancelEventArgs e)
{ {
RegisteredFunctionsContextItem.Enabled = LuaImp.RegisteredFunctions.Any(); RegisteredFunctionsContextItem.Enabled = LuaImp.GetRegisteredFunctions().Any();
CopyContextItem.Enabled = OutputBox.SelectedText.Any(); CopyContextItem.Enabled = OutputBox.SelectedText.Any();
ClearConsoleContextItem.Enabled = ClearConsoleContextItem.Enabled =
SelectAllContextItem.Enabled = SelectAllContextItem.Enabled =

View File

@ -373,7 +373,6 @@ namespace BizHawk.Client.EmuHawk
boxBackground.FillRectangle(GetBrush(backcolor ?? _defaultTextBackground.Value), rect); boxBackground.FillRectangle(GetBrush(backcolor ?? _defaultTextBackground.Value), rect);
boxBackground = Graphics.FromImage(Image); boxBackground = Graphics.FromImage(Image);
boxBackground.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; boxBackground.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
boxBackground = Graphics.FromImage(Image);
boxBackground.DrawString(message, font, new SolidBrush(forecolor ?? Color.Black), x, y); boxBackground.DrawString(message, font, new SolidBrush(forecolor ?? Color.Black), x, y);
} }

View File

@ -17,7 +17,7 @@ namespace BizHawk.Client.EmuHawk
public void UpdateValues() public void UpdateValues()
{ {
if (GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions.Any()) if (GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions().Any())
{ {
PopulateListView(); PopulateListView();
} }
@ -46,7 +46,7 @@ namespace BizHawk.Client.EmuHawk
{ {
FunctionView.Items.Clear(); FunctionView.Items.Clear();
var nlfs = GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions.OrderBy(x => x.Event).ThenBy(x => x.Name).ToList(); var nlfs = GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions().OrderBy(x => x.Event).ThenBy(x => x.Name).ToList();
foreach (var nlf in nlfs) foreach (var nlf in nlfs)
{ {
var item = new ListViewItem { Text = nlf.Event }; var item = new ListViewItem { Text = nlf.Event };
@ -76,7 +76,7 @@ namespace BizHawk.Client.EmuHawk
foreach (int index in indices) foreach (int index in indices)
{ {
var guid = FunctionView.Items[index].SubItems[2].Text; var guid = FunctionView.Items[index].SubItems[2].Text;
GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions[guid].Call(); GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions()[guid].Call();
} }
} }
} }
@ -89,8 +89,8 @@ namespace BizHawk.Client.EmuHawk
foreach (int index in indices) foreach (int index in indices)
{ {
var guid = FunctionView.Items[index].SubItems[2].Text; var guid = FunctionView.Items[index].SubItems[2].Text;
var nlf = GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions[guid]; var nlf = GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions()[guid];
GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions.Remove(nlf); GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions().Remove(nlf);
} }
PopulateListView(); PopulateListView();
@ -109,7 +109,7 @@ namespace BizHawk.Client.EmuHawk
private void RemoveAllBtn_Click(object sender, EventArgs e) private void RemoveAllBtn_Click(object sender, EventArgs e)
{ {
GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions.ClearAll(); GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions().ClearAll();
PopulateListView(); PopulateListView();
} }
@ -118,7 +118,7 @@ namespace BizHawk.Client.EmuHawk
var indexes = FunctionView.SelectedIndices; var indexes = FunctionView.SelectedIndices;
CallButton.Enabled = indexes.Count > 0; CallButton.Enabled = indexes.Count > 0;
RemoveButton.Enabled = indexes.Count > 0; RemoveButton.Enabled = indexes.Count > 0;
RemoveAllBtn.Enabled = GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions.Any(); RemoveAllBtn.Enabled = GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions().Any();
} }
private void FunctionView_KeyDown(object sender, KeyEventArgs e) private void FunctionView_KeyDown(object sender, KeyEventArgs e)

View File

@ -9,9 +9,11 @@ using System.Windows.Forms;
using BizHawk.Client.ApiHawk; using BizHawk.Client.ApiHawk;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Emulation.Common; using BizHawk.Client.EmuHawk;
using BizHawk.Common.ReflectionExtensions;
using BizHawk.Client.EmuHawk.CoreExtensions; using BizHawk.Client.EmuHawk.CoreExtensions;
using BizHawk.Common;
using BizHawk.Common.ReflectionExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -738,6 +740,8 @@ namespace BizHawk.Client.EmuHawk
return false; return false;
} }
if (t == typeof(LuaConsole) && PlatformLinkedLibSingleton.RunningOnUnix) return false;
var tool = Assembly var tool = Assembly
.GetExecutingAssembly() .GetExecutingAssembly()
.GetTypes() .GetTypes()

View File

@ -39,7 +39,6 @@
this.SelectAllContextMenu = new System.Windows.Forms.ToolStripMenuItem(); this.SelectAllContextMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ClearContextMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ClearContextMenu = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1 = new MenuStripEx(); this.menuStrip1 = new MenuStripEx();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.FileSubMenu = new System.Windows.Forms.ToolStripMenuItem(); this.FileSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.SaveLogMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.SaveLogMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
@ -149,7 +148,6 @@
// //
this.menuStrip1.ClickThrough = true; this.menuStrip1.ClickThrough = true;
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem1,
this.FileSubMenu, this.FileSubMenu,
this.EditSubMenu, this.EditSubMenu,
this.OptionsSubMenu}); this.OptionsSubMenu});
@ -159,11 +157,6 @@
this.menuStrip1.TabIndex = 2; this.menuStrip1.TabIndex = 2;
this.menuStrip1.Text = "menuStrip1"; this.menuStrip1.Text = "menuStrip1";
// //
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(12, 20);
//
// FileSubMenu // FileSubMenu
// //
this.FileSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.FileSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -371,7 +364,6 @@
private System.Windows.Forms.GroupBox TracerBox; private System.Windows.Forms.GroupBox TracerBox;
private MenuStripEx menuStrip1; private MenuStripEx menuStrip1;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem FileSubMenu; private System.Windows.Forms.ToolStripMenuItem FileSubMenu;
private System.Windows.Forms.ToolStripMenuItem SaveLogMenuItem; private System.Windows.Forms.ToolStripMenuItem SaveLogMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;

View File

@ -84,6 +84,7 @@
<Compile Include="Log.cs" /> <Compile Include="Log.cs" />
<Compile Include="MruStack.cs" /> <Compile Include="MruStack.cs" />
<Compile Include="NDBDatabase.cs" /> <Compile Include="NDBDatabase.cs" />
<Compile Include="PlatformLinkedLibSingleton.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="QuickCollections.cs" /> <Compile Include="QuickCollections.cs" />
<Compile Include="Serializer.cs" /> <Compile Include="Serializer.cs" />

View File

@ -8,41 +8,24 @@ namespace BizHawk.Common.BizInvoke
public class DynamicLibraryImportResolver : IImportResolver, IDisposable public class DynamicLibraryImportResolver : IImportResolver, IDisposable
{ {
private IntPtr _p; private IntPtr _p;
private readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager;
public DynamicLibraryImportResolver(string dllName) public DynamicLibraryImportResolver(string dllName)
{ {
#if !MONO _p = libLoader.LoadPlatformSpecific(dllName);
_p = Win32.LoadLibrary(dllName); if (_p == IntPtr.Zero) throw new InvalidOperationException("null pointer returned by LoadPlatformSpecific");
#else
// TODO: how can we read name remaps out of app.confg <dllmap> ?
_p = Libdl.dlopen(dllName, Libdl.RTLD_NOW);
#endif
if (_p == IntPtr.Zero)
{
throw new InvalidOperationException("LoadLibrary returned NULL");
}
} }
public IntPtr Resolve(string entryPoint) public IntPtr Resolve(string entryPoint)
{ {
#if !MONO return libLoader.GetProcAddr(_p, entryPoint);
return Win32.GetProcAddress(_p, entryPoint);
#else
return Libdl.dlsym(_p, entryPoint);
#endif
} }
private void Free() private void Free()
{ {
if (_p != IntPtr.Zero) if (_p == IntPtr.Zero) return;
{ libLoader.FreePlatformSpecific(_p);
#if !MONO _p = IntPtr.Zero;
Win32.FreeLibrary(_p);
#else
Libdl.dlclose(_p);
#endif
_p = IntPtr.Zero;
}
} }
public void Dispose() public void Dispose()
@ -55,30 +38,5 @@ namespace BizHawk.Common.BizInvoke
{ {
Free(); Free();
} }
#if !MONO
private static class Win32
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
}
#else
private static class Libdl
{
[DllImport("libdl.so")]
public static extern IntPtr dlopen(string filename, int flags);
[DllImport("libdl.so")]
public static extern IntPtr dlsym(IntPtr handle, string symbol);
[DllImport("libdl.so")]
public static extern int dlclose(IntPtr handle);
public const int RTLD_NOW = 2;
}
#endif
} }
} }

View File

@ -9,6 +9,8 @@ namespace BizHawk.Common.BizInvoke
{ {
public sealed class MemoryBlock : IDisposable public sealed class MemoryBlock : IDisposable
{ {
//TODO rewrite this class without using the external functions in Kernel32 - this may help: https://docs.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files
/// <summary> /// <summary>
/// starting address of the memory block /// starting address of the memory block
/// </summary> /// </summary>
@ -442,37 +444,10 @@ namespace BizHawk.Common.BizInvoke
private static class Kernel32 private static class Kernel32
{ {
[DllImport("kernel32.dll", SetLastError = true)]
public static extern UIntPtr VirtualAlloc(UIntPtr lpAddress, UIntPtr dwSize,
AllocationType flAllocationType, MemoryProtection flProtect);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualFree(UIntPtr lpAddress, UIntPtr dwSize,
FreeType dwFreeType);
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualProtect(UIntPtr lpAddress, UIntPtr dwSize, public static extern bool VirtualProtect(UIntPtr lpAddress, UIntPtr dwSize,
MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect); MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect);
public enum FreeType : uint
{
DECOMMIT = 0x4000,
RELEASE = 0x8000
}
[Flags]
public enum AllocationType : uint
{
COMMIT = 0x1000,
RESERVE = 0x2000,
RESET = 0x80000,
RESET_UNDO = 0x1000000,
LARGE_PAGES = 0x20000000,
PHYSICAL = 0x400000,
TOP_DOWN = 0x100000,
WRITE_WATCH = 0x200000
}
[Flags] [Flags]
public enum MemoryProtection : uint public enum MemoryProtection : uint
{ {

View File

@ -0,0 +1,86 @@
using System;
using System.Runtime.InteropServices;
namespace BizHawk.Common
{
public sealed class PlatformLinkedLibSingleton
{
public static readonly bool RunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX;
private static readonly Lazy<PlatformLinkedLibManager> lazy = new Lazy<PlatformLinkedLibManager>(() => RunningOnUnix
? (PlatformLinkedLibManager) new UnixMonoLinkedLibManager()
: (PlatformLinkedLibManager) new Win32LinkedLibManager());
public static PlatformLinkedLibManager LinkedLibManager { get { return lazy.Value; } }
private PlatformLinkedLibSingleton() {}
public interface PlatformLinkedLibManager
{
IntPtr LoadPlatformSpecific(string dllToLoad);
IntPtr GetProcAddr(IntPtr hModule, string procName);
int FreePlatformSpecific(IntPtr hModule);
}
public class UnixMonoLinkedLibManager : PlatformLinkedLibManager
{
// This class is copied from a tutorial, so don't git blame and then email me expecting insight.
const int RTLD_NOW = 2;
[DllImport("libdl.so.2")]
private static extern IntPtr dlopen(String fileName, int flags);
[DllImport("libdl.so.2")]
private static extern IntPtr dlerror();
[DllImport("libdl.so.2")]
private static extern IntPtr dlsym(IntPtr handle, String symbol);
[DllImport("libdl.so.2")]
private static extern int dlclose(IntPtr handle);
public IntPtr LoadPlatformSpecific(string dllToLoad)
{
return dlopen(dllToLoad, RTLD_NOW);
}
public IntPtr GetProcAddr(IntPtr hModule, string procName)
{
dlerror();
var res = dlsym(hModule, procName);
var errPtr = dlerror();
if (errPtr != IntPtr.Zero) throw new InvalidOperationException($"error in dlsym: {Marshal.PtrToStringAnsi(errPtr)}");
return res;
}
public int FreePlatformSpecific(IntPtr hModule)
{
return dlclose(hModule);
}
}
public class Win32LinkedLibManager : PlatformLinkedLibManager
{
[DllImport("kernel32.dll")]
private static extern UInt32 GetLastError();
// was annotated `[DllImport("kernel32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true)]` in SevenZip.NativeMethods
// param dllToLoad was annotated `[MarshalAs(UnmanagedType.LPStr)]` in SevenZip.NativeMethods
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string dllToLoad);
// was annotated `[DllImport("kernel32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true)]` in SevenZip.NativeMethods
// param procName was annotated `[MarshalAs(UnmanagedType.LPStr)]` in SevenZip.NativeMethods
[DllImport("kernel32.dll")]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
// was annotated `[return: MarshalAs(UnmanagedType.Bool)]` in SevenZip.NativeMethods
[DllImport("kernel32.dll")]
private static extern bool FreeLibrary(IntPtr hModule);
public IntPtr LoadPlatformSpecific(string dllToLoad)
{
var p = LoadLibrary(dllToLoad);
if (p == IntPtr.Zero) throw new InvalidOperationException($"got null pointer, error code {GetLastError()}");
return p;
}
public IntPtr GetProcAddr(IntPtr hModule, string procName)
{
return GetProcAddress(hModule, procName);
}
public int FreePlatformSpecific(IntPtr hModule)
{
return FreeLibrary(hModule) ? 1 : 0;
}
}
}
}

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// ReSharper disable StyleCop.SA1300 // ReSharper disable StyleCop.SA1300
@ -17,12 +17,12 @@ namespace BizHawk.Emulation.Common
/** Creates new buffer that can hold at most sample_count samples. Sets rates /** Creates new buffer that can hold at most sample_count samples. Sets rates
so that there are blip_max_ratio clocks per sample. Returns pointer to new so that there are blip_max_ratio clocks per sample. Returns pointer to new
buffer, or NULL if insufficient memory. */ buffer, or NULL if insufficient memory. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr blip_new(int sample_count); public static extern IntPtr blip_new(int sample_count);
/** Sets approximate input clock rate and output sample rate. For every /** Sets approximate input clock rate and output sample rate. For every
clock_rate input clocks, approximately sample_rate samples are generated. */ clock_rate input clocks, approximately sample_rate samples are generated. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern void blip_set_rates(IntPtr context, double clock_rate, double sample_rate); public static extern void blip_set_rates(IntPtr context, double clock_rate, double sample_rate);
/** Maximum clock_rate/sample_rate ratio. For a given sample_rate, /** Maximum clock_rate/sample_rate ratio. For a given sample_rate,
@ -30,20 +30,20 @@ namespace BizHawk.Emulation.Common
public const int BlipMaxRatio = 1 << 20; public const int BlipMaxRatio = 1 << 20;
/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */ /** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern void blip_clear(IntPtr context); public static extern void blip_clear(IntPtr context);
/** Adds positive/negative delta into buffer at specified clock time. */ /** Adds positive/negative delta into buffer at specified clock time. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern void blip_add_delta(IntPtr context, uint clock_time, int delta); public static extern void blip_add_delta(IntPtr context, uint clock_time, int delta);
/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */ /** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern void blip_add_delta_fast(IntPtr context, uint clock_time, int delta); public static extern void blip_add_delta_fast(IntPtr context, uint clock_time, int delta);
/** Length of time frame, in clocks, needed to make sample_count additional /** Length of time frame, in clocks, needed to make sample_count additional
samples available. */ samples available. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern int blip_clocks_needed(IntPtr context, int sample_count); public static extern int blip_clocks_needed(IntPtr context, int sample_count);
/** Maximum number of samples that can be generated from one time frame. */ /** Maximum number of samples that can be generated from one time frame. */
@ -54,24 +54,24 @@ namespace BizHawk.Emulation.Common
the new time frame specifies the same clock as clock_duration in the old time the new time frame specifies the same clock as clock_duration in the old time
frame specified. Deltas can have been added slightly past clock_duration (up to frame specified. Deltas can have been added slightly past clock_duration (up to
however many clocks there are in two output samples). */ however many clocks there are in two output samples). */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern void blip_end_frame(IntPtr context, uint clock_duration); public static extern void blip_end_frame(IntPtr context, uint clock_duration);
/** Number of buffered samples available for reading. */ /** Number of buffered samples available for reading. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern int blip_samples_avail(IntPtr context); public static extern int blip_samples_avail(IntPtr context);
/** Reads and removes at most 'count' samples and writes them to 'out'. If /** Reads and removes at most 'count' samples and writes them to 'out'. If
'stereo' is true, writes output to every other element of 'out', allowing easy 'stereo' is true, writes output to every other element of 'out', allowing easy
interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed
samples. Returns number of samples actually read. */ samples. Returns number of samples actually read. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern int blip_read_samples(IntPtr context, short[] @out, int count, int stereo); public static extern int blip_read_samples(IntPtr context, short[] @out, int count, int stereo);
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern int blip_read_samples(IntPtr context, IntPtr @out, int count, int stereo); public static extern int blip_read_samples(IntPtr context, IntPtr @out, int count, int stereo);
/** Frees buffer. No effect if NULL is passed. */ /** Frees buffer. No effect if NULL is passed. */
[DllImport("blip_buf.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("blip_buf", CallingConvention = CallingConvention.Cdecl)]
public static extern void blip_delete(IntPtr context); public static extern void blip_delete(IntPtr context);
} }

View File

@ -317,27 +317,33 @@
<Compile Include="Computers\Commodore64\SaveState.cs" /> <Compile Include="Computers\Commodore64\SaveState.cs" />
<Compile Include="Computers\Commodore64\User\UserPortDevice.cs" /> <Compile Include="Computers\Commodore64\User\UserPortDevice.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IFDDHost.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IFDDHost.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\StandardKeyboard.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\AY38912.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\AY38912.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\Beeper.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\Beeper.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\CPUMonitor.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Memory.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Port.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Screen.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ULA.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Screen.cs" />
<Compile Include="Computers\SinclairSpectrum\Media\Disk\FloppyDisk.cs" /> <Compile Include="Computers\SinclairSpectrum\Media\Disk\FloppyDisk.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IJoystick.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IJoystick.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IPortIODevice.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IPortIODevice.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IPSG.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IPSG.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\CHRN.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Disk\CHRN.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.Definitions.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.Definitions.cs">
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.FDC.cs" /> <DependentUpon>NECUPD765.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.FDD.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.IPortIODevice.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.FDC.cs">
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.Timing.cs" /> <DependentUpon>NECUPD765.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPS765.Static.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.FDD.cs">
<DependentUpon>NECUPD765.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.IPortIODevice.cs">
<DependentUpon>NECUPD765.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.Timing.cs">
<DependentUpon>NECUPD765.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPS765.Static.cs">
<DependentUpon>NECUPD765.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\CursorJoystick.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Input\CursorJoystick.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\SinclairJoystick2.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Input\SinclairJoystick2.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\SinclairJoystick1.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Input\SinclairJoystick1.cs" />
@ -346,10 +352,6 @@
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IKeyboard.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IKeyboard.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\KempstonJoystick.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Input\KempstonJoystick.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IBeeperDevice.cs" /> <Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IBeeperDevice.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Memory.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Port.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum16K\ZX16.cs" />
<Compile Include="Computers\SinclairSpectrum\Media\Disk\CPCFormat\CPCExtendedFloppyDisk.cs" /> <Compile Include="Computers\SinclairSpectrum\Media\Disk\CPCFormat\CPCExtendedFloppyDisk.cs" />
<Compile Include="Computers\SinclairSpectrum\Media\Disk\CPCFormat\CPCFloppyDisk.cs" /> <Compile Include="Computers\SinclairSpectrum\Media\Disk\CPCFormat\CPCFloppyDisk.cs" />
<Compile Include="Computers\SinclairSpectrum\Media\Disk\DiskType.cs" /> <Compile Include="Computers\SinclairSpectrum\Media\Disk\DiskType.cs" />
@ -372,30 +374,94 @@
<Compile Include="Computers\SinclairSpectrum\SoundProviderMixer.cs" /> <Compile Include="Computers\SinclairSpectrum\SoundProviderMixer.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\MachineType.cs" /> <Compile Include="Computers\SinclairSpectrum\Machine\MachineType.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.cs" /> <Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Input.cs" /> <Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Input.cs">
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Port.cs" /> <DependentUpon>SpectrumBase.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Memory.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2\ZX128Plus2.cs" /> <Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Port.cs">
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.cs" /> <DependentUpon>SpectrumBase.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.Memory.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.Port.cs" /> <Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Memory.cs">
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.cs" /> <DependentUpon>SpectrumBase.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Memory.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Port.cs" /> <Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Media.cs">
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.cs" /> <DependentUpon>SpectrumBase.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Memory.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\Hardware\Rom\RomData.cs" /> <Compile Include="Computers\SinclairSpectrum\Machine\ULA.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Controllers.cs" /> <Compile Include="Computers\SinclairSpectrum\Machine\CPUMonitor.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Memory.cs">
<DependentUpon>ZX48.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Port.cs">
<DependentUpon>ZX48.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Screen.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum16K\ZX16.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Memory.cs">
<DependentUpon>ZX128.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Port.cs">
<DependentUpon>ZX128.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Screen.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2\ZX128Plus2.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Memory.cs">
<DependentUpon>ZX128Plus2a.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Port.cs">
<DependentUpon>ZX128Plus2a.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Screen.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.Memory.cs">
<DependentUpon>ZX128Plus3.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.Port.cs">
<DependentUpon>ZX128Plus3.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Memory.cs">
<DependentUpon>Pentagon128.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Port.cs">
<DependentUpon>Pentagon128.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Screen.cs" />
<None Include="Computers\SinclairSpectrum\readme.md" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Rom\RomData.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.cs" /> <Compile Include="Computers\SinclairSpectrum\ZXSpectrum.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IDebuggable.cs" /> <Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IDebuggable.cs">
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IEmulator.cs" /> <DependentUpon>ZXSpectrum.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IInputPollable.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.ICodeDataLog.cs" /> <Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IEmulator.cs">
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IMemoryDomains.cs" /> <DependentUpon>ZXSpectrum.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.ISettable.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IStatable.cs" /> <Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IInputPollable.cs">
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Messaging.cs" /> <DependentUpon>ZXSpectrum.cs</DependentUpon>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Util.cs" /> </Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.ICodeDataLog.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IMemoryDomains.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.ISettable.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IStatable.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Messaging.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Util.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Controllers.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Atari\2600\Atari2600.cs" /> <Compile Include="Consoles\Atari\2600\Atari2600.cs" />
<Compile Include="Consoles\Atari\2600\Atari2600.Core.cs"> <Compile Include="Consoles\Atari\2600\Atari2600.Core.cs">
<DependentUpon>Atari2600.cs</DependentUpon> <DependentUpon>Atari2600.cs</DependentUpon>
@ -723,6 +789,31 @@
<DependentUpon>VBANext.cs</DependentUpon> <DependentUpon>VBANext.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Consoles\Nintendo\GBA\VBARegisterHelper.cs" /> <Compile Include="Consoles\Nintendo\GBA\VBARegisterHelper.cs" />
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.cs" />
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.ICodeDataLog.cs" />
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.IDebuggable.cs">
<DependentUpon>GBHawkLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.IEmulator.cs">
<DependentUpon>GBHawkLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.IInputPollable.cs">
<DependentUpon>GBHawkLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.IMemoryDomains.cs">
<DependentUpon>GBHawkLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.ISaveRam.cs">
<DependentUpon>GBHawkLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.ISettable.cs">
<DependentUpon>GBHawkLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLink.IStatable.cs">
<DependentUpon>GBHawkLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLinkControllerDeck.cs" />
<Compile Include="Consoles\Nintendo\GBHawkLink\GBHawkLinkControllers.cs" />
<Compile Include="Consoles\Nintendo\GBHawk\Audio.cs" /> <Compile Include="Consoles\Nintendo\GBHawk\Audio.cs" />
<Compile Include="Consoles\Nintendo\GBHawk\GBHawk.ICodeDataLog.cs" /> <Compile Include="Consoles\Nintendo\GBHawk\GBHawk.ICodeDataLog.cs" />
<Compile Include="Consoles\Nintendo\GBHawk\Mappers\Mapper_WisdomTree.cs" /> <Compile Include="Consoles\Nintendo\GBHawk\Mappers\Mapper_WisdomTree.cs" />
@ -1500,13 +1591,7 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\StandardKeyboard.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Port.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Screen.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Screen.cs" />
<None Include="Computers\AmstradCPC\readme.md" /> <None Include="Computers\AmstradCPC\readme.md" />
<None Include="Computers\SinclairSpectrum\readme.md" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Media.cs" />
<None Include="Consoles\Atari\docs\stella.pdf" /> <None Include="Consoles\Atari\docs\stella.pdf" />
<None Include="Consoles\Coleco\docs\colecovision tech1.pdf" /> <None Include="Consoles\Coleco\docs\colecovision tech1.pdf" />
<None Include="Consoles\Coleco\docs\colecovision tech2.pdf" /> <None Include="Consoles\Coleco\docs\colecovision tech2.pdf" />

View File

@ -131,13 +131,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <summary> /// <summary>
/// Should be fired at the end of every frame /// Should be fired at the end of every frame
/// Primary purpose is to detect tape traps and manage auto play (if/when this is ever implemented) /// Primary purpose is to detect tape traps and manage auto play
/// </summary> /// </summary>
public void EndFrame() public void EndFrame()
{ {
MonitorFrame(); MonitorFrame();
} }
/// <summary>
/// No longer in use
/// </summary>
public void StartFrame() public void StartFrame()
{ {
//_buzzer.ProcessPulseValue(currentState); //_buzzer.ProcessPulseValue(currentState);
@ -296,14 +299,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sbd.Append("("); sbd.Append("(");
sbd.Append((targetBlockId + 1) + " of " + _dataBlocks.Count()); sbd.Append((targetBlockId + 1) + " of " + _dataBlocks.Count());
sbd.Append(") : "); sbd.Append(") : ");
//sbd.Append("ID" + bl.BlockID.ToString("X2") + " - ");
sbd.Append(bl.BlockDescription); sbd.Append(bl.BlockDescription);
if (bl.MetaData.Count > 0) if (bl.MetaData.Count > 0)
{ {
sbd.Append(" - "); sbd.Append(" - ");
sbd.Append(bl.MetaData.First().Key + ": " + bl.MetaData.First().Value); sbd.Append(bl.MetaData.First().Key + ": " + bl.MetaData.First().Value);
//sbd.Append("\n");
//sbd.Append(bl.MetaData.Skip(1).First().Key + ": " + bl.MetaData.Skip(1).First().Value);
} }
if (skipForward) if (skipForward)
@ -522,7 +522,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sbd.Append("("); sbd.Append("(");
sbd.Append((_currentDataBlockIndex + 1) + " of " + _dataBlocks.Count()); sbd.Append((_currentDataBlockIndex + 1) + " of " + _dataBlocks.Count());
sbd.Append(") : "); sbd.Append(") : ");
//sbd.Append("ID" + bl.BlockID.ToString("X2") + " - ");
sbd.Append(bl.BlockDescription); sbd.Append(bl.BlockDescription);
if (bl.MetaData.Count > 0) if (bl.MetaData.Count > 0)
{ {
@ -532,14 +531,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
_machine.Spectrum.OSD_TapePlayingBlockInfo(sbd.ToString()); _machine.Spectrum.OSD_TapePlayingBlockInfo(sbd.ToString());
} }
// increment the current period position // increment the current period position
_position++; _position++;
if (_position >= _dataBlocks[_currentDataBlockIndex].DataPeriods.Count()) if (_position >= _dataBlocks[_currentDataBlockIndex].DataPeriods.Count())
{ {
// we have reached the end of the current block // we have reached the end of the current block
if (_dataBlocks[_currentDataBlockIndex].DataPeriods.Count() == 0) if (_dataBlocks[_currentDataBlockIndex].DataPeriods.Count() == 0)
{ {
// notify about the current block (we are skipping it because its empty) // notify about the current block (we are skipping it because its empty)
@ -548,13 +545,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sbd.Append("("); sbd.Append("(");
sbd.Append((_currentDataBlockIndex + 1) + " of " + _dataBlocks.Count()); sbd.Append((_currentDataBlockIndex + 1) + " of " + _dataBlocks.Count());
sbd.Append(") : "); sbd.Append(") : ");
//sbd.Append("ID" + bl.BlockID.ToString("X2") + " - ");
sbd.Append(bl.BlockDescription); sbd.Append(bl.BlockDescription);
if (bl.MetaData.Count > 0) if (bl.MetaData.Count > 0)
{ {
sbd.Append(" - "); sbd.Append(" - ");
sbd.Append(bl.MetaData.First().Key + ": " + bl.MetaData.First().Value); sbd.Append(bl.MetaData.First().Key + ": " + bl.MetaData.First().Value);
} }
_machine.Spectrum.OSD_TapePlayingSkipBlockInfo(sbd.ToString()); _machine.Spectrum.OSD_TapePlayingSkipBlockInfo(sbd.ToString());
} }
@ -583,7 +579,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
} }
_monitorTimeOut = 2000; _monitorTimeOut = 2000;
break; break;
case TapeCommand.STOP_THE_TAPE_48K: case TapeCommand.STOP_THE_TAPE_48K:
if (is48k) if (is48k)
@ -624,20 +619,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
} }
} }
// update waitEdge with current position within the current block // update waitEdge with current position within the current block
_waitEdge = _dataBlocks[_currentDataBlockIndex].DataPeriods[_position]; _waitEdge = _dataBlocks[_currentDataBlockIndex].DataPeriods.Count() > 0 ? _dataBlocks[_currentDataBlockIndex].DataPeriods[_position] : 0;
// flip the current state // flip the current state
FlipTapeState(); FlipTapeState();
} }
// update lastCycle and return currentstate // update lastCycle and return currentstate
_lastCycle = cpuCycle - (long)cycles; _lastCycle = cpuCycle - (long)cycles;
// play the buzzer
//_buzzer.ProcessPulseValue(false, currentState);
return currentState; return currentState;
} }
@ -649,6 +640,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <summary> /// <summary>
/// Flash loading implementation /// Flash loading implementation
/// (Deterministic Emulation must be FALSE) /// (Deterministic Emulation must be FALSE)
/// CURRENTLY NOT ENABLED/WORKING
/// </summary> /// </summary>
private bool FlashLoad() private bool FlashLoad()
{ {
@ -962,47 +954,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
if (_machine.UPDDiskDevice == null || !_machine.UPDDiskDevice.FDD_IsDiskLoaded) if (_machine.UPDDiskDevice == null || !_machine.UPDDiskDevice.FDD_IsDiskLoaded)
MonitorRead(); MonitorRead();
/*
if (TapeIsPlaying)
{
if (GetEarBit(_cpu.TotalExecutedCycles))
{
result &= ~(TAPE_BIT); // reset is EAR ON
}
else
{
result |= (TAPE_BIT); // set is EAR Off
}
}
else
{
if (_machine.KeyboardDevice.IsIssue2Keyboard)
{
if ((_machine.LASTULAOutByte & (EAR_BIT + MIC_BIT)) == 0)
{
result &= ~(TAPE_BIT);
}
else
{
result |= (TAPE_BIT);
}
}
else
{
if ((_machine.LASTULAOutByte & EAR_BIT) == 0)
{
result &= ~(TAPE_BIT);
}
else
{
result |= TAPE_BIT;
}
}
}
*/
return true; return true;
} }

View File

@ -183,7 +183,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
return (byte)index; return (byte)index;
} }
#region IPortIODevice #region IPortIODevice
/// <summary> /// <summary>

View File

@ -8,9 +8,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// Logical Beeper class /// Logical Beeper class
/// Represents the piezoelectric buzzer used in the Spectrum to produce sound /// Represents the piezoelectric buzzer used in the Spectrum to produce sound
/// The beeper is controlled by rapidly toggling bit 4 of port &FE /// The beeper is controlled by rapidly toggling bit 4 of port &FE
///
/// It is instantiated twice, once for speccy beeper output, and once tape buzzer emulation /// It is instantiated twice, once for speccy beeper output, and once tape buzzer emulation
///
/// This implementation uses BlipBuffer and should *always* output at 44100 with 882 samples per frame /// This implementation uses BlipBuffer and should *always* output at 44100 with 882 samples per frame
/// (so that it can be mixed easily further down the line) /// (so that it can be mixed easily further down the line)
/// </summary> /// </summary>

View File

@ -198,7 +198,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{ {
if (!pressed_TapeStatus) if (!pressed_TapeStatus)
{ {
//Spectrum.OSD_FireInputMessage(TapeStatus);
Spectrum.OSD_ShowTapeStatus(); Spectrum.OSD_ShowTapeStatus();
pressed_TapeStatus = true; pressed_TapeStatus = true;
} }
@ -269,7 +268,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{ {
if (!pressed_DiskStatus) if (!pressed_DiskStatus)
{ {
//Spectrum.OSD_FireInputMessage(TapeStatus);
Spectrum.OSD_ShowDiskStatus(); Spectrum.OSD_ShowDiskStatus();
pressed_DiskStatus = true; pressed_DiskStatus = true;
} }

View File

@ -63,6 +63,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
// load the media into the tape device // load the media into the tape device
tapeMediaIndex = result; tapeMediaIndex = result;
// fire osd message // fire osd message
if (!IsLoadState) if (!IsLoadState)
Spectrum.OSD_TapeInserted(); Spectrum.OSD_TapeInserted();
@ -232,10 +233,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
Spectrum.CoreComm.ShowMessage("You are trying to load one of more disk images.\n\n Please select ZX Spectrum +3 emulation immediately and reboot the core"); Spectrum.CoreComm.ShowMessage("You are trying to load one of more disk images.\n\n Please select ZX Spectrum +3 emulation immediately and reboot the core");
return; return;
} }
else
{
//Spectrum.CoreComm.ShowMessage("You are attempting to load a disk into the +3 disk drive.\n\nThis DOES NOT currently work properly but IS under active development.");
}
UPDDiskDevice.FDD_LoadDisk(diskImages[diskMediaIndex]); UPDDiskDevice.FDD_LoadDisk(diskImages[diskMediaIndex]);
} }

View File

@ -199,6 +199,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <summary> /// <summary>
/// Monitors ROM access /// Monitors ROM access
/// Used to auto start/stop the tape device when appropriate /// Used to auto start/stop the tape device when appropriate
/// * This isnt really used anymore for tape trap detection *
/// </summary> /// </summary>
/// <param name="addr"></param> /// <param name="addr"></param>
public virtual void TestForTapeTraps(int addr) public virtual void TestForTapeTraps(int addr)

View File

@ -34,22 +34,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="value"></param> /// <param name="value"></param>
public abstract void WritePort(ushort port, byte value); public abstract void WritePort(ushort port, byte value);
/// <summary>
/// Increments the CPU totalCycles counter by the tStates value specified
/// </summary>
/// <param name="tStates"></param>
//public virtual void PortContention(int tStates)
//{
// CPU.TotalExecutedCycles += tStates;
//}
/// <summary>
/// Simulates IO port contention based on the supplied address
/// This method is for 48k and 128k/+2 machines only and should be overridden for other models
/// </summary>
/// <param name="addr"></param>
//public abstract void ContendPort(ushort addr);
} }
} }

View File

@ -72,11 +72,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// </summary> /// </summary>
public virtual IJoystick[] JoystickCollection { get; set; } public virtual IJoystick[] JoystickCollection { get; set; }
/// <summary>
/// Signs whether the disk motor is on or off
/// </summary>
//protected bool DiskMotorState;
/// <summary> /// <summary>
/// +3/2a printer port strobe /// +3/2a printer port strobe
/// </summary> /// </summary>
@ -153,8 +148,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
FrameCompleted = false; FrameCompleted = false;
if (UPDDiskDevice == null || !UPDDiskDevice.FDD_IsDiskLoaded) //if (UPDDiskDevice == null || !UPDDiskDevice.FDD_IsDiskLoaded)
TapeDevice.StartFrame(); //TapeDevice.StartFrame();
if (_renderSound) if (_renderSound)
{ {

View File

@ -785,7 +785,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns> /// <returns></returns>
public int GetContentionValue(int tstate) public int GetContentionValue(int tstate)
{ {
//tstate += MemoryContentionOffset;
if (tstate >= FrameCycleLength) if (tstate >= FrameCycleLength)
tstate -= FrameCycleLength; tstate -= FrameCycleLength;
@ -801,7 +800,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns> /// <returns></returns>
public int GetPortContentionValue(int tstate) public int GetPortContentionValue(int tstate)
{ {
//tstate += PortContentionOffset;
if (tstate >= FrameCycleLength) if (tstate >= FrameCycleLength)
tstate -= FrameCycleLength; tstate -= FrameCycleLength;

View File

@ -18,8 +18,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
public ZX128Plus3(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks) public ZX128Plus3(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
{ {
Spectrum = spectrum; Spectrum = spectrum;
CPU = cpu; CPU = cpu;
CPUMon = new CPUMonitor(this); CPUMon = new CPUMonitor(this);
CPUMon.machineType = MachineType.ZXSpectrum128Plus3; CPUMon.machineType = MachineType.ZXSpectrum128Plus3;

View File

@ -22,8 +22,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
CPU = cpu; CPU = cpu;
CPUMon = new CPUMonitor(this); CPUMon = new CPUMonitor(this);
//ULADevice = new ULA48(this);
ULADevice = new Screen48(this); ULADevice = new Screen48(this);
BuzzerDevice = new Beeper(this); BuzzerDevice = new Beeper(this);

View File

@ -92,25 +92,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
SyncByteArrayDomain("RAM - BANK 7 (Shadow Screen)", _machine.RAM7); SyncByteArrayDomain("RAM - BANK 7 (Shadow Screen)", _machine.RAM7);
break; break;
} }
/*
SyncByteArrayDomain("ROM0", _machine.ROM0);
SyncByteArrayDomain("ROM1", _machine.ROM1);
SyncByteArrayDomain("ROM2", _machine.ROM2);
SyncByteArrayDomain("ROM3", _machine.ROM3);
SyncByteArrayDomain("RAM0", _machine.RAM0);
SyncByteArrayDomain("RAM1", _machine.RAM1);
SyncByteArrayDomain("RAM2", _machine.RAM2);
SyncByteArrayDomain("RAM3", _machine.RAM3);
SyncByteArrayDomain("RAM4", _machine.RAM4);
SyncByteArrayDomain("RAM5", _machine.RAM5);
SyncByteArrayDomain("RAM6", _machine.RAM6);
SyncByteArrayDomain("RAM7", _machine.RAM7);
*/
} }
private void SyncByteArrayDomain(string name, byte[] data) private void SyncByteArrayDomain(string name, byte[] data)
{ {
if (_memoryDomainsInit || _byteArrayDomains.ContainsKey(name)) if (_memoryDomainsInit || _byteArrayDomains.ContainsKey(name))
{ {
var m = _byteArrayDomains[name]; var m = _byteArrayDomains[name];
@ -120,8 +105,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{ {
var m = new MemoryDomainByteArray(name, MemoryDomain.Endian.Little, data, true, 1); var m = new MemoryDomainByteArray(name, MemoryDomain.Endian.Little, data, true, 1);
_byteArrayDomains.Add(name, m); _byteArrayDomains.Add(name, m);
} }
} }
} }
} }

View File

@ -242,6 +242,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
Dictionary<string, string> Data = new Dictionary<string, string>(); Dictionary<string, string> Data = new Dictionary<string, string>();
/// <summary>
/// Detailed info to be displayed within the settings UIs
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static ZXMachineMetaData GetMetaObject(MachineType type) public static ZXMachineMetaData GetMetaObject(MachineType type)
{ {
ZXMachineMetaData m = new ZXMachineMetaData(); ZXMachineMetaData m = new ZXMachineMetaData();
@ -345,6 +350,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
return m; return m;
} }
/// <summary>
/// Returns machine metadata as a formatted string (to be displayed in a textbox)
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static string GetMetaString(MachineType type) public static string GetMetaString(MachineType type)
{ {
var m = GetMetaObject(type); var m = GetMetaObject(type);
@ -410,8 +420,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sb.Append(builder[i]); sb.Append(builder[i]);
sb.Append("\r\n"); sb.Append("\r\n");
} }
//sb.Append("\r\n");
} }
return sb.ToString(); return sb.ToString();

View File

@ -35,7 +35,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
_machine.WriteBus(addr, value); _machine.WriteBus(addr, value);
} }
/// <summary>
/// Called by MainForm so that the core label can display a more detailed tooltip about the emulated spectrum model
/// </summary>
/// <returns></returns>
public string GetMachineType() public string GetMachineType()
{ {
string m = ""; string m = "";
@ -59,17 +62,31 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
case MachineType.ZXSpectrum128Plus3: case MachineType.ZXSpectrum128Plus3:
m = "(Amstrad) ZX Spectrum 128K +3"; m = "(Amstrad) ZX Spectrum 128K +3";
break; break;
case MachineType.Pentagon128:
m = "(Clone) Pentagon 128K";
break;
} }
return m; return m;
} }
/// <summary>
/// Called by MainForm - dumps a close approximation of the Spectaculator SZX snapshot format
/// DEV use only - this is nowhere near accurate
/// </summary>
/// <returns></returns>
public byte[] GetSZXSnapshot() public byte[] GetSZXSnapshot()
{ {
return SZX.ExportSZX(_machine); return SZX.ExportSZX(_machine);
//return System.Text.Encoding.Default.GetString(data);
} }
/// <summary>
/// Utility method to get MemberName from an object
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="memberAccess"></param>
/// <returns></returns>
public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess) public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{ {
return ((MemberExpression)memberAccess.Body).Member.Name; return ((MemberExpression)memberAccess.Body).Member.Name;

View File

@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte HDMA_ctrl public byte HDMA_ctrl
{ {
get { return (byte)(((HDMA_active ? 0 : 1) << 7) | ((HDMA_length >> 16) - 1)); } get { return (byte)(((HDMA_active ? 0 : 1) << 7) | ((HDMA_length >> 4) - 1)); }
} }
@ -53,6 +53,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public int last_HBL; public int last_HBL;
public bool HBL_HDMA_go; public bool HBL_HDMA_go;
public bool HBL_test; public bool HBL_test;
public byte LYC_t;
public int LYC_cd;
public override byte ReadReg(int addr) public override byte ReadReg(int addr)
{ {
@ -112,11 +114,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0xFF41: // STAT case 0xFF41: // STAT
// note that their is no stat interrupt bug in GBC // note that their is no stat interrupt bug in GBC
// writing to STAT during mode 0 or 1 causes a STAT IRQ // writing to STAT during mode 0 or 1 causes a STAT IRQ
if (LCDC.Bit(7) && !Core.GBC_compat) if (LCDC.Bit(7))
{ {
if (((STAT & 3) == 0) || ((STAT & 3) == 1)) if (!Core.GBC_compat)
{ {
LYC_INT = true; if (((STAT & 3) == 0) || ((STAT & 3) == 1))
{
LYC_INT = true;
}
}
if (value.Bit(6))
{
if (LY == LYC) { LYC_INT = true; }
else { LYC_INT = false; }
} }
} }
STAT = (byte)((value & 0xF8) | (STAT & 7) | 0x80); STAT = (byte)((value & 0xF8) | (STAT & 7) | 0x80);
@ -134,20 +145,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
LY = 0; /*reset*/ LY = 0; /*reset*/
break; break;
case 0xFF45: // LYC case 0xFF45: // LYC
LYC = value;
if (LCDC.Bit(7))
{
if (LY != LYC) { STAT &= 0xFB; LYC_INT = false; }
else { STAT |= 0x4; LYC_INT = true; }
// special case: at cycle 454, some strange things are happening, and it appears as though LY becomes LY + 1 // tests indicate that latching writes to LYC should take place 4 cycles after the write
// two cycles ahead of where it's supposed to. this is probably related to strange behaviour around cycle 452 // otherwise tests around LY boundaries will fail
if ((LY_inc == 0) && cycle == 6) LYC_t = value;
{ LYC_cd = 4;
//if (0 == LYC) { STAT |= 0x4; LYC_INT = true; }
//else { STAT &= 0xFB; LYC_INT = false; }
}
}
break; break;
case 0xFF46: // DMA case 0xFF46: // DMA
DMA_addr = value; DMA_addr = value;
@ -569,12 +571,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (LY_inc == 0) if (LY_inc == 0)
{ {
if (cycle == 10) if (cycle == 12)
{ {
LYC_INT = false; LYC_INT = false;
STAT &= 0xFB; STAT &= 0xFB;
} }
else if (cycle == 12) else if (cycle == 14)
{ {
// Special case of LY = LYC // Special case of LY = LYC
if ((LY == LYC) && !STAT.Bit(2)) if ((LY == LYC) && !STAT.Bit(2))
@ -587,7 +589,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
// here LY=LYC will be asserted or cleared (but only if LY isnt 0 as that's a special case) // here LY=LYC will be asserted or cleared (but only if LY isnt 0 as that's a special case)
if ((cycle == 2) && (LY != 0)) if ((cycle == 4) && (LY != 0))
{ {
if (LY_inc == 1) if (LY_inc == 1)
{ {
@ -595,7 +597,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
STAT &= 0xFB; STAT &= 0xFB;
} }
} }
else if ((cycle == 4) && (LY != 0)) else if ((cycle == 6) && (LY != 0))
{ {
if ((LY == LYC) && !STAT.Bit(2)) if ((LY == LYC) && !STAT.Bit(2))
{ {
@ -636,6 +638,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// process latch delays // process latch delays
//latch_delay(); //latch_delay();
if (LYC_cd > 0)
{
LYC_cd--;
if (LYC_cd == 0)
{
LYC = LYC_t;
if (LCDC.Bit(7))
{
if (LY != LYC) { STAT &= 0xFB; LYC_INT = false; }
else { STAT |= 0x4; LYC_INT = true; }
}
}
}
} }
// might be needed, not sure yet // might be needed, not sure yet
@ -1526,6 +1543,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("BG_bytes_index", ref BG_bytes_index); ser.Sync("BG_bytes_index", ref BG_bytes_index);
ser.Sync("OBJ_bytes_index", ref OBJ_bytes_index); ser.Sync("OBJ_bytes_index", ref OBJ_bytes_index);
ser.Sync("LYC_t", ref LYC_t);
ser.Sync("LYC_cd", ref LYC_cd);
base.SyncState(ser); base.SyncState(ser);
} }

View File

@ -159,7 +159,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
ticker++; ticker++;
//if (ticker > 10000000) { vblank_rise = true; }//throw new Exception("ERROR: Unable to Resolve Frame"); } // if (ticker > 10000000) { vblank_rise = true; }//throw new Exception("ERROR: Unable to Resolve Frame"); }
in_vblank_old = in_vblank; in_vblank_old = in_vblank;
REG_FF0F_OLD = REG_FF0F; REG_FF0F_OLD = REG_FF0F;
@ -168,6 +168,89 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
vblank_rise = false; vblank_rise = false;
} }
public void do_single_step()
{
// These things do not change speed in GBC double spped mode
audio.tick();
ppu.tick();
if (Use_MT) { mapper.Mapper_Tick(); }
if (!HDMA_transfer)
{
// These things all tick twice as fast in GBC double speed mode
ppu.DMA_tick();
timer.tick_1();
serialport.serial_transfer_tick();
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
timer.tick_2();
if (double_speed)
{
ppu.DMA_tick();
timer.tick_1();
serialport.serial_transfer_tick();
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
timer.tick_2();
}
}
else
{
timer.tick_1();
timer.tick_2();
cpu.TotalExecutedCycles++;
if (double_speed)
{
timer.tick_1();
timer.tick_2();
cpu.TotalExecutedCycles++;
}
}
if (in_vblank && !in_vblank_old)
{
vblank_rise = true;
}
in_vblank_old = in_vblank;
REG_FF0F_OLD = REG_FF0F;
}
public void do_controller_check()
{
// check if new input changed the input register and triggered IRQ
byte contr_prev = input_register;
input_register &= 0xF0;
if ((input_register & 0x30) == 0x20)
{
input_register |= (byte)(controller_state & 0xF);
}
else if ((input_register & 0x30) == 0x10)
{
input_register |= (byte)((controller_state & 0xF0) >> 4);
}
else if ((input_register & 0x30) == 0x00)
{
// if both polls are set, then a bit is zero if either or both pins are zero
byte temp = (byte)((controller_state & 0xF) & ((controller_state & 0xF0) >> 4));
input_register |= temp;
}
else
{
input_register |= 0xF;
}
// check for interrupts
if (((contr_prev & 8) > 0) && ((input_register & 8) == 0) ||
((contr_prev & 4) > 0) && ((input_register & 4) == 0) ||
((contr_prev & 2) > 0) && ((input_register & 2) == 0) ||
((contr_prev & 1) > 0) && ((input_register & 1) == 0))
{
if (REG_FFFF.Bit(4)) { cpu.FlagI = true; }
REG_FF0F |= 0x10;
}
}
// Switch Speed (GBC only) // Switch Speed (GBC only)
public int SpeedFunc(int temp) public int SpeedFunc(int temp)
{ {

View File

@ -90,6 +90,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("speed_switch", ref speed_switch); ser.Sync("speed_switch", ref speed_switch);
ser.Sync("HDMA_transfer", ref HDMA_transfer); ser.Sync("HDMA_transfer", ref HDMA_transfer);
ser.Sync("undoc_6C", ref undoc_6C);
ser.Sync("undoc_72", ref undoc_72);
ser.Sync("undoc_73", ref undoc_73);
ser.Sync("undoc_74", ref undoc_74);
ser.Sync("undoc_75", ref undoc_75);
ser.Sync("undoc_76", ref undoc_76);
ser.Sync("undoc_77", ref undoc_77);
ser.Sync("Use_MT", ref Use_MT); ser.Sync("Use_MT", ref Use_MT);
ser.Sync("addr_access", ref addr_access); ser.Sync("addr_access", ref addr_access);
@ -99,9 +107,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("cart_RAM", ref cart_RAM, false); ser.Sync("cart_RAM", ref cart_RAM, false);
} }
ser.EndSection();
ser.EndSection();
} }
} }
} }

View File

@ -3,7 +3,6 @@
using BizHawk.Common.BufferExtensions; using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.Components.LR35902; using BizHawk.Emulation.Common.Components.LR35902;
using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -56,6 +55,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public bool speed_switch; public bool speed_switch;
public bool HDMA_transfer; // stalls CPU when in progress public bool HDMA_transfer; // stalls CPU when in progress
// several undocumented GBC Registers
public byte undoc_6C, undoc_72, undoc_73, undoc_74, undoc_75, undoc_76, undoc_77;
public byte[] _bios; public byte[] _bios;
public readonly byte[] _rom; public readonly byte[] _rom;
public readonly byte[] header = new byte[0x50]; public readonly byte[] header = new byte[0x50];
@ -272,10 +274,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
private readonly GBHawkControllerDeck _controllerDeck; private readonly GBHawkControllerDeck _controllerDeck;
private void HardReset() public void HardReset()
{ {
GB_bios_register = 0; // bios enable GB_bios_register = 0; // bios enable
GBC_compat = true; GBC_compat = is_GBC;
in_vblank = true; // we start off in vblank since the LCD is off in_vblank = true; // we start off in vblank since the LCD is off
in_vblank_old = true; in_vblank_old = true;

View File

@ -101,7 +101,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// Speed Control for GBC // Speed Control for GBC
case 0xFF4D: case 0xFF4D:
if (is_GBC) if (GBC_compat)
{ {
ret = (byte)(((double_speed ? 1 : 0) << 7) + ((speed_switch ? 1 : 0))); ret = (byte)(((double_speed ? 1 : 0) << 7) + ((speed_switch ? 1 : 0)));
} }
@ -149,7 +149,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// Speed Control for GBC // Speed Control for GBC
case 0xFF70: case 0xFF70:
if (is_GBC) if (GBC_compat)
{ {
ret = (byte)RAM_Bank; ret = (byte)RAM_Bank;
} }
@ -159,6 +159,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
break; break;
case 0xFF6C:
if (GBC_compat) { ret = undoc_6C; }
else { ret = 0xFF; }
break;
case 0xFF72:
if (is_GBC) { ret = undoc_72; }
else { ret = 0xFF; }
break;
case 0xFF73:
if (is_GBC) { ret = undoc_73; }
else { ret = 0xFF; }
break;
case 0xFF74:
if (GBC_compat) { ret = undoc_74; }
else { ret = 0xFF; }
break;
case 0xFF75:
if (is_GBC) { ret = undoc_75; }
else { ret = 0xFF; }
break;
case 0xFF76:
if (is_GBC) { ret = undoc_76; }
else { ret = 0xFF; }
break;
case 0xFF77:
if (is_GBC) { ret = undoc_77; }
else { ret = 0xFF; }
break;
// interrupt control register // interrupt control register
case 0xFFFF: case 0xFFFF:
ret = REG_FFFF; ret = REG_FFFF;
@ -323,7 +358,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// Speed Control for GBC // Speed Control for GBC
case 0xFF4D: case 0xFF4D:
if (is_GBC) if (GBC_compat)
{ {
speed_switch = (value & 1) > 0; speed_switch = (value & 1) > 0;
} }
@ -365,13 +400,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// RAM Bank in GBC mode // RAM Bank in GBC mode
case 0xFF70: case 0xFF70:
//Console.WriteLine(value); //Console.WriteLine(value);
if (is_GBC) if (GBC_compat)
{ {
RAM_Bank = value & 7; RAM_Bank = value & 7;
if (RAM_Bank == 0) { RAM_Bank = 1; } if (RAM_Bank == 0) { RAM_Bank = 1; }
} }
break; break;
case 0xFF6C:
if (GBC_compat) { undoc_6C |= (byte)(value & 1); }
break;
case 0xFF72:
if (is_GBC) { undoc_72 = value; }
break;
case 0xFF73:
if (is_GBC) { undoc_73 = value; }
break;
case 0xFF74:
if (GBC_compat) { undoc_74 = value; }
break;
case 0xFF75:
if (is_GBC) { undoc_75 |= (byte)(value & 0x70); }
break;
case 0xFF76:
// read only
break;
case 0xFF77:
// read only
break;
// interrupt control register // interrupt control register
case 0xFFFF: case 0xFFFF:
REG_FFFF = value; REG_FFFF = value;
@ -401,6 +464,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public void Register_Reset() public void Register_Reset()
{ {
input_register = 0xCF; // not reading any input input_register = 0xCF; // not reading any input
//undocumented registers
undoc_6C = 0xFE;
undoc_72 = 0;
undoc_73 = 0;
undoc_74 = 0;
undoc_75 = 0x8F;
undoc_76 = 0;
undoc_77 = 0;
} }
} }
} }

View File

@ -16,6 +16,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public int serial_bits; public int serial_bits;
public bool clk_internal; public bool clk_internal;
public int clk_rate; public int clk_rate;
public byte going_out;
public byte coming_in;
public byte ReadReg(int addr) public byte ReadReg(int addr)
{ {
@ -84,16 +86,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (serial_start) if (serial_start)
{ {
if (serial_clock > 0) { serial_clock--; } if (serial_clock > 0) { serial_clock--; }
if (serial_clock == 0) if (serial_clock == 0)
{ {
if (serial_bits > 0) if (serial_bits > 0)
{ {
send_external_bit((byte)(serial_data & 0x80));
byte temp = get_external_bit(); byte temp = get_external_bit();
serial_data = (byte)((serial_data << 1) | temp); serial_data = (byte)((serial_data << 1) | temp);
serial_bits--; serial_bits--;
if (serial_bits == 0) if (serial_bits == 0)
{ {
serial_control &= 0x7F; serial_control &= 0x7F;
@ -122,12 +124,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// no device connected returns 0xFF // no device connected returns 0xFF
public byte get_external_bit() public byte get_external_bit()
{ {
return 1; return coming_in;
} }
// calling this function buts an external bit on the cable line
public void send_external_bit(byte bit_send) public void send_external_bit(byte bit_send)
{ {
going_out = (byte)(bit_send >> 7);
} }
public void Reset() public void Reset()
@ -135,6 +138,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
serial_control = 0x7E; serial_control = 0x7E;
serial_start = false; serial_start = false;
serial_data = 0x00; serial_data = 0x00;
going_out = 0;
coming_in = 1;
} }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
@ -146,6 +151,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("serial_bits", ref serial_bits); ser.Sync("serial_bits", ref serial_bits);
ser.Sync("clk_internal", ref clk_internal); ser.Sync("clk_internal", ref clk_internal);
ser.Sync("clk_rate", ref clk_rate); ser.Sync("clk_rate", ref clk_rate);
ser.Sync("going_out", ref going_out);
ser.Sync("coming_in", ref coming_in);
} }
} }
} }

View File

@ -0,0 +1,186 @@
using System;
using System.IO;
using System.Collections.Generic;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.Components.LR35902;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public partial class GBHawkLink : ICodeDataLogger
{
private ICodeDataLog _cdl;
public void SetCDL(ICodeDataLog cdl)
{
_cdl = cdl;
if (cdl == null)
this.L.cpu.CDLCallback = null;
else this.L.cpu.CDLCallback = CDLCpuCallback;
}
public void NewCDL(ICodeDataLog cdl)
{
cdl["ROM"] = new byte[MemoryDomains["ROM L"].Size];
cdl["HRAM"] = new byte[MemoryDomains["Zero Page RAM L"].Size];
cdl["WRAM"] = new byte[MemoryDomains["Main RAM L"].Size];
if (MemoryDomains.Has("Cart RAM L"))
{
cdl["CartRAM"] = new byte[MemoryDomains["Cart RAM L"].Size];
}
cdl.SubType = "GB";
cdl.SubVer = 0;
}
[FeatureNotImplemented]
void ICodeDataLogger.DisassembleCDL(Stream s, ICodeDataLog cdl)
{
}
public void SetCDL(LR35902.eCDLogMemFlags flags, string type, int cdladdr)
{
if (type == null) return;
byte val = (byte)flags;
_cdl[type][cdladdr] |= (byte)flags;
}
void CDLCpuCallback(ushort addr, LR35902.eCDLogMemFlags flags)
{
if (addr < 0x8000)
{
//don't record writes to the ROM, it's just noisy
//NOTE: in principle a mapper could mount a useful resource here, but I doubt it)
if ((flags & LR35902.eCDLogMemFlags.Write) != 0) return;
}
if (L.ppu.DMA_start)
{
// some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000)
{
if (L.ppu.DMA_addr < 0x80)
{
return;
}
else
{
L.mapper.MapCDL(addr, flags);
return;
}
}
else if ((addr >= 0xE000) && (addr < 0xF000))
{
SetCDL(flags, "WRAM", addr - 0xE000);
}
else if ((addr >= 0xF000) && (addr < 0xFE00))
{
SetCDL(flags, "WRAM", (L.RAM_Bank * 0x1000) + (addr - 0xF000));
}
else if ((addr >= 0xFE00) && (addr < 0xFEA0) && L.ppu.DMA_OAM_access)
{
return;
}
else if ((addr >= 0xFF00) && (addr < 0xFF80)) // The game GOAL! Requires Hardware Regs to be accessible
{
return;
}
else if ((addr >= 0xFF80))
{
SetCDL(flags, "HRAM", addr - 0xFF80);
}
}
if (addr < 0x900)
{
if (addr < 0x100)
{
// return Either BIOS ROM or Game ROM
if ((L.GB_bios_register & 0x1) == 0)
{
return;
}
else
{
L.mapper.MapCDL(addr, flags);
return;
}
}
else if (addr >= 0x200)
{
// return Either BIOS ROM or Game ROM
if (((L.GB_bios_register & 0x1) == 0) && L.is_GBC)
{
return;
}
else
{
L.mapper.MapCDL(addr, flags);
return;
}
}
else
{
L.mapper.MapCDL(addr, flags);
return;
}
}
else if (addr < 0x8000)
{
L.mapper.MapCDL(addr, flags);
return;
}
else if (addr < 0xA000)
{
return;
}
else if (addr < 0xC000)
{
L.mapper.MapCDL(addr, flags);
return;
}
else if (addr < 0xD000)
{
return;
}
else if (addr < 0xE000)
{
SetCDL(flags, "WRAM", (L.RAM_Bank * 0x1000) + (addr - 0xD000));
}
else if (addr < 0xF000)
{
SetCDL(flags, "WRAM", addr - 0xE000);
}
else if (addr < 0xFE00)
{
SetCDL(flags, "WRAM", (L.RAM_Bank * 0x1000) + (addr - 0xF000));
}
else if (addr < 0xFEA0)
{
return;
}
else if (addr < 0xFF00)
{
return;
}
else if (addr < 0xFF80)
{
return;
}
else if (addr < 0xFFFF)
{
SetCDL(flags, "HRAM", addr - 0xFF80);
}
else
{
return;
}
}
}
}

View File

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public partial class GBHawkLink : IDebuggable
{
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
return new Dictionary<string, RegisterValue>
{
/*
["A"] = cpu.A,
["X"] = cpu.X,
["Y"] = cpu.Y,
["S"] = cpu.S,
["PC"] = cpu.PC,
["Flag C"] = cpu.FlagC,
["Flag Z"] = cpu.FlagZ,
["Flag I"] = cpu.FlagI,
["Flag D"] = cpu.FlagD,
["Flag B"] = cpu.FlagB,
["Flag V"] = cpu.FlagV,
["Flag N"] = cpu.FlagN,
["Flag T"] = cpu.FlagT
*/
};
}
public void SetCpuRegister(string register, int value)
{
switch (register)
{
default:
throw new InvalidOperationException();
case "A":
//cpu.A = (byte)value;
break;
case "X":
//cpu.X = (byte)value;
break;
case "Y":
//cpu.Y = (byte)value;
break;
case "S":
//cpu.S = (byte)value;
break;
case "PC":
//cpu.PC = (ushort)value;
break;
case "Flag I":
//cpu.FlagI = value > 0;
break;
}
}
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" });
public bool CanStep(StepType type)
{
return false;
}
[FeatureNotImplemented]
public void Step(StepType type)
{
throw new NotImplementedException();
}
public long TotalExecutedCycles
{
get { return (long)L.cpu.TotalExecutedCycles; }
}
}
}

View File

@ -0,0 +1,287 @@
using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using BizHawk.Emulation.Cores.Nintendo.GBHawk;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public partial class GBHawkLink : IEmulator, IVideoProvider, ISoundProvider
{
public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition => _controllerDeck.Definition;
public byte controller_state;
public bool in_vblank_old;
public bool in_vblank;
public bool vblank_rise;
public void FrameAdvance(IController controller, bool render, bool rendersound)
{
//Console.WriteLine("-----------------------FRAME-----------------------");
//Update the color palette if a setting changed
if (linkSettings.Palette_L == GBHawk.GBHawk.GBSettings.PaletteType.BW)
{
L.color_palette[0] = color_palette_BW[0];
L.color_palette[1] = color_palette_BW[1];
L.color_palette[2] = color_palette_BW[2];
L.color_palette[3] = color_palette_BW[3];
}
else
{
L.color_palette[0] = color_palette_Gr[0];
L.color_palette[1] = color_palette_Gr[1];
L.color_palette[2] = color_palette_Gr[2];
L.color_palette[3] = color_palette_Gr[3];
}
if (linkSettings.Palette_R == GBHawk.GBHawk.GBSettings.PaletteType.BW)
{
R.color_palette[0] = color_palette_BW[0];
R.color_palette[1] = color_palette_BW[1];
R.color_palette[2] = color_palette_BW[2];
R.color_palette[3] = color_palette_BW[3];
}
else
{
R.color_palette[0] = color_palette_Gr[0];
R.color_palette[1] = color_palette_Gr[1];
R.color_palette[2] = color_palette_Gr[2];
R.color_palette[3] = color_palette_Gr[3];
}
if (_tracer.Enabled)
{
L.cpu.TraceCallback = s => _tracer.Put(s);
}
else
{
L.cpu.TraceCallback = null;
}
_frame++;
if (controller.IsPressed("Power"))
{
HardReset();
}
bool cablediscosignalNew = controller.IsPressed("Toggle Cable");
if (cablediscosignalNew && !_cablediscosignal)
{
_cableconnected ^= true;
Console.WriteLine("Cable connect status to {0}", _cableconnected);
LinkConnected = _cableconnected;
}
_cablediscosignal = cablediscosignalNew;
_islag = true;
GetControllerState(controller);
do_frame();
_islag = L._islag;
if (_islag)
{
_lagcount++;
}
}
public void do_frame()
{
L.do_controller_check();
R.do_controller_check();
// advance one full frame
for (int i = 0; i < 70224; i++)
{
L.do_single_step();
R.do_single_step();
// the signal to shift out a bit is when serial_clock = 1
if (L.serialport.serial_clock == 1)
{
if (LinkConnected)
{
L.serialport.send_external_bit((byte)(L.serialport.serial_data & 0x80));
if ((R.serialport.clk_rate == -1) && R.serialport.serial_start)
{
R.serialport.serial_clock = 1;
R.serialport.send_external_bit((byte)(R.serialport.serial_data & 0x80));
R.serialport.coming_in = L.serialport.going_out;
}
L.serialport.coming_in = R.serialport.going_out;
}
}
else if (R.serialport.serial_clock == 1)
{
if (LinkConnected)
{
R.serialport.send_external_bit((byte)(R.serialport.serial_data & 0x80));
if ((L.serialport.clk_rate == -1) && L.serialport.serial_start)
{
L.serialport.serial_clock = 1;
L.serialport.send_external_bit((byte)(L.serialport.serial_data & 0x80));
L.serialport.coming_in = R.serialport.going_out;
}
R.serialport.coming_in = L.serialport.going_out;
}
}
// if we hit a frame boundary, update video
if (L.vblank_rise)
{
buff_L = L.GetVideoBuffer();
L.vblank_rise = false;
}
if (R.vblank_rise)
{
buff_R = R.GetVideoBuffer();
R.vblank_rise = false;
}
}
}
public void GetControllerState(IController controller)
{
InputCallbacks.Call();
L.controller_state = _controllerDeck.ReadPort1(controller);
R.controller_state = _controllerDeck.ReadPort2(controller);
}
public int Frame => _frame;
public string SystemId => "DGB";
public bool DeterministicEmulation { get; set; }
public void ResetCounters()
{
_frame = 0;
_lagcount = 0;
_islag = false;
}
public CoreComm CoreComm { get; }
public void Dispose()
{
L.Dispose();
R.Dispose();
}
#region Video provider
public int _frameHz = 60;
public int[] _vidbuffer = new int[160 * 2 * 144];
public int[] buff_L = new int[160 * 144];
public int[] buff_R = new int[160 * 144];
public int[] GetVideoBuffer()
{
// combine the 2 video buffers from the instances
for (int i = 0; i < 144; i++)
{
for (int j = 0; j < 160; j++)
{
_vidbuffer[i * 320 + j] = buff_L[i * 160 + j];
_vidbuffer[i * 320 + j + 160] = buff_R[i * 160 + j];
}
}
return _vidbuffer;
}
public int VirtualWidth => 160 * 2;
public int VirtualHeight => 144;
public int BufferWidth => 160 * 2;
public int BufferHeight => 144;
public int BackgroundColor => unchecked((int)0xFF000000);
public int VsyncNumerator => _frameHz;
public int VsyncDenominator => 1;
public static readonly uint[] color_palette_BW = { 0xFFFFFFFF , 0xFFAAAAAA, 0xFF555555, 0xFF000000 };
public static readonly uint[] color_palette_Gr = { 0xFFA4C505, 0xFF88A905, 0xFF1D551D, 0xFF052505 };
public uint[] color_palette = new uint[4];
#endregion
#region audio
public bool CanProvideAsync => false;
public void SetSyncMode(SyncSoundMode mode)
{
if (mode != SyncSoundMode.Sync)
{
throw new InvalidOperationException("Only Sync mode is supported_");
}
}
public SyncSoundMode SyncMode => SyncSoundMode.Sync;
public void GetSamplesSync(out short[] samples, out int nsamp)
{
short[] temp_samp_L;
short[] temp_samp_R;
int nsamp_L;
int nsamp_R;
L.audio.GetSamplesSync(out temp_samp_L, out nsamp_L);
R.audio.GetSamplesSync(out temp_samp_R, out nsamp_R);
if (linkSettings.AudioSet == GBLinkSettings.AudioSrc.Left)
{
samples = temp_samp_L;
nsamp = nsamp_L;
}
else if (linkSettings.AudioSet == GBLinkSettings.AudioSrc.Right)
{
samples = temp_samp_R;
nsamp = nsamp_R;
}
else
{
samples = new short[0];
nsamp = 0;
}
}
public void GetSamplesAsync(short[] samples)
{
throw new NotSupportedException("Async is not available");
}
public void DiscardSamples()
{
L.audio.DiscardSamples();
R.audio.DiscardSamples();
}
private void GetSamples(short[] samples)
{
}
public void DisposeSound()
{
L.audio.DisposeSound();
R.audio.DisposeSound();
}
#endregion
}
}

View File

@ -0,0 +1,24 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public partial class GBHawkLink : IInputPollable
{
public int LagCount
{
get { return _lagcount; }
set { _lagcount = value; }
}
public bool IsLagFrame
{
get { return _islag; }
set { _islag = value; }
}
public IInputCallbackSystem InputCallbacks { get; } = new InputCallbackSystem();
public bool _islag = true;
private int _lagcount;
}
}

View File

@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public partial class GBHawkLink
{
private IMemoryDomains MemoryDomains;
public void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>
{
new MemoryDomainDelegate(
"Main RAM L",
L.RAM.Length,
MemoryDomain.Endian.Little,
addr => L.RAM[addr],
(addr, value) => L.RAM[addr] = value,
1),
new MemoryDomainDelegate(
"Main RAM R",
R.RAM.Length,
MemoryDomain.Endian.Little,
addr => R.RAM[addr],
(addr, value) => R.RAM[addr] = value,
1),
new MemoryDomainDelegate(
"Zero Page RAM L",
L.ZP_RAM.Length,
MemoryDomain.Endian.Little,
addr => L.ZP_RAM[addr],
(addr, value) => L.ZP_RAM[addr] = value,
1),
new MemoryDomainDelegate(
"Zero Page RAM R",
R.ZP_RAM.Length,
MemoryDomain.Endian.Little,
addr => R.ZP_RAM[addr],
(addr, value) => R.ZP_RAM[addr] = value,
1),
new MemoryDomainDelegate(
"System Bus L",
0X10000,
MemoryDomain.Endian.Little,
addr => PeekSystemBusL(addr),
(addr, value) => PokeSystemBusL(addr, value),
1),
new MemoryDomainDelegate(
"System Bus R",
0X10000,
MemoryDomain.Endian.Little,
addr => PeekSystemBusR(addr),
(addr, value) => PokeSystemBusR(addr, value),
1),
new MemoryDomainDelegate(
"ROM L",
L._rom.Length,
MemoryDomain.Endian.Little,
addr => L._rom[addr],
(addr, value) => L._rom[addr] = value,
1),
new MemoryDomainDelegate(
"ROM R",
R._rom.Length,
MemoryDomain.Endian.Little,
addr => R._rom[addr],
(addr, value) => R._rom[addr] = value,
1),
new MemoryDomainDelegate(
"VRAM L",
L.VRAM.Length,
MemoryDomain.Endian.Little,
addr => L.VRAM[addr],
(addr, value) => L.VRAM[addr] = value,
1),
new MemoryDomainDelegate(
"VRAM R",
R.VRAM.Length,
MemoryDomain.Endian.Little,
addr => R.VRAM[addr],
(addr, value) => R.VRAM[addr] = value,
1)
};
if (L.cart_RAM != null)
{
var CartRamL = new MemoryDomainByteArray("Cart RAM L", MemoryDomain.Endian.Little, L.cart_RAM, true, 1);
domains.Add(CartRamL);
}
if (R.cart_RAM != null)
{
var CartRamR = new MemoryDomainByteArray("Cart RAM R", MemoryDomain.Endian.Little, R.cart_RAM, true, 1);
domains.Add(CartRamR);
}
MemoryDomains = new MemoryDomainList(domains);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains);
}
private byte PeekSystemBusL(long addr)
{
ushort addr2 = (ushort)(addr & 0xFFFF);
return L.PeekMemory(addr2);
}
private byte PeekSystemBusR(long addr)
{
ushort addr2 = (ushort)(addr & 0xFFFF);
return R.PeekMemory(addr2);
}
private void PokeSystemBusL(long addr, byte value)
{
ushort addr2 = (ushort)(addr & 0xFFFF);
L.WriteMemory(addr2, value);
}
private void PokeSystemBusR(long addr, byte value)
{
ushort addr2 = (ushort)(addr & 0xFFFF);
R.WriteMemory(addr2, value);
}
}
}

View File

@ -0,0 +1,81 @@
using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public partial class GBHawkLink : ISaveRam
{
public byte[] CloneSaveRam()
{
if ((L.cart_RAM != null) || (R.cart_RAM != null))
{
int Len1 = 0;
int Len2 = 0;
int index = 0;
if (L.cart_RAM != null)
{
Len1 = L.cart_RAM.Length;
}
if (R.cart_RAM != null)
{
Len2 = R.cart_RAM.Length;
}
byte[] temp = new byte[Len1 + Len2];
if (L.cart_RAM != null)
{
for (int i = 0; i < L.cart_RAM.Length; i++)
{
temp[index] = L.cart_RAM[i];
index++;
}
}
if (R.cart_RAM != null)
{
for (int i = 0; i < L.cart_RAM.Length; i++)
{
temp[index] = R.cart_RAM[i];
index++;
}
}
return temp;
}
else
{
return null;
}
}
public void StoreSaveRam(byte[] data)
{
if ((L.cart_RAM != null) && (R.cart_RAM == null))
{
Buffer.BlockCopy(data, 0, L.cart_RAM, 0, L.cart_RAM.Length);
}
else if ((R.cart_RAM != null) && (L.cart_RAM == null))
{
Buffer.BlockCopy(data, 0, R.cart_RAM, 0, R.cart_RAM.Length);
}
else if ((R.cart_RAM != null) && (L.cart_RAM != null))
{
Buffer.BlockCopy(data, 0, L.cart_RAM, 0, L.cart_RAM.Length);
Buffer.BlockCopy(data, L.cart_RAM.Length, R.cart_RAM, 0, R.cart_RAM.Length);
}
Console.WriteLine("loading SRAM here");
}
public bool SaveRamModified
{
get
{
return (L.has_bat || R.has_bat) & linkSyncSettings.Use_SRAM;
}
}
}
}

View File

@ -0,0 +1,146 @@
using System;
using System.ComponentModel;
using Newtonsoft.Json;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.GBHawk;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public partial class GBHawkLink : IEmulator, IStatable, ISettable<GBHawkLink.GBLinkSettings, GBHawkLink.GBLinkSyncSettings>
{
public GBLinkSettings GetSettings()
{
return linkSettings.Clone();
}
public GBLinkSyncSettings GetSyncSettings()
{
return linkSyncSettings.Clone();
}
public bool PutSettings(GBLinkSettings o)
{
linkSettings = o;
return false;
}
public bool PutSyncSettings(GBLinkSyncSettings o)
{
bool ret = GBLinkSyncSettings.NeedsReboot(linkSyncSettings, o);
linkSyncSettings = o;
return ret;
}
private GBLinkSettings linkSettings = new GBLinkSettings();
public GBLinkSyncSettings linkSyncSettings = new GBLinkSyncSettings();
public class GBLinkSettings
{
[DisplayName("Color Mode")]
[Description("Pick Between Green scale and Grey scale colors")]
[DefaultValue(GBHawk.GBHawk.GBSettings.PaletteType.BW)]
public GBHawk.GBHawk.GBSettings.PaletteType Palette_L { get; set; }
[DisplayName("Color Mode")]
[Description("Pick Between Green scale and Grey scale colors")]
[DefaultValue(GBHawk.GBHawk.GBSettings.PaletteType.BW)]
public GBHawk.GBHawk.GBSettings.PaletteType Palette_R { get; set; }
public enum AudioSrc
{
Left,
Right,
Both
}
[DisplayName("Audio Selection")]
[Description("Choose Audio Source. Both will produce Stereo sound.")]
[DefaultValue(AudioSrc.Left)]
public AudioSrc AudioSet { get; set; }
public GBLinkSettings Clone()
{
return (GBLinkSettings)MemberwiseClone();
}
}
public class GBLinkSyncSettings
{
[DisplayName("Console Mode L")]
[Description("Pick which console to run, 'Auto' chooses from ROM extension, 'GB' and 'GBC' chooses the respective system")]
[DefaultValue(GBHawk.GBHawk.GBSyncSettings.ConsoleModeType.Auto)]
public GBHawk.GBHawk.GBSyncSettings.ConsoleModeType ConsoleMode_L { get; set; }
[DisplayName("Console Mode R")]
[Description("Pick which console to run, 'Auto' chooses from ROM extension, 'GB' and 'GBC' chooses the respective system")]
[DefaultValue(GBHawk.GBHawk.GBSyncSettings.ConsoleModeType.Auto)]
public GBHawk.GBHawk.GBSyncSettings.ConsoleModeType ConsoleMode_R { get; set; }
[DisplayName("CGB in GBA")]
[Description("Emulate GBA hardware running a CGB game, instead of CGB hardware. Relevant only for titles that detect the presense of a GBA, such as Shantae.")]
[DefaultValue(false)]
public bool GBACGB { get; set; }
[DisplayName("RTC Initial Time L")]
[Description("Set the initial RTC time in terms of elapsed seconds.")]
[DefaultValue(0)]
public int RTCInitialTime_L
{
get { return _RTCInitialTime_L; }
set { _RTCInitialTime_L = Math.Max(0, Math.Min(1024 * 24 * 60 * 60, value)); }
}
[DisplayName("RTC Initial Time R")]
[Description("Set the initial RTC time in terms of elapsed seconds.")]
[DefaultValue(0)]
public int RTCInitialTime_R
{
get { return _RTCInitialTime_R; }
set { _RTCInitialTime_R = Math.Max(0, Math.Min(1024 * 24 * 60 * 60, value)); }
}
[DisplayName("Timer Div Initial Time L")]
[Description("Don't change from 0 unless it's hardware accurate. GBA GBC mode is known to be 8.")]
[DefaultValue(8)]
public int DivInitialTime_L
{
get { return _DivInitialTime_L; }
set { _DivInitialTime_L = Math.Min((ushort)65535, (ushort)value); }
}
[DisplayName("Timer Div Initial Time R")]
[Description("Don't change from 0 unless it's hardware accurate. GBA GBC mode is known to be 8.")]
[DefaultValue(8)]
public int DivInitialTime_R
{
get { return _DivInitialTime_R; }
set { _DivInitialTime_R = Math.Min((ushort)65535, (ushort)value); }
}
[DisplayName("Use Existing SaveRAM")]
[Description("When true, existing SaveRAM will be loaded at boot up")]
[DefaultValue(false)]
public bool Use_SRAM { get; set; }
[JsonIgnore]
private int _RTCInitialTime_L;
private int _RTCInitialTime_R;
[JsonIgnore]
public ushort _DivInitialTime_L;
public ushort _DivInitialTime_R;
public GBLinkSyncSettings Clone()
{
return (GBLinkSyncSettings)MemberwiseClone();
}
public static bool NeedsReboot(GBLinkSyncSettings x, GBLinkSyncSettings y)
{
return !DeepEquality.DeepEquals(x, y);
}
}
}
}

View File

@ -0,0 +1,65 @@
using System.IO;
using Newtonsoft.Json;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.GBHawk;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public partial class GBHawkLink : IStatable
{
public bool BinarySaveStatesPreferred => true;
public void SaveStateText(TextWriter writer)
{
L.SaveStateText(writer);
R.SaveStateText(writer);
SyncState(new Serializer(writer));
}
public void LoadStateText(TextReader reader)
{
L.LoadStateText(reader);
R.LoadStateText(reader);
SyncState(new Serializer(reader));
}
public void SaveStateBinary(BinaryWriter bw)
{
L.SaveStateBinary(bw);
R.SaveStateBinary(bw);
// other variables
SyncState(new Serializer(bw));
}
public void LoadStateBinary(BinaryReader br)
{
L.LoadStateBinary(br);
R.LoadStateBinary(br);
// other variables
SyncState(new Serializer(br));
}
public byte[] SaveStateBinary()
{
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
return ms.ToArray();
}
//private JsonSerializer ser = new JsonSerializer { Formatting = Formatting.Indented };
private void SyncState(Serializer ser)
{
ser.Sync("Lag", ref _lagcount);
ser.Sync("Frame", ref _frame);
ser.Sync("IsLag", ref _islag);
ser.Sync("_cableconnected", ref _cableconnected);
ser.Sync("_cablediscosignal", ref _cablediscosignal);
_controllerDeck.SyncState(ser);
}
}
}

View File

@ -0,0 +1,100 @@
using System;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.Components.LR35902;
using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy;
using BizHawk.Emulation.Cores.Nintendo.GBHawk;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
[Core(
"GBHawkLink",
"",
isPorted: false,
isReleased: false)]
[ServiceNotApplicable(typeof(IDriveLight))]
public partial class GBHawkLink : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable, ILinkable,
ISettable<GBHawkLink.GBLinkSettings, GBHawkLink.GBLinkSyncSettings>
{
// we want to create two GBHawk instances that we will run concurrently
// maybe up to 4 eventually?
public GBHawk.GBHawk L;
public GBHawk.GBHawk R;
// if true, the link cable is currently connected
private bool _cableconnected = true;
// if true, the link cable toggle signal is currently asserted
private bool _cablediscosignal = false;
//[CoreConstructor("GB", "GBC")]
public GBHawkLink(CoreComm comm, GameInfo game_L, byte[] rom_L, GameInfo game_R, byte[] rom_R, /*string gameDbFn,*/ object settings, object syncSettings)
{
var ser = new BasicServiceProvider(this);
linkSettings = (GBLinkSettings)settings ?? new GBLinkSettings();
linkSyncSettings = (GBLinkSyncSettings)syncSettings ?? new GBLinkSyncSettings();
_controllerDeck = new GBHawkLinkControllerDeck(GBHawkControllerDeck.DefaultControllerName, GBHawkControllerDeck.DefaultControllerName);
CoreComm = comm;
var temp_set_L = new GBHawk.GBHawk.GBSettings();
var temp_set_R = new GBHawk.GBHawk.GBSettings();
var temp_sync_L = new GBHawk.GBHawk.GBSyncSettings();
var temp_sync_R = new GBHawk.GBHawk.GBSyncSettings();
temp_sync_L.ConsoleMode = linkSyncSettings.ConsoleMode_L;
temp_sync_R.ConsoleMode = linkSyncSettings.ConsoleMode_R;
temp_sync_L.DivInitialTime = linkSyncSettings.DivInitialTime_L;
temp_sync_R.DivInitialTime = linkSyncSettings.DivInitialTime_R;
temp_sync_L.RTCInitialTime = linkSyncSettings.RTCInitialTime_L;
temp_sync_R.RTCInitialTime = linkSyncSettings.RTCInitialTime_R;
L = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify) { CoreFileProvider = comm.CoreFileProvider },
game_L, rom_L, temp_set_L, temp_sync_L);
R = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify) { CoreFileProvider = comm.CoreFileProvider },
game_R, rom_R, temp_set_R, temp_sync_R);
ser.Register<IVideoProvider>(this);
ser.Register<ISoundProvider>(this);
_tracer = new TraceBuffer { Header = L.cpu.TraceHeader };
ser.Register<ITraceable>(_tracer);
ServiceProvider = ser;
SetupMemoryDomains();
HardReset();
LinkConnected = _cableconnected;
}
public void HardReset()
{
L.HardReset();
R.HardReset();
}
public DisplayType Region => DisplayType.NTSC;
public int _frame = 0;
private readonly GBHawkLinkControllerDeck _controllerDeck;
private readonly ITraceable _tracer;
public bool LinkConnected { get; private set; }
private void ExecFetch(ushort addr)
{
MemoryCallbacks.CallExecutes(addr, "System Bus");
}
}
}

View File

@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Common;
using BizHawk.Common.ReflectionExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
public class GBHawkLinkControllerDeck
{
public GBHawkLinkControllerDeck(string controller1Name, string controller2Name)
{
if (!ValidControllerTypes.ContainsKey(controller1Name))
{
throw new InvalidOperationException("Invalid controller type: " + controller1Name);
}
if (!ValidControllerTypes.ContainsKey(controller2Name))
{
throw new InvalidOperationException("Invalid controller type: " + controller2Name);
}
Port1 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller1Name], 1);
Port2 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller2Name], 2);
Definition = new ControllerDefinition
{
Name = Port1.Definition.Name,
BoolButtons = Port1.Definition.BoolButtons
.Concat(Port2.Definition.BoolButtons)
.Concat(new[] { "Toggle Cable" } )
.ToList()
};
}
public byte ReadPort1(IController c)
{
return Port1.Read(c);
}
public byte ReadPort2(IController c)
{
return Port2.Read(c);
}
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
{
ser.BeginSection("Port1");
Port1.SyncState(ser);
ser.EndSection();
ser.BeginSection("Port2");
Port2.SyncState(ser);
ser.EndSection();
}
private readonly IPort Port1;
private readonly IPort Port2;
private static Dictionary<string, Type> _controllerTypes;
public static Dictionary<string, Type> ValidControllerTypes
{
get
{
if (_controllerTypes == null)
{
_controllerTypes = typeof(GBHawkLinkControllerDeck).Assembly
.GetTypes()
.Where(t => typeof(IPort).IsAssignableFrom(t))
.Where(t => !t.IsAbstract && !t.IsInterface)
.ToDictionary(tkey => tkey.DisplayName());
}
return _controllerTypes;
}
}
public static string DefaultControllerName => typeof(StandardControls).DisplayName();
}
}

View File

@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{
/// <summary>
/// Represents a GB add on
/// </summary>
public interface IPort
{
byte Read(IController c);
ControllerDefinition Definition { get; }
void SyncState(Serializer ser);
int PortNum { get; }
}
[DisplayName("Gameboy Controller")]
public class StandardControls : IPort
{
public StandardControls(int portNum)
{
PortNum = portNum;
Definition = new ControllerDefinition
{
Name = "Gameboy Controller H",
BoolButtons = BaseDefinition
.Select(b => "P" + PortNum + " " + b)
.ToList()
};
}
public int PortNum { get; }
public ControllerDefinition Definition { get; }
public byte Read(IController c)
{
byte result = 0xFF;
if (c.IsPressed(Definition.BoolButtons[0]))
{
result -= 4;
}
if (c.IsPressed(Definition.BoolButtons[1]))
{
result -= 8;
}
if (c.IsPressed(Definition.BoolButtons[2]))
{
result -= 2;
}
if (c.IsPressed(Definition.BoolButtons[3]))
{
result -= 1;
}
if (c.IsPressed(Definition.BoolButtons[4]))
{
result -= 128;
}
if (c.IsPressed(Definition.BoolButtons[5]))
{
result -= 64;
}
if (c.IsPressed(Definition.BoolButtons[6]))
{
result -= 32;
}
if (c.IsPressed(Definition.BoolButtons[7]))
{
result -= 16;
}
return result;
}
private static readonly string[] BaseDefinition =
{
"Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
};
public void SyncState(Serializer ser)
{
//nothing
}
}
}

View File

@ -0,0 +1 @@
TODO:

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using System.Text; using System.Text;
@ -26,17 +27,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
bool event_frameend = false; bool event_frameend = false;
bool event_breakpoint = false; bool event_breakpoint = false;
[DllImport("kernel32.dll")] private static readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager;
public static extern UInt32 GetLastError();
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
public enum m64p_error public enum m64p_error
{ {
@ -506,7 +497,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
} }
this.bizhawkCore = bizhawkCore; this.bizhawkCore = bizhawkCore;
CoreDll = LoadLibrary("mupen64plus.dll"); CoreDll = libLoader.LoadPlatformSpecific("mupen64plus");
if (CoreDll == IntPtr.Zero) if (CoreDll == IntPtr.Zero)
throw new InvalidOperationException(string.Format("Failed to load mupen64plus.dll")); throw new InvalidOperationException(string.Format("Failed to load mupen64plus.dll"));
@ -605,41 +596,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
/// </summary> /// </summary>
void connectFunctionPointers() void connectFunctionPointers()
{ {
m64pCoreStartup = (CoreStartup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreStartup"), typeof(CoreStartup)); m64pCoreStartup = (CoreStartup)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreStartup"), typeof(CoreStartup));
m64pCoreShutdown = (CoreShutdown)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreShutdown"), typeof(CoreShutdown)); m64pCoreShutdown = (CoreShutdown)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreShutdown"), typeof(CoreShutdown));
m64pCoreDoCommandByteArray = (CoreDoCommandByteArray)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandByteArray)); m64pCoreDoCommandByteArray = (CoreDoCommandByteArray)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandByteArray));
m64pCoreDoCommandPtr = (CoreDoCommandPtr)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandPtr)); m64pCoreDoCommandPtr = (CoreDoCommandPtr)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandPtr));
m64pCoreDoCommandRefInt = (CoreDoCommandRefInt)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRefInt)); m64pCoreDoCommandRefInt = (CoreDoCommandRefInt)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRefInt));
m64pCoreDoCommandFrameCallback = (CoreDoCommandFrameCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandFrameCallback)); m64pCoreDoCommandFrameCallback = (CoreDoCommandFrameCallback)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandFrameCallback));
m64pCoreDoCommandVICallback = (CoreDoCommandVICallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandVICallback)); m64pCoreDoCommandVICallback = (CoreDoCommandVICallback)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandVICallback));
m64pCoreDoCommandRenderCallback = (CoreDoCommandRenderCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRenderCallback)); m64pCoreDoCommandRenderCallback = (CoreDoCommandRenderCallback)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRenderCallback));
m64pCoreAttachPlugin = (CoreAttachPlugin)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreAttachPlugin"), typeof(CoreAttachPlugin)); m64pCoreAttachPlugin = (CoreAttachPlugin)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreAttachPlugin"), typeof(CoreAttachPlugin));
m64pCoreDetachPlugin = (CoreDetachPlugin)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDetachPlugin"), typeof(CoreDetachPlugin)); m64pCoreDetachPlugin = (CoreDetachPlugin)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDetachPlugin"), typeof(CoreDetachPlugin));
m64pConfigOpenSection = (ConfigOpenSection)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "ConfigOpenSection"), typeof(ConfigOpenSection)); m64pConfigOpenSection = (ConfigOpenSection)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "ConfigOpenSection"), typeof(ConfigOpenSection));
m64pConfigSetParameter = (ConfigSetParameter)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "ConfigSetParameter"), typeof(ConfigSetParameter)); m64pConfigSetParameter = (ConfigSetParameter)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "ConfigSetParameter"), typeof(ConfigSetParameter));
m64pConfigSetParameterStr = (ConfigSetParameterStr)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "ConfigSetParameter"), typeof(ConfigSetParameterStr)); m64pConfigSetParameterStr = (ConfigSetParameterStr)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "ConfigSetParameter"), typeof(ConfigSetParameterStr));
m64pCoreSaveState = (savestates_save_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_save_bkm"), typeof(savestates_save_bkm)); m64pCoreSaveState = (savestates_save_bkm)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "savestates_save_bkm"), typeof(savestates_save_bkm));
m64pCoreLoadState = (savestates_load_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_load_bkm"), typeof(savestates_load_bkm)); m64pCoreLoadState = (savestates_load_bkm)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "savestates_load_bkm"), typeof(savestates_load_bkm));
m64pDebugMemGetPointer = (DebugMemGetPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugMemGetPointer"), typeof(DebugMemGetPointer)); m64pDebugMemGetPointer = (DebugMemGetPointer)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugMemGetPointer"), typeof(DebugMemGetPointer));
m64pDebugSetCallbacks = (DebugSetCallbacks)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugSetCallbacks"), typeof(DebugSetCallbacks)); m64pDebugSetCallbacks = (DebugSetCallbacks)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugSetCallbacks"), typeof(DebugSetCallbacks));
m64pDebugBreakpointLookup = (DebugBreakpointLookup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugBreakpointLookup"), typeof(DebugBreakpointLookup)); m64pDebugBreakpointLookup = (DebugBreakpointLookup)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugBreakpointLookup"), typeof(DebugBreakpointLookup));
m64pDebugBreakpointCommand = ( DebugBreakpointCommand )Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugBreakpointCommand"), typeof(DebugBreakpointCommand)); m64pDebugBreakpointCommand = ( DebugBreakpointCommand )Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugBreakpointCommand"), typeof(DebugBreakpointCommand));
m64pDebugGetState = (DebugGetState)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugGetState"), typeof(DebugGetState)); m64pDebugGetState = (DebugGetState)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugGetState"), typeof(DebugGetState));
m64pDebugSetRunState = (DebugSetRunState)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugSetRunState"), typeof(DebugSetRunState)); m64pDebugSetRunState = (DebugSetRunState)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugSetRunState"), typeof(DebugSetRunState));
m64pDebugStep = (DebugStep)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugStep"), typeof(DebugStep)); m64pDebugStep = (DebugStep)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugStep"), typeof(DebugStep));
m64pMemGetSize = (MemGetSize)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "MemGetSize"), typeof(MemGetSize)); m64pMemGetSize = (MemGetSize)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "MemGetSize"), typeof(MemGetSize));
m64pinit_saveram = (init_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "init_saveram"), typeof(init_saveram)); m64pinit_saveram = (init_saveram)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "init_saveram"), typeof(init_saveram));
m64psave_saveram = (save_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "save_saveram"), typeof(save_saveram)); m64psave_saveram = (save_saveram)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "save_saveram"), typeof(save_saveram));
m64pload_saveram = (load_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "load_saveram"), typeof(load_saveram)); m64pload_saveram = (load_saveram)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "load_saveram"), typeof(load_saveram));
m64pSetTraceCallback = (SetTraceCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetTraceCallback"), typeof(SetTraceCallback)); m64pSetTraceCallback = (SetTraceCallback)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "SetTraceCallback"), typeof(SetTraceCallback));
m64pGetRegisters = (GetRegisters)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "GetRegisters"), typeof(GetRegisters)); m64pGetRegisters = (GetRegisters)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "GetRegisters"), typeof(GetRegisters));
m64p_read_memory_8 = (biz_read_memory)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "biz_read_memory"), typeof(biz_read_memory)); m64p_read_memory_8 = (biz_read_memory)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "biz_read_memory"), typeof(biz_read_memory));
m64p_write_memory_8 = (biz_write_memory)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "biz_write_memory"), typeof(biz_write_memory)); m64p_write_memory_8 = (biz_write_memory)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "biz_write_memory"), typeof(biz_write_memory));
m64p_decode_op = (biz_r4300_decode_op)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "biz_r4300_decode_op"), typeof(biz_r4300_decode_op)); m64p_decode_op = (biz_r4300_decode_op)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "biz_r4300_decode_op"), typeof(biz_r4300_decode_op));
} }
/// <summary> /// <summary>
@ -933,7 +924,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
m64pCoreDoCommandPtr(m64p_command.M64CMD_ROM_CLOSE, 0, IntPtr.Zero); m64pCoreDoCommandPtr(m64p_command.M64CMD_ROM_CLOSE, 0, IntPtr.Zero);
m64pCoreShutdown(); m64pCoreShutdown();
FreeLibrary(CoreDll); libLoader.FreePlatformSpecific(CoreDll);
disposed = true; disposed = true;
} }
@ -953,18 +944,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
DetachPlugin(type); DetachPlugin(type);
AttachedPlugin plugin; AttachedPlugin plugin;
plugin.dllHandle = LoadLibrary(PluginName); plugin.dllHandle = libLoader.LoadPlatformSpecific(PluginName);
if (plugin.dllHandle == IntPtr.Zero)
throw new InvalidOperationException(string.Format("Failed to load plugin {0}, error code: 0x{1:X}", PluginName, GetLastError()));
plugin.dllStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(plugin.dllHandle, "PluginStartup"), typeof(PluginStartup)); plugin.dllStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(plugin.dllHandle, "PluginStartup"), typeof(PluginStartup));
plugin.dllShutdown = (PluginShutdown)Marshal.GetDelegateForFunctionPointer(GetProcAddress(plugin.dllHandle, "PluginShutdown"), typeof(PluginShutdown)); plugin.dllShutdown = (PluginShutdown)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(plugin.dllHandle, "PluginShutdown"), typeof(PluginShutdown));
plugin.dllStartup(CoreDll, null, null); plugin.dllStartup(CoreDll, null, null);
m64p_error result = m64pCoreAttachPlugin(type, plugin.dllHandle); m64p_error result = m64pCoreAttachPlugin(type, plugin.dllHandle);
if (result != m64p_error.M64ERR_SUCCESS) if (result != m64p_error.M64ERR_SUCCESS)
{ {
FreeLibrary(plugin.dllHandle); libLoader.FreePlatformSpecific(plugin.dllHandle);
throw new InvalidOperationException(string.Format("Error during attaching plugin {0}", PluginName)); throw new InvalidOperationException(string.Format("Error during attaching plugin {0}", PluginName));
} }
@ -980,7 +969,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
plugins.Remove(type); plugins.Remove(type);
m64pCoreDetachPlugin(type); m64pCoreDetachPlugin(type);
plugin.dllShutdown(); plugin.dllShutdown();
FreeLibrary(plugin.dllHandle); libLoader.FreePlatformSpecific(plugin.dllHandle);
} }
} }

View File

@ -21,8 +21,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
{ {
static QuickNES() static QuickNES()
{ {
Resolver = new DynamicLibraryImportResolver(LibQuickNES.dllname); QN = BizInvoker.GetInvoker<LibQuickNES>(new DynamicLibraryImportResolver(LibQuickNES.dllname), CallingConventionAdapters.Native);
QN = BizInvoker.GetInvoker<LibQuickNES>(Resolver, CallingConventionAdapters.Native);
QN.qn_setup_mappers(); QN.qn_setup_mappers();
} }
@ -74,7 +73,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
} }
static readonly LibQuickNES QN; static readonly LibQuickNES QN;
static readonly DynamicLibraryImportResolver Resolver;
public IEmulatorServiceProvider ServiceProvider { get; private set; } public IEmulatorServiceProvider ServiceProvider { get; private set; }

View File

@ -23,7 +23,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{ {
var regs = DebuggableCore.GetCpuFlagsAndRegisters(); var regs = DebuggableCore.GetCpuFlagsAndRegisters();
uint pc = (uint)regs["M68K PC"].Value; uint pc = (uint)regs["M68K PC"].Value;
var disasm = Disassembler.Disassemble(MemoryDomains.SystemBus, pc & 0xFFFFFF, out int length); int length;
var disasm = Disassembler.Disassemble(MemoryDomains.SystemBus, pc & 0xFFFFFF, out length);
var traceInfo = new TraceInfo var traceInfo = new TraceInfo
{ {

Binary file not shown.

Binary file not shown.

View File

@ -1,16 +1,25 @@
<configuration> <configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/> <dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/> <dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/> <dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/> <dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/> <dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.so.6"/> <dllmap os="linux" dll="libX11" target="libX11.so.6"/>
<dllmap os="linux" dll="libXi" target="libXi.so.6"/> <dllmap os="linux" dll="libXi" target="libXi.so.6"/>
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/> <dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" /> <dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" /> <dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" /> <dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" /> <dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/> <dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/> <dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
</configuration> <dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
<!-- XQuartz compatibility (X11 on Mac) -->
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>