mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-28 10:59:16 -04:00
72196d3dc9
The thirds anchor is chosen per union-find run, and runs only joined when the group key matched within JOIN_GAP. That key folds CLUT, texpage, a 24px Y band and the poly-vs-rect family together, so a digit and the box it is drawn on could never land in the same run. They got independent anchors and were squashed about different points, which pulls one piece of a readout toward a screen edge and leaves the rest behind -- worse the wider the frame. On WipEout 3's race HUD at 32:9 the lap readout draws its digits at y=[219,227] x=[137,202] and the box they label at y=[228,244] x=[138,202]. The digits anchored left, the box anchored centre, and the box landed about 500 screen pixels from the digits it belongs to. Join on being one visual element as well as on the key: share screen columns and touch vertically within STACK_GAP. Both halves are needed. Column overlap alone merged the top-left lap counter with the bottom-left lap timer 200 scanlines below, and since union is transitive that chained all 71 HUD primitives into one run spanning the full width, which anchors centre and drags the corners inward. A strict row intersection missed the stacked case above, whose seam is one pixel. WsUiGroupItem carries y/height for this; the anchor stays horizontal. After: 9 runs, bottom-left readout whole and anchored left, timer and energy bar right, speed centre -- matching the 4:3 layout. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
55 lines
2.0 KiB
C
55 lines
2.0 KiB
C
#ifndef PSXRECOMP_WS_UI_GROUP_H
|
|
#define PSXRECOMP_WS_UI_GROUP_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define WS_UI_GROUP_JOIN_GAP 24
|
|
|
|
/* Vertical slack, in scanlines, still counted as "stacked on" rather than
|
|
* "somewhere else on screen". A readout drawn as a label directly above its
|
|
* box leaves a one-pixel seam; the nearest thing that must NOT join is the
|
|
* other end of the screen, ~200 scanlines away. */
|
|
#define WS_UI_GROUP_STACK_GAP 4
|
|
|
|
typedef struct {
|
|
uint32_t key;
|
|
int32_t x;
|
|
int32_t width;
|
|
/* Vertical extent, needed to tell "drawn on top of each other" (one visual
|
|
* element) from "happens to share screen columns" (the top-left lap counter
|
|
* and the bottom-left lap timer). Grouping only ever produces a HORIZONTAL
|
|
* anchor, but deciding the grouping is a 2-D question. */
|
|
int32_t y;
|
|
int32_t height;
|
|
int32_t anchor;
|
|
/* Diagnostic only: index of the union-find representative this item
|
|
* merged into, so an observer can tell "these two share an anchor because
|
|
* they are one run" from "these two happen to land on the same third".
|
|
* Anchor equality cannot distinguish those — there are only three anchor
|
|
* values — and that distinction is the whole question when a HUD element
|
|
* splits apart under the squash. Written by ws_ui_group_assign; never read
|
|
* by the transform path. */
|
|
uint32_t root;
|
|
} WsUiGroupItem;
|
|
|
|
/* Assign one thirds anchor to each complete spatial run. Items with the same
|
|
* texture/row key join when their horizontal intervals touch or are separated
|
|
* by at most WS_UI_GROUP_JOIN_GAP pixels. This is intentionally a whole-frame
|
|
* operation: animated text is coherent on its first frame, not one frame late. */
|
|
void ws_ui_group_assign(WsUiGroupItem *items, size_t count,
|
|
int32_t display_width, int dense_menu);
|
|
|
|
int32_t ws_ui_anchor_for_bounds(int32_t x, int32_t width,
|
|
int32_t display_width);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|