mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2026-08-15 02:57:49 +04:00
add config file
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
namespace NResUI.Abstractions;
|
||||
|
||||
public interface IConfigProvider
|
||||
{
|
||||
ConfigJson GetConfig();
|
||||
void Set(ConfigJson config);
|
||||
}
|
||||
|
||||
public class ConfigProvider : IConfigProvider
|
||||
{
|
||||
private ConfigJson _instance;
|
||||
|
||||
public ConfigProvider(ConfigJson instance)
|
||||
{
|
||||
_instance = instance;
|
||||
}
|
||||
|
||||
public void Set(ConfigJson config)
|
||||
{
|
||||
_instance = config;
|
||||
}
|
||||
|
||||
public ConfigJson GetConfig()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace NResUI.Abstractions;
|
||||
|
||||
public interface ILaunchReceiver
|
||||
{
|
||||
void OnLaunch();
|
||||
}
|
||||
@@ -26,6 +26,7 @@ public class App
|
||||
public ImFontPtr OpenSansFont;
|
||||
|
||||
private List<IImGuiPanel> _imGuiPanels = [];
|
||||
private Later _later = new();
|
||||
|
||||
public App()
|
||||
{
|
||||
@@ -40,6 +41,9 @@ public class App
|
||||
|
||||
IServiceCollection serviceCollection = new ServiceCollection();
|
||||
|
||||
serviceCollection.AddSingleton<ILater>(_later);
|
||||
serviceCollection.AddSingleton<IConfigProvider>(new ConfigProvider(new ConfigJson()));
|
||||
|
||||
foreach (var type in Utils.GetAssignableTypes<IService>())
|
||||
{
|
||||
serviceCollection.AddSingleton(type);
|
||||
@@ -50,6 +54,11 @@ public class App
|
||||
serviceCollection.AddSingleton(type);
|
||||
}
|
||||
|
||||
foreach (var type in Utils.GetAssignableTypes<ILaunchReceiver>())
|
||||
{
|
||||
serviceCollection.AddSingleton(type);
|
||||
}
|
||||
|
||||
serviceCollection.AddSingleton(openGl);
|
||||
serviceCollection.AddSingleton(window);
|
||||
|
||||
@@ -68,6 +77,12 @@ public class App
|
||||
_imGuiPanels = Utils.GetAssignableTypes<IImGuiPanel>()
|
||||
.Select(t => (serviceProvider.GetService(t) as IImGuiPanel)!)
|
||||
.ToList();
|
||||
|
||||
foreach (var type in Utils.GetAssignableTypes<ILaunchReceiver>())
|
||||
{
|
||||
var launchReceiver = serviceProvider.GetService(type) as ILaunchReceiver;
|
||||
launchReceiver?.OnLaunch();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnImGuiRender()
|
||||
@@ -123,6 +138,11 @@ public class App
|
||||
{
|
||||
imGuiPanel.OnImGuiRender();
|
||||
}
|
||||
|
||||
foreach (var action in _later.Enumerate())
|
||||
{
|
||||
action();
|
||||
}
|
||||
|
||||
// ImGui.ShowMetricsWindow();
|
||||
// ImGui.ShowDemoWindow();
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace NResUI;
|
||||
|
||||
public class ConfigJson
|
||||
{
|
||||
/// <summary>
|
||||
/// Path to the game itself (the folder that contains DATA, MISSIONS, UNITS etc)
|
||||
/// </summary>
|
||||
public string GameBasePath { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace NResUI;
|
||||
|
||||
public interface ILater
|
||||
{
|
||||
void Execute(Action action);
|
||||
}
|
||||
|
||||
public class Later : ILater
|
||||
{
|
||||
private Queue<Action> _queue = new();
|
||||
|
||||
public void Execute(Action action)
|
||||
{
|
||||
_queue.Enqueue(action);
|
||||
}
|
||||
|
||||
public IEnumerable<Action> Enumerate()
|
||||
{
|
||||
while (_queue.Count > 0)
|
||||
{
|
||||
var action = _queue.Dequeue();
|
||||
yield return action;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,14 @@ public sealed class ViewportPanel : IImGuiPanel
|
||||
private readonly ViewportScene _scene;
|
||||
private readonly ViewportCamera _camera = new();
|
||||
private readonly ViewportInputController _inputController = new();
|
||||
private readonly IConfigProvider _configProvider;
|
||||
|
||||
private string? _loadedModelPath;
|
||||
private string? _loadError;
|
||||
|
||||
public ViewportPanel(GL gl, IWindow window)
|
||||
public ViewportPanel(GL gl, IWindow window, IConfigProvider configProvider)
|
||||
{
|
||||
_configProvider = configProvider;
|
||||
var cubeMesh = PrimitiveMeshes.CreateCube(gl);
|
||||
var gridMesh = PrimitiveMeshes.CreateWorldGrid(gl);
|
||||
|
||||
@@ -94,7 +96,7 @@ public sealed class ViewportPanel : IImGuiPanel
|
||||
if (ImGui.Button("Reset cube"))
|
||||
{
|
||||
var cubeMesh = PrimitiveMeshes.CreateCube(_renderer.Gl);
|
||||
_scene.ReplacePieces(new[] { ViewportPiece.CreateUnitCube(0, "Cube", cubeMesh) });
|
||||
_scene.ReplacePieces([ViewportPiece.CreateUnitCube(0, "Cube", cubeMesh)]);
|
||||
_loadedModelPath = null;
|
||||
_loadError = null;
|
||||
_camera.Reset();
|
||||
@@ -109,7 +111,7 @@ public sealed class ViewportPanel : IImGuiPanel
|
||||
|
||||
private void LoadMsh(string path)
|
||||
{
|
||||
var loadResult = MshViewportLoader.LoadFromFile(_renderer.Gl, path);
|
||||
var loadResult = MshViewportLoader.LoadFromFile(_renderer.Gl, path, _configProvider);
|
||||
if (!loadResult.IsSuccess)
|
||||
{
|
||||
_loadError = loadResult.Error ?? "Unknown error.";
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Text.Json;
|
||||
using NResUI.Abstractions;
|
||||
using NResUI.ImGuiUI;
|
||||
|
||||
namespace NResUI;
|
||||
|
||||
public class LoadConfigOnLaunch : ILaunchReceiver
|
||||
{
|
||||
private readonly ILater _later;
|
||||
private readonly MessageBoxModalPanel _messageBoxModalPanel;
|
||||
private readonly IConfigProvider _configProvider;
|
||||
|
||||
public LoadConfigOnLaunch(ILater later, MessageBoxModalPanel messageBoxModalPanel, IConfigProvider configProvider)
|
||||
{
|
||||
_later = later;
|
||||
_messageBoxModalPanel = messageBoxModalPanel;
|
||||
_configProvider = configProvider;
|
||||
}
|
||||
|
||||
public void OnLaunch()
|
||||
{
|
||||
if (!File.Exists("config.json"))
|
||||
{
|
||||
_later.Execute(() =>
|
||||
{
|
||||
_messageBoxModalPanel.Show(
|
||||
"config.json is not present\nViewport may be broken without game files\nPlaceholder file has been created");
|
||||
});
|
||||
var config = new ConfigJson() { GameBasePath = "" };
|
||||
File.WriteAllText("config.json", JsonSerializer.Serialize(config));
|
||||
_configProvider.Set(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = File.ReadAllText("config.json");
|
||||
var config = JsonSerializer.Deserialize<ConfigJson>(content);
|
||||
if (config is null)
|
||||
{
|
||||
_later.Execute(() =>
|
||||
{
|
||||
_messageBoxModalPanel.Show("config.json was corrupted\nReplacement has been created");
|
||||
});
|
||||
config = new ConfigJson() { GameBasePath = "" };
|
||||
File.WriteAllText("config.json", JsonSerializer.Serialize(config));
|
||||
_configProvider.Set(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
_configProvider.Set(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
using System.Numerics;
|
||||
using MshLib;
|
||||
using NResLib;
|
||||
using NResUI.Abstractions;
|
||||
using NResUI.Rendering.Viewport.Meshes;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
@@ -11,7 +12,7 @@ public static class MshViewportLoader
|
||||
private const int DefaultModelState = 0;
|
||||
private const int DefaultLod = 0;
|
||||
|
||||
public static MshViewportLoadResult LoadFromFile(GL gl, string path)
|
||||
public static MshViewportLoadResult LoadFromFile(GL gl, string path, IConfigProvider configProvider)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -30,7 +31,7 @@ public static class MshViewportLoader
|
||||
}
|
||||
|
||||
fs.Seek(0, SeekOrigin.Begin);
|
||||
var pieces = LoadModelPieces(gl, fs, archive, path);
|
||||
var pieces = LoadModelPieces(gl, fs, archive, path, configProvider);
|
||||
if (pieces.Count == 0)
|
||||
return MshViewportLoadResult.Failure("MSH was parsed, but no renderable geometry pieces were found.", path);
|
||||
|
||||
@@ -42,7 +43,9 @@ public static class MshViewportLoader
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ViewportPiece> LoadModelPieces(GL gl, FileStream fs, NResArchive archive, string path)
|
||||
private static List<ViewportPiece> LoadModelPieces(
|
||||
GL gl, FileStream fs, NResArchive archive, string path, IConfigProvider configProvider
|
||||
)
|
||||
{
|
||||
var nodes = Msh0x01.ReadComponent(fs, archive);
|
||||
var geometry = Msh0x02.ReadComponent(fs, archive);
|
||||
@@ -54,7 +57,7 @@ public static class MshViewportLoader
|
||||
var restPoses = MshRestPoseBuilder.BuildRestPose(nodes, animationDescriptors);
|
||||
var mshToViewportTransform = Matrix4x4.CreateRotationX(-MathF.PI * 0.5f);
|
||||
var names = TryReadNames(fs, archive);
|
||||
var materialLibrary = WeaMaterialLibrary.TryLoadForMsh(gl, path);
|
||||
var materialLibrary = WeaMaterialLibrary.TryLoadForMsh(gl, path, configProvider);
|
||||
|
||||
var pieces = new List<ViewportPiece>();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using MaterialLib;
|
||||
using NResLib;
|
||||
using NResUI.Abstractions;
|
||||
using NResUI.Rendering.Viewport.OpenGL;
|
||||
using Silk.NET.OpenGL;
|
||||
using TexmLib;
|
||||
@@ -24,7 +25,7 @@ public sealed class WeaMaterialLibrary
|
||||
: null;
|
||||
}
|
||||
|
||||
public static WeaMaterialLibrary TryLoadForMsh(GL gl, string mshPath)
|
||||
public static WeaMaterialLibrary TryLoadForMsh(GL gl, string mshPath, IConfigProvider configProvider)
|
||||
{
|
||||
var weaPath = FindMatchingWeaPath(mshPath);
|
||||
if (!File.Exists(weaPath))
|
||||
@@ -34,9 +35,13 @@ public sealed class WeaMaterialLibrary
|
||||
if (materialRefs.Count == 0)
|
||||
return Empty;
|
||||
|
||||
// TODO: Hardcoded for now
|
||||
var materialLibFs = "C:\\IronStrategy\\Material.lib";
|
||||
var materialLibFs = Path.Combine(configProvider.GetConfig().GameBasePath, "Material.lib");
|
||||
|
||||
if (!File.Exists(materialLibFs))
|
||||
{
|
||||
return new WeaMaterialLibrary([]);
|
||||
}
|
||||
|
||||
using var materialFs = new FileStream(materialLibFs, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
var parseResult = NResParser.ReadFile(materialFs);
|
||||
if (parseResult.Archive == null)
|
||||
@@ -46,7 +51,7 @@ public sealed class WeaMaterialLibrary
|
||||
|
||||
foreach (var materialRef in materialRefs)
|
||||
{
|
||||
var texture = TryLoadMaterialTexture(gl, materialFs, parseResult.Archive, materialRef.Name, out var texm);
|
||||
var texture = TryLoadMaterialTexture(gl, materialFs, parseResult.Archive, materialRef.Name, configProvider, out var texm);
|
||||
result[materialRef.Id] = texture != null
|
||||
? new ViewportMaterial(materialRef.Name, texture.Value, texm)
|
||||
: new ViewportMaterial(materialRef.Name);
|
||||
@@ -194,7 +199,8 @@ public sealed class WeaMaterialLibrary
|
||||
}
|
||||
|
||||
private static uint? TryLoadMaterialTexture(
|
||||
GL gl, FileStream materialFs, NResArchive materialArchive, string materialName, out TexmFile? texm
|
||||
GL gl, FileStream materialFs, NResArchive materialArchive, string materialName, IConfigProvider configProvider,
|
||||
out TexmFile? texm
|
||||
)
|
||||
{
|
||||
texm = null;
|
||||
@@ -212,7 +218,12 @@ public sealed class WeaMaterialLibrary
|
||||
|
||||
var texture = materialFile.Stages[0].TextureName;
|
||||
|
||||
var textureLibFs = "C:\\IronStrategy\\Textures.lib";
|
||||
var textureLibFs = Path.Combine(configProvider.GetConfig().GameBasePath, "Textures.lib");
|
||||
|
||||
if (!File.Exists(textureLibFs))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using var textureFs = new FileStream(textureLibFs, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
var textureResult = NResParser.ReadFile(textureFs);
|
||||
@@ -269,27 +280,5 @@ public sealed class WeaMaterialLibrary
|
||||
Normalize(x.FileName) == normalized);
|
||||
}
|
||||
|
||||
private static string? FindTexturesLib(string? startDirectory)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(startDirectory))
|
||||
return null;
|
||||
|
||||
var directory = new DirectoryInfo(startDirectory);
|
||||
while (directory != null)
|
||||
{
|
||||
var candidate = Path.Combine(directory.FullName, "Textures.lib");
|
||||
if (Directory.Exists(candidate))
|
||||
return candidate;
|
||||
|
||||
candidate = Path.Combine(directory.FullName, "textures.lib");
|
||||
if (Directory.Exists(candidate))
|
||||
return candidate;
|
||||
|
||||
directory = directory.Parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private readonly record struct WeaMaterialRef(int Id, string Name);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user