diff --git a/MUNGA_L4/L4MFDVIEW.h b/MUNGA_L4/L4MFDVIEW.h index 27666cc..d85fd1f 100644 --- a/MUNGA_L4/L4MFDVIEW.h +++ b/MUNGA_L4/L4MFDVIEW.h @@ -195,13 +195,14 @@ protected: // display panes position only. A pane's size follows its content and // its button banks, so an old size from a different // build must not distort it. -// the game window position, and size in the cockpit view. Nothing -// derives that size - the cockpit fits itself to -// whatever client area it is given - so a window sized -// to suit a monitor should come back that way, and -// half-restoring it would be the strange behaviour. In -// the exploded view its size IS the render resolution -// -res asked for, so there only the position returns. +// the game window position and size. Nothing derives that size - -res +// only decides how sharp the scene is, and the cockpit +// fits itself to whatever client area it is given - so +// a window sized to suit a monitor should come back +// that way, and half-restoring it would be the strange +// behaviour. RPL4.CPP registers it before the console +// screen, so the saved placement is there from the +// first frame rather than arriving when a race starts. // // A placement that lands on none of the monitors currently plugged in is // ignored rather than applied - restoring the game window off screen diff --git a/MUNGA_L4/L4VB16.cpp b/MUNGA_L4/L4VB16.cpp index d34d1a8..89c9ebb 100644 --- a/MUNGA_L4/L4VB16.cpp +++ b/MUNGA_L4/L4VB16.cpp @@ -3839,15 +3839,11 @@ static LRESULT CALLBACK cockpit->LayoutCockpit(LOWORD(lParam), HIWORD(lParam)); } } - else if (message == WM_EXITSIZEMOVE) - { - // - // The shell was just dragged or resized. Write the arrangement now - // rather than trusting teardown, so a hard kill still leaves what - // was on screen. No-op unless RP412MFDLAYOUT is save. - // - RPWindowLayout_Save(); - } + // + // WM_EXITSIZEMOVE is not handled here: RPL4.CPP's own WndProc takes + // it, and this chains straight through to that, so the shell saves on + // every finished drag whether or not a cockpit has been built. + // return CallWindowProcA(gCockpitBaseProc, hwnd, message, wParam, lParam); } @@ -4467,23 +4463,12 @@ SVGA16::SVGA16( work.left + right_x, work.top + bottom_y); splitView[SplitMap]->SetPosition(work.left + map_x, work.top + map_y); - // - // The game window joins them, position only: here its size is the - // render resolution -res asked for, so restoring an old one would - // leave a stretched back buffer in a window the wrong size. - // - { - HWND shell = ApplicationManager::GetCurrentManager()->GetHWnd(); - if (shell != NULL) - { - RPWindowLayout_Register(shell, "RPL4", False); - } - } - // // ...and then let RP412MFDLAYOUT put everything back where it was // dragged to last time. Windows the file does not mention keep the - // arrangement just computed above. + // arrangement just computed above. The game window is registered + // already - RPL4.CPP does that before the console screen ever + // shows - so this picks it up alongside the panes. // RPWindowLayout_Load(); } @@ -4702,16 +4687,16 @@ SVGA16::SVGA16( // Sticky placement for the shell. Position AND size: nothing // derives that size here - -res only decides how sharp the // scene is - so a window sized to suit a monitor should come - // back that way. Registered after the subclass on purpose, so - // the restore's WM_SIZE runs LayoutCockpit again and the - // canvas re-fits the restored client area. + // back that way. RPL4.CPP registered it before the console + // screen; this reload undoes the sizing just done above, and + // runs after the subclass on purpose so its WM_SIZE puts + // LayoutCockpit over the restored client area. // // -fit sits it borderless over the whole monitor, so there is // no placement of the player's to remember. // if (!fit_display) { - RPWindowLayout_Register(cockpit, "RPL4", True); RPWindowLayout_Load(); } } diff --git a/RP_L4/RPL4.CPP b/RP_L4/RPL4.CPP index 828b99e..86ffa97 100644 --- a/RP_L4/RPL4.CPP +++ b/RP_L4/RPL4.CPP @@ -26,6 +26,7 @@ #include "rpl4lobby.h" #include "..\munga_l4\l4steamtransport.h" #include "..\munga_l4\l4splr.h" +#include "..\munga_l4\l4mfdview.h" // RPWindowLayout_* #include "rpl4ver.h" #include "..\munga\resver.h" #include "..\munga\resource.h" @@ -123,6 +124,15 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; } break; + case WM_EXITSIZEMOVE: + // + // A drag or resize just finished. Here rather than in the + // cockpit's subclass so it also covers the console screen, which + // is where the window gets moved before there is any cockpit to + // subclass. No-op unless RP412MFDLAYOUT is save. + // + RPWindowLayout_Save(); + return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } @@ -254,6 +264,21 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine return FALSE; ShowWindow(hWnd, nShowCmd); + + // + // Sticky placement, from the first frame the player sees. SVGA16 also + // registers and reloads when it builds the cockpit, but that is not + // until a mission starts - without this the console screen would come + // up at the default rect with its title bar still on, and only jump + // to the saved placement once a race began. -fit takes the whole + // monitor and has no placement of the player's to restore. + // + if (!L4Application::GetFitDisplay() && !L4Application::GetFullscreen()) + { + RPWindowLayout_Register(hWnd, "RPL4", True); + RPWindowLayout_Load(); + } + #if !_DEBUG // Arcade pods have no mouse - but desktop/windowed play needs the // cursor for the on-screen cockpit buttons, so hide it only when @@ -475,6 +500,19 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } } + // + // Last word on the window's placement. Every finished drag has already + // written it and SVGA16 writes again as the cockpit comes down, but a + // session that never started a race has neither - and quitting from + // the console screen is exactly how somebody would leave after moving + // the window to where they want it. No-op unless the mode is save. + // + if (IsWindow(hWnd)) + { + RPWindowLayout_Save(); + } + RPWindowLayout_Forget(hWnd); + #if !_DEBUG // symmetric with the fullscreen-only hide at startup if (L4Application::GetFullscreen()) diff --git a/RP_L4/RPL4FE.cpp b/RP_L4/RPL4FE.cpp index 2c07399..1a382ad 100644 --- a/RP_L4/RPL4FE.cpp +++ b/RP_L4/RPL4FE.cpp @@ -177,6 +177,7 @@ namespace GroupLaunch, GroupSteamHost, // buttons, not selections (Steam builds only) GroupSteamJoin, + GroupExit, GroupCount }; @@ -434,6 +435,23 @@ namespace join->rect.bottom = client_h - (7 * row_h) / 2; } + // + // Exit, bottom left. Diagonally opposite LAUNCH on purpose: it is + // the one button on this screen you cannot undo, so it does not go + // next to the one people are aiming for. Half width for the same + // reason - it is a way out, not a peer of LAUNCH. + // + // The window frame used to be the way out, and mfd_layout.cfg's + // ,noframe takes it away, so the screen has to offer its own. + // + FEItem *quit = &fe->items[fe->itemCount++]; + quit->group = GroupExit; + quit->index = 0; + quit->rect.left = col1; + quit->rect.top = client_h - 2 * row_h; + quit->rect.right = col1 + col_w / 2; + quit->rect.bottom = client_h - row_h; + // pilot name edit sits at the top of column 3 if (fe->nameEdit != NULL) { @@ -485,6 +503,7 @@ namespace case GroupLaunch: return "L A U N C H G A M E"; case GroupSteamHost: return "HOST STEAM GAME"; case GroupSteamJoin: return "JOIN STEAM GAME"; + case GroupExit: return "EXIT GAME"; } return ""; } @@ -647,6 +666,12 @@ namespace PostMessageA(fe->menuWindow, WM_NULL, 0, 0); } } + else if (item->group == GroupExit) + { + // the same door closing the window goes through + fe->closed = True; + PostMessageA(fe->menuWindow, WM_NULL, 0, 0); + } else { fe->selection[item->group] = item->index;