Auto-fit the cockpit to the monitor; hide the plasma glass for now
The assembled shell could exceed the work area (1291px tall at default scale) - on a 1080p monitor the whole lower row, map included, hung off the bottom of the screen, which read as the map not rendering, and the lamp-reactive preset buttons were unreachable down there. (The render and click paths themselves were verified fine: a synthetic press on a map preset button lights it through the game lamp command.) The layout now measures SPI_GETWORKAREA and fits: the pane scale steps down (to 20% minimum) and the viewscreen takes the leftover height at the 3D aspect, shrinking below native when needed - Present stretches, so the scene scales cleanly. Rows and viewscreen center in the shell, which is sized to the work area. Verified: at 70% panes in a 1392-high work area the viewscreen reduced to 609x457 with everything on screen. The plasma glass sits out of the cockpit for the moment (PlasmaScreen::Hide) per playtest direction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
+101
-57
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user