From 6d5f51b5ba79e8140bbf4e079c62d83b712027ce Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 14:04:53 +1000 Subject: [PATCH 01/16] Update .gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 20ffa86c34..a8f5a6d362 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ svnrev.cs **/ipch/** *.ilk +*.il *.tlog *.obj *.o @@ -74,3 +75,7 @@ libsnes/vs2015/libsnes.VC.db waterbox/**/*.wbx waterbox/**/*.wbx.in /BizHawkTool_template.zip + +mono_crash* + +.idea From 77a6e9c3ace34a0df3c2d775340cc3044da4dc20 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 14:05:41 +1000 Subject: [PATCH 02/16] Remove unused shell script --- subwcrev.sh | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100755 subwcrev.sh diff --git a/subwcrev.sh b/subwcrev.sh deleted file mode 100755 index 4e445b6947..0000000000 --- a/subwcrev.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -cd "`dirname "$0"`" - -if test -d .git ; then - REV="`git svn info | grep Revision: | cut -d' ' -f2`" -else - REV="`svn info | grep Revision: | cut -d' ' -f2`" -fi - -sed -e 's/\$WCREV\$/'$REV'/g' "$1/Properties/svnrev_template" > "$1/Properties/svnrev.cs.tmp" -cmp -s "$1/Properties/svnrev.cs.tmp" "$1/Properties/svnrev.cs" || cp "$1/Properties/svnrev.cs.tmp" "$1/Properties/svnrev.cs" From e8f66570adde3f5ebd24ef049b253583276e270b Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 14:09:50 +1000 Subject: [PATCH 03/16] Update EmuHawkMono.sh --- Assets/EmuHawkMono.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Assets/EmuHawkMono.sh b/Assets/EmuHawkMono.sh index a42a52a5f6..0e59998135 100755 --- a/Assets/EmuHawkMono.sh +++ b/Assets/EmuHawkMono.sh @@ -8,11 +8,14 @@ libpath="" if [ "$(command -v lsb_release)" ]; then case "$(lsb_release -i | cut -c17- | tr -d "\n")" in "Arch"|"ManjaroLinux") libpath="/usr/lib/wine";; - "Debian"|"Ubuntu"|"LinuxMint") libpath="/usr/lib/x86_64-linux-gnu/wine";; + "Debian"|"LinuxMint") libpath="/usr/lib/x86_64-linux-gnu/wine";; + "Ubuntu") libpath="/usr/lib/x86_64-linux-gnu/wine"; export MONO_WINFORMS_XIM_STYLE=disabled;; # see https://bugzilla.xamarin.com/show_bug.cgi?id=28047#c9 esac +else + printf "Distro does not provide LSB release info API! (You've met with a terrible fate, haven't you?)\n" 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 +LD_LIBRARY_PATH="$libpath" mono ./EmuHawk.exe >EmuHawkMono_laststdout.txt From 2d5b069793ff76c9f143b8d633a56f68ff9aeb8d Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 14:27:50 +1000 Subject: [PATCH 04/16] Inline PlatformSpecificMainLoopCrashHandler and implentations UnixMono copy contained workaround for a bug that has since been fixed --- BizHawk.Client.EmuHawk/Program.cs | 168 +++++++++--------------------- 1 file changed, 51 insertions(+), 117 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 02189ec31d..747ac8b7f8 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -89,121 +89,6 @@ namespace BizHawk.Client.EmuHawk return SubMain(args); } - private interface PlatformSpecificMainLoopCrashHandler - { - void TryCatchFinally(string[] args); - } - private class Win32MainLoopCrashHandler : PlatformSpecificMainLoopCrashHandler - { - public void TryCatchFinally(string[] args) - { - try - { - if (Global.Config.SingleInstanceMode) - { - try - { - new SingleInstanceController(args).Run(args); - } - catch (ObjectDisposedException) - { - // Eat it, MainForm disposed itself and Run attempts to dispose of itself. Eventually we would want to figure out a way to prevent that, but in the meantime it is harmless, so just eat the error - } - } - else - { - using (var mf = new MainForm(args)) - { - var title = mf.Text; - mf.Show(); - mf.Text = title; - try - { - GlobalWin.ExitCode = mf.ProgramRunLoop(); - } - catch (Exception e) when (!Debugger.IsAttached && !VersionInfo.DeveloperBuild && Global.MovieSession.Movie.IsActive) - { - var result = MessageBox.Show( - "EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)", - $"Fatal error: {e.GetType().Name}", - MessageBoxButtons.YesNo, - MessageBoxIcon.Exclamation - ); - if (result == DialogResult.Yes) - { - Global.MovieSession.Movie.Save(); - } - } - } - } - } - catch (Exception e) when (!Debugger.IsAttached) - { - new ExceptionBox(e).ShowDialog(); - } - finally - { - if (GlobalWin.Sound != null) - { - GlobalWin.Sound.Dispose(); - GlobalWin.Sound = null; - } - GlobalWin.GL.Dispose(); - Input.Cleanup(); - } - } - } - private class UnixMonoMainLoopCrashHandler : PlatformSpecificMainLoopCrashHandler - { - // Identical to the implementation in Win32MainLoopCrashHandler sans the single-instance check. - public void TryCatchFinally(string[] args) - { - try - { - using (var mf = new MainForm(args)) - { - var title = mf.Text; - mf.Show(); - mf.Text = title; - try - { - GlobalWin.ExitCode = mf.ProgramRunLoop(); - } - catch (Exception e) when (!Debugger.IsAttached && !VersionInfo.DeveloperBuild && Global.MovieSession.Movie.IsActive) - { - var result = MessageBox.Show( - "EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)", - $"Fatal error: {e.GetType().Name}", - MessageBoxButtons.YesNo, - MessageBoxIcon.Exclamation - ); - if (result == DialogResult.Yes) - { - Global.MovieSession.Movie.Save(); - } - } - } - } - catch (Exception e) when (!Debugger.IsAttached) - { - new ExceptionBox(e).ShowDialog(); - } - finally - { - if (GlobalWin.Sound != null) - { - GlobalWin.Sound.Dispose(); - GlobalWin.Sound = null; - } - GlobalWin.GL.Dispose(); - Input.Cleanup(); - } - } - } - private static PlatformSpecificMainLoopCrashHandler mainLoopCrashHandler = EXE_PROJECT.PlatformLinkedLibSingleton.RunningOnUnix - ? (PlatformSpecificMainLoopCrashHandler) new UnixMonoMainLoopCrashHandler() - : (PlatformSpecificMainLoopCrashHandler) new Win32MainLoopCrashHandler(); - //NoInlining should keep this code from getting jammed into Main() which would create dependencies on types which havent been setup by the resolver yet... or something like that [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] static int SubMain(string[] args) @@ -324,8 +209,57 @@ namespace BizHawk.Client.EmuHawk SetDllDirectory(dllDir); } - // Using a simple conditional to skip the single-instancing step caused crashes on GNU+Linux, even though the single-instancing step wasn't being executed. Something about the way instantiation works in C# means this workaround is possible. - mainLoopCrashHandler.TryCatchFinally(args); + try + { + if (Global.Config.SingleInstanceMode) + { + try + { + new SingleInstanceController(args).Run(args); + } + catch (ObjectDisposedException) + { + // Eat it, MainForm disposed itself and Run attempts to dispose of itself. Eventually we would want to figure out a way to prevent that, but in the meantime it is harmless, so just eat the error + } + } + else + { + using (var mf = new MainForm(args)) + { + var title = mf.Text; + mf.Show(); + mf.Text = title; + try + { + GlobalWin.ExitCode = mf.ProgramRunLoop(); + } + catch (Exception e) when (Global.MovieSession.Movie.IsActive && !(Debugger.IsAttached || VersionInfo.DeveloperBuild)) + { + var result = MessageBox.Show( + "EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)", + $"Fatal error: {e.GetType().Name}", + MessageBoxButtons.YesNo, + MessageBoxIcon.Exclamation + ); + if (result == DialogResult.Yes) + { + Global.MovieSession.Movie.Save(); + } + } + } + } + } + catch (Exception e) when (!Debugger.IsAttached) + { + new ExceptionBox(e).ShowDialog(); + } + finally + { + GlobalWin.Sound?.Dispose(); + GlobalWin.Sound = null; + GlobalWin.GL.Dispose(); + Input.Cleanup(); + } //cleanup: //cleanup IGL stuff so we can get better refcounts when exiting process, for debugging From 752f8cfd49368c65d0b3f6ff89d09c9c5e9f789f Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 14:34:15 +1000 Subject: [PATCH 05/16] Don't bother checking for Windows prereqs on Unix --- BizHawk.Client.EmuHawk/Program.cs | 83 +++++++++++++++---------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 747ac8b7f8..86692bdd87 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -23,50 +23,49 @@ namespace BizHawk.Client.EmuHawk Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - var libLoader = EXE_PROJECT.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 libExt = EXE_PROJECT.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; - fail |= vc2010 == IntPtr.Zero; - fail |= vc2012 == IntPtr.Zero; - fail |= vc2010p == IntPtr.Zero; - if (fail || warn) - { - var sw = new System.IO.StringWriter(); - sw.WriteLine("[ OK ] .Net 4.6.1 (You couldn't even get here without it)"); - sw.WriteLine("[{0}] Direct3d 9", d3dx9 == IntPtr.Zero ? "FAIL" : " OK "); - sw.WriteLine("[{0}] Visual C++ 2010 SP1 Runtime", (vc2010 == IntPtr.Zero || vc2010p == IntPtr.Zero) ? "FAIL" : " OK "); - sw.WriteLine("[{0}] Visual C++ 2012 Runtime", (vc2012 == IntPtr.Zero) ? "FAIL" : " OK "); - sw.WriteLine("[{0}] Visual C++ 2015 Runtime", (vc2015 == IntPtr.Zero) ? "FAIL" : " OK "); - var str = sw.ToString(); - var box = new BizHawk.Client.EmuHawk.CustomControls.PrereqsAlert(!fail); - box.textBox1.Text = str; - box.ShowDialog(); - if (!fail) { } - else - System.Diagnostics.Process.GetCurrentProcess().Kill(); - } - - libLoader.FreePlatformSpecific(d3dx9); - libLoader.FreePlatformSpecific(vc2015); - libLoader.FreePlatformSpecific(vc2012); - libLoader.FreePlatformSpecific(vc2010); - libLoader.FreePlatformSpecific(vc2010p); - if (!EXE_PROJECT.PlatformLinkedLibSingleton.RunningOnUnix) { + var libLoader = EXE_PROJECT.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"); + bool fail = false, warn = false; + warn |= d3dx9 == IntPtr.Zero; + fail |= vc2015 == IntPtr.Zero; + fail |= vc2010 == IntPtr.Zero; + fail |= vc2012 == IntPtr.Zero; + fail |= vc2010p == IntPtr.Zero; + if (fail || warn) + { + var sw = new System.IO.StringWriter(); + sw.WriteLine("[ OK ] .Net 4.6.1 (You couldn't even get here without it)"); + sw.WriteLine("[{0}] Direct3d 9", d3dx9 == IntPtr.Zero ? "FAIL" : " OK "); + sw.WriteLine("[{0}] Visual C++ 2010 SP1 Runtime", (vc2010 == IntPtr.Zero || vc2010p == IntPtr.Zero) ? "FAIL" : " OK "); + sw.WriteLine("[{0}] Visual C++ 2012 Runtime", (vc2012 == IntPtr.Zero) ? "FAIL" : " OK "); + sw.WriteLine("[{0}] Visual C++ 2015 Runtime", (vc2015 == IntPtr.Zero) ? "FAIL" : " OK "); + var str = sw.ToString(); + var box = new BizHawk.Client.EmuHawk.CustomControls.PrereqsAlert(!fail); + box.textBox1.Text = str; + box.ShowDialog(); + if (!fail) { } + else + System.Diagnostics.Process.GetCurrentProcess().Kill(); + } + + libLoader.FreePlatformSpecific(d3dx9); + libLoader.FreePlatformSpecific(vc2015); + libLoader.FreePlatformSpecific(vc2012); + libLoader.FreePlatformSpecific(vc2010); + libLoader.FreePlatformSpecific(vc2010p); + // this will look in subdirectory "dll" to load pinvoked stuff string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll"); SetDllDirectory(dllDir); From 436b6452fbe0a791ce8f7487d021d41c5f01a4bb Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 15:14:08 +1000 Subject: [PATCH 06/16] Misc. refactoring --- BizHawk.Client.EmuHawk/Program.cs | 138 +++++++++++++----------------- 1 file changed, 59 insertions(+), 79 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 86692bdd87..b09c9b6a51 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.Diagnostics; using System.IO; using System.Collections.Generic; @@ -15,7 +14,7 @@ using BizHawk.Client.Common; namespace BizHawk.Client.EmuHawk { - static class Program + internal static class Program { static Program() { @@ -37,27 +36,24 @@ namespace BizHawk.Client.EmuHawk var vc2012 = libLoader.LoadPlatformSpecific("msvcr120.dll"); //TODO - check version? var vc2010 = libLoader.LoadPlatformSpecific("msvcr100.dll"); //TODO - check version? var vc2010p = libLoader.LoadPlatformSpecific("msvcp100.dll"); - bool fail = false, warn = false; - warn |= d3dx9 == IntPtr.Zero; - fail |= vc2015 == IntPtr.Zero; - fail |= vc2010 == IntPtr.Zero; - fail |= vc2012 == IntPtr.Zero; - fail |= vc2010p == IntPtr.Zero; + var fail = vc2015 == IntPtr.Zero || vc2010 == IntPtr.Zero || vc2012 == IntPtr.Zero || vc2010p == IntPtr.Zero; + var warn = d3dx9 == IntPtr.Zero; if (fail || warn) { - var sw = new System.IO.StringWriter(); - sw.WriteLine("[ OK ] .Net 4.6.1 (You couldn't even get here without it)"); - sw.WriteLine("[{0}] Direct3d 9", d3dx9 == IntPtr.Zero ? "FAIL" : " OK "); - sw.WriteLine("[{0}] Visual C++ 2010 SP1 Runtime", (vc2010 == IntPtr.Zero || vc2010p == IntPtr.Zero) ? "FAIL" : " OK "); - sw.WriteLine("[{0}] Visual C++ 2012 Runtime", (vc2012 == IntPtr.Zero) ? "FAIL" : " OK "); - sw.WriteLine("[{0}] Visual C++ 2015 Runtime", (vc2015 == IntPtr.Zero) ? "FAIL" : " OK "); - var str = sw.ToString(); - var box = new BizHawk.Client.EmuHawk.CustomControls.PrereqsAlert(!fail); - box.textBox1.Text = str; + var alertLines = new[] + { + "[ OK ] .NET CLR (You wouldn't even get here without it)", + $"[{(d3dx9 == IntPtr.Zero ? "WARN" : " OK ")}] Direct3d 9", + $"[{(vc2010 == IntPtr.Zero || vc2010p == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2010 SP1 Runtime", + $"[{(vc2012 == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2012 Runtime", + $"[{(vc2015 == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2015 Runtime" + }; + var box = new BizHawk.Client.EmuHawk.CustomControls.PrereqsAlert(!fail) + { + textBox1 = { Text = string.Concat("\n", alertLines) } + }; box.ShowDialog(); - if (!fail) { } - else - System.Diagnostics.Process.GetCurrentProcess().Kill(); + if (fail) System.Diagnostics.Process.GetCurrentProcess().Kill(); } libLoader.FreePlatformSpecific(d3dx9); @@ -67,11 +63,11 @@ namespace BizHawk.Client.EmuHawk libLoader.FreePlatformSpecific(vc2010p); // this will look in subdirectory "dll" to load pinvoked stuff - string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll"); + var dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll"); SetDllDirectory(dllDir); //in case assembly resolution fails, such as if we moved them into the dll subdiretory, this event handler can reroute to them - AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); + AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; //but before we even try doing that, whack the MOTW from everything in that directory (thats a dll) //otherwise, some people will have crashes at boot-up due to .net security disliking MOTW. @@ -83,14 +79,14 @@ namespace BizHawk.Client.EmuHawk } [STAThread] - static int Main(string[] args) + private static int Main(string[] args) { return SubMain(args); } //NoInlining should keep this code from getting jammed into Main() which would create dependencies on types which havent been setup by the resolver yet... or something like that [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] - static int SubMain(string[] args) + private static int SubMain(string[] args) { // this check has to be done VERY early. i stepped through a debug build with wrong .dll versions purposely used, // and there was a TypeLoadException before the first line of SubMain was reached (some static ColorType init?) @@ -112,7 +108,7 @@ namespace BizHawk.Client.EmuHawk HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler(); - ArgParser argParser = new ArgParser(); + var argParser = new ArgParser(); argParser.ParseArguments(args); if (argParser.cmdConfigFile != null) PathManager.SetDefaultIniPath(argParser.cmdConfigFile); @@ -132,13 +128,9 @@ namespace BizHawk.Client.EmuHawk BizHawk.Client.Common.StringLogUtil.DefaultToAWE = Global.Config.MoviesInAWE; // super hacky! this needs to be done first. still not worth the trouble to make this system fully proper - for (int i = 0; i < args.Length; i++) + if (Array.Exists(args, arg => arg.StartsWith("--gdi", StringComparison.InvariantCultureIgnoreCase))) { - var arg = args[i].ToLower(); - if (arg.StartsWith("--gdi")) - { - Global.Config.DispMethod = Config.EDispMethod.GdiPlus; - } + Global.Config.DispMethod = Config.EDispMethod.GdiPlus; } // create IGL context. we do this whether or not the user has selected OpenGL, so that we can run opengl-based emulator cores @@ -161,8 +153,7 @@ namespace BizHawk.Client.EmuHawk } catch(Exception ex) { - var e2 = new Exception("Initialization of Direct3d 9 Display Method failed; falling back to GDI+", ex); - new ExceptionBox(e2).ShowDialog(); + new ExceptionBox(new Exception("Initialization of Direct3d 9 Display Method failed; falling back to GDI+", ex)).ShowDialog(); // fallback Global.Config.DispMethod = Config.EDispMethod.GdiPlus; @@ -174,8 +165,7 @@ namespace BizHawk.Client.EmuHawk GlobalWin.GL = GlobalWin.IGL_GL; // check the opengl version and dont even try to boot this crap up if its too old - int version = GlobalWin.IGL_GL.Version; - if (version < 200) + if (GlobalWin.IGL_GL.Version < 200) { // fallback Global.Config.DispMethod = Config.EDispMethod.GdiPlus; @@ -190,8 +180,8 @@ namespace BizHawk.Client.EmuHawk } catch(Exception ex) { - var e2 = new Exception("Initialization of Display Method failed; falling back to GDI+", ex); - new ExceptionBox(e2).ShowDialog(); + new ExceptionBox(new Exception("Initialization of Display Method failed; falling back to GDI+", ex)).ShowDialog(); + //fallback Global.Config.DispMethod = Config.EDispMethod.GdiPlus; goto REDO_DISPMETHOD; @@ -204,7 +194,7 @@ namespace BizHawk.Client.EmuHawk //It isn't clear whether we need the earlier SetDllDirectory(), but I think we do. //note: this is pasted instead of being put in a static method due to this initialization code being sensitive to things like that, and not wanting to cause it to break //pasting should be safe (not affecting the jit order of things) - string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll"); + var dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll"); SetDllDirectory(dllDir); } @@ -214,7 +204,7 @@ namespace BizHawk.Client.EmuHawk { try { - new SingleInstanceController(args).Run(args); + new SingleInstanceController(args).Run(); } catch (ObjectDisposedException) { @@ -273,20 +263,21 @@ namespace BizHawk.Client.EmuHawk return GlobalWin.ExitCode; } //SubMain - //declared here instead of a more usual place to avoid dependencies on the more usual place #if WINDOWS + //declared here instead of a more usual place to avoid dependencies on the more usual place + [DllImport("kernel32.dll", SetLastError = true)] - static extern uint SetDllDirectory(string lpPathName); + private static extern uint SetDllDirectory(string lpPathName); [DllImport("kernel32.dll", EntryPoint = "DeleteFileW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] - static extern bool DeleteFileW([MarshalAs(UnmanagedType.LPWStr)]string lpFileName); + private static extern bool DeleteFileW([MarshalAs(UnmanagedType.LPWStr)]string lpFileName); - public static void RemoveMOTW(string path) + private static void RemoveMOTW(string path) { DeleteFileW($"{path}:Zone.Identifier"); } - static void WhackAllMOTW(string dllDir) + private static void WhackAllMOTW(string dllDir) { var todo = new Queue(new[] { new DirectoryInfo(dllDir) }); while (todo.Count > 0) @@ -298,14 +289,12 @@ namespace BizHawk.Client.EmuHawk foreach (var fi in di.GetFiles("*.exe")) RemoveMOTW(fi.FullName); } - } #endif - - static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) + private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { - string requested = args.Name; + var requested = args.Name; //mutate filename depending on selection of lua core. here's how it works //1. we build NLua to the output/dll/lua directory. that brings KopiLua with it @@ -313,52 +302,43 @@ namespace BizHawk.Client.EmuHawk //3. When NLua assembly attempts to load, it can't find it //I. if LuaInterface is selected by the user, we switch to requesting that. // (those DLLs are built into the output/DLL directory) - //II. if NLua is selected by the user, we skip over this part; + //II. if NLua is selected by the user, we skip over this part; // later, we look for NLua or KopiLua assembly names and redirect them to files located in the output/DLL/nlua directory if (new AssemblyName(requested).Name == "NLua") { //this method referencing Global.Config makes assemblies get loaded, which isnt smart from the assembly resolver. //so.. we're going to resort to something really bad. //avert your eyes. - bool UseNLua = true; - string configPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.ini"); - if (File.Exists(configPath)) + var configPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.ini"); + if (File.Exists(configPath) + && (Array.Find(File.ReadAllLines(configPath), line => line.Contains(" \"UseNLua\": ")) ?? string.Empty) + .Contains("false")) { - var cfg = File.ReadAllLines(configPath); - var usenlua_key = cfg.FirstOrDefault(line=>line.Contains(" \"UseNLua\": ")); - if (usenlua_key != null) - if (usenlua_key.Contains("false")) - UseNLua = false; + requested = "LuaInterface"; } - - if (UseNLua) { } - else requested = "LuaInterface"; } lock (AppDomain.CurrentDomain) { - var asms = AppDomain.CurrentDomain.GetAssemblies(); - foreach (var asm in asms) - if (asm.FullName == requested) - return asm; + var firstAsm = Array.Find(AppDomain.CurrentDomain.GetAssemblies(), asm => asm.FullName == requested); + if (firstAsm != null) return firstAsm; //load missing assemblies by trying to find them in the dll directory - string dllname = $"{new AssemblyName(requested).Name}.dll"; - string directory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll"); - string simpleName = new AssemblyName(requested).Name; + var dllname = $"{new AssemblyName(requested).Name}.dll"; + var directory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll"); + var simpleName = new AssemblyName(requested).Name; if (simpleName == "NLua" || simpleName == "KopiLua") directory = Path.Combine(directory, "nlua"); - string fname = Path.Combine(directory, dllname); - if (!File.Exists(fname)) return null; - - //it is important that we use LoadFile here and not load from a byte array; otherwise mixed (managed/unamanged) assemblies can't load - return Assembly.LoadFile(fname); + var fname = Path.Combine(directory, dllname); + //it is important that we use LoadFile here and not load from a byte array; otherwise mixed (managed/unmanaged) assemblies can't load + return File.Exists(fname) ? Assembly.LoadFile(fname) : null; } } #if WINDOWS - public class SingleInstanceController : WindowsFormsApplicationBase + private class SingleInstanceController : WindowsFormsApplicationBase { - readonly string[] cmdArgs; + private readonly string[] cmdArgs; + public SingleInstanceController(string[] args) { cmdArgs = args; @@ -366,10 +346,12 @@ namespace BizHawk.Client.EmuHawk StartupNextInstance += this_StartupNextInstance; } - void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e) + public void Run() => Run(cmdArgs); + + private void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e) { if (e.CommandLine.Count >= 1) - (MainForm as MainForm).LoadRom(e.CommandLine[0], new MainForm.LoadRomArgs() { OpenAdvanced = new OpenAdvanced_OpenRom() }); + ((MainForm)MainForm).LoadRom(e.CommandLine[0], new MainForm.LoadRomArgs { OpenAdvanced = new OpenAdvanced_OpenRom() }); } protected override void OnCreateMainForm() @@ -378,11 +360,9 @@ namespace BizHawk.Client.EmuHawk var title = MainForm.Text; MainForm.Show(); MainForm.Text = title; - GlobalWin.ExitCode = (MainForm as MainForm).ProgramRunLoop(); + GlobalWin.ExitCode = ((MainForm)MainForm).ProgramRunLoop(); } } - - #endif } } From d76e1a8a8b7483b052574e8fa62e657ec80ebc4e Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 15:30:29 +1000 Subject: [PATCH 07/16] Refactor PlatformLinkedLibSingleton and replace RunningOnUnix with CurrentOS --- BizHawk.Client.EmuHawk/Input/Input.cs | 30 ++++---- BizHawk.Client.EmuHawk/Program.cs | 10 +-- BizHawk.Client.EmuHawk/ScreenSaver.cs | 6 +- BizHawk.Client.EmuHawk/Sound/Sound.cs | 2 +- BizHawk.Client.EmuHawk/Throttle.cs | 2 +- BizHawk.Client.EmuHawk/config/InputWidget.cs | 4 +- .../tools/Lua/LuaConsole.cs | 6 +- BizHawk.Client.EmuHawk/tools/ToolManager.cs | 2 +- BizHawk.Common/PlatformLinkedLibSingleton.cs | 70 ++++++++++++++----- 9 files changed, 85 insertions(+), 47 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Input/Input.cs b/BizHawk.Client.EmuHawk/Input/Input.cs index 519594fe34..2f84152d7f 100644 --- a/BizHawk.Client.EmuHawk/Input/Input.cs +++ b/BizHawk.Client.EmuHawk/Input/Input.cs @@ -123,24 +123,24 @@ namespace BizHawk.Client.EmuHawk public static void Initialize() { - if (PlatformLinkedLibSingleton.RunningOnUnix) - { - OTK_Keyboard.Initialize(); -// OTK_Gamepad.Initialize(); - } - else + if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) { KeyInput.Initialize(); IPCKeyInput.Initialize(); GamePad.Initialize(); GamePad360.Initialize(); } + else + { + OTK_Keyboard.Initialize(); +// OTK_Gamepad.Initialize(); + } Instance = new Input(); } public static void Cleanup() { - if (!PlatformLinkedLibSingleton.RunningOnUnix) + if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) { KeyInput.Cleanup(); GamePad.Cleanup(); @@ -331,18 +331,18 @@ namespace BizHawk.Client.EmuHawk { while (true) { - var keyEvents = PlatformLinkedLibSingleton.RunningOnUnix - ? OTK_Keyboard.Update() - : KeyInput.Update().Concat(IPCKeyInput.Update()); - if (PlatformLinkedLibSingleton.RunningOnUnix) - { - //TODO - } - else + var keyEvents = PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows + ? KeyInput.Update().Concat(IPCKeyInput.Update()) + : OTK_Keyboard.Update(); + if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) { GamePad.UpdateAll(); GamePad360.UpdateAll(); } + else + { + //TODO + } //this block is going to massively modify data structures that the binding method uses, so we have to lock it all lock (this) diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index b09c9b6a51..6993c8f3f8 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -22,7 +22,7 @@ namespace BizHawk.Client.EmuHawk Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - if (!EXE_PROJECT.PlatformLinkedLibSingleton.RunningOnUnix) + if (EXE_PROJECT.PlatformLinkedLibSingleton.CurrentOS == EXE_PROJECT.PlatformLinkedLibSingleton.DistinctOS.Windows) { var libLoader = EXE_PROJECT.PlatformLinkedLibSingleton.LinkedLibManager; @@ -141,8 +141,10 @@ 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 (EXE_PROJECT.PlatformLinkedLibSingleton.RunningOnUnix) Global.Config.DispMethod = Config.EDispMethod.GdiPlus; - REDO_DISPMETHOD: + if (EXE_PROJECT.PlatformLinkedLibSingleton.CurrentOS != EXE_PROJECT.PlatformLinkedLibSingleton.DistinctOS.Windows) + Global.Config.DispMethod = Config.EDispMethod.GdiPlus; + +REDO_DISPMETHOD: if (Global.Config.DispMethod == Config.EDispMethod.GdiPlus) GlobalWin.GL = new Bizware.BizwareGL.Drivers.GdiPlus.IGL_GdiPlus(); else if (Global.Config.DispMethod == Config.EDispMethod.SlimDX9) @@ -187,7 +189,7 @@ namespace BizHawk.Client.EmuHawk goto REDO_DISPMETHOD; } - if (!EXE_PROJECT.PlatformLinkedLibSingleton.RunningOnUnix) + if (EXE_PROJECT.PlatformLinkedLibSingleton.CurrentOS == EXE_PROJECT.PlatformLinkedLibSingleton.DistinctOS.Windows) { //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". diff --git a/BizHawk.Client.EmuHawk/ScreenSaver.cs b/BizHawk.Client.EmuHawk/ScreenSaver.cs index d362b4b2c2..d09ea9b8a9 100644 --- a/BizHawk.Client.EmuHawk/ScreenSaver.cs +++ b/BizHawk.Client.EmuHawk/ScreenSaver.cs @@ -41,9 +41,9 @@ namespace BizHawk.Client.EmuHawk //TODO implement } } - private static PlatformSpecificScreenBlankInterface screenBlankInterface = PlatformLinkedLibSingleton.RunningOnUnix - ? (PlatformSpecificScreenBlankInterface) new MiscUnixScreenBlankInterface() - : (PlatformSpecificScreenBlankInterface) new WinScreenBlankInterface(); + private static PlatformSpecificScreenBlankInterface screenBlankInterface = PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows + ? (PlatformSpecificScreenBlankInterface) new WinScreenBlankInterface() + : (PlatformSpecificScreenBlankInterface) new MiscUnixScreenBlankInterface(); private const int SPI_GETSCREENSAVERTIMEOUT = 14; private const int SPI_SETSCREENSAVERTIMEOUT = 15; diff --git a/BizHawk.Client.EmuHawk/Sound/Sound.cs b/BizHawk.Client.EmuHawk/Sound/Sound.cs index 1edaaae699..cd6891bd9d 100644 --- a/BizHawk.Client.EmuHawk/Sound/Sound.cs +++ b/BizHawk.Client.EmuHawk/Sound/Sound.cs @@ -27,7 +27,7 @@ namespace BizHawk.Client.EmuHawk { if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL) _outputDevice = new OpenALSoundOutput(this); - if (!PlatformLinkedLibSingleton.RunningOnUnix) + if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) { if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound) _outputDevice = new DirectSoundSoundOutput(this, mainWindowHandle); diff --git a/BizHawk.Client.EmuHawk/Throttle.cs b/BizHawk.Client.EmuHawk/Throttle.cs index af7334ef81..d703bce4ac 100644 --- a/BizHawk.Client.EmuHawk/Throttle.cs +++ b/BizHawk.Client.EmuHawk/Throttle.cs @@ -160,7 +160,7 @@ namespace BizHawk.Client.EmuHawk return timeBeginPeriod(ms); } } - static PlatformSpecificSysTimer sysTimer = PlatformLinkedLibSingleton.RunningOnUnix ? (PlatformSpecificSysTimer) new UnixMonoSysTimer() : (PlatformSpecificSysTimer) new WinSysTimer(); + static PlatformSpecificSysTimer sysTimer = PlatformLinkedLibSingleton.CurrentOS != PlatformLinkedLibSingleton.DistinctOS.Windows ? (PlatformSpecificSysTimer) new UnixMonoSysTimer() : (PlatformSpecificSysTimer) new WinSysTimer(); static uint TimeBeginPeriod(uint ms) { return sysTimer.TimeBeginPeriod(ms); diff --git a/BizHawk.Client.EmuHawk/config/InputWidget.cs b/BizHawk.Client.EmuHawk/config/InputWidget.cs index 79167ea11f..b6ffe91457 100644 --- a/BizHawk.Client.EmuHawk/config/InputWidget.cs +++ b/BizHawk.Client.EmuHawk/config/InputWidget.cs @@ -71,7 +71,7 @@ namespace BizHawk.Client.EmuHawk protected override void OnMouseClick(MouseEventArgs e) { - if (!PlatformLinkedLibSingleton.RunningOnUnix) HideCaret(Handle); + if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) HideCaret(Handle); base.OnMouseClick(e); } @@ -264,7 +264,7 @@ namespace BizHawk.Client.EmuHawk protected override void OnGotFocus(EventArgs e) { - if (!PlatformLinkedLibSingleton.RunningOnUnix) HideCaret(Handle); + if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) HideCaret(Handle); } protected override bool ProcessCmdKey(ref Message msg, Keys keyData) diff --git a/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs b/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs index 17b646b63c..92f954e0c2 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs @@ -186,9 +186,9 @@ namespace BizHawk.Client.EmuHawk } var currentScripts = LuaImp?.ScriptList; // Temp fix for now - LuaImp = PlatformLinkedLibSingleton.RunningOnUnix - ? (PlatformEmuLuaLibrary) new NotReallyLuaLibrary() - : (PlatformEmuLuaLibrary) new EmuLuaLibrary(Emulator.ServiceProvider); + LuaImp = PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows + ? (PlatformEmuLuaLibrary) new EmuLuaLibrary(Emulator.ServiceProvider) + : (PlatformEmuLuaLibrary) new NotReallyLuaLibrary(); if (currentScripts != null) { LuaImp.ScriptList.AddRange(currentScripts); diff --git a/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/BizHawk.Client.EmuHawk/tools/ToolManager.cs index 1d4f348f0f..5d381b2184 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -740,7 +740,7 @@ namespace BizHawk.Client.EmuHawk return false; } - if (t == typeof(LuaConsole) && PlatformLinkedLibSingleton.RunningOnUnix) return false; + if (t == typeof(LuaConsole) && PlatformLinkedLibSingleton.CurrentOS != PlatformLinkedLibSingleton.DistinctOS.Windows) return false; var tool = Assembly .GetExecutingAssembly() diff --git a/BizHawk.Common/PlatformLinkedLibSingleton.cs b/BizHawk.Common/PlatformLinkedLibSingleton.cs index 14ed9c29e6..afc8b46054 100644 --- a/BizHawk.Common/PlatformLinkedLibSingleton.cs +++ b/BizHawk.Common/PlatformLinkedLibSingleton.cs @@ -1,24 +1,53 @@ using System; -using System.Runtime.InteropServices; - -//put in a different namespace for EXE so we can have an instance of this type (by linking to this file rather than copying it) built-in to the exe -//so the exe doesnt implicitly depend on the dll +using System.Diagnostics; +using System.Runtime.InteropServices; + +//put in a different namespace for EXE so we can have an instance of this type (by linking to this file rather than copying it) built-in to the exe +//so the exe doesnt implicitly depend on the dll #if EXE_PROJECT namespace EXE_PROJECT #else namespace BizHawk.Common #endif -{ - -public sealed class PlatformLinkedLibSingleton +{ + public sealed class PlatformLinkedLibSingleton { - public static readonly bool RunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX; + /// macOS doesn't use PlatformID.MacOSX + public static readonly DistinctOS CurrentOS = Environment.OSVersion.Platform == PlatformID.Unix + ? currentIsMacOS() ? DistinctOS.macOS : DistinctOS.Linux + : DistinctOS.Windows; - private static readonly Lazy lazy = new Lazy(() => RunningOnUnix - ? (PlatformLinkedLibManager) new UnixMonoLinkedLibManager() - : (PlatformLinkedLibManager) new Win32LinkedLibManager()); + private static readonly Lazy lazy = new Lazy(() => + { + switch (CurrentOS) + { + case DistinctOS.Linux: + case DistinctOS.macOS: + return new UnixMonoLinkedLibManager(); + case DistinctOS.Windows: + return new Win32LinkedLibManager(); + default: + throw new ArgumentOutOfRangeException(); + } + }); - public static PlatformLinkedLibManager LinkedLibManager { get { return lazy.Value; } } + public static PlatformLinkedLibManager LinkedLibManager => lazy.Value; + + private static bool currentIsMacOS() + { + var proc = new Process { + StartInfo = new ProcessStartInfo { + Arguments = "-s", + CreateNoWindow = true, + FileName = "uname", + RedirectStandardOutput = true, + UseShellExecute = false + } + }; + proc.Start(); + if (proc.StandardOutput.EndOfStream) throw new Exception("Can't determine OS (uname wrote nothing to stdout)!"); + return proc.StandardOutput.ReadLine() == "Darwin"; + } private PlatformLinkedLibSingleton() {} @@ -29,16 +58,16 @@ public sealed class PlatformLinkedLibSingleton int FreePlatformSpecific(IntPtr hModule); } - public class UnixMonoLinkedLibManager : PlatformLinkedLibManager + private 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); + 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); + 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) @@ -59,7 +88,7 @@ public sealed class PlatformLinkedLibSingleton } } - public class Win32LinkedLibManager : PlatformLinkedLibManager + private class Win32LinkedLibManager : PlatformLinkedLibManager { [DllImport("kernel32.dll")] private static extern UInt32 GetLastError(); @@ -89,5 +118,12 @@ public sealed class PlatformLinkedLibSingleton return FreeLibrary(hModule) ? 1 : 0; } } + + public enum DistinctOS : byte + { + Linux = 0, + macOS = 1, + Windows = 2 + } } -} +} \ No newline at end of file From 58c738957ce78bc87e1d2f8464e9c37f1eee7c24 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 15:38:51 +1000 Subject: [PATCH 08/16] Rename PlatformLinkedLibSingleton and children --- BizHawk.Client.Common/7z/LibraryManager.cs | 2 +- .../BizHawk.Client.EmuHawk.csproj | 6 ++-- BizHawk.Client.EmuHawk/Input/Input.cs | 8 ++--- BizHawk.Client.EmuHawk/Program.cs | 8 ++--- BizHawk.Client.EmuHawk/ScreenSaver.cs | 2 +- BizHawk.Client.EmuHawk/Sound/Sound.cs | 2 +- BizHawk.Client.EmuHawk/Throttle.cs | 2 +- BizHawk.Client.EmuHawk/config/InputWidget.cs | 4 +-- .../tools/Lua/LuaConsole.cs | 2 +- BizHawk.Client.EmuHawk/tools/ToolManager.cs | 2 +- BizHawk.Common/BizHawk.Common.csproj | 2 +- .../BizInvoke/DynamicLibraryImportResolver.cs | 4 +-- ...inkedLibSingleton.cs => OSTailoredCode.cs} | 30 +++++++++---------- .../N64/NativeApi/mupen64plusCoreApi.cs | 2 +- 14 files changed, 38 insertions(+), 38 deletions(-) rename BizHawk.Common/{PlatformLinkedLibSingleton.cs => OSTailoredCode.cs} (82%) diff --git a/BizHawk.Client.Common/7z/LibraryManager.cs b/BizHawk.Client.Common/7z/LibraryManager.cs index ac0aedd2ee..6f2f375862 100644 --- a/BizHawk.Client.Common/7z/LibraryManager.cs +++ b/BizHawk.Client.Common/7z/LibraryManager.cs @@ -89,7 +89,7 @@ namespace SevenZip // private static string _LibraryVersion; private static bool? _modifyCapabale; - private static readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager; + private static readonly OSTailoredCode.ILinkedLibManager libLoader = OSTailoredCode.LinkedLibManager; private static void InitUserInFormat(object user, InArchiveFormat format) { diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 97a06e1c3b..f8710bbc42 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -113,8 +113,8 @@ - - PlatformLinkedLibSingleton.cs + + OSTailoredCode.cs svnrev.cs @@ -2283,4 +2283,4 @@ - \ No newline at end of file + diff --git a/BizHawk.Client.EmuHawk/Input/Input.cs b/BizHawk.Client.EmuHawk/Input/Input.cs index 2f84152d7f..a890029682 100644 --- a/BizHawk.Client.EmuHawk/Input/Input.cs +++ b/BizHawk.Client.EmuHawk/Input/Input.cs @@ -123,7 +123,7 @@ namespace BizHawk.Client.EmuHawk public static void Initialize() { - if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) { KeyInput.Initialize(); IPCKeyInput.Initialize(); @@ -140,7 +140,7 @@ namespace BizHawk.Client.EmuHawk public static void Cleanup() { - if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) { KeyInput.Cleanup(); GamePad.Cleanup(); @@ -331,10 +331,10 @@ namespace BizHawk.Client.EmuHawk { while (true) { - var keyEvents = PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows + var keyEvents = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows ? KeyInput.Update().Concat(IPCKeyInput.Update()) : OTK_Keyboard.Update(); - if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) { GamePad.UpdateAll(); GamePad360.UpdateAll(); diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 6993c8f3f8..c46f0c961c 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -22,9 +22,9 @@ namespace BizHawk.Client.EmuHawk Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - if (EXE_PROJECT.PlatformLinkedLibSingleton.CurrentOS == EXE_PROJECT.PlatformLinkedLibSingleton.DistinctOS.Windows) + if (EXE_PROJECT.OSTailoredCode.CurrentOS == EXE_PROJECT.OSTailoredCode.DistinctOS.Windows) { - var libLoader = EXE_PROJECT.PlatformLinkedLibSingleton.LinkedLibManager; + var libLoader = EXE_PROJECT.OSTailoredCode.LinkedLibManager; //http://www.codeproject.com/Articles/310675/AppDomain-AssemblyResolve-Event-Tips @@ -141,7 +141,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 (EXE_PROJECT.PlatformLinkedLibSingleton.CurrentOS != EXE_PROJECT.PlatformLinkedLibSingleton.DistinctOS.Windows) + if (EXE_PROJECT.OSTailoredCode.CurrentOS != EXE_PROJECT.OSTailoredCode.DistinctOS.Windows) Global.Config.DispMethod = Config.EDispMethod.GdiPlus; REDO_DISPMETHOD: @@ -189,7 +189,7 @@ REDO_DISPMETHOD: goto REDO_DISPMETHOD; } - if (EXE_PROJECT.PlatformLinkedLibSingleton.CurrentOS == EXE_PROJECT.PlatformLinkedLibSingleton.DistinctOS.Windows) + if (EXE_PROJECT.OSTailoredCode.CurrentOS == EXE_PROJECT.OSTailoredCode.DistinctOS.Windows) { //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". diff --git a/BizHawk.Client.EmuHawk/ScreenSaver.cs b/BizHawk.Client.EmuHawk/ScreenSaver.cs index d09ea9b8a9..64a90807f2 100644 --- a/BizHawk.Client.EmuHawk/ScreenSaver.cs +++ b/BizHawk.Client.EmuHawk/ScreenSaver.cs @@ -41,7 +41,7 @@ namespace BizHawk.Client.EmuHawk //TODO implement } } - private static PlatformSpecificScreenBlankInterface screenBlankInterface = PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows + private static PlatformSpecificScreenBlankInterface screenBlankInterface = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows ? (PlatformSpecificScreenBlankInterface) new WinScreenBlankInterface() : (PlatformSpecificScreenBlankInterface) new MiscUnixScreenBlankInterface(); diff --git a/BizHawk.Client.EmuHawk/Sound/Sound.cs b/BizHawk.Client.EmuHawk/Sound/Sound.cs index cd6891bd9d..6461747c50 100644 --- a/BizHawk.Client.EmuHawk/Sound/Sound.cs +++ b/BizHawk.Client.EmuHawk/Sound/Sound.cs @@ -27,7 +27,7 @@ namespace BizHawk.Client.EmuHawk { if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL) _outputDevice = new OpenALSoundOutput(this); - if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) { if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound) _outputDevice = new DirectSoundSoundOutput(this, mainWindowHandle); diff --git a/BizHawk.Client.EmuHawk/Throttle.cs b/BizHawk.Client.EmuHawk/Throttle.cs index d703bce4ac..20aed07964 100644 --- a/BizHawk.Client.EmuHawk/Throttle.cs +++ b/BizHawk.Client.EmuHawk/Throttle.cs @@ -160,7 +160,7 @@ namespace BizHawk.Client.EmuHawk return timeBeginPeriod(ms); } } - static PlatformSpecificSysTimer sysTimer = PlatformLinkedLibSingleton.CurrentOS != PlatformLinkedLibSingleton.DistinctOS.Windows ? (PlatformSpecificSysTimer) new UnixMonoSysTimer() : (PlatformSpecificSysTimer) new WinSysTimer(); + static PlatformSpecificSysTimer sysTimer = OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows ? (PlatformSpecificSysTimer) new UnixMonoSysTimer() : (PlatformSpecificSysTimer) new WinSysTimer(); static uint TimeBeginPeriod(uint ms) { return sysTimer.TimeBeginPeriod(ms); diff --git a/BizHawk.Client.EmuHawk/config/InputWidget.cs b/BizHawk.Client.EmuHawk/config/InputWidget.cs index b6ffe91457..7026051674 100644 --- a/BizHawk.Client.EmuHawk/config/InputWidget.cs +++ b/BizHawk.Client.EmuHawk/config/InputWidget.cs @@ -71,7 +71,7 @@ namespace BizHawk.Client.EmuHawk protected override void OnMouseClick(MouseEventArgs e) { - if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) HideCaret(Handle); + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) HideCaret(Handle); base.OnMouseClick(e); } @@ -264,7 +264,7 @@ namespace BizHawk.Client.EmuHawk protected override void OnGotFocus(EventArgs e) { - if (PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows) HideCaret(Handle); + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) HideCaret(Handle); } protected override bool ProcessCmdKey(ref Message msg, Keys keyData) diff --git a/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs b/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs index 92f954e0c2..01e632f799 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs @@ -186,7 +186,7 @@ namespace BizHawk.Client.EmuHawk } var currentScripts = LuaImp?.ScriptList; // Temp fix for now - LuaImp = PlatformLinkedLibSingleton.CurrentOS == PlatformLinkedLibSingleton.DistinctOS.Windows + LuaImp = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows ? (PlatformEmuLuaLibrary) new EmuLuaLibrary(Emulator.ServiceProvider) : (PlatformEmuLuaLibrary) new NotReallyLuaLibrary(); if (currentScripts != null) diff --git a/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/BizHawk.Client.EmuHawk/tools/ToolManager.cs index 5d381b2184..fee0f9b269 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -740,7 +740,7 @@ namespace BizHawk.Client.EmuHawk return false; } - if (t == typeof(LuaConsole) && PlatformLinkedLibSingleton.CurrentOS != PlatformLinkedLibSingleton.DistinctOS.Windows) return false; + if (t == typeof(LuaConsole) && OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows) return false; var tool = Assembly .GetExecutingAssembly() diff --git a/BizHawk.Common/BizHawk.Common.csproj b/BizHawk.Common/BizHawk.Common.csproj index 33f8d29023..57821a4430 100644 --- a/BizHawk.Common/BizHawk.Common.csproj +++ b/BizHawk.Common/BizHawk.Common.csproj @@ -85,7 +85,7 @@ - + diff --git a/BizHawk.Common/BizInvoke/DynamicLibraryImportResolver.cs b/BizHawk.Common/BizInvoke/DynamicLibraryImportResolver.cs index 9bc02c487b..e71a78fbef 100644 --- a/BizHawk.Common/BizInvoke/DynamicLibraryImportResolver.cs +++ b/BizHawk.Common/BizInvoke/DynamicLibraryImportResolver.cs @@ -8,12 +8,12 @@ namespace BizHawk.Common.BizInvoke public class DynamicLibraryImportResolver : IImportResolver, IDisposable { private IntPtr _p; - private readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager; + private readonly OSTailoredCode.ILinkedLibManager libLoader = OSTailoredCode.LinkedLibManager; public DynamicLibraryImportResolver(string dllName) { _p = libLoader.LoadPlatformSpecific(dllName); - if (_p == IntPtr.Zero) throw new InvalidOperationException($"null pointer returned by {nameof(PlatformLinkedLibSingleton.PlatformLinkedLibManager.LoadPlatformSpecific)}"); + if (_p == IntPtr.Zero) throw new InvalidOperationException($"null pointer returned by {nameof(libLoader.LoadPlatformSpecific)}"); } public IntPtr Resolve(string entryPoint) diff --git a/BizHawk.Common/PlatformLinkedLibSingleton.cs b/BizHawk.Common/OSTailoredCode.cs similarity index 82% rename from BizHawk.Common/PlatformLinkedLibSingleton.cs rename to BizHawk.Common/OSTailoredCode.cs index afc8b46054..fa7c882556 100644 --- a/BizHawk.Common/PlatformLinkedLibSingleton.cs +++ b/BizHawk.Common/OSTailoredCode.cs @@ -10,28 +10,28 @@ namespace EXE_PROJECT namespace BizHawk.Common #endif { - public sealed class PlatformLinkedLibSingleton + public sealed class OSTailoredCode { /// macOS doesn't use PlatformID.MacOSX public static readonly DistinctOS CurrentOS = Environment.OSVersion.Platform == PlatformID.Unix ? currentIsMacOS() ? DistinctOS.macOS : DistinctOS.Linux : DistinctOS.Windows; - private static readonly Lazy lazy = new Lazy(() => + private static readonly Lazy lazy = new Lazy(() => { switch (CurrentOS) { case DistinctOS.Linux: case DistinctOS.macOS: - return new UnixMonoLinkedLibManager(); + return new UnixMonoLLManager(); case DistinctOS.Windows: - return new Win32LinkedLibManager(); + return new WindowsLLManager(); default: throw new ArgumentOutOfRangeException(); } }); - public static PlatformLinkedLibManager LinkedLibManager => lazy.Value; + public static ILinkedLibManager LinkedLibManager => lazy.Value; private static bool currentIsMacOS() { @@ -49,19 +49,19 @@ namespace BizHawk.Common return proc.StandardOutput.ReadLine() == "Darwin"; } - private PlatformLinkedLibSingleton() {} + private OSTailoredCode() {} - public interface PlatformLinkedLibManager + public interface ILinkedLibManager { IntPtr LoadPlatformSpecific(string dllToLoad); IntPtr GetProcAddr(IntPtr hModule, string procName); int FreePlatformSpecific(IntPtr hModule); } - private class UnixMonoLinkedLibManager : PlatformLinkedLibManager + /// This class is copied from a tutorial, so don't git blame and then email me expecting insight. + private class UnixMonoLLManager : ILinkedLibManager { - // This class is copied from a tutorial, so don't git blame and then email me expecting insight. - const int RTLD_NOW = 2; + private const int RTLD_NOW = 2; [DllImport("libdl.so.2")] private static extern IntPtr dlopen(string fileName, int flags); [DllImport("libdl.so.2")] @@ -88,10 +88,10 @@ namespace BizHawk.Common } } - private class Win32LinkedLibManager : PlatformLinkedLibManager + private class WindowsLLManager : ILinkedLibManager { [DllImport("kernel32.dll")] - private static extern UInt32 GetLastError(); + private static extern uint 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")] @@ -121,9 +121,9 @@ namespace BizHawk.Common public enum DistinctOS : byte { - Linux = 0, - macOS = 1, - Windows = 2 + Linux, + macOS, + Windows } } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeApi/mupen64plusCoreApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeApi/mupen64plusCoreApi.cs index c499855ae5..3547d5459c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeApi/mupen64plusCoreApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeApi/mupen64plusCoreApi.cs @@ -27,7 +27,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi bool event_frameend = false; bool event_breakpoint = false; - private static readonly PlatformLinkedLibSingleton.PlatformLinkedLibManager libLoader = PlatformLinkedLibSingleton.LinkedLibManager; + private static readonly OSTailoredCode.ILinkedLibManager libLoader = OSTailoredCode.LinkedLibManager; public enum m64p_error { From e208edd573be1f125c049cbf63beaa5a95dc049d Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 15:42:32 +1000 Subject: [PATCH 09/16] Refactor ScreenSaver --- BizHawk.Client.EmuHawk/ScreenSaver.cs | 102 +++++++++++--------------- 1 file changed, 44 insertions(+), 58 deletions(-) diff --git a/BizHawk.Client.EmuHawk/ScreenSaver.cs b/BizHawk.Client.EmuHawk/ScreenSaver.cs index 64a90807f2..5b40fe8af3 100644 --- a/BizHawk.Client.EmuHawk/ScreenSaver.cs +++ b/BizHawk.Client.EmuHawk/ScreenSaver.cs @@ -1,80 +1,66 @@ -using System; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; -using BizHawk.Client.Common; using BizHawk.Common; namespace BizHawk.Client.EmuHawk { - // Derived from http://www.codeproject.com/KB/cs/ScreenSaverControl.aspx + /// Derived from http://www.codeproject.com/KB/cs/ScreenSaverControl.aspx public static class ScreenSaver { - private interface PlatformSpecificScreenBlankInterface + private interface IScreenBlankTimer { - Int32 Get(); - void Set(Int32 v); + /// + /// The screen saver timeout setting, in seconds + /// + int Duration { get; set; } } - private class WinScreenBlankInterface : PlatformSpecificScreenBlankInterface + + private class Win32ScreenBlankTimer : IScreenBlankTimer { [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern bool SystemParametersInfo(int uAction, int uParam, ref int lpvParam, int flags); - public Int32 Get() - { - Int32 value = 0; - SystemParametersInfo(SPI_GETSCREENSAVERTIMEOUT, 0, ref value, 0); - return value; - } - public void Set(Int32 v) - { - int nullVar = 0; - SystemParametersInfo(SPI_SETSCREENSAVERTIMEOUT, v, ref nullVar, SPIF_SENDWININICHANGE); - } - } - private class MiscUnixScreenBlankInterface : PlatformSpecificScreenBlankInterface - { - public Int32 Get() - { - return 0; //TODO implement - } - public void Set(Int32 v) - { - //TODO implement - } - } - private static PlatformSpecificScreenBlankInterface screenBlankInterface = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows - ? (PlatformSpecificScreenBlankInterface) new WinScreenBlankInterface() - : (PlatformSpecificScreenBlankInterface) new MiscUnixScreenBlankInterface(); - private const int SPI_GETSCREENSAVERTIMEOUT = 14; - private const int SPI_SETSCREENSAVERTIMEOUT = 15; - private const int SPIF_SENDWININICHANGE = 2; + private const int SPI_GETSCREENSAVERTIMEOUT = 14; + private const int SPI_SETSCREENSAVERTIMEOUT = 15; + private const int SPIF_SENDWININICHANGE = 2; + + public int Duration + { + get + { + var value = 0; + SystemParametersInfo(SPI_GETSCREENSAVERTIMEOUT, 0, ref value, 0); + return value; + } + set + { + var nullVar = 0; + SystemParametersInfo(SPI_SETSCREENSAVERTIMEOUT, value, ref nullVar, SPIF_SENDWININICHANGE); + } + } + } + + private class UnixScreenBlankTimer : IScreenBlankTimer + { + public int Duration { get; set; } = 0; //TODO implementation + } + + private static readonly IScreenBlankTimer _screenBlankTimer = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows + ? (IScreenBlankTimer) new Win32ScreenBlankTimer() + : new UnixScreenBlankTimer(); + + private static int ctr; public static void ResetTimerImmediate() { - SetScreenSaverTimeout(GetScreenSaverTimeout()); + _screenBlankTimer.Duration = _screenBlankTimer.Duration; } - private static int ctr; public static void ResetTimerPeriodically() { - ctr++; - if (ctr == 120) - { - SetScreenSaverTimeout(GetScreenSaverTimeout()); - ctr = 0; - } - } - - // Returns the screen saver timeout setting, in seconds - private static Int32 GetScreenSaverTimeout() - { - return screenBlankInterface.Get(); - } - - // Pass in the number of seconds to set the screen saver timeout value. - private static void SetScreenSaverTimeout(Int32 Value) - { - screenBlankInterface.Set(Value); + if (++ctr < 120) return; + ctr = 0; + ResetTimerImmediate(); } } -} +} \ No newline at end of file From cefba8e16e1f24caa6f4133999c1f2ce35755945 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 15:45:49 +1000 Subject: [PATCH 10/16] Refactor CurrentOS usage in Throttle --- BizHawk.Client.EmuHawk/Throttle.cs | 39 ++++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Throttle.cs b/BizHawk.Client.EmuHawk/Throttle.cs index 20aed07964..d25af833ca 100644 --- a/BizHawk.Client.EmuHawk/Throttle.cs +++ b/BizHawk.Client.EmuHawk/Throttle.cs @@ -153,14 +153,16 @@ namespace BizHawk.Client.EmuHawk } private class UnixMonoSysTimer : PlatformSpecificSysTimer { - [DllImport("winmm.dll.so", EntryPoint = "timeBeginPeriod")] - private static extern uint timeBeginPeriod(uint uMilliseconds); public uint TimeBeginPeriod(uint ms) { - return timeBeginPeriod(ms); + // we are not going to bother trying to set a minimum resolution for periodic timers + // (on linux I don't think you can set this in user code) + return ms; } } - static PlatformSpecificSysTimer sysTimer = OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows ? (PlatformSpecificSysTimer) new UnixMonoSysTimer() : (PlatformSpecificSysTimer) new WinSysTimer(); + static PlatformSpecificSysTimer sysTimer = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows + ? (PlatformSpecificSysTimer) new WinSysTimer() + : new UnixMonoSysTimer(); static uint TimeBeginPeriod(uint ms) { return sysTimer.TimeBeginPeriod(ms); @@ -362,18 +364,23 @@ namespace BizHawk.Client.EmuHawk int sleepTime = (int)((timePerFrame - elapsedTime) * 1000 / afsfreq); if (sleepTime >= 2 || paused) { -#if WINDOWS - // Assuming a timer period of 1 ms (i.e. TimeBeginPeriod(1)): The actual sleep time - // on Windows XP is generally within a half millisecond either way of the requested - // time. The actual sleep time on Windows 8 is generally between the requested time - // and up to a millisecond over. So we'll subtract 1 ms from the time to avoid - // sleeping longer than desired. - sleepTime -= 1; -#else - // The actual sleep time on OS X with Mono is generally between the request time - // and up to 25% over. So we'll scale the sleep time back to account for that. - sleepTime = sleepTime * 4 / 5; -#endif + switch (OSTailoredCode.CurrentOS) + { + case OSTailoredCode.DistinctOS.Linux: //TODO repro + case OSTailoredCode.DistinctOS.macOS: + // The actual sleep time on OS X with Mono is generally between the request time + // and up to 25% over. So we'll scale the sleep time back to account for that. + sleepTime = sleepTime * 4 / 5; + break; + case OSTailoredCode.DistinctOS.Windows: + // Assuming a timer period of 1 ms (i.e. TimeBeginPeriod(1)): The actual sleep time + // on Windows XP is generally within a half millisecond either way of the requested + // time. The actual sleep time on Windows 8 is generally between the requested time + // and up to a millisecond over. So we'll subtract 1 ms from the time to avoid + // sleeping longer than desired. + sleepTime -= 1; + break; + } Thread.Sleep(Math.Max(sleepTime, 1)); } From 18874202445c7549b3f122fbf120b3ebd1a4f026 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 15:51:37 +1000 Subject: [PATCH 11/16] Refactor CurrentOS usage in Sound --- BizHawk.Client.EmuHawk/Sound/Sound.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Sound/Sound.cs b/BizHawk.Client.EmuHawk/Sound/Sound.cs index 6461747c50..85aaa2502d 100644 --- a/BizHawk.Client.EmuHawk/Sound/Sound.cs +++ b/BizHawk.Client.EmuHawk/Sound/Sound.cs @@ -25,15 +25,17 @@ namespace BizHawk.Client.EmuHawk public Sound(IntPtr mainWindowHandle) { - if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL) - _outputDevice = new OpenALSoundOutput(this); if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) { + if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL) + _outputDevice = new OpenALSoundOutput(this); if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound) _outputDevice = new DirectSoundSoundOutput(this, mainWindowHandle); if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.XAudio2) _outputDevice = new XAudio2SoundOutput(this); } + else _outputDevice = new OpenALSoundOutput(this); // at the moment unix/mono can only support OpenAL (so ignore whatever is set in the config) + if (_outputDevice == null) _outputDevice = new DummySoundOutput(this); } From 35056ae2d9e0504be87cf500e63f013153d23219 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 20:17:02 +1000 Subject: [PATCH 12/16] Remove #if WINDOWS, using runtime check where applicable --- BizHawk.Client.Common/config/Config.cs | 9 ++- BizHawk.Client.Common/lua/LuaSandbox.cs | 60 ++++++++++--------- BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs | 10 ++-- BizHawk.Client.EmuHawk/MainForm.cs | 23 +++---- BizHawk.Client.EmuHawk/PresentationPanel.cs | 3 - BizHawk.Client.EmuHawk/Program.cs | 7 +-- .../Sound/Output/DirectSoundSoundOutput.cs | 4 +- .../Sound/Output/XAudio2SoundOutput.cs | 4 +- BizHawk.Client.EmuHawk/config/SoundConfig.cs | 23 ++++--- BizHawk.Common/TempFileManager.cs | 12 ++-- 10 files changed, 75 insertions(+), 80 deletions(-) diff --git a/BizHawk.Client.Common/config/Config.cs b/BizHawk.Client.Common/config/Config.cs index 2ff5988861..37221da1d1 100644 --- a/BizHawk.Client.Common/config/Config.cs +++ b/BizHawk.Client.Common/config/Config.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Drawing; +using BizHawk.Common; using BizHawk.Emulation.Common; // ReSharper disable FieldCanBeMadeReadOnly.Global @@ -370,11 +371,9 @@ namespace BizHawk.Client.Common public int DispCropBottom = 0; // Sound options -#if WINDOWS - public ESoundOutputMethod SoundOutputMethod = ESoundOutputMethod.DirectSound; -#else - public ESoundOutputMethod SoundOutputMethod = ESoundOutputMethod.OpenAL; -#endif + public ESoundOutputMethod SoundOutputMethod = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows + ? ESoundOutputMethod.DirectSound + : ESoundOutputMethod.OpenAL; // force OpenAL for Unix when config is generated public bool SoundEnabled = true; public bool SoundEnabledNormal = true; public bool SoundEnabledRWFF = true; diff --git a/BizHawk.Client.Common/lua/LuaSandbox.cs b/BizHawk.Client.Common/lua/LuaSandbox.cs index 920984300d..ab1ebdd9e3 100644 --- a/BizHawk.Client.Common/lua/LuaSandbox.cs +++ b/BizHawk.Client.Common/lua/LuaSandbox.cs @@ -1,5 +1,8 @@ using System; using System.Runtime.InteropServices; + +using BizHawk.Common; + using NLua; // TODO - evaluate for re-entrancy problems @@ -18,12 +21,10 @@ namespace BizHawk.Client.Common private string _currentDirectory; - #if WINDOWS [DllImport("kernel32.dll", SetLastError = true)] static extern bool SetCurrentDirectoryW(byte* lpPathName); [DllImport("kernel32.dll", SetLastError=true)] static extern uint GetCurrentDirectoryW(uint nBufferLength, byte* pBuffer); - #endif private bool CoolSetCurrentDirectory(string path, string currDirSpeedHack = null) { @@ -42,40 +43,43 @@ namespace BizHawk.Client.Common return true; } - // WARNING: setting the current directory is SLOW!!! security checks for some reason. - // so we're bypassing it with windows hacks - #if WINDOWS + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) + { + // WARNING: setting the current directory is SLOW!!! security checks for some reason. + // so we're bypassing it with windows hacks fixed (byte* pstr = &System.Text.Encoding.Unicode.GetBytes($"{target}\0")[0]) return SetCurrentDirectoryW(pstr); - #else - if (System.IO.Directory.Exists(CurrentDirectory)) // race condition for great justice - { - Environment.CurrentDirectory = CurrentDirectory; // thats right, you can't set a directory as current that doesnt exist because .net's got to do SENSELESS SLOW-ASS SECURITY CHECKS on it and it can't do that on a NONEXISTENT DIRECTORY - return true; - } - else - { - return false; - } - #endif + } + else + { + if (System.IO.Directory.Exists(_currentDirectory)) // race condition for great justice + { + Environment.CurrentDirectory = _currentDirectory; // thats right, you can't set a directory as current that doesnt exist because .net's got to do SENSELESS SLOW-ASS SECURITY CHECKS on it and it can't do that on a NONEXISTENT DIRECTORY + return true; + } + else + { + return false; + } + } } private string CoolGetCurrentDirectory() { - // GUESS WHAT! - // .NET DOES A SECURITY CHECK ON THE DIRECTORY WE JUST RETRIEVED - // AS IF ASKING FOR THE CURRENT DIRECTORY IS EQUIVALENT TO TRYING TO ACCESS IT - // SCREW YOU - #if WINDOWS + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) + { + // GUESS WHAT! + // .NET DOES A SECURITY CHECK ON THE DIRECTORY WE JUST RETRIEVED + // AS IF ASKING FOR THE CURRENT DIRECTORY IS EQUIVALENT TO TRYING TO ACCESS IT + // SCREW YOU var buf = new byte[32768]; - fixed(byte* pBuf = &buf[0]) - { - uint ret = GetCurrentDirectoryW(32767, pBuf); - return System.Text.Encoding.Unicode.GetString(buf, 0, (int)ret*2); - } - #else + fixed (byte* pBuf = &buf[0]) + return System.Text.Encoding.Unicode.GetString(buf, 0, 2 * (int) GetCurrentDirectoryW(32767, pBuf)); + } + else + { return Environment.CurrentDirectory; - #endif + } } private void Sandbox(Action callback, Action exceptionCallback) diff --git a/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs b/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs index 6f71c4b682..ccb9f64379 100644 --- a/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Windows.Forms; using BizHawk.Client.Common; +using BizHawk.Common; using BizHawk.Emulation.Common; namespace BizHawk.Client.EmuHawk @@ -85,12 +86,9 @@ namespace BizHawk.Client.EmuHawk try { _ffmpeg = new Process(); -#if WINDOWS - _ffmpeg.StartInfo.FileName = Path.Combine(PathManager.GetDllDirectory(), "ffmpeg.exe"); -#else - ffmpeg.StartInfo.FileName = "ffmpeg"; // expecting native version to be in path -#endif - + _ffmpeg.StartInfo.FileName = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows + ? Path.Combine(PathManager.GetDllDirectory(), "ffmpeg.exe") + : "ffmpeg"; _ffmpeg.StartInfo.Arguments = $"-y -f nut -i - {_token.Commandline} \"{_baseName}{(_segment == 0 ? string.Empty : $"_{_segment}")}{_ext}\""; _ffmpeg.StartInfo.CreateNoWindow = true; diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 10120587b1..283cb22aa5 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -1052,7 +1052,7 @@ namespace BizHawk.Client.EmuHawk if (!_inFullscreen) { SuspendLayout(); -#if WINDOWS + // Work around an AMD driver bug in >= vista: // It seems windows will activate opengl fullscreen mode when a GL control is occupying the exact space of a screen (0,0 and dimensions=screensize) // AMD cards manifest a problem under these circumstances, flickering other monitors. @@ -1060,7 +1060,9 @@ namespace BizHawk.Client.EmuHawk // (this could be determined with more work; other side affects of the fullscreen mode include: corrupted taskbar, no modal boxes on top of GL control, no screenshots) // At any rate, we can solve this by adding a 1px black border around the GL control // Please note: It is important to do this before resizing things, otherwise momentarily a GL control without WS_BORDER will be at the magic dimensions and cause the flakeout - if (Global.Config.DispFullscreenHacks && Global.Config.DispMethod == Config.EDispMethod.OpenGL) + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows + && Global.Config.DispFullscreenHacks + && Global.Config.DispMethod == Config.EDispMethod.OpenGL) { //ATTENTION: this causes the statusbar to not work well, since the backcolor is now set to black instead of SystemColors.Control. //It seems that some statusbar elements composite with the backcolor. @@ -1071,7 +1073,6 @@ namespace BizHawk.Client.EmuHawk // FUTURE WORK: // re-add this padding back into the display manager (so the image will get cut off a little but, but a few more resolutions will fully fit into the screen) } -#endif _windowedLocation = Location; @@ -1088,13 +1089,15 @@ namespace BizHawk.Client.EmuHawk WindowState = FormWindowState.Normal; -#if WINDOWS - // do this even if DispFullscreenHacks arent enabled, to restore it in case it changed underneath us or something - Padding = new Padding(0); - // it's important that we set the form color back to this, because the statusbar icons blend onto the mainform, not onto the statusbar-- - // so we need the statusbar and mainform backdrop color to match - BackColor = SystemColors.Control; -#endif + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) + { + // do this even if DispFullscreenHacks arent enabled, to restore it in case it changed underneath us or something + Padding = new Padding(0); + + // it's important that we set the form color back to this, because the statusbar icons blend onto the mainform, not onto the statusbar-- + // so we need the statusbar and mainform backdrop color to match + BackColor = SystemColors.Control; + } _inFullscreen = false; diff --git a/BizHawk.Client.EmuHawk/PresentationPanel.cs b/BizHawk.Client.EmuHawk/PresentationPanel.cs index a20b656ac8..b647f2ce01 100644 --- a/BizHawk.Client.EmuHawk/PresentationPanel.cs +++ b/BizHawk.Client.EmuHawk/PresentationPanel.cs @@ -6,9 +6,6 @@ using sysdrawing2d=System.Drawing.Drawing2D; using System.IO; using System.Threading; using System.Windows.Forms; -#if WINDOWS -using SlimDX; -#endif using BizHawk.Client.Common; using BizHawk.Bizware.BizwareGL; diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index c46f0c961c..96e98ff548 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -5,9 +5,8 @@ using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; -#if WINDOWS + using Microsoft.VisualBasic.ApplicationServices; -#endif using BizHawk.Common; using BizHawk.Client.Common; @@ -265,7 +264,6 @@ REDO_DISPMETHOD: return GlobalWin.ExitCode; } //SubMain -#if WINDOWS //declared here instead of a more usual place to avoid dependencies on the more usual place [DllImport("kernel32.dll", SetLastError = true)] @@ -292,7 +290,6 @@ REDO_DISPMETHOD: RemoveMOTW(fi.FullName); } } -#endif private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { @@ -336,7 +333,6 @@ REDO_DISPMETHOD: } } -#if WINDOWS private class SingleInstanceController : WindowsFormsApplicationBase { private readonly string[] cmdArgs; @@ -365,6 +361,5 @@ REDO_DISPMETHOD: GlobalWin.ExitCode = ((MainForm)MainForm).ProgramRunLoop(); } } -#endif } } diff --git a/BizHawk.Client.EmuHawk/Sound/Output/DirectSoundSoundOutput.cs b/BizHawk.Client.EmuHawk/Sound/Output/DirectSoundSoundOutput.cs index df362aa7aa..21ca8bd90f 100644 --- a/BizHawk.Client.EmuHawk/Sound/Output/DirectSoundSoundOutput.cs +++ b/BizHawk.Client.EmuHawk/Sound/Output/DirectSoundSoundOutput.cs @@ -1,5 +1,4 @@ -#if WINDOWS -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -164,4 +163,3 @@ namespace BizHawk.Client.EmuHawk } } } -#endif diff --git a/BizHawk.Client.EmuHawk/Sound/Output/XAudio2SoundOutput.cs b/BizHawk.Client.EmuHawk/Sound/Output/XAudio2SoundOutput.cs index 913fb91c94..e5bf4f8dc0 100644 --- a/BizHawk.Client.EmuHawk/Sound/Output/XAudio2SoundOutput.cs +++ b/BizHawk.Client.EmuHawk/Sound/Output/XAudio2SoundOutput.cs @@ -1,5 +1,4 @@ -#if WINDOWS -using System; +using System; using System.Collections.Generic; using System.Linq; @@ -185,4 +184,3 @@ namespace BizHawk.Client.EmuHawk } } } -#endif diff --git a/BizHawk.Client.EmuHawk/config/SoundConfig.cs b/BizHawk.Client.EmuHawk/config/SoundConfig.cs index 782ae648aa..97faed7762 100644 --- a/BizHawk.Client.EmuHawk/config/SoundConfig.cs +++ b/BizHawk.Client.EmuHawk/config/SoundConfig.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Windows.Forms; using BizHawk.Client.Common; +using BizHawk.Common; namespace BizHawk.Client.EmuHawk { @@ -24,10 +25,14 @@ namespace BizHawk.Client.EmuHawk cbEnableNormal.Checked = Global.Config.SoundEnabledNormal; cbEnableRWFF.Checked = Global.Config.SoundEnabledRWFF; cbMuteFrameAdvance.Checked = Global.Config.MuteFrameAdvance; -#if !WINDOWS - rbOutputMethodDirectSound.Enabled = false; - rbOutputMethodXAudio2.Enabled = false; -#endif + + if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows) + { + // Disable DirectSound and XAudio2 on Mono + rbOutputMethodDirectSound.Enabled = false; + rbOutputMethodXAudio2.Enabled = false; + } + rbOutputMethodDirectSound.Checked = Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound; rbOutputMethodXAudio2.Checked = Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.XAudio2; rbOutputMethodOpenAL.Checked = Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL; @@ -83,11 +88,13 @@ namespace BizHawk.Client.EmuHawk private void PopulateDeviceList() { IEnumerable deviceNames = Enumerable.Empty(); -#if WINDOWS - if (rbOutputMethodDirectSound.Checked) deviceNames = DirectSoundSoundOutput.GetDeviceNames(); - if (rbOutputMethodXAudio2.Checked) deviceNames = XAudio2SoundOutput.GetDeviceNames(); -#endif + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) + { + if (rbOutputMethodDirectSound.Checked) deviceNames = DirectSoundSoundOutput.GetDeviceNames(); + if (rbOutputMethodXAudio2.Checked) deviceNames = XAudio2SoundOutput.GetDeviceNames(); + } if (rbOutputMethodOpenAL.Checked) deviceNames = OpenALSoundOutput.GetDeviceNames(); + listBoxSoundDevices.Items.Clear(); listBoxSoundDevices.Items.Add(""); listBoxSoundDevices.SelectedIndex = 0; diff --git a/BizHawk.Common/TempFileManager.cs b/BizHawk.Common/TempFileManager.cs index d21da556bd..88d5b628cc 100644 --- a/BizHawk.Common/TempFileManager.cs +++ b/BizHawk.Common/TempFileManager.cs @@ -59,10 +59,8 @@ namespace BizHawk.Common } } - #if WINDOWS [DllImport("kernel32.dll", EntryPoint = "DeleteFileW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] static extern bool DeleteFileW([MarshalAs(UnmanagedType.LPWStr)]string lpFileName); - #endif static void ThreadProc() { @@ -94,12 +92,10 @@ namespace BizHawk.Common { try { - // SHUT. UP. THE. EXCEPTIONS. - #if WINDOWS - DeleteFileW(fi.FullName); - #else - fi.Delete(); - #endif + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) + DeleteFileW(fi.FullName); // SHUT. UP. THE. EXCEPTIONS. + else + fi.Delete(); } catch { From df232e6184430988b766a56674e802844e395233 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sat, 18 May 2019 20:25:33 +1000 Subject: [PATCH 13/16] Add additional CurrentOS checks --- BizHawk.Client.Common/config/Config.cs | 9 ++++++-- BizHawk.Client.EmuHawk/MainForm.Events.cs | 10 ++++++++- BizHawk.Client.EmuHawk/MainForm.cs | 21 +++++++++++++++++-- BizHawk.Client.EmuHawk/Program.cs | 11 ++++++++-- .../config/DisplayConfigLite.cs | 11 ++++++++++ .../config/FirmwaresConfig.cs | 2 ++ BizHawk.Client.EmuHawk/tools/CDL.cs | 12 ++++++++++- BizHawk.Client.EmuHawk/tools/ToolBox.cs | 3 +++ BizHawk.Common/BizInvoke/MemoryBlock.cs | 3 +++ 9 files changed, 74 insertions(+), 8 deletions(-) diff --git a/BizHawk.Client.Common/config/Config.cs b/BizHawk.Client.Common/config/Config.cs index 37221da1d1..c0bf196702 100644 --- a/BizHawk.Client.Common/config/Config.cs +++ b/BizHawk.Client.Common/config/Config.cs @@ -342,8 +342,13 @@ namespace BizHawk.Client.Common public int DispPrescale = 1; - // warning: we dont even want to deal with changing this at runtime. but we want it changed here for config purposes. so dont check this variable. check in GlobalWin or something like that. - public EDispMethod DispMethod = EDispMethod.SlimDX9; + /// + /// warning: we dont even want to deal with changing this at runtime. but we want it changed here for config purposes. so dont check this variable. check in GlobalWin or something like that. + /// force DX for Windows and GDI+ for Unix when a new config is generated + /// + public EDispMethod DispMethod = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows + ? EDispMethod.SlimDX9 + : EDispMethod.GdiPlus; public int DispChrome_FrameWindowed = 2; public bool DispChrome_StatusBarWindowed = true; diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index 65878e36e2..4ece99a72f 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -25,6 +25,7 @@ using BizHawk.Client.EmuHawk.WinFormExtensions; using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Emulation.Cores.Computers.AppleII; using BizHawk.Client.ApiHawk; +using BizHawk.Common; using BizHawk.Emulation.Cores.Computers.Commodore64; using BizHawk.Emulation.Cores.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Computers.SinclairSpectrum; @@ -1469,7 +1470,14 @@ namespace BizHawk.Client.EmuHawk private void RamSearchMenuItem_Click(object sender, EventArgs e) { - GlobalWin.Tools.Load(); + var ramSearch = GlobalWin.Tools.Load(); + if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows) + { + // this is apparently needed for weird mono-forms-on-different-thread issues + // dont do .Show() within Load() for RamSearch - instead put an instance of it here on MainForm, then show here + // the mono winforms implementation is.... weird and buggy + ramSearch.Show(); + } } private void LuaConsoleMenuItem_Click(object sender, EventArgs e) diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 283cb22aa5..4623b15806 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -161,7 +161,9 @@ namespace BizHawk.Client.EmuHawk Database.LoadDatabase(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb.txt")); // TODO GL - a lot of disorganized wiring-up here - CGC.CGCBinPath = Path.Combine(PathManager.GetDllDirectory(), "cgc.exe"); + CGC.CGCBinPath = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows + ? Path.Combine(PathManager.GetDllDirectory(), "cgc.exe") + : "cgc"; // installed separately (via package manager or from https://developer.nvidia.com/cg-toolkit-download), look in $PATH PresentationPanel = new PresentationPanel(); PresentationPanel.GraphicsControl.MainWindow = true; GlobalWin.DisplayManager = new DisplayManager(PresentationPanel); @@ -2069,7 +2071,22 @@ namespace BizHawk.Client.EmuHawk // sends an alt+mnemonic combination private void SendAltKeyChar(char c) { - typeof(ToolStrip).InvokeMember("ProcessMnemonicInternal", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance, null, MainformMenu, new object[] { c }); + switch (OSTailoredCode.CurrentOS) + { + case OSTailoredCode.DistinctOS.Linux: + case OSTailoredCode.DistinctOS.macOS: + // no mnemonics for you + break; + case OSTailoredCode.DistinctOS.Windows: + //HACK + var _ = typeof(ToolStrip).InvokeMember( + "ProcessMnemonicInternal", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance, + null, + MainformMenu, + new object[] { c }); + break; + } } public static string FormatFilter(params string[] args) diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 96e98ff548..2b0f14d079 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -80,7 +80,13 @@ namespace BizHawk.Client.EmuHawk [STAThread] private static int Main(string[] args) { - return SubMain(args); + var exitCode = SubMain(args); + if (EXE_PROJECT.OSTailoredCode.CurrentOS == EXE_PROJECT.OSTailoredCode.DistinctOS.Linux) + { + Console.WriteLine("BizHawk has completed its shutdown routines, killing process..."); + Process.GetCurrentProcess().Kill(); + } + return exitCode; } //NoInlining should keep this code from getting jammed into Main() which would create dependencies on types which havent been setup by the resolver yet... or something like that @@ -309,7 +315,8 @@ REDO_DISPMETHOD: //so.. we're going to resort to something really bad. //avert your eyes. var configPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.ini"); - if (File.Exists(configPath) + if (EXE_PROJECT.OSTailoredCode.CurrentOS == EXE_PROJECT.OSTailoredCode.DistinctOS.Windows // LuaInterface is not currently working on Mono + && File.Exists(configPath) && (Array.Find(File.ReadAllLines(configPath), line => line.Contains(" \"UseNLua\": ")) ?? string.Empty) .Contains("false")) { diff --git a/BizHawk.Client.EmuHawk/config/DisplayConfigLite.cs b/BizHawk.Client.EmuHawk/config/DisplayConfigLite.cs index a094247ef3..cb4f4f7515 100644 --- a/BizHawk.Client.EmuHawk/config/DisplayConfigLite.cs +++ b/BizHawk.Client.EmuHawk/config/DisplayConfigLite.cs @@ -3,6 +3,7 @@ using System.IO; using System.Windows.Forms; using BizHawk.Emulation.Common; using BizHawk.Client.Common; +using BizHawk.Common; namespace BizHawk.Client.EmuHawk { @@ -91,6 +92,16 @@ namespace BizHawk.Client.EmuHawk txtCropBottom.Text = Global.Config.DispCropBottom.ToString(); RefreshAspectRatioOptions(); + + if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows) + { + // Disable SlimDX on Unix + rbD3D9.Enabled = false; + rbD3D9.AutoCheck = false; + cbAlternateVsync.Enabled = false; + label13.Enabled = false; + label8.Enabled = false; + } } private void btnOk_Click(object sender, EventArgs e) diff --git a/BizHawk.Client.EmuHawk/config/FirmwaresConfig.cs b/BizHawk.Client.EmuHawk/config/FirmwaresConfig.cs index 826df7d025..69a302c097 100644 --- a/BizHawk.Client.EmuHawk/config/FirmwaresConfig.cs +++ b/BizHawk.Client.EmuHawk/config/FirmwaresConfig.cs @@ -358,6 +358,8 @@ namespace BizHawk.Client.EmuHawk private void tbbOpenFolder_Click(object sender, EventArgs e) { var frmWares = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null); + if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows && !Directory.Exists(frmWares)) + Directory.CreateDirectory(frmWares); System.Diagnostics.Process.Start(frmWares); } diff --git a/BizHawk.Client.EmuHawk/tools/CDL.cs b/BizHawk.Client.EmuHawk/tools/CDL.cs index 0571d4e4ac..92fee7a5c5 100644 --- a/BizHawk.Client.EmuHawk/tools/CDL.cs +++ b/BizHawk.Client.EmuHawk/tools/CDL.cs @@ -7,6 +7,7 @@ using BizHawk.Emulation.Common; using BizHawk.Client.Common; using BizHawk.Client.EmuHawk.ToolExtensions; +using BizHawk.Common; //TODO - select which memorydomains go out to the CDL file. will this cause a problem when re-importing it? //perhaps missing domains shouldnt fail a check @@ -98,7 +99,16 @@ namespace BizHawk.Client.EmuHawk if (_cdl == null) { lvCDL.BeginUpdate(); - lvCDL.Items.Clear(); + if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) + { + lvCDL.Items.Clear(); + } + else + { + // this is a winforms implementation problem for mono + // see https://github.com/mono/mono/issues/11070 + // until this is resolved in mono we should just skip this call + } lvCDL.EndUpdate(); return; } diff --git a/BizHawk.Client.EmuHawk/tools/ToolBox.cs b/BizHawk.Client.EmuHawk/tools/ToolBox.cs index 67aefdfd0f..23c3a8df8c 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolBox.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolBox.cs @@ -7,6 +7,7 @@ using System.Windows.Forms; using BizHawk.Emulation.Common; using BizHawk.Client.ApiHawk; +using BizHawk.Common; namespace BizHawk.Client.EmuHawk { @@ -68,6 +69,8 @@ namespace BizHawk.Client.EmuHawk continue; // if (!ApiInjector.IsAvailable(, t)) // continue; + if (t == typeof(HexView) && OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows) + continue; // Skip this tool on Unix. It isn't finished and only causes exceptions var instance = Activator.CreateInstance(t); diff --git a/BizHawk.Common/BizInvoke/MemoryBlock.cs b/BizHawk.Common/BizInvoke/MemoryBlock.cs index ae3c867adf..7bbdf04f36 100644 --- a/BizHawk.Common/BizInvoke/MemoryBlock.cs +++ b/BizHawk.Common/BizInvoke/MemoryBlock.cs @@ -79,6 +79,9 @@ namespace BizHawk.Common.BizInvoke /// public MemoryBlock(ulong start, ulong size) { + if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows) + throw new InvalidOperationException("MemoryBlock ctor called on Unix"); + if (!WaterboxUtils.Aligned(start)) throw new ArgumentOutOfRangeException(); if (size == 0) From 2377e644e6fde55cffd02a7978f3f13f9cdb5a62 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sun, 19 May 2019 14:59:11 +1000 Subject: [PATCH 14/16] Add build scripts for Unix --- Dist/BuildDebug.sh | 2 ++ Dist/BuildRelease.sh | 2 ++ 2 files changed, 4 insertions(+) create mode 100755 Dist/BuildDebug.sh create mode 100755 Dist/BuildRelease.sh diff --git a/Dist/BuildDebug.sh b/Dist/BuildDebug.sh new file mode 100755 index 0000000000..388cc5536d --- /dev/null +++ b/Dist/BuildDebug.sh @@ -0,0 +1,2 @@ +#!/bin/sh +cd "$(dirname "$0")/.." && msbuild /p:Configuration=Debug BizHawk.sln diff --git a/Dist/BuildRelease.sh b/Dist/BuildRelease.sh new file mode 100755 index 0000000000..203546a22c --- /dev/null +++ b/Dist/BuildRelease.sh @@ -0,0 +1,2 @@ +#!/bin/sh +cd "$(dirname "$0")/.." && msbuild /p:Configuration=Release BizHawk.sln From ddbe3c7942fa5f265f81216ec31e9f75a2222e0f Mon Sep 17 00:00:00 2001 From: Asnivor Date: Mon, 20 May 2019 08:59:59 +0100 Subject: [PATCH 15/16] Remove Virtu.csproj references from solution (because they shouldnt be there - my bad) --- BizHawk.sln | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/BizHawk.sln b/BizHawk.sln index 5c6cd2044b..53559fc6dc 100644 --- a/BizHawk.sln +++ b/BizHawk.sln @@ -59,8 +59,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Client.MultiHawk", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Client.ApiHawk", "BizHawk.Client.ApiHawk\BizHawk.Client.ApiHawk.csproj", "{8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Virtu", "ExternalCoreProjects\Virtu\Virtu.csproj", "{8E522778-7A2C-4364-BDCE-0BA5623828E1}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -127,18 +125,6 @@ Global {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|Any CPU.Build.0 = Debug|Any CPU {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|Any CPU.ActiveCfg = Release|Any CPU {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|Any CPU.Build.0 = Release|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Debug|x64.ActiveCfg = Debug|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Debug|x64.Build.0 = Debug|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Debug|x86.ActiveCfg = Debug|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Debug|x86.Build.0 = Debug|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Release|Any CPU.Build.0 = Release|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Release|x64.ActiveCfg = Release|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Release|x64.Build.0 = Release|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Release|x86.ActiveCfg = Release|Any CPU - {8E522778-7A2C-4364-BDCE-0BA5623828E1}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From d11e35dc44bf4dec5249053bac968e14b0ca55a6 Mon Sep 17 00:00:00 2001 From: James Groom Date: Mon, 20 May 2019 23:32:46 +1000 Subject: [PATCH 16/16] Add CurrentOS check paired with the one in MainForm.Events.cs --- BizHawk.Client.EmuHawk/tools/ToolManager.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/BizHawk.Client.EmuHawk/tools/ToolManager.cs index fee0f9b269..27d1ed70e8 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -159,7 +159,15 @@ namespace BizHawk.Client.EmuHawk } newTool.Restart(); - newTool.Show(); + if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows + && newTool is RamSearch) + { + // the mono winforms implementation is buggy, skip to the return statement and call Show in MainForm instead + } + else + { + newTool.Show(); + } return (T)newTool; }