diff --git a/Core/Core.csproj b/Core/Core.csproj
index 58476b41..bacc600a 100644
--- a/Core/Core.csproj
+++ b/Core/Core.csproj
@@ -393,6 +393,7 @@
+
@@ -1117,11 +1118,6 @@
-
-
-
-
-
@@ -1295,7 +1291,9 @@
PreserveNewest
-
+
+
+
{a9b33bf4-9b03-4e3d-bf6a-181521046ee8}
diff --git a/Core/GameDirectoryFinder.cs b/Core/GameDirectoryFinder.cs
new file mode 100644
index 00000000..4fb29783
--- /dev/null
+++ b/Core/GameDirectoryFinder.cs
@@ -0,0 +1,111 @@
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace OpenVIII.Core {
+
+ ///
+ /// Class is resposible for finding the root directory where Final Fantasy VIII is stored.
+ ///
+ public static class GameDirectoryFinder
+ {
+ ///
+ /// Looks for root directory where the game is installed.
+ ///
+ /// Path to a directory where the game is installed.
+ public static string FindRootGameDirectory()
+ {
+ return RuntimeEnvironment.Platform switch
+ {
+ RuntimePlatform.Windows => WindowsRootGameDirectory(),
+ RuntimePlatform.Linux => LinuxRootGameDirectory(),
+ _ => throw new NotSupportedException(RuntimeEnvironment.Platform.ToString()),
+ };
+ }
+
+ private static string WindowsRootGameDirectory()
+ {
+ var commonRoots = new string[]
+ {
+ @"C:\Program Files (x86)\Steam\steamapps\common\FINAL FANTASY VIII",
+ @"D:\SteamLibrary\steamapps\common\FINAL FANTASY VIII",
+ @"D:\Steam\steamapps\common\FINAL FANTASY VIII",
+ };
+
+ if (commonRoots.Where(path => Directory.Exists(path)).Any())
+ return commonRoots.Where(path => Directory.Exists(path)).First();
+
+ var registryRoots = RootsFromRegistry();
+
+ if (registryRoots.Where(path => Directory.Exists(path)).Any())
+ return registryRoots.Where(path => Directory.Exists(path)).First();
+
+ throw new DirectoryNotFoundException($"Cannot find game directory." +
+ $"Add your own path to the {nameof(WindowsRootGameDirectory)}.");
+ }
+
+ private static List RootsFromRegistry()
+ {
+ // Now, we are looking into registers.
+ #region Registries paths and tags
+
+ // Steam 2013
+ const string SteamRegistryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 39150";
+ const string SteamGamePathTag = @"InstallLocation";
+
+ // Supplied from LordUrQuan
+ const string CD2000RegistryPath = @"SOFTWARE\Wow6432Node\Square Soft, Inc\FINAL FANTASY VIII\1.00";
+ const string CD2000GamePathTag = @"AppPath";
+
+ // Steam Remaster
+ const string SteamRERegistryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1026680";
+ const string SteamREGamePathTag = @"InstallLocation";
+ #endregion
+
+ var regs = new Dictionary()
+ {
+ {SteamRegistryPath, SteamGamePathTag},
+ {CD2000RegistryPath, CD2000GamePathTag},
+ {SteamRERegistryPath, SteamREGamePathTag}
+ };
+
+ var regValues = new List();
+ foreach (var pair in regs)
+ {
+ regValues.Add(ValueFromRegistry(pair.Key, pair.Value, RegistryView.Registry32));
+ regValues.Add(ValueFromRegistry(pair.Key, pair.Value, RegistryView.Registry64));
+ }
+
+ return regValues;
+ }
+
+ private static string ValueFromRegistry(string subKey, string valueName, RegistryView view)
+ {
+ using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view);
+ using var key = baseKey.OpenSubKey(subKey);
+
+ // Starting from C# 6 we can use Null-conditional operator (?.)
+ // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-
+ return (string)key?.GetValue(valueName);
+ }
+
+ private static string LinuxRootGameDirectory()
+ {
+ var commonRoots = new string[]
+ {
+ @"/home/robert/Final Fantasy VIII",
+ @"/media/griever/Data/SteamLibrary/steamapps/common/FINAL FANTASY VIII",
+ @"/home/griever/.PlayOnLinux/wineprefix/Steam/drive_c/Program Files/Steam/steamapps/common/FINAL FANTASY VIII",
+ @"/home/parallels/src/ff8/steam"
+ };
+
+ if (commonRoots.Where(path => Directory.Exists(path)).Any())
+ return commonRoots.Where(path => Directory.Exists(path)).First();
+
+ throw new DirectoryNotFoundException($"Cannot find game directory." +
+ $"Add your own path to the {nameof(LinuxRootGameDirectory)}.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Core/Memory.cs b/Core/Memory.cs
index d9c34a99..5189c270 100644
--- a/Core/Memory.cs
+++ b/Core/Memory.cs
@@ -1,6 +1,8 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
+using OpenVIII;
+using OpenVIII.Core;
using OpenVIII.Kernel;
using System;
using System.Collections.Concurrent;
@@ -833,9 +835,8 @@ public static void Init(GraphicsDeviceManager graphics, SpriteBatch spriteBatch,
Log.WriteLine($"{nameof(Memory)} :: {nameof(MainThreadOnlyActions)}");
MainThreadOnlyActions = new ConcurrentQueue();
- FF8Dir = GameLocation.Current.DataPath;
- void SetData() =>
- FF8DirData = Extended.GetUnixFullPath(Path.Combine(FF8Dir, "Data"));
+ FF8Dir = GameDirectoryFinder.FindRootGameDirectory();
+ void SetData() => FF8DirData = Extended.GetUnixFullPath(Path.Combine(FF8Dir, "Data"));
SetData();
var languageSet = false;
diff --git a/Core/Sources/Environment/Game/Location/GameLocation.cs b/Core/Sources/Environment/Game/Location/GameLocation.cs
deleted file mode 100644
index 15ebfbb2..00000000
--- a/Core/Sources/Environment/Game/Location/GameLocation.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System;
-
-namespace OpenVIII
-{
- public sealed class GameLocation
- {
- private readonly static GameLocation s_current = GetCurrentLocation();
-
- public string DataPath { get; private set; }
-
- public GameLocation(string dataPath)
- {
- DataPath = dataPath;
- }
-
- public static GameLocation Current
- {
- get
- {
- return s_current;
- }
- }
-
- private static GameLocation GetCurrentLocation()
- {
- var provider = GetLocationProvider();
- return provider.GetGameLocation();
- }
-
- private static IGameLocationProvider GetLocationProvider()
- {
- switch (RuntimeEnvironment.Platform)
- {
- case RuntimePlatform.Windows:
- return new WindowsGameLocationProvider();
- case RuntimePlatform.Linux:
- return new LinuxGameLocationProvider();
- default:
- throw new NotSupportedException(RuntimeEnvironment.Platform.ToString());
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Core/Sources/Environment/Game/Location/HardcodedGameLocationProvider.cs b/Core/Sources/Environment/Game/Location/HardcodedGameLocationProvider.cs
deleted file mode 100644
index ea1afaf6..00000000
--- a/Core/Sources/Environment/Game/Location/HardcodedGameLocationProvider.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.IO;
-
-namespace OpenVIII
-{
- public sealed class HardcodedGameLocationProvider
- {
- private readonly string[] _knownPaths;
-
- public HardcodedGameLocationProvider(string[] knownPaths)
- {
- _knownPaths = knownPaths ?? throw new ArgumentNullException(nameof(knownPaths));
- }
-
- public bool FindGameLocation(out GameLocation gameLocation)
- {
- //using (var errors = new ExceptionList())
- //{
- foreach (var path in _knownPaths)
- {
- try
- {
- if (!Directory.Exists(path))
- continue;
-
- gameLocation = new GameLocation(path);
- //errors.Clear();
- return true;
- }
- catch (Exception ex)
- {
- ex.Rethrow();
- //errors.Add(ex);
- }
- }
- //}
-
- gameLocation = null;
- return false;
- }
- }
-}
\ No newline at end of file
diff --git a/Core/Sources/Environment/Game/Location/IGameLocationProvider.cs b/Core/Sources/Environment/Game/Location/IGameLocationProvider.cs
deleted file mode 100644
index 419c529c..00000000
--- a/Core/Sources/Environment/Game/Location/IGameLocationProvider.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace OpenVIII
-{
- public interface IGameLocationProvider
- {
- GameLocation GetGameLocation();
- }
-}
\ No newline at end of file
diff --git a/Core/Sources/Environment/Game/Location/LinuxGameLocationProvider.cs b/Core/Sources/Environment/Game/Location/LinuxGameLocationProvider.cs
deleted file mode 100644
index ff475dda..00000000
--- a/Core/Sources/Environment/Game/Location/LinuxGameLocationProvider.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.IO;
-
-namespace OpenVIII
-{
- public sealed class LinuxGameLocationProvider : IGameLocationProvider
- {
- public GameLocation GetGameLocation()
- {
- if (_hardcoded.FindGameLocation(out var gameLocation))
- return gameLocation;
-
- throw new DirectoryNotFoundException($"Cannot find game directory." +
- $"Add your own path to the {nameof(LinuxGameLocationProvider)} type.");
- }
-
- private readonly HardcodedGameLocationProvider _hardcoded = new HardcodedGameLocationProvider(new[]
- {
- "/home/robert/Final Fantasy VIII",
- "/media/griever/Data/SteamLibrary/steamapps/common/FINAL FANTASY VIII",
- "/home/griever/.PlayOnLinux/wineprefix/Steam/drive_c/Program Files/Steam/steamapps/common/FINAL FANTASY VIII",
- "/home/parallels/src/ff8/steam"
- });
- }
-}
diff --git a/Core/Sources/Environment/Game/Location/WindowsGameLocationProvider.cs b/Core/Sources/Environment/Game/Location/WindowsGameLocationProvider.cs
deleted file mode 100644
index c5c0ddcf..00000000
--- a/Core/Sources/Environment/Game/Location/WindowsGameLocationProvider.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using Microsoft.Win32;
-using System.IO;
-
-namespace OpenVIII
-{
- public sealed class WindowsGameLocationProvider : IGameLocationProvider
- {
- ///
- /// Steam 2013
- ///
- private const string SteamRegistyPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 39150";
-
- ///
- /// Steam 2013
- ///
- private const string SteamGamePathTag = @"InstallLocation";
-
- ///
- /// Supplied from LordUrQuan
- ///
- private const string CD2000RegistyPath = @"SOFTWARE\Wow6432Node\Square Soft, Inc\FINAL FANTASY VIII\1.00";
-
- ///
- /// Supplied from LordUrQuan
- ///
- private const string CD2000GamePathTag = @"AppPath";
-
- ///
- /// ReMaster
- ///
- private const string SteamRERegistyPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1026680";
-
- ///
- /// ReMaster
- ///
- private const string SteamREGamePathTag = @"InstallLocation";
-
- public GameLocation GetGameLocation()
- {
- if (_hardcoded.FindGameLocation(out var gameLocation))
- return gameLocation;
-
- foreach (var registryView in new RegistryView[] { RegistryView.Registry32, RegistryView.Registry64 })
- {
- GameLocation r;
- if ((r = Check(SteamRegistyPath, SteamGamePathTag)) == null &&
- (r = Check(CD2000RegistyPath, CD2000RegistyPath)) == null &&
- (r = Check(SteamRERegistyPath, SteamREGamePathTag)) == null)
- continue;
- else
- return r;
-
- GameLocation Check(string path, string tag)
- {
- using (var localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
- using (var registryKey = localMachine.OpenSubKey(path))
- {
- if (registryKey != null)
- {
- var installLocation = (string)registryKey.GetValue(tag);
- var dataPath = installLocation;
- if (Directory.Exists(dataPath))
- return new GameLocation(dataPath);
- }
- }
- return null;
- }
- }
-
- throw new DirectoryNotFoundException($"Cannot find game directory." +
- $"Add your own path to the {nameof(WindowsGameLocationProvider)} type or fix a registration in the registry:" +
- $"{SteamRegistyPath}.{SteamGamePathTag}");
- }
-
- private readonly HardcodedGameLocationProvider _hardcoded = new HardcodedGameLocationProvider(new[]
- {
- @"C:\Program Files (x86)\Steam\steamapps\common\FINAL FANTASY VIII",//Data\lang-en
- @"D:\SteamLibrary\steamapps\common\FINAL FANTASY VIII",
- @"D:\Steam\steamapps\common\FINAL FANTASY VIII",
- });
- }
-}
\ No newline at end of file