Merge pull request #1568 from TASVideos/unix_prep
Preparation for Unix port
This commit is contained in:
commit
27a4062ea2
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
// ReSharper disable FieldCanBeMadeReadOnly.Global
|
||||
|
@ -341,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;
|
||||
/// <remarks>
|
||||
/// 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
|
||||
/// </remarks>
|
||||
public EDispMethod DispMethod = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows
|
||||
? EDispMethod.SlimDX9
|
||||
: EDispMethod.GdiPlus;
|
||||
|
||||
public int DispChrome_FrameWindowed = 2;
|
||||
public bool DispChrome_StatusBarWindowed = true;
|
||||
|
@ -370,11 +376,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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -113,8 +113,8 @@
|
|||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\BizHawk.Common\PlatformLinkedLibSingleton.cs">
|
||||
<Link>PlatformLinkedLibSingleton.cs</Link>
|
||||
<Compile Include="..\BizHawk.Common\OSTailoredCode.cs">
|
||||
<Link>OSTailoredCode.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Version\svnrev.cs">
|
||||
<Link>svnrev.cs</Link>
|
||||
|
@ -2283,4 +2283,4 @@
|
|||
<PreBuildEvent />
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)Build\Common.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -123,24 +123,24 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (PlatformLinkedLibSingleton.RunningOnUnix)
|
||||
{
|
||||
OTK_Keyboard.Initialize();
|
||||
// OTK_Gamepad.Initialize();
|
||||
}
|
||||
else
|
||||
if (OSTailoredCode.CurrentOS == OSTailoredCode.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 (OSTailoredCode.CurrentOS == OSTailoredCode.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 = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows
|
||||
? KeyInput.Update().Concat(IPCKeyInput.Update())
|
||||
: OTK_Keyboard.Update();
|
||||
if (OSTailoredCode.CurrentOS == OSTailoredCode.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)
|
||||
|
|
|
@ -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<RamSearch>();
|
||||
var ramSearch = GlobalWin.Tools.Load<RamSearch>();
|
||||
if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows)
|
||||
{
|
||||
// this is apparently needed for weird mono-forms-on-different-thread issues
|
||||
// dont do .Show() within Load<T>() 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)
|
||||
|
|
|
@ -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);
|
||||
|
@ -1057,7 +1059,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.
|
||||
|
@ -1065,7 +1067,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.
|
||||
|
@ -1076,7 +1080,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;
|
||||
|
||||
|
@ -1093,13 +1096,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;
|
||||
|
||||
|
@ -2071,7 +2076,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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
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;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
static class Program
|
||||
internal static class Program
|
||||
{
|
||||
static Program()
|
||||
{
|
||||
|
@ -23,56 +21,52 @@ 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)
|
||||
if (EXE_PROJECT.OSTailoredCode.CurrentOS == EXE_PROJECT.OSTailoredCode.DistinctOS.Windows)
|
||||
{
|
||||
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();
|
||||
}
|
||||
var libLoader = EXE_PROJECT.OSTailoredCode.LinkedLibManager;
|
||||
|
||||
libLoader.FreePlatformSpecific(d3dx9);
|
||||
libLoader.FreePlatformSpecific(vc2015);
|
||||
libLoader.FreePlatformSpecific(vc2012);
|
||||
libLoader.FreePlatformSpecific(vc2010);
|
||||
libLoader.FreePlatformSpecific(vc2010p);
|
||||
//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 fail = vc2015 == IntPtr.Zero || vc2010 == IntPtr.Zero || vc2012 == IntPtr.Zero || vc2010p == IntPtr.Zero;
|
||||
var warn = d3dx9 == IntPtr.Zero;
|
||||
if (fail || warn)
|
||||
{
|
||||
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) 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)
|
||||
{
|
||||
// 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.
|
||||
|
@ -84,129 +78,20 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
[STAThread]
|
||||
static int Main(string[] args)
|
||||
private static int Main(string[] args)
|
||||
{
|
||||
return SubMain(args);
|
||||
}
|
||||
|
||||
private interface PlatformSpecificMainLoopCrashHandler
|
||||
{
|
||||
void TryCatchFinally(string[] args);
|
||||
}
|
||||
private class Win32MainLoopCrashHandler : PlatformSpecificMainLoopCrashHandler
|
||||
{
|
||||
public void TryCatchFinally(string[] args)
|
||||
var exitCode = SubMain(args);
|
||||
if (EXE_PROJECT.OSTailoredCode.CurrentOS == EXE_PROJECT.OSTailoredCode.DistinctOS.Linux)
|
||||
{
|
||||
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();
|
||||
}
|
||||
Console.WriteLine("BizHawk has completed its shutdown routines, killing process...");
|
||||
Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
return exitCode;
|
||||
}
|
||||
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)
|
||||
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?)
|
||||
|
@ -228,7 +113,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);
|
||||
|
||||
|
@ -248,13 +133,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
|
||||
|
@ -265,8 +146,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.OSTailoredCode.CurrentOS != EXE_PROJECT.OSTailoredCode.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)
|
||||
|
@ -277,8 +160,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;
|
||||
|
@ -290,8 +172,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;
|
||||
|
@ -306,26 +187,75 @@ 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;
|
||||
}
|
||||
|
||||
if (!EXE_PROJECT.PlatformLinkedLibSingleton.RunningOnUnix)
|
||||
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".
|
||||
//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);
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
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
|
||||
|
@ -341,19 +271,19 @@ namespace BizHawk.Client.EmuHawk
|
|||
} //SubMain
|
||||
|
||||
//declared here instead of a more usual place to avoid dependencies on the more usual place
|
||||
#if WINDOWS
|
||||
|
||||
[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<DirectoryInfo>(new[] { new DirectoryInfo(dllDir) });
|
||||
while (todo.Count > 0)
|
||||
|
@ -365,14 +295,11 @@ 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
|
||||
|
@ -380,52 +307,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 (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"))
|
||||
{
|
||||
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;
|
||||
|
@ -433,10 +351,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()
|
||||
|
@ -445,11 +365,8 @@ 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
/// <remarks>Derived from http://www.codeproject.com/KB/cs/ScreenSaverControl.aspx</remarks>
|
||||
public static class ScreenSaver
|
||||
{
|
||||
private interface PlatformSpecificScreenBlankInterface
|
||||
private interface IScreenBlankTimer
|
||||
{
|
||||
Int32 Get();
|
||||
void Set(Int32 v);
|
||||
/// <summary>
|
||||
/// The screen saver timeout setting, in seconds
|
||||
/// </summary>
|
||||
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 = PlatformLinkedLibSingleton.RunningOnUnix
|
||||
? (PlatformSpecificScreenBlankInterface) new MiscUnixScreenBlankInterface()
|
||||
: (PlatformSpecificScreenBlankInterface) new WinScreenBlankInterface();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -25,15 +25,17 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public Sound(IntPtr mainWindowHandle)
|
||||
{
|
||||
if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL)
|
||||
_outputDevice = new OpenALSoundOutput(this);
|
||||
if (!PlatformLinkedLibSingleton.RunningOnUnix)
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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 = PlatformLinkedLibSingleton.RunningOnUnix ? (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));
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
protected override void OnMouseClick(MouseEventArgs e)
|
||||
{
|
||||
if (!PlatformLinkedLibSingleton.RunningOnUnix) 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.RunningOnUnix) HideCaret(Handle);
|
||||
if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows) HideCaret(Handle);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
|
|
|
@ -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<string> deviceNames = Enumerable.Empty<string>();
|
||||
#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("<default>");
|
||||
listBoxSoundDevices.SelectedIndex = 0;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows
|
||||
? (PlatformEmuLuaLibrary) new EmuLuaLibrary(Emulator.ServiceProvider)
|
||||
: (PlatformEmuLuaLibrary) new NotReallyLuaLibrary();
|
||||
if (currentScripts != null)
|
||||
{
|
||||
LuaImp.ScriptList.AddRange(currentScripts);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -740,7 +748,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
return false;
|
||||
}
|
||||
|
||||
if (t == typeof(LuaConsole) && PlatformLinkedLibSingleton.RunningOnUnix) return false;
|
||||
if (t == typeof(LuaConsole) && OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows) return false;
|
||||
|
||||
var tool = Assembly
|
||||
.GetExecutingAssembly()
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
<Compile Include="MruStack.cs" />
|
||||
<Compile Include="MutableIntRange.cs" />
|
||||
<Compile Include="NDBDatabase.cs" />
|
||||
<Compile Include="PlatformLinkedLibSingleton.cs" />
|
||||
<Compile Include="OSTailoredCode.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="QuickCollections.cs" />
|
||||
<Compile Include="Serializer.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)
|
||||
|
|
|
@ -79,6 +79,9 @@ namespace BizHawk.Common.BizInvoke
|
|||
/// <param name="size"></param>
|
||||
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)
|
||||
|
|
|
@ -1,44 +1,73 @@
|
|||
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 OSTailoredCode
|
||||
{
|
||||
public static readonly bool RunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX;
|
||||
/// <remarks>macOS doesn't use PlatformID.MacOSX</remarks>
|
||||
public static readonly DistinctOS CurrentOS = Environment.OSVersion.Platform == PlatformID.Unix
|
||||
? currentIsMacOS() ? DistinctOS.macOS : DistinctOS.Linux
|
||||
: DistinctOS.Windows;
|
||||
|
||||
private static readonly Lazy<PlatformLinkedLibManager> lazy = new Lazy<PlatformLinkedLibManager>(() => RunningOnUnix
|
||||
? (PlatformLinkedLibManager) new UnixMonoLinkedLibManager()
|
||||
: (PlatformLinkedLibManager) new Win32LinkedLibManager());
|
||||
private static readonly Lazy<ILinkedLibManager> lazy = new Lazy<ILinkedLibManager>(() =>
|
||||
{
|
||||
switch (CurrentOS)
|
||||
{
|
||||
case DistinctOS.Linux:
|
||||
case DistinctOS.macOS:
|
||||
return new UnixMonoLLManager();
|
||||
case DistinctOS.Windows:
|
||||
return new WindowsLLManager();
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
});
|
||||
|
||||
public static PlatformLinkedLibManager LinkedLibManager { get { return lazy.Value; } }
|
||||
public static ILinkedLibManager LinkedLibManager => lazy.Value;
|
||||
|
||||
private PlatformLinkedLibSingleton() {}
|
||||
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";
|
||||
}
|
||||
|
||||
public interface PlatformLinkedLibManager
|
||||
private OSTailoredCode() {}
|
||||
|
||||
public interface ILinkedLibManager
|
||||
{
|
||||
IntPtr LoadPlatformSpecific(string dllToLoad);
|
||||
IntPtr GetProcAddr(IntPtr hModule, string procName);
|
||||
int FreePlatformSpecific(IntPtr hModule);
|
||||
}
|
||||
|
||||
public class UnixMonoLinkedLibManager : PlatformLinkedLibManager
|
||||
/// <remarks>This class is copied from a tutorial, so don't git blame and then email me expecting insight.</remarks>
|
||||
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);
|
||||
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,10 +88,10 @@ public sealed class PlatformLinkedLibSingleton
|
|||
}
|
||||
}
|
||||
|
||||
public 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")]
|
||||
|
@ -89,5 +118,12 @@ public sealed class PlatformLinkedLibSingleton
|
|||
return FreeLibrary(hModule) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public enum DistinctOS : byte
|
||||
{
|
||||
Linux,
|
||||
macOS,
|
||||
Windows
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
14
BizHawk.sln
14
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
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
cd "$(dirname "$0")/.." && msbuild /p:Configuration=Debug BizHawk.sln
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
cd "$(dirname "$0")/.." && msbuild /p:Configuration=Release BizHawk.sln
|
12
subwcrev.sh
12
subwcrev.sh
|
@ -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"
|
Loading…
Reference in New Issue