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/>.
*/
using BizHawk.Common;
using System;
using System.Collections.Generic;
#if !WINCE && !MONO
@ -87,6 +89,8 @@ namespace SevenZip
// private static string _LibraryVersion;
private static bool? _modifyCapabale;
private static readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager;
private static void InitUserInFormat(object user, InArchiveFormat format)
{
if (!_inArchives.ContainsKey(user))
@ -148,16 +152,16 @@ namespace SevenZip
//{
// 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
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.");
}
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.");
}
}
@ -431,7 +435,7 @@ namespace SevenZip
if (_totalUsers == 0)
{
#if !WINCE && !MONO
NativeMethods.FreeLibrary(_modulePtr);
libLoader.FreePlatformSpecific(_modulePtr);
#endif
_modulePtr = IntPtr.Zero;
@ -466,7 +470,7 @@ namespace SevenZip
}
var createObject = (NativeMethods.CreateObjectDelegate)
Marshal.GetDelegateForFunctionPointer(
NativeMethods.GetProcAddress(_modulePtr, "CreateObject"),
libLoader.GetProcAddr(_modulePtr, "CreateObject"),
typeof(NativeMethods.CreateObjectDelegate));
if (createObject == null)
{
@ -525,7 +529,7 @@ namespace SevenZip
}
var createObject = (NativeMethods.CreateObjectDelegate)
Marshal.GetDelegateForFunctionPointer(
NativeMethods.GetProcAddress(_modulePtr, "CreateObject"),
libLoader.GetProcAddr(_modulePtr, "CreateObject"),
typeof(NativeMethods.CreateObjectDelegate));
if (createObject == null)
{

View File

@ -35,18 +35,8 @@ namespace SevenZip
[MarshalAs(UnmanagedType.Interface)] out object outObject);
#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
#if WINCE
[DllImport("7z.dll", EntryPoint="CreateObject")]
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 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.Nintendo.Gameboy;
using BizHawk.Emulation.Cores.Nintendo.GBHawk;
using BizHawk.Emulation.Cores.Nintendo.GBHawkLink;
using BizHawk.Emulation.Cores.Nintendo.SNES;
using BizHawk.Emulation.Cores.PCEngine;
using BizHawk.Emulation.Cores.Sega.Saturn;
@ -630,7 +631,20 @@ namespace BizHawk.Client.Common
var left = Database.GetGameInfo(leftBytes, "left.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,
left,
leftBytes,
@ -639,7 +653,8 @@ namespace BizHawk.Client.Common
GetCoreSettings<GambatteLink>(),
GetCoreSyncSettings<GambatteLink>(),
Deterministic);
}
// other stuff todo
break;
case "AppleII":

View File

@ -950,6 +950,8 @@
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Input.cs" />
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Savestate.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\LuaCanvas.cs">
<SubType>Form</SubType>

View File

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

View File

@ -6,18 +6,47 @@ namespace BizHawk.Client.EmuHawk
{
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 ()
{
_kbState = OpenTK.Input.Keyboard.GetState();
_kbState = Keyboard.GetState();
}
public static void Update ()
public static IEnumerable<KeyInput.KeyEvent> Update ()
{
_eventList.Clear();
var lastState = _kbState;
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
{
@ -30,6 +59,7 @@ namespace BizHawk.Client.EmuHawk
System.Console.WriteLine("OpenTK Keyboard thread is angry.");
}
}
return _eventList;
}
public static bool IsPressed (Key key)

View File

@ -351,7 +351,9 @@
this.SaturnPreferencesMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.DGBSubMenu = 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.GenesisGameGenieECDC = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator26 = new System.Windows.Forms.ToolStripSeparator();
@ -503,7 +505,8 @@
this.N64SubMenu,
this.SaturnSubMenu,
this.DGBSubMenu,
this.GenesisSubMenu,
this.DGBHawkSubMenu,
this.GenesisSubMenu,
this.wonderSwanToolStripMenuItem,
this.AppleSubMenu,
this.C64SubMenu,
@ -3177,10 +3180,25 @@
this.DGBsettingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.DGBsettingsToolStripMenuItem.Text = "Settings...";
this.DGBsettingsToolStripMenuItem.Click += new System.EventHandler(this.DgbSettingsMenuItem_Click);
//
// GenesisSubMenu
//
this.GenesisSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
//
// DGBHawkSubMenu
//
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.GenesisGameGenieECDC,
this.toolStripSeparator26,
@ -4504,6 +4522,8 @@
private System.Windows.Forms.ToolStripMenuItem FdsEjectDiskMenuItem;
private System.Windows.Forms.ToolStripMenuItem DGBSubMenu;
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 GenesisSettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem AtariSettingsToolStripMenuItem;

View File

@ -1386,6 +1386,7 @@ namespace BizHawk.Client.EmuHawk
RamSearchMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["RAM Search"].Bindings;
HexEditorMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Hex Editor"].Bindings;
LuaConsoleMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Lua Console"].Bindings;
LuaConsoleMenuItem.Enabled = GlobalWin.Tools.IsAvailable<LuaConsole>();
CheatsMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Cheats"].Bindings;
TAStudioMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["TAStudio"].Bindings;
VirtualPadMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Virtual Pad"].Bindings;
@ -2349,6 +2350,11 @@ namespace BizHawk.Client.EmuHawk
DGBPrefs.DoDGBPrefsDialog(this);
}
private void DgbHawkSettingsMenuItem_Click(object sender, EventArgs e)
{
GenericCoreConfig.DoDialog(this, "Gameboy Settings");
}
#endregion
#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.SNES;
using BizHawk.Emulation.Cores.Nintendo.N64;
using BizHawk.Emulation.Cores.Nintendo.GBHawkLink;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions;
@ -1118,11 +1119,7 @@ namespace BizHawk.Client.EmuHawk
private void OpenLuaConsole()
{
#if WINDOWS
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()
@ -1724,6 +1721,7 @@ namespace BizHawk.Client.EmuHawk
N64SubMenu.Visible = false;
SaturnSubMenu.Visible = false;
DGBSubMenu.Visible = false;
DGBHawkSubMenu.Visible = false;
GenesisSubMenu.Visible = false;
wonderSwanToolStripMenuItem.Visible = false;
AppleSubMenu.Visible = false;
@ -1806,7 +1804,14 @@ namespace BizHawk.Client.EmuHawk
SaturnSubMenu.Visible = true;
break;
case "DGB":
DGBSubMenu.Visible = true;
if (Emulator is GBHawkLink)
{
DGBHawkSubMenu.Visible = true;
}
else
{
DGBSubMenu.Visible = true;
}
break;
case "WSWAN":
wonderSwanToolStripMenuItem.Visible = true;

View File

@ -17,26 +17,25 @@ namespace BizHawk.Client.EmuHawk
{
static class Program
{
static bool RunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX;
static Program()
{
//this needs to be done before the warnings/errors show up
Application.EnableVisualStyles();
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
//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
//but oddly it lets us proceed and we'll then catch it here
var d3dx9 = libLoader.LoadPlatformSpecific("d3dx9_43.dll");
var vc2015 = libLoader.LoadPlatformSpecific("vcruntime140.dll");
var vc2012 = libLoader.LoadPlatformSpecific("msvcr120.dll"); //TODO - check version?
var vc2010 = libLoader.LoadPlatformSpecific("msvcr100.dll"); //TODO - check version?
var vc2010p = libLoader.LoadPlatformSpecific("msvcp100.dll");
var libExt = PlatformLinkedLibSingleton.RunningOnUnix ? ".dll.so" : ".dll";
var d3dx9 = libLoader.LoadPlatformSpecific($"d3dx9_43{libExt}");
var vc2015 = libLoader.LoadPlatformSpecific($"vcruntime140{libExt}");
var vc2012 = libLoader.LoadPlatformSpecific($"msvcr120{libExt}"); //TODO - check version?
var vc2010 = libLoader.LoadPlatformSpecific($"msvcr100{libExt}"); //TODO - check version?
var vc2010p = libLoader.LoadPlatformSpecific($"msvcp100{libExt}");
bool fail = false, warn = false;
warn |= d3dx9 == IntPtr.Zero;
fail |= vc2015 == IntPtr.Zero;
@ -66,7 +65,7 @@ namespace BizHawk.Client.EmuHawk
libLoader.FreePlatformSpecific(vc2010);
libLoader.FreePlatformSpecific(vc2010p);
if (!RunningOnUnix)
if (!PlatformLinkedLibSingleton.RunningOnUnix)
{
// this will look in subdirectory "dll" to load pinvoked stuff
string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll");
@ -90,63 +89,6 @@ namespace BizHawk.Client.EmuHawk
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
{
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 Win32MainLoopCrashHandler();
@ -323,7 +265,7 @@ namespace BizHawk.Client.EmuHawk
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
if (RunningOnUnix) Global.Config.DispMethod = Config.EDispMethod.GdiPlus;
if (PlatformLinkedLibSingleton.RunningOnUnix) Global.Config.DispMethod = Config.EDispMethod.GdiPlus;
REDO_DISPMETHOD:
if (Global.Config.DispMethod == Config.EDispMethod.GdiPlus)
GlobalWin.GL = new Bizware.BizwareGL.Drivers.GdiPlus.IGL_GdiPlus();
@ -371,7 +313,7 @@ namespace BizHawk.Client.EmuHawk
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.
//The relevant initialization happened just before in "create IGL context".

View File

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

View File

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

View File

@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
using System.Threading;
using BizHawk.Client.Common;
using BizHawk.Common;
//this throttle is nitsuja's fine-tuned techniques from desmume
@ -159,7 +160,7 @@ namespace BizHawk.Client.EmuHawk
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)
{
return sysTimer.TimeBeginPeriod(ms);

View File

@ -24,6 +24,8 @@ namespace BizHawk.Client.EmuHawk
ControllerImages.Add("SNES Controller", Properties.Resources.SNES_Controller);
ControllerImages.Add("Nintento 64 Controller", Properties.Resources.N64);
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("Dual Gameboy Controller", Properties.Resources.GBController);

View File

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

View File

@ -13,7 +13,7 @@ using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
public class EmuLuaLibrary
public class EmuLuaLibrary : PlatformEmuLuaLibrary
{
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 _currThread;
@ -101,9 +91,7 @@ namespace BizHawk.Client.EmuHawk
private EmulatorLuaLibrary EmulatorLuaLibrary => (EmulatorLuaLibrary)Libraries[typeof(EmulatorLuaLibrary)];
public GuiLuaLibrary GuiLibrary => (GuiLuaLibrary)Libraries[typeof(GuiLuaLibrary)];
public void Restart(IEmulatorServiceProvider newServiceProvider)
public override void Restart(IEmulatorServiceProvider newServiceProvider)
{
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)
{
@ -119,7 +107,7 @@ namespace BizHawk.Client.EmuHawk
}
}
public void EndLuaDrawing()
public override void EndLuaDrawing()
{
if (ScriptList.Any())
{
@ -127,34 +115,35 @@ namespace BizHawk.Client.EmuHawk
}
}
public LuaDocumentation Docs { get; }
public bool IsRunning { get; set; }
public EventWaitHandle LuaWait { 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);
}
public void CallSaveStateEvent(string name)
public override void CallSaveStateEvent(string name)
{
EventsLibrary.CallSaveStateEvent(name);
}
public void CallLoadStateEvent(string name)
public override void CallLoadStateEvent(string name)
{
EventsLibrary.CallLoadStateEvent(name);
}
public void CallFrameBeforeEvent()
public override void CallFrameBeforeEvent()
{
EventsLibrary.CallFrameBeforeEvent();
}
public void CallFrameAfterEvent()
public override void CallFrameAfterEvent()
{
EventsLibrary.CallFrameAfterEvent();
}
@ -164,7 +153,12 @@ namespace BizHawk.Client.EmuHawk
EventsLibrary.CallExitEvent(thread);
}
public void Close()
public override void CallExitEvent(LuaFile lf)
{
CallExitEvent(lf.Thread);
}
public override void Close()
{
FormsLibrary.DestroyAll();
_lua.Close();
@ -187,7 +181,12 @@ namespace BizHawk.Client.EmuHawk
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.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)
{
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.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
@ -78,7 +79,7 @@ namespace BizHawk.Client.EmuHawk
LuaSandbox.DefaultLogger = ConsoleLog;
}
public EmuLuaLibrary LuaImp { get; private set; }
public PlatformEmuLuaLibrary LuaImp { get; private set; }
public bool UpdateBefore => true;
@ -154,15 +155,15 @@ namespace BizHawk.Client.EmuHawk
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)
.ToList();
foreach (var function in functions)
{
LuaImp.RegisteredFunctions.Remove(function);
LuaImp.GetRegisteredFunctions().Remove(function);
}
UpdateRegisteredFunctionsDialog();
@ -172,7 +173,9 @@ namespace BizHawk.Client.EmuHawk
}
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)
{
LuaImp.ScriptList.AddRange(currentScripts);
@ -188,7 +191,7 @@ namespace BizHawk.Client.EmuHawk
{
LuaSandbox.Sandbox(file.Thread, () =>
{
file.Thread = LuaImp.SpawnCoroutine(pathToLoad);
LuaImp.SpawnAndSetFileThread(pathToLoad, file);
LuaSandbox.CreateSandbox(file.Thread, Path.GetDirectoryName(pathToLoad));
file.State = LuaFile.RunState.Running;
}, () =>
@ -306,7 +309,7 @@ namespace BizHawk.Client.EmuHawk
LuaSandbox.Sandbox(null, () =>
{
string pathToLoad = ProcessPath(file.Path);
file.Thread = LuaImp.SpawnCoroutine(file.Path);
LuaImp.SpawnAndSetFileThread(file.Path, file);
LuaSandbox.CreateSandbox(file.Thread, Path.GetDirectoryName(pathToLoad));
}, () =>
{
@ -552,10 +555,10 @@ namespace BizHawk.Client.EmuHawk
var prohibit = lf.FrameWaiting && !includeFrameWaiters;
if (!prohibit)
{
var result = LuaImp.ResumeScript(lf.Thread);
var result = LuaImp.ResumeScriptFromThreadOf(lf);
if (result.Terminated)
{
LuaImp.CallExitEvent(lf.Thread);
LuaImp.CallExitEvent(lf);
lf.Stop();
UpdateDialog();
}
@ -786,7 +789,7 @@ namespace BizHawk.Client.EmuHawk
SelectAllMenuItem.Enabled = LuaImp.ScriptList.Any();
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)
@ -840,26 +843,26 @@ namespace BizHawk.Client.EmuHawk
else if (!file.Enabled && file.Thread != null)
{
LuaImp.CallExitEvent(file.Thread);
LuaImp.CallExitEvent(file);
var items = SelectedItems.ToList();
foreach (var sitem in items)
{
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)
{
LuaImp.RegisteredFunctions.Remove(function);
LuaImp.GetRegisteredFunctions().Remove(function);
}
UpdateRegisteredFunctionsDialog();
}
LuaImp.CallExitEvent(file.Thread);
LuaImp.CallExitEvent(file);
file.Stop();
if (Global.Config.RemoveRegisteredFunctionsOnToggle)
{
LuaImp.RegisteredFunctions.ClearAll();
LuaImp.GetRegisteredFunctions().ClearAll();
}
}
}
@ -879,7 +882,7 @@ namespace BizHawk.Client.EmuHawk
? item.Path
: PathManager.MakeProgramRelativePath(item.Path);
item.Thread = LuaImp.SpawnCoroutine(pathToLoad);
LuaImp.SpawnAndSetFileThread(pathToLoad, item);
LuaSandbox.CreateSandbox(item.Thread, Path.GetDirectoryName(pathToLoad));
}, () =>
{
@ -933,10 +936,10 @@ namespace BizHawk.Client.EmuHawk
foreach (var item in items)
{
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)
{
LuaImp.RegisteredFunctions.Remove(function);
LuaImp.GetRegisteredFunctions().Remove(function);
}
LuaImp.ScriptList.Remove(item);
@ -1052,7 +1055,7 @@ namespace BizHawk.Client.EmuHawk
private void RegisteredFunctionsMenuItem_Click(object sender, EventArgs e)
{
if (LuaImp.RegisteredFunctions.Any())
if (LuaImp.GetRegisteredFunctions().Any())
{
var alreadyOpen = false;
foreach (Form form in Application.OpenForms)
@ -1209,7 +1212,7 @@ namespace BizHawk.Client.EmuHawk
private void ConsoleContextMenu_Opening(object sender, CancelEventArgs e)
{
RegisteredFunctionsContextItem.Enabled = LuaImp.RegisteredFunctions.Any();
RegisteredFunctionsContextItem.Enabled = LuaImp.GetRegisteredFunctions().Any();
CopyContextItem.Enabled = OutputBox.SelectedText.Any();
ClearConsoleContextItem.Enabled =
SelectAllContextItem.Enabled =

View File

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

View File

@ -17,7 +17,7 @@ namespace BizHawk.Client.EmuHawk
public void UpdateValues()
{
if (GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions.Any())
if (GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions().Any())
{
PopulateListView();
}
@ -46,7 +46,7 @@ namespace BizHawk.Client.EmuHawk
{
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)
{
var item = new ListViewItem { Text = nlf.Event };
@ -76,7 +76,7 @@ namespace BizHawk.Client.EmuHawk
foreach (int index in indices)
{
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)
{
var guid = FunctionView.Items[index].SubItems[2].Text;
var nlf = GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions[guid];
GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions.Remove(nlf);
var nlf = GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions()[guid];
GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions().Remove(nlf);
}
PopulateListView();
@ -109,7 +109,7 @@ namespace BizHawk.Client.EmuHawk
private void RemoveAllBtn_Click(object sender, EventArgs e)
{
GlobalWin.Tools.LuaConsole.LuaImp.RegisteredFunctions.ClearAll();
GlobalWin.Tools.LuaConsole.LuaImp.GetRegisteredFunctions().ClearAll();
PopulateListView();
}
@ -118,7 +118,7 @@ namespace BizHawk.Client.EmuHawk
var indexes = FunctionView.SelectedIndices;
CallButton.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)

View File

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

View File

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

View File

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

View File

@ -8,41 +8,24 @@ namespace BizHawk.Common.BizInvoke
public class DynamicLibraryImportResolver : IImportResolver, IDisposable
{
private IntPtr _p;
private readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager;
public DynamicLibraryImportResolver(string dllName)
{
#if !MONO
_p = Win32.LoadLibrary(dllName);
#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");
}
_p = libLoader.LoadPlatformSpecific(dllName);
if (_p == IntPtr.Zero) throw new InvalidOperationException("null pointer returned by LoadPlatformSpecific");
}
public IntPtr Resolve(string entryPoint)
{
#if !MONO
return Win32.GetProcAddress(_p, entryPoint);
#else
return Libdl.dlsym(_p, entryPoint);
#endif
return libLoader.GetProcAddr(_p, entryPoint);
}
private void Free()
{
if (_p != IntPtr.Zero)
{
#if !MONO
Win32.FreeLibrary(_p);
#else
Libdl.dlclose(_p);
#endif
_p = IntPtr.Zero;
}
if (_p == IntPtr.Zero) return;
libLoader.FreePlatformSpecific(_p);
_p = IntPtr.Zero;
}
public void Dispose()
@ -55,30 +38,5 @@ namespace BizHawk.Common.BizInvoke
{
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
{
//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>
/// starting address of the memory block
/// </summary>
@ -442,37 +444,10 @@ namespace BizHawk.Common.BizInvoke
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)]
public static extern bool VirtualProtect(UIntPtr lpAddress, UIntPtr dwSize,
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]
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;
// 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
so that there are blip_max_ratio clocks per sample. Returns pointer to new
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);
/** Sets approximate input clock rate and output sample rate. For every
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);
/** 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;
/** 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);
/** 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);
/** 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);
/** Length of time frame, in clocks, needed to make sample_count additional
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);
/** 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
frame specified. Deltas can have been added slightly past clock_duration (up to
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);
/** 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);
/** 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
interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed
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);
[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);
/** 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);
}

View File

@ -317,27 +317,33 @@
<Compile Include="Computers\Commodore64\SaveState.cs" />
<Compile Include="Computers\Commodore64\User\UserPortDevice.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\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\Hardware\SoundOuput\Beeper.cs" />
<Compile Include="Computers\SinclairSpectrum\Media\Disk\FloppyDisk.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IJoystick.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IPortIODevice.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IPSG.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\CHRN.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.FDC.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.FDD.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.IPortIODevice.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.Timing.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPS765.Static.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.Definitions.cs">
<DependentUpon>NECUPD765.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Hardware\Disk\NECUPD765.FDC.cs">
<DependentUpon>NECUPD765.cs</DependentUpon>
</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\SinclairJoystick2.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\Input\KempstonJoystick.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\CPCFloppyDisk.cs" />
<Compile Include="Computers\SinclairSpectrum\Media\Disk\DiskType.cs" />
@ -372,30 +374,94 @@
<Compile Include="Computers\SinclairSpectrum\SoundProviderMixer.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\MachineType.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Input.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Port.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Memory.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2\ZX128Plus2.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.Memory.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus3\ZX128Plus3.Port.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Memory.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Port.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Memory.cs" />
<Compile Include="Computers\SinclairSpectrum\Hardware\Rom\RomData.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Controllers.cs" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Input.cs">
<DependentUpon>SpectrumBase.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Port.cs">
<DependentUpon>SpectrumBase.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Memory.cs">
<DependentUpon>SpectrumBase.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Media.cs">
<DependentUpon>SpectrumBase.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\Machine\ULA.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.IDebuggable.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IEmulator.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IInputPollable.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.ICodeDataLog.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IMemoryDomains.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.ISettable.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IStatable.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Messaging.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.Util.cs" />
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IDebuggable.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IEmulator.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</Compile>
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IInputPollable.cs">
<DependentUpon>ZXSpectrum.cs</DependentUpon>
</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.Core.cs">
<DependentUpon>Atari2600.cs</DependentUpon>
@ -723,6 +789,31 @@
<DependentUpon>VBANext.cs</DependentUpon>
</Compile>
<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\GBHawk.ICodeDataLog.cs" />
<Compile Include="Consoles\Nintendo\GBHawk\Mappers\Mapper_WisdomTree.cs" />
@ -1500,13 +1591,7 @@
</ProjectReference>
</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\SinclairSpectrum\readme.md" />
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Media.cs" />
<None Include="Consoles\Atari\docs\stella.pdf" />
<None Include="Consoles\Coleco\docs\colecovision tech1.pdf" />
<None Include="Consoles\Coleco\docs\colecovision tech2.pdf" />

View File

@ -131,13 +131,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <summary>
/// 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>
public void EndFrame()
{
MonitorFrame();
}
/// <summary>
/// No longer in use
/// </summary>
public void StartFrame()
{
//_buzzer.ProcessPulseValue(currentState);
@ -296,14 +299,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sbd.Append("(");
sbd.Append((targetBlockId + 1) + " of " + _dataBlocks.Count());
sbd.Append(") : ");
//sbd.Append("ID" + bl.BlockID.ToString("X2") + " - ");
sbd.Append(bl.BlockDescription);
if (bl.MetaData.Count > 0)
{
sbd.Append(" - ");
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)
@ -522,7 +522,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sbd.Append("(");
sbd.Append((_currentDataBlockIndex + 1) + " of " + _dataBlocks.Count());
sbd.Append(") : ");
//sbd.Append("ID" + bl.BlockID.ToString("X2") + " - ");
sbd.Append(bl.BlockDescription);
if (bl.MetaData.Count > 0)
{
@ -532,14 +531,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
_machine.Spectrum.OSD_TapePlayingBlockInfo(sbd.ToString());
}
// increment the current period position
_position++;
if (_position >= _dataBlocks[_currentDataBlockIndex].DataPeriods.Count())
{
// we have reached the end of the current block
if (_dataBlocks[_currentDataBlockIndex].DataPeriods.Count() == 0)
{
// 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((_currentDataBlockIndex + 1) + " of " + _dataBlocks.Count());
sbd.Append(") : ");
//sbd.Append("ID" + bl.BlockID.ToString("X2") + " - ");
sbd.Append(bl.BlockDescription);
if (bl.MetaData.Count > 0)
{
sbd.Append(" - ");
sbd.Append(bl.MetaData.First().Key + ": " + bl.MetaData.First().Value);
}
{
sbd.Append(" - ");
sbd.Append(bl.MetaData.First().Key + ": " + bl.MetaData.First().Value);
}
_machine.Spectrum.OSD_TapePlayingSkipBlockInfo(sbd.ToString());
}
@ -583,7 +579,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
}
_monitorTimeOut = 2000;
break;
case TapeCommand.STOP_THE_TAPE_48K:
if (is48k)
@ -624,20 +619,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
}
}
// update waitEdge with current position within the current block
_waitEdge = _dataBlocks[_currentDataBlockIndex].DataPeriods[_position];
// update waitEdge with current position within the current block
_waitEdge = _dataBlocks[_currentDataBlockIndex].DataPeriods.Count() > 0 ? _dataBlocks[_currentDataBlockIndex].DataPeriods[_position] : 0;
// flip the current state
FlipTapeState();
}
// update lastCycle and return currentstate
_lastCycle = cpuCycle - (long)cycles;
// play the buzzer
//_buzzer.ProcessPulseValue(false, currentState);
return currentState;
}
@ -649,6 +640,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <summary>
/// Flash loading implementation
/// (Deterministic Emulation must be FALSE)
/// CURRENTLY NOT ENABLED/WORKING
/// </summary>
private bool FlashLoad()
{
@ -962,47 +954,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
if (_machine.UPDDiskDevice == null || !_machine.UPDDiskDevice.FDD_IsDiskLoaded)
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;
}

View File

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

View File

@ -8,9 +8,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// Logical Beeper class
/// Represents the piezoelectric buzzer used in the Spectrum to produce sound
/// 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
///
/// 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)
/// </summary>

View File

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

View File

@ -63,6 +63,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
// load the media into the tape device
tapeMediaIndex = result;
// fire osd message
if (!IsLoadState)
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");
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]);
}

View File

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

View File

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

View File

@ -785,7 +785,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns>
public int GetContentionValue(int tstate)
{
//tstate += MemoryContentionOffset;
if (tstate >= FrameCycleLength)
tstate -= FrameCycleLength;
@ -801,7 +800,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns>
public int GetPortContentionValue(int tstate)
{
//tstate += PortContentionOffset;
if (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)
{
Spectrum = spectrum;
CPU = cpu;
CPU = cpu;
CPUMon = new CPUMonitor(this);
CPUMon.machineType = MachineType.ZXSpectrum128Plus3;

View File

@ -22,8 +22,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
CPU = cpu;
CPUMon = new CPUMonitor(this);
//ULADevice = new ULA48(this);
ULADevice = new Screen48(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);
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)
{
{
if (_memoryDomainsInit || _byteArrayDomains.ContainsKey(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);
_byteArrayDomains.Add(name, m);
}
}
}
}
}

View File

@ -242,6 +242,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
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)
{
ZXMachineMetaData m = new ZXMachineMetaData();
@ -345,6 +350,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
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)
{
var m = GetMetaObject(type);
@ -410,8 +420,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
sb.Append(builder[i]);
sb.Append("\r\n");
}
//sb.Append("\r\n");
}
return sb.ToString();

View File

@ -35,7 +35,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
_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()
{
string m = "";
@ -59,17 +62,31 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
case MachineType.ZXSpectrum128Plus3:
m = "(Amstrad) ZX Spectrum 128K +3";
break;
case MachineType.Pentagon128:
m = "(Clone) Pentagon 128K";
break;
}
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()
{
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)
{
return ((MemberExpression)memberAccess.Body).Member.Name;

View File

@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
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 bool HBL_HDMA_go;
public bool HBL_test;
public byte LYC_t;
public int LYC_cd;
public override byte ReadReg(int addr)
{
@ -112,11 +114,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0xFF41: // STAT
// note that their is no stat interrupt bug in GBC
// 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);
@ -134,20 +145,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
LY = 0; /*reset*/
break;
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
// two cycles ahead of where it's supposed to. this is probably related to strange behaviour around cycle 452
if ((LY_inc == 0) && cycle == 6)
{
//if (0 == LYC) { STAT |= 0x4; LYC_INT = true; }
//else { STAT &= 0xFB; LYC_INT = false; }
}
}
// tests indicate that latching writes to LYC should take place 4 cycles after the write
// otherwise tests around LY boundaries will fail
LYC_t = value;
LYC_cd = 4;
break;
case 0xFF46: // DMA
DMA_addr = value;
@ -569,12 +571,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (LY_inc == 0)
{
if (cycle == 10)
if (cycle == 12)
{
LYC_INT = false;
STAT &= 0xFB;
}
else if (cycle == 12)
else if (cycle == 14)
{
// Special case of LY = LYC
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)
if ((cycle == 2) && (LY != 0))
if ((cycle == 4) && (LY != 0))
{
if (LY_inc == 1)
{
@ -595,7 +597,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
STAT &= 0xFB;
}
}
else if ((cycle == 4) && (LY != 0))
else if ((cycle == 6) && (LY != 0))
{
if ((LY == LYC) && !STAT.Bit(2))
{
@ -636,6 +638,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// process latch delays
//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
@ -1526,6 +1543,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("BG_bytes_index", ref BG_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);
}

View File

@ -159,7 +159,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
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;
REG_FF0F_OLD = REG_FF0F;
@ -168,6 +168,89 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
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)
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("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("addr_access", ref addr_access);
@ -99,9 +107,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("cart_RAM", ref cart_RAM, false);
}
ser.EndSection();
ser.EndSection();
}
}
}

View File

@ -3,7 +3,6 @@
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.Components.LR35902;
using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy;
using System.Runtime.InteropServices;
@ -56,6 +55,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public bool speed_switch;
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 readonly byte[] _rom;
public readonly byte[] header = new byte[0x50];
@ -272,10 +274,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
private readonly GBHawkControllerDeck _controllerDeck;
private void HardReset()
public void HardReset()
{
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_old = true;

View File

@ -101,7 +101,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// Speed Control for GBC
case 0xFF4D:
if (is_GBC)
if (GBC_compat)
{
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
case 0xFF70:
if (is_GBC)
if (GBC_compat)
{
ret = (byte)RAM_Bank;
}
@ -159,6 +159,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
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
case 0xFFFF:
ret = REG_FFFF;
@ -323,7 +358,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// Speed Control for GBC
case 0xFF4D:
if (is_GBC)
if (GBC_compat)
{
speed_switch = (value & 1) > 0;
}
@ -365,13 +400,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// RAM Bank in GBC mode
case 0xFF70:
//Console.WriteLine(value);
if (is_GBC)
if (GBC_compat)
{
RAM_Bank = value & 7;
if (RAM_Bank == 0) { RAM_Bank = 1; }
}
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
case 0xFFFF:
REG_FFFF = value;
@ -401,6 +464,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public void Register_Reset()
{
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 bool clk_internal;
public int clk_rate;
public byte going_out;
public byte coming_in;
public byte ReadReg(int addr)
{
@ -84,16 +86,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (serial_start)
{
if (serial_clock > 0) { serial_clock--; }
if (serial_clock == 0)
{
if (serial_bits > 0)
{
send_external_bit((byte)(serial_data & 0x80));
byte temp = get_external_bit();
serial_data = (byte)((serial_data << 1) | temp);
serial_bits--;
if (serial_bits == 0)
{
serial_control &= 0x7F;
@ -122,12 +124,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// no device connected returns 0xFF
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)
{
going_out = (byte)(bit_send >> 7);
}
public void Reset()
@ -135,6 +138,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
serial_control = 0x7E;
serial_start = false;
serial_data = 0x00;
going_out = 0;
coming_in = 1;
}
public void SyncState(Serializer ser)
@ -146,6 +151,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("serial_bits", ref serial_bits);
ser.Sync("clk_internal", ref clk_internal);
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.Threading;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using System.Text;
@ -26,17 +27,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
bool event_frameend = false;
bool event_breakpoint = false;
[DllImport("kernel32.dll")]
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);
private static readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager;
public enum m64p_error
{
@ -506,7 +497,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
}
this.bizhawkCore = bizhawkCore;
CoreDll = LoadLibrary("mupen64plus.dll");
CoreDll = libLoader.LoadPlatformSpecific("mupen64plus");
if (CoreDll == IntPtr.Zero)
throw new InvalidOperationException(string.Format("Failed to load mupen64plus.dll"));
@ -605,41 +596,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
/// </summary>
void connectFunctionPointers()
{
m64pCoreStartup = (CoreStartup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreStartup"), typeof(CoreStartup));
m64pCoreShutdown = (CoreShutdown)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreShutdown"), typeof(CoreShutdown));
m64pCoreDoCommandByteArray = (CoreDoCommandByteArray)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandByteArray));
m64pCoreDoCommandPtr = (CoreDoCommandPtr)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandPtr));
m64pCoreDoCommandRefInt = (CoreDoCommandRefInt)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRefInt));
m64pCoreDoCommandFrameCallback = (CoreDoCommandFrameCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandFrameCallback));
m64pCoreDoCommandVICallback = (CoreDoCommandVICallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandVICallback));
m64pCoreDoCommandRenderCallback = (CoreDoCommandRenderCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRenderCallback));
m64pCoreAttachPlugin = (CoreAttachPlugin)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreAttachPlugin"), typeof(CoreAttachPlugin));
m64pCoreDetachPlugin = (CoreDetachPlugin)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "CoreDetachPlugin"), typeof(CoreDetachPlugin));
m64pConfigOpenSection = (ConfigOpenSection)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "ConfigOpenSection"), typeof(ConfigOpenSection));
m64pConfigSetParameter = (ConfigSetParameter)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "ConfigSetParameter"), typeof(ConfigSetParameter));
m64pConfigSetParameterStr = (ConfigSetParameterStr)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "ConfigSetParameter"), typeof(ConfigSetParameterStr));
m64pCoreSaveState = (savestates_save_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_save_bkm"), typeof(savestates_save_bkm));
m64pCoreLoadState = (savestates_load_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_load_bkm"), typeof(savestates_load_bkm));
m64pDebugMemGetPointer = (DebugMemGetPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugMemGetPointer"), typeof(DebugMemGetPointer));
m64pDebugSetCallbacks = (DebugSetCallbacks)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugSetCallbacks"), typeof(DebugSetCallbacks));
m64pDebugBreakpointLookup = (DebugBreakpointLookup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugBreakpointLookup"), typeof(DebugBreakpointLookup));
m64pDebugBreakpointCommand = ( DebugBreakpointCommand )Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugBreakpointCommand"), typeof(DebugBreakpointCommand));
m64pDebugGetState = (DebugGetState)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugGetState"), typeof(DebugGetState));
m64pDebugSetRunState = (DebugSetRunState)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugSetRunState"), typeof(DebugSetRunState));
m64pDebugStep = (DebugStep)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugStep"), typeof(DebugStep));
m64pMemGetSize = (MemGetSize)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "MemGetSize"), typeof(MemGetSize));
m64pinit_saveram = (init_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "init_saveram"), typeof(init_saveram));
m64psave_saveram = (save_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "save_saveram"), typeof(save_saveram));
m64pload_saveram = (load_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "load_saveram"), typeof(load_saveram));
m64pCoreStartup = (CoreStartup)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreStartup"), typeof(CoreStartup));
m64pCoreShutdown = (CoreShutdown)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreShutdown"), typeof(CoreShutdown));
m64pCoreDoCommandByteArray = (CoreDoCommandByteArray)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandByteArray));
m64pCoreDoCommandPtr = (CoreDoCommandPtr)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandPtr));
m64pCoreDoCommandRefInt = (CoreDoCommandRefInt)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRefInt));
m64pCoreDoCommandFrameCallback = (CoreDoCommandFrameCallback)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandFrameCallback));
m64pCoreDoCommandVICallback = (CoreDoCommandVICallback)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandVICallback));
m64pCoreDoCommandRenderCallback = (CoreDoCommandRenderCallback)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDoCommand"), typeof(CoreDoCommandRenderCallback));
m64pCoreAttachPlugin = (CoreAttachPlugin)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreAttachPlugin"), typeof(CoreAttachPlugin));
m64pCoreDetachPlugin = (CoreDetachPlugin)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "CoreDetachPlugin"), typeof(CoreDetachPlugin));
m64pConfigOpenSection = (ConfigOpenSection)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "ConfigOpenSection"), typeof(ConfigOpenSection));
m64pConfigSetParameter = (ConfigSetParameter)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "ConfigSetParameter"), typeof(ConfigSetParameter));
m64pConfigSetParameterStr = (ConfigSetParameterStr)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "ConfigSetParameter"), typeof(ConfigSetParameterStr));
m64pCoreSaveState = (savestates_save_bkm)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "savestates_save_bkm"), typeof(savestates_save_bkm));
m64pCoreLoadState = (savestates_load_bkm)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "savestates_load_bkm"), typeof(savestates_load_bkm));
m64pDebugMemGetPointer = (DebugMemGetPointer)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugMemGetPointer"), typeof(DebugMemGetPointer));
m64pDebugSetCallbacks = (DebugSetCallbacks)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugSetCallbacks"), typeof(DebugSetCallbacks));
m64pDebugBreakpointLookup = (DebugBreakpointLookup)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugBreakpointLookup"), typeof(DebugBreakpointLookup));
m64pDebugBreakpointCommand = ( DebugBreakpointCommand )Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugBreakpointCommand"), typeof(DebugBreakpointCommand));
m64pDebugGetState = (DebugGetState)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugGetState"), typeof(DebugGetState));
m64pDebugSetRunState = (DebugSetRunState)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugSetRunState"), typeof(DebugSetRunState));
m64pDebugStep = (DebugStep)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "DebugStep"), typeof(DebugStep));
m64pMemGetSize = (MemGetSize)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "MemGetSize"), typeof(MemGetSize));
m64pinit_saveram = (init_saveram)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "init_saveram"), typeof(init_saveram));
m64psave_saveram = (save_saveram)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(CoreDll, "save_saveram"), typeof(save_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_write_memory_8 = (biz_write_memory)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "biz_write_memory"), typeof(biz_write_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(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>
@ -933,7 +924,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
m64pCoreDoCommandPtr(m64p_command.M64CMD_ROM_CLOSE, 0, IntPtr.Zero);
m64pCoreShutdown();
FreeLibrary(CoreDll);
libLoader.FreePlatformSpecific(CoreDll);
disposed = true;
}
@ -953,18 +944,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
DetachPlugin(type);
AttachedPlugin plugin;
plugin.dllHandle = LoadLibrary(PluginName);
if (plugin.dllHandle == IntPtr.Zero)
throw new InvalidOperationException(string.Format("Failed to load plugin {0}, error code: 0x{1:X}", PluginName, GetLastError()));
plugin.dllHandle = libLoader.LoadPlatformSpecific(PluginName);
plugin.dllStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(plugin.dllHandle, "PluginStartup"), typeof(PluginStartup));
plugin.dllShutdown = (PluginShutdown)Marshal.GetDelegateForFunctionPointer(GetProcAddress(plugin.dllHandle, "PluginShutdown"), typeof(PluginShutdown));
plugin.dllStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(plugin.dllHandle, "PluginStartup"), typeof(PluginStartup));
plugin.dllShutdown = (PluginShutdown)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(plugin.dllHandle, "PluginShutdown"), typeof(PluginShutdown));
plugin.dllStartup(CoreDll, null, null);
m64p_error result = m64pCoreAttachPlugin(type, plugin.dllHandle);
if (result != m64p_error.M64ERR_SUCCESS)
{
FreeLibrary(plugin.dllHandle);
libLoader.FreePlatformSpecific(plugin.dllHandle);
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);
m64pCoreDetachPlugin(type);
plugin.dllShutdown();
FreeLibrary(plugin.dllHandle);
libLoader.FreePlatformSpecific(plugin.dllHandle);
}
}

View File

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

View File

@ -23,7 +23,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
{
var regs = DebuggableCore.GetCpuFlagsAndRegisters();
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
{

Binary file not shown.

Binary file not shown.

View File

@ -1,16 +1,25 @@
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.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="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.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="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.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="libGLESv2.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="SDL2.dll" target="libSDL2.dylib"/>
</configuration>
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.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="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.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="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.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="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.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="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>