using AcDream.App.UI.Layout; using AcDream.UI.Abstractions.Input; using Silk.NET.Input; namespace AcDream.App.Tests.UI.Layout; /// /// OP8 re-gate (2026-08-14): retail's key-binding display names — /// CInputManager_WIN32::GetNameFromKey @ 0x00687F40 over /// GetNameFromKey_Internal @ 0x00687800. DAT string-table override /// first (key table enum 4 → DID 0x2300000A, meta enum 5 → 0x2300000B), /// OS-localized key name second, DIK-suffix spelling last; modifier prefixes /// join through the authored ID_KeyDescDelimiter (enum 3 → 0x23000007). /// public sealed class RetailKeyNamesTests { private static string? NoStrings(uint table, uint hash) => null; private static Func Table( params (uint Table, string Key, string Value)[] entries) => (table, hash) => { foreach ((uint t, string key, string value) in entries) if (t == table && DatStringResolver.ComputeHash(key) == hash) return value; return null; }; [Fact] public void DatTableOverride_WinsOverOsName() { // The shipped dat authors DIK_LCONTROL -> "Left Ctrl" in 0x2300000A // (live-probed 2026-08-14); the OS name must not be consulted. var names = new RetailKeyNames( Table((RetailKeyNames.KeyNameTableId, "DIK_LCONTROL", "Left Ctrl")), osKeyName: (_, _) => throw new InvalidOperationException("OS lookup must not run")); Assert.Equal("Left Ctrl", names.Describe(new KeyChord(Key.ControlLeft, ModifierMask.None))); } [Fact] public void OsLocalizedName_UsedWhenTheDatTableMisses() { // DIK_LSHIFT has no authored override in the shipped dat — retail // shows the keyboard layout's own name ("SKIFT" on Swedish). var names = new RetailKeyNames( NoStrings, osKeyName: (scan, extended) => scan == 0x2A && !extended ? "SKIFT" : null); Assert.Equal("SKIFT", names.Describe(new KeyChord(Key.ShiftLeft, ModifierMask.None))); } [Fact] public void SelfModifier_ShowsOnlyTheKeyName_NeverShiftPlusShiftLeft() { // acdream's wire-side chord for retail's bare DIK_LSHIFT walk-mode row // carries the self-modifier bit; retail's QualifiedControl has // meta-mode 0 and displays just the key. var names = new RetailKeyNames( NoStrings, osKeyName: (scan, _) => scan == 0x2A ? "SKIFT" : null); Assert.Equal("SKIFT", names.Describe(new KeyChord(Key.ShiftLeft, ModifierMask.Shift))); // The fake OS lookup only answers LSHIFT's scan code; RSHIFT proves // the same no-prefix rule through the DIK-suffix fallback instead. Assert.Equal("RSHIFT", names.Describe(new KeyChord(Key.ShiftRight, ModifierMask.Shift))); } [Fact] public void ModifierPrefixes_JoinWithTheAuthoredDelimiter_InMetaBitOrder() { // Meta-mode bits ascending (Shift=1, Ctrl=2, Alt=4 — the shipped // keymap's Metakeys header), each named through the meta table + OS // fallback, joined by ID_KeyDescDelimiter. var names = new RetailKeyNames( Table((RetailKeyNames.DelimiterTableId, "ID_KeyDescDelimiter", "+")), osKeyName: (scan, _) => scan switch { 0x2A => "SKIFT", 0x1D => "CTRL", 0x38 => "ALT", 0x32 => "M", _ => null, }); Assert.Equal( "SKIFT+CTRL+ALT+M", names.Describe(new KeyChord( Key.M, ModifierMask.Shift | ModifierMask.Ctrl | ModifierMask.Alt))); } [Fact] public void MetaTableOverride_WinsForTheModifierPrefix() { var names = new RetailKeyNames( Table( (RetailKeyNames.DelimiterTableId, "ID_KeyDescDelimiter", "+"), (RetailKeyNames.MetaKeyNameTableId, "DIK_LSHIFT", "Shift")), osKeyName: (scan, _) => scan == 0x32 ? "M" : null); Assert.Equal("Shift+M", names.Describe(new KeyChord(Key.M, ModifierMask.Shift))); } [Fact] public void ExtendedKeys_PassTheExtendedFlagToTheOsLookup() { // DIK_UP = 0xC8: scan 0x48 + the extended bit — the same split // GetKeyNameText expects in lParam bit 24. (byte Scan, bool Extended)? seen = null; var names = new RetailKeyNames( NoStrings, osKeyName: (scan, extended) => { seen = (scan, extended); return "UP ARROW"; }); Assert.Equal("UP ARROW", names.Describe(new KeyChord(Key.Up, ModifierMask.None))); Assert.Equal(((byte)0x48, true), seen); } [Fact] public void DikSuffixSpelling_WhenBothDatAndOsMiss() { var names = new RetailKeyNames(NoStrings, osKeyName: (_, _) => null); Assert.Equal("W", names.Describe(new KeyChord(Key.W, ModifierMask.None))); Assert.Equal("NUMPADENTER", names.Describe(new KeyChord(Key.KeypadEnter, ModifierMask.None))); } [Fact] public void ControlsOutsideTheDikTable_KeepTheEnumSpelling() { var names = new RetailKeyNames(NoStrings, osKeyName: (_, _) => null); // Key.F13 never appears in the DAT's 84 observed scan codes. Assert.Equal("F13", names.Describe(new KeyChord(Key.F13, ModifierMask.None))); Assert.Equal( "Shift+F13", names.Describe(new KeyChord(Key.F13, ModifierMask.Shift))); } [Fact] public void DefaultChord_DescribesAsEmpty() { var names = new RetailKeyNames(NoStrings, osKeyName: (_, _) => null); Assert.Equal(string.Empty, names.Describe(default)); } }