diff --git a/MUNGA_L4/L4MFDVIEW.cpp b/MUNGA_L4/L4MFDVIEW.cpp index 2485327..f974c9d 100644 --- a/MUNGA_L4/L4MFDVIEW.cpp +++ b/MUNGA_L4/L4MFDVIEW.cpp @@ -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);