diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 339d945db..ca3256d08 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -332,9 +332,31 @@ void ScreenJobDraw() // //============================================================================= +bool ScreenJobValidate() +{ + if (runner) + { + IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, Validate) + { + int res; + VMValue parm[] = { runner }; + VMReturn ret(&res); + VMCall(func, parm, 2, &ret, 1); + return res; + } + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_) { - if (cs.function.CompareNoCase("none") != 0) + if (cs.function.IsNotEmpty() && cs.video.IsNotEmpty()cs.function.CompareNoCase("none") != 0) { completion = completion_; runner = CreateRunner(); @@ -342,14 +364,20 @@ bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_ try { cs.Create(runner); + if (!ScreenJobValidate()) + { + runner->Destroy(); + runner = nullptr; + return false; + } + gameaction = (flags & SJ_BLOCKUI) ? ga_intro : ga_intermission; } catch (...) { - runner->Destroy(); + if (runner) runner->Destroy(); runner = nullptr; throw; } - gameaction = (flags & SJ_BLOCKUI) ? ga_intro : ga_intermission; return true; } return false; @@ -401,7 +429,14 @@ void ShowScoreboard(int numplayers, const CompletionFunc& completion_) I_Error("Bad cutscene function %s. Must receive ScreenJobRunner reference and integer.", qname); VMValue val[2] = { runner, numplayers }; VMCall(func, val, 2, nullptr, 0); - + if (!ScreenJobValidate()) + { + runner->Destroy(); + runner = nullptr; + if (completion) completion(false); + completion = nullptr; + return; + } gameaction = ga_intermission; } @@ -417,12 +452,11 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C runner = CreateRunner(); GC::WriteBarrier(runner); - // outro: first check the map's own outro. - // if that is empty, check the cluster's outro - // if that also fails, check the default outro - try { + // outro: first check the map's own outro. + // if that is empty, check the cluster's outro + // if that also fails, check the default outro if (!fromMap->outro.Create(runner, fromMap)) { auto& cluster = volumeList[fromMap->cluster - 1]; @@ -441,11 +475,19 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C { globalCutscenes.SharewareEnd.Create(runner); } + if (!ScreenJobValidate()) + { + runner->Destroy(); + runner = nullptr; + if (completion) completion(false); + completion = nullptr; + return; + } gameaction = ga_intermission; } catch (...) { - runner->Destroy(); + if (runner) runner->Destroy(); runner = nullptr; throw; } diff --git a/wadsrc/static/filter/redneck/engine/engine.def b/wadsrc/static/filter/redneck/engine/engine.def index 140e385d6..51313fd07 100644 --- a/wadsrc/static/filter/redneck/engine/engine.def +++ b/wadsrc/static/filter/redneck/engine/engine.def @@ -24,4 +24,8 @@ definecutscene episode 2 definecutscene summary RRCutscenes.BuildSPSummary definecutscene mpsummary DukeCutscenes.BuildMPSummary // identical with Duke's -definecutscene mapintro RRCutscenes.BuildMapIntro // this plays the 'travel' animation. +definecutscene mapintro +{ + function RRCutscenes.BuildMapIntro // this plays the 'travel' animation. +} + diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 481e9f0f7..cb3a0e672 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -932,7 +932,7 @@ class RRLevelSummaryScreen : SummaryScreenBase if (displaystate & printKillsVal) { - tempbuf.Format("%-3d", stats.kills); + tempbuf = String.Format("%-3d", stats.kills); Duke.BigText(231, 112, tempbuf, -1); if (stats.maxkills < 0) { @@ -965,8 +965,8 @@ class RRLevelSummaryScreen : SummaryScreenBase { Screen.DrawTexture(texBg, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal); - if (lastmapname) Duke.BigText(80, 16, lastmapname, 0, 0); - Duke.BigText(15, 192, "$PRESSKEY", 0, 0); + Duke.BigText(80, 16, lastmapname, -1); + Duke.BigText(15, 192, "$PRESSKEY", -1); if (displaystate & printTimeText) { diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index fbfdb98d7..a2f30f5d7 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -251,7 +251,7 @@ class MoviePlayerJob : SkippableScreenJob { let movie = MoviePlayer.Create(filename, soundinfo, flags, frametime, firstframetime, lastframetime); if (movie) return new("MoviePlayerJob").Init(movie); - return BlackScreen.Create(1); // do not return null. + return null; } static ScreenJob Create(String filename, int flags, int frametime = -1) { @@ -348,7 +348,12 @@ class ScreenJobRunner : Object void Append(ScreenJob job) { - jobs.Push(job); + if (job != null) jobs.Push(job); + } + + virtual bool Validate() + { + return jobs.Size() > 0; } //---------------------------------------------------------------------------