Gitea #44: the reticle TARGET NAME PLATE (PNAME1-8) -- the target's callsign under the crosshair
Reconstructed the last deferred piece of the 1995 reticle, decoded from the Execute disassembly @004cdcf0 [T1]: - selection: target_mech+0x190 (owning BTPlayer) -> player+0x1e0 (playerBitmapIndex), 1-based into the mesh table at this+0x2e8 - placement: re-placed every frame the aim moves -- scale 0.12 uniform, translate (K*retPos.x, K*retPos.y - 0.08, -1.0), K = 1/2.8 (the x87 long double @0x4cee64) -- so the label TRACKS THE AIM POINT, not screen centre - visibility: the LOCK attribute (this+0x184, cached +0x188) AND an owning player; reticle-off / simple-X also hide it - art: the plate quad UV-addresses a shared 128x64 bitslice texmap whose texels the pod OVERWROTE each mission with the egg's callsign rasters (original source commented out at L4VIDEO.cpp:5682-5710) -- the baked 'PLAYER n' art in BMAP.BSL is only the shipped fallback. Material colour is a neutral (0.5,0.5,0.5): grey-white, not phosphor green. Port: same geometry in reticle units (0.224 below the aim point, 0.336x0.084) drawn as the target's egg callsign texture through the reticle's own MapX/MapY mapping, so it follows the world view in every layout and BT_SHOT captures it. New: dpl2d_DrawTexturedRect, BTReticleTargetPlate, BTGetPlayerNameTexture. Also: kRetCaret corrected 0.02f -> 0.025f (_DAT_004cd7f4 read from the binary; the old value was a T3 guess, 20% small). KB: gauges-hud + open-questions corrected (the chain was filed as deferred and mis-attributed to 'the 3D marker'); TWO PNAME consumers now distinguished (this plate, and CameraShipHUDRenderable's ranking window which shipped 2026-07-18); new bgf-format section on the plate atlas. Rig-verified: 2-node relay, BT_GOTO=enemy -> '[hud] name plate: bmp=2 tex=1' and 'Boreas' rendered under the crosshair on the locked target. Solo clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0166KTsC7ADm7VXEi1HF1jNg
This commit is contained in:
co-authored by
Claude Opus 5
parent
b7107b1020
commit
35c750dc7c
@@ -1386,7 +1386,9 @@ static const float kRetTickMajor = 0.016f; // [0x82]
|
||||
static const float kRetBotX = -0.25f; // [0x84] bottom heading-ladder x0
|
||||
static const float kRetBotY = 0.35f; // [0x85] heading ladder y
|
||||
static const float kRetBotSpan = 0.5f; // [0x86]
|
||||
static const float kRetCaret = 0.02f; // _DAT_004cd7f4 (caret triangle size) [T3]
|
||||
static const float kRetCaret = 0.025f; // _DAT_004cd7f4 (caret triangle size)
|
||||
// [T1] read from the binary 2026-07-24
|
||||
// (was a 0.02f guess -- 20% small)
|
||||
static const int kRetTicksR = 13; // [9] right ladder tick count
|
||||
static const int kRetTicksB = 21; // [0xb] bottom ladder tick count
|
||||
static const float kRetMaxRange = 1200.0f; // ctor param 11 (0x44960000)
|
||||
@@ -1789,9 +1791,10 @@ void
|
||||
|
||||
// the LOCK RING [0xb7] + its SPIN [0x9d] (Execute @4cebf9-4cee54 [T1]):
|
||||
// while a target is locked the ring+cross (subB9) draws at the reticle
|
||||
// frame centre, spinning 4 degrees per frame; unlocked it clears. (The
|
||||
// binary also hangs the PNAMEx.bgf player-name mesh on the 3D marker here
|
||||
// -- the 3D marker chain remains deferred.)
|
||||
// frame centre, spinning 4 degrees per frame; unlocked it clears. The SAME
|
||||
// lock-change block drives the PNAMEx.bgf player NAME PLATE (the target's
|
||||
// callsign under the crosshair) -- reconstructed at the end of this
|
||||
// function, no longer deferred.
|
||||
{
|
||||
extern int gBTHudLockState;
|
||||
const int locked = (gBTHudLockState == 2); // the Lock attr rule, not just a target
|
||||
@@ -1856,6 +1859,93 @@ void
|
||||
extern int gBTHudPrimary;
|
||||
dpl2d_ExecuteList(gBTHudPrimary ? masterList : simpleXList, device);
|
||||
}
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// THE TARGET NAME PLATE (PNAME1-8.bgf) -- the floating callsign under the
|
||||
// crosshair. Reconstructed from the reticle Execute disassembly
|
||||
// (reference/decomp/reticle_execute_004cdcf0.disasm.txt) [T1]:
|
||||
//
|
||||
// @004cdede, every frame while the full HUD is up:
|
||||
// dpl_IdentityDCS (plate);
|
||||
// dpl_ScaleDCS (plate, 0.12f, 0.12f, 0.12f);
|
||||
// dpl_TranslateDCS(plate, K*reticlePos.x + -0.0f,
|
||||
// K*reticlePos.y + -0.08f, -1.0f);
|
||||
// dpl_FlushDCS (plate);
|
||||
// K = the x87 long double @0x4cee64 = 0.35714286 = 1/2.8 -- the SAME
|
||||
// 2.8 projection constant the hotbox uses, i.e. K converts the reticle's
|
||||
// -1..+1 screen space into eye-space extents at z = -1.
|
||||
// @004cec98: the plate's MESH is the target player's (see
|
||||
// BTReticleTargetPlate in mech4.cpp), visibility 1; no owning player
|
||||
// -> visibility 0.
|
||||
// @004cdd75 / @004cddc1: reticle Off, or On-but-simple-X (PrimaryHudOn
|
||||
// clear) -> visibility 0 and the cached target cleared.
|
||||
// @004cebf9-@004cec47 -- THE LOCK GATE: the block is entered on a change
|
||||
// of EITHER the target (Reticle+0x1c) or the LOCK attribute (the
|
||||
// Scalar* at this+0x184, cached at +0x188), and when that lock value
|
||||
// reads 0 it branches to the hide path (@004ced87). So the plate needs
|
||||
// a real fire-control LOCK, not merely something under the crosshair --
|
||||
// the same `gBTHudLockState == 2` rule the lock RING uses below.
|
||||
//
|
||||
// So the plate TRACKS THE AIM POINT (it is not fixed under screen centre),
|
||||
// sits 0.08 eye-space units below it, and shows the TARGET'S CALLSIGN.
|
||||
//
|
||||
// PORT: identical placement expressed in reticle units -- dividing the
|
||||
// eye-space offsets by K (i.e. x2.8) puts the plate centre at
|
||||
// (reticlePos.x, reticlePos.y +/- 0.08*2.8 = 0.224)
|
||||
// spanning the plate quad's own 1.0 x 0.25 extents (content/VIDEO/GEO/
|
||||
// PNAME1.BGF, verified) scaled by 0.12 and back-converted: 0.336 x 0.084.
|
||||
// The art is the player's callsign raster, exactly as the 1995 plate's
|
||||
// `bmap:name12_mtl` material supplied it -- here the egg's 128x32 name
|
||||
// texture (4:1 == the quad's aspect) via BTGetPlayerNameTexture.
|
||||
//
|
||||
{
|
||||
extern int gBTHudPrimary;
|
||||
extern int gBTHudLockState; // 2 == authentic LOCK
|
||||
extern int BTReticleTargetPlate(void); // mech4.cpp
|
||||
extern void *BTGetPlayerNameTexture(int index0); // L4VIDEO.cpp
|
||||
extern void dpl2d_DrawTexturedRect(struct IDirect3DDevice9 *device,
|
||||
void *texture, float cx, float cy, float w, float h,
|
||||
unsigned long argb);
|
||||
extern float gBTAimX, gBTAimY;
|
||||
|
||||
const float kPlateScale = 0.12f; // dpl_ScaleDCS, uniform
|
||||
const float kPlateW = 1.0f; // the PNAMEx quad's x extent
|
||||
const float kPlateH = 0.25f; // ... and its y extent (4:1)
|
||||
const float kInvK = 2.8f; // 1/K -- eye-space -> reticle
|
||||
const float kPlateDY = 0.08f * kInvK; // = 0.224 below the aim point
|
||||
// The plate's own material colour: content/VIDEO/MAT/BMAP.BMF gives
|
||||
// `name12_mtl` (and each sibling) a NEUTRAL (0.5, 0.5, 0.5) -- the pod's
|
||||
// plate is a grey-white label, NOT phosphor green like the reticle
|
||||
// glyphs. 0.5 * 255 = 128.
|
||||
const unsigned long kPlateARGB = 0xFF808080;
|
||||
|
||||
const int plate = (gBTHudPrimary && gBTHudLockState == 2)
|
||||
? BTReticleTargetPlate() : 0;
|
||||
if (plate > 0)
|
||||
{
|
||||
void *texture = BTGetPlayerNameTexture(plate - 1);
|
||||
if (texture != 0)
|
||||
{
|
||||
// reticle y is +DOWN on screen (dpl2d MapY), eye-space y is
|
||||
// +UP, so the binary's -0.08 eye offset is +kPlateDY here.
|
||||
dpl2d_DrawTexturedRect(device, texture,
|
||||
gBTAimX, gBTAimY + kPlateDY,
|
||||
kPlateW * kPlateScale * kInvK,
|
||||
kPlateH * kPlateScale * kInvK,
|
||||
kPlateARGB);
|
||||
}
|
||||
if (getenv("BT_HUD_LOG"))
|
||||
{
|
||||
static int s_plog = 0;
|
||||
if ((s_plog++ % 120) == 0)
|
||||
DEBUG_STREAM << "[hud] name plate: bmp=" << plate
|
||||
<< " tex=" << (texture != 0)
|
||||
<< " at (" << gBTAimX << "," << (gBTAimY + kPlateDY)
|
||||
<< ")\n" << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user