fix(studio): Character window — larger row text + tighter attribute rows
- RowHeight reduced 44→30px to pack the 9 rows tighter, matching retail's denser list - Attribute row name/value text now uses Font 0x40000001 (MaxCharHeight=18px) instead of the default 0x40000000 (16px); both fonts are in client_portal.dat (confirmed 2026-06-26) - RenderStack gains LargeDatFont field; RenderBootstrap.Create loads both fonts - FixtureProvider passes LargeDatFont as rowDatFont to CharacterStatController.Bind - CharacterStatController.Bind gains rowDatFont? parameter (falls back to datFont); passed to BuildAttributeRows so row UiText elements use the larger font - Full solution tests green (681/683 App + 1579/1581 Core + 343 Net + 425 UI) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
405b0d5077
commit
a236dc33ac
3 changed files with 22 additions and 4 deletions
|
|
@ -22,7 +22,8 @@ public sealed record RenderStack(
|
||||||
Wb.WbDrawDispatcher DrawDispatcher,
|
Wb.WbDrawDispatcher DrawDispatcher,
|
||||||
SceneLightingUboBinding LightingUbo,
|
SceneLightingUboBinding LightingUbo,
|
||||||
AcDream.App.UI.UiHost UiHost,
|
AcDream.App.UI.UiHost UiHost,
|
||||||
AcDream.App.UI.UiDatFont? VitalsDatFont) : System.IDisposable
|
AcDream.App.UI.UiDatFont? VitalsDatFont,
|
||||||
|
AcDream.App.UI.UiDatFont? LargeDatFont) : System.IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>Dispose the GL pieces this stack OWNS (everything created in
|
/// <summary>Dispose the GL pieces this stack OWNS (everything created in
|
||||||
/// <see cref="RenderBootstrap.Create"/>). <see cref="Dats"/> + <see cref="Gl"/> are caller-owned
|
/// <see cref="RenderBootstrap.Create"/>). <see cref="Dats"/> + <see cref="Gl"/> are caller-owned
|
||||||
|
|
@ -147,6 +148,12 @@ public static class RenderBootstrap
|
||||||
// --- Vitals dat font (GameWindow ~1820-1822) ---
|
// --- Vitals dat font (GameWindow ~1820-1822) ---
|
||||||
var vitalsDatFont = AcDream.App.UI.UiDatFont.Load(dats, textureCache);
|
var vitalsDatFont = AcDream.App.UI.UiDatFont.Load(dats, textureCache);
|
||||||
|
|
||||||
|
// --- Larger retail font (0x40000001, MaxCharHeight=18) for attribute row text.
|
||||||
|
// The default font (0x40000000, 16px) renders the row names too small; the 18px
|
||||||
|
// variant (confirmed in client_portal.dat 2026-06-26) matches the retail character
|
||||||
|
// window list more closely (≈ icon height ≈ 24px target, 18px is best available).
|
||||||
|
var largeDatFont = AcDream.App.UI.UiDatFont.Load(dats, textureCache, 0x40000001u);
|
||||||
|
|
||||||
// --- UiHost (GameWindow ~1790); pass null for debugFont (only used as
|
// --- UiHost (GameWindow ~1790); pass null for debugFont (only used as
|
||||||
// a fallback BitmapFont for the world-space HUD — not needed for the
|
// a fallback BitmapFont for the world-space HUD — not needed for the
|
||||||
// UI Studio, and BitmapFont requires a system font byte array) ---
|
// UI Studio, and BitmapFont requires a system font byte array) ---
|
||||||
|
|
@ -164,7 +171,8 @@ public static class RenderBootstrap
|
||||||
DrawDispatcher: drawDispatcher,
|
DrawDispatcher: drawDispatcher,
|
||||||
LightingUbo: lightingUbo,
|
LightingUbo: lightingUbo,
|
||||||
UiHost: uiHost,
|
UiHost: uiHost,
|
||||||
VitalsDatFont: vitalsDatFont);
|
VitalsDatFont: vitalsDatFont,
|
||||||
|
LargeDatFont: largeDatFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NullAnimLoader mirrors GameWindow's private NullAnimLoader (GameWindow ~13327-13330).
|
// NullAnimLoader mirrors GameWindow's private NullAnimLoader (GameWindow ~13327-13330).
|
||||||
|
|
|
||||||
|
|
@ -118,10 +118,13 @@ public static class FixtureProvider
|
||||||
// Bind the REAL importer-mounted header + list elements (name/heritage/PK/level/
|
// Bind the REAL importer-mounted header + list elements (name/heritage/PK/level/
|
||||||
// total-XP/XP-meter + the 9-row attribute list + footer State-A). NOT the text-report
|
// total-XP/XP-meter + the 9-row attribute list + footer State-A). NOT the text-report
|
||||||
// sub-panel (that is gmCharacterInfoUI 0x2100001A → CharacterController).
|
// sub-panel (that is gmCharacterInfoUI 0x2100001A → CharacterController).
|
||||||
|
// LargeDatFont (0x40000001, MaxCharHeight=18) is used for the attribute row text;
|
||||||
|
// fallback to VitalsDatFont (0x40000000, 16px) if unavailable.
|
||||||
CharacterStatController.Bind(
|
CharacterStatController.Bind(
|
||||||
layout,
|
layout,
|
||||||
data: SampleData.SampleCharacter,
|
data: SampleData.SampleCharacter,
|
||||||
datFont: stack.VitalsDatFont,
|
datFont: stack.VitalsDatFont,
|
||||||
|
rowDatFont: stack.LargeDatFont ?? stack.VitalsDatFont,
|
||||||
spriteResolve: stack.ResolveChrome);
|
spriteResolve: stack.ResolveChrome);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,10 @@ public static class CharacterStatController
|
||||||
private static readonly Vector4 HighlightBg = new(1f, 0.75f, 0.2f, 0.25f);
|
private static readonly Vector4 HighlightBg = new(1f, 0.75f, 0.2f, 0.25f);
|
||||||
|
|
||||||
// ── Row layout constants ─────────────────────────────────────────────────
|
// ── Row layout constants ─────────────────────────────────────────────────
|
||||||
private const float RowHeight = 44f;
|
// RowHeight reduced from 44 to 30px to match retail's tighter attribute list.
|
||||||
|
// The larger row font (0x40000001, MaxCharHeight=18) fits in 30px with 6px total vertical
|
||||||
|
// padding (3px above/below). Retail spec (2026-06-26 ref): "rows tighter, text ≈ icon height".
|
||||||
|
private const float RowHeight = 30f;
|
||||||
private const float IconSize = 24f;
|
private const float IconSize = 24f;
|
||||||
private const float RowPadX = 4f;
|
private const float RowPadX = 4f;
|
||||||
private const float IconGap = 6f;
|
private const float IconGap = 6f;
|
||||||
|
|
@ -172,8 +175,12 @@ public static class CharacterStatController
|
||||||
ImportedLayout layout,
|
ImportedLayout layout,
|
||||||
Func<CharacterSheet> data,
|
Func<CharacterSheet> data,
|
||||||
UiDatFont? datFont = null,
|
UiDatFont? datFont = null,
|
||||||
|
UiDatFont? rowDatFont = null,
|
||||||
Func<uint, (uint handle, int w, int h)>? spriteResolve = null)
|
Func<uint, (uint handle, int w, int h)>? spriteResolve = null)
|
||||||
{
|
{
|
||||||
|
// rowDatFont: larger font for attribute row name/value text (18px vs 16px default).
|
||||||
|
// Falls back to datFont when null (tests, or dat missing).
|
||||||
|
rowDatFont ??= datFont;
|
||||||
// Name: retail "Horan" is WHITE, not gold. Heritage and PK status are also white.
|
// Name: retail "Horan" is WHITE, not gold. Heritage and PK status are also white.
|
||||||
Label(layout, NameId, datFont, Vector4.One, () => data().Name);
|
Label(layout, NameId, datFont, Vector4.One, () => data().Name);
|
||||||
Label(layout, HeritageId, datFont, Body, () => data().Heritage ?? data().Race ?? string.Empty);
|
Label(layout, HeritageId, datFont, Body, () => data().Heritage ?? data().Race ?? string.Empty);
|
||||||
|
|
@ -348,7 +355,7 @@ public static class CharacterStatController
|
||||||
|
|
||||||
if (layout.FindElement(ListBoxId) is { } list)
|
if (layout.FindElement(ListBoxId) is { } list)
|
||||||
{
|
{
|
||||||
rowPanels = BuildAttributeRows(list, datFont, spriteResolve, data, sel,
|
rowPanels = BuildAttributeRows(list, rowDatFont, spriteResolve, data, sel,
|
||||||
allRaise1, allRaise10);
|
allRaise1, allRaise10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue