Cameraship Map/Armor diagnostics: -tmr ladder, draw counter, CTCL type log

Investigating a field report that the cameraship secondary armor/score/map
screen showed its background BMP but no overlay graphics "on certain video
cards". The video card was a red herring: the machine was launched with
-ctcltype 2 (game pod) instead of 3 (cameraship), and the overlay block in
hudchat.cpp is gated on CTCL_GetType()==_ECTCL_CameraShip, so it never ran.

This is hard to spot because the two gates are independent. HSH_EnterFullScreen2
and CMR_Device open the screen and paint its background based purely on whether
a spare secondary monitor exists, and never consult the CTCL role. A wrong
-ctcltype therefore yields a screen that lights up, shows the correct artwork
and renders nothing, which is visually identical to a DirectDraw failure. The
same background-only screen also appears on a game pod when an MFD mode finds no
dual-head span and falls through to the single-secondary mr_device path.

Diagnostics added:

- render.cpp: log the CTCL type in gos-displays.txt from HSH_EnterFullScreen2,
  via the existing g_pfnCTCL_GetType hook so GameOS gains no game-code
  dependency. Always logged, and states in words whether overlays will be drawn.
- render.cpp/.hpp: CHSH_Device::m_nDrawCalls, incremented in DrawQuad,
  DrawThickFrame and DrawTexture, reset in CMR_Device::BeginScene and reported
  for the first 5 frames from CMR_Device::EndScene when -tmr is active. Zero
  draws proves the overlay code never ran; non-zero with a blank screen would
  mean it ran and drew invisibly. This distinction is what settled the case.
- render.cpp: log CMR_Device surface creation plus the overlay texture's
  dimensions, depth and channel masks.
- New -tmr <0-3> switch (MW4Application.cpp, documented in -help): 0 normal,
  1 background blit with DDBLTFAST_WAIT|DDBLTFAST_NOCOLORKEY, 2 Clear instead of
  the background blit, 3 as 2 plus alpha blending off and an untextured magenta
  DrawQuad.

Mode 3 drew magenta and mode 2 was pure black, which cleared the 3D device, the
flip and the background blit in two runs; the draw counter then reported 0 and
pointed straight at the gate. Documented as STEP 11 in CLAUDE.md, including the
field triage rule: read "CTCL type =" in gos-displays.txt before suspecting
drivers.

Co-authored-by: Claude Opus 5 (Anthropic) <noreply@anthropic.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
This commit is contained in:
2026-07-26 11:59:56 -05:00
co-authored by Claude Opus 5 GitHub Copilot
parent b40892910b
commit 24ce46ab6d
4 changed files with 177 additions and 5 deletions
@@ -98,6 +98,9 @@ extern int g_nFpsLog;
// [panelcoop] SetCooperativeLevel form used by the radar/MFD panels; 0 = legacy.
// Defined in CoreTech GameOS render.cpp.
extern int g_nHshCoopMode;
// [mrdiag] Cameraship secondary-screen (Map/Armor) diagnostic mode; 0 = normal.
// Defined in CoreTech GameOS render.cpp.
extern int g_nMRDiag;
extern LONG g_ThrottleDir;
extern bool g_bCanSuicideAllways;
extern bool g_f3dtarget;
@@ -881,6 +884,14 @@ static const char* const g_apszCommandLineHelp[] =
" panels never contend for it.",
" 5 = as 4, plus ALLOWREBOOT.",
" Results are reported in gos-displays.txt.",
" -tmr <0-3> Cameraship Map/Armor screen diagnostics.",
" 0 = normal.",
" 1 = wait for the background blit to finish before",
" drawing the overlays.",
" 2 = skip the background image entirely.",
" 3 = as 2, plus a solid magenta test rectangle.",
" Use when that screen shows its background but no",
" overlay graphics or text.",
" -mechview <1|2> Show the rotating mech view. 1 = on the radar",
" -mv <1|2> screen, 2 = on the main screen. Default: off.",
" -3dt Draw the MFD target as a live 3D model instead of",
@@ -1709,6 +1720,14 @@ int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int n
if ((0 <= n) && (n <= 5))
g_nHshCoopMode = n;
}
// [mrdiag] Cameraship Map/Armor screen diagnostics. 0 = normal behaviour.
token = strstr(all_lower, "-tmr ");
if (token && token[5])
{
int n = atoi(&token[5]);
if ((0 <= n) && (n <= 3))
g_nMRDiag = n;
}
// [fpslog] Enable the per-second frame pacing report written to gos-fps.txt.
g_nFpsLog = (strstr(all_lower, "-fps") != NULL) ? 1 : 0;
g_bCanSuicideAllways = (strstr(all_lower, "-suicide") != NULL);