feat(ui): Campaign OP slice OP6 — the Config tab
Binds the retail Options panel's Config tab (LayoutDesc 0x21000029, 27 authored rows across 6 sections) through OP2's template mechanism and OP3's per-page OptionPage model, matching the Character/Chat tab controllers' established pattern. The row table is transcribed directly from two decompiled sources — gmConfigUI::InitOptions @0x0049E400 (row order, widget shape, defaults) and gmClient::InitUIPreferences @0x004035b0 (the complete UIPreferences::AttachPreference registration: every label/tooltip key, every slider's real-unit range, every menu's enum choices) — which resolves the research docs' own "U4" unverified slider-caption pairing: retail ships ZERO range captions on this tab (every SetSliderLabel call passes literal string id 0). Consumer disposition: LIVE — Sound/Ambient volume-trio sliders and their toggle halves (AudioSettings.SfxDisabled/AmbientDisabled now gate the already-live engine write; RuntimeSettingsController.SaveAudio newly pushes into OpenAlAudioEngine on every change, not just at startup), Resolution/Full Screen (immediate window resize on save). NEXT-LAUNCH (pre-existing precedent): Sync To Refresh, Field of View. STORE-ONLY (register rows AP-198/199/200, TS-74 extended): Sound Features/Interface trio/Play-Only-When-Active, the nine Graphics/Rendering-Quality rows (Vulkan has no per-feature render knobs), Camera/Input's six rows and Use Mouse Turning (no persistent mouse-turning camera mode), Chat Font Face/Size (distinct new fields from the existing live ChatSettings.FontSize). AudioSettings/DisplaySettings/CameraTurningSettings/ChatSettings each gain new fields for their slice of the 27 rows, backed by SettingsStore round-trips. A real bug caught by testing: the scrollbar scope lookup used the standalone-layout root id (0x100001FF), which does not survive base-merge into the host-mounted tree — fixed to scope from the tab host's own page-slot id (0x10000213), matching Chat's established pattern for the same shared-scrollbar-id hazard (0x10000201, authored by both the Chat and Config ListBoxes). 30 new tests (27 authored rows register as 30 IOptionRow instances — the three toggle+slider trios each register two). Full Release suite: 13,107 passed / 4 skipped / 0 failed (was 13,083/4/0 — net +24, the one existing RuntimeSettingsControllerTests case updated for SaveAudio's new live-apply call, not a regression). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
527a3a4056
commit
f5ac1742ba
16 changed files with 2188 additions and 30 deletions
|
|
@ -16,9 +16,19 @@ public enum ParticleRange
|
|||
|
||||
/// <summary>
|
||||
/// Display-related preferences persisted to <c>settings.json</c>.
|
||||
/// Modern addition (no retail equivalent for FOV / vsync etc) — replaces
|
||||
/// the various <c>ACDREAM_*</c> environment variables for resolution +
|
||||
/// windowed mode with an in-game UI.
|
||||
/// Originally documented as "no retail equivalent for FOV / vsync etc" —
|
||||
/// Campaign OP slice OP6's Config-tab research corrected that: retail's
|
||||
/// <c>gmClient::InitUIPreferences @0x004035b0</c> DOES register
|
||||
/// <c>Render_FieldOfView</c> (<c>ID_Graphics_FieldOfView</c>, range
|
||||
/// [10,160]), <c>Display_SyncToRefresh</c>, <c>Display_Resolution</c>, and
|
||||
/// <c>Render_ScreenBrightness</c> (range [-1,1], mapped onto
|
||||
/// <see cref="Gamma"/> below) as genuine <c>UserPreferences.ini</c> rows —
|
||||
/// they simply had no acdream UI surface until OP6's Config tab. Resolution/
|
||||
/// Fullscreen are LIVE on save (<c>RuntimeSettingsTargets.
|
||||
/// ApplyDisplayWindowState</c> resizes the window immediately); VSync/FOV/
|
||||
/// Gamma apply at the next launch only (<c>RuntimeSettingsController.
|
||||
/// ApplyStartup</c>), matching this record's pre-existing behaviour — OP6
|
||||
/// did not change when these three take effect, only how they're reached.
|
||||
///
|
||||
/// <para>
|
||||
/// Records are immutable; mutation goes through
|
||||
|
|
@ -34,7 +44,26 @@ public sealed record DisplaySettings(
|
|||
float Gamma,
|
||||
bool ShowFps,
|
||||
QualityPreset Quality,
|
||||
ParticleRange ParticleRange)
|
||||
ParticleRange ParticleRange,
|
||||
// Campaign OP slice OP6: the Config tab's "Graphics Options" +
|
||||
// "Rendering Quality Options" rows with no acdream renderer consumer —
|
||||
// the world renderer is Vulkan + one aggregate QualityPreset, not
|
||||
// per-feature knobs (register row, OP6). Persisted faithfully; every
|
||||
// default below is retail's own byte-verified
|
||||
// gmClient::InitUIPreferences / gmConfigUI::InitOptions literal.
|
||||
bool AutomaticDegrades = false,
|
||||
float GraphicsPerformance = 0f,
|
||||
float DegradeDistance = 50f,
|
||||
int LandscapeTextureDetail = 2,
|
||||
int EnvironmentTextureDetail = 1,
|
||||
int TextureFiltering = 1,
|
||||
// UNRESOLVED (OP6, cite in register row): retail's own
|
||||
// SetDefaultValue(8) does not index its 6-entry SetEnumChoices array
|
||||
// (VeryLow..Extreme) — reproduced faithfully as an opaque int, not
|
||||
// guessed into a clamped index.
|
||||
int LandscapeDrawDistance = 8,
|
||||
bool BuildingDetailTextures = true,
|
||||
bool MultiPassAlpha = false)
|
||||
{
|
||||
/// <summary>Values used on first launch / when settings.json is absent.
|
||||
/// Geometry defaults preserve the pre-L.0 runtime state: Resolution
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue