diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 5e4416c32..e1537f72d 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -2714,11 +2714,8 @@ int32_t engineLoadBoard(const char *filename, char flags, vec3_t *dapos, int16_t fr.Read( sprite, sizeof(spritetype)*numsprites); fr.Seek(0, FileReader::SeekSet); - int32_t boardsize = fr.GetLength(); - uint8_t *fullboard = (uint8_t*)Xmalloc(boardsize); - fr.Read( fullboard, boardsize); - md4once(fullboard, boardsize, g_loadedMapHack.md4); - Xfree(fullboard); + auto buffer = fr.Read(); + md4once(buffer.Data(), buffer.Size(), g_loadedMapHack.md4); // Done reading file. @@ -3019,10 +3016,10 @@ void videoNextPage(void) // which calls videoNextPage for page flipping again. In this loop the UI drawers may not get called again. // Ideally this stuff should be moved out of videoNextPage so that all those busy loops won't call UI overlays at all. recursion = true; - M_Drawer(); FStat::PrintStat(twod); C_DrawConsole(); - recursion = false; + M_Drawer(); + recursion = false; } // Handle the final 2D overlays. diff --git a/source/core/console/c_console.cpp b/source/core/console/c_console.cpp index fc4388d50..14b013bf8 100644 --- a/source/core/console/c_console.cpp +++ b/source/core/console/c_console.cpp @@ -63,6 +63,8 @@ #include "v_draw.h" #include "g_input.h" #include "timer.h" +#include "menu.h" +#include "raze_music.h" #define LEFTMARGIN 8 #define RIGHTMARGIN 8 @@ -87,7 +89,7 @@ static bool TabbedList; // True if tab list was shown CVAR(Bool, con_notablist, false, CVAR_ARCHIVE) -static FGameTexture* conback; +static FGameTexture *conback; static uint32_t conshade; static bool conline; @@ -780,8 +782,8 @@ void FNotifyBuffer::AddString(int printlevel, FString source) if (hud_messages != 2 || source.IsEmpty() || - //gamestate == GS_FULLCONSOLE || - //gamestate == GS_DEMOSCREEN || + gamestate == GS_FULLCONSOLE || + gamestate == GS_DEMOSCREEN || con_notifylines == 0) return; @@ -977,9 +979,9 @@ void C_FlushDisplay () void C_AdjustBottom () { - /*if (gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) - ConBottom = screen->GetHeight(); - else*/ if (ConBottom > twod->GetHeight() / 2 || ConsoleState == c_down) + if (gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) + ConBottom = twod->GetHeight(); + else if (ConBottom > twod->GetHeight() / 2 || ConsoleState == c_down) ConBottom = twod->GetHeight() / 2; } @@ -1016,7 +1018,6 @@ void C_Ticker() ConBottom += (consoletic - lasttic) * (twod->GetHeight() * 2 / 25); if (ConBottom >= twod->GetHeight() / 2) { - GSnd->SetSfxPaused(true, PAUSESFX_CONSOLE); ConBottom = twod->GetHeight() / 2; ConsoleState = c_down; } @@ -1026,7 +1027,6 @@ void C_Ticker() ConBottom -= (consoletic - lasttic) * (twod->GetHeight() * 2 / 25); if (ConBottom <= 0) { - GSnd->SetSfxPaused(false, PAUSESFX_CONSOLE); ConsoleState = c_up; ConBottom = 0; } @@ -1035,10 +1035,6 @@ void C_Ticker() lasttic = consoletic; NotifyStrings.Tick(); - if (ConsoleState == c_down) - { - D_ProcessEvents(); - } } void FNotifyBuffer::Tick() @@ -1078,8 +1074,8 @@ void FNotifyBuffer::Draw() int line, lineadv, color, j; bool canskip; - //if (gamestate == GS_FULLCONSOLE || gamestate == GS_DEMOSCREEN/* || menuactive != MENU_Off*/) - //return; + if (gamestate == GS_FULLCONSOLE || gamestate == GS_DEMOSCREEN) + return; FFont* font = generic_ui ? NewSmallFont : SmallFont? SmallFont : AlternativeSmallFont; @@ -1210,12 +1206,10 @@ void C_DrawConsole () } -#if 0 if (menuactive != MENU_Off) { return; } -#endif if (lines > 0) { @@ -1270,15 +1264,16 @@ void C_DrawConsole () } } -#if 0 void C_FullConsole () { + /* if (hud_toggled) D_ToggleHud(); if (demoplayback) G_CheckDemoStatus (); D_QuitNetGame (); advancedemo = false; + */ ConsoleState = c_down; HistPos = NULL; TabbedLast = false; @@ -1286,29 +1281,24 @@ void C_FullConsole () if (gamestate != GS_STARTUP) { gamestate = GS_FULLCONSOLE; - primaryLevel->Music = ""; - S_Start (); - S_StopMusic(true); - P_FreeLevelData (); - } - else - { - C_AdjustBottom (); + Mus_Stop(); } + C_AdjustBottom (); } -#endif void C_ToggleConsole () { - /* - if (gamestate == GS_DEMOSCREEN || demoplayback) + if (gamestate == GS_INTRO) // blocked { - gameaction = ga_fullconsole; + return; } - else if (!chatmodeon && (ConsoleState == c_up || ConsoleState == c_rising) && menuactive == MENU_Off)*/ - - if (ConsoleState == c_up || ConsoleState == c_rising)// && menuactive == MENU_Off) + if (gamestate == GS_DEMOSCREEN) + { + gamestate = GS_FULLCONSOLE; + C_FullConsole(); + } + else if (!chatmodeon && (ConsoleState == c_up || ConsoleState == c_rising) && menuactive == MENU_Off) { ConsoleState = c_falling; HistPos = NULL; @@ -1316,7 +1306,7 @@ void C_ToggleConsole () TabbedList = false; } - else //if (gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP) + else if (gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP) { ConsoleState = c_rising; C_FlushDisplay (); @@ -1390,7 +1380,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) if (ev->data3 & (GKM_SHIFT|GKM_CTRL)) { // Scroll console buffer up one page RowAdjust += (screen->GetHeight()-4)/active_con_scale(twod) / - ((/*gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP*/false) ? CurrentConsoleFont->GetHeight() : CurrentConsoleFont->GetHeight()*2) - 3; + ((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? CurrentConsoleFont->GetHeight() : CurrentConsoleFont->GetHeight()*2) - 3; } else if (RowAdjust < conbuffer->GetFormattedLineCount()) { // Scroll console buffer up @@ -1413,7 +1403,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) if (ev->data3 & (GKM_SHIFT|GKM_CTRL)) { // Scroll console buffer down one page const int scrollamt = (screen->GetHeight()-4)/active_con_scale(twod) / - ((/*gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP*/false) ? CurrentConsoleFont->GetHeight() : CurrentConsoleFont->GetHeight()*2) - 3; + ((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? CurrentConsoleFont->GetHeight() : CurrentConsoleFont->GetHeight()*2) - 3; if (RowAdjust < scrollamt) { RowAdjust = 0; @@ -1615,6 +1605,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) } else if (gamestate == GS_FULLCONSOLE) { + gamestate = GS_DEMOSCREEN; C_DoCommand ("menu_main"); } else @@ -1723,8 +1714,8 @@ bool C_Responder (event_t *ev) { if (ev->type != EV_GUI_Event || ConsoleState == c_up || - ConsoleState == c_rising /*|| - menuactive != MENU_Off*/) + ConsoleState == c_rising || + menuactive != MENU_Off) { return false; } diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 622441e54..a16be4da8 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -202,7 +202,6 @@ enum PAUSESFX_CONSOLE = 2 }; -bool UIActive(); void updatePauseStatus(); void updatePauseStatus(bool state, bool multiplayer); extern int paused; diff --git a/source/core/gamestate.h b/source/core/gamestate.h index 112592f41..55cf9db9d 100644 --- a/source/core/gamestate.h +++ b/source/core/gamestate.h @@ -6,6 +6,7 @@ enum gamestate_t : int { GS_LEVEL, + GS_INTRO, GS_INTERMISSION, GS_FINALE, GS_DEMOSCREEN, diff --git a/source/core/menu/menu.cpp b/source/core/menu/menu.cpp index 340287cb3..6a7f2cf4b 100644 --- a/source/core/menu/menu.cpp +++ b/source/core/menu/menu.cpp @@ -55,6 +55,7 @@ #include "raze_sound.h" #include "texturemanager.h" #include "v_video.h" +#include "gamestate.h" void RegisterDuke3dMenus(); void RegisterBloodMenus(); @@ -204,7 +205,7 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller) { case MKEY_Back: { - if (scriptID != 0) + //if (scriptID != 0) { M_MenuSound(CurrentMenu->mParentMenu? BackSound : CloseSound); Close(); @@ -824,8 +825,12 @@ bool M_DoResponder (event_t *ev) // Pop-up menu? if (ev->data1 == KEY_ESCAPE) // Should we let the games handle Escape for special actions, like backing out of cameras? { - M_StartControlPanel(true); - M_SetMenu(NAME_IngameMenu, -1); + if (gamestate != GS_STARTUP && gamestate != GS_INTRO) + { + M_StartControlPanel(true); + M_SetMenu(gi->CanSave()? NAME_IngameMenu : NAME_Mainmenu, -1); + if (gamestate == GS_FULLCONSOLE) gamestate = GS_DEMOSCREEN; + } return true; } return false; @@ -872,7 +877,6 @@ void M_Ticker (void) if (DMenu::MenuTime & 3) return; if (CurrentMenu != NULL && menuactive != MENU_Off) { - if (DMenu::MenuTime != 0) D_ProcessEvents(); // The main loop is blocked when the menu is open and cannot dispatch the events. if (transition.previous) transition.previous->Ticker(); if (CurrentMenu == nullptr) return; // In case one of the sub-screens has closed the menu. CurrentMenu->Ticker(); diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index ef374b9d1..8c2a6b5ec 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -43,6 +43,7 @@ #include "s_soundinternal.h" #include "animtexture.h" #include "gamestate.h" +#include "menu.h" IMPLEMENT_CLASS(DScreenJob, true, false) @@ -242,6 +243,7 @@ class ScreenJobRunner bool clearbefore; bool skipped = false; uint64_t startTime = -1; + uint64_t lastTime = -1; int actionState; int terminateState; @@ -290,12 +292,19 @@ public: auto now = I_nsTime(); bool skiprequest = inputState.CheckAllInput(); if (startTime == -1) startTime = now; + + if (M_Active()) + { + startTime += now - lastTime; + } + lastTime = now; + auto clock = now - startTime; if (screenfade < 1.f) { float ms = (clock / 1'000'000) / job.job->fadetime; screenfade = clamp(ms, 0.f, 1.f); - twod->SetScreenFade(screenfade); + if (!M_Active()) twod->SetScreenFade(screenfade); job.job->fadestate = DScreenJob::fadein; } else job.job->fadestate = DScreenJob::visible; @@ -308,10 +317,17 @@ public: int FadeoutFrame() { auto now = I_nsTime(); + + if (M_Active()) + { + startTime += now - lastTime; + } + lastTime = now; + auto clock = now - startTime; float ms = (clock / 1'000'000) / jobs[index].job->fadetime; float screenfade2 = clamp(screenfade - ms, 0.f, 1.f); - twod->SetScreenFade(screenfade2); + if (!M_Active()) twod->SetScreenFade(screenfade2); if (screenfade2 <= 0.f) { twod->Unlock(); // must unlock before displaying. @@ -368,13 +384,13 @@ public: ScreenJobRunner *runner; -void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore) +void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore, bool blockingui) { assert(completion != nullptr); if (count) { runner = new ScreenJobRunner(jobs, count, completion, clearbefore); - gamestate = GS_INTERMISSION; + gamestate = blockingui? GS_INTRO : GS_INTERMISSION; } } diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 77c5afdc3..4093e9a57 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -79,7 +79,7 @@ struct JobDesc }; -void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore = true); +void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore = true, bool blockingui = false); void DeleteScreenJob(); void RunScreenJobFrame(); diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index ba0d0e467..803d04441 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -272,7 +272,7 @@ void Logo_d(const CompletionFunc &completion) if (VOLUMEALL && !inputState.CheckAllInput()) jobs[job++] = { PlayVideo("logo.anm", logosound, logoframetimes), []() { S_PlaySpecialMusic(MUS_INTRO); } }; if (!isNam()) jobs[job++] = { Create(), nullptr }; jobs[job++] = { Create(), []() { S_PlaySound(NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI); } }; - RunScreenJob(jobs, job, completion); + RunScreenJob(jobs, job, completion, true, true); } //--------------------------------------------------------------------------- diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index 24c1152f3..0d00c6f71 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -203,7 +203,7 @@ void Logo_r(const CompletionFunc& completion) { jobs[job++] = { PlayVideo("redint.mve"), nullptr }; } - RunScreenJob(jobs, job, completion); + RunScreenJob(jobs, job, completion, true, true); } //--------------------------------------------------------------------------- diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 4229a2a59..1c82f9fa7 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -395,56 +395,67 @@ void app_loop() while (true) { - handleevents(); - updatePauseStatus(); - switch (gamestate) + try { - default: - case GS_STARTUP: - totalclock = 0; - ototalclock = 0; - lockclock = 0; - - ps[myconnectindex].ftq = 0; - - if (userConfig.CommandMap.IsNotEmpty()) + handleevents(); + updatePauseStatus(); + D_ProcessEvents(); + switch (gamestate) { - auto maprecord = FindMapByName(userConfig.CommandMap); - userConfig.CommandMap = ""; - if (maprecord) + default: + case GS_STARTUP: + totalclock = 0; + ototalclock = 0; + lockclock = 0; + + ps[myconnectindex].ftq = 0; + + if (userConfig.CommandMap.IsNotEmpty()) { - ud.m_respawn_monsters = ud.m_player_skill == 4; - - for (int i = 0; i != -1; i = connectpoint2[i]) + auto maprecord = FindMapByName(userConfig.CommandMap); + userConfig.CommandMap = ""; + if (maprecord) { - resetweapons(i); - resetinventory(i); + ud.m_respawn_monsters = ud.m_player_skill == 4; + + for (int i = 0; i != -1; i = connectpoint2[i]) + { + resetweapons(i); + resetinventory(i); + } + startnewgame(maprecord, /*userConfig.skill*/2); } - startnewgame(maprecord, /*userConfig.skill*/2); } + else + { + fi.ShowLogo([](bool) { startmainmenu(); }); + } + break; + + case GS_DEMOSCREEN: + case GS_FULLCONSOLE: + drawbackground(); + break; + + case GS_LEVEL: + if (GameTicker()) gamestate = GS_STARTUP; + else videoSetBrightness(thunder_brightness); + break; + + case GS_INTERMISSION: + case GS_INTRO: + RunScreenJobFrame(); // This handles continuation through its completion callback. + break; + } - else - { - fi.ShowLogo([](bool) { startmainmenu(); }); - } - break; - - case GS_DEMOSCREEN: - drawbackground(); - break; - - case GS_LEVEL: - if (GameTicker()) gamestate = GS_STARTUP; - else videoSetBrightness(thunder_brightness); - break; - - case GS_INTERMISSION: - RunScreenJobFrame(); // This handles continuation through its completion callback. - break; - + videoNextPage(); + videoSetBrightness(0); // immediately reset this so that the value doesn't stick around in the backend. + } + catch (CRecoverableError& err) + { + C_FullConsole(); + Printf(TEXTCOLOR_RED "%s\n", err.what()); } - videoNextPage(); - videoSetBrightness(0); // immediately reset this so that the value doesn't stick around in the backend. } }