Add preliminary Unix compatibility (using Mono; resolves #1384) (#1380)

* Move PlatformSpecificLinkedLibs and implementations to common and rename
* Specify file ext. at LoadPlatformSpecific call site
* Move Client.Common.Global.RunningOnUnix to PlatformLinkedLibSingleton
* Inline var Resolver
* Use PlatformLinkedLibManager internally
* Move plugin load check to LinkedLibManager, use LinkedLibManager
* Interpolate
* Return exit code from dlclose/FreeLibrary
* Skip all calls to externs in BlipBufDll when using mono
* Use PlatformLinkedLibManager in SevenZipLibraryManager
* Add expected return value to workaround (from testing on Win32)
* Remove ".dll" from DllImport attr, remove temporary workaround, see desc.
The library can be built by changing the output file name in
`.../blip_buf/Makefile` to `libblip_buf.so`, and running `make`. It will be
loaded if placed in the `.../output` folder.
* Remove unused code, add TODO (this class is req. for Waterbox.PeWrapper)
The TODO is to [rewrite with
C#](https://docs.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files)
instead of importing from `kernel32.dll`.
* Update OpenTK again but better (for #1384)
* Add Mono run script
* Add libblip_buf.so (temporary)
Temporary because it should be a separate package which BizHawk depends on.
* Add distro detection, add "already running" and "unknown distro" messages
* Gray-out Lua Console on Unix
* Extract superclass from EmuLuaLibrary, add shell implementation for Unix
* Specify libdl version, Fedora doesn't have the versionless symlink
* Remove empty `ToolStripMenuItem`, null `Text` caused crash on Unix
* Transform OpenTK keyboard input into a `List<KeyEvent>` and read that
Also fixes crash on rebind
* Remove debug `using ...;`
This commit is contained in:
James Groom 2019-01-04 08:50:55 +10:00 committed by feos
parent f47c2d1558
commit 42764f0019
32 changed files with 455 additions and 342 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

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

@ -943,6 +943,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

@ -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;

View File

@ -1118,11 +1118,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()

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

@ -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

@ -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

@ -8,9 +8,11 @@ using System.ComponentModel;
using System.Windows.Forms;
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
{
@ -730,6 +732,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

@ -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; }

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>