fix(ui): Campaign LA gate round 2 — character-select scales as one authored canvas
Third iteration on the screen, completing AD-98. The previous substitution
stretched only the root BACKGROUND while the child widgets stayed at their
authored 800x600 pixel positions - and the background painting carries
visual anchors (the World/Characters captions are art), so the user gate
showed captions overlapping the listbox and every widget misaligned
against the stretched art.
Retail model (established at 71bf24fb): fixed-canvas pre-world screens
render at authored 800x600 and the whole composed frame stretches once at
presentation; the blitter has no stretch mode. Our equivalent now does the
same one stage earlier:
- UiRoot.FixedCanvasSize: while the char-select screen is active, the
retained tree lays out in its authored canvas and Draw scopes a uniform
scale onto TextRenderer.CanvasScale; the mouse entry points apply the
exact inverse so MouseX/MouseY and every hit test live in canvas space.
- TextRenderer.AppendQuad is the single emission chokepoint - sprites,
rects, AND glyphs scale together, including retail-authentic non-uniform
aspect distortion and stretched text. World-space HUD stays native (the
scale resets outside UiRoot.Draw).
- CharacterManagementUiController stops resizing Root to the viewport;
activate/deactivate/dispose set and clear the host canvas.
- UiDatElement returns to retail-pure copy-or-tile; the interim
StretchOwnBackgroundToFill flag is deleted.
- AD-98 updated to describe the completed substitution.
Tests: canvas-scale quad math, inverse input mapping (window click lands
on the canvas-space widget), degenerate-size guards, controller keeps
authored extent + sets/clears the canvas. App suite 5085/6 skips; live-DAT
char-select probes 3/3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
71bf24fb6f
commit
73041d7015
8 changed files with 277 additions and 106 deletions
|
|
@ -201,6 +201,23 @@ public sealed class TextRenderer : IDisposable
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Campaign LA gate round 2 (register AD-98): uniform canvas scale applied
|
||||
/// to every emitted quad — sprites, rects, AND glyphs — at the single
|
||||
/// emission chokepoint (<see cref="AppendQuad"/>). Retail renders its
|
||||
/// fixed-canvas pre-world screens (char select's authored 800×600, root
|
||||
/// 0x1000039A, zero edge anchors) at authored size and stretches the whole
|
||||
/// composed frame once at presentation; its UI blitter has no stretch mode
|
||||
/// at all (Graphic::Draw @0x00693b20 is copy-or-tile only). We have no
|
||||
/// present-time frame stretch, so the equivalent lives here: while a
|
||||
/// fixed-canvas screen is active, <see cref="UiRoot"/> sets this for the
|
||||
/// duration of its Draw and everything scales together — including retail's
|
||||
/// characteristic non-uniform aspect distortion and stretched glyphs.
|
||||
/// UVs and colors are untouched. Always reset to One outside UiRoot.Draw
|
||||
/// so the world-space HUD keeps native pixels.
|
||||
/// </summary>
|
||||
internal Vector2 CanvasScale = Vector2.One;
|
||||
|
||||
/// <summary>Begin a HUD pass. Call once per frame before any Draw* calls.</summary>
|
||||
public void Begin(Vector2 screenSize)
|
||||
{
|
||||
|
|
@ -388,10 +405,19 @@ public sealed class TextRenderer : IDisposable
|
|||
return ns;
|
||||
}
|
||||
|
||||
private static void AppendQuad(List<float> buf,
|
||||
private void AppendQuad(List<float> buf,
|
||||
float x, float y, float w, float h,
|
||||
float u0, float v0, float u1, float v1, Vector4 color)
|
||||
{
|
||||
// AD-98 canvas stretch — see CanvasScale's doc comment. Applied after
|
||||
// all canvas-space clipping, so geometry and UVs stay consistent.
|
||||
if (CanvasScale != Vector2.One)
|
||||
{
|
||||
x *= CanvasScale.X;
|
||||
y *= CanvasScale.Y;
|
||||
w *= CanvasScale.X;
|
||||
h *= CanvasScale.Y;
|
||||
}
|
||||
// Two triangles (6 verts). CCW in pixel space is clockwise in NDC
|
||||
// because the vertex shader flips Y, so OpenGL's default front-face
|
||||
// is GL_CCW — we rely on cull-face being disabled during HUD pass.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue