D335: native widescreen, HUD + front end (Option B Phase 3)

HUD elements now keep 4:3 proportions via fast3d's EXT aspect modes (the PD
pattern): watch, gauge bars, messages/title card, upper text and countdown
CENTER; ammo RIGHT (right hand) / LEFT (left hand). The front end is
pillarboxed (whole menu_jump_constructor_handler CENTER) and the menu
pointer is mapped into the pillarbox. port/include/hudaspect.h emits only
when native widescreen is on and the window is wider than 4:3, so 4:3 and
native-off stay byte-identical. Rule-2 approved.

Verified with 16:9/21:9 captures (HUD, watch, title card, legal, file
select, gun barrel); golden 3/3; Win + Linux builds. Gun-barrel circle
leaks into the bars while sliding in -> GRAPHICS-BACKLOG D335a.
This commit is contained in:
James Dansereau committed 2026-09-23 14:56:29 -04:00
1 parent d5d9a36a6f
commit f62bceaf88
8 files changed
+144

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
#ifndef _HUDASPECT_H_
#define _HUDASPECT_H_
/* D335 (WIDESCREEN-FOV-PLAN Option B, Phase 3): HUD alignment under native
* widescreen (D334). The world is projected at the window aspect, but 2D/HUD
* elements are laid out in the game's 4:3 logical canvas, which fast3d
* stretches to the window. Wrapping a HUD draw in an aspect mode makes fast3d
* map its x undistorted (x scaled by (4/3)/window_aspect) and anchor it to
* the left edge, the right edge, or the centre -- the PD port's
* G_ASPECT_{LEFT,RIGHT,CENTER}_EXT extra-geometry-mode, which GE's fast3d
* already decodes (gfx_pc.cpp gfx_sp_extra_geometry_mode /
* gfx_update_aspect_mode). Game-includable: no SDL, no fast3d headers.
*
* PORT_HUD_ASPECT emits only while native widescreen is on and the window is
* wider than 4:3; otherwise the display list is byte-identical to before. */
#define GE_HUD_ASPECT_NONE 0x00u
#define GE_HUD_ASPECT_LEFT 0x10u /* G_ASPECT_LEFT_EXT (port/fast3d/gbiex.h) */
#define GE_HUD_ASPECT_RIGHT 0x20u /* G_ASPECT_RIGHT_EXT */
#define GE_HUD_ASPECT_CENTER 0x30u /* G_ASPECT_CENTER_EXT */
#define GE_HUD_ASPECT_MASK 0x70u /* G_ASPECT_MODE_EXT */
#define GE_EXTRAGEOMETRYMODE_EXT 0x3a /* G_EXTRAGEOMETRYMODE_EXT */
/* The decoder does extra_mode = (extra_mode & ~clear) | set with
* clear = ~(w0 & 0xFFFFFF): passing ~MASK as the low 24 bits clears exactly
* the aspect bits and leaves the other extra-geometry flags alone. */
#define gSPHudAspectEXT(pkt, mode) \
gDma0p((pkt), GE_EXTRAGEOMETRYMODE_EXT, (mode), ((~GE_HUD_ASPECT_MASK) & 0xFFFFFFu))
extern float portNativeAspect(void); /* port/src/video.c */
/* Only for windows wider than 4:3: in a narrower window a centred 4:3 HUD
* would be wider than the window and crop, so there the HUD keeps the canvas
* mapping (squeezed, never cropped). 1.3334 so exact 4:3 emits nothing. */
#define PORT_HUD_ASPECT(gdl, mode) \
do { if (portNativeAspect() > 1.3334f) { gSPHudAspectEXT((gdl)++, (mode)); } } while (0)
#endif
+12
View File
@@ -1052,6 +1052,18 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
}
if (mx != lastMenuMouseX || my != lastMenuMouseY) {
double fx = (double)mx / (double)ww;
/* D335: under native widescreen the front end is
* pillarboxed to a centred 4:3 region
* (front.c menu_jump_constructor_handler), so map
* the pointer across that region, not the window. */
{
extern f32 portNativeAspect(void);
f32 na = portNativeAspect();
if (na > (4.0f / 3.0f)) {
double vis = (4.0 / 3.0) / (double)na; /* visible width fraction */
fx = (fx - (1.0 - vis) * 0.5) / vis;
}
}
double fy = (double)my / (double)wh;
if (fx < 0.0) fx = 0.0; else if (fx > 1.0) fx = 1.0;
if (fy < 0.0) fy = 0.0; else if (fy > 1.0) fy = 1.0;