Camera-seat ranking window LIVE: the 1995 broadcast overlay reimplemented

The stubbed dpl-instance ranking display is reborn as screen-space
quads in CameraShipHUDRenderable::Render:
  - followed-player callsign banner (bottom center; the old direct
    index was correct -- Execute already converts to the 0-based
    texture slot)
  - the RANKING WINDOW: one row per scoring player, [ordinal][callsign]
    in rank order right of center; visibility = the Director's
    authentic flash logic (10s on / 15s off, solid final 30s); rows
    follow LIVE playerRank pointers so they re-sort as scores change
  - discovery: each 128x32 ordinal bitmap packs TWO ordinals side by
    side ('1st|2nd', '3rd|4th' -- why 4 bitmaps serve 8 players);
    draw = texture rank/2 with a u-half selected by rank parity
  - alpha-blended A4R4G4B4 white-on-transparent textures x green
    diffuse = the authentic green look

BT_SHOT moved AFTER the 2D pass -- it captured the backbuffer pre-HUD,
so overlays were on screen but invisible to screenshots (cost one
false debugging round).  GetOrdinalTexture accessor added.

Screenshot-verified: '1st MAVERICK' standings + MAVERICK banner over
live auto-directed coverage; 2-node mech smoke PASS (un-regressed;
the new render path only executes when a CameraDirector HUD exists).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-18 16:32:23 -05:00
co-authored by Claude Fable 5
parent 4459262b9c
commit 0a77d8e54b
5 changed files with 214 additions and 95 deletions
+31 -28
View File
@@ -7431,6 +7431,9 @@ void
Check_Pointer(display_rank_window);
mCamShipHUD = new CameraShipHUDRenderable(entity, CameraShipHUDRenderable::Dynamic, player_index, display_rank_window);
if (getenv("BT_CAM_LOG"))
DEBUG_STREAM << "[cam] CameraShipHUDRenderable created\n"
<< std::flush;
}
break;
}
@@ -8518,34 +8521,6 @@ void DPLRenderer::ExecuteImplementation(RendererComplexity, RendererOrigin::Inte
BTDrawTranslocationSpheres(mDevice, &viewTransform, (float)dT, mTargetRenderTime);
}
// DIAG (off by default): BT_SHOT=<path> dumps this instance's backbuffer (the rendered
// WORLD, before the 2D HUD overlay) to a PNG once ~180 frames in, for non-disruptive
// per-instance frame capture without foregrounding the window. Each instance sets its
// own path. Built for the -net render glitch (task #53) but general.
{
const char *shotPath = getenv("BT_SHOT");
if (shotPath)
{
static int s_btShotN = 0;
++s_btShotN;
// dump (overwriting) every 90 frames once past 90, so the file always holds a
// recent frame regardless of load timing / debug fps.
if (s_btShotN >= 90 && (s_btShotN % 90) == 0)
{
IDirect3DSurface9 *bb = 0;
if (SUCCEEDED(mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb)) && bb)
{
HRESULT hr = D3DXSaveSurfaceToFileA(shotPath, D3DXIFF_PNG, bb, 0, 0);
bb->Release();
DEBUG_STREAM << "[btshot] frame " << s_btShotN << " -> " << shotPath
<< " hr=0x" << std::hex << (unsigned)hr << std::dec << "\n" << std::flush;
}
else
DEBUG_STREAM << "[btshot] GetBackBuffer FAILED frame " << s_btShotN << "\n" << std::flush;
}
}
}
// The BT targeting reticle / weapon pips (2D screen space, cockpit view
// only -- the dpl2d layer; see game/reconstructed/dpl2d.cpp).
{
@@ -8588,6 +8563,34 @@ void DPLRenderer::ExecuteImplementation(RendererComplexity, RendererOrigin::Inte
if (mCamShipHUD)
mCamShipHUD->Render(0, &viewTransform);
// DIAG (off by default): BT_SHOT=<path> dumps this instance's backbuffer to a
// PNG every 90 frames -- non-disruptive per-instance frame capture without
// foregrounding the window. Built for the -net render glitch (task #53);
// moved AFTER the 2D pass (2026-07-18, camera-seat bring-up) so captures
// include the HUD overlays (reticle, camera-ship ranking window) the screen
// actually shows.
{
const char *shotPath = getenv("BT_SHOT");
if (shotPath)
{
static int s_btShotN = 0;
++s_btShotN;
if (s_btShotN >= 90 && (s_btShotN % 90) == 0)
{
IDirect3DSurface9 *bb = 0;
if (SUCCEEDED(mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb)) && bb)
{
HRESULT hr = D3DXSaveSurfaceToFileA(shotPath, D3DXIFF_PNG, bb, 0, 0);
bb->Release();
DEBUG_STREAM << "[btshot] frame " << s_btShotN << " -> " << shotPath
<< " hr=0x" << std::hex << (unsigned)hr << std::dec << "\n" << std::flush;
}
else
DEBUG_STREAM << "[btshot] GetBackBuffer FAILED frame " << s_btShotN << "\n" << std::flush;
}
}
}
// DEV-COMPOSITE: in DOCKED mode (BT_DEV_GAUGES_DOCK) blit the 6-surface gauge panel
// into this window as the LAST draw before EndScene (no-op otherwise / off pod).
extern void BTDrawGaugeInset(LPDIRECT3DDEVICE9 device);