Gitea #9: the upper-MFD PRESET pages (3 MFDs x 5) live -- SetPresetMode
table re-decoded to the ModeMFD bits + desktop J/K/L page cycle
The preset system was unwired by ONE defect in the message layer: the
SetPresetMode @004d1b24 table @0051dbf0 had been transcribed from the
section dump as BIG-endian dwords ({0x1e,0x01000000} instead of
{0x1e,0x01}), so a preset press set a garbage high bit -- and for group 1
items 3-4 / group 2 items 0-2 stomped the LIVE NonMapping / Intercom /
ModeSecondary* bits -- while the real page bits never moved. Ground
truth (section_dump.txt:72901-72908, little-endian + BTL4MODE.HPP [T0]):
set = ModeMFD{1,2,3}{Quad,Eng1-4} = 1<<(group*5+item), bits 0-14, fully
disjoint from the #6 secondary trio (bits 18-20); group 2 is MFD3, NOT a
duplicate of the secondary views.
What the 15 presets show (l4gauge.cfg): group = the MFD (Mfd1 lower left
/ Mfd2 upper center / Mfd3 lower right), item 0 = the btquad.pcx Quad
overview (up to 4 vehicleSubSystems cluster panels), items 1-4 = the
full-screen engineering-detail pages (bteng.pcx + prepEngr screens
group*4+1..4 + the cluster eng children: GENERATOR SELECT A-D, POWER
graph, COOLING loop, DAMAGE, ammo). Empty screens are authored per mech
(Blackhawk: 3/11/12 empty).
Authentic dispatch (streamed "L4" .CTL EventMappings, BT_CTRLMAP_LOG
dump): each MFD owns the 8-button RIO bank around it, MODE-MASK-gated --
Mfd1 = 0x08-0x0F, Mfd2 = 0x20-0x27, Mfd3 = 0x00-0x07. Quad page ->
direct-select buttons for the POPULATED eng pages (mapper msgs
Aux1Eng1-4 0x4-0x7 / Aux2* 0x9-0xC / Aux3* 0xE-0x11); eng page -> one
back-to-Quad button (0x3/0x8/0xD) + per-subsystem controls. These
records already install and fire on desktop (btinput passes the live
manager mask), so the NUMPAD profile's 0x20-0x27 keys page MFD2
authentically.
Port wiring (the #6 pattern): keys J/K/L -> actions Mfd1/2/3Cycle ->
gBTPresetCycle -> L4MechControlsMapper::CyclePresetModeNow(group) -- a
documented desktop shim (24 mode-dependent pod buttons don't fit a
keyboard) that cycles Quad -> populated Eng pages -> Quad, visiting
exactly the pod-reachable set; the body is the authentic SetPresetMode.
Dev-composite: BTDrawGaugeSurfaces now draws the Eng1-3 planes at their
sibling cells and skips any mono plane whose channel is BlankColor,
honoring the mode-driven reconfigure (RemapGraphicsPort) -- each dev
cell shows the ACTIVE page like the pod monitor. This supersedes and
removes the 2026-07-12 GAUGREND "frozen-dial" scaffold (forced all 15
page bits active under BT_DEV_GAUGES; it pinned the shared Eng plane on
the highest screen and ate the page flips).
Pixel-verified (BT_PRESET_TEST + BT_DEV_GAUGES_DOCK + BT_SHOT,
Blackhawk): all three MFDs page Quad -> SYSTEM NN eng details -> back to
Quad in lockstep with the [mode] preset mask log; group 0 skips the
authored-empty screen 3, group 2 skips 11/12. Un-regressed: N display
cycle (0x450421->0x490421->0x510421, page bits intact), M control mode,
CONTROLS.MAP 52 bindings parse clean.
Diags: BT_MODE_LOG ([mode] preset), BT_PRESET_TEST=<frame>.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1d6339b226
commit
6783619069
@@ -167,7 +167,7 @@ void SVGA16::DrawDevSurface(LPDIRECT3DDEVICE9 device, int slot, int mask, int pa
|
||||
{
|
||||
int w = pixelBuffer.Data.Size.x; // 640
|
||||
int h = pixelBuffer.Data.Size.y; // 480
|
||||
if (device == NULL || slot < 0 || slot >= 8 || w <= 0 || h <= 0) return;
|
||||
if (device == NULL || slot < 0 || slot >= 10 || w <= 0 || h <= 0) return;
|
||||
|
||||
// Lazily create this surface's texture on the MAIN device (MANAGED -> lockable +
|
||||
// survives device reset).
|
||||
@@ -289,7 +289,13 @@ struct BTGaugeSurfaceDesc
|
||||
// buffer, so past ~1.5x you magnify, not sharpen.
|
||||
static const float kBTPanelW = 1320.0f;
|
||||
static const float kBTPanelH = 480.0f;
|
||||
static const BTGaugeSurfaceDesc kBTGaugeSurfaces[6] =
|
||||
// Gitea #9: each preset-able MFD is TWO bit-planes sharing one physical
|
||||
// monitor -- the base Quad plane (Mfd1/2/3) and the engineering-page plane
|
||||
// (Eng1/2/3). The mode-driven `reconfigure` swaps which of the pair is
|
||||
// channel-enabled and which is BlankColor; the draw loop below skips the
|
||||
// blanked plane, so the dev cell shows exactly what the pod monitor shows.
|
||||
// The Eng entries share their sibling's cell rect and FOLLOW it in the list.
|
||||
static const BTGaugeSurfaceDesc kBTGaugeSurfaces[9] =
|
||||
{
|
||||
{ "Heat", 0xFFFF, 0.0f / kBTPanelW, 0.0f, 320.0f / kBTPanelW, 0.5f, 0 },
|
||||
{ "Mfd2", 0xFFFF, 320.0f / kBTPanelW, 0.0f, 320.0f / kBTPanelW, 0.5f, 0 },
|
||||
@@ -297,6 +303,9 @@ static const BTGaugeSurfaceDesc kBTGaugeSurfaces[6] =
|
||||
{ "Mfd3", 0xFFFF, 320.0f / kBTPanelW, 0.5f, 320.0f / kBTPanelW, 0.5f, 0 },
|
||||
{ "sec", -1, 640.0f / kBTPanelW, 0.0f, 360.0f / kBTPanelW, 1.0f, 1 },
|
||||
{ "Comm", 0xFFFF, 1000.0f / kBTPanelW, 0.0f, 320.0f / kBTPanelW, 0.5f, 0 },
|
||||
{ "Eng2", 0xFFFF, 320.0f / kBTPanelW, 0.0f, 320.0f / kBTPanelW, 0.5f, 0 },
|
||||
{ "Eng1", 0xFFFF, 0.0f / kBTPanelW, 0.5f, 320.0f / kBTPanelW, 0.5f, 0 },
|
||||
{ "Eng3", 0xFFFF, 320.0f / kBTPanelW, 0.5f, 320.0f / kBTPanelW, 0.5f, 0 },
|
||||
};
|
||||
|
||||
//
|
||||
@@ -345,11 +354,17 @@ void BTDrawGaugeSurfaces(LPDIRECT3DDEVICE9 device, float px, float py, float pw,
|
||||
}
|
||||
if (svga == NULL) return;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
const BTGaugeSurfaceDesc &d = kBTGaugeSurfaces[i];
|
||||
L4GraphicsPort *port = static_cast<L4GraphicsPort*>(gr->GetGraphicsPort(d.portName));
|
||||
if (port == NULL) continue; // this surface's port isn't configured -> skip
|
||||
// Gitea #9: honor the live mode-driven `reconfigure` -- a mono plane
|
||||
// whose channel is currently BlankColor contributes nothing on the pod
|
||||
// monitor (its palette bits translate to black), so skip it; its
|
||||
// non-blank sibling (Mfd<n> or Eng<n>, same cell rect) draws instead.
|
||||
if (d.monoTint >= 0 && port->GetEnableID() == L4GraphicsPort::BlankColor)
|
||||
continue;
|
||||
// Secondary-CRT unrotation direction is env-flippable (BT_GAUGE_SEC_ROT=3
|
||||
// for the other way) in case the assumed pod mounting is mirrored.
|
||||
int rot = d.rotateCCW;
|
||||
@@ -4309,7 +4324,7 @@ SVGA16::SVGA16(
|
||||
):Video16BitBuffered(init_width, init_height)
|
||||
{
|
||||
BuildWindows(init_width,init_height,windowed, secondaryIndex, aux1Index, aux2Index);
|
||||
for (int _i = 0; _i < 8; _i++) // DEV-COMPOSITE: lazily created on first surface draw
|
||||
for (int _i = 0; _i < 10; _i++) // DEV-COMPOSITE: lazily created on first surface draw
|
||||
mDevSurfaceTex[_i] = NULL;
|
||||
//STUBBED: VIDEO RB 1/15/07
|
||||
# if defined(DEBUG)
|
||||
|
||||
Reference in New Issue
Block a user