platform profile + gauge dev-composite (Milestone A: gauge renderer woken)
PLATFORM PROFILE (-platform pod|dev / BT_PLATFORM / run.cmd pod; default dev): an env-preset selector, NOT a code fork -- it picks which environment the existing video/gauge/input code reads. dev = single 800x600 window + keyboard (the working build); pod = RIO input + (on real hardware) the multi-surface gauges/MFDs, mirroring content/SETENV.BAT (the pod path -- FindBestAdapterIndices / SVGA16 -- is left untouched). The multi-surface needs the pod's 2 video cards, so -platform pod does NOT auto-enable L4GAUGE on a dev box (stays bootable, single-window). Also fixes a real engine bug: SVGA16::BuildWindows PostQuitMessage'd on a CreateDevice failure but fell through to a null-device deref (segfault) -- now breaks (inert on the pod). GAUGE DEV-COMPOSITE, Milestone A (option B; opt-in BT_DEV_GAUGES, default OFF): wake the (dormant) gauge renderer so its CPU-rastered pixelBuffer can later be composited into the dev window, WITHOUT touching the pod SVGA16 output path. SVGA16 does no per-surface D3D in this mode (a DevGaugeComposite() gate forces the no-surface path + short-circuits Update/Refresh). Waking the never-exercised gauge subsystem exposed 4 latent reconstruction bugs, each guarded: SVGA16::Update / Refresh (empty mSurfaces[]), LBE4ControlsManager::MakeLinkedLamp (NULL lamp manager), L4GaugeRenderer::NotifyOfNewInterestingEntity (garbage warehouse chain). It now boots STABLY; the gauge reconstruction is incomplete (shadowed lamp-manager + warehouse members) -- Milestone B (the composite pass) will reveal whether the content is real. See docs/GAUGE_COMPOSITE.md. Verified: default DEV un-regressed (combat DESTROYED, 0 crashes); pod path untouched; BT_DEV_GAUGES boots stable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8b36440d05
commit
c13e72d0ba
@@ -98,6 +98,17 @@
|
||||
// );
|
||||
|
||||
|
||||
// DEV-COMPOSITE (option B): opt-in via BT_DEV_GAUGES. When set, SVGA16 does NO
|
||||
// per-surface D3D output (no per-adapter devices/windows/present) -- it only holds
|
||||
// the CPU pixelBuffer the gauge widgets raster into; the MAIN renderer composites
|
||||
// that buffer as a window inset. The pod multi-surface path is left untouched.
|
||||
static bool DevGaugeComposite()
|
||||
{
|
||||
static int v = -1;
|
||||
if (v < 0) v = (getenv("BT_DEV_GAUGES") != NULL) ? 1 : 0;
|
||||
return v != 0;
|
||||
}
|
||||
|
||||
void SVGA16::BuildWindows(unsigned int width, unsigned int height, bool windowed, int *secondaryIndex, int *aux1Index, int *aux2Index)
|
||||
{
|
||||
NUMGAUGEWINDOWS = 0;
|
||||
@@ -117,8 +128,22 @@ void SVGA16::BuildWindows(unsigned int width, unsigned int height, bool windowed
|
||||
NUMGAUGEWINDOWS++;
|
||||
}
|
||||
|
||||
if (DevGaugeComposite())
|
||||
{
|
||||
// DEV COMPOSITE (option B): force the "no D3D output surfaces" path. Do NOT
|
||||
// create per-surface devices/windows -- FindBestAdapterIndices hands us the
|
||||
// primary adapter (up to 3x) on a dev box, but a 2nd/3rd fullscreen device
|
||||
// can't be created there. The base Video16BitBuffered pixelBuffer still
|
||||
// exists and the widgets raster into it; the main renderer composites it.
|
||||
NUMGAUGEWINDOWS = 0;
|
||||
}
|
||||
|
||||
if (NUMGAUGEWINDOWS == 0)
|
||||
{
|
||||
// (defensive) NULL the per-surface arrays so ~SVGA16 delete[] is safe on the
|
||||
// no-surface path (they are not allocated below).
|
||||
gaugeWindows = NULL; mDevice = NULL; mVertBuffers = NULL;
|
||||
mSurfaces = NULL; mLockFlags = NULL; mPresentParams = NULL; mSurfaceRects = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,6 +227,15 @@ void SVGA16::BuildWindows(unsigned int width, unsigned int height, bool windowed
|
||||
{
|
||||
DEBUG_STREAM<<"Couldn't create Direct3D device!"<<std::endl<<std::flush;
|
||||
PostQuitMessage(1);
|
||||
// GUARD (platform profile): mDevice[j] is null/uninitialised on
|
||||
// failure, and the code below (GetDeviceCaps @next line, CreateTexture,
|
||||
// CreateVertexBuffer) derefs it -> segfault. This is hit when the POD
|
||||
// profile runs on a box WITHOUT the pod's extra adapters/monitors (a
|
||||
// second fullscreen gauge device can't be created). PostQuitMessage
|
||||
// already asked to bail; break so we exit the surface loop cleanly
|
||||
// instead of crashing. INERT on real pod hardware (CreateDevice
|
||||
// succeeds there) -- does not change the pod multi-surface behavior.
|
||||
break;
|
||||
}
|
||||
|
||||
D3DCAPS9 caps;
|
||||
@@ -4040,6 +4074,13 @@ Logical SVGA16::Update(Logical forceAll)
|
||||
return False; // Do no more!
|
||||
}
|
||||
|
||||
// DEV-COMPOSITE GUARD (option B): dev-composite SVGA16 does NO per-surface D3D
|
||||
// (BuildWindows forced NUMGAUGEWINDOWS=0 + allocated nothing); the mSurfaces[0]
|
||||
// path below would index an absent array. The main renderer composites the shared
|
||||
// CPU pixelBuffer as a window inset instead. Inert on the pod.
|
||||
if (DevGaugeComposite() || NUMGAUGEWINDOWS <= 0)
|
||||
return False;
|
||||
|
||||
if (++mDisplayToUpdate >= NUMGAUGEWINDOWS)
|
||||
mDisplayToUpdate = 0;
|
||||
|
||||
@@ -4221,6 +4262,12 @@ Logical SVGA16::Update(Logical forceAll)
|
||||
|
||||
void SVGA16::Refresh()
|
||||
{
|
||||
// DEV-COMPOSITE GUARD (option B): dev-composite does NO per-surface D3D; skip the
|
||||
// per-surface clear/present (the main renderer composites the CPU pixelBuffer
|
||||
// inset). Inert on the pod.
|
||||
if (DevGaugeComposite() || NUMGAUGEWINDOWS <= 0)
|
||||
return;
|
||||
|
||||
HRESULT hr;
|
||||
V( mDevice[mDisplayToUpdate]->Clear(0, NULL, D3DCLEAR_TARGET, 0xFF000000, 1.0f, 0) );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user