mirror of
https://github.com/MaSzyna-EU07/StarterNG.git
synced 2026-10-16 23:49:19 +02:00
Add hide-archival, last-scenery, HDR tone map and external-change settings
#13 HideArchivalVehicles; #19 LastScenery; HDR tonemap + framebuffer fidelity; reload eu07.ini when it changes on disk; dump missing-vehicle log on exit.
This commit is contained in:
@@ -70,6 +70,7 @@ public partial class App : Application
|
||||
desktop.ShutdownRequested += (_, _) =>
|
||||
{
|
||||
Settings.Instance.CaptureAndSave();
|
||||
Settings.Instance.DumpMissingVehicleLog();
|
||||
if (KeyboardConfig.Instance.Dirty)
|
||||
KeyboardConfig.Instance.Save();
|
||||
};
|
||||
|
||||
@@ -65,13 +65,15 @@ public sealed class Settings
|
||||
public string ExecutablePath = "eu07.exe"; // starter.exe.path (launcher-only)
|
||||
public bool DebugMode; // debugmode
|
||||
public bool VirtualShunting = true; // ai.trainman
|
||||
public bool LogMissingVehicleFiles; // starter.logmissingvehicles (launcher-only; not yet wired to any load/export codepath)
|
||||
public bool LogMissingVehicleFiles; // starter.logmissingvehicles → bledy.txt dump
|
||||
|
||||
// ── Graphics ──────────────────────────────────────────────────────────
|
||||
public int RenderEngine; // gfxrenderer (index, see RenderEngines)
|
||||
public int Width = 1280; // width
|
||||
public int Height = 720; // height
|
||||
public int BufferScalePercent = 100; // starter.bufferscale (NOTE: launcher-only)
|
||||
public int BufferScalePercent = 100; // starter.bufferscale → gfx.framebuffer.fidelity
|
||||
/// <summary>0 = Reinhard, 1 = ACESFilm (Pascal ChangeHDR).</summary>
|
||||
public int HdrToneMap; // starter.hdr
|
||||
public int MaxTextureSize = 4096; // maxtexturesize
|
||||
public int MaxCabTextureSize = 4096; // maxcabtexturesize
|
||||
public int TextureFiltering = 8; // anisotropicfiltering (1/2/4/8/16)
|
||||
@@ -146,6 +148,9 @@ public sealed class Settings
|
||||
public bool ShowAiVehicles = true; // starter.show.ai (show //$o "-" consists)
|
||||
public bool DrivableOnly = true; // starter.drivableonly (hide //$decor consists)
|
||||
public bool ShowArchivalSceneries = true; // starter.show.archival
|
||||
public bool HideArchivalVehicles = true; // starter.hide.archivalvehicles
|
||||
/// <summary>Last selected scenery file name (without path), restored on next launch.</summary>
|
||||
public string LastScenery = ""; // starter.last.scenery
|
||||
|
||||
/// <summary>gfxrenderer tokens in the order shown by the render-engine combo.</summary>
|
||||
public static readonly string[] RenderEngines =
|
||||
@@ -160,6 +165,7 @@ public sealed class Settings
|
||||
|
||||
private ConfigFile _config = new();
|
||||
private string _savePath = string.Empty;
|
||||
private DateTime _configAgeUtc = DateTime.MinValue;
|
||||
|
||||
/// <summary>Resolves the per-user eu07.ini path for the current OS.</summary>
|
||||
public static string UserConfigPath()
|
||||
@@ -308,6 +314,7 @@ public sealed class Settings
|
||||
}
|
||||
|
||||
ReadFromConfig();
|
||||
TouchConfigAge();
|
||||
}
|
||||
|
||||
/// <summary>Persists settings to the per-user eu07.ini, keeping unknown keys.</summary>
|
||||
@@ -323,6 +330,8 @@ public sealed class Settings
|
||||
public void SaveTo(string path)
|
||||
{
|
||||
WriteToConfig();
|
||||
ApplyFramebufferFidelity();
|
||||
ApplyHdrShader();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -330,6 +339,7 @@ public sealed class Settings
|
||||
if (!string.IsNullOrEmpty(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
File.WriteAllText(path, _config.ToText(), FileEncoding);
|
||||
TouchConfigAge();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -337,6 +347,103 @@ public sealed class Settings
|
||||
}
|
||||
}
|
||||
|
||||
public void TouchConfigAge()
|
||||
{
|
||||
string path = string.IsNullOrEmpty(_savePath) ? UserConfigPath() : _savePath;
|
||||
try
|
||||
{
|
||||
_configAgeUtc = File.Exists(path)
|
||||
? File.GetLastWriteTimeUtc(path)
|
||||
: DateTime.UtcNow;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_configAgeUtc = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Pascal CheckSettingsFile: true when eu07.ini is newer than last load/save.</summary>
|
||||
public bool IsConfigNewerOnDisk()
|
||||
{
|
||||
string path = string.IsNullOrEmpty(_savePath) ? UserConfigPath() : _savePath;
|
||||
try
|
||||
{
|
||||
if (!File.Exists(path) || _configAgeUtc == DateTime.MinValue)
|
||||
return false;
|
||||
return File.GetLastWriteTimeUtc(path) > _configAgeUtc + TimeSpan.FromSeconds(1);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Map BufferScalePercent → gfx.framebuffer.fidelity like Pascal's 720/1080/1440/Custom.
|
||||
private void ApplyFramebufferFidelity()
|
||||
{
|
||||
int fidelity = BufferScalePercent switch
|
||||
{
|
||||
<= 75 => 1,
|
||||
<= 125 => 2,
|
||||
<= 175 => 3,
|
||||
_ => 0
|
||||
};
|
||||
if (fidelity > 0)
|
||||
_config.SetInt("gfx.framebuffer.fidelity", fidelity);
|
||||
else
|
||||
_config.Remove("gfx.framebuffer.fidelity");
|
||||
}
|
||||
|
||||
/// <summary>Copy Reinhard/ACESFilm GLSL into shaders/tonemapping.glsl when present.</summary>
|
||||
public void ApplyHdrShader()
|
||||
{
|
||||
// Only meaningful for full / legacy / experimental renderers (Pascal).
|
||||
if (RenderEngine is not (0 or 1 or 5))
|
||||
return;
|
||||
|
||||
string name = HdrToneMap == 0 ? "Reinhard.glsl" : "ACESFilm.glsl";
|
||||
string? src = FindBundled(name);
|
||||
if (src is null) return;
|
||||
|
||||
try
|
||||
{
|
||||
string destDir = Path.Combine(Directory.GetCurrentDirectory(), "shaders");
|
||||
Directory.CreateDirectory(destDir);
|
||||
File.Copy(src, Path.Combine(destDir, "tonemapping.glsl"), overwrite: true);
|
||||
}
|
||||
catch { /* missing shaders dir / permissions */ }
|
||||
}
|
||||
|
||||
private static string? FindBundled(string fileName)
|
||||
{
|
||||
foreach (string dir in new[]
|
||||
{
|
||||
Path.Combine(Directory.GetCurrentDirectory(), "starter"),
|
||||
Path.Combine(AppContext.BaseDirectory, "startercfg"),
|
||||
Path.Combine(Directory.GetCurrentDirectory(), "startercfg")
|
||||
})
|
||||
{
|
||||
string path = Path.Combine(dir, fileName);
|
||||
if (File.Exists(path)) return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Pascal chLogExt on exit: dump missing vehicle assets to starter/bledy.txt.</summary>
|
||||
public void DumpMissingVehicleLog()
|
||||
{
|
||||
if (!LogMissingVehicleFiles) return;
|
||||
try
|
||||
{
|
||||
var lines = GameData.Instance.Vehicles.CollectMissingAssetLines();
|
||||
if (lines.Count == 0) return;
|
||||
string dir = Path.Combine(Directory.GetCurrentDirectory(), "starter");
|
||||
Directory.CreateDirectory(dir);
|
||||
File.WriteAllLines(Path.Combine(dir, "bledy.txt"), lines);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
// ── config → fields ───────────────────────────────────────────────────
|
||||
private void ReadFromConfig()
|
||||
{
|
||||
@@ -388,6 +495,7 @@ public sealed class Settings
|
||||
DebugMode = c.GetBool("debugmode", false);
|
||||
VirtualShunting = c.GetBool("ai.trainman", true);
|
||||
LogMissingVehicleFiles = c.GetBool("starter.logmissingvehicles", false);
|
||||
HdrToneMap = Clamp(c.GetInt("starter.hdr", 0), 0, 1);
|
||||
|
||||
// Graphics
|
||||
RenderEngine = IndexOf(RenderEngines, c.GetString("gfxrenderer", "full"), 0);
|
||||
@@ -470,6 +578,8 @@ public sealed class Settings
|
||||
ShowAiVehicles = c.GetBool("starter.show.ai", true);
|
||||
DrivableOnly = c.GetBool("starter.drivableonly", true);
|
||||
ShowArchivalSceneries = c.GetBool("starter.show.archival", true);
|
||||
HideArchivalVehicles = c.GetBool("starter.hide.archivalvehicles", true);
|
||||
LastScenery = c.GetString("starter.last.scenery", "");
|
||||
}
|
||||
|
||||
// ── fields → config ───────────────────────────────────────────────────
|
||||
@@ -511,6 +621,7 @@ public sealed class Settings
|
||||
c.SetBool("debugmode", DebugMode);
|
||||
c.SetBool("ai.trainman", VirtualShunting);
|
||||
c.SetBool("starter.logmissingvehicles", LogMissingVehicleFiles);
|
||||
c.SetInt("starter.hdr", Clamp(HdrToneMap, 0, 1));
|
||||
|
||||
// Graphics
|
||||
c.Set("gfxrenderer", RenderEngines[Clamp(RenderEngine, 0, RenderEngines.Length - 1)]);
|
||||
@@ -590,6 +701,11 @@ public sealed class Settings
|
||||
c.SetBool("starter.show.ai", ShowAiVehicles);
|
||||
c.SetBool("starter.drivableonly", DrivableOnly);
|
||||
c.SetBool("starter.show.archival", ShowArchivalSceneries);
|
||||
c.SetBool("starter.hide.archivalvehicles", HideArchivalVehicles);
|
||||
if (!string.IsNullOrWhiteSpace(LastScenery))
|
||||
c.Set("starter.last.scenery", LastScenery);
|
||||
else
|
||||
c.Remove("starter.last.scenery");
|
||||
}
|
||||
|
||||
// ── small helpers ──────────────────────────────────────────────────────
|
||||
|
||||
@@ -130,6 +130,13 @@
|
||||
<ComboBoxItem Content="{Binding [REExperimental], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [HdrToneMap], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="HdrToneMapCb" MinWidth="150" MaxWidth="150" SelectedIndex="0">
|
||||
<ComboBoxItem Content="Reinhard" />
|
||||
<ComboBoxItem Content="ACES Film" />
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [Resolution], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="ResolutionCb" MinWidth="150" MaxWidth="150" SelectedIndex="0">
|
||||
@@ -367,6 +374,7 @@
|
||||
<CheckBox x:Name="AutoCloseStarterCb" Content="{Binding [AutoCloseStarter], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="LargeThumbnailsCb" Content="{Binding [LargeThumbnails], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="AutoExpandTreeCb" Content="{Binding [AutoExpandSceneryTree], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="HideArchivalVehiclesCb" Content="{Binding [HideArchivalVehicles], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" Text="{Binding [BatteryDefault], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="BatteryDefaultCb" MinWidth="220" SelectedIndex="0">
|
||||
|
||||
@@ -131,6 +131,8 @@ public partial class Settings : UserControl
|
||||
}
|
||||
|
||||
// ── Settings instance → controls ──────────────────────────────────────
|
||||
public void ReloadFromSettings() => ApplyToUi();
|
||||
|
||||
private void ApplyToUi()
|
||||
{
|
||||
var s = StarterNG.Classes.Settings.Instance;
|
||||
@@ -175,6 +177,7 @@ public partial class Settings : UserControl
|
||||
|
||||
// Graphics
|
||||
RenderEngineCb.SelectedIndex = s.RenderEngine;
|
||||
HdrToneMapCb.SelectedIndex = Clamp(s.HdrToneMap, 0, 1);
|
||||
SelectResolution(s.Width, s.Height);
|
||||
bufferScale.Value = s.BufferScalePercent;
|
||||
textureResolutionSlider.Value = Log2(s.MaxTextureSize, 12);
|
||||
@@ -246,6 +249,7 @@ public partial class Settings : UserControl
|
||||
AutoCloseStarterCb.IsChecked = s.AutoCloseStarter;
|
||||
LargeThumbnailsCb.IsChecked = s.LargeThumbnails;
|
||||
AutoExpandTreeCb.IsChecked = s.AutoExpandSceneryTree;
|
||||
HideArchivalVehiclesCb.IsChecked = s.HideArchivalVehicles;
|
||||
BatteryDefaultCb.SelectedIndex = (int)s.BatteryDefault;
|
||||
}
|
||||
finally
|
||||
@@ -293,6 +297,7 @@ public partial class Settings : UserControl
|
||||
|
||||
// Graphics
|
||||
s.RenderEngine = Math.Max(0, RenderEngineCb.SelectedIndex);
|
||||
s.HdrToneMap = Clamp(HdrToneMapCb.SelectedIndex, 0, 1);
|
||||
ReadResolution(s);
|
||||
s.BufferScalePercent = (int)bufferScale.Value;
|
||||
s.MaxTextureSize = 1 << (int)textureResolutionSlider.Value;
|
||||
@@ -364,6 +369,7 @@ public partial class Settings : UserControl
|
||||
s.AutoCloseStarter = IsChecked(AutoCloseStarterCb);
|
||||
s.LargeThumbnails = IsChecked(LargeThumbnailsCb);
|
||||
s.AutoExpandSceneryTree = IsChecked(AutoExpandTreeCb);
|
||||
s.HideArchivalVehicles = IsChecked(HideArchivalVehiclesCb);
|
||||
s.BatteryDefault = (BatteryDefault)Math.Max(0, BatteryDefaultCb.SelectedIndex);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user