diff --git a/Client/Simitone/Simitone.Windows/GameStartProxy.cs b/Client/Simitone/Simitone.Windows/GameStartProxy.cs new file mode 100644 index 0000000..d7e88a4 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/GameStartProxy.cs @@ -0,0 +1,32 @@ +using FSO.Client; +using FSO.LotView; +using FSO.UI; +using Simitone.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Simitone.Windows +{ + public class GameStartProxy + { + public void Start(bool useDX) + { + GameFacade.DirectX = useDX; + World.DirectX = useDX; + SimitoneGame game = new SimitoneGame(); + var form = (Form)Form.FromHandle(game.Window.Handle); + if (form != null) form.FormClosing += Form_FormClosing; + game.Run(); + game.Dispose(); + } + + private static void Form_FormClosing(object sender, FormClosingEventArgs e) + { + e.Cancel = !(GameFacade.Screens.CurrentUIScreen?.CloseAttempt() ?? true); + } + } +} diff --git a/Client/Simitone/Simitone.Windows/Program.cs b/Client/Simitone/Simitone.Windows/Program.cs index cfde3a5..021aaaf 100644 --- a/Client/Simitone/Simitone.Windows/Program.cs +++ b/Client/Simitone/Simitone.Windows/Program.cs @@ -3,10 +3,13 @@ using FSO.Common; using FSO.LotView; using Simitone.Client; using Simitone.Windows.GameLocator; +using Simitone.Windows.Utils; using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; +using System.Linq; +using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; @@ -25,10 +28,22 @@ namespace Simitone.Windows [STAThread] static void Main(string[] args) { - var gameLocator = new WindowsLocator(); + AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; - var useDX = true; - var path = gameLocator.FindTheSimsOnline(); + OperatingSystem os = Environment.OSVersion; + PlatformID pid = os.Platform; + + ILocator gameLocator; + bool linux = pid == PlatformID.MacOSX || pid == PlatformID.Unix; + if (linux && Directory.Exists("/Users")) + gameLocator = new MacOSLocator(); + else if (linux) + gameLocator = new LinuxLocator(); + else + gameLocator = new WindowsLocator(); + + var useDX = !linux; + var path = gameLocator.FindTheSims1(); FSOEnvironment.Enable3D = false; bool ide = false; @@ -63,12 +78,26 @@ namespace Simitone.Windows case "jit": jit = true; break; + case "dx": + case "dx11": + useDX = true; + break; + case "gl": + case "ogl": + useDX = false; + break; + case "touch": + FSOEnvironment.SoftwareKeyboard = true; + break; + case "nosound": + FSOEnvironment.NoSound = true; + break; } } } } - #endregion + useDX = MonogameLinker.Link(useDX); FSO.Files.ImageLoaderHelpers.BitmapFunction = BitmapReader; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; @@ -90,16 +119,13 @@ namespace Simitone.Windows GlobalSettings.Default.StartupPath = path; GlobalSettings.Default.TS1HybridEnable = true; - GlobalSettings.Default.TS1HybridPath = gameLocator.FindTheSims1(); + GlobalSettings.Default.TS1HybridPath = path; GlobalSettings.Default.ClientVersion = "0"; GlobalSettings.Default.LightingMode = 3; GlobalSettings.Default.AntiAlias = aa ? 1 : 0; GlobalSettings.Default.ComplexShaders = true; GlobalSettings.Default.EnableTransitions = true; - GameFacade.DirectX = useDX; - World.DirectX = useDX; - if (ide) new FSO.IDE.VolcanicStartProxy().InitVolcanic(args); var assemblies = new FSO.SimAntics.JIT.Runtime.AssemblyStore(); @@ -107,11 +133,8 @@ namespace Simitone.Windows if (jit) assemblies.InitAOT(); FSO.SimAntics.Engine.VMTranslator.INSTANCE = new FSO.SimAntics.JIT.Runtime.VMAOTTranslator(assemblies); - SimitoneGame game = new SimitoneGame(); - var form = (Form)Form.FromHandle(game.Window.Handle); - if (form != null) form.FormClosing += Form_FormClosing; - game.Run(); - game.Dispose(); + var start = new GameStartProxy(); + start.Start(useDX); } } @@ -120,6 +143,28 @@ namespace Simitone.Windows e.Cancel = !(GameFacade.Screens.CurrentUIScreen?.CloseAttempt() ?? true); } + private static System.Reflection.Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) + { + try + { + var name = args.Name; + if (name.StartsWith("FSO.Scripts")) + { + return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.FullName == name); + } + else + { + var assemblyPath = Path.Combine(MonogameLinker.AssemblyDir, args.Name.Substring(0, name.IndexOf(',')) + ".dll"); + var assembly = Assembly.LoadFrom(assemblyPath); + return assembly; + } + } + catch (Exception e) + { + return null; + } + } + private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { var exception = e.ExceptionObject; diff --git a/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj b/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj index ec19c0b..b326122 100644 --- a/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj +++ b/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj @@ -43,8 +43,92 @@ + + + + Monogame\Linux\MonoGame.Framework.dll + PreserveNewest + + + Monogame\WindowsGL\MonoGame.Framework.dll + PreserveNewest + + + Monogame\Windows\MonoGame.Framework.dll + PreserveNewest + + + Monogame\Windows\SharpDX.D3DCompiler.dll + PreserveNewest + + + Monogame\Windows\SharpDX.D3DCompiler.xml + PreserveNewest + + + Monogame\Windows\SharpDX.Direct2D1.dll + PreserveNewest + + + Monogame\Windows\SharpDX.Direct2D1.xml + PreserveNewest + + + Monogame\Windows\SharpDX.Direct3D11.dll + PreserveNewest + + + Monogame\Windows\SharpDX.Direct3D11.xml + PreserveNewest + + + Monogame\Windows\SharpDX.dll + PreserveNewest + + + Monogame\Windows\SharpDX.DXGI.dll + PreserveNewest + + + Monogame\Windows\SharpDX.DXGI.xml + PreserveNewest + + + Monogame\Windows\SharpDX.MediaFoundation.dll + PreserveNewest + + + Monogame\Windows\SharpDX.MediaFoundation.xml + PreserveNewest + + + Monogame\Windows\SharpDX.XAudio2.dll + PreserveNewest + + + Monogame\Windows\SharpDX.XAudio2.xml + PreserveNewest + + + Monogame\Windows\SharpDX.XInput.dll + PreserveNewest + + + Monogame\Windows\SharpDX.XInput.xml + PreserveNewest + + + Monogame\Windows\SharpDX.xml + PreserveNewest + + + PreserveNewest + + + PreserveNewest + @@ -120,4 +204,4 @@ --> - + \ No newline at end of file diff --git a/Client/Simitone/Simitone.Windows/Utils/MonogameLinker.cs b/Client/Simitone/Simitone.Windows/Utils/MonogameLinker.cs new file mode 100644 index 0000000..8d7e2d5 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/Utils/MonogameLinker.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Simitone.Windows.Utils +{ + class MonogameLinker + { + //detects OS and copies the correct version of monogame into the parent directory. + //there is probably a better way to do this that doesn't mess with multiple clients + + public static string AssemblyDir = "./"; + + public static bool Link(bool preferDX11) + { + OperatingSystem os = Environment.OSVersion; + PlatformID pid = os.Platform; + + bool linux = false; + if (pid == PlatformID.MacOSX || pid == PlatformID.Unix) linux = true; + + if (linux && preferDX11) + { + Console.WriteLine("DirectX is usually only available on Windows. I hope you know what you're doing..."); + } + + try + { + string contentDir = "Content/OGL/"; + string monogameDir = "Monogame/WindowsGL/"; + if (!linux) + { + if (preferDX11) + { + contentDir = "Content/DX/"; + monogameDir = "Monogame/Windows/"; + } + } + //Check if MacOS by checkking user directory. Because PlatformID.MacOSX is not true on OS X. + else if (Directory.Exists("/Users")) + { + monogameDir = "Monogame/MacOS/"; + return false; + } + else + { + monogameDir = "Monogame/Linux/"; + return false; + } + + if (File.Exists("Monogame.Framework.dll")) File.Delete("Monogame.Framework.dll"); + + AssemblyDir = monogameDir; + } + catch (Exception e) + { + Console.WriteLine("Unable to link Monogame. Continuing... (" + e.ToString() + ")"); + } + + return preferDX11; + } + + private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs) + { + // Get the subdirectories for the specified directory. + DirectoryInfo dir = new DirectoryInfo(sourceDirName); + + if (!dir.Exists) + { + throw new DirectoryNotFoundException( + "Source directory does not exist or could not be found: " + + sourceDirName); + } + + DirectoryInfo[] dirs = dir.GetDirectories(); + // If the destination directory doesn't exist, create it. + if (!Directory.Exists(destDirName)) + { + Directory.CreateDirectory(destDirName); + } + + // Get the files in the directory and copy them to the new location. + FileInfo[] files = dir.GetFiles(); + foreach (FileInfo file in files) + { + string temppath = Path.Combine(destDirName, file.Name); + file.CopyTo(temppath, true); + } + + // If copying subdirectories, copy them and their contents to new location. + if (copySubDirs) + { + foreach (DirectoryInfo subdir in dirs) + { + string temppath = Path.Combine(destDirName, subdir.Name); + DirectoryCopy(subdir.FullName, temppath, copySubDirs); + } + } + } + } +} diff --git a/Client/Simitone/Simitone.Windows/sdl2.dll b/Client/Simitone/Simitone.Windows/sdl2.dll new file mode 100644 index 0000000..2b7e319 Binary files /dev/null and b/Client/Simitone/Simitone.Windows/sdl2.dll differ diff --git a/Client/Simitone/Simitone.Windows/soft_oal.dll b/Client/Simitone/Simitone.Windows/soft_oal.dll new file mode 100644 index 0000000..8c9e33c Binary files /dev/null and b/Client/Simitone/Simitone.Windows/soft_oal.dll differ