Glass cockpit: MFD buttons reach under the display

The red banks were thin strips sitting outside the glass, so the click
target was only as tall as the strip. They are now 100px buttons that
extend BEHIND the MFD picture with just a 10px indicator clearing the
edge: the lamp still reads as a slim strip along the bezel, but the
region of the display above or below it is what you press. Paint order
flipped to match - buttons first, glass over them.

The banks are clamped so they can never meet in the middle on a
scaled-down cockpit, and the panes lost 40px of height each (260 vs
300 for a 240-tall glass), which hands that space back to the
viewscreen.

Verified live: clicking 50px inside the picture presses the button
behind it and the press shows in the indicator strip (770 pixels
changed, all of them within the strip).

Amber map columns are untouched for now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-25 12:25:23 -05:00
co-authored by Claude Fable 5
parent 8fb4b72f7a
commit 0bec0f9640
+46 -20
View File
@@ -10,6 +10,15 @@ namespace
const int buttonGap = 4;
//---------------------------------------------------------------
// MFD button banks run UNDER the glass: the button is this tall
// in total, but only the indicator strip shows past the display
// edge - the rest sits behind the MFD picture, which is what the
// player actually clicks.
//---------------------------------------------------------------
const int mfdButtonHeight = 100;
const int mfdIndicatorStrip = 10;
//---------------------------------------------------------------
// Button fill colors by lamp brightness (0 off / 1-2 dim / 3
// bright), red family for MFD strips, amber for the side columns.
@@ -255,10 +264,20 @@ void
// edges (no border against the viewscreen behind); RIO
// addresses descend from the anchor, row-major (vRIO
// CockpitLayout::Mfd).
//
// The banks reach BEHIND the display: each button is
// mfdButtonHeight tall but only mfdIndicatorStrip of it
// clears the glass edge, so the lamp reads as a thin strip
// and the picture above/below it is the click target. Paint
// draws the buttons before the MFD image for that reason.
//-----------------------------------------------------------
int strip_h = display_height / 8;
if (strip_h < 18) strip_h = 18;
if (strip_h > 40) strip_h = 40;
int strip_h = mfdIndicatorStrip;
int button_h = mfdButtonHeight;
// on a scaled-down cockpit, keep the two banks from meeting
int limit = (display_height + 2 * strip_h) / 2;
if (button_h > limit) button_h = limit;
if (button_h < strip_h) button_h = strip_h;
int button_w = (display_width - 3 * buttonGap) / 4;
@@ -267,18 +286,20 @@ void
for (int i = 0; i < 8; ++i)
{
int row = i / 4; // 0 = top strip, 1 = bottom strip
int row = i / 4; // 0 = top bank, 1 = bottom bank
int col = i % 4;
ScreenButton *button = &buttons[buttonCount++];
button->unit = anchorA - i;
button->amber = 0;
button->x = col * (button_w + buttonGap);
button->y = row ? (displayY + displayH) : 0;
button->y = row
? (displayY + displayH + strip_h - button_h)
: 0;
button->w = (col == 3)
? (display_width - 3 * (button_w + buttonGap))
: button_w;
button->h = strip_h;
button->h = button_h;
}
}
else if (button_style == SideColumns)
@@ -342,20 +363,11 @@ void
FillRect(mem, &client, (HBRUSH) GetStockObject(BLACK_BRUSH));
// HALFTONE area-averages the downscale (the compact glass shows the
// full 640x480 canvas at ~half size); COLORONCOLOR dropped every other
// row/column, which shredded the 1-bit vector strokes and small text.
// HALFTONE requires the brush origin be set (MSDN).
SetStretchBltMode(mem, HALFTONE);
SetBrushOrgEx(mem, 0, 0, NULL);
StretchDIBits(
mem,
displayX, displayY, displayW, displayH,
0, 0, sourceWidth, sourceHeight,
pixels, (const BITMAPINFO *) blitHeader,
DIB_RGB_COLORS, SRCCOPY
);
//---------------------------------------------------------------
// Buttons first, glass second: the MFD banks extend under the
// display so the picture is the click target, and the image
// painted over them leaves only their indicator strips showing.
//---------------------------------------------------------------
for (int i = 0; i < buttonCount; ++i)
{
const ScreenButton *button = &buttons[i];
@@ -380,6 +392,20 @@ void
DeleteObject(frame);
}
// HALFTONE area-averages the downscale (the compact glass shows the
// full 640x480 canvas at ~half size); COLORONCOLOR dropped every other
// row/column, which shredded the 1-bit vector strokes and small text.
// HALFTONE requires the brush origin be set (MSDN).
SetStretchBltMode(mem, HALFTONE);
SetBrushOrgEx(mem, 0, 0, NULL);
StretchDIBits(
mem,
displayX, displayY, displayW, displayH,
0, 0, sourceWidth, sourceHeight,
pixels, (const BITMAPINFO *) blitHeader,
DIB_RGB_COLORS, SRCCOPY
);
BitBlt(hdc, 0, 0, client.right, client.bottom, mem, 0, 0, SRCCOPY);
SelectObject(mem, old_surface);