SHA256
Fix Preset Label Not Matching Loaded Config Values
This commit is contained in:
2 files changed
+63
-17
No files matched your search
@@ -520,7 +520,9 @@ public class RenderSession
|
|||||||
}
|
}
|
||||||
|
|
||||||
RenderManager.Instance.levelPath = levelPath;
|
RenderManager.Instance.levelPath = levelPath;
|
||||||
RenderManager.Instance.Configuration = renderConfig;
|
// The render uses its own copy of the configuration: values adjusted during the render
|
||||||
|
// (e.g. the audio sample rate in SetupPlay) stay in this copy and do not change the caller's object.
|
||||||
|
RenderManager.Instance.Configuration = renderConfig.Clone();
|
||||||
|
|
||||||
RenderManager.Instance.stage = RenderStage.Load;
|
RenderManager.Instance.stage = RenderStage.Load;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using ADOFAIRenderer.Data;
|
|||||||
using ADOFAIRenderer.Localization;
|
using ADOFAIRenderer.Localization;
|
||||||
using ADOFAIRenderer.Util.OS;
|
using ADOFAIRenderer.Util.OS;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using O5Kit.Control;
|
using O5Kit.Control;
|
||||||
using O5Kit.Core;
|
using O5Kit.Core;
|
||||||
using O5Kit.Factory;
|
using O5Kit.Factory;
|
||||||
@@ -32,6 +33,14 @@ internal static class RenderConfigWindow
|
|||||||
private static Coroutine? _deleteResetCoroutine;
|
private static Coroutine? _deleteResetCoroutine;
|
||||||
private static string? _lastLoadedPresetName;
|
private static string? _lastLoadedPresetName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configuration edited by this window. Kept for the whole game session; a render started from the window
|
||||||
|
/// receives a copy of it (RenderSession.Start), so values adjusted during the render are not written back here.
|
||||||
|
/// </summary>
|
||||||
|
private static RenderConfig? _uiConfig;
|
||||||
|
|
||||||
|
private static RenderConfig UiConfig => _uiConfig ??= new RenderConfig();
|
||||||
|
|
||||||
// Controls cache for validation & sync
|
// Controls cache for validation & sync
|
||||||
private static O5Slider? _renderFpsSlider;
|
private static O5Slider? _renderFpsSlider;
|
||||||
private static O5Slider? _videoFPSSlider;
|
private static O5Slider? _videoFPSSlider;
|
||||||
@@ -111,8 +120,7 @@ internal static class RenderConfigWindow
|
|||||||
ReloadPresetDropdown(GlobalSettings.Current.LastPresetName);
|
ReloadPresetDropdown(GlobalSettings.Current.LastPresetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract
|
var config = UiConfig;
|
||||||
var config = RenderManager.Instance.Configuration ??= new RenderConfig();
|
|
||||||
ApplyConfigToUI(config);
|
ApplyConfigToUI(config);
|
||||||
|
|
||||||
SetWindowActive(true);
|
SetWindowActive(true);
|
||||||
@@ -125,8 +133,7 @@ internal static class RenderConfigWindow
|
|||||||
var (_, scrollContent, _) =
|
var (_, scrollContent, _) =
|
||||||
O5Factory.ScrollView(ctx, content, spacing: 10f, padding: 8f);
|
O5Factory.ScrollView(ctx, content, spacing: 10f, padding: 8f);
|
||||||
|
|
||||||
// ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract
|
var config = UiConfig;
|
||||||
var config = RenderManager.Instance.Configuration ??= new RenderConfig();
|
|
||||||
EnsureDefaultConfig(config);
|
EnsureDefaultConfig(config);
|
||||||
|
|
||||||
double[] renderFpsSnap = { 23.976, 24, 29.97, 30, 59.94, 60, 144,
|
double[] renderFpsSnap = { 23.976, 24, 29.97, 30, 59.94, 60, 144,
|
||||||
@@ -744,11 +751,14 @@ internal static class RenderConfigWindow
|
|||||||
{
|
{
|
||||||
EnsureDefaultConfig(config);
|
EnsureDefaultConfig(config);
|
||||||
|
|
||||||
_renderFpsSlider?.Set((float) config.RenderFPS, false);
|
// Sliders show the config values as they are (noFilter: true).
|
||||||
_videoFPSSlider?.Set((float) config.VideoFPS, false);
|
// O5Slider.Set applies the slider filter (snapping to the nearest snap value) unless noFilter is set;
|
||||||
_renderWidthSlider?.Set(config.RenderWidth, false);
|
// the filter is meant for dragging, and typed values are not snapped either (O5Slider.SetFromInput).
|
||||||
_renderHeightSlider?.Set(config.RenderHeight, false);
|
_renderFpsSlider?.Set(config.RenderFPS, false, noFilter: true);
|
||||||
_delayAfterEndSlider?.Set((float) config.DelayAfterEnd, false);
|
_videoFPSSlider?.Set(config.VideoFPS, false, noFilter: true);
|
||||||
|
_renderWidthSlider?.Set(config.RenderWidth, false, noFilter: true);
|
||||||
|
_renderHeightSlider?.Set(config.RenderHeight, false, noFilter: true);
|
||||||
|
_delayAfterEndSlider?.Set(config.DelayAfterEnd, false, noFilter: true);
|
||||||
_showJudgementToggle?.Set(config.ShowJudgementText, false);
|
_showJudgementToggle?.Set(config.ShowJudgementText, false);
|
||||||
|
|
||||||
_codecDropdown?.Set(config.VideoConfig.Codec, false);
|
_codecDropdown?.Set(config.VideoConfig.Codec, false);
|
||||||
@@ -756,13 +766,13 @@ internal static class RenderConfigWindow
|
|||||||
_bitrateInput?.Set(config.VideoConfig.Bitrate.ToString(), false);
|
_bitrateInput?.Set(config.VideoConfig.Bitrate.ToString(), false);
|
||||||
_maxBitrateInput?.Set(config.VideoConfig.MaxBitrate.ToString(), false);
|
_maxBitrateInput?.Set(config.VideoConfig.MaxBitrate.ToString(), false);
|
||||||
_qpInput?.Set(config.VideoConfig.QP.ToString(), false);
|
_qpInput?.Set(config.VideoConfig.QP.ToString(), false);
|
||||||
_keyframeIntervalSlider?.Set(config.VideoConfig.KeyframeInterval, false);
|
_keyframeIntervalSlider?.Set(config.VideoConfig.KeyframeInterval, false, noFilter: true);
|
||||||
_forceSoftwareToggle?.Set(config.VideoConfig.ForceSoftwareEncoder, false);
|
_forceSoftwareToggle?.Set(config.VideoConfig.ForceSoftwareEncoder, false);
|
||||||
|
|
||||||
_renderAudioToggle?.Set(config.AudioConfig.RenderAudio, false);
|
_renderAudioToggle?.Set(config.AudioConfig.RenderAudio, false);
|
||||||
_sampleRateDropdown?.Set(config.AudioConfig.AudioSampleRate, false);
|
_sampleRateDropdown?.Set(config.AudioConfig.AudioSampleRate, false);
|
||||||
_channelsDropdown?.Set(config.AudioConfig.AudioChannels, false);
|
_channelsDropdown?.Set(config.AudioConfig.AudioChannels, false);
|
||||||
_audioBitrateSlider?.Set(config.AudioConfig.AudioBitrate / 1000.0, false);
|
_audioBitrateSlider?.Set(config.AudioConfig.AudioBitrate / 1000.0, false, noFilter: true);
|
||||||
|
|
||||||
_outputDirInput?.Set(GlobalSettings.EffectiveOutputDirectory, false);
|
_outputDirInput?.Set(GlobalSettings.EffectiveOutputDirectory, false);
|
||||||
|
|
||||||
@@ -789,17 +799,51 @@ internal static class RenderConfigWindow
|
|||||||
UpdateVideoCodecUI(config.VideoConfig.Codec, config);
|
UpdateVideoCodecUI(config.VideoConfig.Codec, config);
|
||||||
UpdateRateControlUI(config.VideoConfig.RateControlMode, noAnimate: true);
|
UpdateRateControlUI(config.VideoConfig.RateControlMode, noAnimate: true);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(GlobalSettings.Current.LastPresetName))
|
UpdatePresetLabel(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the preset dropdown from the config values.
|
||||||
|
/// Every value equals the last loaded preset (_lastLoadedPresetName): the preset name is shown.
|
||||||
|
/// Any value differs (edited, or the preset file changed): the Custom label is shown (MarkConfigModified),
|
||||||
|
/// the same state as after editing a value in the window.
|
||||||
|
/// </summary>
|
||||||
|
private static void UpdatePresetLabel(RenderConfig config)
|
||||||
|
{
|
||||||
|
if (_presetDropdown == null) return;
|
||||||
|
|
||||||
|
var presetName = _lastLoadedPresetName;
|
||||||
|
var preset = string.IsNullOrEmpty(presetName)
|
||||||
|
? null
|
||||||
|
: PresetManager.GetPresets().FirstOrDefault(p => string.Equals(p.Name, presetName, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (preset == null || !ConfigValuesEqual(config, preset.Config))
|
||||||
{
|
{
|
||||||
_presetDropdown?.Set(GlobalSettings.Current.LastPresetName, false);
|
MarkConfigModified();
|
||||||
_lastLoadedPresetName = GlobalSettings.Current.LastPresetName;
|
return;
|
||||||
UpdateDeleteButtonState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_presetDropdown.Values.Contains(CustomPresetLabel))
|
||||||
|
{
|
||||||
|
_presetDropdown.SetValues(_presetDropdown.Values.Where(v => v != CustomPresetLabel).ToList());
|
||||||
|
}
|
||||||
|
_presetDropdown.Set(preset.Name, false);
|
||||||
|
UpdateDeleteButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compares two configs by their serialized JSON (the same form as the preset files), so every saved value is compared.
|
||||||
|
/// </summary>
|
||||||
|
private static bool ConfigValuesEqual(RenderConfig a, RenderConfig b)
|
||||||
|
{
|
||||||
|
var settings = new JsonSerializerSettings();
|
||||||
|
settings.Converters.Add(new ColorJsonConverter());
|
||||||
|
return JsonConvert.SerializeObject(a, settings) == JsonConvert.SerializeObject(b, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void TryGoRender()
|
private static void TryGoRender()
|
||||||
{
|
{
|
||||||
var config = RenderManager.Instance.Configuration;
|
var config = UiConfig;
|
||||||
SyncUItoConfig(config);
|
SyncUItoConfig(config);
|
||||||
|
|
||||||
// Sync Output Directory
|
// Sync Output Directory
|
||||||
|
|||||||
Reference in new issue
Block a user