diff --git a/BUILD.md b/BUILD.md index d8571e1..e0a021a 100644 --- a/BUILD.md +++ b/BUILD.md @@ -132,9 +132,12 @@ Two new environment options remove the hardware dependency entirely: scene presents into the viewscreen pane via `Present`'s `hDestWindowOverride` (`gMainPresentWindow`), so no swap-chain changes. Mouse clicks over the viewscreen fall through to the game window - (STATIC pane hit-test transparency). `L4MFDSCALE` sets the MFD/map pane - size in percent of the gauge canvas (default 50). This replaces the - external BitBlt-mirror launcher wrapper. + (STATIC pane hit-test transparency). The shell **auto-fits the monitor + work area**: the pane scale steps down and the viewscreen shrinks (the + present stretches) until the whole cockpit is on screen. `L4MFDSCALE` + sets the *requested* MFD/map pane size in percent of the gauge canvas + (default 50). The plasma glass is currently hidden in cockpit mode. + This replaces the external BitBlt-mirror launcher wrapper. Each split window also carries its display's **physical button bank** (geometry per vRIO's `CockpitLayout`): 4 red buttons above and below diff --git a/MUNGA_L4/L4PLASMASCREEN.cpp b/MUNGA_L4/L4PLASMASCREEN.cpp index 81e81dd..89de93f 100644 --- a/MUNGA_L4/L4PLASMASCREEN.cpp +++ b/MUNGA_L4/L4PLASMASCREEN.cpp @@ -103,6 +103,15 @@ void ); } +void + PlasmaScreen::Hide() +{ + if (activeInstance != NULL && activeInstance->window != NULL) + { + ShowWindow((HWND) activeInstance->window, SW_HIDE); + } +} + PlasmaScreen::PlasmaScreen(): Video8BitBuffered(plasmaWidth, plasmaHeight) { diff --git a/MUNGA_L4/L4PLASMASCREEN.h b/MUNGA_L4/L4PLASMASCREEN.h index 0663276..d64153a 100644 --- a/MUNGA_L4/L4PLASMASCREEN.h +++ b/MUNGA_L4/L4PLASMASCREEN.h @@ -44,6 +44,10 @@ public: static void Position(void *parent, int x, int y, int client_width, int client_height); + // Hide the glass entirely (cockpit currently runs without it). + static void + Hide(); + protected: static PlasmaScreen *activeInstance; diff --git a/MUNGA_L4/L4VB16.cpp b/MUNGA_L4/L4VB16.cpp index 5ada290..fcd9cd7 100644 --- a/MUNGA_L4/L4VB16.cpp +++ b/MUNGA_L4/L4VB16.cpp @@ -3856,69 +3856,116 @@ SVGA16::SVGA16( } } - int cell_w = (init_width * scale_percent) / 100; - int cell_h = (init_height * scale_percent) / 100; - //--------------------------------------------------------------- // Assemble the pod interior in ONE window (the main game window // becomes the cockpit shell; every display is a chrome-less // child pane): // [ MFD UL ] [ MFD UC ] [ MFD UR ] - // [ plasma (reduced) ][ viewscreen (centered) ] + // [ viewscreen (centered) ] // [ MFD LL ] [ Map ] [ MFD LR ] // The 3D scene presents into the viewscreen child via - // gMainPresentWindow. + // gMainPresentWindow. The whole shell AUTO-FITS the monitor work + // area: pane scale steps down and the viewscreen shrinks (the + // present stretches) until everything is on screen. //--------------------------------------------------------------- int gap = 8; - - // pane sizes mirror MFDSplitView::LayoutButtons (buttonGap = 4) - int strip_h = cell_h / 8; - if (strip_h < 18) strip_h = 18; - if (strip_h > 40) strip_h = 40; - int block_h = cell_h + 2 * (strip_h + 8); - - int map_col_w = cell_h / 8; - if (map_col_w < 20) map_col_w = 20; - if (map_col_w > 40) map_col_w = 40; - int map_block_w = cell_h + 2 * (map_col_w + 8); - int map_block_h = cell_w; - - int col_span = cell_w + gap; - int row_w = 3 * cell_w + 2 * gap; - - int band_y = block_h + gap; int main_w = (int) L4Application::GetScreenWidth(); int main_h = (int) L4Application::GetScreenHeight(); - // center the viewscreen under the columns, but always leave the - // plasma glass at least 128px of space at its left - int main_x = (row_w - main_w) / 2; - int plasma_min = 128 + 2 * gap; - if (main_x < plasma_min) main_x = plasma_min; + HWND cockpit = ApplicationManager::GetCurrentManager()->GetHWnd(); - int lower_y = band_y + main_h + gap; - int lower_h = (block_h > map_block_h) ? block_h : map_block_h; - int client_w = (row_w > main_x + main_w) ? row_w : (main_x + main_w); - int client_h = lower_y + lower_h; + int chrome_w = 16, chrome_h = 40; + if (cockpit != NULL) + { + RECT outer, inner; + GetWindowRect(cockpit, &outer); + GetClientRect(cockpit, &inner); + chrome_w = (outer.right - outer.left) - inner.right; + chrome_h = (outer.bottom - outer.top) - inner.bottom; + } + + RECT work; + work.left = 0; work.top = 0; work.right = 1600; work.bottom = 900; + SystemParametersInfoA(SPI_GETWORKAREA, 0, &work, 0); + int avail_w = (work.right - work.left) - chrome_w; + int avail_h = (work.bottom - work.top) - chrome_h; + + //--------------------------------------------------------------- + // Fit: step the pane scale down until the rows fit the width + // and leave a usable viewscreen height. Pane sizes mirror + // MFDSplitView::LayoutButtons (buttonGap = 4). + //--------------------------------------------------------------- + int scale = scale_percent; + int cell_w, cell_h, strip_h, block_h; + int map_col_w, map_block_w, map_block_h; + int row_w, col_span, lower_h; + int view_w, view_h; + + for (;;) + { + cell_w = (init_width * scale) / 100; + cell_h = (init_height * scale) / 100; + + strip_h = cell_h / 8; + if (strip_h < 18) strip_h = 18; + if (strip_h > 40) strip_h = 40; + block_h = cell_h + 2 * (strip_h + 8); + + map_col_w = cell_h / 8; + if (map_col_w < 20) map_col_w = 20; + if (map_col_w > 40) map_col_w = 40; + map_block_w = cell_h + 2 * (map_col_w + 8); + map_block_h = cell_w; + + col_span = cell_w + gap; + row_w = 3 * cell_w + 2 * gap; + lower_h = (block_h > map_block_h) ? block_h : map_block_h; + + // viewscreen gets the leftover height, at most native size, + // keeping the 3D aspect + view_h = avail_h - block_h - lower_h - 2 * gap; + if (view_h > main_h) view_h = main_h; + view_w = (int)((__int64) main_w * view_h / main_h); + if (view_w > avail_w) + { + view_w = avail_w; + view_h = (int)((__int64) main_h * view_w / main_w); + } + + if ((row_w <= avail_w && view_h >= 240) || scale <= 20) + { + break; + } + scale -= 5; + } + + if (scale != scale_percent) + { + DEBUG_STREAM << "SVGA16: pane scale reduced to " << scale + << "% to fit the " << (work.right - work.left) << "x" + << (work.bottom - work.top) << " work area\n" << std::flush; + } + + int client_w = (row_w > view_w) ? row_w : view_w; + int client_h = block_h + gap + view_h + gap + lower_h; + int rows_x = (client_w - row_w) / 2; + if (rows_x < 0) rows_x = 0; + int view_x = (client_w - view_w) / 2; + if (view_x < 0) view_x = 0; + int band_y = block_h + gap; + int lower_y = band_y + view_h + gap; //--------------------------------------------------------------- // Grow the main window into the cockpit shell //--------------------------------------------------------------- - HWND cockpit = ApplicationManager::GetCurrentManager()->GetHWnd(); if (cockpit != NULL) { SetWindowLongPtrA(cockpit, GWL_STYLE, GetWindowLongPtrA(cockpit, GWL_STYLE) | WS_CLIPCHILDREN); - RECT outer, inner; - GetWindowRect(cockpit, &outer); - GetClientRect(cockpit, &inner); - int chrome_w = (outer.right - outer.left) - inner.right; - int chrome_h = (outer.bottom - outer.top) - inner.bottom; - - SetWindowPos(cockpit, NULL, 0, 0, + SetWindowPos(cockpit, NULL, work.left, work.top, client_w + chrome_w, client_h + chrome_h, - SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); + SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); } //--------------------------------------------------------------- @@ -3930,30 +3977,30 @@ SVGA16::SVGA16( //--------------------------------------------------------------- splitView[SplitMFDUpperLeft] = new MFDSplitView( "MFD upper left", init_width, init_height, - cell_w, cell_h, 0, 0, + cell_w, cell_h, rows_x, 0, MFDSplitView::MFDStrips, 0x2F, 0, cockpit); splitView[SplitMFDUpperCenter] = new MFDSplitView( "MFD upper center", init_width, init_height, - cell_w, cell_h, col_span, 0, + cell_w, cell_h, rows_x + col_span, 0, MFDSplitView::MFDStrips, 0x27, 0, cockpit); splitView[SplitMFDUpperRight] = new MFDSplitView( "MFD upper right", init_width, init_height, - cell_w, cell_h, 2 * col_span, 0, + cell_w, cell_h, rows_x + 2 * col_span, 0, MFDSplitView::MFDStrips, 0x37, 0, cockpit); splitView[SplitMFDLowerLeft] = new MFDSplitView( "MFD lower left", init_width, init_height, - cell_w, cell_h, 0, lower_y, + cell_w, cell_h, rows_x, lower_y, MFDSplitView::MFDStrips, 0x0F, 0, cockpit); splitView[SplitMFDLowerRight] = new MFDSplitView( "MFD lower right", init_width, init_height, - cell_w, cell_h, 2 * col_span, lower_y, + cell_w, cell_h, rows_x + 2 * col_span, lower_y, MFDSplitView::MFDStrips, 0x07, 0, cockpit); // map is portrait: source rotated 90 degrees clockwise, its pane // centered under the middle column splitView[SplitMap] = new MFDSplitView( "Map", init_height, init_width, cell_h, cell_w, - col_span + (cell_w - map_block_w) / 2, lower_y, + rows_x + col_span + (cell_w - map_block_w) / 2, lower_y, MFDSplitView::SideColumns, 0x10, 0x18, cockpit); //--------------------------------------------------------------- @@ -3966,25 +4013,22 @@ SVGA16::SVGA16( cockpitViewscreen = CreateWindowExA( 0, "STATIC", "", WS_CHILD | WS_VISIBLE | SS_BLACKRECT, - main_x, band_y, main_w, main_h, + view_x, band_y, view_w, view_h, cockpit, NULL, GetModuleHandleA(NULL), NULL); if (cockpitViewscreen != NULL) { gMainPresentWindow = cockpitViewscreen; } - - // plasma glass, reduced to fill the space left of the - // viewscreen, vertically centered in the band - int glass_w = main_x - 2 * gap; - int glass_h = glass_w / 4; - PlasmaScreen::Position(cockpit, - gap, band_y + (main_h - glass_h) / 2, - glass_w, glass_h); } + // the plasma glass sits out for now + PlasmaScreen::Hide(); + DEBUG_STREAM << "SVGA16: single-window cockpit assembled (" - << client_w << "x" << client_h << ", scale " - << scale_percent << "%)\n" << std::flush; + << client_w << "x" << client_h << " in " + << (work.right - work.left) << "x" << (work.bottom - work.top) + << " work area, scale " << scale << "%, viewscreen " + << view_w << "x" << view_h << ")\n" << std::flush; } //STUBBED: VIDEO RB 1/15/07 # if defined(DEBUG)