Cockpit: 1920x1080 single-window MFD arrangement (L4MFDSPLIT=1, RP412 layout)
The RP412 single-window cockpit, adapted to reuse BT's working D3D
surface compositor (DrawDevSurface) instead of RP's GDI child-window
panes -- same visual outcome, far lower risk (no L4VIDEO present-routing
rewrite):
- L4VB16.cpp: kBTCockpitSurfaces places the six instrument surfaces at
RP412's exact 1920x1080 fractional positions (Heat=UL, Mfd2=UC,
Comm=UR, Mfd1=LL, Mfd3=LR, radar=center-bottom portrait);
BTDrawGaugeSurfaces parameterized by surface table; BTDrawCockpitPanel
composites them over the full-window 3D as the pod bezels frame the
viewscreen. Hooked in L4VIDEO before EndScene (L4MFDSPLIT-gated).
- btl4main.cpp: L4MFDSPLIT sizes the window to the 1920x1080 canvas
(scaled to fit the work area; -res overrides) and wakes the gauge
renderer (L4GAUGE) + PAD controls.
Fixed two more pre-existing latent gauge crashes that only fire when the
gauge renderer is woken off-pod (would hit the real pod too), previously
gated only on BT_DEV_GAUGES -- extended the safety nets to L4MFDSPLIT:
* gauge.h: NULL gauge-attribute-source binds a static zero instead of
AV'ing in GaugeConnectionDirectOf ctor (crashed building HeatSink
cluster's VertTwoPartBar at ConfigureForModel).
* GAUGE.cpp: SEH-guarded gauge Execute (disable a faulting gauge, not
crash). GAUGREND.cpp: skip unresolved primitives + activate all MFD
pages so every surface renders.
Verified: L4MFDSPLIT boots the cockpit; all six surfaces render framing
the 3D viewscreen; survives coolant-loop + gauge activation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -575,7 +575,8 @@ Logical
|
||||
// BT_DEV_GAUGES; the pod build calls Execute() directly.
|
||||
static int s_devGaugesUpd = -1;
|
||||
if (s_devGaugesUpd < 0)
|
||||
s_devGaugesUpd = (getenv("BT_DEV_GAUGES") != NULL) ? 1 : 0;
|
||||
s_devGaugesUpd = (getenv("BT_DEV_GAUGES") != NULL ||
|
||||
getenv("L4MFDSPLIT") != NULL) ? 1 : 0;
|
||||
if (s_devGaugesUpd)
|
||||
{
|
||||
if (!GuardedExecute())
|
||||
|
||||
@@ -1347,7 +1347,7 @@ void
|
||||
// widgets). Gated on BT_DEV_GAUGES so the POD path keeps the
|
||||
// strict Fail (it needs a complete, real method table).
|
||||
//
|
||||
if (getenv("BT_DEV_GAUGES") != NULL)
|
||||
if (getenv("BT_DEV_GAUGES") != NULL || getenv("L4MFDSPLIT") != NULL)
|
||||
{
|
||||
if (getenv("BT_GAUGE_SKIP_LOG"))
|
||||
DEBUG_STREAM << "[gskip] unresolved primitive '"
|
||||
@@ -3689,7 +3689,8 @@ void
|
||||
{
|
||||
static int s_devAllPages = -1;
|
||||
if (s_devAllPages < 0)
|
||||
s_devAllPages = (getenv("BT_DEV_GAUGES") != NULL) ? 1 : 0;
|
||||
s_devAllPages = (getenv("BT_DEV_GAUGES") != NULL ||
|
||||
getenv("L4MFDSPLIT") != NULL) ? 1 : 0;
|
||||
if (s_devAllPages)
|
||||
current_mode_mask |= (ModeMask)0x7FFF;
|
||||
}
|
||||
|
||||
@@ -299,14 +299,51 @@ static const BTGaugeSurfaceDesc kBTGaugeSurfaces[6] =
|
||||
{ "Comm", 0xFFFF, 1000.0f / kBTPanelW, 0.0f, 320.0f / kBTPanelW, 0.5f, 0 },
|
||||
};
|
||||
|
||||
//
|
||||
// SINGLE-WINDOW COCKPIT (L4MFDSPLIT=1) -- the RP412 arrangement: the 3D
|
||||
// viewscreen fills the whole window and the six instrument surfaces frame it
|
||||
// like the pod's bezels (they occlude the corners of the main display by
|
||||
// design). Positions are fractions of a 1920x1080 canvas, matching RP412's
|
||||
// SVGA16 split layout (top row of three MFDs, bottom corners, radar centered
|
||||
// on the bottom edge):
|
||||
// [ Heat ][ ][ Mfd2 ][ ][ Comm ] <- top row (3D shows between)
|
||||
// [ Mfd1 ] [ radar (portrait) ] [ Mfd3 ]
|
||||
// BT's five mono MFDs + the palette radar map onto RP's UL/UC/UR/LL/LR + map.
|
||||
//
|
||||
static const float kMfdW = 320.0f / 1920.0f; // 0.16667
|
||||
static const float kMfdH = 240.0f / 1080.0f; // 0.22222
|
||||
static const float kRadW = 324.0f / 1920.0f; // 0.16875
|
||||
static const float kRadH = 432.0f / 1080.0f; // 0.40000
|
||||
static const BTGaugeSurfaceDesc kBTCockpitSurfaces[6] =
|
||||
{
|
||||
{ "Heat", 0xFFFF, 0.0f, 0.0f, kMfdW, kMfdH, 0 }, // UL
|
||||
{ "Mfd2", 0xFFFF, (1.0f - kMfdW) * 0.5f, 0.0f, kMfdW, kMfdH, 0 }, // UC
|
||||
{ "Comm", 0xFFFF, 1.0f - kMfdW, 0.0f, kMfdW, kMfdH, 0 }, // UR
|
||||
{ "Mfd1", 0xFFFF, 0.0f, 1.0f - kMfdH, kMfdW, kMfdH, 0 }, // LL
|
||||
{ "Mfd3", 0xFFFF, 1.0f - kMfdW, 1.0f - kMfdH, kMfdW, kMfdH, 0 }, // LR
|
||||
{ "sec", -1, (1.0f - kRadW) * 0.5f, 1.0f - kRadH, kRadW, kRadH, 1 }, // radar, bottom center
|
||||
};
|
||||
|
||||
// L4MFDSPLIT: the single-window cockpit (RP412's flag). Distinct from the
|
||||
// dev-gauge dock (BT_DEV_GAUGES) -- here the 3D fills the window and the
|
||||
// surfaces frame it, rather than a strip below a restricted world viewport.
|
||||
static bool DevCockpitPanel()
|
||||
{
|
||||
static int v = -1;
|
||||
if (v < 0) v = (getenv("L4MFDSPLIT") != NULL) ? 1 : 0;
|
||||
return v != 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Composite ALL SIX gauge surfaces into the CURRENT render target, tiled within the
|
||||
// panel rect (px,py,pw,ph). Reaches the ONE shared SVGA16 via any resolvable port and
|
||||
// extracts each surface by its own bit-plane mask. Ports that don't resolve are skipped.
|
||||
//
|
||||
void BTDrawGaugeSurfaces(LPDIRECT3DDEVICE9 device, float px, float py, float pw, float ph)
|
||||
void BTDrawGaugeSurfaces(LPDIRECT3DDEVICE9 device, float px, float py, float pw, float ph,
|
||||
const BTGaugeSurfaceDesc *surfaces = 0)
|
||||
{
|
||||
if (device == NULL) return;
|
||||
if (surfaces == NULL) surfaces = kBTGaugeSurfaces;
|
||||
GaugeRenderer *gr = application ? application->GetGaugeRenderer() : NULL;
|
||||
if (gr == NULL) return;
|
||||
|
||||
@@ -347,7 +384,7 @@ void BTDrawGaugeSurfaces(LPDIRECT3DDEVICE9 device, float px, float py, float pw,
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
const BTGaugeSurfaceDesc &d = kBTGaugeSurfaces[i];
|
||||
const BTGaugeSurfaceDesc &d = surfaces[i];
|
||||
L4GraphicsPort *port = static_cast<L4GraphicsPort*>(gr->GetGraphicsPort(d.portName));
|
||||
if (port == NULL) continue; // this surface's port isn't configured -> skip
|
||||
// Secondary-CRT unrotation direction is env-flippable (BT_GAUGE_SEC_ROT=3
|
||||
@@ -406,6 +443,26 @@ void BTDrawGaugeInset(LPDIRECT3DDEVICE9 device)
|
||||
BTDrawGaugeSurfaces(device, 2.0f, 400.0f, 540.0f, 540.0f / 2.75f);
|
||||
}
|
||||
|
||||
//
|
||||
// SINGLE-WINDOW COCKPIT (L4MFDSPLIT=1): the 3D fills the whole window; frame
|
||||
// it with the six instrument surfaces at the RP412 arrangement (kBTCockpitSurfaces),
|
||||
// composited OVER the world as the last draw before EndScene. The world pass
|
||||
// runs at the FULL viewport in this mode (no strip carve-out), so the surfaces
|
||||
// occlude the corners like the pod bezels. Called from L4VIDEO alongside the
|
||||
// dev-gauge inset; the two modes are mutually exclusive.
|
||||
//
|
||||
void BTDrawCockpitPanel(LPDIRECT3DDEVICE9 device)
|
||||
{
|
||||
if (!DevCockpitPanel() || device == NULL) return;
|
||||
IDirect3DSurface9 *rt = NULL;
|
||||
if (FAILED(device->GetRenderTarget(0, &rt)) || rt == NULL) return;
|
||||
D3DSURFACE_DESC d;
|
||||
rt->GetDesc(&d);
|
||||
rt->Release();
|
||||
BTDrawGaugeSurfaces(device, 0.0f, 0.0f, (float)d.Width, (float)d.Height,
|
||||
kBTCockpitSurfaces);
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
// DEV-COMPOSITE -- the SEPARATE cockpit-MFD window (the default under BT_DEV_GAUGES).
|
||||
// A second top-level window fed by an ADDITIONAL SWAP CHAIN on the existing main
|
||||
|
||||
@@ -8560,6 +8560,11 @@ void DPLRenderer::ExecuteImplementation(RendererComplexity, RendererOrigin::Inte
|
||||
extern void BTDrawGaugeInset(LPDIRECT3DDEVICE9 device);
|
||||
BTDrawGaugeInset(mDevice);
|
||||
|
||||
// SINGLE-WINDOW COCKPIT (L4MFDSPLIT=1): frame the 3D with the six instrument
|
||||
// surfaces in the RP412 arrangement (no-op unless L4MFDSPLIT is set).
|
||||
extern void BTDrawCockpitPanel(LPDIRECT3DDEVICE9 device);
|
||||
BTDrawCockpitPanel(mDevice);
|
||||
|
||||
hr = mDevice->EndScene();
|
||||
|
||||
// DEV-COMPOSITE: default mode -- render the 6 cockpit surfaces into a SEPARATE window
|
||||
|
||||
Reference in New Issue
Block a user