diff --git a/Aetheria.State/README.md b/Aetheria.State/README.md index 5dae7875e..60b4eee41 100644 --- a/Aetheria.State/README.md +++ b/Aetheria.State/README.md @@ -21,6 +21,10 @@ disabled. That is intentional: the missing runtime package is the owner gap, and the old bespoke file formats must not keep acting as durable truth while the state spine is being rebuilt. +Keyboard layout rendering now reads the checked-in Unity text asset directly. +The old generated `GameData/KeyboardLayouts/*.msgpack` cache was deleted; layout +edits are runtime-only until Verse owns a typed layout/settings document. + Current rebuild notes: - `MessagePack` 3.1.4 is pulled transitively through CultLib and is currently diff --git a/Assets/Scripts/UI/InputScreen/InputDisplayLayout.cs b/Assets/Scripts/UI/InputScreen/InputDisplayLayout.cs index b3dd65623..7c197f0a7 100644 --- a/Assets/Scripts/UI/InputScreen/InputDisplayLayout.cs +++ b/Assets/Scripts/UI/InputScreen/InputDisplayLayout.cs @@ -1,9 +1,8 @@ using System; using System.Collections; using System.Collections.Generic; -using System.IO; using System.Linq; -using MessagePack; +using Ink.Runtime; using TMPro; using UniRx; using UnityEngine; @@ -83,11 +82,7 @@ public class InputDisplayLayout : MonoBehaviour void Start() { _canvas = transform.root.GetComponent(); - var path = Path.Combine(ActionGameManager.GameDataDirectory.CreateSubdirectory("KeyboardLayouts").FullName, $"{LayoutFile.name}.msgpack"); - // _inputLayout = ParseJson(LayoutFile.text); - RegisterResolver.Register(); - _inputLayout = MessagePackSerializer.Deserialize(File.ReadAllBytes(path)); - // SaveLayout(); + _inputLayout = ParseJson(LayoutFile.text); DisplayLayout(_inputLayout); _buttonMappings.Add(MapMouseButton(MouseLeft, "/leftButton")); @@ -386,65 +381,27 @@ public class InputDisplayLayout : MonoBehaviour var rows = new List(); var nextWidth = 1f; var nextHeight = 1; - var reader = new JsonTextReader(new StringReader(layout)); - reader.Read(); - if (reader.TokenType != JsonToken.StartArray) - throw new JsonReaderException($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}, expected: StartArray, received: {Enum.GetName(typeof(JsonToken), reader.TokenType)}"); - - while(reader.Read() && reader.TokenType != JsonToken.EndArray) + foreach (var rowValue in SimpleJson.TextToArray(layout)) { - if (reader.TokenType != JsonToken.StartArray) - throw new JsonReaderException($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}, expected: StartArray, received: {Enum.GetName(typeof(JsonToken), reader.TokenType)}"); + if (!(rowValue is List parsedRow)) + throw new FormatException("Unexpected keyboard layout JSON format: expected a row array."); var row = new InputLayoutKeyRow(); var columns = new List(); - while (reader.Read() && reader.TokenType != JsonToken.EndArray) + foreach (var columnValue in parsedRow) { - switch (reader.TokenType) + switch (columnValue) { - case JsonToken.StartObject: - while(reader.Read() && reader.TokenType != JsonToken.EndObject) - { - switch (reader.Value.ToString()) - { - case "a": break; - case "w": - nextWidth = (float) (reader.ReadAsDouble() ?? 1.0); - break; - case "h": - nextHeight = reader.ReadAsInt32() ?? 1; - break; - case "y": - rows.Add(new InputLayoutRowSpacer{Height = (float) (reader.ReadAsDouble() ?? 0.0)}); - break; - case "x": - columns.Add(new InputLayoutColumnSpacer{Width = (float) (reader.ReadAsDouble() ?? 0.0)}); - break; - } - } + case Dictionary options: + ApplyLayoutOptions(options, rows, columns, ref nextWidth, ref nextHeight); break; - case JsonToken.String: - InputLayoutKey key; - var v = reader.Value.ToString().Trim(); - if (!string.IsNullOrEmpty(v)) - { - var labels = v.Split('\n'); - key = nextHeight != 1 ? new InputLayoutMultiRowKey {Height = nextHeight} : new InputLayoutBindableKey(); - nextHeight = 1; - ((InputLayoutBindableKey) key).MainLabel = labels.Length == 2 ? labels[1] : v; - ((InputLayoutBindableKey) key).AltLabel = labels.Length == 2 ? labels[0] : ""; - } - else - key = new InputLayoutKey(); - - key.Width = nextWidth; - columns.Add(key); - nextWidth = 1f; + case string label: + columns.Add(CreateLayoutKey(label, ref nextWidth, ref nextHeight)); break; default: - throw new JsonReaderException($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}"); + throw new FormatException("Unexpected keyboard layout JSON format: expected a key label or options object."); } } @@ -455,6 +412,57 @@ public class InputDisplayLayout : MonoBehaviour return new InputLayout {Rows = rows.ToArray()}; } + private static void ApplyLayoutOptions( + Dictionary options, + ICollection rows, + ICollection columns, + ref float nextWidth, + ref int nextHeight) + { + foreach (var option in options) + { + switch (option.Key) + { + case "a": + break; + case "w": + nextWidth = Convert.ToSingle(option.Value); + break; + case "h": + nextHeight = Convert.ToInt32(option.Value); + break; + case "y": + rows.Add(new InputLayoutRowSpacer {Height = Convert.ToSingle(option.Value)}); + break; + case "x": + columns.Add(new InputLayoutColumnSpacer {Width = Convert.ToSingle(option.Value)}); + break; + } + } + } + + private static InputLayoutKey CreateLayoutKey(string label, ref float nextWidth, ref int nextHeight) + { + InputLayoutKey key; + var trimmedLabel = label.Trim(); + if (!string.IsNullOrEmpty(trimmedLabel)) + { + var labels = trimmedLabel.Split('\n'); + key = nextHeight != 1 ? new InputLayoutMultiRowKey {Height = nextHeight} : new InputLayoutBindableKey(); + nextHeight = 1; + ((InputLayoutBindableKey) key).MainLabel = labels.Length == 2 ? labels[1] : trimmedLabel; + ((InputLayoutBindableKey) key).AltLabel = labels.Length == 2 ? labels[0] : ""; + } + else + { + key = new InputLayoutKey(); + } + + key.Width = nextWidth; + nextWidth = 1f; + return key; + } + private IEnumerator AssociateInputKeys() { var path = ""; @@ -491,10 +499,7 @@ public class InputDisplayLayout : MonoBehaviour private void SaveLayout() { - RegisterResolver.Register(); - File.WriteAllBytes( - Path.Combine(ActionGameManager.GameDataDirectory.CreateSubdirectory("KeyboardLayouts").FullName, $"{LayoutFile.name}.msgpack"), - MessagePackSerializer.Serialize(_inputLayout)); + Debug.LogWarning("Keyboard layout persistence belongs to the Verse state spine. Layout edits are runtime-only until Aetheria.State is available as a Unity runtime package."); } private void OnEnable() diff --git a/GameData/KeyboardLayouts/ansi104.json b/GameData/KeyboardLayouts/ansi104.json deleted file mode 100644 index 44a2ba7e6..000000000 --- a/GameData/KeyboardLayouts/ansi104.json +++ /dev/null @@ -1 +0,0 @@ -{"rows":[{"columns":[{"mainLabel":"Esc","altLabel":"","path":"escape","width":1.0,"$type":"InputLayoutBindableKey"},{"width":1.0,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"F1","altLabel":"","path":"f1","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F2","altLabel":"","path":"f2","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F3","altLabel":"","path":"f3","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F4","altLabel":"","path":"f4","width":1.0,"$type":"InputLayoutBindableKey"},{"width":0.5,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"F5","altLabel":"","path":"f5","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F6","altLabel":"","path":"f6","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F7","altLabel":"","path":"f7","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F8","altLabel":"","path":"f8","width":1.0,"$type":"InputLayoutBindableKey"},{"width":0.5,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"F9","altLabel":"","path":"f9","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F10","altLabel":"","path":"f10","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F11","altLabel":"","path":"f11","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F12","altLabel":"","path":"f12","width":1.0,"$type":"InputLayoutBindableKey"},{"width":0.25,"$type":"InputLayoutColumnSpacer"},{"width":1.0,"$type":"InputLayoutKey"},{"width":1.0,"$type":"InputLayoutKey"},{"width":1.0,"$type":"InputLayoutKey"}],"$type":"InputLayoutKeyRow"},{"height":0.5,"$type":"InputLayoutRowSpacer"},{"columns":[{"mainLabel":"`","altLabel":"~","path":"backquote","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"1","altLabel":"!","path":"1","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"2","altLabel":"@","path":"2","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"3","altLabel":"#","path":"3","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"4","altLabel":"$","path":"4","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"5","altLabel":"%","path":"5","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"6","altLabel":"^","path":"6","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"7","altLabel":"&","path":"7","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"8","altLabel":"*","path":"8","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"9","altLabel":"(","path":"9","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"0","altLabel":")","path":"0","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"-","altLabel":"_","path":"minus","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"=","altLabel":"+","path":"equals","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"Backspace","altLabel":"","path":"backspace","width":2.0,"$type":"InputLayoutBindableKey"},{"width":0.25,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"Insert","altLabel":"","path":"insert","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"Home","altLabel":"","path":"home","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"PgUp","altLabel":"","path":"pageUp","width":1.0,"$type":"InputLayoutBindableKey"},{"width":0.25,"$type":"InputLayoutColumnSpacer"},{"width":1.0,"$type":"InputLayoutKey"},{"mainLabel":"/","altLabel":"","path":"numpadDivide","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"*","altLabel":"","path":"numpadMultiply","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"-","altLabel":"","path":"numpadMinus","width":1.0,"$type":"InputLayoutBindableKey"}],"$type":"InputLayoutKeyRow"},{"columns":[{"mainLabel":"Tab","altLabel":"","path":"tab","width":1.5,"$type":"InputLayoutBindableKey"},{"mainLabel":"Q","altLabel":"","path":"q","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"W","altLabel":"","path":"w","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"E","altLabel":"","path":"e","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"R","altLabel":"","path":"r","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"T","altLabel":"","path":"t","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"Y","altLabel":"","path":"y","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"U","altLabel":"","path":"u","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"I","altLabel":"","path":"i","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"O","altLabel":"","path":"o","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"P","altLabel":"","path":"p","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"[","altLabel":"{","path":"leftBracket","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"]","altLabel":"}","path":"rightBracket","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"\\","altLabel":"|","path":"backslash","width":1.5,"$type":"InputLayoutBindableKey"},{"width":0.25,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"Delete","altLabel":"","path":"delete","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"End","altLabel":"","path":"end","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"PgDn","altLabel":"","path":"pageDown","width":1.0,"$type":"InputLayoutBindableKey"},{"width":0.25,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"7","altLabel":"Home","path":"numpad7","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"8","altLabel":"↑","path":"numpad8","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"9","altLabel":"PgUp","path":"numpad9","width":1.0,"$type":"InputLayoutBindableKey"},{"height":2,"mainLabel":"+","altLabel":"","path":"numpadPlus","width":1.0,"$type":"InputLayoutMultiRowKey"}],"$type":"InputLayoutKeyRow"},{"columns":[{"mainLabel":"Caps Lock","altLabel":"","path":"capsLock","width":1.75,"$type":"InputLayoutBindableKey"},{"mainLabel":"A","altLabel":"","path":"a","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"S","altLabel":"","path":"s","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"D","altLabel":"","path":"d","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"F","altLabel":"","path":"f","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"G","altLabel":"","path":"g","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"H","altLabel":"","path":"h","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"J","altLabel":"","path":"j","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"K","altLabel":"","path":"k","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"L","altLabel":"","path":"l","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":";","altLabel":":","path":"semicolon","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"'","altLabel":"\"","path":"quote","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"Enter","altLabel":"","path":"enter","width":2.25,"$type":"InputLayoutBindableKey"},{"width":3.5,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"4","altLabel":"←","path":"numpad4","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"5","altLabel":"","path":"numpad5","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"6","altLabel":"→","path":"numpad6","width":1.0,"$type":"InputLayoutBindableKey"}],"$type":"InputLayoutKeyRow"},{"columns":[{"mainLabel":"Shift","altLabel":"","path":"leftShift","width":2.25,"$type":"InputLayoutBindableKey"},{"mainLabel":"Z","altLabel":"","path":"z","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"X","altLabel":"","path":"x","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"C","altLabel":"","path":"c","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"V","altLabel":"","path":"v","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"B","altLabel":"","path":"b","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"N","altLabel":"","path":"n","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"M","altLabel":"","path":"m","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":",","altLabel":"<","path":"comma","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":".","altLabel":">","path":"period","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"/","altLabel":"?","path":"slash","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"Shift","altLabel":"","path":"rightShift","width":2.75,"$type":"InputLayoutBindableKey"},{"width":1.25,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"↑","altLabel":"","path":"upArrow","width":1.0,"$type":"InputLayoutBindableKey"},{"width":1.25,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"1","altLabel":"End","path":"numpad1","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"2","altLabel":"↓","path":"numpad2","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"3","altLabel":"PgDn","path":"numpad3","width":1.0,"$type":"InputLayoutBindableKey"},{"height":2,"mainLabel":"Enter","altLabel":"","path":"numpadEnter","width":1.0,"$type":"InputLayoutMultiRowKey"}],"$type":"InputLayoutKeyRow"},{"columns":[{"mainLabel":"Ctrl","altLabel":"","path":"leftCtrl","width":1.25,"$type":"InputLayoutBindableKey"},{"width":1.25,"$type":"InputLayoutKey"},{"mainLabel":"Alt","altLabel":"","path":"leftAlt","width":1.25,"$type":"InputLayoutBindableKey"},{"mainLabel":"Spacebar","altLabel":"","path":"space","width":6.25,"$type":"InputLayoutBindableKey"},{"mainLabel":"Alt","altLabel":"","path":"rightAlt","width":1.25,"$type":"InputLayoutBindableKey"},{"width":1.25,"$type":"InputLayoutKey"},{"width":1.25,"$type":"InputLayoutKey"},{"mainLabel":"Ctrl","altLabel":"","path":"rightCtrl","width":1.25,"$type":"InputLayoutBindableKey"},{"width":0.25,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"←","altLabel":"","path":"leftArrow","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"↓","altLabel":"","path":"downArrow","width":1.0,"$type":"InputLayoutBindableKey"},{"mainLabel":"→","altLabel":"","path":"rightArrow","width":1.0,"$type":"InputLayoutBindableKey"},{"width":0.25,"$type":"InputLayoutColumnSpacer"},{"mainLabel":"0","altLabel":"Ins","path":"numpad0","width":2.0,"$type":"InputLayoutBindableKey"},{"mainLabel":".","altLabel":"Del","path":"numpadPeriod","width":1.0,"$type":"InputLayoutBindableKey"}],"$type":"InputLayoutKeyRow"}]} \ No newline at end of file diff --git a/GameData/KeyboardLayouts/ansi104.msgpack b/GameData/KeyboardLayouts/ansi104.msgpack deleted file mode 100644 index 839a6dcc1..000000000 --- a/GameData/KeyboardLayouts/ansi104.msgpack +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:77a2be69d0ba3fc3d7b89183c8cac69137728b7f298547fc2263cfdd69862ce7 -size 1961