This commit is contained in:
Major Cooke 2023-01-21 12:05:50 -06:00
parent 050f982fe2
commit 3d7e8bf7af
10 changed files with 372 additions and 22 deletions

View file

@ -23,13 +23,13 @@ public:
void ToggleFullscreen(bool yes) override;
void SetWindowSize(int client_w, int client_h);
void PositionWindow(bool fullscreen, bool initialcall = false); // RicardoLuis0: this needs to be public for proper fullscreen handling in netgame restarts
protected:
void GetCenteredPos(int in_w, int in_h, int &winx, int &winy, int &winw, int &winh, int &scrwidth, int &scrheight);
void KeepWindowOnScreen(int &winx, int &winy, int winw, int winh, int scrwidth, int scrheight);
void PositionWindow(bool fullscreen, bool initialcall = false);
float m_Gamma, m_Brightness, m_Contrast;
uint16_t m_origGamma[768];
bool m_Fullscreen = false;

View file

@ -79,6 +79,7 @@
#include "printf.h"
#include "i_mainwindow.h"
#include "base_sysfb.h"
// MACROS ------------------------------------------------------------------
@ -314,6 +315,17 @@ void I_ShowFatalError(const char *msg)
}
}
void I_NetRestartShowConsole()
{
if(vid_fullscreen)
{
static_cast<SystemBaseFrameBuffer*>(screen)->PositionWindow(false, true);
screen->Update();
vid_fullscreen = true; // vid_fullscreen is forced to false by PositionWindow
}
mainwindow.RestoreConView(true);
}
// Here is how the error logging system works.
//
// To catch exceptions that occur in secondary threads, CatchAllExceptions is

View file

@ -95,20 +95,22 @@ int MainWindow::GetGameTitleWindowHeight()
// Sets the main WndProc, hides all the child windows, and starts up in-game input.
void MainWindow::ShowGameView()
{
if (GetWindowLongPtr(Window, GWLP_USERDATA) == 0)
if (GetWindowLongPtr(Window, GWLP_USERDATA) != 1)
{
SetWindowLongPtr(Window, GWLP_USERDATA, 1);
SetWindowLongPtr(Window, GWLP_WNDPROC, (LONG_PTR)WndProc);
ShowWindow(ConWindow, SW_HIDE);
ShowWindow(ProgressBar, SW_HIDE);
ConWindowHidden = true;
ShowWindow(GameTitleWindow, SW_HIDE);
I_InitInput(Window);
if (GetWindowLongPtr(Window, GWLP_USERDATA) != 2) I_InitInput(Window);
SetWindowLongPtr(Window, GWLP_USERDATA, 1);
}
}
// Returns the main window to its startup state.
void MainWindow::RestoreConView()
void MainWindow::RestoreConView(bool netgame_restart)
{
HDC screenDC = GetDC(0);
int dpi = GetDeviceCaps(screenDC, LOGPIXELSX);
@ -118,6 +120,31 @@ void MainWindow::RestoreConView()
// Make sure the window has a frame in case it was fullscreened.
SetWindowLongPtr(Window, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW);
if(netgame_restart)
{
DEVMODE displaysettings;
// Many Windows structures that specify their size do so with the first
// element. DEVMODE is not one of those structures.
memset (&displaysettings, 0, sizeof(displaysettings));
displaysettings.dmSize = sizeof(displaysettings);
EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &displaysettings);
int x = (displaysettings.dmPelsWidth - width) / 2;
int y = (displaysettings.dmPelsHeight - height) / 2;
// Make sure the window has a frame in case it was fullscreened.
SetWindowLongPtr(Window, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW);
if (GetWindowLong(Window, GWL_EXSTYLE) & WS_EX_TOPMOST)
{
SetWindowPos(Window, HWND_BOTTOM, x, y, width, height, SWP_DRAWFRAME | SWP_NOCOPYBITS);
SetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE);
}
else
{
SetWindowPos(Window, NULL, x, y, width, height, SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOZORDER);
}
}
else
{
if (GetWindowLong(Window, GWL_EXSTYLE) & WS_EX_TOPMOST)
{
SetWindowPos(Window, HWND_BOTTOM, 0, 0, width, height, SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE);
@ -127,16 +154,28 @@ void MainWindow::RestoreConView()
{
SetWindowPos(Window, NULL, 0, 0, width, height, SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER);
}
}
SetWindowLongPtr(Window, GWLP_WNDPROC, (LONG_PTR)LConProc);
ShowWindow(ConWindow, SW_SHOW);
ConWindowHidden = false;
ShowWindow(GameTitleWindow, SW_SHOW);
I_ShutdownInput(); // Make sure the mouse pointer is available.
if(netgame_restart)
{ // Make sure the input system isn't reset
I_CheckNativeMouse(true, false);
}
else
{ // Make sure the mouse pointer is available.
I_ShutdownInput();
}
// Make sure the progress bar isn't visible.
DeleteStartupScreen();
FlushBufferedConsoleStuff();
// Make sure the input system isn't reset
SetWindowLongPtr(Window, GWLP_USERDATA, 2);
}
// Shows an error message, preferably in the main window, but it can use a normal message box too.

View file

@ -17,7 +17,7 @@ public:
void Create(const FString& title, int x, int y, int width, int height);
void ShowGameView();
void RestoreConView();
void RestoreConView(bool netgame_restart = false);
void ShowErrorPane(const char* text);
void CheckForRestart();

View file

@ -479,7 +479,7 @@ FString VkShaderManager::LoadPrivateShaderLump(const char *lumpname)
VkPPShader* VkShaderManager::GetVkShader(PPShader* shader)
{
if (!shader->Backend)
if (!shader->Backend || !static_cast<VkPPShader*>(shader->Backend.get())->VertexShader)
shader->Backend = std::make_unique<VkPPShader>(fb, shader);
return static_cast<VkPPShader*>(shader->Backend.get());
}

View file

@ -136,7 +136,7 @@ VkFormat VkTextureManager::GetTextureFormat(PPTexture* texture)
VkPPTexture* VkTextureManager::GetVkTexture(PPTexture* texture)
{
if (!texture->Backend)
if (!texture->Backend || !static_cast<VkPPTexture*>(texture->Backend.get())->TexImage.View)
texture->Backend = std::make_unique<VkPPTexture>(fb, texture);
return static_cast<VkPPTexture*>(texture->Backend.get());
}

View file

@ -142,6 +142,14 @@ void Local_Job_Init();
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
extern void I_SetWindowTitle(const char* caption);
#ifdef _WIN32
extern void I_NetRestartShowConsole();
//RicardoLuis0: TODO fix host/join CCMD startup window on non-windows platforms
#else
#define I_NetRestartShowConsole()
#endif
extern void ReadStatistics();
extern void M_SetDefaultMode ();
extern void G_NewInit ();
@ -166,6 +174,7 @@ void G_BuildTiccmd (ticcmd_t* cmd);
void D_DoAdvanceDemo ();
void D_LoadWadSettings ();
void ParseGLDefs();
void ClearGLDefs();
void DrawFullscreenSubtitle(FFont* font, const char *text);
void D_Cleanup();
void FreeSBarInfoScript();
@ -332,6 +341,7 @@ const char *Subtitle;
bool nospriterename;
FString lastIWAD;
int restart = 0;
bool restart_multiplayer = false;
extern bool AppActive;
bool playedtitlemusic;
@ -3049,6 +3059,9 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
gameinfo.nokeyboardcheats = iwad_info->nokeyboardcheats;
gameinfo.ConfigName = iwad_info->Configname;
// make sure shaders/etc aren't loaded twice when restarting the engine
ClearGLDefs();
const char *v = Args->CheckValue("-rngseed");
if (v)
{
@ -3173,7 +3186,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
CT_Init ();
if (!restart)
if (!restart || restart_multiplayer)
{
if (!batchrun) Printf ("I_Init: Setting up machine state.\n");
CheckCPUID(&CPU);
@ -3215,7 +3228,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
}
if (!batchrun) Printf ("ST_Init: Init startup screen.\n");
if (!restart)
if (!restart || restart_multiplayer)
{
StartWindow = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5, StartScreen == nullptr);
}
@ -3382,7 +3395,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
}
}
if (!restart)
if (!restart || restart_multiplayer)
{
if (!batchrun) Printf ("D_CheckNetGame: Checking network game status.\n");
if (StartScreen) StartScreen->LoadingStatus ("Checking network game status.", 0x3f);
@ -3409,7 +3422,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
if (cl_customizeinvulmap)
R_UpdateInvulnerabilityColormap();
if (!restart)
if (!restart || restart_multiplayer)
{
// start the apropriate game based on parms
auto v = Args->CheckValue ("-record");
@ -3462,7 +3475,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
}
v = Args->CheckValue("-playdemo");
if (v != NULL)
if (v && !restart_multiplayer)
{
singledemo = true; // quit after one demo
G_DeferedPlayDemo (v);
@ -3470,7 +3483,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
else
{
v = Args->CheckValue("-timedemo");
if (v)
if (v && !restart_multiplayer)
{
G_TimeDemo(v);
}
@ -3524,7 +3537,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
D_StartTitle (); // start up intro loop
setmodeneeded = false; // This may be set to true here, but isn't needed for a restart
}
restart_multiplayer = false;
staticEventManager.OnEngineInitialize();
return 0;
}
@ -3646,6 +3659,10 @@ static int D_DoomMain_Internal (void)
if (restart)
{
C_InitConsole(SCREENWIDTH, SCREENHEIGHT, false);
if(restart_multiplayer)
{
I_NetRestartShowConsole();
}
}
nospriterename = false;
@ -3858,6 +3875,148 @@ UNSAFE_CCMD(restart)
wantToRestart = true;
}
UNSAFE_CCMD(host)
{
if(netgame || multiplayer)
{
Printf ("You must not be in a net game when hosting\n");
return;
}
int numplayers = 0;
FString map = "";
int ticdup = -1;
int port = -1;
int skill = -1;
FString loadsave = "";
int flags = 0;
const auto n = argv.argc();
if(n <= 1)
{
Printf ("Not enough arguments for host\n");
return;
}
numplayers = atoi(argv[1]);
for(int i = 2; i < n; i++)
{
FString arg(argv[i]);
auto sep = arg.IndexOf('=');
if(sep == -1)
{
if(arg.CompareNoCase("EXTRATIC") == 0)
{
flags |= MP_EXTRATIC;
}
else if(arg.CompareNoCase("PACKET_SERVER") == 0)
{
flags |= MP_PACKET_SERVER;
}
else if(arg.CompareNoCase("DEATHMATCH") == 0)
{
flags |= MP_DEATHMATCH;
}
else if(arg.CompareNoCase("ALTDEATH") == 0)
{
flags |= MP_ALTDEATH;
}
else if(arg.CompareNoCase("NOMONSTERS") == 0)
{
flags |= MP_NOMONSTERS;
}
else
{
Printf ("Invalid argument for host: %s\n",arg.GetChars());
return;
}
}
else
{
if(strnicmp(arg.GetChars(),"MAP",sep) == 0)
{
map = FString(arg.GetChars() + sep + 1);
}
else if(strnicmp(arg.GetChars(),"LOADSAVE",sep) == 0)
{
loadsave = FString(arg.GetChars() + sep + 1);
}
else if(strnicmp(arg.GetChars(),"PORT",sep) == 0)
{
port = atoi(arg.GetChars() + sep + 1);
}
else if(strnicmp(arg.GetChars(),"SKILL",sep) == 0)
{
skill = atoi(arg.GetChars() + sep + 1);
}
else if(strnicmp(arg.GetChars(),"TICDUP",sep) == 0)
{
ticdup = atoi(arg.GetChars() + sep + 1);
}
else
{
Printf ("Invalid argument for host: %s\n",arg.GetChars());
return;
}
}
}
D_RestartHostMultiplayer(numplayers,map,ticdup,port,skill,loadsave,flags);
}
UNSAFE_CCMD(join)
{
if(netgame || multiplayer)
{
Printf ("You must not be in a net game when joining\n");
return;
}
FString addr = "";
int port = -1;
FString loadsave = "";
const auto n = argv.argc();
if(n <= 1)
{
Printf ("Not enough arguments for host\n");
return;
}
addr = FString(argv[1]);
for(int i = 2; i < n; i++)
{
FString arg(argv[i]);
auto sep = arg.IndexOf('=');
if(sep == -1)
{
Printf ("Invalid argument for host: %s\n",arg.GetChars());
return;
}
else
{
if(strnicmp(arg.GetChars(),"LOADSAVE",sep) == 0)
{
loadsave = FString(arg.GetChars() + sep + 1);
}
else if(strnicmp(arg.GetChars(),"PORT",sep) == 0)
{
port = atoi(arg.GetChars() + sep + 1);
}
else
{
Printf ("Invalid argument for host: %s\n",arg.GetChars());
return;
}
}
}
D_RestartJoinMultiplayer(addr,port,loadsave);
}
DEFINE_FIELD_X(InputEventData, event_t, type)
DEFINE_FIELD_X(InputEventData, event_t, subtype)
DEFINE_FIELD_X(InputEventData, event_t, data1)

View file

@ -1802,6 +1802,124 @@ void D_QuitNetGame (void)
fclose (debugfile);
}
extern bool wantToRestart;
extern bool restart_multiplayer;
void D_RestartHostMultiplayer(int numplayers, FString map, int ticdup, int port, int skill, FString loadsave, int flags)
{
if(netgame || multiplayer)
{
I_FatalError ("You must not be in a net game before starting one");
}
Args->RemoveArgs("-join");
Args->RemoveArgs("-host");
Args->RemoveArgs("-net");
Args->RemoveArgs("-netmode");
Args->RemoveArgs("-port");
Args->RemoveArgs("-dup");
Args->RemoveArgs("-extratic");
Args->RemoveArgs("-deathmatch");
Args->RemoveArgs("-nomonsters");
Args->RemoveArgs("+map");
FString tmp;
tmp.Format("%d",numplayers);
Args->AppendArg("-host");
Args->AppendArg(tmp);
if(!map.IsEmpty()) {
Args->AppendArg("+map");
Args->AppendArg(map);
}
if(ticdup > 0)
{
tmp.Format("%d",ticdup);
Args->AppendArg("-dup");
Args->AppendArg(tmp);
}
if(port >= 0)
{
tmp.Format("%d",port);
Args->AppendArg("-port");
Args->AppendArg(tmp);
}
if(skill >= 0)
{
tmp.Format("%d",skill);
Args->AppendArg("-skill");
Args->AppendArg(tmp);
}
if(!loadsave.IsEmpty())
{
Args->AppendArg("+loadsave");
Args->AppendArg(loadsave);
}
if(flags & MP_EXTRATIC)
{
Args->AppendArg("-extratic");
}
if(flags & MP_PACKET_SERVER)
{
Args->AppendArg("-netmode");
Args->AppendArg("1");
}
if(flags & MP_DEATHMATCH)
{
Args->AppendArg("-deathmatch");
if(flags & MP_ALTDEATH)
{
Args->AppendArg("-altdeath");
}
}
if(flags & MP_NOMONSTERS)
{
Args->AppendArg("-nomonsters");
}
wantToRestart = true;
restart_multiplayer = true;
}
void D_RestartJoinMultiplayer(const char * host_addr, int port, FString loadsave)
{
if(netgame || multiplayer)
{
I_FatalError ("You must not be in a net game before starting one");
}
Args->RemoveArgs("-join");
Args->RemoveArgs("-host");
Args->RemoveArgs("-net");
Args->RemoveArgs("-netmode");
Args->RemoveArgs("-port");
Args->RemoveArgs("-dup");
Args->RemoveArgs("-extratic");
Args->RemoveArgs("-deathmatch");
Args->RemoveArgs("-nomonsters");
Args->RemoveArgs("+map");
Args->AppendArg("-join");
Args->AppendArg(host_addr);
if(port >= 0)
{
FString tmp;
tmp.Format("%d",port);
Args->AppendArg("-port");
Args->AppendArg(tmp);
}
if(!loadsave.IsEmpty())
{
Args->AppendArg("+loadsave");
Args->AppendArg(loadsave);
}
wantToRestart = true;
restart_multiplayer = true;
}
// Forces playsim processing time to be consistent across frames.
// This improves interpolation for frames in between tics.
//

View file

@ -56,6 +56,23 @@ void NetUpdate (void);
// to notify of game exit
void D_QuitNetGame (void);
enum EMultiplayerHostFlags
{
MP_EXTRATIC = 1,
MP_PACKET_SERVER = 2,
MP_DEATHMATCH = 4,
MP_ALTDEATH = 8,
MP_NOMONSTERS = 16,
};
void D_RestartHostMultiplayer(int numplayers, FString map= "", int ticdup = -1, int port = -1, int skill = -1, FString loadsave = "", int flags = 0);
void D_RestartJoinMultiplayer(const char * host_addr, int port = -1, FString loadsave = "");
//? how many ticks to run?
void TryRunTics (void);

View file

@ -2016,7 +2016,6 @@ void LoadGLDefs(const char *defsLump)
InitializeActorLights(LightAssociations);
}
//==========================================================================
//
//
@ -2053,3 +2052,9 @@ void ParseGLDefs()
ParseVavoomSkybox();
LoadGLDefs(defsLump);
}
void ClearGLDefs()
{
PostProcessShaders.Clear();
usershaders.Clear();
}