fix #391: curated modern-only resolution list from the monitor's modes
User-directed (2026-08-13): "we should only support modern resolutions. Not any old format." New DisplayModeCatalog enumerates the window's monitor (Silk IMonitor.GetAllVideoModes) once at GameWindow load and curates via a pure, tested rule: modern widescreen families only (16:9/16:10/21:9/32:9 within 2.5%), at least 1280 wide, must fit the desktop (an impossible windowed pick is not offered - the measured 3840x2160-on-2560x1440 silent clamp class), desktop mode always included, refresh-rate duplicates collapsed, ascending order. The Config Resolution row consumes the catalog through two new optional Bind parameters; its Defaults value becomes the desktop's own mode. Fixture/headless callers keep the static preset ladder, which now drops 800x600 and is pinned by test to pass the same curation rule (the OP6 S4 "default must be re-selectable" invariant holds on both paths). Deliberate retail deviation, register row IA-22: retail listed the adapter's complete enumeration including 4:3 legacy modes and authored 800x600 as the Config default (gmConfigUI::InitOptions SetDefaultValue(0x03200258); gmClient::Init @0x004047af). The catalog is also the designated fullscreen mode-switch validation source for #376/#388 - an offered mode is supported by construction. Tests: DisplayModeCatalogTests (8 - filter/clamp/dedupe/sort/ultrawide/ desktop-inclusion/fallback-consistency); ConfigOptionsPageControllerTests row-12 default updated. App suite 4,961/3 skips; UI.Abstractions 916. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7e0c130344
commit
13d388e5a9
9 changed files with 324 additions and 23 deletions
108
tests/AcDream.App.Tests/Rendering/DisplayModeCatalogTests.cs
Normal file
108
tests/AcDream.App.Tests/Rendering/DisplayModeCatalogTests.cs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
using AcDream.App.Rendering;
|
||||
using AcDream.UI.Abstractions.Panels.Settings;
|
||||
|
||||
namespace AcDream.App.Tests.Rendering;
|
||||
|
||||
/// <summary>#391 (user-directed): the curation rule that turns a monitor's
|
||||
/// raw mode enumeration into the modern-only resolution list. Pure-function
|
||||
/// tests — the Silk monitor adapter is a thin projection over this.</summary>
|
||||
public sealed class DisplayModeCatalogTests
|
||||
{
|
||||
private static readonly (int W, int H) Desktop2560 = (2560, 1440);
|
||||
|
||||
[Fact]
|
||||
public void Curate_DropsLegacyFormats_KeepsModernFamilies()
|
||||
{
|
||||
var modes = new (int, int)[]
|
||||
{
|
||||
(640, 480), (800, 600), (1024, 768), (1280, 1024), // 4:3 / 5:4 legacy
|
||||
(1280, 720), (1366, 768), (1600, 900), (1920, 1080), // 16:9
|
||||
(1920, 1200), // 16:10
|
||||
(2560, 1440),
|
||||
};
|
||||
|
||||
var curated = DisplayModeCatalog.Curate(modes, Desktop2560);
|
||||
|
||||
Assert.Equal(
|
||||
["1280x720", "1366x768", "1600x900", "1920x1080", "1920x1200", "2560x1440"],
|
||||
curated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Curate_ExcludesModesLargerThanTheDesktop()
|
||||
{
|
||||
// A windowed pick larger than the desktop can only silently clamp
|
||||
// (measured live 2026-08-13: a 3840x2160 pick on this desktop
|
||||
// produced a 2564x1421 window) — if it cannot exist, it is not
|
||||
// offered.
|
||||
var curated = DisplayModeCatalog.Curate(
|
||||
[(1920, 1080), (2560, 1440), (3840, 2160)], Desktop2560);
|
||||
|
||||
Assert.Equal(["1920x1080", "2560x1440"], curated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Curate_CollapsesRefreshRateDuplicates_AndSortsAscending()
|
||||
{
|
||||
// Real enumerations repeat each WxH once per refresh rate and are
|
||||
// not ordered; the catalog is one entry per size, ascending.
|
||||
var curated = DisplayModeCatalog.Curate(
|
||||
[(2560, 1440), (1920, 1080), (1920, 1080), (1920, 1080), (1280, 720)],
|
||||
Desktop2560);
|
||||
|
||||
Assert.Equal(["1280x720", "1920x1080", "2560x1440"], curated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Curate_KeepsUltrawideFamilies()
|
||||
{
|
||||
var curated = DisplayModeCatalog.Curate(
|
||||
[(2560, 1080), (3440, 1440), (3840, 1080)], (3840, 1600));
|
||||
|
||||
Assert.Equal(["2560x1080", "3440x1440", "3840x1080"], curated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Curate_AlwaysIncludesTheDesktopModeItself()
|
||||
{
|
||||
// The desktop mode is displayable by definition — it stays even when
|
||||
// its aspect matches no listed family (and it is the Defaults value).
|
||||
var curated = DisplayModeCatalog.Curate(
|
||||
[(1920, 1080), (1920, 1440)], (1920, 1440)); // desktop is 4:3!
|
||||
|
||||
Assert.Contains("1920x1440", curated);
|
||||
Assert.Contains("1920x1080", curated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Curate_DropsSubMinimumWidths_EvenWhenWidescreen()
|
||||
{
|
||||
// 1024x576 is exactly 16:9 but below the modern floor.
|
||||
var curated = DisplayModeCatalog.Curate(
|
||||
[(1024, 576), (1280, 720)], Desktop2560);
|
||||
|
||||
Assert.Equal(["1280x720"], curated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FallbackPresetLadder_ItselfPassesTheCurationRule()
|
||||
{
|
||||
// The static fixture-fallback list must never offer something the
|
||||
// production rule would reject (a big desktop accepts all of it).
|
||||
var parsed = DisplaySettings.AvailableResolutions
|
||||
.Select(static s => s.Split('x'))
|
||||
.Select(static p => (int.Parse(p[0]), int.Parse(p[1])));
|
||||
|
||||
var curated = DisplayModeCatalog.Curate(parsed, (3840, 2160));
|
||||
|
||||
Assert.Equal(DisplaySettings.AvailableResolutions, curated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FallbackDefault_IsAMemberOfTheFallbackList()
|
||||
{
|
||||
// The S4 rule survives the curation: the Defaults value must always
|
||||
// be re-selectable from the offered list.
|
||||
Assert.Contains(DisplaySettings.Default.Resolution, DisplaySettings.AvailableResolutions);
|
||||
}
|
||||
}
|
||||
|
|
@ -726,7 +726,9 @@ public sealed class ConfigOptionsPageControllerTests
|
|||
90.0f, // 10 Field Of View
|
||||
true, // 11 Align To Slope
|
||||
|
||||
"800x600", // 12 Resolution
|
||||
"1280x720", // 12 Resolution (#391: fixture fallback default —
|
||||
// DisplaySettings.Default.Resolution; production
|
||||
// passes the desktop mode via DisplayModeCatalog)
|
||||
true, // 13 Full Screen
|
||||
false, // 14 Sync To Refresh
|
||||
0f, // 15 Screen Brightness
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue