diff --git a/source/core/cheats.cpp b/source/core/cheats.cpp index 1a7086f8b..b802a7d42 100644 --- a/source/core/cheats.cpp +++ b/source/core/cheats.cpp @@ -242,7 +242,7 @@ void changeMap(int player, uint8_t** stream, bool skip) void endScreenJob(int player, uint8_t** stream, bool skip) { - if (!skip) EndScreenJob(); + if (!skip) gameaction = ga_endscreenjob; } //--------------------------------------------------------------------------- diff --git a/source/core/gamestate.h b/source/core/gamestate.h index 523ead5d0..26d7f6767 100644 --- a/source/core/gamestate.h +++ b/source/core/gamestate.h @@ -43,6 +43,7 @@ enum gameaction_t : int ga_nextlevel, // Actually start the next level. ga_loadgamehidecon, ga_newgamenostopsound, // start a new game + ga_endscreenjob, ga_fullconsole, }; diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 4d52eaa7b..9be356b4c 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -133,23 +133,6 @@ void G_BuildTiccmd(ticcmd_t* cmd) //========================================================================== bool newGameStarted; -void NewGame(MapRecord* map, int skill, bool ns = false) -{ - newGameStarted = true; - int volume = map->cluster - 1; - if (volume >= 0 && volume < MAXVOLUMES) - { - if (StartCutscene(volumeList[volume].intro, 0, [=](bool) { gi->NewGame(map, skill, ns); })) return; - } - gi->NewGame(map, skill, ns); -} - -//========================================================================== -// -// -// -//========================================================================== - static void GameTicker() { int i; @@ -176,6 +159,7 @@ static void GameTicker() FX_SetReverb(0); gi->FreeLevelData(); gameaction = ga_level; + newGameStarted = true; NewGame(g_nextmap, -1); BackupSaveGame = ""; } @@ -213,6 +197,7 @@ static void GameTicker() C_FlushDisplay(); gameaction = ga_level; BackupSaveGame = ""; + newGameStarted = true; NewGame(g_nextmap, g_nextskill, ga == ga_newgamenostopsound); break; @@ -269,6 +254,10 @@ static void GameTicker() gameaction = ga_nothing; break; + case ga_endscreenjob: + EndScreenJob(); + break; + // for later // case ga_recordgame, // start a new demo recording (later) // case ga_loadgameplaydemo, // load a savegame and play a demo. @@ -659,6 +648,7 @@ void MainLoop () userConfig.CommandMap = ""; if (maprecord) { + newGameStarted = true; NewGame(maprecord, /*userConfig.skill*/2); // todo: fix the skill. } } diff --git a/source/core/mapinfo.h b/source/core/mapinfo.h index 951b58a5e..fff7a9ec3 100644 --- a/source/core/mapinfo.h +++ b/source/core/mapinfo.h @@ -64,6 +64,7 @@ struct GlobalCutscenes CutsceneDef DefaultMapIntro; CutsceneDef DefaultMapOutro; CutsceneDef SharewareEnd; + CutsceneDef LoadingScreen; FString MPSummaryScreen; FString SummaryScreen; }; diff --git a/source/core/parsefuncs.h b/source/core/parsefuncs.h index e5a1031bd..145abcbb9 100644 --- a/source/core/parsefuncs.h +++ b/source/core/parsefuncs.h @@ -100,6 +100,10 @@ void parseDefineCutscene(FScanner& sc, FScriptPosition& pos) { parseCutscene(sc, globalCutscenes.SharewareEnd); } + else if (sc.Compare("loading")) // sets the loading screen when entering a level. + { + parseCutscene(sc, globalCutscenes.LoadingScreen); + } else if (sc.Compare({ "episode", "volume", "cluster" })) { FScanner::SavedPos eblockend; diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index ca3256d08..6405b3793 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -356,7 +356,7 @@ bool ScreenJobValidate() bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_) { - if (cs.function.IsNotEmpty() && cs.video.IsNotEmpty()cs.function.CompareNoCase("none") != 0) + if (cs.function.IsNotEmpty() && cs.video.IsNotEmpty() && cs.function.CompareNoCase("none") != 0) { completion = completion_; runner = CreateRunner(); @@ -440,6 +440,43 @@ void ShowScoreboard(int numplayers, const CompletionFunc& completion_) gameaction = ga_intermission; } +//========================================================================== +// +// +// +//========================================================================== + +void NewGame(MapRecord* map, int skill, bool ns) +{ + completion = [=](bool) { gi->NewGame(map, skill, ns); }; + runner = CreateRunner(); + GC::WriteBarrier(runner); + + try + { + int volume = map->cluster - 1; + if (volume >= 0 && volume < MAXVOLUMES) + volumeList[volume].intro.Create(runner); + + globalCutscenes.LoadingScreen.Create(runner, map); + if (!ScreenJobValidate()) + { + runner->Destroy(); + runner = nullptr; + completion(false); + completion = nullptr; + return; + } + gameaction = ga_intermission; + } + catch (...) + { + if (runner) runner->Destroy(); + runner = nullptr; + throw; + } +} + //--------------------------------------------------------------------------- // // @@ -468,8 +505,10 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C if (toMap) { - if (!toMap->intro.Create(runner, fromMap)) - globalCutscenes.DefaultMapIntro.Create(runner, fromMap); + if (!toMap->intro.Create(runner, toMap)) + globalCutscenes.DefaultMapIntro.Create(runner, toMap); + + globalCutscenes.LoadingScreen.Create(runner, toMap); } else if (isShareware()) { @@ -502,9 +541,7 @@ CCMD(testcutscene) } try { - CutsceneDef def; - def.function = argv[1]; - if (StartCutscene(def, 0, [](bool) {})) + if (StartCutscene(argv[1], 0, [](bool) {})) { C_HideConsole(); } diff --git a/source/core/screenjob.h b/source/core/screenjob.h index d44669bd1..7b335f25e 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -7,193 +7,14 @@ #include "gamestate.h" using CompletionFunc = std::function; -struct JobDesc; -class ScreenJobRunner; void Job_Init(); - -#if 0 -class DScreenJob : public DObject -{ - DECLARE_CLASS(DScreenJob, DObject) -public: - const int flags; - const float fadetime; // in milliseconds - int fadestate = fadein; - - friend class ScreenJobRunner; -//protected: - int ticks = 0; - int state = running; - bool pausable = true; - -public: - enum - { - running = 1, // normal operation - skipped = 2, // finished by user skipping - finished = 3, // finished by completing its sequence - stopping = 4, // running ending animations / fadeout, etc. Will not accept more input. - stopped = 5, // we're done here. - }; - enum - { - visible = 0, - fadein = 1, - fadeout = 2, - stopmusic = 4, - stopsound = 8, - }; - - DScreenJob(int fade = 0, float fadet = 250.f) : flags(fade), fadetime(fadet) {} - - virtual bool ProcessInput() - { - return false; - } - - virtual void Start() {} - virtual bool OnEvent(event_t* evt) { return false; } - virtual void OnTick() { /*state = finished;*/ } - virtual void Draw(double smoothratio) {} - - int DrawFrame(double smoothratio) - { - if (state != running) smoothratio = 1; // this is necessary because the ticker won't be incremented anymore to avoid having a negative time span. - Draw(smoothratio); - if (state == skipped) return -1; - if (state == finished) return 0; - return 1; - } - - int GetFadeState() const { return fadestate; } - - virtual void OnDestroy() override; -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DSkippableScreenJob : public DScreenJob -{ - DECLARE_CLASS(DSkippableScreenJob, DScreenJob) -public: - DSkippableScreenJob(int fade = 0, float fadet = 250.f) : DScreenJob(fade, fadet) - {} - - bool OnEvent(event_t* evt) override; - virtual void Skipped() {} -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DBlackScreen : public DScreenJob -{ - DECLARE_CLASS(DBlackScreen, DScreenJob) -public: - int wait; - bool cleared = false; - -public: - DBlackScreen(int w, int flags = 0) : DScreenJob(flags & ~(fadein|fadeout)), wait(w) {} - void OnTick() override; - void Draw(double smooth) override; -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DImageScreen : public DSkippableScreenJob -{ - DECLARE_CLASS(DImageScreen, DScreenJob) - -public: - int tilenum = -1; - int trans; - int waittime; // in ms. - bool cleared = false; - FTextureID texid; - FGameTexture* tex = nullptr; - -public: - DImageScreen(FGameTexture* tile, int fade = DScreenJob::fadein | DScreenJob::fadeout, int wait = 3000, int translation = 0) : DSkippableScreenJob(fade), waittime(wait) - { - tex = tile; - trans = translation; - } - - DImageScreen(int tile, int fade = DScreenJob::fadein | DScreenJob::fadeout, int wait = 3000, int translation = 0) : DSkippableScreenJob(fade), waittime(wait) - { - tilenum = tile; - trans = translation; - } - - void OnTick() override; - void Draw(double smooth) override; -}; -#endif - -#if 0 -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class ScreenJobRunner -{ - enum - { - State_Clear, - State_Run, - State_Fadeout - }; - TArray jobs; - CompletionFunc completion; - int index = -1; - float screenfade; - bool clearbefore; - bool skipall; - int actionState; - int terminateState; - int fadeticks = 0; - int last_paused_tic = -1; - -public: - ScreenJobRunner(TArray& jobs, CompletionFunc completion_, bool clearbefore_, bool skipall_); - ~ScreenJobRunner(); - void DeleteJobs(); - void AdvanceJob(bool skip); - int DisplayFrame(double smoothratio); - int FadeoutFrame(double smoothratio); - bool OnEvent(event_t* ev); - void OnFinished(); - void OnTick(); - bool RunFrame(); -}; -#endif - - enum { SJ_BLOCKUI = 1, }; -#if 0 - -void RunScreenJob(TArray& jobs, CompletionFunc completion, int flags = 0); -#endif void EndScreenJob(); void DeleteScreenJob(); bool ScreenJobResponder(event_t* ev); @@ -203,8 +24,8 @@ void ScreenJobDraw(); struct CutsceneDef; struct MapRecord; struct SummaryInfo; -bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion); bool StartCutscene(const char* s, int flags, const CompletionFunc& completion); void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic); void ShowScoreboard(int numplayers, const CompletionFunc& completion_); void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, CompletionFunc completion_); +void NewGame(MapRecord* map, int skill, bool ns = false); diff --git a/wadsrc/static/filter/duke/engine/engine.def b/wadsrc/static/filter/duke/engine/engine.def index 85a545e49..be2ca0a01 100644 --- a/wadsrc/static/filter/duke/engine/engine.def +++ b/wadsrc/static/filter/duke/engine/engine.def @@ -54,6 +54,11 @@ definecutscene sharewareend function DukeCutscenes.BuildSharewareEnd } +definecutscene loading +{ + function DukeCutscenes.BuildLoading +} + definecutscene summary DukeCutscenes.BuildSPSummary definecutscene mpsummary DukeCutscenes.BuildMPSummary diff --git a/wadsrc/static/filter/redneck/engine/engine.def b/wadsrc/static/filter/redneck/engine/engine.def index 51313fd07..2f93e916f 100644 --- a/wadsrc/static/filter/redneck/engine/engine.def +++ b/wadsrc/static/filter/redneck/engine/engine.def @@ -22,10 +22,15 @@ definecutscene episode 2 } } -definecutscene summary RRCutscenes.BuildSPSummary -definecutscene mpsummary DukeCutscenes.BuildMPSummary // identical with Duke's definecutscene mapintro { function RRCutscenes.BuildMapIntro // this plays the 'travel' animation. } +definecutscene loading +{ + function DukeCutscenes.BuildLoading // identical with Duke's +} + +definecutscene summary RRCutscenes.BuildSPSummary +definecutscene mpsummary DukeCutscenes.BuildMPSummary // identical with Duke's diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index cb3a0e672..c4030a162 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -459,7 +459,7 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob override void Start() { - Duke.PlayBonusMusic(); + if (!Raze.isRR()) Duke.PlayBonusMusic(); } override void Draw(double smoothratio) @@ -853,11 +853,6 @@ class RRLevelSummaryScreen : SummaryScreenBase return false; } - override void Start() - { - Duke.PlayBonusMusic(); - } - override void OnTick() { if ((displaystate & printStatsAll) != printStatsAll) @@ -1031,10 +1026,15 @@ class DukeLoadScreen : ScreenJob ScreenJob Init(MapRecord maprec) { - Super.Init(); + Super.Init(fadein); rec = maprec; return self; } + + override void OnTick() + { + if (fadestate == visible) jobstate = finished; + } override void Draw(double sr) {