From 9bebd7fabff9f295ba9b3ec4ccfb77971435f70a Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 26 Apr 2021 12:35:07 +1000 Subject: [PATCH 01/86] - Remove max ammo fudging for when showing the magazine amount for Duke since it overrides ammo maximums set from CON. --- source/games/duke/src/player_d.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index b3dac8381..6f3873836 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -2630,27 +2630,6 @@ static void processweapon(int snum, ESyncBits actions, int psect) auto s = pact->s; int shrunk = (s->yrepeat < 32); - // Set maximum for pistol slightly higher if playing with `cl_showmagamount 1`. - if (!cl_showmagamt) - { - if (p->ammo_amount[PISTOL_WEAPON] > PISTOL_MAXDEFAULT) - p->ammo_amount[PISTOL_WEAPON] = PISTOL_MAXDEFAULT; - - if (gs.max_ammo_amount[PISTOL_WEAPON] != PISTOL_MAXDEFAULT) - gs.max_ammo_amount[PISTOL_WEAPON] = PISTOL_MAXDEFAULT; - } - else - { - short pistolAddition = 4; - short pistolNewMaximum = PISTOL_MAXDEFAULT + pistolAddition; - - if (p->ammo_amount[PISTOL_WEAPON] == PISTOL_MAXDEFAULT && gs.max_ammo_amount[PISTOL_WEAPON] == PISTOL_MAXDEFAULT) - p->ammo_amount[PISTOL_WEAPON] += pistolAddition; - - if (gs.max_ammo_amount[PISTOL_WEAPON] != pistolNewMaximum) - gs.max_ammo_amount[PISTOL_WEAPON] = pistolNewMaximum; - } - if (isNamWW2GI() && (actions & SB_HOLSTER)) // 'Holster Weapon { if (isWW2GI()) From af3eac84562f86d78d35f0c8436d1a7962a1d22f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 00:11:36 +0200 Subject: [PATCH 02/86] - simplified screen job setup where all elements can be skipped in one go. --- source/core/screenjob.cpp | 11 ++++++----- source/core/screenjob.h | 4 ++-- source/games/duke/src/2d_d.cpp | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index f2417dc5b..8f132a5ee 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -125,14 +125,15 @@ class ScreenJobRunner int index = -1; float screenfade; bool clearbefore; + bool skipall; int actionState; int terminateState; int fadeticks = 0; int last_paused_tic = -1; public: - ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_) - : completion(std::move(completion_)), clearbefore(clearbefore_) + ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_, bool skipall_) + : completion(std::move(completion_)), clearbefore(clearbefore_), skipall(skipall_) { jobs.Resize(count); memcpy(jobs.Data(), jobs_, count * sizeof(JobDesc)); @@ -167,7 +168,7 @@ public: jobs[index].job->Destroy(); } index++; - while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && jobs[index].ignoreifskipped))) + while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && skipall))) { if (jobs[index].job != nullptr) jobs[index].job->Destroy(); index++; @@ -316,13 +317,13 @@ public: ScreenJobRunner *runner; -void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore, bool blockingui) +void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore, bool blockingui, bool skipall) { assert(completion != nullptr); videoclearFade(); if (count) { - runner = new ScreenJobRunner(jobs, count, completion, clearbefore); + runner = new ScreenJobRunner(jobs, count, completion, clearbefore, skipall); gameaction = blockingui? ga_intro : ga_intermission; } else diff --git a/source/core/screenjob.h b/source/core/screenjob.h index b0a48b058..7d90de300 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -135,11 +135,11 @@ struct JobDesc { DScreenJob* job; void (*postAction)(); - bool ignoreifskipped; + //bool ignoreifskipped; }; -void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore = true, bool blockingui = false); +void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore = true, bool blockingui = false, bool skipall = false); void EndScreenJob(); void DeleteScreenJob(); bool ScreenJobResponder(event_t* ev); diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index c26c7ad14..d3142086c 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -1129,9 +1129,9 @@ void e4intro(const CompletionFunc& completion) S_PlaySpecialMusic(MUS_BRIEFING); jobs[job++] = { PlayVideo("vol41a.anm", vol41a, framespeed_10), nullptr }; - jobs[job++] = { PlayVideo("vol42a.anm", vol42a, framespeed_14), nullptr, true }; - jobs[job++] = { PlayVideo("vol43a.anm", vol43a, framespeed_10), nullptr, true }; - RunScreenJob(jobs, job, completion); + jobs[job++] = { PlayVideo("vol42a.anm", vol42a, framespeed_14), nullptr }; + jobs[job++] = { PlayVideo("vol43a.anm", vol43a, framespeed_10), nullptr }; + RunScreenJob(jobs, job, completion, true, false, true); } //--------------------------------------------------------------------------- From fb5e2fe0c03f1f2bc955ca0fd2f59e6ca854d892 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 00:18:53 +0200 Subject: [PATCH 03/86] - use flags instead of bools. --- source/core/screenjob.cpp | 6 +++--- source/core/screenjob.h | 9 ++++++++- source/games/blood/src/credits.cpp | 2 +- source/games/duke/src/2d_d.cpp | 4 ++-- source/games/duke/src/2d_r.cpp | 2 +- source/games/exhumed/src/2d.cpp | 2 +- source/games/sw/src/2d.cpp | 6 +++--- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 8f132a5ee..628378b27 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -317,14 +317,14 @@ public: ScreenJobRunner *runner; -void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore, bool blockingui, bool skipall) +void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, int flags) { assert(completion != nullptr); videoclearFade(); if (count) { - runner = new ScreenJobRunner(jobs, count, completion, clearbefore, skipall); - gameaction = blockingui? ga_intro : ga_intermission; + runner = new ScreenJobRunner(jobs, count, completion, !(flags & SJ_DONTCLEAR), !!(flags & SJ_SKIPALL)); + gameaction = (flags & SJ_BLOCKUI)? ga_intro : ga_intermission; } else { diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 7d90de300..733a8e6f8 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -138,8 +138,15 @@ struct JobDesc //bool ignoreifskipped; }; +enum +{ + SJ_DONTCLEAR = 1, + SJ_BLOCKUI = 2, + SJ_SKIPALL = 4 +}; -void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore = true, bool blockingui = false, bool skipall = false); + +void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, int flags = 0); void EndScreenJob(); void DeleteScreenJob(); bool ScreenJobResponder(event_t* ev); diff --git a/source/games/blood/src/credits.cpp b/source/games/blood/src/credits.cpp index 90f9cbc9d..98e37caf2 100644 --- a/source/games/blood/src/credits.cpp +++ b/source/games/blood/src/credits.cpp @@ -89,7 +89,7 @@ void playlogos() RunScreenJob(jobs, job, [](bool) { Mus_Stop(); gameaction = ga_mainmenu; - }, true, true); + }, SJ_BLOCKUI); } void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func) diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index d3142086c..f59ff35dd 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -307,7 +307,7 @@ void Logo_d(const CompletionFunc &completion) } else S_PlaySpecialMusic(MUS_INTRO); jobs[job++] = { Create(), []() { S_PlaySound(NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI); } }; - RunScreenJob(jobs, job, completion, true, true); + RunScreenJob(jobs, job, completion, SJ_BLOCKUI); } //--------------------------------------------------------------------------- @@ -1131,7 +1131,7 @@ void e4intro(const CompletionFunc& completion) jobs[job++] = { PlayVideo("vol41a.anm", vol41a, framespeed_10), nullptr }; jobs[job++] = { PlayVideo("vol42a.anm", vol42a, framespeed_14), nullptr }; jobs[job++] = { PlayVideo("vol43a.anm", vol43a, framespeed_10), nullptr }; - RunScreenJob(jobs, job, completion, true, false, true); + RunScreenJob(jobs, job, completion, SJ_SKIPALL); } //--------------------------------------------------------------------------- diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index c59c28bb6..a7350a928 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -204,7 +204,7 @@ void Logo_r(const CompletionFunc& completion) { jobs[job++] = { PlayVideo("redint.mve"), nullptr }; } - RunScreenJob(jobs, job, completion, true, true); + RunScreenJob(jobs, job, completion, SJ_BLOCKUI); } //--------------------------------------------------------------------------- diff --git a/source/games/exhumed/src/2d.cpp b/source/games/exhumed/src/2d.cpp index 2acd24315..7c0b8da0f 100644 --- a/source/games/exhumed/src/2d.cpp +++ b/source/games/exhumed/src/2d.cpp @@ -528,7 +528,7 @@ void DoTitle(CompletionFunc completion) jobs[job++] = { PlayMovie("book.mov") }; jobs[job++] = { Create() }; - RunScreenJob(jobs, job, completion, true, true); + RunScreenJob(jobs, job, completion, SJ_BLOCKUI); } diff --git a/source/games/sw/src/2d.cpp b/source/games/sw/src/2d.cpp index 9c982f0c6..92cc36ccf 100644 --- a/source/games/sw/src/2d.cpp +++ b/source/games/sw/src/2d.cpp @@ -92,7 +92,7 @@ void Logo(const CompletionFunc& completion) int job = 0; jobs[job++] = { Create() }; jobs[job++] = { PlayVideo("sw.anm", logosound, logoframetimes, true)}; - RunScreenJob(jobs, job, completion, true, true); + RunScreenJob(jobs, job, completion, SJ_BLOCKUI); } else completion(false); } @@ -623,7 +623,7 @@ void StatScreen(int FinishAnim, CompletionFunc completion) { jobs[job++] = { Create() }; } - RunScreenJob(jobs, job, completion, true); + RunScreenJob(jobs, job, completion); } //--------------------------------------------------------------------------- @@ -638,7 +638,7 @@ void SybexScreen(CompletionFunc completion) else { JobDesc job = { Create(tileGetTexture(5261), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff) }; - RunScreenJob(&job, 1, completion, true, true); + RunScreenJob(&job, 1, completion, SJ_BLOCKUI); } } From 71e5f9b70fe972c8872dc324f08d8d56c9891103 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 00:25:55 +0200 Subject: [PATCH 04/86] - changed screen job list to work without per-job completion callbacks. They made things more complex than necessary and do not translate well to scripting. --- source/core/screenjob.cpp | 11 +++- source/core/screenjob.h | 13 +++-- source/games/blood/src/credits.cpp | 24 ++++++-- source/games/duke/src/2d_d.cpp | 89 +++++++++++++++++++++--------- source/games/duke/src/2d_r.cpp | 16 +++--- source/games/sw/src/2d.cpp | 4 +- 6 files changed, 107 insertions(+), 50 deletions(-) diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 628378b27..40d1c0963 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -56,6 +56,11 @@ IMPLEMENT_CLASS(DScreenJob, true, false) IMPLEMENT_CLASS(DImageScreen, true, false) +void DScreenJob::OnDestroy() +{ + if (flags & stopmusic) Mus_Stop(); + if (flags & stopsound) FX_StopAllSounds(); +} bool DSkippableScreenJob::OnEvent(event_t* evt) { @@ -164,7 +169,7 @@ public: { if (index >= 0) { - if (jobs[index].postAction) jobs[index].postAction(); + //if (jobs[index].postAction) jobs[index].postAction(); jobs[index].job->Destroy(); } index++; @@ -176,7 +181,7 @@ public: actionState = clearbefore ? State_Clear : State_Run; if (index < jobs.Size()) { - jobs[index].job->fadestate = !paused && jobs[index].job->fadestyle & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible; + jobs[index].job->fadestate = !paused && jobs[index].job->flags & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible; jobs[index].job->Start(); } inputState.ClearAllInput(); @@ -289,7 +294,7 @@ public: if (terminateState < 1) { // Must lock before displaying. - if (jobs[index].job->fadestyle & DScreenJob::fadeout) + if (jobs[index].job->flags & DScreenJob::fadeout) { jobs[index].job->fadestate = DScreenJob::fadeout; jobs[index].job->state = DScreenJob::stopping; diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 733a8e6f8..3eed95e10 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -3,6 +3,7 @@ #include "dobject.h" #include "v_2ddrawer.h" #include "d_eventbase.h" +#include "s_soundinternal.h" using CompletionFunc = std::function; struct JobDesc; @@ -11,7 +12,7 @@ class ScreenJobRunner; class DScreenJob : public DObject { DECLARE_CLASS(DScreenJob, DObject) - const int fadestyle; + const int flags; const float fadetime; // in milliseconds int fadestate = fadein; @@ -35,9 +36,11 @@ public: visible = 0, fadein = 1, fadeout = 2, + stopmusic = 4, + stopsound = 8, }; - DScreenJob(int fade = 0, float fadet = 250.f) : fadestyle(fade), fadetime(fadet) {} + DScreenJob(int fade = 0, float fadet = 250.f) : flags(fade), fadetime(fadet) {} virtual bool ProcessInput() { @@ -60,6 +63,7 @@ public: int GetFadeState() const { return fadestate; } + virtual void OnDestroy() override; }; //--------------------------------------------------------------------------- @@ -90,7 +94,7 @@ class DBlackScreen : public DScreenJob bool cleared = false; public: - DBlackScreen(int w) : wait(w) {} + DBlackScreen(int w, int flags = 0) : DScreenJob(flags & ~(fadein|fadeout)), wait(w) {} void OnTick() override; void Draw(double smooth) override; }; @@ -134,8 +138,7 @@ public: struct JobDesc { DScreenJob* job; - void (*postAction)(); - //bool ignoreifskipped; + //void (*postAction)(); }; enum diff --git a/source/games/blood/src/credits.cpp b/source/games/blood/src/credits.cpp index 98e37caf2..89efa42ed 100644 --- a/source/games/blood/src/credits.cpp +++ b/source/games/blood/src/credits.cpp @@ -36,6 +36,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS +class DBloodIntroImage : public DImageScreen +{ + bool mus; + +public: + DBloodIntroImage(int tilenum, int flags = 0, bool withmusic = false) : DImageScreen(tilenum, flags), mus(withmusic) + {} + + void Start() override + { + sndStartSample("THUNDER2", 128, -1); + if (mus) sndPlaySpecialMusicOrNothing(MUS_INTRO); + } +}; //--------------------------------------------------------------------------- // @@ -70,8 +84,7 @@ void playlogos() } else { - jobs[job++] = { Create(1), []() { sndStartSample("THUNDER2", 128, -1); } }; - jobs[job++] = { Create(2050) }; + jobs[job++] = { Create(2050) }; } if (fileSystem.FindFile("gti.smk") != -1) { @@ -79,12 +92,11 @@ void playlogos() } else { - jobs[job++] = { Create(1), []() { sndStartSample("THUNDER2", 128, -1); } }; - jobs[job++] = { Create(2052) }; + jobs[job++] = { Create(2052) }; } } - jobs[job++] = { Create(1), []() { sndPlaySpecialMusicOrNothing(MUS_INTRO); sndStartSample("THUNDER2", 128, -1); }}; - jobs[job++] = { Create(2518, DScreenJob::fadein) }; + jobs[job++] = { Create(1) }; + jobs[job++] = { Create(2518, DScreenJob::fadein, true) }; RunScreenJob(jobs, job, [](bool) { Mus_Stop(); diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index f59ff35dd..da895e94d 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -170,6 +170,11 @@ class DDRealmsScreen : public DSkippableScreenJob public: DDRealmsScreen() : DSkippableScreenJob(fadein | fadeout) {} + void Start() override + { + S_PlaySpecialMusic(MUS_INTRO); + } + void OnTick() override { if (ticks >= 7 * GameTicRate) state = finished; @@ -200,6 +205,11 @@ public: { } + void Start() override + { + if (isNam() || userConfig.nologo) S_PlaySpecialMusic(MUS_INTRO); + } + void OnTick() override { int clock = ticks * 120 / GameTicRate; @@ -276,6 +286,11 @@ public: } } } + + void OnDestroy() override + { + S_PlaySound(NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI); + } }; //--------------------------------------------------------------------------- @@ -301,12 +316,10 @@ void Logo_d(const CompletionFunc &completion) int job = 0; if (!userConfig.nologo) { - if (!isShareware()) jobs[job++] = { PlayVideo("logo.anm", logosound, logoframetimes), []() { S_PlaySpecialMusic(MUS_INTRO); } }; - else jobs[job++] = { Create(1), []() { S_PlaySpecialMusic(MUS_INTRO); } }; - if (!isNam()) jobs[job++] = { Create(), nullptr }; + if (!isShareware()) jobs[job++] = { PlayVideo("logo.anm", logosound, logoframetimes) }; + if (!isNam()) jobs[job++] = { Create(), }; } - else S_PlaySpecialMusic(MUS_INTRO); - jobs[job++] = { Create(), []() { S_PlaySound(NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI); } }; + jobs[job++] = { Create() }; RunScreenJob(jobs, job, completion, SJ_BLOCKUI); } @@ -422,6 +435,18 @@ public: } }; + +class DE2EndScreen : public DImageScreen +{ +public: + DE2EndScreen() : DImageScreen(E2ENDSCREEN, DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff, 0) + {} + + void Start() override + { + S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + } +}; //--------------------------------------------------------------------------- // // @@ -513,6 +538,11 @@ public: } if (state != running) FX_StopAllSounds(); } + + void OnDestroy() override + { + if (!isPlutoPak()) S_PlaySound(ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI); + } }; //--------------------------------------------------------------------------- @@ -535,6 +565,11 @@ public: BigText(160, 70 + 16 + 16 + 16, GStrings("Look for a Duke Nukem 3D")); BigText(160, 70 + 16 + 16 + 16 + 16, GStrings("sequel soon.")); } + + void Start() override + { + S_PlaySound(ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI); + } }; //--------------------------------------------------------------------------- @@ -548,7 +583,7 @@ class DEpisode5End : public DImageScreen int sound = 0; public: - DEpisode5End() : DImageScreen(FIREFLYGROWEFFECT, fadein|fadeout) + DEpisode5End() : DImageScreen(FIREFLYGROWEFFECT, fadein|fadeout|stopsound) { } @@ -644,45 +679,45 @@ static void bonussequence_d(int num, JobDesc *jobs, int &job) switch (num) { case 0: - jobs[job++] = { Create(), nullptr }; - jobs[job++] = { Create(E1ENDSCREEN, DScreenJob::fadein|DScreenJob::fadeout, 0x7fffffff), []() { Mus_Stop(); } }; + jobs[job++] = { Create() }; + jobs[job++] = { Create(E1ENDSCREEN, DScreenJob::fadein|DScreenJob::fadeout|DScreenJob::stopmusic, 0x7fffffff) }; break; case 1: Mus_Stop(); - jobs[job++] = { PlayVideo("cineov2.anm", cineov2sound, framespeed_18), []() { S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); } }; - jobs[job++] = { Create(E2ENDSCREEN, DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff), []() { FX_StopAllSounds(); } }; + jobs[job++] = { PlayVideo("cineov2.anm", cineov2sound, framespeed_18) }; + jobs[job++] = { Create() }; break; case 2: Mus_Stop(); if (g_gameType & GAMEFLAG_DUKEDC) { - jobs[job++] = { PlayVideo("radlogo.anm", dukedcsound, framespeed_10), nullptr }; + jobs[job++] = { PlayVideo("radlogo.anm", dukedcsound, framespeed_10) }; } else { - jobs[job++] = { PlayVideo("cineov3.anm", cineov3sound, framespeed_10), nullptr }; - jobs[job++] = { Create(200), []() { FX_StopAllSounds(); } }; - jobs[job++] = { Create(), []() { if (!isPlutoPak()) S_PlaySound(ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI); } }; + jobs[job++] = { PlayVideo("cineov3.anm", cineov3sound, framespeed_10) }; + jobs[job++] = { Create(200, DScreenJob::stopsound) }; + jobs[job++] = { Create() }; if (!isPlutoPak()) jobs[job++] = { Create(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), - DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff), []() { FX_StopAllSounds(); } }; + DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff) }; } break; case 3: Mus_Stop(); - jobs[job++] = { PlayVideo("vol4e1.anm", vol4e1, framespeed_10), nullptr }; - jobs[job++] = { PlayVideo("vol4e2.anm", vol4e2, framespeed_10), nullptr }; - jobs[job++] = { PlayVideo("vol4e3.anm", vol4e3, framespeed_10), []() { S_PlaySound(ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI); } }; - jobs[job++] = { Create(), nullptr }; + jobs[job++] = { PlayVideo("vol4e1.anm", vol4e1, framespeed_10) }; + jobs[job++] = { PlayVideo("vol4e2.anm", vol4e2, framespeed_10) }; + jobs[job++] = { PlayVideo("vol4e3.anm", vol4e3, framespeed_10) }; + jobs[job++] = { Create() }; jobs[job++] = { Create(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), - DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff), []() { FX_StopAllSounds(); } }; + DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff) }; break; case 4: Mus_Stop(); - jobs[job++] = { Create(), []() { FX_StopAllSounds(); } }; + jobs[job++] = { Create() }; break; } } @@ -698,8 +733,8 @@ void showtwoscreens(const CompletionFunc& completion) JobDesc jobs[2]; int job = 0; - jobs[job++] = { Create(3291), nullptr }; - jobs[job++] = { Create(3290), nullptr }; + jobs[job++] = { Create(3291) }; + jobs[job++] = { Create(3290) }; RunScreenJob(jobs, job, completion); } @@ -709,7 +744,7 @@ void doorders(const CompletionFunc& completion) int job = 0; for (int i = 0; i < 4; i++) - jobs[job++] = { Create(ORDERING + i), nullptr }; + jobs[job++] = { Create(ORDERING + i) }; RunScreenJob(jobs, job, completion); } @@ -1128,9 +1163,9 @@ void e4intro(const CompletionFunc& completion) static const int framespeed_14[] = { 14, 14, 14 }; S_PlaySpecialMusic(MUS_BRIEFING); - jobs[job++] = { PlayVideo("vol41a.anm", vol41a, framespeed_10), nullptr }; - jobs[job++] = { PlayVideo("vol42a.anm", vol42a, framespeed_14), nullptr }; - jobs[job++] = { PlayVideo("vol43a.anm", vol43a, framespeed_10), nullptr }; + jobs[job++] = { PlayVideo("vol41a.anm", vol41a, framespeed_10) }; + jobs[job++] = { PlayVideo("vol42a.anm", vol42a, framespeed_14) }; + jobs[job++] = { PlayVideo("vol43a.anm", vol43a, framespeed_10) }; RunScreenJob(jobs, job, completion, SJ_SKIPALL); } diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index a7350a928..27bd4bd1d 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -196,13 +196,13 @@ void Logo_r(const CompletionFunc& completion) } else if (!isRRRA()) { - jobs[job++] = { PlayVideo("rr_intro.anm", introsound, framespeed), nullptr }; - jobs[job++] = { PlayVideo("redneck.anm", rednecksound, framespeed), nullptr }; - jobs[job++] = { PlayVideo("xatlogo.anm", xatrixsound, framespeed), nullptr }; + jobs[job++] = { PlayVideo("rr_intro.anm", introsound, framespeed) }; + jobs[job++] = { PlayVideo("redneck.anm", rednecksound, framespeed) }; + jobs[job++] = { PlayVideo("xatlogo.anm", xatrixsound, framespeed) }; } else { - jobs[job++] = { PlayVideo("redint.mve"), nullptr }; + jobs[job++] = { PlayVideo("redint.mve") }; } RunScreenJob(jobs, job, completion, SJ_BLOCKUI); } @@ -235,13 +235,13 @@ static void bonussequence_r(int num, JobDesc* jobs, int& job) switch (num) { case 0: - jobs[job++] = { PlayVideo("turdmov.anm", turdmov, framespeed), nullptr }; - jobs[job++] = { Create(TENSCREEN), nullptr }; + jobs[job++] = { PlayVideo("turdmov.anm", turdmov, framespeed) }; + jobs[job++] = { Create(TENSCREEN) }; break; case 1: - jobs[job++] = { PlayVideo("rr_outro.anm", rr_outro, framespeed), nullptr }; - jobs[job++] = { Create(TENSCREEN), nullptr }; + jobs[job++] = { PlayVideo("rr_outro.anm", rr_outro, framespeed) }; + jobs[job++] = { Create(TENSCREEN) }; break; default: diff --git a/source/games/sw/src/2d.cpp b/source/games/sw/src/2d.cpp index 92cc36ccf..325a44430 100644 --- a/source/games/sw/src/2d.cpp +++ b/source/games/sw/src/2d.cpp @@ -356,6 +356,7 @@ public: seconds = (second_tics % 60); } private: + static void gNextState(STATE** State) { // Transition to the next state @@ -403,6 +404,7 @@ private: void Start() override { + FX_StopAllSounds(); PlaySong(nullptr, ThemeSongs[1], ThemeTrack[1]); } @@ -610,7 +612,7 @@ void StatScreen(int FinishAnim, CompletionFunc completion) if (FinishAnim) { StopSound(); - jobs[job++] = { GetFinishAnim(FinishAnim), []() { soundEngine->StopAllChannels(); } }; + jobs[job++] = { GetFinishAnim(FinishAnim) }; jobs[job++] = { Create() }; if (FinishAnim == ANIM_ZILLA) jobs[job++] = { Create() }; From 805b91b721ef6a0da3934f3f3fada04d5fe62d20 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 00:35:48 +0200 Subject: [PATCH 05/86] - put ScreenJobRunner declaration into header. --- source/core/screenjob.cpp | 371 ++++++++++++++++++++------------------ source/core/screenjob.h | 43 ++++- 2 files changed, 233 insertions(+), 181 deletions(-) diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 40d1c0963..5a9991e51 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -117,208 +117,223 @@ void DImageScreen::Draw(double smoothratio) // //--------------------------------------------------------------------------- -class ScreenJobRunner +ScreenJobRunner::ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_, bool skipall_) + : completion(std::move(completion_)), clearbefore(clearbefore_), skipall(skipall_) { - enum + jobs.Resize(count); + memcpy(jobs.Data(), jobs_, count * sizeof(JobDesc)); + // Release all jobs from the garbage collector - the code as it is cannot deal with them getting collected. This should be removed later once the GC is working. + for (int i = 0; i < count; i++) { - 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; + jobs[i].job->Release(); + } + AdvanceJob(false); +} -public: - ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_, bool skipall_) - : completion(std::move(completion_)), clearbefore(clearbefore_), skipall(skipall_) +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +ScreenJobRunner::~ScreenJobRunner() +{ + DeleteJobs(); +} + +void ScreenJobRunner::DeleteJobs() +{ + for (auto& job : jobs) { - jobs.Resize(count); - memcpy(jobs.Data(), jobs_, count * sizeof(JobDesc)); - // Release all jobs from the garbage collector - the code as it is cannot deal with them getting collected. This should be removed later once the GC is working. - for (int i = 0; i < count; i++) + job.job->ObjectFlags |= OF_YesReallyDelete; + delete job.job; + } + jobs.Clear(); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void ScreenJobRunner::AdvanceJob(bool skip) +{ + if (index >= 0) + { + //if (jobs[index].postAction) jobs[index].postAction(); + jobs[index].job->Destroy(); + } + index++; + while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && skipall))) + { + if (jobs[index].job != nullptr) jobs[index].job->Destroy(); + index++; + } + actionState = clearbefore ? State_Clear : State_Run; + if (index < jobs.Size()) + { + jobs[index].job->fadestate = !paused && jobs[index].job->flags & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible; + jobs[index].job->Start(); + } + inputState.ClearAllInput(); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int ScreenJobRunner::DisplayFrame(double smoothratio) +{ + auto& job = jobs[index]; + auto now = I_GetTimeNS(); + bool processed = job.job->ProcessInput(); + + if (job.job->fadestate == DScreenJob::fadein) + { + double ms = (job.job->ticks + smoothratio) * 1000 / GameTicRate / job.job->fadetime; + float screenfade = (float)clamp(ms, 0., 1.); + twod->SetScreenFade(screenfade); + if (screenfade == 1.f) job.job->fadestate = DScreenJob::visible; + } + int state = job.job->DrawFrame(smoothratio); + twod->SetScreenFade(1.f); + return state; +} + +int ScreenJobRunner::FadeoutFrame(double smoothratio) +{ + auto& job = jobs[index]; + double ms = (fadeticks + smoothratio) * 1000 / GameTicRate / job.job->fadetime; + float screenfade = 1.f - (float)clamp(ms, 0., 1.); + twod->SetScreenFade(screenfade); + job.job->DrawFrame(1.); + return (screenfade > 0.f); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool ScreenJobRunner::OnEvent(event_t* ev) +{ + if (paused || index >= jobs.Size()) return false; + + if (ev->type == EV_KeyDown) + { + // We never reach the key binding checks in G_Responder, so for the console we have to check for ourselves here. + auto binding = Bindings.GetBinding(ev->data1); + if (binding.CompareNoCase("toggleconsole") == 0) { - jobs[i].job->Release(); + C_ToggleConsole(); + return true; } - AdvanceJob(false); } - ~ScreenJobRunner() + if (jobs[index].job->state != DScreenJob::running) return false; + + return jobs[index].job->OnEvent(ev); +} + +void ScreenJobRunner::OnFinished() +{ + if (completion) completion(false); + completion = nullptr; // only finish once. +} + +void ScreenJobRunner::OnTick() +{ + if (paused) return; + if (index >= jobs.Size()) + { + //DeleteJobs(); + //twod->SetScreenFade(1); + //twod->ClearScreen(); // This must not leave the 2d buffer empty. + //if (gamestate == GS_INTRO) OnFinished(); + //else Net_WriteByte(DEM_ENDSCREENJOB); // intermissions must be terminated synchronously. + } + else + { + if (jobs[index].job->state == DScreenJob::running) + { + jobs[index].job->ticks++; + jobs[index].job->OnTick(); + } + else if (jobs[index].job->state == DScreenJob::stopping) + { + fadeticks++; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool ScreenJobRunner::RunFrame() +{ + if (index >= jobs.Size()) { DeleteJobs(); - } - - void DeleteJobs() - { - for (auto& job : jobs) - { - job.job->ObjectFlags |= OF_YesReallyDelete; - delete job.job; - } - jobs.Clear(); - } - - void AdvanceJob(bool skip) - { - if (index >= 0) - { - //if (jobs[index].postAction) jobs[index].postAction(); - jobs[index].job->Destroy(); - } - index++; - while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && skipall))) - { - if (jobs[index].job != nullptr) jobs[index].job->Destroy(); - index++; - } - actionState = clearbefore ? State_Clear : State_Run; - if (index < jobs.Size()) - { - jobs[index].job->fadestate = !paused && jobs[index].job->flags & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible; - jobs[index].job->Start(); - } - inputState.ClearAllInput(); - } - - int DisplayFrame(double smoothratio) - { - auto& job = jobs[index]; - auto now = I_GetTimeNS(); - bool processed = job.job->ProcessInput(); - - if (job.job->fadestate == DScreenJob::fadein) - { - double ms = (job.job->ticks + smoothratio) * 1000 / GameTicRate / job.job->fadetime; - float screenfade = (float)clamp(ms, 0., 1.); - twod->SetScreenFade(screenfade); - if (screenfade == 1.f) job.job->fadestate = DScreenJob::visible; - } - int state = job.job->DrawFrame(smoothratio); - twod->SetScreenFade(1.f); - return state; - } - - int FadeoutFrame(double smoothratio) - { - auto& job = jobs[index]; - double ms = (fadeticks + smoothratio) * 1000 / GameTicRate / job.job->fadetime; - float screenfade = 1.f - (float)clamp(ms, 0., 1.); - twod->SetScreenFade(screenfade); - job.job->DrawFrame(1.); - return (screenfade > 0.f); - } - - bool OnEvent(event_t* ev) - { - if (paused || index >= jobs.Size()) return false; - - if (ev->type == EV_KeyDown) - { - // We never reach the key binding checks in G_Responder, so for the console we have to check for ourselves here. - auto binding = Bindings.GetBinding(ev->data1); - if (binding.CompareNoCase("toggleconsole") == 0) - { - C_ToggleConsole(); - return true; - } - } - - if (jobs[index].job->state != DScreenJob::running) return false; - - return jobs[index].job->OnEvent(ev); - } - - void OnFinished() - { + twod->SetScreenFade(1); + twod->ClearScreen(); // This must not leave the 2d buffer empty. if (completion) completion(false); - completion = nullptr; // only finish once. + return false; } - void OnTick() + // ensure that we won't go back in time if the menu is dismissed without advancing our ticker + bool menuon = paused; + if (menuon) last_paused_tic = jobs[index].job->ticks; + else if (last_paused_tic == jobs[index].job->ticks) menuon = true; + double smoothratio = menuon ? 1. : I_GetTimeFrac(); + + if (actionState == State_Clear) { - if (paused) return; - if (index >= jobs.Size()) - { - //DeleteJobs(); - //twod->SetScreenFade(1); - //twod->ClearScreen(); // This must not leave the 2d buffer empty. - //if (gamestate == GS_INTRO) OnFinished(); - //else Net_WriteByte(DEM_ENDSCREENJOB); // intermissions must be terminated synchronously. - } - else - { - if (jobs[index].job->state == DScreenJob::running) - { - jobs[index].job->ticks++; - jobs[index].job->OnTick(); - } - else if (jobs[index].job->state == DScreenJob::stopping) - { - fadeticks++; - } - } + actionState = State_Run; + twod->ClearScreen(); } - - bool RunFrame() + else if (actionState == State_Run) { - if (index >= jobs.Size()) + terminateState = DisplayFrame(smoothratio); + if (terminateState < 1) { - DeleteJobs(); - twod->SetScreenFade(1); - twod->ClearScreen(); // This must not leave the 2d buffer empty. - if (completion) completion(false); - return false; - } - - // ensure that we won't go back in time if the menu is dismissed without advancing our ticker - bool menuon = paused; - if (menuon) last_paused_tic = jobs[index].job->ticks; - else if (last_paused_tic == jobs[index].job->ticks) menuon = true; - double smoothratio = menuon ? 1. : I_GetTimeFrac(); - - if (actionState == State_Clear) - { - actionState = State_Run; - twod->ClearScreen(); - } - else if (actionState == State_Run) - { - terminateState = DisplayFrame(smoothratio); - if (terminateState < 1) + // Must lock before displaying. + if (jobs[index].job->flags & DScreenJob::fadeout) { - // Must lock before displaying. - if (jobs[index].job->flags & DScreenJob::fadeout) - { - jobs[index].job->fadestate = DScreenJob::fadeout; - jobs[index].job->state = DScreenJob::stopping; - actionState = State_Fadeout; - fadeticks = 0; - } - else - { - AdvanceJob(terminateState < 0); - } + jobs[index].job->fadestate = DScreenJob::fadeout; + jobs[index].job->state = DScreenJob::stopping; + actionState = State_Fadeout; + fadeticks = 0; } - } - else if (actionState == State_Fadeout) - { - int ended = FadeoutFrame(smoothratio); - if (ended < 1) + else { - jobs[index].job->state = DScreenJob::stopped; AdvanceJob(terminateState < 0); } } - return true; } -}; + else if (actionState == State_Fadeout) + { + int ended = FadeoutFrame(smoothratio); + if (ended < 1) + { + jobs[index].job->state = DScreenJob::stopped; + AdvanceJob(terminateState < 0); + } + } + return true; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- ScreenJobRunner *runner; diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 3eed95e10..4dd35dd56 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -132,15 +132,52 @@ public: void Draw(double smooth) override; }; - - +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- struct JobDesc { DScreenJob* job; - //void (*postAction)(); }; + +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(JobDesc* jobs_, int count, 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(); +}; + + + enum { SJ_DONTCLEAR = 1, From 4a7430c8e41b50aa6a94fae238a31ca42bedaa2f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 00:51:14 +0200 Subject: [PATCH 06/86] - got rid of JobDesc. --- source/core/screenjob.cpp | 67 ++++++++++--------- source/core/screenjob.h | 12 +--- source/games/blood/src/credits.cpp | 23 ++++--- source/games/blood/src/endgame.cpp | 10 +-- source/games/duke/src/2d_d.cpp | 92 +++++++++++++-------------- source/games/duke/src/2d_r.cpp | 48 +++++++------- source/games/exhumed/src/2d.cpp | 39 ++++++------ source/games/exhumed/src/exhumed.h | 6 +- source/games/exhumed/src/gameloop.cpp | 8 +-- source/games/sw/src/2d.cpp | 34 +++++----- 10 files changed, 165 insertions(+), 174 deletions(-) diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 5a9991e51..8e8b83bd8 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -117,15 +117,14 @@ void DImageScreen::Draw(double smoothratio) // //--------------------------------------------------------------------------- -ScreenJobRunner::ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_, bool skipall_) +ScreenJobRunner::ScreenJobRunner(TArray& jobs_, CompletionFunc completion_, bool clearbefore_, bool skipall_) : completion(std::move(completion_)), clearbefore(clearbefore_), skipall(skipall_) { - jobs.Resize(count); - memcpy(jobs.Data(), jobs_, count * sizeof(JobDesc)); + jobs = std::move(jobs_); // Release all jobs from the garbage collector - the code as it is cannot deal with them getting collected. This should be removed later once the GC is working. - for (int i = 0; i < count; i++) + for (unsigned i = 0; i < jobs.Size(); i++) { - jobs[i].job->Release(); + jobs[i]->Release(); } AdvanceJob(false); } @@ -145,8 +144,8 @@ void ScreenJobRunner::DeleteJobs() { for (auto& job : jobs) { - job.job->ObjectFlags |= OF_YesReallyDelete; - delete job.job; + job->ObjectFlags |= OF_YesReallyDelete; + delete job; } jobs.Clear(); } @@ -162,19 +161,19 @@ void ScreenJobRunner::AdvanceJob(bool skip) if (index >= 0) { //if (jobs[index].postAction) jobs[index].postAction(); - jobs[index].job->Destroy(); + jobs[index]->Destroy(); } index++; - while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && skipall))) + while (index < jobs.Size() && (jobs[index] == nullptr || (skip && skipall))) { - if (jobs[index].job != nullptr) jobs[index].job->Destroy(); + if (jobs[index] != nullptr) jobs[index]->Destroy(); index++; } actionState = clearbefore ? State_Clear : State_Run; if (index < jobs.Size()) { - jobs[index].job->fadestate = !paused && jobs[index].job->flags & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible; - jobs[index].job->Start(); + jobs[index]->fadestate = !paused && jobs[index]->flags & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible; + jobs[index]->Start(); } inputState.ClearAllInput(); } @@ -189,16 +188,16 @@ int ScreenJobRunner::DisplayFrame(double smoothratio) { auto& job = jobs[index]; auto now = I_GetTimeNS(); - bool processed = job.job->ProcessInput(); + bool processed = job->ProcessInput(); - if (job.job->fadestate == DScreenJob::fadein) + if (job->fadestate == DScreenJob::fadein) { - double ms = (job.job->ticks + smoothratio) * 1000 / GameTicRate / job.job->fadetime; + double ms = (job->ticks + smoothratio) * 1000 / GameTicRate / job->fadetime; float screenfade = (float)clamp(ms, 0., 1.); twod->SetScreenFade(screenfade); - if (screenfade == 1.f) job.job->fadestate = DScreenJob::visible; + if (screenfade == 1.f) job->fadestate = DScreenJob::visible; } - int state = job.job->DrawFrame(smoothratio); + int state = job->DrawFrame(smoothratio); twod->SetScreenFade(1.f); return state; } @@ -206,10 +205,10 @@ int ScreenJobRunner::DisplayFrame(double smoothratio) int ScreenJobRunner::FadeoutFrame(double smoothratio) { auto& job = jobs[index]; - double ms = (fadeticks + smoothratio) * 1000 / GameTicRate / job.job->fadetime; + double ms = (fadeticks + smoothratio) * 1000 / GameTicRate / job->fadetime; float screenfade = 1.f - (float)clamp(ms, 0., 1.); twod->SetScreenFade(screenfade); - job.job->DrawFrame(1.); + job->DrawFrame(1.); return (screenfade > 0.f); } @@ -234,9 +233,9 @@ bool ScreenJobRunner::OnEvent(event_t* ev) } } - if (jobs[index].job->state != DScreenJob::running) return false; + if (jobs[index]->state != DScreenJob::running) return false; - return jobs[index].job->OnEvent(ev); + return jobs[index]->OnEvent(ev); } void ScreenJobRunner::OnFinished() @@ -258,12 +257,12 @@ void ScreenJobRunner::OnTick() } else { - if (jobs[index].job->state == DScreenJob::running) + if (jobs[index]->state == DScreenJob::running) { - jobs[index].job->ticks++; - jobs[index].job->OnTick(); + jobs[index]->ticks++; + jobs[index]->OnTick(); } - else if (jobs[index].job->state == DScreenJob::stopping) + else if (jobs[index]->state == DScreenJob::stopping) { fadeticks++; } @@ -289,8 +288,8 @@ bool ScreenJobRunner::RunFrame() // ensure that we won't go back in time if the menu is dismissed without advancing our ticker bool menuon = paused; - if (menuon) last_paused_tic = jobs[index].job->ticks; - else if (last_paused_tic == jobs[index].job->ticks) menuon = true; + if (menuon) last_paused_tic = jobs[index]->ticks; + else if (last_paused_tic == jobs[index]->ticks) menuon = true; double smoothratio = menuon ? 1. : I_GetTimeFrac(); if (actionState == State_Clear) @@ -304,10 +303,10 @@ bool ScreenJobRunner::RunFrame() if (terminateState < 1) { // Must lock before displaying. - if (jobs[index].job->flags & DScreenJob::fadeout) + if (jobs[index]->flags & DScreenJob::fadeout) { - jobs[index].job->fadestate = DScreenJob::fadeout; - jobs[index].job->state = DScreenJob::stopping; + jobs[index]->fadestate = DScreenJob::fadeout; + jobs[index]->state = DScreenJob::stopping; actionState = State_Fadeout; fadeticks = 0; } @@ -322,7 +321,7 @@ bool ScreenJobRunner::RunFrame() int ended = FadeoutFrame(smoothratio); if (ended < 1) { - jobs[index].job->state = DScreenJob::stopped; + jobs[index]->state = DScreenJob::stopped; AdvanceJob(terminateState < 0); } } @@ -337,13 +336,13 @@ bool ScreenJobRunner::RunFrame() ScreenJobRunner *runner; -void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, int flags) +void RunScreenJob(TArray& jobs, CompletionFunc completion, int flags) { assert(completion != nullptr); videoclearFade(); - if (count) + if (jobs.Size()) { - runner = new ScreenJobRunner(jobs, count, completion, !(flags & SJ_DONTCLEAR), !!(flags & SJ_SKIPALL)); + runner = new ScreenJobRunner(jobs, completion, !(flags & SJ_DONTCLEAR), !!(flags & SJ_SKIPALL)); gameaction = (flags & SJ_BLOCKUI)? ga_intro : ga_intermission; } else diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 4dd35dd56..aa02c075e 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -138,12 +138,6 @@ public: // //--------------------------------------------------------------------------- -struct JobDesc -{ - DScreenJob* job; -}; - - class ScreenJobRunner { enum @@ -152,7 +146,7 @@ class ScreenJobRunner State_Run, State_Fadeout }; - TArray jobs; + TArray jobs; CompletionFunc completion; int index = -1; float screenfade; @@ -164,7 +158,7 @@ class ScreenJobRunner int last_paused_tic = -1; public: - ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_, bool skipall_); + ScreenJobRunner(TArray& jobs, CompletionFunc completion_, bool clearbefore_, bool skipall_); ~ScreenJobRunner(); void DeleteJobs(); void AdvanceJob(bool skip); @@ -186,7 +180,7 @@ enum }; -void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, int flags = 0); +void RunScreenJob(TArray& jobs, CompletionFunc completion, int flags = 0); void EndScreenJob(); void DeleteScreenJob(); bool ScreenJobResponder(event_t* ev); diff --git a/source/games/blood/src/credits.cpp b/source/games/blood/src/credits.cpp index 89efa42ed..4919c2219 100644 --- a/source/games/blood/src/credits.cpp +++ b/source/games/blood/src/credits.cpp @@ -59,8 +59,7 @@ public: void playlogos() { - JobDesc jobs[6]; - int job = 0; + TArray jobs; static AnimSound logosound[] = { { 1, -1 }, @@ -80,25 +79,25 @@ void playlogos() { if (fileSystem.FindFile("logo.smk") != -1) { - jobs[job++] = { PlayVideo("logo.smk", &logosound[0], 0) }; + jobs.Push(PlayVideo("logo.smk", &logosound[0], 0)); } else { - jobs[job++] = { Create(2050) }; + jobs.Push(Create(2050)); } if (fileSystem.FindFile("gti.smk") != -1) { - jobs[job++] = { PlayVideo("gti.smk", &logosound[2], 0) }; + jobs.Push(PlayVideo("gti.smk", &logosound[2], 0)); } else { - jobs[job++] = { Create(2052) }; + jobs.Push(Create(2052)); } } - jobs[job++] = { Create(1) }; - jobs[job++] = { Create(2518, DScreenJob::fadein, true) }; + jobs.Push(Create(1)); + jobs.Push(Create(2518, DScreenJob::fadein, true)); - RunScreenJob(jobs, job, [](bool) { + RunScreenJob(jobs, [](bool) { Mus_Stop(); gameaction = ga_mainmenu; }, SJ_BLOCKUI); @@ -106,7 +105,7 @@ void playlogos() void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func) { - JobDesc jobs{}; + TArray jobs; static AnimSound smksound[] = { { 1, -1 }, @@ -127,8 +126,8 @@ void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func) FString smkk = smk; FixPathSeperator(smkk); smksound[0].soundnum = id; - jobs.job = PlayVideo(smkk, smksound, nullptr); - RunScreenJob(&jobs, 1, func); + jobs.Push(PlayVideo(smkk, smksound, nullptr)); + RunScreenJob(jobs, func); } void levelPlayIntroScene(int nEpisode, CompletionFunc completion) diff --git a/source/games/blood/src/endgame.cpp b/source/games/blood/src/endgame.cpp index a50b2e298..16f163b5b 100644 --- a/source/games/blood/src/endgame.cpp +++ b/source/games/blood/src/endgame.cpp @@ -173,10 +173,11 @@ class DBloodSummaryScreen : public DSkippableScreenJob void GameInterface::LevelCompleted(MapRecord *map, int skill) { - JobDesc job = { Create() }; + TArray job(1, true); + job[0] = Create(); sndStartSample(268, 128, -1, false, CHANF_UI); Mus_Stop(); - RunScreenJob(&job, 1, [=](bool) + RunScreenJob(job, [=](bool) { soundEngine->StopAllChannels(); gameaction = ga_nextlevel; @@ -301,8 +302,9 @@ public: void loadscreen(const char *caption, MapRecord* rec, CompletionFunc func) { - JobDesc job = { Create(caption, rec) }; - RunScreenJob(&job, 1, func); + TArray job(1, true); + job[0] = Create(caption, rec); + RunScreenJob(job, func); } diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index da895e94d..f4cce3d97 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -312,15 +312,15 @@ void Logo_d(const CompletionFunc &completion) }; static const int logoframetimes[] = { 9, 9, 9 }; - JobDesc jobs[3]; + TArray jobs; int job = 0; if (!userConfig.nologo) { - if (!isShareware()) jobs[job++] = { PlayVideo("logo.anm", logosound, logoframetimes) }; - if (!isNam()) jobs[job++] = { Create(), }; + if (!isShareware()) jobs.Push(PlayVideo("logo.anm", logosound, logoframetimes)); + if (!isNam()) jobs.Push(Create()); } - jobs[job++] = { Create() }; - RunScreenJob(jobs, job, completion, SJ_BLOCKUI); + jobs.Push(Create()); + RunScreenJob(jobs, completion, SJ_BLOCKUI); } //--------------------------------------------------------------------------- @@ -612,7 +612,7 @@ public: // //--------------------------------------------------------------------------- -static void bonussequence_d(int num, JobDesc *jobs, int &job) +static void bonussequence_d(int num, TArray& jobs) { static const AnimSound cineov2sound[] = { @@ -679,45 +679,45 @@ static void bonussequence_d(int num, JobDesc *jobs, int &job) switch (num) { case 0: - jobs[job++] = { Create() }; - jobs[job++] = { Create(E1ENDSCREEN, DScreenJob::fadein|DScreenJob::fadeout|DScreenJob::stopmusic, 0x7fffffff) }; + jobs.Push(Create()); + jobs.Push(Create(E1ENDSCREEN, DScreenJob::fadein|DScreenJob::fadeout|DScreenJob::stopmusic, 0x7fffffff)); break; case 1: Mus_Stop(); - jobs[job++] = { PlayVideo("cineov2.anm", cineov2sound, framespeed_18) }; - jobs[job++] = { Create() }; + jobs.Push(PlayVideo("cineov2.anm", cineov2sound, framespeed_18)); + jobs.Push(Create()); break; case 2: Mus_Stop(); if (g_gameType & GAMEFLAG_DUKEDC) { - jobs[job++] = { PlayVideo("radlogo.anm", dukedcsound, framespeed_10) }; + jobs.Push(PlayVideo("radlogo.anm", dukedcsound, framespeed_10)); } else { - jobs[job++] = { PlayVideo("cineov3.anm", cineov3sound, framespeed_10) }; - jobs[job++] = { Create(200, DScreenJob::stopsound) }; - jobs[job++] = { Create() }; - if (!isPlutoPak()) jobs[job++] = { Create(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), - DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff) }; + jobs.Push(PlayVideo("cineov3.anm", cineov3sound, framespeed_10)); + jobs.Push(Create(200, DScreenJob::stopsound)); + jobs.Push(Create()); + if (!isPlutoPak()) jobs.Push(Create(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), + DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff)); } break; case 3: Mus_Stop(); - jobs[job++] = { PlayVideo("vol4e1.anm", vol4e1, framespeed_10) }; - jobs[job++] = { PlayVideo("vol4e2.anm", vol4e2, framespeed_10) }; - jobs[job++] = { PlayVideo("vol4e3.anm", vol4e3, framespeed_10) }; - jobs[job++] = { Create() }; - jobs[job++] = { Create(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), - DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff) }; + jobs.Push(PlayVideo("vol4e1.anm", vol4e1, framespeed_10)); + jobs.Push(PlayVideo("vol4e2.anm", vol4e2, framespeed_10)); + jobs.Push(PlayVideo("vol4e3.anm", vol4e3, framespeed_10)); + jobs.Push(Create()); + jobs.Push(Create(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), + DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff)); break; case 4: Mus_Stop(); - jobs[job++] = { Create() }; + jobs.Push(Create()); break; } } @@ -730,22 +730,20 @@ static void bonussequence_d(int num, JobDesc *jobs, int &job) void showtwoscreens(const CompletionFunc& completion) { - JobDesc jobs[2]; - int job = 0; + TArray jobs; - jobs[job++] = { Create(3291) }; - jobs[job++] = { Create(3290) }; - RunScreenJob(jobs, job, completion); + jobs.Push(Create(3291)); + jobs.Push(Create(3290)); + RunScreenJob(jobs, completion); } void doorders(const CompletionFunc& completion) { - JobDesc jobs[4]; - int job = 0; + TArray jobs; for (int i = 0; i < 4; i++) - jobs[job++] = { Create(ORDERING + i) }; - RunScreenJob(jobs, job, completion); + jobs.Push(Create(ORDERING + i)); + RunScreenJob(jobs, completion); } //--------------------------------------------------------------------------- @@ -1097,29 +1095,28 @@ public: void dobonus_d(int bonusonly, const CompletionFunc& completion) { - JobDesc jobs[20]; - int job = 0; + TArray jobs; FX_StopAllSounds(); if (bonusonly < 0 && numplayers < 2 && ud.from_bonus == 0) { - bonussequence_d(volfromlevelnum(currentLevel->levelNumber), jobs, job); + bonussequence_d(volfromlevelnum(currentLevel->levelNumber), jobs); } else Mus_Stop(); if (playerswhenstarted > 1 && ud.coop != 1) { - jobs[job++] = { Create(playerswhenstarted) }; + jobs.Push(Create(playerswhenstarted)); } else if (bonusonly <= 0 && ud.multimode <= 1) { - jobs[job++] = { Create() }; + jobs.Push(Create()); } - if (job) + if (jobs.Size()) { - RunScreenJob(jobs, job, completion); + RunScreenJob(jobs, completion); } else if (completion) completion(false); } @@ -1132,8 +1129,7 @@ void dobonus_d(int bonusonly, const CompletionFunc& completion) void e4intro(const CompletionFunc& completion) { - JobDesc jobs[5]; - int job = 0; + TArray jobs; static const AnimSound vol42a[] = { @@ -1163,10 +1159,10 @@ void e4intro(const CompletionFunc& completion) static const int framespeed_14[] = { 14, 14, 14 }; S_PlaySpecialMusic(MUS_BRIEFING); - jobs[job++] = { PlayVideo("vol41a.anm", vol41a, framespeed_10) }; - jobs[job++] = { PlayVideo("vol42a.anm", vol42a, framespeed_14) }; - jobs[job++] = { PlayVideo("vol43a.anm", vol43a, framespeed_10) }; - RunScreenJob(jobs, job, completion, SJ_SKIPALL); + jobs.Push(PlayVideo("vol41a.anm", vol41a, framespeed_10)); + jobs.Push(PlayVideo("vol42a.anm", vol42a, framespeed_14)); + jobs.Push(PlayVideo("vol43a.anm", vol43a, framespeed_10)); + RunScreenJob(jobs, completion, SJ_SKIPALL); } //--------------------------------------------------------------------------- @@ -1194,8 +1190,10 @@ public: void loadscreen_d(MapRecord *rec, CompletionFunc func) { - JobDesc job = { Create(rec) }; - RunScreenJob(&job, 1, func); + TArray jobs(1, true); + + jobs[0] = Create(rec); + RunScreenJob(jobs, func); } void PrintPaused_d() diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index 27bd4bd1d..101c41567 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -186,8 +186,7 @@ void Logo_r(const CompletionFunc& completion) static const int framespeed[] = { 9, 9, 9 }; // same for all 3 anims - JobDesc jobs[3]; - int job = 0; + TArray jobs; if (userConfig.nologo) { @@ -196,15 +195,15 @@ void Logo_r(const CompletionFunc& completion) } else if (!isRRRA()) { - jobs[job++] = { PlayVideo("rr_intro.anm", introsound, framespeed) }; - jobs[job++] = { PlayVideo("redneck.anm", rednecksound, framespeed) }; - jobs[job++] = { PlayVideo("xatlogo.anm", xatrixsound, framespeed) }; + jobs.Push(PlayVideo("rr_intro.anm", introsound, framespeed)); + jobs.Push(PlayVideo("redneck.anm", rednecksound, framespeed)); + jobs.Push(PlayVideo("xatlogo.anm", xatrixsound, framespeed)); } else { - jobs[job++] = { PlayVideo("redint.mve") }; + jobs.Push(PlayVideo("redint.mve")); } - RunScreenJob(jobs, job, completion, SJ_BLOCKUI); + RunScreenJob(jobs, completion, SJ_BLOCKUI); } //--------------------------------------------------------------------------- @@ -213,7 +212,7 @@ void Logo_r(const CompletionFunc& completion) // //--------------------------------------------------------------------------- -static void bonussequence_r(int num, JobDesc* jobs, int& job) +static void bonussequence_r(int num, TArray& jobs) { static const AnimSound turdmov[] = { @@ -235,13 +234,13 @@ static void bonussequence_r(int num, JobDesc* jobs, int& job) switch (num) { case 0: - jobs[job++] = { PlayVideo("turdmov.anm", turdmov, framespeed) }; - jobs[job++] = { Create(TENSCREEN) }; + jobs.Push(PlayVideo("turdmov.anm", turdmov, framespeed)); + jobs.Push(Create(TENSCREEN)); break; case 1: - jobs[job++] = { PlayVideo("rr_outro.anm", rr_outro, framespeed) }; - jobs[job++] = { Create(TENSCREEN) }; + jobs.Push(PlayVideo("rr_outro.anm", rr_outro, framespeed)); + jobs.Push(Create(TENSCREEN)); break; default: @@ -594,8 +593,7 @@ public: void dobonus_r(int bonusonly, const CompletionFunc& completion) { - JobDesc jobs[20]; - int job = 0; + TArray jobs; FX_StopAllSounds(); Mus_Stop(); @@ -603,32 +601,32 @@ void dobonus_r(int bonusonly, const CompletionFunc& completion) if (bonusonly < 0 && !isRRRA() && numplayers < 2 && ud.from_bonus == 0) { int vol = volfromlevelnum(currentLevel->levelNumber); - bonussequence_r(vol, jobs, job); + bonussequence_r(vol, jobs); } if (playerswhenstarted > 1 && ud.coop != 1) { - jobs[job++] = { Create(playerswhenstarted) }; + jobs.Push(Create(playerswhenstarted)); } else if (bonusonly <= 0 && ud.multimode <= 1) { if (isRRRA() && !(currentLevel->flags & MI_USERMAP) && currentLevel->levelNumber < 106) // fixme: The logic here is awful. Shift more control to the map records. { - jobs[job++] = { Create(true) }; + jobs.Push(Create(true)); int levnum = clamp((currentLevel->levelNumber / 100) * 7 + (currentLevel->levelNumber % 100), 0, 13); char fn[20]; mysnprintf(fn, 20, "lvl%d.anm", levnum + 1); static const int framespeed[] = { 20, 20, 7200 }; // wait for one minute on the final frame so that the video doesn't stop before the user notices. - jobs[job++] = { PlayVideo(fn, nullptr, framespeed) }; + jobs.Push(PlayVideo(fn, nullptr, framespeed)); if (bonusonly < 0 && currentLevel->levelNumber > 100) { - jobs[job++] = { Create() }; + jobs.Push(Create()); } } - else jobs[job++] = { Create(false) }; + else jobs.Push(Create(false)); } - if (job) - RunScreenJob(jobs, job, completion); + if (jobs.Size()) + RunScreenJob(jobs, completion); else if (completion) completion(false); } @@ -658,8 +656,10 @@ public: void loadscreen_r(MapRecord* rec, CompletionFunc func) { - JobDesc job = { Create(rec) }; - RunScreenJob(&job, 1, func); + TArray jobs(1, true); + + jobs[0] = Create(rec); + RunScreenJob(jobs, func); } void PrintPaused_r() diff --git a/source/games/exhumed/src/2d.cpp b/source/games/exhumed/src/2d.cpp index 7c0b8da0f..b982bc7e1 100644 --- a/source/games/exhumed/src/2d.cpp +++ b/source/games/exhumed/src/2d.cpp @@ -520,15 +520,14 @@ DScreenJob *PlayMovie(const char* fileName); void DoTitle(CompletionFunc completion) { - JobDesc jobs[5]; - int job = 0; + TArray jobs; - jobs[job++] = { Create(tileGetTexture(PublisherLogo()), DScreenJob::fadein | DScreenJob::fadeout) }; - jobs[job++] = { Create(tileGetTexture(seq_GetSeqPicnum(kSeqScreens, 0, 0)), DScreenJob::fadein | DScreenJob::fadeout) }; - jobs[job++] = { PlayMovie("book.mov") }; - jobs[job++] = { Create() }; + jobs.Push(Create(tileGetTexture(PublisherLogo()), DScreenJob::fadein | DScreenJob::fadeout)); + jobs.Push(Create(tileGetTexture(seq_GetSeqPicnum(kSeqScreens, 0, 0)), DScreenJob::fadein | DScreenJob::fadeout)); + jobs.Push(PlayMovie("book.mov")); + jobs.Push(Create()); - RunScreenJob(jobs, job, completion, SJ_BLOCKUI); + RunScreenJob(jobs, completion, SJ_BLOCKUI); } @@ -815,7 +814,7 @@ public: } }; - void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray &jobs) + void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray &jobs) { if (nLevel > kMap20 || nLevelNew > kMap20) // max single player levels { @@ -829,7 +828,7 @@ public: if (nLevelNew < 1) nLevelNew = nLevel; // 0-offset the level numbers - jobs.Push( { Create(nLevel-1, nLevelNew-1, nLevelBest-1) }); + jobs.Push(Create(nLevel-1, nLevelNew-1, nLevelBest-1)); } //--------------------------------------------------------------------------- @@ -1346,37 +1345,37 @@ public: void DoGameOverScene(bool finallevel) { - JobDesc job; + TArray jobs(1, true); if (finallevel) { - job = { Create(CINEMA_LOSE_SCENE) }; + jobs[0] = Create(CINEMA_LOSE_SCENE); } else { StopCD(); PlayGameOverSound(); - job = { Create(tileGetTexture(kTile3591), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff, TRANSLATION(Translation_BasePalettes, 16)) }; + jobs[0] = Create(tileGetTexture(kTile3591), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff, TRANSLATION(Translation_BasePalettes, 16)); } - RunScreenJob(&job, 1, [](bool) { gameaction = ga_mainmenu; }); + RunScreenJob(jobs, [](bool) { gameaction = ga_mainmenu; }); } -void DoAfterCinemaScene(int nLevel, TArray& jobs) +void DoAfterCinemaScene(int nLevel, TArray& jobs) { int scene = -1; if (nLevel == 10) scene = CINEMA_AFTER_LEVEL_10; if (nLevel == 15) scene = CINEMA_AFTER_LEVEL_15; if (nLevel == 20) scene = CINEMA_AFTER_LEVEL_20; - if (scene > 0) jobs.Push({ Create(scene) }); - if (nLevel == 19) { jobs.Push({ Create() }); selectedlevelnew = 20; } - if (nLevel == 20) jobs.Push({ Create() }); + if (scene > 0) jobs.Push(Create(scene)); + if (nLevel == 19) { jobs.Push(Create()); selectedlevelnew = 20; } + if (nLevel == 20) jobs.Push(Create()); } -void DoBeforeCinemaScene(int nLevel, TArray& jobs) +void DoBeforeCinemaScene(int nLevel, TArray& jobs) { - if (nLevel == 5) jobs.Push({ Create(CINEMA_BEFORE_LEVEL_5) }); - else if (nLevel == 11) jobs.Push({ Create(CINEMA_BEFORE_LEVEL_11, 11) }); + if (nLevel == 5) jobs.Push(Create(CINEMA_BEFORE_LEVEL_5)); + else if (nLevel == 11) jobs.Push(Create(CINEMA_BEFORE_LEVEL_11, 11)); } END_PS_NS diff --git a/source/games/exhumed/src/exhumed.h b/source/games/exhumed/src/exhumed.h index 87bdc393e..81ae0916d 100644 --- a/source/games/exhumed/src/exhumed.h +++ b/source/games/exhumed/src/exhumed.h @@ -54,8 +54,8 @@ void SetHiRes(); void BlackOut(); void DoGameOverScene(bool finallevel); -void DoAfterCinemaScene(int nLevel, TArray &jobs); -void DoBeforeCinemaScene(int nLevel, TArray& jobs); +void DoAfterCinemaScene(int nLevel, TArray &jobs); +void DoBeforeCinemaScene(int nLevel, TArray& jobs); int Query(short n, short l, ...); @@ -88,7 +88,7 @@ void InitNewGame(); int showmap(short nLevel, short nLevelNew, short nLevelBest); void menu_DoPlasma(); -void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray& jobs); +void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray& jobs); void DoEnergyTile(); void InitEnergyTile(); diff --git a/source/games/exhumed/src/gameloop.cpp b/source/games/exhumed/src/gameloop.cpp index d810eab56..dd3ef421e 100644 --- a/source/games/exhumed/src/gameloop.cpp +++ b/source/games/exhumed/src/gameloop.cpp @@ -62,7 +62,7 @@ void DrawClock(); double calc_smoothratio(); void DoTitle(CompletionFunc completion); -static void showmap(short nLevel, short nLevelNew, short nLevelBest, TArray &jobs) +static void showmap(short nLevel, short nLevelNew, short nLevelBest, TArray &jobs) { if (nLevelNew == 5 && !(nCinemaSeen & 1)) { nCinemaSeen |= 1; @@ -135,7 +135,7 @@ void GameInterface::DrawBackground() static void Intermission(MapRecord *from_map, MapRecord *to_map) { - TArray jobs; + TArray jobs; if (from_map) StopAllSounds(); bCamera = false; @@ -167,7 +167,7 @@ static void Intermission(MapRecord *from_map, MapRecord *to_map) showmap(from_map ? from_map->levelNumber : -1, to_map->levelNumber, nBestLevel, jobs); } else - jobs.Push({ Create(1) }); // we need something in here even in the multiplayer case. + jobs.Push(Create(1)); // we need something in here even in the multiplayer case. } } else @@ -179,7 +179,7 @@ static void Intermission(MapRecord *from_map, MapRecord *to_map) if (jobs.Size() > 0) { - RunScreenJob(jobs.Data(), jobs.Size(), [=](bool) + RunScreenJob(jobs, [=](bool) { if (!to_map) gameaction = ga_startup; // this was the end of the game else diff --git a/source/games/sw/src/2d.cpp b/source/games/sw/src/2d.cpp index 325a44430..eca216415 100644 --- a/source/games/sw/src/2d.cpp +++ b/source/games/sw/src/2d.cpp @@ -88,11 +88,10 @@ void Logo(const CompletionFunc& completion) if (!userConfig.nologo) { - JobDesc jobs[3]; - int job = 0; - jobs[job++] = { Create() }; - jobs[job++] = { PlayVideo("sw.anm", logosound, logoframetimes, true)}; - RunScreenJob(jobs, job, completion, SJ_BLOCKUI); + TArray jobs; + jobs.Push(Create()); + jobs.Push(PlayVideo("sw.anm", logosound, logoframetimes, true)); + RunScreenJob(jobs, completion, SJ_BLOCKUI); } else completion(false); } @@ -606,26 +605,25 @@ class DSWMultiSummaryScreen : public DSkippableScreenJob void StatScreen(int FinishAnim, CompletionFunc completion) { - JobDesc jobs[5]; - int job = 0; + TArray jobs; if (FinishAnim) { StopSound(); - jobs[job++] = { GetFinishAnim(FinishAnim) }; - jobs[job++] = { Create() }; + jobs.Push(GetFinishAnim(FinishAnim)); + jobs.Push(Create()); if (FinishAnim == ANIM_ZILLA) - jobs[job++] = { Create() }; + jobs.Push(Create()); } else if (gNet.MultiGameType != MULTI_GAME_COMMBAT) { - jobs[job++] = { Create() }; + jobs.Push(Create()); } else { - jobs[job++] = { Create() }; + jobs.Push(Create()); } - RunScreenJob(jobs, job, completion); + RunScreenJob(jobs, completion); } //--------------------------------------------------------------------------- @@ -639,8 +637,9 @@ void SybexScreen(CompletionFunc completion) if (!SW_SHAREWARE || CommEnabled) completion(false); else { - JobDesc job = { Create(tileGetTexture(5261), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff) }; - RunScreenJob(&job, 1, completion, SJ_BLOCKUI); + TArray jobs(1, true); + jobs[0] = Create(tileGetTexture(5261), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff); + RunScreenJob(jobs, completion, SJ_BLOCKUI); } } @@ -670,8 +669,9 @@ public: void loadscreen(MapRecord* rec, CompletionFunc func) { - JobDesc job = { Create(rec) }; - RunScreenJob(&job, 1, func); + TArray jobs(1, true); + jobs[0] = Create(rec); + RunScreenJob(jobs, func); } END_SW_NS From 1022564cab5591e1846cbdc2c386a9653eea8034 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 18:52:39 +0200 Subject: [PATCH 07/86] - initial framework for scriptification of screen jobs. --- source/common/2d/v_draw.cpp | 8 ++ .../common/scripting/interface/vmnatives.cpp | 15 +++ source/core/screenjob.cpp | 96 +++++++++++++++++++ source/core/screenjob.h | 10 +- source/games/duke/src/sounds.cpp | 9 ++ wadsrc/static/zscript.txt | 3 + wadsrc/static/zscript/engine/base.zs | 2 + wadsrc/static/zscript/games/duke/dukegame.zs | 26 +++++ .../static/zscript/games/duke/ui/screens.zs | 35 +++++++ wadsrc/static/zscript/screenjob.zs | 87 +++++++++++++++++ 10 files changed, 289 insertions(+), 2 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/dukegame.zs create mode 100644 wadsrc/static/zscript/games/duke/ui/screens.zs create mode 100644 wadsrc/static/zscript/screenjob.zs diff --git a/source/common/2d/v_draw.cpp b/source/common/2d/v_draw.cpp index 70bf53042..7250a11c9 100644 --- a/source/common/2d/v_draw.cpp +++ b/source/common/2d/v_draw.cpp @@ -324,6 +324,14 @@ DEFINE_ACTION_FUNCTION(_Screen, ClearClipRect) return 0; } +DEFINE_ACTION_FUNCTION(_Screen, ClearScreen) +{ + PARAM_PROLOGUE; + twod->ClearScreen(); + return 0; +} + + void F2DDrawer::GetClipRect(int *x, int *y, int *w, int *h) { if (x) *x = clipleft; diff --git a/source/common/scripting/interface/vmnatives.cpp b/source/common/scripting/interface/vmnatives.cpp index 502d78de3..c196c7d93 100644 --- a/source/common/scripting/interface/vmnatives.cpp +++ b/source/common/scripting/interface/vmnatives.cpp @@ -49,6 +49,7 @@ #include "s_music.h" #include "i_interface.h" #include "base_sbar.h" +#include "image.h" //========================================================================== // @@ -477,6 +478,20 @@ DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, OkForLocalization, OkForLocalization_) ACTION_RETURN_INT(OkForLocalization_(name, subst)); } +static int UseGamePalette(int index) +{ + auto tex = TexMan.GameByIndex(index, false); + if (!tex) return false; + auto image = tex->GetTexture()->GetImage(); + return image ? image->UseGamePalette() : false; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, UseGamePalette, UseGamePalette) +{ + PARAM_PROLOGUE; + PARAM_INT(texid); + ACTION_RETURN_INT(UseGamePalette(texid)); +} //===================================================================================== // diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 8e8b83bd8..b80f22a39 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -51,11 +51,107 @@ #include #include #include "raze_music.h" +#include "vm.h" IMPLEMENT_CLASS(DScreenJob, true, false) +IMPLEMENT_CLASS(DSkippableScreenJob, true, false) +IMPLEMENT_CLASS(DBlackScreen, true, false) IMPLEMENT_CLASS(DImageScreen, true, false) +DEFINE_FIELD(DScreenJob, flags) +DEFINE_FIELD(DScreenJob, fadetime) +DEFINE_FIELD_NAMED(DScreenJob, state, jobstate) +DEFINE_FIELD(DScreenJob, fadestate) +DEFINE_FIELD(DScreenJob, ticks) +DEFINE_FIELD(DScreenJob, pausable) + +DEFINE_FIELD(DBlackScreen, wait) +DEFINE_FIELD(DBlackScreen, cleared) + +DEFINE_FIELD(DImageScreen, tilenum) +DEFINE_FIELD(DImageScreen, trans) +DEFINE_FIELD(DImageScreen, waittime) +DEFINE_FIELD(DImageScreen, cleared) +DEFINE_FIELD(DImageScreen, texid) + +DEFINE_ACTION_FUNCTION(DScreenJob, Init) +{ + // todo + return 0; +} + +DEFINE_ACTION_FUNCTION(DScreenJob, ProcessInput) +{ + PARAM_SELF_PROLOGUE(DScreenJob); + ACTION_RETURN_BOOL(self->ProcessInput()); +} + +DEFINE_ACTION_FUNCTION(DScreenJob, Start) +{ + PARAM_SELF_PROLOGUE(DScreenJob); + self->Start(); + return 0; +} + +DEFINE_ACTION_FUNCTION(DScreenJob, OnEvent) +{ + PARAM_SELF_PROLOGUE(DScreenJob); + PARAM_POINTER(evt, FInputEvent); + if (evt->Type != EV_KeyDown) + { + // not needed in the transition phase + ACTION_RETURN_BOOL(false); + } + event_t ev = {}; + ev.type = EV_KeyDown; + ev.data1 = evt->KeyScan; + ACTION_RETURN_BOOL(self->OnEvent(&ev)); +} + +DEFINE_ACTION_FUNCTION(DScreenJob, OnTick) +{ + PARAM_SELF_PROLOGUE(DScreenJob); + self->OnTick(); + return 0; +} + +DEFINE_ACTION_FUNCTION(DScreenJob, Draw) +{ + PARAM_SELF_PROLOGUE(DScreenJob); + PARAM_FLOAT(smooth); + self->Draw(smooth); + return 0; +} + +DEFINE_ACTION_FUNCTION(DSkippableScreenJob, Init) +{ + // todo + return 0; +} + +DEFINE_ACTION_FUNCTION(DSkippableScreenJob, Skipped) +{ + PARAM_SELF_PROLOGUE(DSkippableScreenJob); + self->Skipped(); + return 0; +} + +DEFINE_ACTION_FUNCTION(DBlackScreen, Init) +{ + // todo + return 0; +} + +DEFINE_ACTION_FUNCTION(DImageScreen, Init) +{ + // todo + return 0; +} + + + + void DScreenJob::OnDestroy() { if (flags & stopmusic) Mus_Stop(); diff --git a/source/core/screenjob.h b/source/core/screenjob.h index aa02c075e..3916a3373 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -12,12 +12,13 @@ class ScreenJobRunner; class DScreenJob : public DObject { DECLARE_CLASS(DScreenJob, DObject) +public: const int flags; const float fadetime; // in milliseconds int fadestate = fadein; friend class ScreenJobRunner; -protected: +//protected: int ticks = 0; int state = running; bool pausable = true; @@ -74,7 +75,8 @@ public: class DSkippableScreenJob : public DScreenJob { -protected: + DECLARE_CLASS(DSkippableScreenJob, DScreenJob) +public: DSkippableScreenJob(int fade = 0, float fadet = 250.f) : DScreenJob(fade, fadet) {} @@ -90,6 +92,8 @@ protected: class DBlackScreen : public DScreenJob { + DECLARE_CLASS(DBlackScreen, DScreenJob) +public: int wait; bool cleared = false; @@ -109,10 +113,12 @@ 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: diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index c9214b65b..8a4abf5ff 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -46,6 +46,7 @@ source as it is released. #include "gamestate.h" #include "names_d.h" #include "i_music.h" +#include "vm.h" CVAR(Bool, wt_forcemidi, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // quick hack to disable the oggs, which are of lower quality than playing the MIDIs with a good synth and sound font. CVAR(Bool, wt_forcevoc, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // The same for sound effects. The re-recordings are rather poor and disliked @@ -719,6 +720,14 @@ void S_PlaySpecialMusic(unsigned int m) } } +DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PlaySpecialMusic, S_PlaySpecialMusic) +{ + PARAM_PROLOGUE; + PARAM_INT(song); + S_PlaySpecialMusic(song); + return 0; +} + //--------------------------------------------------------------------------- // // diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index da000f758..44b9bc8ee 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -28,6 +28,9 @@ version "4.3" #include "zscript/constants.zs" #include "zscript/razebase.zs" +#include "zscript/screenjob.zs" +#include "zscript/games/duke/dukegame.zs" +#include "zscript/games/duke/ui/screens.zs" #include "zscript/games/duke/ui/menu.zs" #include "zscript/games/blood/ui/menu.zs" #include "zscript/games/sw/ui/menu.zs" diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index a0b2a0c83..3a3a4fb3b 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -239,6 +239,7 @@ struct TexMan native static Vector2 GetScaledOffset(TextureID tex); native static int CheckRealHeight(TextureID tex); native static bool OkForLocalization(TextureID patch, String textSubstitute); + native static bool UseGamePalette(TextureID tex); } enum EScaleMode @@ -402,6 +403,7 @@ struct Screen native native static int, int, int, int GetViewWindow(); native static double, double, double, double GetFullscreenRect(double vwidth, double vheight, int fsmode); native static Vector2 SetOffset(double x, double y); + native static void ClearScreen(color col = 0); } struct Font native diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs new file mode 100644 index 000000000..7b47cff15 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -0,0 +1,26 @@ +// contains all global Duke definitions +struct Duke native +{ + enum ESpecialMusic + { + MUS_INTRO = 0, + MUS_BRIEFING = 1, + MUS_LOADING = 2, + }; + + enum EPalette + { + BASEPAL = 0, + WATERPAL, + SLIMEPAL, + TITLEPAL, + DREALMSPAL, + ENDINGPAL, // 5 + ANIMPAL, // not used anymore. The anim code now generates true color textures. + DRUGPAL, + BASEPALCOUNT + }; + + + native static void PlaySpecialMusic(int which); +} diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs new file mode 100644 index 000000000..324e0a03e --- /dev/null +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -0,0 +1,35 @@ + + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DRealmsScreen : SkippableScreenJob +{ + void Init() + { + Super.Init(fadein | fadeout); + } + + override void Start() + { + Duke.PlaySpecialMusic(Duke.MUS_INTRO); + } + + override void OnTick() + { + if (ticks >= 7 * GameTicRate) jobstate = finished; + } + + override void Draw(double smoothratio) + { + let tex = TexMan.CheckForTexture("DREALMS"); + int translation = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.DREALMSPAL) : 0; + + screen.ClearScreen(); + screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal); + } +} + diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs new file mode 100644 index 000000000..5c8f7f25a --- /dev/null +++ b/wadsrc/static/zscript/screenjob.zs @@ -0,0 +1,87 @@ + +class ScreenJob native +{ + native int flags; + native float fadetime; // in milliseconds + native int fadestate; + + native int ticks; + native int jobstate; + native bool pausable; + + enum EJobState + { + 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 EJobFlags + { + visible = 0, + fadein = 1, + fadeout = 2, + stopmusic = 4, + stopsound = 8, + }; + + native void Init(int flags = 0, float fadet = 250.f); + native virtual bool ProcessInput(); + native virtual void Start(); + native virtual bool OnEvent(InputEvent evt); + native virtual void OnTick(); + native virtual void Draw(double smoothratio); + + //native int DrawFrame(double smoothratio); + //native int GetFadeState(); + //native override void OnDestroy(); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class SkippableScreenJob : ScreenJob native +{ + native void Init(int flags = 0, float fadet = 250.f); + //native override bool OnEvent(InputEvent evt); + virtual void Skipped() {} +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class BlackScreen : ScreenJob native +{ + native int wait; + native bool cleared; + + native void Init(int w, int flags = 0); + //override void OnTick(); + //override void Draw(double smooth); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class ImageScreen : SkippableScreenJob native +{ + native int tilenum; + native int trans; + native int waittime; // in ms. + native bool cleared; + native TextureID texid; + + native void Init(TextureID tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0); + //override void OnTick(); + //override void Draw(double smooth); +} From e75f0c17e490456748802567acbe379f98528319 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 19:59:45 +0200 Subject: [PATCH 08/86] - ported the TitleScreen class. --- source/core/gamecontrol.cpp | 6 + source/games/duke/src/dispatch.cpp | 2 - source/games/duke/src/flags_d.cpp | 4 - source/games/duke/src/flags_r.cpp | 4 - source/games/duke/src/namelist_d.h | 1 + source/games/duke/src/names.h | 4 - source/games/duke/src/sounds.cpp | 32 +- wadsrc/static/zscript/games/duke/dukegame.zs | 411 +++++++++++++++++- .../static/zscript/games/duke/ui/screens.zs | 101 +++++ wadsrc/static/zscript/razebase.zs | 58 +++ 10 files changed, 600 insertions(+), 23 deletions(-) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 75b4b577e..c3e0c027c 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -73,6 +73,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "automap.h" #include "v_draw.h" #include "gi.h" +#include "vm.h" CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -275,6 +276,11 @@ void System_CrashInfo(char* buffer, size_t bufflen, const char *lfstr) UserConfig userConfig; +DEFINE_GLOBAL(userConfig) +DEFINE_FIELD_X(UserConfigStruct, UserConfig, nomonsters) +DEFINE_FIELD_X(UserConfigStruct, UserConfig, nosound) +DEFINE_FIELD_X(UserConfigStruct, UserConfig, nologo) + void UserConfig::ProcessOptions() { // -help etc are omitted diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index b19a80e46..7e9ae2675 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -235,8 +235,6 @@ int TILE_STATIC; int TILE_BOTTOMSTATUSBAR; int TILE_THREEDEE; int TILE_INGAMEDUKETHREEDEE; -int TILE_PLUTOPAKSPRITE; -int TILE_MENUBAR; int TILE_ATOMICHEALTH; int TILE_FLOORSLIME; int TILE_JIBS6; diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp index 28b50b056..4a7029751 100644 --- a/source/games/duke/src/flags_d.cpp +++ b/source/games/duke/src/flags_d.cpp @@ -261,10 +261,6 @@ void initactorflags_d() TILE_CAMLIGHT = CAMLIGHT; TILE_STATIC = STATIC; TILE_BOTTOMSTATUSBAR = isWorldTour()? WIDESCREENSTATUSBAR : BOTTOMSTATUSBAR; - TILE_THREEDEE = THREEDEE; - TILE_INGAMEDUKETHREEDEE = INGAMEDUKETHREEDEE; - TILE_PLUTOPAKSPRITE = PLUTOPAKSPRITE; - TILE_MENUBAR = MENUBAR; TILE_ATOMICHEALTH = ATOMICHEALTH; TILE_FLOORSLIME = FLOORSLIME; TILE_JIBS6 = JIBS6; diff --git a/source/games/duke/src/flags_r.cpp b/source/games/duke/src/flags_r.cpp index e609c925f..04ef28b6e 100644 --- a/source/games/duke/src/flags_r.cpp +++ b/source/games/duke/src/flags_r.cpp @@ -235,10 +235,6 @@ void initactorflags_r() TILE_CAMLIGHT = CAMLIGHT; TILE_STATIC = STATIC; TILE_BOTTOMSTATUSBAR = BOTTOMSTATUSBAR; - TILE_THREEDEE = THREEDEE; - TILE_INGAMEDUKETHREEDEE = INGAMEDUKETHREEDEE; - TILE_PLUTOPAKSPRITE = PLUTOPAKSPRITE; - TILE_MENUBAR = MENUBAR; TILE_ATOMICHEALTH = ATOMICHEALTH; TILE_FLOORSLIME = FLOORSLIME; TILE_JIBS6 = JIBS6; diff --git a/source/games/duke/src/namelist_d.h b/source/games/duke/src/namelist_d.h index e098e67b4..9a81a6f94 100644 --- a/source/games/duke/src/namelist_d.h +++ b/source/games/duke/src/namelist_d.h @@ -517,6 +517,7 @@ x(THREEDEE, 2498) x(INGAMEDUKETHREEDEE, 2499) x(TENSCREEN, 2500) x(PLUTOPAKSPRITE, 2501) +x(TITLEPLUTOPAKSPRITE, 2502) x(MENUPLUTOPAKSPRITE, 2503) x(CREDITPAGE1, 2504) x(CREDITPAGE2, 2505) diff --git a/source/games/duke/src/names.h b/source/games/duke/src/names.h index 2318c9bd1..e29e19ba6 100644 --- a/source/games/duke/src/names.h +++ b/source/games/duke/src/names.h @@ -22,10 +22,6 @@ extern int TILE_CAMCORNER; extern int TILE_CAMLIGHT; extern int TILE_STATIC; extern int TILE_BOTTOMSTATUSBAR; -extern int TILE_THREEDEE; -extern int TILE_INGAMEDUKETHREEDEE; -extern int TILE_PLUTOPAKSPRITE; -extern int TILE_MENUBAR; extern int TILE_ATOMICHEALTH; extern int TILE_FLOORSLIME; extern int TILE_JIBS6; diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index 8a4abf5ff..d617e7df8 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -720,14 +720,6 @@ void S_PlaySpecialMusic(unsigned int m) } } -DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PlaySpecialMusic, S_PlaySpecialMusic) -{ - PARAM_PROLOGUE; - PARAM_INT(song); - S_PlaySpecialMusic(song); - return 0; -} - //--------------------------------------------------------------------------- // // @@ -881,4 +873,28 @@ bool StartCommentary(int tag, DDukeActor* actor) return false; } + +DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PlaySpecialMusic, S_PlaySpecialMusic) +{ + PARAM_PROLOGUE; + PARAM_INT(song); + S_PlaySpecialMusic(song); + return 0; +} + +static int PlaySound(int num, int chan, int flags, double vol) +{ + return S_PlaySound(num, chan, EChanFlags::FromInt(flags), float(vol)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PLaySound, PlaySound) +{ + PARAM_PROLOGUE; + PARAM_INT(snd); + PARAM_INT(chan); + PARAM_INT(flags); + PARAM_FLOAT(vol); + ACTION_RETURN_INT(PlaySound(snd, chan, flags, vol)); +} + END_DUKE_NS diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index 7b47cff15..2eb7b2e98 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -20,7 +20,416 @@ struct Duke native DRUGPAL, BASEPALCOUNT }; - native static void PlaySpecialMusic(int which); + native static int PlaySound(int num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f); + } + +struct DukeSnd native +{ + // This really needs to be done better... + enum EDukeSounds + { + KICK_HIT = 0, + PISTOL_RICOCHET = 1, + PISTOL_BODYHIT = 2, + PISTOL_FIRE = 3, + EJECT_CLIP = 4, + INSERT_CLIP = 5, + CHAINGUN_FIRE = 6, + RPG_SHOOT = 7, + POOLBALLHIT = 8, + RPG_EXPLODE = 9, + CAT_FIRE = 10, + SHRINKER_FIRE = 11, + ACTOR_SHRINKING = 12, + PIPEBOMB_BOUNCE = 13, + PIPEBOMB_EXPLODE = 14, + LASERTRIP_ONWALL = 15, + LASERTRIP_ARMING = 16, + LASERTRIP_EXPLODE = 17, + VENT_BUST = 18, + GLASS_BREAKING = 19, + GLASS_HEAVYBREAK = 20, + SHORT_CIRCUIT = 21, + ITEM_SPLASH = 22, + DUKE_BREATHING = 23, + DUKE_EXHALING = 24, + DUKE_GASP = 25, + SLIM_RECOG = 26, + + DUKE_URINATE = 28, + ENDSEQVOL3SND2 = 29, + ENDSEQVOL3SND3 = 30, + DUKE_PASSWIND = 32, + DUKE_CRACK = 33, + SLIM_ATTACK = 34, + SOMETHINGHITFORCE = 35, + DUKE_DRINKING = 36, + DUKE_KILLED1 = 37, + DUKE_GRUNT = 38, + DUKE_HARTBEAT = 39, + DUKE_ONWATER = 40, + DUKE_DEAD = 41, + DUKE_LAND = 42, + DUKE_WALKINDUCTS = 43, + DUKE_GLAD = 44, + DUKE_YES = 45, + DUKE_HEHE = 46, + DUKE_SHUCKS = 47, + DUKE_UNDERWATER = 48, + DUKE_JETPACK_ON = 49, + DUKE_JETPACK_IDLE = 50, + DUKE_JETPACK_OFF = 51, + LIZTROOP_GROWL = 52, + LIZTROOP_TALK1 = 53, + LIZTROOP_TALK2 = 54, + LIZTROOP_TALK3 = 55, + DUKETALKTOBOSS = 56, + LIZCAPT_GROWL = 57, + LIZCAPT_TALK1 = 58, + LIZCAPT_TALK2 = 59, + LIZCAPT_TALK3 = 60, + LIZARD_BEG = 61, + LIZARD_PAIN = 62, + LIZARD_DEATH = 63, + LIZARD_SPIT = 64, + DRONE1_HISSRATTLE = 65, + DRONE1_HISSSCREECH = 66, + DUKE_TIP2 = 67, + FLESH_BURNING = 68, + SQUISHED = 69, + TELEPORTER = 70, + ELEVATOR_ON = 71, + DUKE_KILLED3 = 72, + ELEVATOR_OFF = 73, + DOOR_OPERATE1 = 74, + SUBWAY = 75, + SWITCH_ON = 76, + FAN = 77, + DUKE_GETWEAPON3 = 78, + FLUSH_TOILET = 79, + HOVER_CRAFT = 80, + EARTHQUAKE = 81, + INTRUDER_ALERT = 82, + END_OF_LEVEL_WARN = 83, + ENGINE_OPERATING = 84, + REACTOR_ON = 85, + COMPUTER_AMBIENCE = 86, + GEARS_GRINDING = 87, + BUBBLE_AMBIENCE = 88, + MACHINE_AMBIENCE = 89, + SEWER_AMBIENCE = 90, + WIND_AMBIENCE = 91, + SOMETHING_DRIPPING = 92, + STEAM_HISSING = 93, + THEATER_BREATH = 94, + BAR_MUSIC = 95, + BOS1_ROAM = 96, + BOS1_RECOG = 97, + BOS1_ATTACK1 = 98, + BOS1_PAIN = 99, + BOS1_DYING =100, + BOS2_ROAM =101, + BOS2_RECOG =102, + BOS2_ATTACK =103, + BOS2_PAIN =104, + BOS2_DYING =105, + GETATOMICHEALTH =106, + DUKE_GETWEAPON2 =107, + BOS3_DYING =108, + SHOTGUN_FIRE =109, + PRED_ROAM =110, + PRED_RECOG =111, + PRED_ATTACK =112, + PRED_PAIN =113, + PRED_DYING =114, + CAPT_ROAM =115, + CAPT_ATTACK =116, + CAPT_RECOG =117, + CAPT_PAIN =118, + CAPT_DYING =119, + PIG_ROAM =120, + PIG_RECOG =121, + PIG_ATTACK =122, + PIG_PAIN =123, + PIG_DYING =124, + RECO_ROAM =125, + RECO_RECOG =126, + RECO_ATTACK =127, + RECO_PAIN =128, + RECO_DYING =129, + DRON_ROAM =130, + DRON_RECOG =131, + DRON_ATTACK1 =132, + DRON_PAIN =133, + DRON_DYING =134, + COMM_ROAM =135, + COMM_RECOG =136, + COMM_ATTACK =137, + COMM_PAIN =138, + COMM_DYING =139, + OCTA_ROAM =140, + OCTA_RECOG =141, + OCTA_ATTACK1 =142, + OCTA_PAIN =143, + OCTA_DYING =144, + TURR_ROAM =145, + TURR_RECOG =146, + TURR_ATTACK =147, + DUMPSTER_MOVE =148, + SLIM_DYING =149, + BOS3_ROAM =150, + BOS3_RECOG =151, + BOS3_ATTACK1 =152, + BOS3_PAIN =153, + BOS1_ATTACK2 =154, + COMM_SPIN =155, + BOS1_WALK =156, + DRON_ATTACK2 =157, + THUD =158, + OCTA_ATTACK2 =159, + WIERDSHOT_FLY =160, + TURR_PAIN =161, + TURR_DYING =162, + SLIM_ROAM =163, + LADY_SCREAM =164, + DOOR_OPERATE2 =165, + DOOR_OPERATE3 =166, + DOOR_OPERATE4 =167, + BORNTOBEWILDSND =168, + SHOTGUN_COCK =169, + GENERIC_AMBIENCE1 =170, + GENERIC_AMBIENCE2 =171, + GENERIC_AMBIENCE3 =172, + GENERIC_AMBIENCE4 =173, + GENERIC_AMBIENCE5 =174, + GENERIC_AMBIENCE6 =175, + BOS3_ATTACK2 =176, + GENERIC_AMBIENCE17 =177, + GENERIC_AMBIENCE18 =178, + GENERIC_AMBIENCE19 =179, + GENERIC_AMBIENCE20 =180, + GENERIC_AMBIENCE21 =181, + GENERIC_AMBIENCE22 =182, + SECRETLEVELSND =183, + GENERIC_AMBIENCE8 =184, + GENERIC_AMBIENCE9 =185, + GENERIC_AMBIENCE10 =186, + GENERIC_AMBIENCE11 =187, + GENERIC_AMBIENCE12 =188, + GENERIC_AMBIENCE13 =189, + GENERIC_AMBIENCE14 =190, + GENERIC_AMBIENCE15 =192, + GENERIC_AMBIENCE16 =193, + FIRE_CRACKLE =194, + BONUS_SPEECH1 =195, + BONUS_SPEECH2 =196, + BONUS_SPEECH3 =197, + PIG_CAPTURE_DUKE =198, + BONUS_SPEECH4 =199, + DUKE_LAND_HURT =200, + DUKE_HIT_STRIPPER1 =201, + DUKE_TIP1 =202, + DUKE_KILLED2 =203, + PRED_ROAM2 =204, + PIG_ROAM2 =205, + DUKE_GETWEAPON1 =206, + DUKE_SEARCH2 =207, + DUKE_CRACK2 =208, + DUKE_SEARCH =209, + DUKE_GET =210, + DUKE_LONGTERM_PAIN =211, + MONITOR_ACTIVE =212, + NITEVISION_ONOFF =213, + DUKE_HIT_STRIPPER2 =214, + DUKE_CRACK_FIRST =215, + DUKE_USEMEDKIT =216, + DUKE_TAKEPILLS =217, + DUKE_PISSRELIEF =218, + SELECT_WEAPON =219, + WATER_GURGLE =220, + DUKE_GETWEAPON4 =221, + JIBBED_ACTOR1 =222, + JIBBED_ACTOR2 =223, + JIBBED_ACTOR3 =224, + JIBBED_ACTOR4 =225, + JIBBED_ACTOR5 =226, + JIBBED_ACTOR6 =227, + JIBBED_ACTOR7 =228, + DUKE_GOTHEALTHATLOW =229, + BOSSTALKTODUKE =230, + WAR_AMBIENCE1 =231, + WAR_AMBIENCE2 =232, + WAR_AMBIENCE3 =233, + WAR_AMBIENCE4 =234, + WAR_AMBIENCE5 =235, + WAR_AMBIENCE6 =236, + WAR_AMBIENCE7 =237, + WAR_AMBIENCE8 =238, + WAR_AMBIENCE9 =239, + WAR_AMBIENCE10 =240, + ALIEN_TALK1 =241, + ALIEN_TALK2 =242, + EXITMENUSOUND =243, + FLY_BY =244, + DUKE_SCREAM =245, + SHRINKER_HIT =246, + RATTY =247, + INTO_MENU =248, + BONUSMUSIC =249, + DUKE_BOOBY =250, + DUKE_TALKTOBOSSFALL =251, + DUKE_LOOKINTOMIRROR =252, + PIG_ROAM3 =253, + KILLME =254, + DRON_JETSND =255, + SPACE_DOOR1 =256, + SPACE_DOOR2 =257, + SPACE_DOOR3 =258, + SPACE_DOOR4 =259, + SPACE_DOOR5 =260, + ALIEN_ELEVATOR1 =261, + VAULT_DOOR =262, + JIBBED_ACTOR13 =263, + DUKE_GETWEAPON6 =264, + JIBBED_ACTOR8 =265, + JIBBED_ACTOR9 =266, + JIBBED_ACTOR10 =267, + JIBBED_ACTOR11 =268, + JIBBED_ACTOR12 =269, + DUKE_KILLED4 =270, + DUKE_KILLED5 =271, + ALIEN_SWITCH1 =272, + DUKE_STEPONFECES =273, + DUKE_LONGTERM_PAIN2 =274, + DUKE_LONGTERM_PAIN3 =275, + DUKE_LONGTERM_PAIN4 =276, + COMPANB2 =277, + KTIT =278, + HELICOP_IDLE =279, + STEPNIT =280, + SPACE_AMBIENCE1 =281, + SPACE_AMBIENCE2 =282, + SLIM_HATCH =283, + RIPHEADNECK =284, + FOUNDJONES =285, + ALIEN_DOOR1 =286, + ALIEN_DOOR2 =287, + ENDSEQVOL3SND4 =288, + ENDSEQVOL3SND5 =289, + ENDSEQVOL3SND6 =290, + ENDSEQVOL3SND7 =291, + ENDSEQVOL3SND8 =292, + ENDSEQVOL3SND9 =293, + WHIPYOURASS =294, + ENDSEQVOL2SND1 =295, + ENDSEQVOL2SND2 =296, + ENDSEQVOL2SND3 =297, + ENDSEQVOL2SND4 =298, + ENDSEQVOL2SND5 =299, + ENDSEQVOL2SND6 =300, + ENDSEQVOL2SND7 =301, + GENERIC_AMBIENCE23 =302, + SOMETHINGFROZE =303, + DUKE_LONGTERM_PAIN5 =304, + DUKE_LONGTERM_PAIN6 =305, + DUKE_LONGTERM_PAIN7 =306, + DUKE_LONGTERM_PAIN8 =307, + WIND_REPEAT =308, + MYENEMY_ROAM =309, + MYENEMY_HURT =310, + MYENEMY_DEAD =311, + MYENEMY_SHOOT =312, + STORE_MUSIC =313, + STORE_MUSIC_BROKE =314, + ACTOR_GROWING =315, + NEWBEAST_ROAM =316, + NEWBEAST_RECOG =317, + NEWBEAST_ATTACK =318, + NEWBEAST_PAIN =319, + NEWBEAST_DYING =320, + NEWBEAST_SPIT =321, + VOL4_1 =322, + SUPERMARKET =323, + MOUSEANNOY =324, + BOOKEM =325, + SUPERMARKETCRY =326, + DESTRUCT =327, + EATFOOD =328, + MAKEMYDAY =329, + WITNESSSTAND =330, + VACATIONSPEECH =331, + YIPPEE1 =332, + YOHOO1 =333, + YOHOO2 =334, + DOLPHINSND =335, + TOUGHGALSND1 =336, + TOUGHGALSND2 =337, + TOUGHGALSND3 =338, + TOUGHGALSND4 =339, + TANK_ROAM =340, + BOS4_ROAM =341, + BOS4_RECOG =342, + BOS4_ATTACK =343, + BOS4_PAIN =344, + BOS4_DYING =345, + NEWBEAST_ATTACKMISS =346, + VOL4_2 =347, + COOKINGDEEPFRIER =348, + WHINING_DOG =349, + DEAD_DOG =350, + LIGHTNING_SLAP =351, + THUNDER =352, + HAPPYMOUSESND1 =353, + HAPPYMOUSESND2 =354, + HAPPYMOUSESND3 =355, + HAPPYMOUSESND4 =356, + ALARM =357, + RAIN =358, + DTAG_GREENRUN =359, + DTAG_BROWNRUN =360, + DTAG_GREENSCORE =361, + DTAG_BROWNSCORE =362, + INTRO4_1 =363, + INTRO4_2 =364, + INTRO4_3 =365, + INTRO4_4 =366, + INTRO4_5 =367, + INTRO4_6 =368, + SCREECH =369, + BOSS4_DEADSPEECH =370, + BOSS4_FIRSTSEE =371, + PARTY_SPEECH =372, + POSTAL_SPEECH =373, + TGSPEECH =374, + DOGROOMSPEECH =375, + SMACKED =376, + MDEVSPEECH =377, + AREA51SPEECH =378, + JEEPSOUND =379, + BIGDOORSLAM =380, + BOS4_LAY =381, + WAVESOUND =382, + ILLBEBACK =383, + VOL4ENDSND1 =384, + VOL4ENDSND2 =385, + EXPANDERHIT =386, + SNAKESPEECH =387, + EXPANDERSHOOT =388, + GETBACKTOWORK =389, + JIBBED_ACTOR14 =390, + JIBBED_ACTOR15 =391, + INTRO4_B =392, + BIGBANG =393, + SMACKIT =394, + BELLSND =395, + GOAWAY =396, + JOKE =397, + FLAMETHROWER_INTRO =398, + FLAMETHROWER_LOOP =399, + FLAMETHROWER_END =400, + E5L7_DUKE_QUIT_YOU =401, + } +} \ No newline at end of file diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 324e0a03e..429ffb8e3 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -33,3 +33,104 @@ class DRealmsScreen : SkippableScreenJob } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class TitleScreen : SkippableScreenJob +{ + int soundanm; + + void Init() + { + Super.Init(fadein | fadeout); + soundanm = 0; + } + + override void Start() + { + if (Build.isNam() || userConfig.nologo) Duke.PlaySpecialMusic(Duke.MUS_INTRO); + } + + override void OnTick() + { + int clock = ticks * 120 / GameTicRate; + if (soundanm == 0 && clock >= 120 && clock < 120 + 60) + { + soundanm = 1; + Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + } + if (soundanm == 1 && clock > 220 && clock < (220 + 30)) + { + soundanm = 2; + Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + } + if (soundanm == 2 && clock >= 280 && clock < 395) + { + soundanm = 3; + if (Build.isPlutoPak()) Duke.PlaySound(DukeSnd.FLY_BY, CHAN_AUTO, CHANF_UI); + } + else if (soundanm == 3 && clock >= 395) + { + soundanm = 4; + if (Build.isPlutoPak()) Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + } + + if (clock > (860 + 120)) + { + jobstate = finished; + } + } + + override void Draw(double smoothratio) + { + int clock = (ticks + smoothratio) * 120 / GameTicRate; + + screen.ClearScreen(); + + // Only translate if the image depends on the global palette. + let tex = TexMan.CheckForTexture("BETASCREEN"); + int trans = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL) : 0; + screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, trans, DTA_LegacyRenderStyle, STYLE_Normal); + + double scale = clamp(clock - 120, 0, 60) / 64.; + if (scale > 0.) + { + let tex = TexMan.CheckForTexture("DUKENUKEM"); + trans = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL) : 0; // re-check for different texture! + + screen.DrawTexture(tex, true, 160, 104, DTA_FullscreenScale, FSMode_Fit320x200, + DTA_CenterOffsetRel, true, DTA_TranslationIndex, trans, DTA_ScaleX, scale, DTA_ScaleY, scale); + } + + scale = clamp(clock - 220, 0, 30) / 32.; + if (scale > 0.) + { + let tex = TexMan.CheckForTexture("THREEDEE"); + trans = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL) : 0; // re-check for different texture! + + screen.DrawTexture(tex, true, 160, 129, DTA_FullscreenScale, FSMode_Fit320x200, + DTA_CenterOffsetRel, true, DTA_TranslationIndex, trans, DTA_ScaleX, scale, DTA_ScaleY, scale); + } + + if (Build.isPlutoPak()) + { + scale = (410 - clamp(clock, 280, 395)) / 16.; + if (scale > 0. && clock > 280) + { + let tex = TexMan.CheckForTexture("TITLEPLUTOPAKSPRITE"); + trans = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL) : 0; // re-check for different texture! + + screen.DrawTexture(tex, true, 160, 151, DTA_FullscreenScale, FSMode_Fit320x200, + DTA_CenterOffsetRel, true, DTA_TranslationIndex, trans, DTA_ScaleX, scale, DTA_ScaleY, scale); + } + } + } + + override void OnDestroy() + { + Duke.PlaySound(DukeSnd.NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI); + } +} diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index 3dc64c532..4c6273945 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -27,6 +27,17 @@ enum EGameType }; +struct UserConfigStruct native +{ + native bool nomonsters; + native bool nosound; + native bool nologo; +} + +extend struct _ +{ + native @UserConfigStruct userConfig; +} struct Build { @@ -36,6 +47,53 @@ struct Build } native static Color shadeToLight(int shade); + + // game check shortcuts + static bool isNam() + { + return gameinfo.gametype & (GAMEFLAG_NAM | GAMEFLAG_NAPALM); + } + + static bool isNamWW2GI() + { + return gameinfo.gametype & (GAMEFLAG_NAM | GAMEFLAG_NAPALM |GAMEFLAG_WW2GI); + } + + static bool isWW2GI() + { + return gameinfo.gametype & (GAMEFLAG_WW2GI); + } + + static bool isRR() + { + return gameinfo.gametype & (GAMEFLAG_RRALL); + } + + static bool isRRRA() + { + return gameinfo.gametype & (GAMEFLAG_RRRA); + } + + static bool isWorldTour() + { + return gameinfo.gametype & GAMEFLAG_WORLDTOUR; + } + + static bool isPlutoPak() + { + return gameinfo.gametype & GAMEFLAG_PLUTOPAK; + } + + static bool isShareware() + { + return gameinfo.gametype & GAMEFLAG_SHAREWARE; + } + + static bool isBlood() + { + return gameinfo.gametype & GAMEFLAG_BLOOD; + } + } /* From b0163ff729127e14288f0f6305243fc4e97f7d48 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 20:56:08 +0200 Subject: [PATCH 09/86] - made the end of E1 cutscene a bit more scripting friendly. --- source/games/duke/src/2d_d.cpp | 45 +++++++++++++----------------- source/games/duke/src/namelist_d.h | 8 ++++++ 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index f4cce3d97..ab3d3cfcf 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -332,28 +332,21 @@ void Logo_d(const CompletionFunc &completion) class DEpisode1End1 : public DSkippableScreenJob { int bonuscnt = 0; - int bossani = -1; + int bossani = -1; int breatheani = -1; bool breathebg = false; - static inline const int breathe[] = - { - 0, 30,VICTORY1 + 1,176,59, - 30, 60,VICTORY1 + 2,176,59, - 60, 90,VICTORY1 + 1,176,59, - 90, 120,0 ,176,59 - }; + static inline const int breathe_time[] = { 0, 30, 60, 90 }; + static inline const int breathe_time2[] = { 30, 60, 90, 120 }; + static inline const int breathe_tile[] = { VICTORY2, VICTORY3, VICTORY2, 0 }; + static const int breathe_x = 176; + static const int breathe_y = 59; - static inline const int bossmove[] = - { - 0, 120,VICTORY1 + 3,86,59, - 220, 260,VICTORY1 + 4,86,59, - 260, 290,VICTORY1 + 5,86,59, - 290, 320,VICTORY1 + 6,86,59, - 320, 350,VICTORY1 + 7,86,59, - 350, 380,VICTORY1 + 8,86,59, - 350, 380,VICTORY1 + 8,86,59, - }; + static inline const int boss_time[] = { 0, 220, 260, 290, 320, 350, 350 }; + static inline const int boss_time2[] = { 120, 260, 290, 320, 350, 380, 380 }; + static inline const int boss_tile[] = { VICTORY4, VICTORY5, VICTORY6, VICTORY7, VICTORY8, VICTORY9, VICTORY9 }; + static const int boss_x = 86; + static const int boss_y = 59; public: DEpisode1End1() : DSkippableScreenJob(fadein | fadeout) {} @@ -369,7 +362,7 @@ public: // boss if (currentclock > 390 && currentclock < 780) { - for (int t = 0; t < 35; t += 5) if (bossmove[t + 2] && (currentclock % 390) > bossmove[t] && (currentclock % 390) <= bossmove[t + 1]) + for (int t = 0, tt = 0; t < 35; t +=5, tt++) if ((currentclock % 390) > boss_time[tt] && (currentclock % 390) <= boss_time2[tt]) { if (t == 10 && bonuscnt == 1) { @@ -377,7 +370,7 @@ public: S_PlaySound(SQUISHED, CHAN_AUTO, CHANF_UI); bonuscnt++; } - bossani = t; + bossani = tt; } } @@ -393,15 +386,15 @@ public: bonuscnt++; } } - for (int t = 0; t < 20; t += 5) - if (breathe[t + 2] && (currentclock % 120) > breathe[t] && (currentclock % 120) <= breathe[t + 1]) + for (int t = 0, tt = 0; t < 20; t += 5, tt++) + if (breathe_tile[tt] && (currentclock % 120) > breathe_time[tt] && (currentclock % 120) <= breathe_time2[tt]) { if (t == 5 && bonuscnt == 0) { S_PlaySound(BOSSTALKTODUKE, CHAN_AUTO, CHANF_UI); bonuscnt++; } - breatheani = t; + breatheani = tt; } } @@ -417,19 +410,19 @@ public: if (bossani != -1) { - DrawTexture(twod, tileGetTexture(bossmove[bossani + 2], true), bossmove[bossani + 3], bossmove[bossani + 4], DTA_FullscreenScale, FSMode_Fit320x200, + DrawTexture(twod, tileGetTexture(boss_tile[bossani], true), boss_x, boss_y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, translation, DTA_TopLeft, true, TAG_DONE); } if (breathebg) { - DrawTexture(twod, tileGetTexture(VICTORY1 + 8, true), 86, 59, DTA_FullscreenScale, FSMode_Fit320x200, + DrawTexture(twod, tileGetTexture(VICTORY9, true), 86, 59, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, translation, DTA_TopLeft, true, TAG_DONE); } if (breatheani != -1) { - DrawTexture(twod, tileGetTexture(breathe[breatheani + 2], true), breathe[breatheani + 3], breathe[breatheani + 4], DTA_FullscreenScale, FSMode_Fit320x200, + DrawTexture(twod, tileGetTexture(breathe_tile[breatheani], true), breathe_x, breathe_y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, translation, DTA_TopLeft, true, TAG_DONE); } } diff --git a/source/games/duke/src/namelist_d.h b/source/games/duke/src/namelist_d.h index 9a81a6f94..62748883d 100644 --- a/source/games/duke/src/namelist_d.h +++ b/source/games/duke/src/namelist_d.h @@ -590,6 +590,14 @@ x(RESPAWNMARKERGREEN, 3210) x(BONUSSCREEN, 3240) x(VIEWBORDER, 3250) x(VICTORY1, 3260) +x(VICTORY2, 3261) +x(VICTORY3, 3262) +x(VICTORY4, 3263) +x(VICTORY5, 3264) +x(VICTORY6, 3265) +x(VICTORY7, 3266) +x(VICTORY8, 3267) +x(VICTORY9, 3268) x(ORDERING, 3270) x(TEXTSTORY, 3280) x(LOADSCREEN, 3281) From 05fa21785d3b2701c4c60b74525b924750a1cf3c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 21:30:13 +0200 Subject: [PATCH 10/86] - ported Duke end of E1 cutscene --- .../static/zscript/games/duke/ui/screens.zs | 125 +++++++++++++++++- 1 file changed, 121 insertions(+), 4 deletions(-) diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 429ffb8e3..fd58543a3 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -87,19 +87,20 @@ class TitleScreen : SkippableScreenJob override void Draw(double smoothratio) { int clock = (ticks + smoothratio) * 120 / GameTicRate; + int etrans = Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL); screen.ClearScreen(); // Only translate if the image depends on the global palette. let tex = TexMan.CheckForTexture("BETASCREEN"); - int trans = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL) : 0; + int trans = TexMan.UseGamePalette(tex)? etrans : 0; screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, trans, DTA_LegacyRenderStyle, STYLE_Normal); double scale = clamp(clock - 120, 0, 60) / 64.; if (scale > 0.) { let tex = TexMan.CheckForTexture("DUKENUKEM"); - trans = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL) : 0; // re-check for different texture! + trans = TexMan.UseGamePalette(tex)? etrans : 0; // re-check for different texture! screen.DrawTexture(tex, true, 160, 104, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true, DTA_TranslationIndex, trans, DTA_ScaleX, scale, DTA_ScaleY, scale); @@ -109,7 +110,7 @@ class TitleScreen : SkippableScreenJob if (scale > 0.) { let tex = TexMan.CheckForTexture("THREEDEE"); - trans = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL) : 0; // re-check for different texture! + trans = TexMan.UseGamePalette(tex)? etrans : 0; // re-check for different texture! screen.DrawTexture(tex, true, 160, 129, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true, DTA_TranslationIndex, trans, DTA_ScaleX, scale, DTA_ScaleY, scale); @@ -121,7 +122,7 @@ class TitleScreen : SkippableScreenJob if (scale > 0. && clock > 280) { let tex = TexMan.CheckForTexture("TITLEPLUTOPAKSPRITE"); - trans = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL) : 0; // re-check for different texture! + trans = TexMan.UseGamePalette(tex)? etrans : 0; // re-check for different texture! screen.DrawTexture(tex, true, 160, 151, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true, DTA_TranslationIndex, trans, DTA_ScaleX, scale, DTA_ScaleY, scale); @@ -134,3 +135,119 @@ class TitleScreen : SkippableScreenJob Duke.PlaySound(DukeSnd.NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI); } } + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class Episode1End1 : SkippableScreenJob +{ + int bonuscnt; + TextureID bossani; + TextureID breatheani; + bool breathebg; + + const breathe_x = 176; + const breathe_y = 59; + const boss_x = 86; + const boss_y = 59; + + void Init() + { + bonuscnt = 0; + breathebg = false; + bossani.SetInvalid(); + breatheani.SetInvalid(); + Super.Init(fadein | fadeout); + } + + + override void OnTick() + { + static const int breathe_time[] = { 0, 30, 60, 90 }; + static const int breathe_time2[] = { 30, 60, 90, 120 }; + static const String breathe_tile[] = { "VICTORY2", "VICTORY3", "VICTORY2", "" }; + + static const int boss_time[] = { 0, 220, 260, 290, 320, 350, 350 }; + static const int boss_time2[] = { 120, 260, 290, 320, 350, 380, 380 }; + static const String boss_tile[] = { "VICTORY4", "VICTORY5", "VICTORY6", "VICTORY7", "VICTORY8", "VICTORY9", "VICTORY9" }; + + int currentclock = ticks * 120 / GameTicRate; + + bossani.SetInvalid(); + breathebg = false; + breatheani.SetInvalid(); + + // boss + if (currentclock > 390 && currentclock < 780) + { + for (int t = 0, tt = 0; t < 35; t +=5, tt++) if ((currentclock % 390) > boss_time[tt] && (currentclock % 390) <= boss_time2[tt]) + { + if (t == 10 && bonuscnt == 1) + { + Duke.PlaySound(DukeSnd.SHOTGUN_FIRE, CHAN_AUTO, CHANF_UI); + Duke.PlaySound(DukeSnd.SQUISHED, CHAN_AUTO, CHANF_UI); + bonuscnt++; + } + bossani = TexMan.CheckForTexture(boss_tile[tt]); + } + } + + // Breathe + if (currentclock < 450 || currentclock >= 750) + { + if (currentclock >= 750) + { + breathebg = true; + if (currentclock >= 750 && bonuscnt == 2) + { + Duke.PlaySound(DukeSnd.DUKETALKTOBOSS, CHAN_AUTO, CHANF_UI); + bonuscnt++; + } + } + for (int t = 0, tt = 0; t < 20; t += 5, tt++) + if (breathe_tile[tt] != "" && (currentclock % 120) > breathe_time[tt] && (currentclock % 120) <= breathe_time2[tt]) + { + if (t == 5 && bonuscnt == 0) + { + Duke.PlaySound(DukeSnd.BOSSTALKTODUKE, CHAN_AUTO, CHANF_UI); + bonuscnt++; + } + breatheani = TexMan.CheckForTexture(breathe_tile[tt]); + } + } + + } + + override void Draw(double sr) + { + int etrans = Translation.MakeID(Translation_BasePalette, Duke.ENDINGPAL); + + screen.ClearScreen(); + let tex = TexMan.CheckForTexture("VICTORY1"); + int trans = TexMan.UseGamePalette(tex)? etrans : 0; + screen.DrawTexture(tex, false, 0, 50, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, trans, DTA_LegacyRenderStyle, STYLE_Normal, DTA_TopLeft, true); + + if (bossani.isValid()) + { + trans = TexMan.UseGamePalette(tex)? etrans : 0; // re-check for different texture! + screen.DrawTexture(bossani, false, boss_x, boss_y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, trans, DTA_TopLeft, true); + } + + if (breathebg) + { + tex = TexMan.CheckForTexture("VICTORY9"); + trans = TexMan.UseGamePalette(tex)? etrans : 0; // re-check for different texture! + screen.DrawTexture(tex, false, 86, 59, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, trans, DTA_TopLeft, true); + } + + if (breatheani.isValid()) + { + trans = TexMan.UseGamePalette(tex)? etrans : 0; // re-check for different texture! + screen.DrawTexture(breatheani, false, breathe_x, breathe_y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, trans, DTA_TopLeft, true); + } + } +} + From 9c95f003f1c740da27876db61463c5eba78c4d54 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Apr 2021 21:33:51 +0200 Subject: [PATCH 11/86] - ported E2ENDSCREEN --- wadsrc/static/zscript/games/duke/ui/screens.zs | 18 ++++++++++++++++++ wadsrc/static/zscript/screenjob.zs | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index fd58543a3..282f1d7bf 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -251,3 +251,21 @@ class Episode1End1 : SkippableScreenJob } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class E2EndScreen : ImageScreen +{ + void Init() + { + Super.Init("E2ENDSCREEN", fadein | fadeout | stopsound, 0x7fffffff, 0); + } + + override void Start() + { + Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + } +} diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 5c8f7f25a..f1aac763b 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -81,7 +81,7 @@ class ImageScreen : SkippableScreenJob native native bool cleared; native TextureID texid; - native void Init(TextureID tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0); + native void Init(String tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0); //override void OnTick(); //override void Draw(double smooth); } From 7fbe153ae79ec43c0e7557b455613cb286823185 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 23 Apr 2021 10:07:02 +0200 Subject: [PATCH 12/86] - more Duke screen porting. --- source/core/gamecontrol.cpp | 18 ++- source/core/gamecontrol.h | 4 +- source/games/duke/src/2d_d.cpp | 7 +- source/games/duke/src/2d_r.cpp | 3 +- source/games/duke/src/sounds.cpp | 7 + source/games/duke/src/sounds.h | 1 - wadsrc/static/zscript/engine/base.zs | 4 +- wadsrc/static/zscript/games/blood/ui/menu.zs | 2 +- wadsrc/static/zscript/games/duke/dukegame.zs | 50 ++++++ wadsrc/static/zscript/games/duke/ui/menu.zs | 6 +- .../static/zscript/games/duke/ui/screens.zs | 150 +++++++++++++++++- .../static/zscript/games/exhumed/ui/menu.zs | 4 +- wadsrc/static/zscript/razebase.zs | 5 +- wadsrc/static/zscript/screenjob.zs | 2 +- 14 files changed, 241 insertions(+), 22 deletions(-) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index c3e0c027c..665c8b8e1 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1436,13 +1436,29 @@ DEFINE_ACTION_FUNCTION(_Screen, GetViewWindow) return MIN(numret, 4); } -DEFINE_ACTION_FUNCTION_NATIVE(_Build, ShadeToLight, shadeToLight) +DEFINE_ACTION_FUNCTION_NATIVE(_Raze, ShadeToLight, shadeToLight) { PARAM_PROLOGUE; PARAM_INT(shade); ACTION_RETURN_INT(shadeToLight(shade)); } +DEFINE_ACTION_FUNCTION_NATIVE(_Raze, StopAllSounds, FX_StopAllSounds) +{ + FX_StopAllSounds(); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Raze, SoundEnabled, SoundEnabled) +{ + ACTION_RETURN_INT(SoundEnabled()); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Raze, MusicEnabled, MusicEnabled) +{ + ACTION_RETURN_INT(MusicEnabled()); +} + extern bool demoplayback; DEFINE_GLOBAL(multiplayer) DEFINE_GLOBAL(netgame) diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index fa2cab18a..6d6188af9 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -70,12 +70,12 @@ extern UserConfig userConfig; extern int nomusic; extern bool nosound; -inline bool MusicEnabled() +inline int MusicEnabled() // int return is for scripting { return mus_enabled && !nomusic; } -inline bool SoundEnabled() +inline int SoundEnabled() { return snd_enabled && !nosound; } diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index ab3d3cfcf..0667fd568 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -139,10 +139,11 @@ void InitFonts_d() // //========================================================================== -static void BigText(double x, double y, const char* text, double alpha = 1.) +static void BigText(double x, double y, const char* text, int align = -1, double alpha = 1.) { - auto width = BigFont->StringWidth(text); - DrawText(twod, BigFont, CR_UNTRANSLATED, x - width / 2, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Alpha, alpha, TAG_DONE); + if (align != -1) + x -= BigFont->StringWidth(text) * (align == 0 ? 0.5 : 1); + DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Alpha, alpha, TAG_DONE); } static void GameText(double x, double y, const char* t, int shade, int align = -1, int trans = 0) diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index 101c41567..01602ee37 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -135,7 +135,6 @@ static void BigText(double x, double y, const char* text, int align, double alph //x *= 2.2; y *= 2.64; if (align != -1) x -= BigFont->StringWidth(text) * (align == 0 ? 0.2 : 0.4); - auto width = BigFont->StringWidth(text); DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 0.4, DTA_ScaleY, 0.4, DTA_Alpha, alpha, TAG_DONE); } @@ -576,7 +575,7 @@ public: void OnTick() override { - if (!S_CheckSoundPlaying(-1, 35) && ticks > 15 * GameTicRate) state = finished; // make sure it stays, even if sound is off. + if (!S_CheckSoundPlaying(35) && ticks > 15 * GameTicRate) state = finished; // make sure it stays, even if sound is off. } void Draw(double) override { diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index d617e7df8..f5a693dc3 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -897,4 +897,11 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PLaySound, PlaySound) ACTION_RETURN_INT(PlaySound(snd, chan, flags, vol)); } +DEFINE_ACTION_FUNCTION_NATIVE(_Duke, CheckSoundPlaying, S_CheckSoundPlaying) +{ + PARAM_PROLOGUE; + PARAM_INT(snd); + ACTION_RETURN_INT(S_CheckSoundPlaying(snd)); +} + END_DUKE_NS diff --git a/source/games/duke/src/sounds.h b/source/games/duke/src/sounds.h index 415af4406..4862ee28c 100644 --- a/source/games/duke/src/sounds.h +++ b/source/games/duke/src/sounds.h @@ -48,7 +48,6 @@ void S_MenuSound(void); void S_StopSound(int sndNum, DDukeActor* spr = nullptr, int flags = -1); int S_CheckSoundPlaying(int soundNum); -inline int S_CheckSoundPlaying(int sprnum, int soundNum) { return S_CheckSoundPlaying(soundNum); } int S_CheckActorSoundPlaying(DDukeActor* spriteNum, int soundNum, int channel = 0); int S_CheckAnyActorSoundPlaying(DDukeActor* spriteNum); diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index 3a3a4fb3b..0fef04818 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -218,7 +218,9 @@ struct TexMan AllowSkins = 8, ShortNameOnly = 16, DontCreate = 32, - Localize = 64 + Localize = 64, + ForceLookup = 128, + NoAlias = 256 }; enum ETexReplaceFlags diff --git a/wadsrc/static/zscript/games/blood/ui/menu.zs b/wadsrc/static/zscript/games/blood/ui/menu.zs index 53035e7af..dbcb2a947 100644 --- a/wadsrc/static/zscript/games/blood/ui/menu.zs +++ b/wadsrc/static/zscript/games/blood/ui/menu.zs @@ -85,7 +85,7 @@ class ListMenuItemBloodTextItem : ListMenuItemTextItem if (selected) shade = 32 - ((MSTime() * 120 / 1000) & 63); Screen.DrawText(gamefont, Font.CR_UNDEFINED, xpos+1, mYpos+1, mText, DTA_Color, 0xff000000, DTA_FullscreenScale, FSMode_Fit320x200); - Screen.DrawText(gamefont, Font.CR_UNDEFINED, xpos, mYpos, mText, DTA_TranslationIndex, trans, DTA_Color, Build.shadeToLight(shade), DTA_FullscreenScale, FSMode_Fit320x200); + Screen.DrawText(gamefont, Font.CR_UNDEFINED, xpos, mYpos, mText, DTA_TranslationIndex, trans, DTA_Color, Raze.shadeToLight(shade), DTA_FullscreenScale, FSMode_Fit320x200); } } diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index 2eb7b2e98..d92e9e27d 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -23,6 +23,56 @@ struct Duke native native static void PlaySpecialMusic(int which); native static int PlaySound(int num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f); + native static bool CheckSoundPlaying(int num); + + //========================================================================== + // + // wrappers around DrawText to allow easier reuse of the old code. + // The vertical displacements are to have the same positioning as with the original code. + // + //========================================================================== + + static void BigText(double x, double y, String text, int align = -1, double alpha = 1.) + { + + if (!Raze.isRR()) + { + if (align != -1) x -= BigFont.StringWidth(text) * (align == 0 ? 0.5 : 1); + Screen.DrawText(BigFont, Font.CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Alpha, alpha); + } + else + { + if (align != -1) x -= BigFont.StringWidth(text) * (align == 0 ? 0.2 : 0.4); + Screen.DrawText(BigFont, Font.CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 0.4, DTA_ScaleY, 0.4, DTA_Alpha, alpha); + } + } + + static void GameText(double x, double y, String t, int shade, int align = -1, int trans = 0) + { + int fsmode = FSMode_Fit320x200; + if (Raze.isRR()) + { + x *= 2; + y *= 2; + fsmode = FSMode_Fit640x400; + } + if (align != -1) x -= SmallFont.StringWidth(t) * (align == 0 ? 0.5 : 1); + Screen.DrawText(SmallFont, Font.CR_UNDEFINED, x, y + 2, t, DTA_FullscreenScale, fsmode, DTA_TranslationIndex, Translation.MakeID(Translation_Remap, trans), DTA_Color, Raze.shadeToLight(shade)); + } + + static void MiniText(double x, double y, String t, int shade, int align = -1, int trans = 0) + { + int fsmode = FSMode_Fit320x200; + if (Raze.isRR()) + { + x *= 2; + y *= 2; + fsmode = FSMode_Fit640x400; + } + if (align != -1) x -= SmallFont2.StringWidth(t) * (align == 0 ? 0.5 : 1); + Screen.DrawText(SmallFont2, Font.CR_UNDEFINED, x, y, t, DTA_FullscreenScale, fsmode, DTA_TranslationIndex, Translation.MakeID(Translation_Remap, trans), DTA_Color, Raze.shadeToLight(shade)); + } + } diff --git a/wadsrc/static/zscript/games/duke/ui/menu.zs b/wadsrc/static/zscript/games/duke/ui/menu.zs index 6c81fbae3..604624f96 100644 --- a/wadsrc/static/zscript/games/duke/ui/menu.zs +++ b/wadsrc/static/zscript/games/duke/ui/menu.zs @@ -38,7 +38,7 @@ class DukeMenuDelegate : RazeMenuDelegate String picname; if (!right) picname= String.Format("SPINNINGNUKEICON%d", ((mclock >> 3) % frames)); else picname = String.Format("SPINNINGNUKEICON%d", frames - 1 - ((frames - 1 + (mclock >> 3)) % frames)); - int light = 231 + (Build.calcSinTableValue(mclock<<5) / 768.); + int light = 231 + (Raze.calcSinTableValue(mclock<<5) / 768.); let pe = color(255, light, light, light); Screen.DrawTexture(TexMan.CheckForTexture(picname), false, x, y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, scale, DTA_ScaleY, scale, DTA_Color, pe, DTA_CenterOffsetRel, true); } @@ -110,7 +110,7 @@ class ListMenuItemDukeLogo : ListMenuItem if (gameinfo.gametype & GAMEFLAG_PLUTOPAK) { int mclock = MSTime() * 120 / 1000; - int light = 223 + (Build.calcSinTableValue(mclock<<4) / 512.); + int light = 223 + (Raze.calcSinTableValue(mclock<<4) / 512.); let pe = Color(255, light, light, light); Screen.DrawTexture(TexMan.CheckForTexture("MENUPLUTOPAKSPRITE"), false, x + 100, 36, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_Color, pe, DTA_CenterOffsetRel, true); } @@ -148,7 +148,7 @@ class ListMenuItemDukeTextItem : ListMenuItemTextItem if (selected) { int mclock = MSTime() * 120 / 1000; - int light = 231 + (Build.calcSinTableValue(mclock<<5) / 512.); + int light = 231 + (Raze.calcSinTableValue(mclock<<5) / 512.); pe = Color(255, light, light, light); } else diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 282f1d7bf..264c78ec1 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -51,7 +51,7 @@ class TitleScreen : SkippableScreenJob override void Start() { - if (Build.isNam() || userConfig.nologo) Duke.PlaySpecialMusic(Duke.MUS_INTRO); + if (Raze.isNam() || userConfig.nologo) Duke.PlaySpecialMusic(Duke.MUS_INTRO); } override void OnTick() @@ -70,12 +70,12 @@ class TitleScreen : SkippableScreenJob if (soundanm == 2 && clock >= 280 && clock < 395) { soundanm = 3; - if (Build.isPlutoPak()) Duke.PlaySound(DukeSnd.FLY_BY, CHAN_AUTO, CHANF_UI); + if (Raze.isPlutoPak()) Duke.PlaySound(DukeSnd.FLY_BY, CHAN_AUTO, CHANF_UI); } else if (soundanm == 3 && clock >= 395) { soundanm = 4; - if (Build.isPlutoPak()) Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + if (Raze.isPlutoPak()) Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); } if (clock > (860 + 120)) @@ -116,7 +116,7 @@ class TitleScreen : SkippableScreenJob DTA_CenterOffsetRel, true, DTA_TranslationIndex, trans, DTA_ScaleX, scale, DTA_ScaleY, scale); } - if (Build.isPlutoPak()) + if (Raze.isPlutoPak()) { scale = (410 - clamp(clock, 280, 395)) / 16.; if (scale > 0. && clock > 280) @@ -269,3 +269,145 @@ class E2EndScreen : ImageScreen Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); } } + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class Episode3End : ImageScreen +{ + int soundstate; + int finishtime; + + void Init() + { + Super.Init("", fadein|fadeout, 0x7fffffff); + texid = TexMan.CheckForTexture("radlogo.anm", TexMan.Type_Any, TexMan.TryAny | TexMan.ForceLookup); // must override with 'forcelookup'. + soundstate = 0; + finishtime = 0; + } + + override void OnSkip() + { + Raze.StopAllSounds(); + } + + override void OnTick() + { + switch (soundstate) + { + case 0: + Duke.PlaySound(DukeSnd.ENDSEQVOL3SND5, CHAN_AUTO, CHANF_UI); + soundstate++; + break; + + case 1: + if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND5)) + { + Duke.PlaySound(DukeSnd.ENDSEQVOL3SND6, CHAN_AUTO, CHANF_UI); + soundstate++; + } + break; + + case 2: + if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND6)) + { + Duke.PlaySound(DukeSnd.ENDSEQVOL3SND7, CHAN_AUTO, CHANF_UI); + soundstate++; + } + break; + + case 3: + if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND7)) + { + Duke.PlaySound(DukeSnd.ENDSEQVOL3SND8, CHAN_AUTO, CHANF_UI); + soundstate++; + } + break; + + case 4: + if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND8)) + { + Duke.PlaySound(DukeSnd.ENDSEQVOL3SND9, CHAN_AUTO, CHANF_UI); + soundstate++; + } + break; + + case 5: + if (!Duke.CheckSoundPlaying(DukeSnd.ENDSEQVOL3SND9)) + { + soundstate++; + finishtime = ticks + GameTicRate * (Raze.SoundEnabled() ? 1 : 5); // if sound is off this wouldn't wait without a longer delay here. + } + break; + + case 6: + if (Raze.isPlutoPak()) + { + if (ticks > finishtime) jobstate = finished; + } + break; + + default: + break; + } + if (jobstate != running) Raze.StopAllSounds(); + } + + override void OnDestroy() + { + if (!Raze.isPlutoPak()) Duke.PlaySound(DukeSnd.ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class Episode4Text : SkippableScreenJob +{ + void Init() + { + Super.Init(fadein|fadeout); + } + + + override void Draw(double sm) + { + Screen.ClearScreen(); + Duke.BigText(160, 60, "$Thanks to all our"); + Duke.BigText(160, 60 + 16, "$fans for giving"); + Duke.BigText(160, 60 + 16 + 16, "$us big heads."); + Duke.BigText(160, 70 + 16 + 16 + 16, "$Look for a Duke Nukem 3D"); + Duke.BigText(160, 70 + 16 + 16 + 16 + 16, "$sequel soon."); + } + + override void Start() + { + Duke.PlaySound(DukeSnd.ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class Episode5End : ImageScreen +{ + void Init() + { + Super.Init("FIREFLYGROWEFFECT", fadein|fadeout|stopsound); + } + + override void OnTick() + { + if (ticks == 1) Duke.PlaySound(DukeSnd.E5L7_DUKE_QUIT_YOU, CHAN_AUTO, CHANF_UI); + } +} + diff --git a/wadsrc/static/zscript/games/exhumed/ui/menu.zs b/wadsrc/static/zscript/games/exhumed/ui/menu.zs index 52101751d..b8e139181 100644 --- a/wadsrc/static/zscript/games/exhumed/ui/menu.zs +++ b/wadsrc/static/zscript/games/exhumed/ui/menu.zs @@ -98,10 +98,10 @@ class ListMenuItemExhumedTextItem : ListMenuItemTextItem double y = mYpos + v.y / 2; int shade; - if (selected) shade = Build.CalcSinTableValue(MSTime() * 16 * 120 / 1000) >> 9; + if (selected) shade = Raze.CalcSinTableValue(MSTime() * 16 * 120 / 1000) >> 9; else if (Selectable()) shade = 0; else shade = 25; - let color = Build.shadeToLight(shade); + let color = Raze.shadeToLight(shade); double scalex = 1.; // Squash the text if it is too wide. Due to design limitations we cannot expand the box here. :( if (texsize.X - 18 < width) diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index 4c6273945..41cb20aee 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -39,7 +39,7 @@ extend struct _ native @UserConfigStruct userConfig; } -struct Build +struct Raze { static int calcSinTableValue(int ang) { @@ -47,6 +47,9 @@ struct Build } native static Color shadeToLight(int shade); + native static void StopAllSounds(); + native static bool SoundEnabled(); + native static bool MusicEnabled(); // game check shortcuts static bool isNam() diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index f1aac763b..477dd8889 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -32,6 +32,7 @@ class ScreenJob native native virtual bool OnEvent(InputEvent evt); native virtual void OnTick(); native virtual void Draw(double smoothratio); + virtual void OnSkip() {} //native int DrawFrame(double smoothratio); //native int GetFadeState(); @@ -48,7 +49,6 @@ class SkippableScreenJob : ScreenJob native { native void Init(int flags = 0, float fadet = 250.f); //native override bool OnEvent(InputEvent evt); - virtual void Skipped() {} } //--------------------------------------------------------------------------- From 4636a526994d1e63d7a6c990b2a266f1c1d85026 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 23 Apr 2021 12:24:42 +0200 Subject: [PATCH 13/86] - MP summary screen ported. --- source/core/gamecontrol.cpp | 22 ++++ wadsrc/static/zscript/games/duke/dukegame.zs | 6 ++ .../static/zscript/games/duke/ui/screens.zs | 102 ++++++++++++++++++ wadsrc/static/zscript/razebase.zs | 55 ++++++++++ wadsrc/static/zscript/screenjob.zs | 28 +++++ 5 files changed, 213 insertions(+) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 665c8b8e1..7b3ef32fe 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1459,6 +1459,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, MusicEnabled, MusicEnabled) ACTION_RETURN_INT(MusicEnabled()); } +DEFINE_ACTION_FUNCTION(_Raze, PlayerName) +{ + PARAM_PROLOGUE; + PARAM_INT(index); + ACTION_RETURN_STRING(unsigned(index) >= MAXPLAYERS ? "" : PlayerName(index)); +} + extern bool demoplayback; DEFINE_GLOBAL(multiplayer) DEFINE_GLOBAL(netgame) @@ -1466,3 +1473,18 @@ DEFINE_GLOBAL(gameaction) DEFINE_GLOBAL(gamestate) DEFINE_GLOBAL(demoplayback) DEFINE_GLOBAL(consoleplayer) +DEFINE_GLOBAL(currentLevel) + +DEFINE_FIELD_X(MapRecord, MapRecord, parTime) +DEFINE_FIELD_X(MapRecord, MapRecord, designerTime) +DEFINE_FIELD_X(MapRecord, MapRecord, fileName) +DEFINE_FIELD_X(MapRecord, MapRecord, labelName) +DEFINE_FIELD_X(MapRecord, MapRecord, name) +DEFINE_FIELD_X(MapRecord, MapRecord, music) +DEFINE_FIELD_X(MapRecord, MapRecord, cdSongId) +DEFINE_FIELD_X(MapRecord, MapRecord, flags) +DEFINE_FIELD_X(MapRecord, MapRecord, levelNumber) +DEFINE_FIELD_X(MapRecord, MapRecord, nextLevel) +DEFINE_FIELD_X(MapRecord, MapRecord, nextSecret) +//native readonly String messages[MAX_MESSAGES]; +DEFINE_FIELD_X(MapRecord, MapRecord, author) diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index d92e9e27d..9bc375d13 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -25,6 +25,12 @@ struct Duke native native static int PlaySound(int num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f); native static bool CheckSoundPlaying(int num); + static void PlayBonusMusic() + { + if (Raze.MusicEnabled()) + PlaySound(DukeSnd.BONUSMUSIC, CHAN_AUTO, CHANF_UI); + } + //========================================================================== // // wrappers around DrawText to allow easier reuse of the old code. diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 264c78ec1..0e14bdf43 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -411,3 +411,105 @@ class Episode5End : ImageScreen } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeMultiplayerBonusScreen : SkippableScreenJob +{ + int playerswhenstarted; + + void Init(int pos) + { + Super.Init(fadein|fadeout); + playerswhenstarted = pos; + } + + override void Start() + { + Duke.PlayBonusMusic(); + } + + override void Draw(double smoothratio) + { + String tempbuf; + int currentclock = int((ticks + smoothratio) * 120 / GameTicRate); + Screen.ClearScreen(); + Screen.DrawTexture(TexMan.CheckForTexture("MENUSCREEN"), false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Color, 0xff808080, DTA_LegacyRenderStyle, STYLE_Normal); + Screen.DrawTexture(TexMan.CheckForTexture("INGAMEDUKETHREEDEE"), true, 160, 34, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true); + if (Raze.isPlutoPak()) Screen.DrawTexture(TexMan.CheckForTexture("MENUPLUTOPAKSPRITE"), true, 260, 36, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true); + + Duke.GameText(160, 58 + 2, "$Multiplayer Totals", 0, 0); + Duke.GameText(160, 58 + 10, currentLevel.DisplayName(), 0, 0); + Duke.GameText(160, 165, "$Presskey", 8 - int(sin(currentclock / 10.) * 8), 0); + + int t = 0; + + Duke.MiniText(38, 80, "$Name", 0, -1, 8); + Duke.MiniText(269+20, 80, "$Kills", 0, 1, 8); + + for (int i = 0; i < playerswhenstarted; i++) + { + tempbuf.Format("%-4d", i + 1); + Duke.MiniText(92 + (i * 23), 80, tempbuf, 0, -1, 3); + } + + for (int i = 0; i < playerswhenstarted; i++) + { + int xfragtotal = 0; + tempbuf.Format("%d", i + 1); + + Duke.MiniText(30, 90 + t, tempbuf, 0); + Duke.MiniText(38, 90 + t, Raze.PlayerName(i), 0, -1, Raze.playerPalette(i)); + + for (int y = 0; y < playerswhenstarted; y++) + { + int frag = Raze.playerFrags(i, y); + if (i == y) + { + int fraggedself = Raze.playerFraggedSelf(y); + tempbuf.Format("%-4d", fraggedself); + Duke.MiniText(92 + (y * 23), 90 + t, tempbuf, 0, -1, 2); + xfragtotal -= fraggedself; + } + else + { + tempbuf.Format("%-4d", frag); + Duke.MiniText(92 + (y * 23), 90 + t, tempbuf, 0); + xfragtotal += frag; + } + /* + if (myconnectindex == connecthead) + { + tempbuf.Format("stats %ld killed %ld %ld\n", i + 1, y + 1, frag); + sendscore(tempbuf); + } + */ + } + + tempbuf.Format("%-4d", xfragtotal); + Duke.MiniText(101 + (8 * 23), 90 + t, tempbuf, 0, -1, 2); + + t += 7; + } + + for (int y = 0; y < playerswhenstarted; y++) + { + int yfragtotal = 0; + for (int i = 0; i < playerswhenstarted; i++) + { + if (i == y) + yfragtotal += Raze.playerFraggedself(i); + int frag = Raze.playerFrags(i, y); + yfragtotal += frag; + } + tempbuf.Format("%-4d", yfragtotal); + Duke.MiniText(92 + (y * 23), 96 + (8 * 7), tempbuf, 0, -1, 2); + } + + Duke.MiniText(45, 96 + (8 * 7), "$Deaths", 0, -1, 8); + } +} + diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index 41cb20aee..9e5609ab1 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -37,8 +37,46 @@ struct UserConfigStruct native extend struct _ { native @UserConfigStruct userConfig; + native MapRecord currentLevel; } +struct MapRecord native +{ + enum MIFlags + { + FORCEEOG = 1, + USERMAP = 2, + } + + native readonly int parTime; + native readonly int designerTime; + native readonly String fileName; + native readonly String labelName; + native readonly String name; + native readonly String music; + native readonly int cdSongId; + native readonly int flags; + native readonly int levelNumber; + + // The rest is only used by Blood + native readonly int nextLevel; + native readonly int nextSecret; + //native readonly String messages[MAX_MESSAGES]; + native readonly String author; + + String GetLabelName() + { + if (flags & USERMAP) return "$TXT_USERMAP"; + return labelName; + } + String DisplayName() + { + if (name == "") return labelName; + return name; + } +} + + struct Raze { static int calcSinTableValue(int ang) @@ -50,6 +88,7 @@ struct Raze native static void StopAllSounds(); native static bool SoundEnabled(); native static bool MusicEnabled(); + native static String PlayerName(int i); // game check shortcuts static bool isNam() @@ -97,6 +136,22 @@ struct Raze return gameinfo.gametype & GAMEFLAG_BLOOD; } + // Dont know yet how to best export this, so for now these are just placeholders as MP is not operational anyway. + static int playerPalette(int i) + { + return 0; + } + + static int playerFrags(int i, int j) + { + return 0; + } + + static int playerFraggedSelf(int i) + { + return 0; + } + } /* diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 477dd8889..c1323e572 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -85,3 +85,31 @@ class ImageScreen : SkippableScreenJob native //override void OnTick(); //override void Draw(double smooth); } + +//--------------------------------------------------------------------------- +// +// this is to have a unified interface to the summary screens +// that can be set up automatically by the games to avoid direct access to game data. +// +//--------------------------------------------------------------------------- + +class SummaryScreenBase : ScreenJob +{ + MapRecord level; + int kills, maxkills; + int secrets, maxsecrets, supersecrets; + int time; + bool cheatflag; + + void SetParameters(MapRecord map, int kills_, int maxkills_, int secrets_, int maxsecrets_, int supersecrets_, int time_, bool cheated) + { + level = map; + kills = kills_; + maxkills = maxkills_; + secrets = secrets_; + maxsecrets = maxsecrets_; + supersecrets = supersecrets_; + time = time_; + cheatflag = cheated; + } +} From c07fcbee083065f825875badb23aad806e007ab4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 23 Apr 2021 14:19:25 +0200 Subject: [PATCH 14/86] - migrated level summary screen. --- source/games/duke/src/namelist_d.h | 9 + wadsrc/static/zscript/engine/inputevents.zs | 3 + .../static/zscript/games/duke/ui/screens.zs | 260 +++++++++++++++++- wadsrc/static/zscript/razebase.zs | 14 + wadsrc/static/zscript/screenjob.zs | 4 +- 5 files changed, 281 insertions(+), 9 deletions(-) diff --git a/source/games/duke/src/namelist_d.h b/source/games/duke/src/namelist_d.h index 62748883d..6da94e0b1 100644 --- a/source/games/duke/src/namelist_d.h +++ b/source/games/duke/src/namelist_d.h @@ -588,6 +588,15 @@ x(RESPAWNMARKERRED, 3190) x(RESPAWNMARKERYELLOW, 3200) x(RESPAWNMARKERGREEN, 3210) x(BONUSSCREEN, 3240) +x(BONUSSCREEN_O1, 3241) +x(BONUSSCREEN_O2, 3242) +x(BONUSSCREEN_O3, 3243) +x(BONUSSCREEN_O4, 3244) +x(BONUSSCREEN2, 3245) +x(BONUSSCREEN2_O1, 3246) +x(BONUSSCREEN2_O2, 3247) +x(BONUSSCREEN2_O3, 3248) +x(BONUSSCREEN2_O4, 3249) x(VIEWBORDER, 3250) x(VICTORY1, 3260) x(VICTORY2, 3261) diff --git a/wadsrc/static/zscript/engine/inputevents.zs b/wadsrc/static/zscript/engine/inputevents.zs index 95a6d29ab..55df156ed 100644 --- a/wadsrc/static/zscript/engine/inputevents.zs +++ b/wadsrc/static/zscript/engine/inputevents.zs @@ -140,6 +140,9 @@ struct InputEvent native play version("2.4") Key_PgUp = 0xc9, // DIK_PRIOR Key_PgDn = 0xd1, // DIK_NEXT + KEY_VOLUMEDOWN = 0xAE, // DIK_VOLUMEDOWN + KEY_VOLUMEUP = 0xB0, // DIK_VOLUMEUP + Key_Mouse1 = 0x100, Key_Mouse2 = 0x101, Key_Mouse3 = 0x102, diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 0e14bdf43..3f88ee1ec 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -452,14 +452,14 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob for (int i = 0; i < playerswhenstarted; i++) { - tempbuf.Format("%-4d", i + 1); + tempbuf = String.Format("%-4d", i + 1); Duke.MiniText(92 + (i * 23), 80, tempbuf, 0, -1, 3); } for (int i = 0; i < playerswhenstarted; i++) { int xfragtotal = 0; - tempbuf.Format("%d", i + 1); + tempbuf = String.Format("%d", i + 1); Duke.MiniText(30, 90 + t, tempbuf, 0); Duke.MiniText(38, 90 + t, Raze.PlayerName(i), 0, -1, Raze.playerPalette(i)); @@ -470,26 +470,26 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob if (i == y) { int fraggedself = Raze.playerFraggedSelf(y); - tempbuf.Format("%-4d", fraggedself); + tempbuf = String.Format("%-4d", fraggedself); Duke.MiniText(92 + (y * 23), 90 + t, tempbuf, 0, -1, 2); xfragtotal -= fraggedself; } else { - tempbuf.Format("%-4d", frag); + tempbuf = String.Format("%-4d", frag); Duke.MiniText(92 + (y * 23), 90 + t, tempbuf, 0); xfragtotal += frag; } /* if (myconnectindex == connecthead) { - tempbuf.Format("stats %ld killed %ld %ld\n", i + 1, y + 1, frag); + tempbuf = String.Format("stats %ld killed %ld %ld\n", i + 1, y + 1, frag); sendscore(tempbuf); } */ } - tempbuf.Format("%-4d", xfragtotal); + tempbuf = String.Format("%-4d", xfragtotal); Duke.MiniText(101 + (8 * 23), 90 + t, tempbuf, 0, -1, 2); t += 7; @@ -505,7 +505,7 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob int frag = Raze.playerFrags(i, y); yfragtotal += frag; } - tempbuf.Format("%-4d", yfragtotal); + tempbuf = String.Format("%-4d", yfragtotal); Duke.MiniText(92 + (y * 23), 96 + (8 * 7), tempbuf, 0, -1, 2); } @@ -513,3 +513,249 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeLevelSummaryScreen : SummaryScreenBase +{ + String lastmapname; + int gfx_offset; + int speech; + int displaystate; + int dukeAnimStart; + + TextureID texBg; + TextureID texOv[4]; + + enum EScreenFlags + { + printTimeText = 1, + printTimeVal = 2, + printKillsText = 4, + printKillsVal = 8, + printSecretsText = 16, + printSecretsVal = 32, + printStatsAll = 63, + dukeAnim = 64, + dukeWait = 128, + + } + + void Init() + { + Super.Init(fadein | fadeout); + int vol = currentLevel.volumeNum(); + String basetex = vol == 1? "BONUSSCREEN2" : "BONUSSCREEN"; + texBg = TexMan.CheckForTexture(basetex); + for(int i = 0; i < 4; i++) + { + String otex = String.Format("%s_O%d", basetex, i+1); + texOv[i] = TexMan.CheckForTexture(otex); + } + lastmapname = currentLevel.DisplayName(); + speech = -1; + displaystate = 0; + + } + + String FormatTime(int time) + { + return String.Format("%02d:%02d", (time / (26 * 60)) % 60, (time / 26) % 60); + } + + override bool OnEvent(InputEvent ev) + { + if (ev.type == InputEvent.Type_KeyDown && !Raze.specialKeyEvent(ev)) + { + if ((displaystate & printStatsAll) != printStatsAll) + { + Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + displaystate = printStatsAll; + } + else if (!(displaystate & dukeAnim)) + { + displaystate |= dukeAnim; + dukeAnimStart = ticks; + Duke.PlaySound(DukeSnd.SHOTGUN_COCK, CHAN_AUTO, CHANF_UI); + static const int speeches[] = { DukeSnd.BONUS_SPEECH1, DukeSnd.BONUS_SPEECH2, DukeSnd.BONUS_SPEECH3, DukeSnd.BONUS_SPEECH4 }; + speech = speeches[random(0, 3)]; + Duke.PlaySound(speech, CHAN_AUTO, CHANF_UI, 1); + } + return true; + } + return false; + } + + override void Start() + { + Duke.PlayBonusMusic(); + } + + override void OnTick() + { + if ((displaystate & printStatsAll) != printStatsAll) + { + if (ticks == 15 * 3) + { + displaystate |= printTimeText; + } + else if (ticks == 15 * 4) + { + displaystate |= printTimeVal; + Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + } + else if (ticks == 15 * 6) + { + displaystate |= printKillsText; + Duke.PlaySound(DukeSnd.FLY_BY, CHAN_AUTO, CHANF_UI); + } + else if (ticks == 15 * 7) + { + displaystate |= printKillsVal; + Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + } + else if (ticks == 15 * 9) + { + displaystate |= printSecretsText; + } + else if (ticks == 15 * 10) + { + displaystate |= printSecretsVal; + Duke.PlaySound(DukeSnd.PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); + } + } + if (displaystate & dukeAnim) + { + if (ticks >= dukeAnimStart + 60) + { + displaystate ^= dukeAnim | dukeWait; + } + } + if (displaystate & dukeWait) + { + if (speech <= 0 || !Duke.CheckSoundPlaying(speech)) + jobstate = finished; + } + } + + void PrintTime() + { + String tempbuf; + Duke.GameText(10, 59 + 9, "$TXT_YourTime", 0); + Duke.GameText(10, 69 + 9, "$TXT_ParTime", 0); + if (!Raze.isNamWW2GI()) + Duke.GameText(10, 79 + 9, "$TXT_3DRTIME", 0); + + if (displaystate & printTimeVal) + { + tempbuf = FormatTime(playtime); + Duke.GameText((320 >> 2) + 71, 59 + 9, tempbuf, 0); + + tempbuf = FormatTime(level.parTime); + Duke.GameText((320 >> 2) + 71, 69 + 9, tempbuf, 0); + + if (!Raze.isNamWW2GI()) + { + tempbuf = FormatTime(level.designerTime); + Duke.GameText((320 >> 2) + 71, 79 + 9, tempbuf, 0); + } + } + } + + void PrintKills() + { + String tempbuf; + Duke.GameText(10, 94 + 9, "$TXT_EnemiesKilled", 0); + Duke.GameText(10, 104 + 9, "$TXT_EnemiesLeft", 0); + + if (displaystate & printKillsVal) + { + tempbuf = String.Format("%-3d", kills); + Duke.GameText((320 >> 2) + 70, 94 + 9, tempbuf, 0); + + if (maxkills < 0) + { + tempbuf = "$TXT_N_A"; + } + else + { + tempbuf = String.Format("%-3d", max(0, maxkills - kills)); + } + Duke.GameText((320 >> 2) + 70, 104 + 9, tempbuf, 0); + } + } + + void PrintSecrets() + { + String tempbuf; + Duke.GameText(10, 119 + 9, "$TXT_SECFND", 0); + Duke.GameText(10, 129 + 9, "$TXT_SECMISS", 0); + + if (displaystate & printSecretsVal) + { + tempbuf = String.Format("%-3d", secrets); + Duke.GameText((320 >> 2) + 70, 119 + 9, tempbuf, 0); + tempbuf = String.Format("%-3d", max(0, maxsecrets - secrets)); + Duke.GameText((320 >> 2) + 70, 129 + 9, tempbuf, 0); + } + } + + override void Draw(double sr) + { + Screen.ClearScreen(); + Screen.DrawTexture(texBg, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal); + + Duke.GameText(160, 190, "$PRESSKEY", 8 - int(sin(ticks * 12 / GameTicRate) * 8), 0); + + if (displaystate & printTimeText) + { + PrintTime(); + } + if (displaystate & printKillsText) + { + PrintKills(); + } + if (displaystate & printSecretsText) + { + PrintSecrets(); + } + + if (displaystate & dukeAnim) + { + switch (((ticks - dukeAnimStart) >> 2) % 15) + { + case 0: + case 1: + case 4: + case 5: + Screen.DrawTexture(texOv[2], true, 199, 31, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true); + break; + case 2: + case 3: + Screen.DrawTexture(texOv[3], true, 199, 31, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true); + break; + } + } + else if (!(displaystate & dukeWait)) + { + switch((ticks >> 3) & 3) + { + case 1: + case 3: + Screen.DrawTexture(texOv[0], true, 199, 31, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true); + break; + case 2: + Screen.DrawTexture(texOv[1], true, 199, 31, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true); + break; + } + } + + if (lastmapname) Duke.BigText(160, 20 - 6, lastmapname); + Duke.BigText(160, 36 - 6, "$Completed"); + } + +} + diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index 9e5609ab1..25ce0cf7f 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -74,6 +74,10 @@ struct MapRecord native if (name == "") return labelName; return name; } + int volumeNum() + { + return levelNumber / 1000; + } } @@ -90,6 +94,16 @@ struct Raze native static bool MusicEnabled(); native static String PlayerName(int i); + static bool specialKeyEvent(InputEvent ev) + { + if (ev.type == InputEvent.Type_KeyDown || ev.type == InputEvent.Type_KeyUp) + { + int key = ev.KeyScan; + if (key == InputEvent.KEY_VOLUMEDOWN || key == InputEvent.KEY_VOLUMEUP || (key > InputEvent.KEY_LASTJOYBUTTON && key < InputEvent.KEY_PAD_LTHUMB_RIGHT)) return true; + } + return false; + } + // game check shortcuts static bool isNam() { diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index c1323e572..89d190b29 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -98,7 +98,7 @@ class SummaryScreenBase : ScreenJob MapRecord level; int kills, maxkills; int secrets, maxsecrets, supersecrets; - int time; + int playtime; bool cheatflag; void SetParameters(MapRecord map, int kills_, int maxkills_, int secrets_, int maxsecrets_, int supersecrets_, int time_, bool cheated) @@ -109,7 +109,7 @@ class SummaryScreenBase : ScreenJob secrets = secrets_; maxsecrets = maxsecrets_; supersecrets = supersecrets_; - time = time_; + playtime = time_; cheatflag = cheated; } } From d5a8147f1bd679b7ea81e18a9405b3e7ba49b592 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 23 Apr 2021 14:26:29 +0200 Subject: [PATCH 15/86] - Duke screens are complete. --- .../static/zscript/games/duke/ui/screens.zs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 3f88ee1ec..680873f63 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -759,3 +759,29 @@ class DukeLevelSummaryScreen : SummaryScreenBase } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeLoadScreen : ScreenJob +{ + MapRecord rec; + + void Init(MapRecord maprec) + { + Super.Init(); + rec = maprec; + } + + override void Draw(double sr) + { + Screen.ClearScreen(); + Screen.DrawTexture(TexMan.CheckForTexture("LOADSCREEN"), false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal); + + Duke.BigText(160, 90, (rec.flags & MapRecord.USERMAP)? "$TXT_LOADUM" : "$TXT_LOADING"); + Duke.BigText(160, 114, rec.DisplayName()); + } +} + From d853b63a1a41ba19245f92dede24431dc49479d1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 23 Apr 2021 16:03:25 +0200 Subject: [PATCH 16/86] - RR summary screen --- source/games/duke/src/namelist_r.h | 1 + source/games/duke/src/sounds.cpp | 15 +- wadsrc/static/zscript/games/duke/dukegame.zs | 508 ++++++++++++++++++ .../static/zscript/games/duke/ui/screens.zs | 282 +++++++++- wadsrc/static/zscript/screenjob.zs | 6 + 5 files changed, 789 insertions(+), 23 deletions(-) diff --git a/source/games/duke/src/namelist_r.h b/source/games/duke/src/namelist_r.h index 9429bf35c..46696dd5e 100644 --- a/source/games/duke/src/namelist_r.h +++ b/source/games/duke/src/namelist_r.h @@ -1241,6 +1241,7 @@ y(RRTILE8640, 8640) y(RRTILE8651, 8651) y(RRTILE8660, 8660) x(ENDGAME, 8677) +x(ENDGAME2, 8678) y(RRTILE8679, 8679) y(RRTILE8680, 8680) y(RRTILE8681, 8681) diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index f5a693dc3..9617b033e 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -887,7 +887,7 @@ static int PlaySound(int num, int chan, int flags, double vol) return S_PlaySound(num, chan, EChanFlags::FromInt(flags), float(vol)); } -DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PLaySound, PlaySound) +DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PlaySound, PlaySound) { PARAM_PROLOGUE; PARAM_INT(snd); @@ -896,6 +896,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Duke, PLaySound, PlaySound) PARAM_FLOAT(vol); ACTION_RETURN_INT(PlaySound(snd, chan, flags, vol)); } +static void StopSound(int num) +{ + S_StopSound(num); +} + + +DEFINE_ACTION_FUNCTION_NATIVE(_Duke, StopSound, StopSound) +{ + PARAM_PROLOGUE; + PARAM_INT(snd); + StopSound(snd); + return 0; +} DEFINE_ACTION_FUNCTION_NATIVE(_Duke, CheckSoundPlaying, S_CheckSoundPlaying) { diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index 9bc375d13..189f4e85e 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -23,6 +23,7 @@ struct Duke native native static void PlaySpecialMusic(int which); native static int PlaySound(int num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f); + native static void StopSound(int num); native static bool CheckSoundPlaying(int num); static void PlayBonusMusic() @@ -488,4 +489,511 @@ struct DukeSnd native FLAMETHROWER_END =400, E5L7_DUKE_QUIT_YOU =401, } +} + +struct RRSnd native +{ + enum ESnd + { + KICK_HIT = 0 , + RICOCHET = 1 , + BULITHIT = 2 , + CASUL_FIRE = 3 , + PISCOCK = 4 , + PISLOAD = 5 , + AK3 = 6 , + XBOWFIRE = 7 , + BUB_HRT1 = 8 , + XBOWEXPL = 9 , + LASERA = 10 , + SHRINKER = 11 , + CRAPFLOW = 12 , + DYNOCLMP = 13 , + DYNEW = 14 , + CRAPSTIR = 15 , + BRICDOOR = 16 , + BOMBEXPL = 17 , + VENTBUST = 18 , + GLASSSND = 19 , + GLASSHVY = 20 , + BUBBLES = 21 , + SPLASH = 22 , + BUB_HRT2 = 23 , + BUB_HRT3 = 24 , + GASP = 25 , + BUB_HRT4 = 26 , + MIRROR1 = 27 , + MIRROR2 = 28 , + MIRROR3 = 29 , + COMPUTER = 30 , + NEON = 31 , + VX_FINAL = 32 , + LN_WAIT = 33 , + BUB_LN1 = 34 , + LN_FINAL = 35 , + CLOCKTK = 36 , + LN_STANK = 37 , + LNRD_GRUNT = 38 , + CLOCKCHM = 39 , + WETFEET = 40 , + LNRD_DEAD = 41 , + LAND = 42 , + END_PIPE = 43 , + ICARUMBA = 44 , + BUB_LN2 = 45 , + LN_CRAP = 46 , + WOODBREK = 47 , + SCUBA = 48 , + TRUCK_LP2 = 49 , + COW1 = 50 , + COW2 = 51 , + COW3 = 52 , + COW4 = 53 , + COW5 = 54 , + BUB_LN3 = 55 , + LATCH = 56 , + BUB_LN5 = 57 , + BUB_LN6 = 58 , + BUB_LN7 = 59 , + BUB_PIK1 = 60 , + BUB_PIK2 = 61 , + BUB_PISS = 62 , + E1L1 = 63 , + E1L2 = 64 , + UFOINSID = 65 , + LN_RODE = 66 , + CURTAIN = 67 , + FIRE09 = 68 , + SQUISHED = 69 , + TELEPORT = 70 , + GBELEV01 = 71 , + LN_BNCH = 72 , + GBELEV02 = 73 , + FROG1 = 74 , + TRUCK_LP = 75 , + SWITCH1 = 76 , + E1L3 = 77 , + LN_HOTDM = 78 , + FLUSH = 79 , + E1L4 = 80 , + QUAKE = 81 , + CHKAMMO = 82 , + MONITORA = 83 , + FROG2 = 84 , + AS_AMB2 = 85 , + AS_AMB1 = 86 , + FBOATIDL = 87 , + FBOATRUN = 88 , + FBOATUP = 89 , + FBOATDN = 90 , + FBOATTRN = 91 , + DRIP3 = 92 , + SWAMPAMB = 93 , + MORTAR = 94 , + JUKEBOX = 95 , + AS_DROPN = 96 , + AS_CRYPT = 97 , + AS_DRCLS = 98 , + LOKGATE = 99 , + METLGAT2 = 100, + METLGAT1 = 101, + E1L5 = 102, + E1L6 = 103, + E1L7 = 104, + E2L1 = 105, + PADDLE = 106, + LN_HOLD = 107, + VX_TAKIT = 108, + SHOT6 = 109, + CT_LAF2 = 110, + CT_GET = 111, + CT_LAF = 112, + CT_PAIN = 113, + CT_DIE = 114, + PIGSOUND1 = 115, + PIGSOUND2 = 116, + PIGSOUND3 = 117, + PIGSOUND4 = 118, + PIGSOUND5 = 119, + BR_ROAM1 = 120, + BR_RECOG = 121, + WHISTLE = 122, + BR_PAIN = 123, + BR_DTH = 124, + VX_ISTHT = 125, + LASERH = 126, + PIGSOUND6 = 127, + PIGSOUND7 = 128, + VX_DIE1 = 129, + MJ_JIB1 = 130, + VX_DIE4 = 131, + VX_DIE5 = 132, + VX_DIE6 = 133, + VX_DIE7 = 134, + VX_OOH = 135, + VX_PAIN1 = 136, + VX_SEX1 = 137, + VX_SEX2 = 138, + VX_SEX3 = 139, + VX_GRNT = 140, + RENO = 141, + BK_MAKE1 = 142, + BK_MAKE2 = 143, + VX_BRNG3 = 144, + VX_CLSR1 = 145, + VX_CLSR2 = 146, + VX_2FAR = 147, + KINGHUH = 148, + VX_BRING = 149, + VX_BITE = 150, + MJ_FART = 151, + VX_LAFF2 = 152, + VX_LAFF3 = 153, + VX_HMMM2 = 154, + VX_HURT2 = 155, + VX_BABY2 = 156, + VX_MHMM = 157, + THUD = 158, + VX_ITSOK = 159, + MJ_RECO2 = 160, + // VX_TPOT1 = 161, + VX_TPOT4 = 162, + // VX_TPIN1 = 163, + ROPECRK = 164, + DR_CRK8 = 165, + DR_ROLL = 166, + STEELAMB = 167, + ROULETTE = 168, + GUNCHANG = 169, + FLIES = 170, + AMB_1 = 171, + GRAVAMB = 172, + HOOTOWL = 173, + WOODS2 = 174, + CATAMB = 175, + E2L2 = 176, + E2L3 = 177, + FBOATX_1 = 178, + FBOATX_2 = 179, + FBOATX_3 = 180, + FBOATX_4 = 181, + FBOATSLW = 182, + PLANE = 183, + CNTAMB = 184, + JUNKAMB2 = 185, + BIKESTRT = 186, + BIKEIDLE = 187, + BIKELOOP = 188, + BIKEJMPS = 189, + BIKEJMPL = 190, + BIKELAND = 191, + JACKJMP1 = 192, + JACKJMP2 = 193, + FIRE_CRACKLE = 194, + BNS_SPCH1 = 195, + BNS_SPCH2 = 196, + BNS_SPCH3 = 197, + E2L4 = 198, + BNS_SPCH4 = 199, + LN_LNDHT = 200, + JACKATK2 = 201, + JACKPAIN = 202, + LN_BITCH = 203, + CT_LAND = 204, + BR_ROAM2 = 205, + LN_HUSH = 206, + LN_PAIN4 = 207, + LN_SLOW = 208, + LN_PAIN4A = 209, + JUG = 210, + LN_PAIN8 = 211, + MONITOR = 212, + JACKATK1 = 213, + BIKEUP = 214, + PLANEXP = 215, + JUGALUG7 = 216, + DIDDLP = 217, + ELVISMOD = 218, + // PISCOCK = 219, + BIKESKID = 220, + LN_STINK = 221, + JIBBED1 = 222, + JIBBED2 = 223, + JIBBED3 = 224, + JIBBED4 = 225, + JIBBED5 = 226, + JIBBED6 = 227, + JIBBED7 = 228, + LN_BACON = 229, + E2L5 = 230, + REGISTER = 231, + BBQGRILL = 232, + CRSSBELL = 233, + TRAIN = 234, + SLOTS = 235, + INDIANS = 236, + RADIO = 237, + BIKEX_1 = 238, + BIKEX_2 = 239, + BIKEX_3 = 240, + TVSNOW = 241, + WINDLITE = 242, + EXITMENU = 243, + CHKBOWFR = 244, + DSCREM04 = 245, + SHRNK_HIT = 246, + CHKBOWEX = 247, + INTOMENU = 248, + LAVAFLOW = 249, + LAVA_RK = 250, + BIKELOO2 = 251, + SLINGBL = 252, + BR_ROAM3 = 253, + KILLME = 254, + E2L6 = 255, + RINTRO = 256, + MIRROR4 = 257, + MIRROR5 = 258, + GAMBELEV = 259, + SLINGHIT = 260, + PIANO_P1 = 261, + BANJO1 = 262, + JIBBED13 = 263, + LN_BBQ = 264, + JIBBED8 = 265, + JIBBED9 = 266, + JIBBED10 = 267, + JIBBED11 = 268, + JIBBED12 = 269, + LNRD_KILLED4 = 270, + LNRD_KILLED5 = 271, + BANJO2 = 272, + BANJO3 = 273, + LN_PAIN2 = 274, + LN_PAIN3 = 275, + BK_ALIVE = 276, + BK_BOURB = 277, + BK_CHEER = 278, + BK_DIENB = 279, + BK_DNTLK = 280, + BK_FUN = 281, + BK_HEY = 282, + E2L7 = 283, + BK_HEYNB = 284, + BK_JOYRD = 285, + BK_KEEPA = 286, + BK_PLEAS = 287, + BK_RIDE = 288, + BK_ROAD = 289, + BK_SCRAT = 290, + BK_SHTUP = 291, + BK_SNORT = 292, + BK_TOHEL = 293, + WHIPYOU = 294, + BK_TRYIN = 295, + BK_PAIN1 = 296, + BK_PAIN2 = 297, + BK_PAIN3 = 298, + CH_BALD = 299, + CH_TEAS1 = 300, + CH_TEAS2 = 301, + CH_TEAS3 = 302, + CH_SANDP = 303, + LN_PAIN5 = 304, + LN_PAIN6 = 305, + LN_PAIN7 = 306, + CH_DONIT = 307, + CH_WHOOP = 308, + CH_NIPPL = 309, + CH_BARN = 310, + CH_GTEAM = 311, + CH_GOGOG = 312, + CH_REDOK = 313, + CH_2468 = 314, + CH_BIGON = 315, + HULK_ROAM = 316, + HULK_RECOG = 317, + HULK_ATTACK = 318, + HULK_PAIN = 319, + HULK_DYING = 320, + HULK_SPIT = 321, + CH_PAIN1 = 322, + CH_PAIN2 = 323, + CH_PAIN3 = 324, + CH_HURT = 325, + AK4 = 326, + CHKSCR1 = 327, + SHIPWREK = 328, + HYDROGLY = 329, + PIANO_P2 = 330, + FROGTOSS = 331, + TRAIN2 = 332, + CRICKET1 = 333, + CRICKET2 = 334, + PIGRUNT = 335, + GOCATGO = 336, + ANNOUNC1 = 337, + ANNOUNC2 = 338, + TRACTOR = 339, + PIANO_P3 = 340, + RESIZE = 341, + VX_TPIN2 = 342, + VX_TPIN4 = 343, + VX_HLPME = 344, + ATFSPEAK = 345, + WINDCAVE = 346, + ALARM = 347, + SF_THLAW = 348, + SF_TLAW2 = 349, + LN_SCREW = 350, + THUNDER1 = 351, + THUNDER2 = 352, + THUNDER3 = 353, + BOWLSTRT = 354, + BOWLPIN = 355, + BOWLLOOP = 356, + MJ_JIB2 = 357, + VX_KICK2 = 358, + VX_KICK3 = 359, + MJ_RECO1 = 360, + VX_HIYA = 361, + VX_HIYA2 = 362, + SF_ATTN = 363, + SF_DETH1 = 364, + SF_DETH2 = 365, + SF_DETH3 = 366, + TEDOUT = 367, + SF_FREZ2 = 368, + SF_GETYA = 369, + SF_HANDS = 370, + STEELAM2 = 371, + STEELAM3 = 372, + SF_HEY = 373, + SF_HOLD = 374, + SF_LAFF1 = 375, + LN_FLYOP = 376, + LN_SHTHD = 377, + SF_NAME = 378, + SF_OVER = 379, + SF_PAIN1 = 380, + SF_PAIN2 = 381, + SF_PAIN3 = 382, + SF_RLOAD = 383, + SF_RLOD2 = 384, + SF_SHOOT = 385, + JAWHARP = 386, + LN_TIGHT = 387, + DR_CLS = 388, + SCRAPE_1 = 389, + YEHAA16 = 390, + LN_WHUP = 391, + CHKNFLAP = 392, + CHKN_1 = 393, + CHKN_2 = 394, + CHIKDETH = 395, + AMB_ROOM = 396, + BR_ITCH = 397, + BR_SCRTH = 398, + BR_SNIFF = 399, + TRUKDIE = 400, + ZIPOPEN = 401, + ZIPPSTRK = 402, + MOSQUI4 = 403, + FART1 = 404, + SWITCH2 = 405, + SQUEAKY = 406, + CATDOOR = 407, + JUNKSWCH = 408, + CONVEYR = 409, + SWITCH3 = 410, + BIKEENEM = 411, + BIGDOOR = 412, + FLOODGAT = 413, + JACK_RM1 = 414, + MN_FREAK = 415, + MN_PN = 416, + MN_REC = 417, + MN_AMB = 418, + LOKDOOR = 419, + VOMIT = 420, + TOSS = 421, + FART2 = 422, + FART3 = 423, + FART4 = 424, + CHUG = 425, + CROWUSH = 426, + WUSSLAF = 427, + LN_CITY = 428, + MUNCH2 = 429, + TESLARC = 430, + BUZSAWSND = 431, + ELEVLOOP = 432, + PISSEND = 433, + PISSLOOP = 434, + PISSSTRT = 435, + CRAP = 436, + PEE = 437, + JACK_RM2 = 438, + BELL = 439, + TRAINWRK = 440, + DOOR_PKT = 441, + GAMBDOOR = 442, + OVEN = 443, + CREMATOR = 444, + JOE9000A = 445, + JOE9000B = 446, + JOE9000C = 447, + CHINESE = 448, + SIGNROT = 449, + XBOWCOCK = 450, + PWDERKEG = 451, + DG_BARK1 = 452, + DG_GRWL1 = 453, + DG_YELP = 454, + DG_DIE = 455, + UFO = 456, + UFOLET = 457, + JACKJIB1 = 458, + JACKJIB2 = 459, + JACKJIB3 = 460, + JACKJIB4 = 461, + JACKJIB5 = 462, + WTRFALL = 463, + BK_JIB1 = 464, + FRIDGEOP = 465, + FRIDGECL = 466, + DG_LUNGE = 467, + DRIVTHRU = 468, + FAN = 469, + CRUSHER = 470, + BALLOON = 471, + POOLBUD = 472, + STAMPER = 473, + BK_JIB2 = 474, + MORNING = 475, + DG_BARK2 = 476, + DG_GRWL2 = 477, + REDNECK2 = 478, + XATRIX = 479, + MJ_ATTK1 = 480, + MJ_JUMP = 485, + MJ_PAIN1 = 481, + MJ_PAIN2 = 482, + MJ_ROAM1 = 483, + MJ_ROAM2 = 484, + MJ_ROLL = 486, + DISHES = 487, + BUB_ELV1 = 488, + BUB_ELV2 = 489, + BUB_ELV3 = 490, + BK_JIB3 = 491, + CH_JIB1 = 492, + CH_JIB2 = 493, + CH_JIB3 = 494, + SIGNHIT = 495, + UMHUM = 496, + COYOTE = 497, + BUB_HEY1 = 498, + BUB_HEY2 = 499, + } } \ No newline at end of file diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 680873f63..8a8d0ed0c 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -413,7 +413,7 @@ class Episode5End : ImageScreen //--------------------------------------------------------------------------- // -// +// This handles both Duke and RR. // //--------------------------------------------------------------------------- @@ -421,10 +421,10 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob { int playerswhenstarted; - void Init(int pos) + void Init(int pws) { Super.Init(fadein|fadeout); - playerswhenstarted = pos; + playerswhenstarted = pws; } override void Start() @@ -434,26 +434,29 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob override void Draw(double smoothratio) { + bool isRR = Raze.isRR(); + double titlescale = isRR? 0.36 : 1; + String tempbuf; int currentclock = int((ticks + smoothratio) * 120 / GameTicRate); Screen.ClearScreen(); Screen.DrawTexture(TexMan.CheckForTexture("MENUSCREEN"), false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Color, 0xff808080, DTA_LegacyRenderStyle, STYLE_Normal); - Screen.DrawTexture(TexMan.CheckForTexture("INGAMEDUKETHREEDEE"), true, 160, 34, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true); + Screen.DrawTexture(TexMan.CheckForTexture("INGAMEDUKETHREEDEE"), true, 160, 34, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true, DTA_ScaleX, titlescale, DTA_ScaleY, titlescale); if (Raze.isPlutoPak()) Screen.DrawTexture(TexMan.CheckForTexture("MENUPLUTOPAKSPRITE"), true, 260, 36, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true); - Duke.GameText(160, 58 + 2, "$Multiplayer Totals", 0, 0); + Duke.GameText(160, isRR? 58 : 58 + 2, "$Multiplayer Totals", 0, 0); Duke.GameText(160, 58 + 10, currentLevel.DisplayName(), 0, 0); Duke.GameText(160, 165, "$Presskey", 8 - int(sin(currentclock / 10.) * 8), 0); int t = 0; - Duke.MiniText(38, 80, "$Name", 0, -1, 8); - Duke.MiniText(269+20, 80, "$Kills", 0, 1, 8); + Duke.MiniText(38, 80, "$Name", 0, -1, isRR? 0 : 8); + Duke.MiniText(269+20, 80, "$Kills", 0, 1, isRR? 0: 8); for (int i = 0; i < playerswhenstarted; i++) { tempbuf = String.Format("%-4d", i + 1); - Duke.MiniText(92 + (i * 23), 80, tempbuf, 0, -1, 3); + Duke.MiniText(92 + (i * 23), 80, tempbuf, 0, -1, isRR? 0: 3); } for (int i = 0; i < playerswhenstarted; i++) @@ -471,7 +474,7 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob { int fraggedself = Raze.playerFraggedSelf(y); tempbuf = String.Format("%-4d", fraggedself); - Duke.MiniText(92 + (y * 23), 90 + t, tempbuf, 0, -1, 2); + Duke.MiniText(92 + (y * 23), 90 + t, tempbuf, 0, -1, isRR? 0: 2); xfragtotal -= fraggedself; } else @@ -490,7 +493,7 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob } tempbuf = String.Format("%-4d", xfragtotal); - Duke.MiniText(101 + (8 * 23), 90 + t, tempbuf, 0, -1, 2); + Duke.MiniText(101 + (8 * 23), 90 + t, tempbuf, 0, -1, isRR? 0: 2); t += 7; } @@ -506,10 +509,10 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob yfragtotal += frag; } tempbuf = String.Format("%-4d", yfragtotal); - Duke.MiniText(92 + (y * 23), 96 + (8 * 7), tempbuf, 0, -1, 2); + Duke.MiniText(92 + (y * 23), 96 + (8 * 7), tempbuf, 0, -1, isRR? 0: 2); } - Duke.MiniText(45, 96 + (8 * 7), "$Deaths", 0, -1, 8); + Duke.MiniText(45, 96 + (8 * 7), "$Deaths", 0, -1, isRR? 0: 8); } } @@ -522,7 +525,6 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob class DukeLevelSummaryScreen : SummaryScreenBase { String lastmapname; - int gfx_offset; int speech; int displaystate; int dukeAnimStart; @@ -547,7 +549,7 @@ class DukeLevelSummaryScreen : SummaryScreenBase void Init() { Super.Init(fadein | fadeout); - int vol = currentLevel.volumeNum(); + int vol = level.volumeNum(); String basetex = vol == 1? "BONUSSCREEN2" : "BONUSSCREEN"; texBg = TexMan.CheckForTexture(basetex); for(int i = 0; i < 4; i++) @@ -555,17 +557,12 @@ class DukeLevelSummaryScreen : SummaryScreenBase String otex = String.Format("%s_O%d", basetex, i+1); texOv[i] = TexMan.CheckForTexture(otex); } - lastmapname = currentLevel.DisplayName(); + lastmapname = level.DisplayName(); speech = -1; displaystate = 0; } - String FormatTime(int time) - { - return String.Format("%02d:%02d", (time / (26 * 60)) % 60, (time / 26) % 60); - } - override bool OnEvent(InputEvent ev) { if (ev.type == InputEvent.Type_KeyDown && !Raze.specialKeyEvent(ev)) @@ -759,6 +756,238 @@ class DukeLevelSummaryScreen : SummaryScreenBase } +//--------------------------------------------------------------------------- +// +// TBD: fold this into DukeLevelSummaryScreen? +// +//--------------------------------------------------------------------------- + +class RRLevelSummaryScreen : SummaryScreenBase +{ + String lastmapname; + int speech; + int displaystate; + int exitSoundStart; + TextureID texBg; + + enum EFlags + { + printTimeText = 1, + printTimeVal = 2, + printKillsText = 4, + printKillsVal = 8, + printSecretsText = 16, + printSecretsVal = 32, + printStatsAll = 63, + exitSound = 64, + exitWait = 128, + + } + + void Init(bool dofadeout = true) + { + Super.Init(dofadeout? (fadein | fadeout) : fadein); + String s; + if (level.flags & MapRecord.USERMAP) + s = "BONUSPIC01"; + else if (!Raze.isRRRA()) + s = String.Format("BONUSPIC%02d", 1 + clamp((level.levelNumber / 1000) * 7 + (level.levelNumber % 1000), 0, 13)); + else + s = String.Format("LEVELMAP%02d", 1 + clamp((level.levelNumber / 1000) * 7 + (level.levelNumber % 1000), 0, 13)); + + lastmapname = level.DisplayName(); + texBg = TexMan.CheckForTexture(s); + } + + override bool OnEvent(InputEvent ev) + { + if (ev.type == InputEvent.Type_KeyDown && !Raze.specialKeyEvent(ev)) + { + if ((displaystate & printStatsAll) != printStatsAll) + { + Duke.PlaySound(RRSnd.FART1, CHAN_AUTO, CHANF_UI); + displaystate = printStatsAll; + } + else if (!(displaystate & exitSound)) + { + displaystate |= exitSound; + exitSoundStart = ticks; + Duke.PlaySound(RRSnd.CHUG, CHAN_AUTO, CHANF_UI); + static const int speeches[] = { RRSnd.BNS_SPCH1, RRSnd.BNS_SPCH2, RRSnd.BNS_SPCH3, RRSnd.BNS_SPCH4 }; + speech = speeches[random(0, 3)]; + Duke.PlaySound(speech, CHAN_AUTO, CHANF_UI); + } + return true; + } + return false; + } + + override void Start() + { + Duke.PlayBonusMusic(); + } + + override void OnTick() + { + if ((displaystate & printStatsAll) != printStatsAll) + { + if (ticks == 15 * 3) + { + displaystate |= printTimeText; + } + else if (ticks == 15 * 4) + { + displaystate |= printTimeVal; + Duke.PlaySound(RRSnd.FART1, CHAN_AUTO, CHANF_UI); + } + else if (ticks == 15 * 6) + { + displaystate |= printKillsText; + } + else if (ticks == 15 * 7) + { + displaystate |= printKillsVal; + Duke.PlaySound(RRSnd.FART1, CHAN_AUTO, CHANF_UI); + } + else if (ticks == 15 * 9) + { + displaystate |= printSecretsText; + } + else if (ticks == 15 * 10) + { + displaystate |= printSecretsVal; + Duke.PlaySound(RRSnd.FART1, CHAN_AUTO, CHANF_UI); + } + } + if (displaystate & exitSound) + { + if (ticks >= exitSoundStart + 60) + { + displaystate ^= exitSound | exitWait; + } + } + if (displaystate & exitWait) + { + if (speech <= 0 || !Duke.CheckSoundPlaying(speech)) + jobstate = finished; + } + } + + void PrintTime() + { + String tempbuf; + Duke.BigText(30, 48, "$TXT_YerTime", -1); + Duke.BigText(30, 64, "$TXT_ParTime", -1); + Duke.BigText(30, 80, "$TXT_XTRTIME", -1); + + if (displaystate & printTimeVal) + { + tempbuf = FormatTime(playtime); + Duke.BigText(191, 48, tempbuf, -1); + + tempbuf = FormatTime(level.parTime); + Duke.BigText(191, 64, tempbuf, -1); + + tempbuf = FormatTime(level.designerTime); + Duke.BigText(191, 80, tempbuf, -1); + } + } + + void PrintKills() + { + String tempbuf; + Duke.BigText(30, 112, "$TXT_VarmintsKilled", -1); + Duke.BigText(30, 128, "$TXT_VarmintsLeft", -1); + + if (displaystate & printKillsVal) + { + tempbuf.Format("%-3d", kills); + Duke.BigText(231, 112, tempbuf, -1); + if (maxkills < 0) + { + tempbuf = "$TXT_N_A"; + } + else + { + tempbuf = String.Format("%-3d", max(0, maxkills - kills)); + } + Duke.BigText(231, 128, tempbuf, -1); + } + } + + void PrintSecrets() + { + String tempbuf; + Duke.BigText(30, 144, "$TXT_SECFND", -1); + Duke.BigText(30, 160, "$TXT_SECMISS", -1); + + if (displaystate & printSecretsVal) + { + tempbuf = String.Format("%-3d", secrets); + Duke.BigText(231, 144, tempbuf, -1); + tempbuf = String.Format("%-3d", max(0, maxsecrets - secrets)); + Duke.BigText(231, 160, tempbuf, -1); + } + } + + override void Draw(double sr) + { + Screen.ClearScreen(); + Screen.DrawTexture(texBg, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal); + + if (lastmapname) Duke.BigText(80, 16, lastmapname, -1); + Duke.BigText(15, 192, "$PRESSKEY", -1); + + if (displaystate & printTimeText) + { + PrintTime(); + } + if (displaystate & printKillsText) + { + PrintKills(); + } + if (displaystate & printSecretsText) + { + PrintSecrets(); + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class RRRAEndOfGame : SkippableScreenJob +{ + void Init() + { + Super.Init(fadein|fadeout); + } + + override void OnSkip() + { + Duke.StopSound(RRSnd.LN_FINAL); + } + + override void Start() + { + Duke.PlaySound(RRSnd.LN_FINAL, CHAN_AUTO, CHANF_UI); + } + + override void OnTick() + { + if (!Duke.CheckSoundPlaying(RRSnd.LN_FINAL) && ticks > 15 * GameTicRate) jobstate = finished; // make sure it stays, even if sound is off. + } + + override void Draw(double sr) + { + let tex = TexMan.CheckForTexture(((ticks >> 2) & 1)? "ENDGAME2" : "ENDGAME"); + Screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43); + } +} + //--------------------------------------------------------------------------- // // @@ -780,8 +1009,17 @@ class DukeLoadScreen : ScreenJob Screen.ClearScreen(); Screen.DrawTexture(TexMan.CheckForTexture("LOADSCREEN"), false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal); - Duke.BigText(160, 90, (rec.flags & MapRecord.USERMAP)? "$TXT_LOADUM" : "$TXT_LOADING"); - Duke.BigText(160, 114, rec.DisplayName()); + if (!Raze.IsRR()) + { + Duke.BigText(160, 90, (rec.flags & MapRecord.USERMAP)? "$TXT_LOADUM" : "$TXT_LOADING"); + Duke.BigText(160, 114, rec.DisplayName()); + } + else + { + int y = Raze.isRRRA()? 140 : 90; + Duke.BigText(160, y, (rec.flags & MapRecord.USERMAP)? "$TXT_ENTRUM" : "$TXT_ENTERIN", 0); + Duke.BigText(160, y+24, rec.DisplayName(), 0); + } } } diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 89d190b29..696215310 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -112,4 +112,10 @@ class SummaryScreenBase : ScreenJob playtime = time_; cheatflag = cheated; } + + String FormatTime(int time) + { + return String.Format("%02d:%02d", (time / (26 * 60)) % 60, (time / 26) % 60); + } + } From 4ff2010bd13d177655f81d8f511f90c0daa61d2f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 25 Apr 2021 20:02:40 +0200 Subject: [PATCH 17/86] - moved the entire screen job management to the script side. This isn't hooked up yet and lots of code is commented out, the games won't start with this commit. --- source/common/2d/v_draw.cpp | 8 + source/core/gamecontrol.cpp | 12 + source/core/movie/movieplayer.cpp | 37 +- source/core/screenjob.cpp | 40 +- source/core/screenjob.h | 9 +- source/games/blood/src/credits.cpp | 6 + source/games/blood/src/endgame.cpp | 10 +- source/games/duke/src/2d_d.cpp | 21 +- source/games/duke/src/2d_r.cpp | 14 +- source/games/exhumed/src/2d.cpp | 105 ++++- source/games/exhumed/src/exhumed.h | 3 - source/games/exhumed/src/gameloop.cpp | 86 +--- source/games/exhumed/src/movie.cpp | 2 + source/games/sw/src/2d.cpp | 19 +- wadsrc/static/zscript/engine/base.zs | 1 + .../static/zscript/games/duke/ui/screens.zs | 7 +- wadsrc/static/zscript/razebase.zs | 11 +- wadsrc/static/zscript/screenjob.zs | 432 ++++++++++++++++-- 18 files changed, 665 insertions(+), 158 deletions(-) diff --git a/source/common/2d/v_draw.cpp b/source/common/2d/v_draw.cpp index 7250a11c9..e662baed4 100644 --- a/source/common/2d/v_draw.cpp +++ b/source/common/2d/v_draw.cpp @@ -331,6 +331,14 @@ DEFINE_ACTION_FUNCTION(_Screen, ClearScreen) return 0; } +DEFINE_ACTION_FUNCTION(_Screen, SetScreenFade) +{ + PARAM_PROLOGUE; + PARAM_FLOAT(x); + twod->SetScreenFade(x); + return 0; +} + void F2DDrawer::GetClipRect(int *x, int *y, int *w, int *h) { diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 7b3ef32fe..2b475f59e 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1449,6 +1449,12 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, StopAllSounds, FX_StopAllSounds) return 0; } +DEFINE_ACTION_FUNCTION_NATIVE(_Raze, StopMusic, Mus_Stop) +{ + Mus_Stop(); + return 0; +} + DEFINE_ACTION_FUNCTION_NATIVE(_Raze, SoundEnabled, SoundEnabled) { ACTION_RETURN_INT(SoundEnabled()); @@ -1459,6 +1465,11 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, MusicEnabled, MusicEnabled) ACTION_RETURN_INT(MusicEnabled()); } +DEFINE_ACTION_FUNCTION_NATIVE(_Raze, GetTimeFrac, I_GetTimeFrac) +{ + ACTION_RETURN_INT(I_GetTimeFrac()); +} + DEFINE_ACTION_FUNCTION(_Raze, PlayerName) { PARAM_PROLOGUE; @@ -1474,6 +1485,7 @@ DEFINE_GLOBAL(gamestate) DEFINE_GLOBAL(demoplayback) DEFINE_GLOBAL(consoleplayer) DEFINE_GLOBAL(currentLevel) +DEFINE_GLOBAL(paused) DEFINE_FIELD_X(MapRecord, MapRecord, parTime) DEFINE_FIELD_X(MapRecord, MapRecord, designerTime) diff --git a/source/core/movie/movieplayer.cpp b/source/core/movie/movieplayer.cpp index 80b6fca7b..7d6c690b5 100644 --- a/source/core/movie/movieplayer.cpp +++ b/source/core/movie/movieplayer.cpp @@ -49,6 +49,7 @@ #include #include #include "raze_music.h" +#include "vm.h" class MoviePlayer @@ -649,6 +650,7 @@ public: } }; +#if 0 //--------------------------------------------------------------------------- // // @@ -697,8 +699,9 @@ public: player = nullptr; } }; +#endif - +#if 0 //--------------------------------------------------------------------------- // // @@ -751,7 +754,7 @@ MoviePlayer* OpenMovie(const char* filename, const AnimSound* ans, const int* fr else if (!memcmp(id, "SMK2", 4)) { fr.Close(); - auto anm = new SmkPlayer(filename, ans, true); // Fixme: Handle Blood's video scaling behavior more intelligently. + auto anm = new SmkPlayer(filename, ans, isBlood()); // Fixme: Handle Blood's video scaling behavior more intelligently. if (!anm->isvalid()) { error.Format("%s: invalid SMK file.\n", filename); @@ -811,4 +814,34 @@ DScreenJob* PlayVideo(const char* filename, const AnimSound* ans, const int* fra return Create(movie); } +#endif +DEFINE_ACTION_FUNCTION(_MoviePlayer, OpenMovie) +{ + PARAM_PROLOGUE; + // todo + return 0; +} + +DEFINE_ACTION_FUNCTION(_MoviePlayer, Start) +{ + PARAM_SELF_STRUCT_PROLOGUE(MoviePlayer); + self->Start(); + return 0; +} + +DEFINE_ACTION_FUNCTION(_MoviePlayer, Frame) +{ + PARAM_SELF_STRUCT_PROLOGUE(MoviePlayer); + PARAM_FLOAT(clock); + self->Frame(int64_t(clock)); + return 0; +} + +DEFINE_ACTION_FUNCTION(_MoviePlayer, Destroy) +{ + PARAM_SELF_STRUCT_PROLOGUE(MoviePlayer); + self->Stop(); + delete self; + return 0; +} diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index b80f22a39..33de0a84e 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -54,6 +54,7 @@ #include "vm.h" +#if 0 IMPLEMENT_CLASS(DScreenJob, true, false) IMPLEMENT_CLASS(DSkippableScreenJob, true, false) IMPLEMENT_CLASS(DBlackScreen, true, false) @@ -318,17 +319,6 @@ bool ScreenJobRunner::OnEvent(event_t* ev) { if (paused || index >= jobs.Size()) return false; - if (ev->type == EV_KeyDown) - { - // We never reach the key binding checks in G_Responder, so for the console we have to check for ourselves here. - auto binding = Bindings.GetBinding(ev->data1); - if (binding.CompareNoCase("toggleconsole") == 0) - { - C_ToggleConsole(); - return true; - } - } - if (jobs[index]->state != DScreenJob::running) return false; return jobs[index]->OnEvent(ev); @@ -432,6 +422,10 @@ bool ScreenJobRunner::RunFrame() ScreenJobRunner *runner; +#endif + + +#if 0 void RunScreenJob(TArray& jobs, CompletionFunc completion, int flags) { assert(completion != nullptr); @@ -446,38 +440,52 @@ void RunScreenJob(TArray& jobs, CompletionFunc completion, int flag completion(false); } } +#endif void DeleteScreenJob() { + /* if (runner) { delete runner; runner = nullptr; } - twod->SetScreenFade(1); + twod->SetScreenFade(1);*/ } void EndScreenJob() { - if (runner) runner->OnFinished(); + //if (runner) runner->OnFinished(); DeleteScreenJob(); } bool ScreenJobResponder(event_t* ev) { - if (runner) return runner->OnEvent(ev); + if (ev->type == EV_KeyDown) + { + // We never reach the key binding checks in G_Responder, so for the console we have to check for ourselves here. + auto binding = Bindings.GetBinding(ev->data1); + if (binding.CompareNoCase("toggleconsole") == 0) + { + C_ToggleConsole(); + return true; + } + } + + //if (runner) return runner->OnEvent(ev); return false; } void ScreenJobTick() { - if (runner) runner->OnTick(); + //if (runner) runner->OnTick(); } bool ScreenJobDraw() { // we cannot recover from this because we have no completion callback to call. + /* if (!runner) { // We can get here before a gameaction has been processed. In that case just draw a black screen and wait. @@ -486,6 +494,7 @@ bool ScreenJobDraw() return false; } auto res = runner->RunFrame(); + */ int res = 0; if (!res) { assert((gamestate != GS_INTERMISSION && gamestate != GS_INTRO) || gameaction != ga_nothing); @@ -493,4 +502,3 @@ bool ScreenJobDraw() } return res; } - diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 3916a3373..bd3dbe5e5 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -9,6 +9,7 @@ using CompletionFunc = std::function; struct JobDesc; class ScreenJobRunner; +#if 0 class DScreenJob : public DObject { DECLARE_CLASS(DScreenJob, DObject) @@ -137,7 +138,9 @@ public: void OnTick() override; void Draw(double smooth) override; }; +#endif +#if 0 //--------------------------------------------------------------------------- // // @@ -175,9 +178,10 @@ public: void OnTick(); bool RunFrame(); }; +#endif - +#if 0 enum { SJ_DONTCLEAR = 1, @@ -187,6 +191,7 @@ enum void RunScreenJob(TArray& jobs, CompletionFunc completion, int flags = 0); +#endif void EndScreenJob(); void DeleteScreenJob(); bool ScreenJobResponder(event_t* ev); @@ -199,4 +204,6 @@ struct AnimSound int soundnum; }; +#if 0 DScreenJob *PlayVideo(const char *filename, const AnimSound *ans = nullptr, const int *frameticks = nullptr, bool nosoundstop = false); +#endif \ No newline at end of file diff --git a/source/games/blood/src/credits.cpp b/source/games/blood/src/credits.cpp index 4919c2219..43f30c6d4 100644 --- a/source/games/blood/src/credits.cpp +++ b/source/games/blood/src/credits.cpp @@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS +#if 0 class DBloodIntroImage : public DImageScreen { bool mus; @@ -50,6 +51,7 @@ public: if (mus) sndPlaySpecialMusicOrNothing(MUS_INTRO); } }; +#endif //--------------------------------------------------------------------------- // @@ -59,6 +61,7 @@ public: void playlogos() { +#if 0 TArray jobs; static AnimSound logosound[] = { @@ -101,10 +104,12 @@ void playlogos() Mus_Stop(); gameaction = ga_mainmenu; }, SJ_BLOCKUI); +#endif } void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func) { +#if 0 TArray jobs; static AnimSound smksound[] = { @@ -128,6 +133,7 @@ void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func) smksound[0].soundnum = id; jobs.Push(PlayVideo(smkk, smksound, nullptr)); RunScreenJob(jobs, func); +#endif } void levelPlayIntroScene(int nEpisode, CompletionFunc completion) diff --git a/source/games/blood/src/endgame.cpp b/source/games/blood/src/endgame.cpp index 16f163b5b..27d19dce5 100644 --- a/source/games/blood/src/endgame.cpp +++ b/source/games/blood/src/endgame.cpp @@ -91,6 +91,7 @@ static void DrawCaption(const char* text) } +#if 0 // public DScreenJob class DBloodSummaryScreen : public DSkippableScreenJob { void DrawKills(void) @@ -170,9 +171,11 @@ class DBloodSummaryScreen : public DSkippableScreenJob } } }; +#endif void GameInterface::LevelCompleted(MapRecord *map, int skill) { +#if 0 TArray job(1, true); job[0] = Create(); sndStartSample(268, 128, -1, false, CHANF_UI); @@ -182,7 +185,9 @@ void GameInterface::LevelCompleted(MapRecord *map, int skill) soundEngine->StopAllChannels(); gameaction = ga_nextlevel; }); - +#else + gameaction = ga_nextlevel; +#endif } @@ -273,6 +278,7 @@ void SerializeGameStats(FSerializer& arc) CSecretMgr gSecretMgr; CKillMgr gKillMgr; +#if 0 class DBloodLoadScreen : public DScreenJob { const char* pzLoadingScreenText1; @@ -306,6 +312,6 @@ void loadscreen(const char *caption, MapRecord* rec, CompletionFunc func) job[0] = Create(caption, rec); RunScreenJob(job, func); } - +#endif END_BLD_NS diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index 0667fd568..274b3452c 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -131,7 +131,7 @@ void InitFonts_d() } - +#if 0 //========================================================================== // // wrappers around DrawText to allow easier reuse of the old code. @@ -293,6 +293,7 @@ public: S_PlaySound(NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI); } }; +#endif //--------------------------------------------------------------------------- // @@ -302,6 +303,7 @@ public: void Logo_d(const CompletionFunc &completion) { +#if 0 Mus_Stop(); FX_StopAllSounds(); // JBF 20031228 @@ -322,8 +324,10 @@ void Logo_d(const CompletionFunc &completion) } jobs.Push(Create()); RunScreenJob(jobs, completion, SJ_BLOCKUI); +#endif } +#if 0 //--------------------------------------------------------------------------- // // @@ -715,6 +719,7 @@ static void bonussequence_d(int num, TArray& jobs) break; } } +#endif //--------------------------------------------------------------------------- // @@ -724,22 +729,27 @@ static void bonussequence_d(int num, TArray& jobs) void showtwoscreens(const CompletionFunc& completion) { +#if 0 TArray jobs; jobs.Push(Create(3291)); jobs.Push(Create(3290)); RunScreenJob(jobs, completion); +#endif } void doorders(const CompletionFunc& completion) { +#if 0 TArray jobs; for (int i = 0; i < 4; i++) jobs.Push(Create(ORDERING + i)); RunScreenJob(jobs, completion); +#endif } +#if 0 //--------------------------------------------------------------------------- // // @@ -1080,6 +1090,7 @@ public: } }; +#endif //--------------------------------------------------------------------------- // @@ -1089,6 +1100,7 @@ public: void dobonus_d(int bonusonly, const CompletionFunc& completion) { +#if 0 TArray jobs; FX_StopAllSounds(); @@ -1113,6 +1125,7 @@ void dobonus_d(int bonusonly, const CompletionFunc& completion) RunScreenJob(jobs, completion); } else if (completion) completion(false); +#endif } //--------------------------------------------------------------------------- @@ -1123,6 +1136,7 @@ void dobonus_d(int bonusonly, const CompletionFunc& completion) void e4intro(const CompletionFunc& completion) { +#if 0 TArray jobs; static const AnimSound vol42a[] = @@ -1157,8 +1171,10 @@ void e4intro(const CompletionFunc& completion) jobs.Push(PlayVideo("vol42a.anm", vol42a, framespeed_14)); jobs.Push(PlayVideo("vol43a.anm", vol43a, framespeed_10)); RunScreenJob(jobs, completion, SJ_SKIPALL); +#endif } +#if 0 //--------------------------------------------------------------------------- // // @@ -1189,10 +1205,11 @@ void loadscreen_d(MapRecord *rec, CompletionFunc func) jobs[0] = Create(rec); RunScreenJob(jobs, func); } +#endif void PrintPaused_d() { - BigText(160, 100, GStrings("Game Paused")); + //BigText(160, 100, GStrings("Game Paused")); } diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index 01602ee37..ae75c9920 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -123,6 +123,7 @@ void InitFonts_r() } +#if 0 //========================================================================== // // wrappers around DrawText to allow easier reuse of the old code. @@ -153,6 +154,7 @@ static void MiniText(double x, double y, const char* t, int shade, int align = - x -= SmallFont2->StringWidth(t) * (align == 0 ? 0.5 : 1); DrawText(twod, SmallFont2, CR_UNDEFINED, x, y, t, DTA_FullscreenScale, FSMode_Fit640x400, DTA_TranslationIndex, TRANSLATION(Translation_Remap, trans), DTA_Color, shadeToLight(shade), TAG_DONE); } +#endif //--------------------------------------------------------------------------- // @@ -162,6 +164,7 @@ static void MiniText(double x, double y, const char* t, int shade, int align = - void Logo_r(const CompletionFunc& completion) { +#if 0 Mus_Stop(); FX_StopAllSounds(); // JBF 20031228 @@ -203,8 +206,10 @@ void Logo_r(const CompletionFunc& completion) jobs.Push(PlayVideo("redint.mve")); } RunScreenJob(jobs, completion, SJ_BLOCKUI); +#endif } +#if 0 //--------------------------------------------------------------------------- // // @@ -246,7 +251,9 @@ static void bonussequence_r(int num, TArray& jobs) break; } } +#endif +#if 0 //--------------------------------------------------------------------------- // // @@ -583,6 +590,7 @@ public: DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, TAG_DONE); } }; +#endif //--------------------------------------------------------------------------- // @@ -592,6 +600,7 @@ public: void dobonus_r(int bonusonly, const CompletionFunc& completion) { +#if 0 TArray jobs; FX_StopAllSounds(); @@ -627,9 +636,11 @@ void dobonus_r(int bonusonly, const CompletionFunc& completion) if (jobs.Size()) RunScreenJob(jobs, completion); else if (completion) completion(false); +#endif } +#if 0 //--------------------------------------------------------------------------- // // @@ -660,10 +671,11 @@ void loadscreen_r(MapRecord* rec, CompletionFunc func) jobs[0] = Create(rec); RunScreenJob(jobs, func); } +#endif void PrintPaused_r() { - BigText(160, 100, GStrings("Game Paused"), 0); + //BigText(160, 100, GStrings("Game Paused"), 0); } diff --git a/source/games/exhumed/src/2d.cpp b/source/games/exhumed/src/2d.cpp index b982bc7e1..66e880ca5 100644 --- a/source/games/exhumed/src/2d.cpp +++ b/source/games/exhumed/src/2d.cpp @@ -372,6 +372,7 @@ void menu_DoPlasma() DrawRel(kTile3512 + ((dword_9AB5F + 2) & 3), 270, 150); } +#if 0 //--------------------------------------------------------------------------- // // @@ -509,6 +510,7 @@ public: } } }; +#endif //--------------------------------------------------------------------------- // @@ -516,10 +518,11 @@ public: // //--------------------------------------------------------------------------- -DScreenJob *PlayMovie(const char* fileName); +//DScreenJob *PlayMovie(const char* fileName); void DoTitle(CompletionFunc completion) { +#if 0 TArray jobs; jobs.Push(Create(tileGetTexture(PublisherLogo()), DScreenJob::fadein | DScreenJob::fadeout)); @@ -528,9 +531,10 @@ void DoTitle(CompletionFunc completion) jobs.Push(Create()); RunScreenJob(jobs, completion, SJ_BLOCKUI); - +#endif } +#if 0 //--------------------------------------------------------------------------- // // pre-level map display @@ -814,7 +818,7 @@ public: } }; - void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray &jobs) +void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray &jobs) { if (nLevel > kMap20 || nLevelNew > kMap20) // max single player levels { @@ -831,6 +835,8 @@ public: jobs.Push(Create(nLevel-1, nLevelNew-1, nLevelBest-1)); } +#endif + //--------------------------------------------------------------------------- // // text overlay @@ -961,6 +967,7 @@ void uploadCinemaPalettes() } } +#if 0 //--------------------------------------------------------------------------- // // cinema @@ -1336,6 +1343,7 @@ public: } } }; +#endif //--------------------------------------------------------------------------- // @@ -1345,6 +1353,7 @@ public: void DoGameOverScene(bool finallevel) { +#if 0 TArray jobs(1, true); if (finallevel) @@ -1358,8 +1367,10 @@ void DoGameOverScene(bool finallevel) jobs[0] = Create(tileGetTexture(kTile3591), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff, TRANSLATION(Translation_BasePalettes, 16)); } RunScreenJob(jobs, [](bool) { gameaction = ga_mainmenu; }); +#endif } +#if 0 void DoAfterCinemaScene(int nLevel, TArray& jobs) { @@ -1378,4 +1389,92 @@ void DoBeforeCinemaScene(int nLevel, TArray& jobs) else if (nLevel == 11) jobs.Push(Create(CINEMA_BEFORE_LEVEL_11, 11)); } +void showmap(short nLevel, short nLevelNew, short nLevelBest, TArray& jobs) +{ + if (nLevelNew == 5 && !(nCinemaSeen & 1)) { + nCinemaSeen |= 1; + DoBeforeCinemaScene(5, jobs); + } + + menu_DrawTheMap(nLevel, nLevelNew, nLevelBest, jobs); + + if (nLevelNew == 11 && !(nCinemaSeen & 2)) { + DoBeforeCinemaScene(11, jobs); + } +} +#endif + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void Intermission(MapRecord* from_map, MapRecord* to_map) +{ +#if 0 + TArray jobs; + + if (from_map) StopAllSounds(); + bCamera = false; + automapMode = am_off; + + if (to_map) + { + if (to_map->levelNumber != 0) + nBestLevel = to_map->levelNumber - 1; + + STAT_Update(false); + if (to_map->levelNumber == kMap20) + nPlayerLives[0] = 0; + + if (to_map->levelNumber == 0) // skip all intermission stuff when going to the training map. + { + gameaction = ga_nextlevel; + return; + } + else + { + DoAfterCinemaScene(to_map->levelNumber - 1, jobs); + } + if (to_map->levelNumber > -1 && to_map->levelNumber < kMap20) + { + // start a new game at the given level + if (!nNetPlayerCount && to_map->levelNumber > 0) + { + showmap(from_map ? from_map->levelNumber : -1, to_map->levelNumber, nBestLevel, jobs); + } + else + jobs.Push(Create(1)); // we need something in here even in the multiplayer case. + } + } + else + { + DoAfterCinemaScene(20, jobs); + STAT_Update(true); + } + + + if (jobs.Size() > 0) + { + RunScreenJob(jobs, [=](bool) + { + if (!to_map) gameaction = ga_startup; // this was the end of the game + else + { + if (to_map->levelNumber != selectedlevelnew) + { + // User can switch destination on the scrolling map. + g_nextmap = FindMapByLevelNum(selectedlevelnew); + STAT_Cancel(); + } + gameaction = ga_nextlevel; + + } + }); + } +#endif +} + + END_PS_NS diff --git a/source/games/exhumed/src/exhumed.h b/source/games/exhumed/src/exhumed.h index 81ae0916d..6f424fbdc 100644 --- a/source/games/exhumed/src/exhumed.h +++ b/source/games/exhumed/src/exhumed.h @@ -54,8 +54,6 @@ void SetHiRes(); void BlackOut(); void DoGameOverScene(bool finallevel); -void DoAfterCinemaScene(int nLevel, TArray &jobs); -void DoBeforeCinemaScene(int nLevel, TArray& jobs); int Query(short n, short l, ...); @@ -88,7 +86,6 @@ void InitNewGame(); int showmap(short nLevel, short nLevelNew, short nLevelBest); void menu_DoPlasma(); -void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray& jobs); void DoEnergyTile(); void InitEnergyTile(); diff --git a/source/games/exhumed/src/gameloop.cpp b/source/games/exhumed/src/gameloop.cpp index dd3ef421e..c741d2a5e 100644 --- a/source/games/exhumed/src/gameloop.cpp +++ b/source/games/exhumed/src/gameloop.cpp @@ -62,19 +62,6 @@ void DrawClock(); double calc_smoothratio(); void DoTitle(CompletionFunc completion); -static void showmap(short nLevel, short nLevelNew, short nLevelBest, TArray &jobs) -{ - if (nLevelNew == 5 && !(nCinemaSeen & 1)) { - nCinemaSeen |= 1; - DoBeforeCinemaScene(5, jobs); - } - - menu_DrawTheMap(nLevel, nLevelNew, nLevelBest, jobs); - - if (nLevelNew == 11 && !(nCinemaSeen & 2)) { - DoBeforeCinemaScene(11, jobs); - } -} void GameInterface::Render() @@ -127,77 +114,6 @@ void GameInterface::DrawBackground() DrawRel(kTile3512 + ((dword_9AB5F + 2) & 3), 270, 150, 0); } -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static void Intermission(MapRecord *from_map, MapRecord *to_map) -{ - TArray jobs; - - if (from_map) StopAllSounds(); - bCamera = false; - automapMode = am_off; - - if (to_map) - { - if (to_map->levelNumber != 0) - nBestLevel = to_map->levelNumber - 1; - - STAT_Update(false); - if (to_map->levelNumber == kMap20) - nPlayerLives[0] = 0; - - if (to_map->levelNumber == 0) // skip all intermission stuff when going to the training map. - { - gameaction = ga_nextlevel; - return; - } - else - { - DoAfterCinemaScene(to_map->levelNumber - 1, jobs); - } - if (to_map->levelNumber > -1 && to_map->levelNumber < kMap20) - { - // start a new game at the given level - if (!nNetPlayerCount && to_map->levelNumber > 0) - { - showmap(from_map ? from_map->levelNumber : -1, to_map->levelNumber, nBestLevel, jobs); - } - else - jobs.Push(Create(1)); // we need something in here even in the multiplayer case. - } - } - else - { - DoAfterCinemaScene(20, jobs); - STAT_Update(true); - } - - - if (jobs.Size() > 0) - { - RunScreenJob(jobs, [=](bool) - { - if (!to_map) gameaction = ga_startup; // this was the end of the game - else - { - if (to_map->levelNumber != selectedlevelnew) - { - // User can switch destination on the scrolling map. - g_nextmap = FindMapByLevelNum(selectedlevelnew); - STAT_Cancel(); - } - gameaction = ga_nextlevel; - - } - }); - } - -} - void GameInterface::NextLevel(MapRecord *map, int skill) { InitLevel(map->levelNumber); @@ -212,6 +128,8 @@ void GameInterface::NextLevel(MapRecord *map, int skill) } +void Intermission(MapRecord* from_map, MapRecord* to_map); + void GameInterface::NewGame(MapRecord *map, int skill, bool frommenu) { // start a new game on the given level diff --git a/source/games/exhumed/src/movie.cpp b/source/games/exhumed/src/movie.cpp index cb632cc05..85399eb3e 100644 --- a/source/games/exhumed/src/movie.cpp +++ b/source/games/exhumed/src/movie.cpp @@ -194,6 +194,7 @@ public: } }; +#if 0 //--------------------------------------------------------------------------- // // @@ -288,5 +289,6 @@ DScreenJob* PlayMovie(const char* fileName) fp.Seek(0, FileReader::SeekSet); return Create(fp); } +#endif END_PS_NS diff --git a/source/games/sw/src/2d.cpp b/source/games/sw/src/2d.cpp index eca216415..372d43383 100644 --- a/source/games/sw/src/2d.cpp +++ b/source/games/sw/src/2d.cpp @@ -39,6 +39,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS +#if 0 //--------------------------------------------------------------------------- // // @@ -64,6 +65,7 @@ public: DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); } }; +#endif //--------------------------------------------------------------------------- @@ -74,6 +76,7 @@ public: void Logo(const CompletionFunc& completion) { +#if 0 StopSound(); PlaySong(nullptr, ThemeSongs[0], ThemeTrack[0]); @@ -94,8 +97,11 @@ void Logo(const CompletionFunc& completion) RunScreenJob(jobs, completion, SJ_BLOCKUI); } else completion(false); +#endif } +#if 0 + //--------------------------------------------------------------------------- // // @@ -225,7 +231,7 @@ class DSWCreditsScreen : public DSkippableScreenJob DrawTexture(twod, tileGetTexture(curpic, true), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); } }; - +#endif //--------------------------------------------------------------------------- // // Summary screen @@ -340,6 +346,7 @@ static STATE * s_BonusAnim[] = s_BonusGrab }; +#if 0 class DSWLevelSummaryScreen : public DScreenJob { int minutes, seconds, second_tics; @@ -462,6 +469,7 @@ private: } }; +#endif //--------------------------------------------------------------------------- // @@ -483,7 +491,7 @@ enum STAT_TABLE_XOFF = SM_SIZ(6) }; - +#if 0 class DSWMultiSummaryScreen : public DSkippableScreenJob { short death_total[MAX_SW_PLAYERS_REG]{}; @@ -596,6 +604,7 @@ class DSWMultiSummaryScreen : public DSkippableScreenJob } } }; +#endif //--------------------------------------------------------------------------- // @@ -605,6 +614,7 @@ class DSWMultiSummaryScreen : public DSkippableScreenJob void StatScreen(int FinishAnim, CompletionFunc completion) { +#if 0 TArray jobs; if (FinishAnim) @@ -624,6 +634,7 @@ void StatScreen(int FinishAnim, CompletionFunc completion) jobs.Push(Create()); } RunScreenJob(jobs, completion); +#endif } //--------------------------------------------------------------------------- @@ -634,6 +645,7 @@ void StatScreen(int FinishAnim, CompletionFunc completion) void SybexScreen(CompletionFunc completion) { +#if 0 if (!SW_SHAREWARE || CommEnabled) completion(false); else { @@ -641,8 +653,10 @@ void SybexScreen(CompletionFunc completion) jobs[0] = Create(tileGetTexture(5261), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff); RunScreenJob(jobs, completion, SJ_BLOCKUI); } +#endif } +#if 0 //--------------------------------------------------------------------------- // // @@ -673,5 +687,6 @@ void loadscreen(MapRecord* rec, CompletionFunc func) jobs[0] = Create(rec); RunScreenJob(jobs, func); } +#endif END_SW_NS diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index 0fef04818..5749ff38c 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -406,6 +406,7 @@ struct Screen native native static double, double, double, double GetFullscreenRect(double vwidth, double vheight, int fsmode); native static Vector2 SetOffset(double x, double y); native static void ClearScreen(color col = 0); + native static void SetScreenFade(double factor); } struct Font native diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 8a8d0ed0c..77595f5e9 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -261,7 +261,7 @@ class E2EndScreen : ImageScreen { void Init() { - Super.Init("E2ENDSCREEN", fadein | fadeout | stopsound, 0x7fffffff, 0); + Super.InitNamed("E2ENDSCREEN", fadein | fadeout | stopsound, 0x7fffffff, 0); } override void Start() @@ -283,8 +283,7 @@ class Episode3End : ImageScreen void Init() { - Super.Init("", fadein|fadeout, 0x7fffffff); - texid = TexMan.CheckForTexture("radlogo.anm", TexMan.Type_Any, TexMan.TryAny | TexMan.ForceLookup); // must override with 'forcelookup'. + Super.InitNamed("radlogo.anm", fadein|fadeout, 0x7fffffff); soundstate = 0; finishtime = 0; } @@ -402,7 +401,7 @@ class Episode5End : ImageScreen { void Init() { - Super.Init("FIREFLYGROWEFFECT", fadein|fadeout|stopsound); + Super.InitNamed("FIREFLYGROWEFFECT", fadein|fadeout|stopsound); } override void OnTick() diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index 25ce0cf7f..9ca6c734f 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -29,15 +29,16 @@ enum EGameType struct UserConfigStruct native { - native bool nomonsters; - native bool nosound; - native bool nologo; + native readonly bool nomonsters; + native readonly bool nosound; + native readonly bool nologo; } extend struct _ { native @UserConfigStruct userConfig; - native MapRecord currentLevel; + native readonly MapRecord currentLevel; + native readonly int paused; } struct MapRecord native @@ -91,8 +92,10 @@ struct Raze native static Color shadeToLight(int shade); native static void StopAllSounds(); native static bool SoundEnabled(); + native static void StopMusic(); native static bool MusicEnabled(); native static String PlayerName(int i); + native static double GetTimeFrac(); static bool specialKeyEvent(InputEvent ev) { diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 696215310..1de285dd5 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -1,13 +1,13 @@ -class ScreenJob native +class ScreenJob : Object { - native int flags; - native float fadetime; // in milliseconds - native int fadestate; + int flags; + float fadetime; // in milliseconds + int fadestate; - native int ticks; - native int jobstate; - native bool pausable; + int ticks; + int jobstate; + bool pausable; enum EJobState { @@ -26,17 +26,41 @@ class ScreenJob native stopsound = 8, }; - native void Init(int flags = 0, float fadet = 250.f); - native virtual bool ProcessInput(); - native virtual void Start(); - native virtual bool OnEvent(InputEvent evt); - native virtual void OnTick(); - native virtual void Draw(double smoothratio); + void Init(int flags = 0, float fadet = 250.f) + { + flags = fadet; + fadetime = fadet; + jobstate = running; + pausable = true; + } + + virtual bool ProcessInput() + { + return false; + } + + virtual void Start() {} + virtual bool OnEvent(InputEvent evt) { return false; } + virtual void OnTick() {} + virtual void Draw(double smoothratio) {} virtual void OnSkip() {} - //native int DrawFrame(double smoothratio); - //native int GetFadeState(); - //native override void OnDestroy(); + int DrawFrame(double smoothratio) + { + if (jobstate != running) smoothratio = 1; // this is necessary because the ticker won't be incremented anymore to avoid having a negative time span. + Draw(smoothratio); + if (jobstate == skipped) return -1; + if (jobstate == finished) return 0; + return 1; + } + + int GetFadeState() { return fadestate; } + override void OnDestroy() + { + if (flags & stopmusic) Raze.StopMusic(); + if (flags & stopsound) Raze.StopAllSounds(); + } + } //--------------------------------------------------------------------------- @@ -45,10 +69,22 @@ class ScreenJob native // //--------------------------------------------------------------------------- -class SkippableScreenJob : ScreenJob native +class SkippableScreenJob : ScreenJob { - native void Init(int flags = 0, float fadet = 250.f); - //native override bool OnEvent(InputEvent evt); + void Init(int flags = 0, float fadet = 250.f) + { + Super.Init(flags, fadet); + } + + override bool OnEvent(InputEvent evt) + { + if (evt.type == InputEvent.Type_KeyDown && !Raze.specialKeyEvent(evt)) + { + jobstate = skipped; + OnSkip(); + } + return true; + } } //--------------------------------------------------------------------------- @@ -57,14 +93,32 @@ class SkippableScreenJob : ScreenJob native // //--------------------------------------------------------------------------- -class BlackScreen : ScreenJob native +class BlackScreen : ScreenJob { - native int wait; - native bool cleared; + int wait; + bool cleared; - native void Init(int w, int flags = 0); - //override void OnTick(); - //override void Draw(double smooth); + void Init(int w, int flags = 0) + { + Super.Init(flags & ~(fadein|fadeout)); + wait = w; + cleared = false; + } + + override void OnTick() + { + if (cleared) + { + int span = ticks * 1000 / GameTicRate; + if (span > wait) jobstate = finished; + } + } + + override void Draw(double smooth) + { + cleared = true; + Screen.ClearScreen(); + } } //--------------------------------------------------------------------------- @@ -73,17 +127,46 @@ class BlackScreen : ScreenJob native // //--------------------------------------------------------------------------- -class ImageScreen : SkippableScreenJob native +class ImageScreen : SkippableScreenJob { - native int tilenum; - native int trans; - native int waittime; // in ms. - native bool cleared; - native TextureID texid; + int tilenum; + int trans; + int waittime; // in ms. + bool cleared; + TextureID texid; - native void Init(String tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0); - //override void OnTick(); - //override void Draw(double smooth); + void Init(TextureID tile, int fade = fadein | fadeout, int wait = 3000, int translation = 0) + { + Super.Init(fade); + waittime = wait; + texid = tile; + trans = translation; + cleared = false; + } + + void InitNamed(String tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0) + { + Super.Init(fade); + waittime = wait; + texid = TexMan.CheckForTexture(tex, TexMan.Type_Any, TexMan.TryAny | TexMan.ForceLookup); + trans = translation; + cleared = false; + } + override void OnTick() + { + if (cleared) + { + int span = ticks * 1000 / GameTicRate; + if (span > waittime) jobstate = finished; + } + } + + override void Draw(double smooth) + { + Screen.ClearScreen(); + if (texid.IsValid()) Screen.DrawTexture(texid, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, DTA_TranslationIndex, trans); + cleared = true; + } } //--------------------------------------------------------------------------- @@ -119,3 +202,284 @@ class SummaryScreenBase : ScreenJob } } + +//--------------------------------------------------------------------------- +// +// internal polymorphic movie player object +// +//--------------------------------------------------------------------------- + +struct AnmControl // ANM has no internal timing and sound info. Ugh... +{ + Array sounds; + int frameticks[3]; // first and last frame have their own durations. +} + +struct MoviePlayer native +{ + native static MoviePlayer OpenMovie(String filename, AnmControl ans, bool nosoundcutoff, out String error); + native void Start(); + native bool Frame(double clock); + native bool Destroy(); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class MoviePlayerJob : SkippableScreenJob +{ + MoviePlayer player; + bool started; + + void Init(MoviePlayer mp) + { + player = mp; + pausable = false; + } + + override void Draw(double smoothratio) + { + if (!player) + { + jobstate = stopped; + return; + } + if (!started) + { + started = true; + player.Start(); + } + double clock = (ticks + smoothratio) * 1000000000. / GameTicRate; + if (jobstate == running && !player.Frame(clock)) + { + jobstate = finished; + } + } + + override void OnDestroy() + { + if (player) + { + player.Destroy(); + } + player = null; + } +} + + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class ScreenJobRunner : Object +{ + enum ERunState + { + State_Clear, + State_Run, + State_Fadeout, + } + Array jobs; + //CompletionFunc completion; + int index; + float screenfade; + bool clearbefore; + bool skipall; + bool advance; + int actionState; + int terminateState; + int fadeticks; + int last_paused_tic; + + void Init(bool clearbefore_ = true, bool skipall_ = false) + { + clearbefore = clearbefore_; + skipall = skipall_; + index = -1; + fadeticks = 0; + last_paused_tic = -1; + } + + override void OnDestroy() + { + DeleteJobs(); + } + + void DeleteJobs() + { + // Free all allocated resources now. + for (int i = 0; i < jobs.Size(); i++) + { + if (jobs[i]) jobs[i].Destroy(); + } + jobs.Clear(); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + void AdvanceJob(bool skip) + { + if (index == jobs.Size()-1) + { + index++; + return; // we need to retain the last element until the runner is done. + } + + if (index >= 0) jobs[index].Destroy(); + index++; + while (index < jobs.Size() && (jobs[index] == null || (skip && skipall))) + { + if (jobs[index] != null) jobs[index].Destroy(); + index++; + } + actionState = clearbefore ? State_Clear : State_Run; + if (index < jobs.Size()) + { + jobs[index].fadestate = !paused && jobs[index].flags & ScreenJob.fadein? ScreenJob.fadein : ScreenJob.visible; + jobs[index].Start(); + } + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + virtual int DisplayFrame(double smoothratio) + { + int x = index >= jobs.Size()? jobs.Size()-1 : index; + let job = jobs[x]; + bool processed = job.ProcessInput(); + + if (job.fadestate == ScreenJob.fadein) + { + double ms = (job.ticks + smoothratio) * 1000 / GameTicRate / job.fadetime; + double screenfade = clamp(ms, 0., 1.); + Screen.SetScreenFade(screenfade); + if (screenfade == 1.) job.fadestate = ScreenJob.visible; + } + int state = job.DrawFrame(smoothratio); + Screen.SetScreenFade(1.); + return state; + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + virtual int FadeoutFrame(double smoothratio) + { + int x = index >= jobs.Size()? jobs.Size()-1 : index; + let job = jobs[x]; + double ms = (fadeticks + smoothratio) * 1000 / GameTicRate / job.fadetime; + float screenfade = 1. - clamp(ms, 0., 1.); + Screen.SetScreenFade(screenfade); + job.DrawFrame(1.); + Screen.SetScreenFade(1.); + return (screenfade > 0.); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + virtual bool OnEvent(InputEvent ev) + { + if (paused || index >= jobs.Size()) return false; + if (jobs[index].jobstate != ScreenJob.running) return false; + return jobs[index].OnEvent(ev); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + virtual bool OnTick() + { + if (paused) return false; + if (advance) + { + advance = false; + AdvanceJob(terminateState < 0); + if (index >= jobs.Size()) + { + return true; + } + } + if (jobs[index].jobstate == ScreenJob.running) + { + jobs[index].ticks++; + jobs[index].OnTick(); + } + else if (jobs[index].jobstate == ScreenJob.stopping) + { + fadeticks++; + } + return false; + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + virtual bool RunFrame(double smoothratio) + { + // ensure that we won't go back in time if the menu is dismissed without advancing our ticker + bool menuon = paused; + if (menuon) last_paused_tic = jobs[index].ticks; + else if (last_paused_tic == jobs[index].ticks) menuon = true; + if (menuon || index >= jobs.Size()) smoothratio = 1.; + + if (actionState == State_Clear) + { + actionState = State_Run; + Screen.ClearScreen(); + } + else if (actionState == State_Run) + { + terminateState = DisplayFrame(smoothratio); + if (terminateState < 1 && index < jobs.Size()) + { + if (jobs[index].flags & ScreenJob.fadeout) + { + jobs[index].fadestate = ScreenJob.fadeout; + jobs[index].jobstate = ScreenJob.stopping; + actionState = State_Fadeout; + fadeticks = 0; + } + else + { + advance = true; + } + } + } + else if (actionState == State_Fadeout) + { + int ended = FadeoutFrame(smoothratio); + if (ended < 1 && index < jobs.Size()) + { + jobs[index].jobstate = ScreenJob.stopped; + advance = true; + } + } + return true; + } +} From 66799d9a6dce2497787776082253e9a2008fe94c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 25 Apr 2021 21:52:58 +0200 Subject: [PATCH 18/86] - more screen job setup work. * interface for movie player done. * first cutscene definition done. * all converted classes removed from C++ code. --- source/core/movie/movieplayer.cpp | 170 ++-- source/core/screenjob.h | 6 - source/games/duke/src/2d_d.cpp | 794 +----------------- source/games/duke/src/2d_r.cpp | 373 +------- .../static/zscript/games/duke/ui/cutscenes.zs | 58 ++ .../static/zscript/games/duke/ui/screens.zs | 65 +- wadsrc/static/zscript/screenjob.zs | 61 +- 7 files changed, 230 insertions(+), 1297 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/ui/cutscenes.zs diff --git a/source/core/movie/movieplayer.cpp b/source/core/movie/movieplayer.cpp index 7d6c690b5..5ab569472 100644 --- a/source/core/movie/movieplayer.cpp +++ b/source/core/movie/movieplayer.cpp @@ -54,6 +54,14 @@ class MoviePlayer { +protected: + enum EMovieFlags + { + NOSOUNDCUTOFF = 1, + FIXEDVIEWPORT = 2, // Forces fixed 640x480 screen size like for Blood's intros. + }; + + int flags; public: virtual void Start() {} virtual bool Frame(uint64_t clock) = 0; @@ -77,16 +85,16 @@ class AnmPlayer : public MoviePlayer int frametime = 0; int nextframetime = 0; AnimTextures animtex; - const AnimSound* animSnd; + const TArray animSnd; const int* frameTicks; - bool nostopsound; public: bool isvalid() { return numframes > 0; } - AnmPlayer(FileReader& fr, const AnimSound* ans, const int *frameticks, bool nosoundcutoff) - : animSnd(ans), frameTicks(frameticks), nostopsound(nosoundcutoff) + AnmPlayer(FileReader& fr, TArray& ans, const int *frameticks, int flags_) + : animSnd(std::move(ans)), frameTicks(frameticks) { + flags = flags_; buffer = fr.ReadPadded(1); fr.Close(); @@ -130,11 +138,12 @@ public: } nextframetime += delay; - if (animSnd) for (int i = 0; animSnd[i].framenum >= 0; i++) + bool nostopsound = (flags & NOSOUNDCUTOFF); + for (unsigned i = 0; i < animSnd.Size(); i+=2) { - if (animSnd[i].framenum == curframe) + if (animSnd[i] == curframe) { - int sound = animSnd[i].soundnum; + int sound = animSnd[i+1]; if (sound == -1) soundEngine->StopAllChannels(); else if (SoundEnabled()) @@ -148,6 +157,7 @@ public: void Stop() override { + bool nostopsound = (flags & NOSOUNDCUTOFF); if (!nostopsound) soundEngine->StopAllChannels(); } @@ -210,7 +220,7 @@ class VpxPlayer : public MoviePlayer bool failed = false; FileReader fr; AnimTextures animtex; - const AnimSound* animSnd; + const TArray animSnd; unsigned width, height; TArray Pic; @@ -235,10 +245,9 @@ public: public: bool isvalid() { return !failed; } - VpxPlayer(FileReader& fr_, const AnimSound* animSnd_, int origframedelay, FString& error) + VpxPlayer(FileReader& fr_, TArray& animSnd_, int flags, int origframedelay, FString& error) : animSnd(std::move(animSnd_)) { fr = std::move(fr_); - animSnd = animSnd_; if (!ReadIVFHeader(origframedelay)) { @@ -434,18 +443,22 @@ public: framenum++; if (framenum >= numframes) stop = true; + bool nostopsound = (flags & NOSOUNDCUTOFF); int soundframe = convdenom ? Scale(framenum, convnumer, convdenom) : framenum; if (soundframe > lastsoundframe) { - if (animSnd && soundtrack == -1) for (int i = 0; animSnd[i].framenum >= 0; i++) + if (soundtrack == -1) { - if (animSnd[i].framenum == soundframe) + for (unsigned i = 0; i < animSnd.Size(); i += 2) { - int sound = animSnd[i].soundnum; - if (sound == -1) - soundEngine->StopAllChannels(); - else if (SoundEnabled()) - soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_AUTO, CHANF_NONE, sound, 1.f, ATTN_NONE); + if (animSnd[i] == soundframe) + { + int sound = animSnd[i + 1]; + if (sound == -1) + soundEngine->StopAllChannels(); + else if (SoundEnabled()) + soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_AUTO, nostopsound ? CHANF_UI : CHANF_NONE, sound, 1.f, ATTN_NONE); + } } } lastsoundframe = soundframe; @@ -458,6 +471,8 @@ public: void Stop() { Mus_Stop(); + bool nostopsound = (flags & NOSOUNDCUTOFF); + if (!nostopsound) soundEngine->StopAllChannels(); } ~VpxPlayer() @@ -499,9 +514,10 @@ class SmkPlayer : public MoviePlayer bool fullscreenScale; uint64_t nFrameNs; int nFrame = 0; - const AnimSound* animSnd; + const TArray animSnd; FString filename; SoundStream* stream = nullptr; + bool hassound = false; public: bool isvalid() { return hSMK.isValid; } @@ -535,7 +551,7 @@ public: } - SmkPlayer(const char *fn, const AnimSound* ans, bool fixedviewport) + SmkPlayer(const char *fn, TArray& ans, int flags) : animSnd(std::move(ans)) { hSMK = Smacker_Open(fn); if (!hSMK.isValid) @@ -548,9 +564,8 @@ public: nFrameNs = 1'000'000'000 / nFrameRate; nFrames = Smacker_GetNumFrames(hSMK); Smacker_GetPalette(hSMK, palette); - fullscreenScale = (!fixedviewport || (nWidth <= 320 && nHeight <= 200) || nWidth >= 640 || nHeight >= 480); + fullscreenScale = (!(flags & FIXEDVIEWPORT) || (nWidth <= 320 && nHeight <= 200) || nWidth >= 640 || nHeight >= 480); - bool hassound = false; numAudioTracks = Smacker_GetNumAudioTracks(hSMK); if (numAudioTracks) { @@ -563,14 +578,12 @@ public: auto read = Smacker_GetAudioData(hSMK, 0, (int16_t*)audioBuffer.Data()); if (adata.inf.bitsPerSample == 8) copy8bitSamples(read); else copy16bitSamples(read); - animSnd = nullptr; hassound = true; } } if (!hassound) { adata.inf = {}; - animSnd = ans; } } @@ -625,15 +638,16 @@ public: { nFrame++; Smacker_GetNextFrame(hSMK); - if (animSnd) for (int i = 0; animSnd[i].framenum >= 0; i++) + bool nostopsound = (flags & NOSOUNDCUTOFF); + if (!hassound) for (unsigned i = 0; i < animSnd.Size(); i += 2) { - if (animSnd[i].framenum == nFrame) + if (animSnd[i] == nFrame) { - int sound = animSnd[i].soundnum; + int sound = animSnd[i + 1]; if (sound == -1) soundEngine->StopAllChannels(); else if (SoundEnabled()) - soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_AUTO, CHANF_NONE, sound, 1.f, ATTN_NONE); + soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_AUTO, nostopsound ? CHANF_UI : CHANF_NONE, sound, 1.f, ATTN_NONE); } } } @@ -641,78 +655,31 @@ public: return nFrame < nFrames; } + void Stop() override + { + if (stream) S_StopCustomStream(stream); + bool nostopsound = (flags & NOSOUNDCUTOFF); + if (!nostopsound && !hassound) soundEngine->StopAllChannels(); + } + ~SmkPlayer() { Smacker_Close(hSMK); - if (stream) S_StopCustomStream(stream); - soundEngine->StopAllChannels(); animtex.Clean(); } }; -#if 0 //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- -class DMoviePlayer : public DSkippableScreenJob -{ - MoviePlayer* player; - bool started = false; - -public: - DMoviePlayer(MoviePlayer* mp) - { - player = mp; - pausable = false; - } - - - void Draw(double smoothratio) override - { - if (!player) - { - state = stopped; - return; - } - if (!started) - { - started = true; - player->Start(); - } - uint64_t clock = (ticks + smoothratio) * 1'000'000'000. / GameTicRate; - if (state == running && !player->Frame(clock)) - { - state = finished; - } - } - - void OnDestroy() override - { - if (player) - { - player->Stop(); - delete player; - } - player = nullptr; - } -}; -#endif - -#if 0 -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -MoviePlayer* OpenMovie(const char* filename, const AnimSound* ans, const int* frameticks, bool nosoundcutoff, FString& error) +MoviePlayer* OpenMovie(const char* filename, TArray& ans, const int* frameticks, int flags, FString& error) { FileReader fr; // first try as .ivf - but only if sounds are provided - the decoder is video only. - if (ans) + if (ans.Size()) { auto fn = StripExtension(filename); DefaultExtension(fn, ".ivf"); @@ -742,7 +709,7 @@ MoviePlayer* OpenMovie(const char* filename, const AnimSound* ans, const int* fr if (!memcmp(id, "LPF ", 4)) { - auto anm = new AnmPlayer(fr, ans, frameticks, nosoundcutoff); + auto anm = new AnmPlayer(fr, ans, frameticks, flags); if (!anm->isvalid()) { error.Format("%s: invalid ANM file.\n", filename); @@ -754,7 +721,7 @@ MoviePlayer* OpenMovie(const char* filename, const AnimSound* ans, const int* fr else if (!memcmp(id, "SMK2", 4)) { fr.Close(); - auto anm = new SmkPlayer(filename, ans, isBlood()); // Fixme: Handle Blood's video scaling behavior more intelligently. + auto anm = new SmkPlayer(filename, ans, flags); if (!anm->isvalid()) { error.Format("%s: invalid SMK file.\n", filename); @@ -775,7 +742,7 @@ MoviePlayer* OpenMovie(const char* filename, const AnimSound* ans, const int* fr } else if (!memcmp(id, "DKIF\0\0 \0VP80", 12)) { - auto anm = new VpxPlayer(fr, ans, frameticks ? frameticks[1] : 0, error); + auto anm = new VpxPlayer(fr, ans, frameticks ? frameticks[1] : 0, flags, error); if (!anm->isvalid()) { delete anm; @@ -798,29 +765,26 @@ MoviePlayer* OpenMovie(const char* filename, const AnimSound* ans, const int* fr // //--------------------------------------------------------------------------- -DScreenJob* PlayVideo(const char* filename, const AnimSound* ans, const int* frameticks, bool nosoundcutoff) +DEFINE_ACTION_FUNCTION(_MoviePlayer, Create) { - if (!filename) - { - return Create(1); - } + PARAM_PROLOGUE; + PARAM_STRING(filename); + PARAM_POINTER(sndinf, TArray); + PARAM_INT(flags); + PARAM_INT(frametime); + PARAM_INT(firstframetime); + PARAM_INT(lastframetime); + FString error; - auto movie = OpenMovie(filename, ans, frameticks, nosoundcutoff, error); + if (firstframetime == -1) firstframetime = frametime; + if (lastframetime == -1) lastframetime = frametime; + int frametimes[] = { firstframetime, frametime, lastframetime }; + auto movie = OpenMovie(filename, *sndinf, frametime == -1? nullptr : frametimes, flags, error); if (!movie) { Printf(TEXTCOLOR_YELLOW, "%s", error.GetChars()); - return Create(1); } - return Create(movie); -} - -#endif - -DEFINE_ACTION_FUNCTION(_MoviePlayer, OpenMovie) -{ - PARAM_PROLOGUE; - // todo - return 0; + ACTION_RETURN_POINTER(movie); } DEFINE_ACTION_FUNCTION(_MoviePlayer, Start) diff --git a/source/core/screenjob.h b/source/core/screenjob.h index bd3dbe5e5..2f5d2a6d1 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -198,12 +198,6 @@ bool ScreenJobResponder(event_t* ev); void ScreenJobTick(); bool ScreenJobDraw(); -struct AnimSound -{ - int framenum; - int soundnum; -}; - #if 0 DScreenJob *PlayVideo(const char *filename, const AnimSound *ans = nullptr, const int *frameticks = nullptr, bool nosoundstop = false); #endif \ No newline at end of file diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index 274b3452c..407459072 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -131,7 +131,6 @@ void InitFonts_d() } -#if 0 //========================================================================== // // wrappers around DrawText to allow easier reuse of the old code. @@ -146,155 +145,6 @@ static void BigText(double x, double y, const char* text, int align = -1, double DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Alpha, alpha, TAG_DONE); } -static void GameText(double x, double y, const char* t, int shade, int align = -1, int trans = 0) -{ - if (align != -1) - x -= SmallFont->StringWidth(t) * (align == 0 ? 0.5 : 1); - DrawText(twod, SmallFont, CR_UNDEFINED, x, y + 2, t, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, TRANSLATION(Translation_Remap, trans), DTA_Color, shadeToLight(shade), TAG_DONE); -} - -static void MiniText(double x, double y, const char* t, int shade, int align = -1, int trans = 0) -{ - if (align != -1) - x -= SmallFont2->StringWidth(t) * (align == 0 ? 0.5 : 1); - DrawText(twod, SmallFont2, CR_UNDEFINED, x, y, t, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, TRANSLATION(Translation_Remap, trans), DTA_Color, shadeToLight(shade), TAG_DONE); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DDRealmsScreen : public DSkippableScreenJob -{ -public: - DDRealmsScreen() : DSkippableScreenJob(fadein | fadeout) {} - - void Start() override - { - S_PlaySpecialMusic(MUS_INTRO); - } - - void OnTick() override - { - if (ticks >= 7 * GameTicRate) state = finished; - } - - void Draw(double smoothratio) override - { - const auto tex = tileGetTexture(DREALMS, true); - int translation = tex->GetTexture()->GetImage()->UseGamePalette() ? TRANSLATION(Translation_BasePalettes, DREALMSPAL) : 0; - - twod->ClearScreen(); - DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); - } -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DTitleScreen : public DSkippableScreenJob -{ - int soundanm = 0; - -public: - DTitleScreen() : DSkippableScreenJob(fadein | fadeout) - { - } - - void Start() override - { - if (isNam() || userConfig.nologo) S_PlaySpecialMusic(MUS_INTRO); - } - - void OnTick() override - { - int clock = ticks * 120 / GameTicRate; - if (soundanm == 0 && clock >= 120 && clock < 120 + 60) - { - soundanm = 1; - S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); - } - if (soundanm == 1 && clock > 220 && clock < (220 + 30)) - { - soundanm = 2; - S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); - } - if (soundanm == 2 && clock >= 280 && clock < 395) - { - soundanm = 3; - if (isPlutoPak()) S_PlaySound(FLY_BY, CHAN_AUTO, CHANF_UI); - } - else if (soundanm == 3 && clock >= 395) - { - soundanm = 4; - if (isPlutoPak()) S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); - } - - if (clock > (860 + 120)) - { - state = finished; - } - } - - void Draw(double smoothratio) override - { - twod->ClearScreen(); - int clock = (ticks + smoothratio) * 120 / GameTicRate; - - twod->ClearScreen(); - - // Only translate if the image depends on the global palette. - auto tex = tileGetTexture(BETASCREEN, true); - int translation = tex->GetTexture()->GetImage()->UseGamePalette() ? TRANSLATION(Translation_BasePalettes, TITLEPAL) : 0; - DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); - - - double scale = clamp(clock - 120, 0, 60) / 64.; - if (scale > 0.) - { - tex = tileGetTexture(DUKENUKEM, true); - translation = tex->GetTexture()->GetImage()->UseGamePalette() ? TRANSLATION(Translation_BasePalettes, TITLEPAL) : 0; - - DrawTexture(twod, tileGetTexture(DUKENUKEM, true), 160, 104, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_CenterOffsetRel, true, DTA_TranslationIndex, translation, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE); - } - - scale = clamp(clock - 220, 0, 30) / 32.; - if (scale > 0.) - { - tex = tileGetTexture(THREEDEE, true); - translation = tex->GetTexture()->GetImage()->UseGamePalette() ? TRANSLATION(Translation_BasePalettes, TITLEPAL) : 0; - - DrawTexture(twod, tileGetTexture(THREEDEE, true), 160, 129, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_CenterOffsetRel, true, DTA_TranslationIndex, translation, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE); - } - - if (isPlutoPak()) - { - scale = (410 - clamp(clock, 280, 395)) / 16.; - if (scale > 0. && clock > 280) - { - tex = tileGetTexture(PLUTOPAKSPRITE + 1, true); - translation = tex->GetTexture()->GetImage()->UseGamePalette() ? TRANSLATION(Translation_BasePalettes, TITLEPAL) : 0; - - DrawTexture(twod, tileGetTexture(PLUTOPAKSPRITE + 1, true), 160, 151, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_CenterOffsetRel, true, DTA_TranslationIndex, translation, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE); - } - } - } - - void OnDestroy() override - { - S_PlaySound(NITEVISION_ONOFF, CHAN_AUTO, CHANF_UI); - } -}; -#endif - //--------------------------------------------------------------------------- // // @@ -327,6 +177,7 @@ void Logo_d(const CompletionFunc &completion) #endif } + #if 0 //--------------------------------------------------------------------------- // @@ -334,282 +185,6 @@ void Logo_d(const CompletionFunc &completion) // //--------------------------------------------------------------------------- -class DEpisode1End1 : public DSkippableScreenJob -{ - int bonuscnt = 0; - int bossani = -1; - int breatheani = -1; - bool breathebg = false; - - static inline const int breathe_time[] = { 0, 30, 60, 90 }; - static inline const int breathe_time2[] = { 30, 60, 90, 120 }; - static inline const int breathe_tile[] = { VICTORY2, VICTORY3, VICTORY2, 0 }; - static const int breathe_x = 176; - static const int breathe_y = 59; - - static inline const int boss_time[] = { 0, 220, 260, 290, 320, 350, 350 }; - static inline const int boss_time2[] = { 120, 260, 290, 320, 350, 380, 380 }; - static inline const int boss_tile[] = { VICTORY4, VICTORY5, VICTORY6, VICTORY7, VICTORY8, VICTORY9, VICTORY9 }; - static const int boss_x = 86; - static const int boss_y = 59; - -public: - DEpisode1End1() : DSkippableScreenJob(fadein | fadeout) {} - - void OnTick() - { - int currentclock = ticks * 120 / GameTicRate; - - bossani = -1; - breathebg = false; - breatheani = -1; - - // boss - if (currentclock > 390 && currentclock < 780) - { - for (int t = 0, tt = 0; t < 35; t +=5, tt++) if ((currentclock % 390) > boss_time[tt] && (currentclock % 390) <= boss_time2[tt]) - { - if (t == 10 && bonuscnt == 1) - { - S_PlaySound(SHOTGUN_FIRE, CHAN_AUTO, CHANF_UI); - S_PlaySound(SQUISHED, CHAN_AUTO, CHANF_UI); - bonuscnt++; - } - bossani = tt; - } - } - - // Breathe - if (currentclock < 450 || currentclock >= 750) - { - if (currentclock >= 750) - { - breathebg = true; - if (currentclock >= 750 && bonuscnt == 2) - { - S_PlaySound(DUKETALKTOBOSS, CHAN_AUTO, CHANF_UI); - bonuscnt++; - } - } - for (int t = 0, tt = 0; t < 20; t += 5, tt++) - if (breathe_tile[tt] && (currentclock % 120) > breathe_time[tt] && (currentclock % 120) <= breathe_time2[tt]) - { - if (t == 5 && bonuscnt == 0) - { - S_PlaySound(BOSSTALKTODUKE, CHAN_AUTO, CHANF_UI); - bonuscnt++; - } - breatheani = tt; - } - } - - } - - void Draw(double) override - { - auto translation = TRANSLATION(Translation_BasePalettes, ENDINGPAL); - - twod->ClearScreen(); - DrawTexture(twod, tileGetTexture(VICTORY1, true), 0, 50, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal, DTA_TopLeft, true, TAG_DONE); - - if (bossani != -1) - { - DrawTexture(twod, tileGetTexture(boss_tile[bossani], true), boss_x, boss_y, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_TranslationIndex, translation, DTA_TopLeft, true, TAG_DONE); - } - - if (breathebg) - { - DrawTexture(twod, tileGetTexture(VICTORY9, true), 86, 59, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_TranslationIndex, translation, DTA_TopLeft, true, TAG_DONE); - } - - if (breatheani != -1) - { - DrawTexture(twod, tileGetTexture(breathe_tile[breatheani], true), breathe_x, breathe_y, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_TranslationIndex, translation, DTA_TopLeft, true, TAG_DONE); - } - } -}; - - -class DE2EndScreen : public DImageScreen -{ -public: - DE2EndScreen() : DImageScreen(E2ENDSCREEN, DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff, 0) - {} - - void Start() override - { - S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); - } -}; -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DEpisode3End : public DImageScreen -{ - int sound = 0; - int64_t waittime = 0; - -public: - - FGameTexture* getTexture() - { - auto texid = TexMan.CheckForTexture("radlogo.anm", ETextureType::Any, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ForceLookup); - if (texid.isValid()) return TexMan.GetGameTexture(texid); - else return TexMan.GameByIndex(0); - } - -public: - DEpisode3End() : DImageScreen(getTexture(), fadein|fadeout, 0x7fffffff) - { - } - - void Skipped() override - { - FX_StopAllSounds(); - } - - void OnTick() override - { - switch (sound) - { - case 0: - S_PlaySound(ENDSEQVOL3SND5, CHAN_AUTO, CHANF_UI); - sound++; - break; - - case 1: - if (!S_CheckSoundPlaying(ENDSEQVOL3SND5)) - { - S_PlaySound(ENDSEQVOL3SND6, CHAN_AUTO, CHANF_UI); - sound++; - } - break; - - case 2: - if (!S_CheckSoundPlaying(ENDSEQVOL3SND6)) - { - S_PlaySound(ENDSEQVOL3SND7, CHAN_AUTO, CHANF_UI); - sound++; - } - break; - - case 3: - if (!S_CheckSoundPlaying(ENDSEQVOL3SND7)) - { - S_PlaySound(ENDSEQVOL3SND8, CHAN_AUTO, CHANF_UI); - sound++; - } - break; - - case 4: - if (!S_CheckSoundPlaying(ENDSEQVOL3SND8)) - { - S_PlaySound(ENDSEQVOL3SND9, CHAN_AUTO, CHANF_UI); - sound++; - } - break; - - case 5: - if (!S_CheckSoundPlaying(ENDSEQVOL3SND9)) - { - sound++; - waittime = ticks + GameTicRate * (SoundEnabled() ? 1 : 5); // if sound is off this wouldn't wait without a longer delay here. - } - break; - - case 6: - if (isPlutoPak()) - { - if (ticks > waittime) state = finished; - } - break; - - default: - break; - } - if (state != running) FX_StopAllSounds(); - } - - void OnDestroy() override - { - if (!isPlutoPak()) S_PlaySound(ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI); - } -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DEpisode4Text : public DSkippableScreenJob -{ -public: - DEpisode4Text() : DSkippableScreenJob(fadein | fadeout) {} - - void Draw(double) override - { - twod->ClearScreen(); - BigText(160, 60, GStrings("Thanks to all our")); - BigText(160, 60 + 16, GStrings("fans for giving")); - BigText(160, 60 + 16 + 16, GStrings("us big heads.")); - BigText(160, 70 + 16 + 16 + 16, GStrings("Look for a Duke Nukem 3D")); - BigText(160, 70 + 16 + 16 + 16 + 16, GStrings("sequel soon.")); - } - - void Start() override - { - S_PlaySound(ENDSEQVOL3SND4, CHAN_AUTO, CHANF_UI); - } -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DEpisode5End : public DImageScreen -{ - int sound = 0; - -public: - DEpisode5End() : DImageScreen(FIREFLYGROWEFFECT, fadein|fadeout|stopsound) - { - } - - void OnTick() override - { - switch (sound) - { - case 0: - sound++; - break; - - case 1: - S_PlaySound(E5L7_DUKE_QUIT_YOU, CHAN_AUTO, CHANF_UI); - sound++; - break; - - default: - break; - } - } -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - static void bonussequence_d(int num, TArray& jobs) { static const AnimSound cineov2sound[] = @@ -749,349 +324,6 @@ void doorders(const CompletionFunc& completion) #endif } -#if 0 -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DDukeMultiplayerBonusScreen : public DSkippableScreenJob -{ - int playerswhenstarted; - -public: - DDukeMultiplayerBonusScreen(int pws) : DSkippableScreenJob(fadein|fadeout) - { - playerswhenstarted = pws; - } - - void Start() override - { - S_PlayBonusMusic(); - } - - void Draw(double smoothratio) override - { - char tempbuf[32]; - int currentclock = int((ticks + smoothratio) * 120 / GameTicRate); - twod->ClearScreen(); - DrawTexture(twod, tileGetTexture(MENUSCREEN), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Color, 0xff808080, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); - DrawTexture(twod, tileGetTexture(INGAMEDUKETHREEDEE, true), 160, 34, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true, TAG_DONE); - if (isPlutoPak()) - DrawTexture(twod, tileGetTexture(PLUTOPAKSPRITE+2, true), 260, 36, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true, TAG_DONE); - - GameText(160, 58 + 2, GStrings("Multiplayer Totals"), 0, 0); - GameText(160, 58 + 10, currentLevel->DisplayName(), 0, 0); - GameText(160, 165, GStrings("Presskey"), 8 - int(sin(currentclock / 10.) * 8), 0); - - int t = 0; - - MiniText(38, 80, GStrings("Name"), 0, -1, 8); - MiniText(269+20, 80, GStrings("Kills"), 0, 1, 8); - - for (int i = 0; i < playerswhenstarted; i++) - { - mysnprintf(tempbuf, 32, "%-4d", i + 1); - MiniText(92 + (i * 23), 80, tempbuf, 0, -1, 3); - } - - for (int i = 0; i < playerswhenstarted; i++) - { - int xfragtotal = 0; - mysnprintf(tempbuf, 32, "%d", i + 1); - - MiniText(30, 90 + t, tempbuf, 0); - MiniText(38, 90 + t, PlayerName(i), 0, -1, ps[i].palookup); - - for (int y = 0; y < playerswhenstarted; y++) - { - int frag = ps[i].frags[y]; - if (i == y) - { - mysnprintf(tempbuf, 32, "%-4d", ps[y].fraggedself); - MiniText(92 + (y * 23), 90 + t, tempbuf, 0, -1, 2); - xfragtotal -= ps[y].fraggedself; - } - else - { - mysnprintf(tempbuf, 32, "%-4d", frag); - MiniText(92 + (y * 23), 90 + t, tempbuf, 0); - xfragtotal += frag; - } - /* - if (myconnectindex == connecthead) - { - mysnprintf(tempbuf, 32, "stats %ld killed %ld %ld\n", i + 1, y + 1, frag); - sendscore(tempbuf); - } - */ - } - - mysnprintf(tempbuf, 32, "%-4d", xfragtotal); - MiniText(101 + (8 * 23), 90 + t, tempbuf, 0, -1, 2); - - t += 7; - } - - for (int y = 0; y < playerswhenstarted; y++) - { - int yfragtotal = 0; - for (int i = 0; i < playerswhenstarted; i++) - { - if (i == y) - yfragtotal += ps[i].fraggedself; - int frag = ps[i].frags[y]; - yfragtotal += frag; - } - mysnprintf(tempbuf, 32, "%-4d", yfragtotal); - MiniText(92 + (y * 23), 96 + (8 * 7), tempbuf, 0, -1, 2); - } - - MiniText(45, 96 + (8 * 7), GStrings("Deaths"), 0, -1, 8); - } -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DDukeLevelSummaryScreen : public DScreenJob -{ - const char* lastmapname; - int gfx_offset; - int speech = -1; - int displaystate = 0; - int dukeAnimStart; - - enum - { - printTimeText = 1, - printTimeVal = 2, - printKillsText = 4, - printKillsVal = 8, - printSecretsText = 16, - printSecretsVal = 32, - printStatsAll = 63, - dukeAnim = 64, - dukeWait = 128, - - }; - -public: - DDukeLevelSummaryScreen() : DScreenJob(fadein | fadeout) - { - int vol = volfromlevelnum(currentLevel->levelNumber); - gfx_offset = BONUSSCREEN + ((vol == 1) ? 5 : 0); - lastmapname = currentLevel->DisplayName(); - } - - void FormatTime(int time, char* tempbuf) - { - mysnprintf(tempbuf, 32, "%02d:%02d", (time / (26 * 60)) % 60, (time / 26) % 60); - } - - bool OnEvent(event_t* ev) override - { - if (ev->type == EV_KeyDown && !specialKeyEvent(ev)) - { - if ((displaystate & printStatsAll) != printStatsAll) - { - S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); - displaystate = printStatsAll; - } - else if (!(displaystate & dukeAnim)) - { - displaystate |= dukeAnim; - dukeAnimStart = ticks; - S_PlaySound(SHOTGUN_COCK, CHAN_AUTO, CHANF_UI); - static const uint16_t speeches[] = { BONUS_SPEECH1, BONUS_SPEECH2, BONUS_SPEECH3, BONUS_SPEECH4 }; - speech = speeches[(rand() & 3)]; - S_PlaySound(speech, CHAN_AUTO, CHANF_UI, 1); - } - return true; - } - return false; - } - - void Start() override - { - S_PlayBonusMusic(); - } - - void OnTick() override - { - if ((displaystate & printStatsAll) != printStatsAll) - { - if (ticks == 15 * 3) - { - displaystate |= printTimeText; - } - else if (ticks == 15 * 4) - { - displaystate |= printTimeVal; - S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); - } - else if (ticks == 15 * 6) - { - displaystate |= printKillsText; - S_PlaySound(FLY_BY, CHAN_AUTO, CHANF_UI); - } - else if (ticks == 15 * 7) - { - displaystate |= printKillsVal; - S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); - } - else if (ticks == 15 * 9) - { - displaystate |= printSecretsText; - } - else if (ticks == 15 * 10) - { - displaystate |= printSecretsVal; - S_PlaySound(PIPEBOMB_EXPLODE, CHAN_AUTO, CHANF_UI); - } - } - if (displaystate & dukeAnim) - { - if (ticks >= dukeAnimStart + 60) - { - displaystate ^= dukeAnim | dukeWait; - } - } - if (displaystate & dukeWait) - { - if (speech <= 0 || !S_CheckSoundPlaying(speech)) - state = finished; - } - } - - void PrintTime() - { - char tempbuf[32]; - GameText(10, 59 + 9, GStrings("TXT_YourTime"), 0); - GameText(10, 69 + 9, GStrings("TXT_ParTime"), 0); - if (!isNamWW2GI()) - GameText(10, 79 + 9, GStrings("TXT_3DRTIME"), 0); - - if (displaystate & printTimeVal) - { - FormatTime(ps[myconnectindex].player_par, tempbuf); - GameText((320 >> 2) + 71, 59 + 9, tempbuf, 0); - - FormatTime(currentLevel->parTime, tempbuf); - GameText((320 >> 2) + 71, 69 + 9, tempbuf, 0); - - if (!isNamWW2GI()) - { - FormatTime(currentLevel->designerTime, tempbuf); - GameText((320 >> 2) + 71, 79 + 9, tempbuf, 0); - } - } - } - - void PrintKills() - { - char tempbuf[32]; - GameText(10, 94 + 9, GStrings("TXT_EnemiesKilled"), 0); - GameText(10, 104 + 9, GStrings("TXT_EnemiesLeft"), 0); - - if (displaystate & printKillsVal) - { - mysnprintf(tempbuf, 32, "%-3d", ps[myconnectindex].actors_killed); - GameText((320 >> 2) + 70, 94 + 9, tempbuf, 0); - - if (ud.player_skill > 3) - { - mysnprintf(tempbuf, 32, "%s", GStrings("TXT_N_A")); - } - else - { - if ((ps[myconnectindex].max_actors_killed - ps[myconnectindex].actors_killed) < 0) - mysnprintf(tempbuf, 32, "%-3d", 0); - else mysnprintf(tempbuf, 32, "%-3d", ps[myconnectindex].max_actors_killed - ps[myconnectindex].actors_killed); - - } - GameText((320 >> 2) + 70, 104 + 9, tempbuf, 0); - } - } - - void PrintSecrets() - { - char tempbuf[32]; - GameText(10, 119 + 9, GStrings("TXT_SECFND"), 0); - GameText(10, 129 + 9, GStrings("TXT_SECMISS"), 0); - - if (displaystate & printSecretsVal) - { - mysnprintf(tempbuf, 32, "%-3d", ps[myconnectindex].secret_rooms); - GameText((320 >> 2) + 70, 119 + 9, tempbuf, 0); - if (ps[myconnectindex].secret_rooms > 0) - sprintf(tempbuf, "%-3d", (100 * ps[myconnectindex].secret_rooms / ps[myconnectindex].max_secret_rooms)); - mysnprintf(tempbuf, 32, "%-3d", ps[myconnectindex].max_secret_rooms - ps[myconnectindex].secret_rooms); - GameText((320 >> 2) + 70, 129 + 9, tempbuf, 0); - } - } - - void Draw(double) override - { - twod->ClearScreen(); - DrawTexture(twod, tileGetTexture(gfx_offset, true), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); - - GameText(160, 190, GStrings("PRESSKEY"), 8 - int(sin(ticks * 12 / GameTicRate) * 8), 0); - - if (displaystate & printTimeText) - { - PrintTime(); - } - if (displaystate & printKillsText) - { - PrintKills(); - } - if (displaystate & printSecretsText) - { - PrintSecrets(); - } - - if (displaystate & dukeAnim) - { - switch (((ticks - dukeAnimStart) >> 2) % 15) - { - case 0: - case 1: - case 4: - case 5: - DrawTexture(twod, tileGetTexture(gfx_offset + 3), 199, 31, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, TAG_DONE); - break; - case 2: - case 3: - DrawTexture(twod, tileGetTexture(gfx_offset + 4), 199, 31, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, TAG_DONE); - break; - } - } - else if (!(displaystate & dukeWait)) - { - switch((ticks >> 3) & 3) - { - case 1: - case 3: - DrawTexture(twod, tileGetTexture(gfx_offset + 1), 199, 31, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, TAG_DONE); - break; - case 2: - DrawTexture(twod, tileGetTexture(gfx_offset + 2), 199, 31, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, TAG_DONE); - break; - } - } - - if (lastmapname) BigText(160, 20 - 6, lastmapname); - BigText(160, 36 - 6, GStrings("Completed")); - } - -}; -#endif - //--------------------------------------------------------------------------- // // @@ -1175,28 +407,6 @@ void e4intro(const CompletionFunc& completion) } #if 0 -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DDukeLoadScreen : public DScreenJob -{ - MapRecord* rec; - -public: - DDukeLoadScreen(MapRecord *maprec) : DScreenJob(0), rec(maprec) {} - - void Draw(double) override - { - twod->ClearScreen(); - DrawTexture(twod, tileGetTexture(LOADSCREEN), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); - - BigText(160, 90, (rec->flags & MI_USERMAP)? GStrings("TXT_LOADUM") : GStrings("TXT_LOADING")); - BigText(160, 114, rec->DisplayName()); - } -}; void loadscreen_d(MapRecord *rec, CompletionFunc func) { @@ -1209,7 +419,7 @@ void loadscreen_d(MapRecord *rec, CompletionFunc func) void PrintPaused_d() { - //BigText(160, 100, GStrings("Game Paused")); + BigText(160, 100, GStrings("Game Paused")); } diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index ae75c9920..844aad2a8 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -123,7 +123,6 @@ void InitFonts_r() } -#if 0 //========================================================================== // // wrappers around DrawText to allow easier reuse of the old code. @@ -139,22 +138,6 @@ static void BigText(double x, double y, const char* text, int align, double alph DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 0.4, DTA_ScaleY, 0.4, DTA_Alpha, alpha, TAG_DONE); } -static void GameText(double x, double y, const char* t, int shade, int align = -1, int trans = 0) -{ - x *= 2; y *= 2; - if (align != -1) - x -= SmallFont->StringWidth(t) * (align == 0 ? 0.5 : 1); - DrawText(twod, SmallFont, CR_UNDEFINED, x, y + 2, t, DTA_FullscreenScale, FSMode_Fit640x400, DTA_TranslationIndex, TRANSLATION(Translation_Remap, trans), DTA_Color, shadeToLight(shade), TAG_DONE); -} - -static void MiniText(double x, double y, const char* t, int shade, int align = -1, int trans = 0) -{ - x *= 2; y *= 2; - if (align != -1) - x -= SmallFont2->StringWidth(t) * (align == 0 ? 0.5 : 1); - DrawText(twod, SmallFont2, CR_UNDEFINED, x, y, t, DTA_FullscreenScale, FSMode_Fit640x400, DTA_TranslationIndex, TRANSLATION(Translation_Remap, trans), DTA_Color, shadeToLight(shade), TAG_DONE); -} -#endif //--------------------------------------------------------------------------- // @@ -253,344 +236,6 @@ static void bonussequence_r(int num, TArray& jobs) } #endif -#if 0 -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DRRMultiplayerBonusScreen : public DScreenJob -{ - int playerswhenstarted; - -public: - DRRMultiplayerBonusScreen(int pws) : DScreenJob(fadein | fadeout) - { - playerswhenstarted = pws; - } - - void Start() override - { - S_PlayBonusMusic(); - } - - - void Draw(double) override - { - char tempbuf[32]; - twod->ClearScreen(); - DrawTexture(twod, tileGetTexture(MENUSCREEN), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Color, 0xff808080, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); - double scale = 0.36; - DrawTexture(twod, tileGetTexture(INGAMEDUKETHREEDEE, true), 160, 34, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_CenterOffsetRel, true, DTA_ScaleX, scale, DTA_ScaleY, 0.36, TAG_DONE); - - GameText(160, 58, GStrings("Multiplayer Totals"), 0, 0); - GameText(160, 58 + 10, currentLevel->DisplayName(), 0, 0); - GameText(160, 165, GStrings("Presskey"), 0, 0); - - int t = 0; - - MiniText(38, 80, GStrings("Name"), 0); - MiniText(269 + 20, 80, GStrings("Kills"), 0, 1); - - for (int i = 0; i < playerswhenstarted; i++) - { - mysnprintf(tempbuf, 32, "%-4d", i + 1); - MiniText(92 + (i * 23), 80, tempbuf, 0); - } - - for (int i = 0; i < playerswhenstarted; i++) - { - int xfragtotal = 0; - mysnprintf(tempbuf, 32, "%d", i + 1); - - MiniText(30, 90 + t, tempbuf, 0); - MiniText(38, 90 + t, PlayerName(i), 0, -1, ps[i].palookup); - - for (int y = 0; y < playerswhenstarted; y++) - { - int frag = ps[i].frags[y]; - if (i == y) - { - mysnprintf(tempbuf, 32, "%-4d", ps[y].fraggedself); - MiniText(92 + (y * 23), 90 + t, tempbuf, 0); - xfragtotal -= ps[y].fraggedself; - } - else - { - mysnprintf(tempbuf, 32, "%-4d", frag); - MiniText(92 + (y * 23), 90 + t, tempbuf, 0); - xfragtotal += frag; - } - /* - if (myconnectindex == connecthead) - { - mysnprintf(tempbuf, 32, "stats %ld killed %ld %ld\n", i + 1, y + 1, frag); - sendscore(tempbuf); - } - */ - } - - mysnprintf(tempbuf, 32, "%-4d", xfragtotal); - MiniText(101 + (8 * 23), 90 + t, tempbuf, 0); - - t += 7; - } - - for (int y = 0; y < playerswhenstarted; y++) - { - int yfragtotal = 0; - for (int i = 0; i < playerswhenstarted; i++) - { - if (i == y) - yfragtotal += ps[i].fraggedself; - int frag = ps[i].frags[y]; - yfragtotal += frag; - } - mysnprintf(tempbuf, 32, "%-4d", yfragtotal); - MiniText(92 + (y * 23), 96 + (8 * 7), tempbuf, 0); - } - - MiniText(45, 96 + (8 * 7), GStrings("Deaths"), 0); - } -}; - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DRRLevelSummaryScreen : public DScreenJob -{ - const char* lastmapname; - int gfx_offset; - int displaystate = 0; - int speech = -1; - int exitSoundStart; - - enum - { - printTimeText = 1, - printTimeVal = 2, - printKillsText = 4, - printKillsVal = 8, - printSecretsText = 16, - printSecretsVal = 32, - printStatsAll = 63, - exitSound = 64, - exitWait = 128, - - }; - -public: - DRRLevelSummaryScreen(bool dofadeout = true) : DScreenJob(dofadeout? (fadein | fadeout) : fadein) - { - if (currentLevel->flags & MI_USERMAP) - gfx_offset = BONUSPIC01; - else if (!isRRRA()) - gfx_offset = BONUSPIC01 + clamp((currentLevel->levelNumber / 1000) * 7 + (currentLevel->levelNumber % 1000), 0, 13); - else - gfx_offset = LEVELMAP01 + clamp((currentLevel->levelNumber / 1000) * 7 + (currentLevel->levelNumber % 1000), 0, 13); - - - lastmapname = currentLevel->DisplayName(); - } - - void FormatTime(int time, char* tempbuf) - { - mysnprintf(tempbuf, 32, "%02d:%02d", (time / (26 * 60)) % 60, (time / 26) % 60); - } - - bool OnEvent(event_t* ev) override - { - if (ev->type == EV_KeyDown && !specialKeyEvent(ev)) - { - if ((displaystate & printStatsAll) != printStatsAll) - { - S_PlaySound(404, CHAN_AUTO, CHANF_UI); - displaystate = printStatsAll; - } - else if (!(displaystate & exitSound)) - { - displaystate |= exitSound; - exitSoundStart = ticks; - S_PlaySound(425, CHAN_AUTO, CHANF_UI); - speech = BONUS_SPEECH1 + (rand() & 3); - S_PlaySound(speech, CHAN_AUTO, CHANF_UI); - } - return true; - } - return false; - } - - void Start() override - { - S_PlayBonusMusic(); - } - - void OnTick() override - { - if ((displaystate & printStatsAll) != printStatsAll) - { - if (ticks == 15 * 3) - { - displaystate |= printTimeText; - } - else if (ticks == 15 * 4) - { - displaystate |= printTimeVal; - S_PlaySound(404, CHAN_AUTO, CHANF_UI); - } - else if (ticks == 15 * 6) - { - displaystate |= printKillsText; - } - else if (ticks == 15 * 7) - { - displaystate |= printKillsVal; - S_PlaySound(404, CHAN_AUTO, CHANF_UI); - } - else if (ticks == 15 * 9) - { - displaystate |= printSecretsText; - } - else if (ticks == 15 * 10) - { - displaystate |= printSecretsVal; - S_PlaySound(404, CHAN_AUTO, CHANF_UI); - } - } - if (displaystate & exitSound) - { - if (ticks >= exitSoundStart + 60) - { - displaystate ^= exitSound | exitWait; - } - } - if (displaystate & exitWait) - { - if (speech <= 0 || !S_CheckSoundPlaying(speech)) - state = finished; - } - } - - void PrintTime() - { - char tempbuf[32]; - BigText(30, 48, GStrings("TXT_YerTime"), -1); - BigText(30, 64, GStrings("TXT_ParTime"), -1); - BigText(30, 80, GStrings("TXT_XTRTIME"), -1); - - if (displaystate & printTimeVal) - { - FormatTime(ps[myconnectindex].player_par, tempbuf); - BigText(191, 48, tempbuf, -1); - - FormatTime(currentLevel->parTime, tempbuf); - BigText(191, 64, tempbuf, -1); - - FormatTime(currentLevel->designerTime, tempbuf); - BigText(191, 80, tempbuf, -1); - } - } - - void PrintKills() - { - char tempbuf[32]; - BigText(30, 112, GStrings("TXT_VarmintsKilled"), -1); - BigText(30, 128, GStrings("TXT_VarmintsLeft"), -1); - - if (displaystate & printKillsVal) - { - mysnprintf(tempbuf, 32, "%-3d", ps[myconnectindex].actors_killed); - BigText(231, 112, tempbuf, -1); - if (ud.player_skill > 3) - { - mysnprintf(tempbuf, 32, "%s", GStrings("TXT_N_A")); - BigText(231, 128, tempbuf, -1); - } - else - { - if ((ps[myconnectindex].max_actors_killed - ps[myconnectindex].actors_killed) < 0) - mysnprintf(tempbuf, 32, "%-3d", 0); - else mysnprintf(tempbuf, 32, "%-3d", ps[myconnectindex].max_actors_killed - ps[myconnectindex].actors_killed); - BigText(231, 128, tempbuf, -1); - } - } - } - - void PrintSecrets() - { - char tempbuf[32]; - BigText(30, 144, GStrings("TXT_SECFND"), -1); - BigText(30, 160, GStrings("TXT_SECMISS"), -1); - - if (displaystate & printSecretsVal) - { - mysnprintf(tempbuf, 32, "%-3d", ps[myconnectindex].secret_rooms); - BigText(231, 144, tempbuf, -1); - if (ps[myconnectindex].secret_rooms > 0) - sprintf(tempbuf, "%-3d", (100 * ps[myconnectindex].secret_rooms / ps[myconnectindex].max_secret_rooms)); - mysnprintf(tempbuf, 32, "%-3d", ps[myconnectindex].max_secret_rooms - ps[myconnectindex].secret_rooms); - BigText(231, 160, tempbuf, -1); - } - } - - void Draw(double) override - { - twod->ClearScreen(); - DrawTexture(twod, tileGetTexture(gfx_offset, true), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); - - if (lastmapname) BigText(80, 16, lastmapname, -1); - BigText(15, 192, GStrings("PRESSKEY"), -1); - - if (displaystate & printTimeText) - { - PrintTime(); - } - if (displaystate & printKillsText) - { - PrintKills(); - } - if (displaystate & printSecretsText) - { - PrintSecrets(); - } - } - -}; - - -class DRRRAEndOfGame : public DSkippableScreenJob -{ -public: - DRRRAEndOfGame() : DSkippableScreenJob(fadein|fadeout) - { - } - - void Skipped() override - { - S_StopSound(35); - } - - void Start() override - { - S_PlaySound(35, CHAN_AUTO, CHANF_UI); - } - - void OnTick() override - { - if (!S_CheckSoundPlaying(35) && ticks > 15 * GameTicRate) state = finished; // make sure it stays, even if sound is off. - } - void Draw(double) override - { - auto tex = tileGetTexture(ENDGAME + ((ticks >> 2) & 1)); - DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, TAG_DONE); - } -}; -#endif //--------------------------------------------------------------------------- // @@ -647,22 +292,6 @@ void dobonus_r(int bonusonly, const CompletionFunc& completion) // //--------------------------------------------------------------------------- -class DRRLoadScreen : public DScreenJob -{ - MapRecord* rec; - -public: - DRRLoadScreen(MapRecord* maprec) : DScreenJob(0), rec(maprec) {} - - void Draw(double) override - { - DrawTexture(twod, tileGetTexture(LOADSCREEN), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); - - int y = isRRRA()? 140 : 90; - BigText(160, y, (rec->flags & MI_USERMAP) ? GStrings("TXT_ENTRUM") : GStrings("TXT_ENTERIN"), 0); - BigText(160, y+24, rec->DisplayName(), 0); - } -}; void loadscreen_r(MapRecord* rec, CompletionFunc func) { @@ -675,7 +304,7 @@ void loadscreen_r(MapRecord* rec, CompletionFunc func) void PrintPaused_r() { - //BigText(160, 100, GStrings("Game Paused"), 0); + BigText(160, 100, GStrings("Game Paused"), 0); } diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs new file mode 100644 index 000000000..f90bdb75a --- /dev/null +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment +Copyright (C) 2020-2021 Christoph Oelckers + +This file is part of Raze. + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +aint with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +( not much left of the original code, though... ;) ) +*/ +//------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeIntro : ScreenJobRunner +{ + void Init() + { + Raze.StopMusic(); + Raze.StopAllSounds(); + + if (!userConfig.nologo) + { + if (!Raze.isShareware()) + { + Array soundinfo; + soundinfo.Push(1); + soundinfo.Push(DukeSnd.FLY_BY+1); + soundinfo.Push(19); + soundinfo.Push(DukeSnd.PIPEBOMB_EXPLODE+1); + jobs.Push(MoviePlayerJob.CreateWithSoundinfo("logo.anm", soundinfo, 9, 9, 9)); + } + if (!Raze.isNam()) jobs.Push(new("DRealmsScreen").Init()); + } + jobs.Push(new("DukeTitleScreen").Init()); + } +} \ No newline at end of file diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 77595f5e9..d93172b6c 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -1,3 +1,31 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment +Copyright (C) 2020-2021 Christoph Oelckers + +This file is part of Raze. + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +aint with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +( not much left of the original code, though... ;) ) +*/ +//------------------------------------------------------------------------- + //--------------------------------------------------------------------------- @@ -8,9 +36,10 @@ class DRealmsScreen : SkippableScreenJob { - void Init() + ScreenJob Init() { Super.Init(fadein | fadeout); + return self; } override void Start() @@ -43,10 +72,11 @@ class TitleScreen : SkippableScreenJob { int soundanm; - void Init() + ScreenJob Init() { Super.Init(fadein | fadeout); soundanm = 0; + return self; } override void Start() @@ -154,13 +184,14 @@ class Episode1End1 : SkippableScreenJob const boss_x = 86; const boss_y = 59; - void Init() + ScreenJob Init() { bonuscnt = 0; breathebg = false; bossani.SetInvalid(); breatheani.SetInvalid(); Super.Init(fadein | fadeout); + return self; } @@ -259,9 +290,10 @@ class Episode1End1 : SkippableScreenJob class E2EndScreen : ImageScreen { - void Init() + ScreenJob Init() { Super.InitNamed("E2ENDSCREEN", fadein | fadeout | stopsound, 0x7fffffff, 0); + return self; } override void Start() @@ -281,11 +313,12 @@ class Episode3End : ImageScreen int soundstate; int finishtime; - void Init() + ScreenJob Init() { Super.InitNamed("radlogo.anm", fadein|fadeout, 0x7fffffff); soundstate = 0; finishtime = 0; + return self; } override void OnSkip() @@ -369,9 +402,10 @@ class Episode3End : ImageScreen class Episode4Text : SkippableScreenJob { - void Init() + ScreenJob Init() { Super.Init(fadein|fadeout); + return self; } @@ -399,9 +433,10 @@ class Episode4Text : SkippableScreenJob class Episode5End : ImageScreen { - void Init() + ScreenJob Init() { Super.InitNamed("FIREFLYGROWEFFECT", fadein|fadeout|stopsound); + return self; } override void OnTick() @@ -420,10 +455,11 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob { int playerswhenstarted; - void Init(int pws) + ScreenJob Init(int pws) { Super.Init(fadein|fadeout); playerswhenstarted = pws; + return self; } override void Start() @@ -545,7 +581,7 @@ class DukeLevelSummaryScreen : SummaryScreenBase } - void Init() + ScreenJob Init() { Super.Init(fadein | fadeout); int vol = level.volumeNum(); @@ -559,7 +595,7 @@ class DukeLevelSummaryScreen : SummaryScreenBase lastmapname = level.DisplayName(); speech = -1; displaystate = 0; - + return self; } override bool OnEvent(InputEvent ev) @@ -783,7 +819,7 @@ class RRLevelSummaryScreen : SummaryScreenBase } - void Init(bool dofadeout = true) + ScreenJob Init(bool dofadeout = true) { Super.Init(dofadeout? (fadein | fadeout) : fadein); String s; @@ -796,6 +832,7 @@ class RRLevelSummaryScreen : SummaryScreenBase lastmapname = level.DisplayName(); texBg = TexMan.CheckForTexture(s); + return self; } override bool OnEvent(InputEvent ev) @@ -960,9 +997,10 @@ class RRLevelSummaryScreen : SummaryScreenBase class RRRAEndOfGame : SkippableScreenJob { - void Init() + ScreenJob Init() { Super.Init(fadein|fadeout); + return self; } override void OnSkip() @@ -997,10 +1035,11 @@ class DukeLoadScreen : ScreenJob { MapRecord rec; - void Init(MapRecord maprec) + ScreenJob Init(MapRecord maprec) { Super.Init(); rec = maprec; + return self; } override void Draw(double sr) diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 1de285dd5..9fd418dfb 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -98,11 +98,17 @@ class BlackScreen : ScreenJob int wait; bool cleared; - void Init(int w, int flags = 0) + ScreenJob Init(int w, int flags = 0) { Super.Init(flags & ~(fadein|fadeout)); wait = w; cleared = false; + return self; + } + + static ScreenJob Create(int w, int flags = 0) + { + return new("BlackScreen").Init(w, flags); } override void OnTick() @@ -135,23 +141,36 @@ class ImageScreen : SkippableScreenJob bool cleared; TextureID texid; - void Init(TextureID tile, int fade = fadein | fadeout, int wait = 3000, int translation = 0) + ScreenJob Init(TextureID tile, int fade = fadein | fadeout, int wait = 3000, int translation = 0) { Super.Init(fade); waittime = wait; texid = tile; trans = translation; cleared = false; + return self; } - void InitNamed(String tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0) + ScreenJob InitNamed(String tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0) { Super.Init(fade); waittime = wait; texid = TexMan.CheckForTexture(tex, TexMan.Type_Any, TexMan.TryAny | TexMan.ForceLookup); trans = translation; cleared = false; + return self; } + + static ScreenJob Create(TextureID tile, int fade = fadein | fadeout, int wait = 3000, int translation = 0) + { + return new("ImageScreen").Init(tile, fade, wait, translation); + } + + static ScreenJob CreateNamed(String tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0) + { + return new("ImageScreen").InitNamed(tex, fade, wait, translation); + } + override void OnTick() { if (cleared) @@ -209,15 +228,15 @@ class SummaryScreenBase : ScreenJob // //--------------------------------------------------------------------------- -struct AnmControl // ANM has no internal timing and sound info. Ugh... -{ - Array sounds; - int frameticks[3]; // first and last frame have their own durations. -} - struct MoviePlayer native { - native static MoviePlayer OpenMovie(String filename, AnmControl ans, bool nosoundcutoff, out String error); + enum EMovieFlags + { + NOSOUNDCUTOFF = 1, + FIXEDVIEWPORT = 2, // Forces fixed 640x480 screen size like for Blood's intros. + } + + native static MoviePlayer Create(String filename, Array soundinfo, int flags, int frametime, int firstframetime, int lastframetime); native void Start(); native bool Frame(double clock); native bool Destroy(); @@ -234,10 +253,30 @@ class MoviePlayerJob : SkippableScreenJob MoviePlayer player; bool started; - void Init(MoviePlayer mp) + ScreenJob Init(MoviePlayer mp) { player = mp; pausable = false; + return self; + } + + static ScreenJob CreateWithSoundInfo(String filename, Array soundinfo, int flags, int frametime, int firstframetime = -1, int lastframetime = -1) + { + 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. + } + static ScreenJob Create(String filename, int flags, int frametime = -1) + { + Array empty; + return CreateWithSoundInfo(filename, empty, flags, frametime); + } + static ScreenJob CreateWithSound(String filename, Sound soundname, int flags, int frametime = -1) + { + Array empty; + empty.Push(1); + empty.Push(int(soundname)); + return CreateWithSoundInfo(filename, empty, flags, frametime); } override void Draw(double smoothratio) From b5155430160acf35c2cac4842646a0df0411e181 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 25 Apr 2021 22:56:47 +0200 Subject: [PATCH 19/86] - added varargs pushv function to Array. We'll need this for the ANM sound arrays. Support for other array<> types to be done later. --- source/common/scripting/core/dynarrays.cpp | 25 ++++++++++++++++++++++ wadsrc/static/zscript/engine/dynarrays.zs | 1 + 2 files changed, 26 insertions(+) diff --git a/source/common/scripting/core/dynarrays.cpp b/source/common/scripting/core/dynarrays.cpp index 3d8e87e85..4182d1d95 100644 --- a/source/common/scripting/core/dynarrays.cpp +++ b/source/common/scripting/core/dynarrays.cpp @@ -37,6 +37,7 @@ #include "dobject.h" #include "vm.h" #include "types.h" +#include "v_draw.h" // We need one specific type for each of the 8 integral VM types and instantiate the needed functions for each of them. // Dynamic arrays cannot hold structs because for every type there'd need to be an internal implementation which is impossible. @@ -412,6 +413,30 @@ DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_I32, Push, ArrayPushPush(val)); } +DEFINE_ACTION_FUNCTION(FDynArray_I32, PushV) +{ + PARAM_SELF_STRUCT_PROLOGUE(FDynArray_I32); + PARAM_INT(val); + PARAM_VA_POINTER(va_reginfo); // Get the hidden type information array + self->Push(val); + VMVa_List args = { param + 3, 0, numparam - 4, va_reginfo + 3 }; + while (args.curindex < args.numargs) + { + if (args.reginfo[args.curindex] == REGT_INT) + { + self->Push(args.args[args.curindex++].i); + } + else if (args.reginfo[args.curindex] == REGT_FLOAT) + { + self->Push(int(args.args[args.curindex++].f)); + } + else ThrowAbortException(X_OTHER, "Invalid parameter in pushv, int expected"); + } + + + ACTION_RETURN_INT(self->Size()-1); +} + DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_I32, Pop, ArrayPop) { PARAM_SELF_STRUCT_PROLOGUE(FDynArray_I32); diff --git a/wadsrc/static/zscript/engine/dynarrays.zs b/wadsrc/static/zscript/engine/dynarrays.zs index 2e80820cd..1db4a6224 100644 --- a/wadsrc/static/zscript/engine/dynarrays.zs +++ b/wadsrc/static/zscript/engine/dynarrays.zs @@ -50,6 +50,7 @@ struct DynArray_I32 native native void Append (DynArray_I32 other); native uint Find(int item) const; native uint Push (int item); + native vararg uint PushV (int item, ...); native bool Pop (); native void Delete (uint index, int deletecount = 1); native void Insert (uint index, int item); From 9d20185b39e05c4496a9eff18c748ddaf340cbad Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 25 Apr 2021 22:57:12 +0200 Subject: [PATCH 20/86] - used pushv to make the intro init code look nicer. --- wadsrc/static/zscript/games/duke/ui/cutscenes.zs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index f90bdb75a..9fda43b1b 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -45,10 +45,9 @@ class DukeIntro : ScreenJobRunner if (!Raze.isShareware()) { Array soundinfo; - soundinfo.Push(1); - soundinfo.Push(DukeSnd.FLY_BY+1); - soundinfo.Push(19); - soundinfo.Push(DukeSnd.PIPEBOMB_EXPLODE+1); + soundinfo.Pushv( + 1, DukeSnd.FLY_BY+1, + 19, DukeSnd.PIPEBOMB_EXPLODE+1); jobs.Push(MoviePlayerJob.CreateWithSoundinfo("logo.anm", soundinfo, 9, 9, 9)); } if (!Raze.isNam()) jobs.Push(new("DRealmsScreen").Init()); From eeefc4355edf24ecfab1859e5571774db68c7564 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 00:09:46 +0200 Subject: [PATCH 21/86] - scriptified all of Duke's end of episode cutscenes. --- wadsrc/static/zscript.txt | 1 + .../static/zscript/games/duke/ui/cutscenes.zs | 147 +++++++++++++++++- .../static/zscript/games/duke/ui/screens.zs | 2 +- 3 files changed, 147 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 44b9bc8ee..087a11145 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -31,6 +31,7 @@ version "4.3" #include "zscript/screenjob.zs" #include "zscript/games/duke/dukegame.zs" #include "zscript/games/duke/ui/screens.zs" +#include "zscript/games/duke/ui/cutscenes.zs" #include "zscript/games/duke/ui/menu.zs" #include "zscript/games/blood/ui/menu.zs" #include "zscript/games/sw/ui/menu.zs" diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index 9fda43b1b..2bb3e1d5f 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -37,6 +37,7 @@ class DukeIntro : ScreenJobRunner { void Init() { + Super.Init(); Raze.StopMusic(); Raze.StopAllSounds(); @@ -48,10 +49,152 @@ class DukeIntro : ScreenJobRunner soundinfo.Pushv( 1, DukeSnd.FLY_BY+1, 19, DukeSnd.PIPEBOMB_EXPLODE+1); - jobs.Push(MoviePlayerJob.CreateWithSoundinfo("logo.anm", soundinfo, 9, 9, 9)); + jobs.Push(MoviePlayerJob.CreateWithSoundinfo("logo.anm", soundinfo, 0, 9, 9, 9)); } if (!Raze.isNam()) jobs.Push(new("DRealmsScreen").Init()); } jobs.Push(new("DukeTitleScreen").Init()); } -} \ No newline at end of file +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeE1End : ScreenJobRunner +{ + void Init() + { + Super.Init(); + jobs.Push(new("Episode1End1").Init()); + jobs.Push(ImageScreen.CreateNamed("E1ENDSCREEN", ScreenJob.fadein|ScreenJob.fadeout|ScreenJob.stopmusic, 0x7fffffff)); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeE2End : ScreenJobRunner +{ + void Init() + { + Super.Init(); + Array soundinfo; + soundinfo.Pushv( + 1, DukeSnd.WIND_AMBIENCE+1, + 26, DukeSnd.ENDSEQVOL2SND1+1, + 36, DukeSnd.ENDSEQVOL2SND2+1, + 54, DukeSnd.THUD+1, + 62, DukeSnd.ENDSEQVOL2SND3+1, + 75, DukeSnd.ENDSEQVOL2SND4 + 1, + 81, DukeSnd.ENDSEQVOL2SND5 + 1, + 115, DukeSnd.ENDSEQVOL2SND6 + 1, + 124, DukeSnd.ENDSEQVOL2SND7 + 1); + + jobs.Push(MoviePlayerJob.CreateWithSoundinfo("cineov2.anm", soundinfo, 0, 18, 18, 18)); + jobs.Push(new("E2EndScreen").Init()); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeE3End : ScreenJobRunner +{ + void Init() + { + Super.Init(); + Array soundinfo; + soundinfo.Pushv( + 1, DukeSnd.WIND_REPEAT + 1, + 98, DukeSnd.DUKE_GRUNT + 1, + 102, DukeSnd.THUD + 1, + 102, DukeSnd.SQUISHED + 1, + 124, DukeSnd.ENDSEQVOL3SND3 + 1, + 134, DukeSnd.ENDSEQVOL3SND2 + 1, + 158, DukeSnd.PIPEBOMB_EXPLODE + 1); + + jobs.Push(MoviePlayerJob.CreateWithSoundinfo("cineov3.anm", soundinfo, 0, 10, 10, 10)); + jobs.Push(BlackScreen.Create(200, ScreenJob.stopsound)); + jobs.Push(new("Episode3End").Init()); + if (!Raze.isPlutoPak()) jobs.Push(ImageScreen.CreateNamed("DUKETEAM.ANM", ScreenJob.fadein | ScreenJob.fadeout | ScreenJob.stopsound, 0x7fffffff)); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeDCEnd : ScreenJobRunner +{ + void Init() + { + Super.Init(); + Array soundinfo; + soundinfo.Pushv(144, DukeSnd.ENDSEQVOL3SND3 + 1); + jobs.Push(MoviePlayerJob.CreateWithSoundinfo("radlogo.anm", soundinfo, 0, 10, 10, 10)); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeE4End : ScreenJobRunner +{ + void Init() + { + Super.Init(true, true); + Array soundinfo; + + soundinfo.Pushv( + 3, DukeSnd.DUKE_UNDERWATER+1, + 35, DukeSnd.VOL4ENDSND1+1); + jobs.Push(MoviePlayerJob.CreateWithSoundinfo("vol4e1.anm", soundinfo, 0, 10, 10, 10)); + + soundinfo.Pushv( + 11, DukeSnd.DUKE_UNDERWATER+1, + 20, DukeSnd.VOL4ENDSND1+1, + 39, DukeSnd.VOL4ENDSND2+1, + 50, -1); + jobs.Push(MoviePlayerJob.CreateWithSoundinfo("vol4e2.anm", soundinfo, 0, 10, 10, 10)); + + soundinfo.Pushv( + 1, DukeSnd.BOSS4_DEADSPEECH+1, + 40, DukeSnd.VOL4ENDSND1+1, + 40, DukeSnd.DUKE_UNDERWATER+1, + 50, DukeSnd.BIGBANG+1); + jobs.Push(MoviePlayerJob.CreateWithSoundinfo("vol4e3.anm", soundinfo, 0, 10, 10, 10)); + + jobs.Push(new("Episode4Text").Init()); + jobs.Push(ImageScreen.CreateNamed("DUKETEAM.ANM", ScreenJob.fadein | ScreenJob.fadeout | ScreenJob.stopsound, 0x7fffffff)); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeE5End : ScreenJobRunner +{ + void Init() + { + Super.Init(); + jobs.Push(new("Episode5End").Init()); + } +} + diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index d93172b6c..6bf32bbb8 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -68,7 +68,7 @@ class DRealmsScreen : SkippableScreenJob // //--------------------------------------------------------------------------- -class TitleScreen : SkippableScreenJob +class DukeTitleScreen : SkippableScreenJob { int soundanm; From 88dfb938659b72d7bc00643be2e26dcbb67c8f05 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 01:20:49 +0200 Subject: [PATCH 22/86] - redid Duke cutscene code to use functions, not classes as exports and added the missing screens. Functions are better because they allow doing more in the internal setup code. --- source/games/duke/src/2d_d.cpp | 118 --------- source/games/duke/src/namelist_d.h | 5 + .../static/zscript/games/duke/ui/cutscenes.zs | 245 +++++++++++------- wadsrc/static/zscript/screenjob.zs | 9 +- 4 files changed, 169 insertions(+), 208 deletions(-) diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index 407459072..3ec25ccaa 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -178,124 +178,6 @@ void Logo_d(const CompletionFunc &completion) } -#if 0 -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static void bonussequence_d(int num, TArray& jobs) -{ - static const AnimSound cineov2sound[] = - { - { 1, WIND_AMBIENCE+1 }, - { 26, ENDSEQVOL2SND1+1 }, - { 36, ENDSEQVOL2SND2+1 }, - { 54, THUD+1 }, - { 62, ENDSEQVOL2SND3+1 }, - { 75, ENDSEQVOL2SND4 + 1 }, - { 81, ENDSEQVOL2SND5 + 1 }, - { 115, ENDSEQVOL2SND6 + 1 }, - { 124, ENDSEQVOL2SND7 + 1 }, - { -1, -1 } - }; - - static const AnimSound cineov3sound[] = - { - { 1, WIND_REPEAT + 1 }, - { 98, DUKE_GRUNT + 1 }, - { 102, THUD + 1 }, - { 102, SQUISHED + 1 }, - { 124, ENDSEQVOL3SND3 + 1 }, - { 134, ENDSEQVOL3SND2 + 1 }, - { 158, PIPEBOMB_EXPLODE + 1 }, - { -1,-1 } - }; - - static const AnimSound dukedcsound[] = - { - { 144, ENDSEQVOL3SND3 + 1 }, - { -1,-1 } - }; - - static const AnimSound vol4e1[] = - { - { 3, DUKE_UNDERWATER+1 }, - { 35, VOL4ENDSND1+1 }, - { -1,-1 } - }; - - static const AnimSound vol4e2[] = - { - { 11, DUKE_UNDERWATER+1 }, - { 20, VOL4ENDSND1+1 }, - { 39, VOL4ENDSND2+1 }, - { 50, -1 }, - { -1,-1 } - }; - - static const AnimSound vol4e3[] = - { - { 1, BOSS4_DEADSPEECH+1 }, - { 40, VOL4ENDSND1+1 }, - { 40, DUKE_UNDERWATER+1 }, - { 50, BIGBANG+1 }, - { -1,-1 } - }; - - - static const int framespeed_10[] = { 10, 10, 10 }; - static const int framespeed_14[] = { 14, 14, 14 }; - static const int framespeed_18[] = { 18, 18, 18 }; - - switch (num) - { - case 0: - jobs.Push(Create()); - jobs.Push(Create(E1ENDSCREEN, DScreenJob::fadein|DScreenJob::fadeout|DScreenJob::stopmusic, 0x7fffffff)); - break; - - case 1: - Mus_Stop(); - jobs.Push(PlayVideo("cineov2.anm", cineov2sound, framespeed_18)); - jobs.Push(Create()); - break; - - case 2: - Mus_Stop(); - if (g_gameType & GAMEFLAG_DUKEDC) - { - jobs.Push(PlayVideo("radlogo.anm", dukedcsound, framespeed_10)); - } - else - { - jobs.Push(PlayVideo("cineov3.anm", cineov3sound, framespeed_10)); - jobs.Push(Create(200, DScreenJob::stopsound)); - jobs.Push(Create()); - if (!isPlutoPak()) jobs.Push(Create(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), - DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff)); - } - break; - - case 3: - Mus_Stop(); - jobs.Push(PlayVideo("vol4e1.anm", vol4e1, framespeed_10)); - jobs.Push(PlayVideo("vol4e2.anm", vol4e2, framespeed_10)); - jobs.Push(PlayVideo("vol4e3.anm", vol4e3, framespeed_10)); - jobs.Push(Create()); - jobs.Push(Create(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), - DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff)); - break; - - case 4: - Mus_Stop(); - jobs.Push(Create()); - break; - } -} -#endif - //--------------------------------------------------------------------------- // // diff --git a/source/games/duke/src/namelist_d.h b/source/games/duke/src/namelist_d.h index 6da94e0b1..d05332000 100644 --- a/source/games/duke/src/namelist_d.h +++ b/source/games/duke/src/namelist_d.h @@ -608,8 +608,13 @@ x(VICTORY7, 3266) x(VICTORY8, 3267) x(VICTORY9, 3268) x(ORDERING, 3270) +x(ORDERING1, 3271) +x(ORDERING2, 3272) +x(ORDERING3, 3273) x(TEXTSTORY, 3280) x(LOADSCREEN, 3281) +x(SWEXIT2, 3290) +x(SWEXIT1, 3291) x(E1ENDSCREEN, 3292) x(E2ENDSCREEN, 3293) x(BORNTOBEWILDSCREEN, 3370) diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index 2bb3e1d5f..abe63c188 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -26,18 +26,16 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms */ //------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DukeIntro : ScreenJobRunner +class DukeCutscenes { - void Init() + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildIntro(ScreenJobRunner runner) { - Super.Init(); Raze.StopMusic(); Raze.StopAllSounds(); @@ -49,41 +47,33 @@ class DukeIntro : ScreenJobRunner soundinfo.Pushv( 1, DukeSnd.FLY_BY+1, 19, DukeSnd.PIPEBOMB_EXPLODE+1); - jobs.Push(MoviePlayerJob.CreateWithSoundinfo("logo.anm", soundinfo, 0, 9, 9, 9)); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("logo.anm", soundinfo, 0, 9, 9, 9)); } - if (!Raze.isNam()) jobs.Push(new("DRealmsScreen").Init()); + if (!Raze.isNam()) runner.Append(new("DRealmsScreen").Init()); } - jobs.Push(new("DukeTitleScreen").Init()); + runner.Append(new("DukeTitleScreen").Init()); } -} -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- -class DukeE1End : ScreenJobRunner -{ - void Init() + static void BuildE1End(ScreenJobRunner runner) { - Super.Init(); - jobs.Push(new("Episode1End1").Init()); - jobs.Push(ImageScreen.CreateNamed("E1ENDSCREEN", ScreenJob.fadein|ScreenJob.fadeout|ScreenJob.stopmusic, 0x7fffffff)); + runner.Append(new("Episode1End1").Init()); + runner.Append(ImageScreen.CreateNamed("E1ENDSCREEN", ScreenJob.fadein|ScreenJob.fadeout|ScreenJob.stopmusic, 0x7fffffff)); } -} -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- -class DukeE2End : ScreenJobRunner -{ - void Init() + static void BuildE2End(ScreenJobRunner runner) { - Super.Init(); Array soundinfo; soundinfo.Pushv( 1, DukeSnd.WIND_AMBIENCE+1, @@ -96,22 +86,18 @@ class DukeE2End : ScreenJobRunner 115, DukeSnd.ENDSEQVOL2SND6 + 1, 124, DukeSnd.ENDSEQVOL2SND7 + 1); - jobs.Push(MoviePlayerJob.CreateWithSoundinfo("cineov2.anm", soundinfo, 0, 18, 18, 18)); - jobs.Push(new("E2EndScreen").Init()); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("cineov2.anm", soundinfo, 0, 18, 18, 18)); + runner.Append(new("E2EndScreen").Init()); } -} -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- -class DukeE3End : ScreenJobRunner -{ - void Init() + static void BuildE3End(ScreenJobRunner runner) { - Super.Init(); Array soundinfo; soundinfo.Pushv( 1, DukeSnd.WIND_REPEAT + 1, @@ -122,79 +108,162 @@ class DukeE3End : ScreenJobRunner 134, DukeSnd.ENDSEQVOL3SND2 + 1, 158, DukeSnd.PIPEBOMB_EXPLODE + 1); - jobs.Push(MoviePlayerJob.CreateWithSoundinfo("cineov3.anm", soundinfo, 0, 10, 10, 10)); - jobs.Push(BlackScreen.Create(200, ScreenJob.stopsound)); - jobs.Push(new("Episode3End").Init()); - if (!Raze.isPlutoPak()) jobs.Push(ImageScreen.CreateNamed("DUKETEAM.ANM", ScreenJob.fadein | ScreenJob.fadeout | ScreenJob.stopsound, 0x7fffffff)); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("cineov3.anm", soundinfo, 0, 10, 10, 10)); + runner.Append(BlackScreen.Create(200, ScreenJob.stopsound)); + runner.Append(new("Episode3End").Init()); + if (!Raze.isPlutoPak()) runner.Append(ImageScreen.CreateNamed("DUKETEAM.ANM", ScreenJob.fadein | ScreenJob.fadeout | ScreenJob.stopsound, 0x7fffffff)); } -} -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- -class DukeDCEnd : ScreenJobRunner -{ - void Init() + static void BuildDCEnd(ScreenJobRunner runner) { - Super.Init(); Array soundinfo; soundinfo.Pushv(144, DukeSnd.ENDSEQVOL3SND3 + 1); - jobs.Push(MoviePlayerJob.CreateWithSoundinfo("radlogo.anm", soundinfo, 0, 10, 10, 10)); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("radlogo.anm", soundinfo, 0, 10, 10, 10)); } -} -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- -class DukeE4End : ScreenJobRunner -{ - void Init() + static void BuildE4End(ScreenJobRunner runner) { - Super.Init(true, true); Array soundinfo; soundinfo.Pushv( 3, DukeSnd.DUKE_UNDERWATER+1, 35, DukeSnd.VOL4ENDSND1+1); - jobs.Push(MoviePlayerJob.CreateWithSoundinfo("vol4e1.anm", soundinfo, 0, 10, 10, 10)); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol4e1.anm", soundinfo, 0, 10, 10, 10)); soundinfo.Pushv( 11, DukeSnd.DUKE_UNDERWATER+1, 20, DukeSnd.VOL4ENDSND1+1, 39, DukeSnd.VOL4ENDSND2+1, 50, -1); - jobs.Push(MoviePlayerJob.CreateWithSoundinfo("vol4e2.anm", soundinfo, 0, 10, 10, 10)); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol4e2.anm", soundinfo, 0, 10, 10, 10)); soundinfo.Pushv( 1, DukeSnd.BOSS4_DEADSPEECH+1, 40, DukeSnd.VOL4ENDSND1+1, 40, DukeSnd.DUKE_UNDERWATER+1, 50, DukeSnd.BIGBANG+1); - jobs.Push(MoviePlayerJob.CreateWithSoundinfo("vol4e3.anm", soundinfo, 0, 10, 10, 10)); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol4e3.anm", soundinfo, 0, 10, 10, 10)); - jobs.Push(new("Episode4Text").Init()); - jobs.Push(ImageScreen.CreateNamed("DUKETEAM.ANM", ScreenJob.fadein | ScreenJob.fadeout | ScreenJob.stopsound, 0x7fffffff)); + runner.Append(new("Episode4Text").Init()); + runner.Append(ImageScreen.CreateNamed("DUKETEAM.ANM", ScreenJob.fadein | ScreenJob.fadeout | ScreenJob.stopsound, 0x7fffffff)); } -} -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- -class DukeE5End : ScreenJobRunner -{ - void Init() + static void BuildE5End(ScreenJobRunner runner) { - Super.Init(); - jobs.Push(new("Episode5End").Init()); + runner.Append(new("Episode5End").Init()); } + + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + + static void BuildE4Intro(ScreenJobRunner runner) + { + Array soundinfo; + + Duke.PlaySpecialMusic(Duke.MUS_BRIEFING); + soundinfo.Pushv( + 1, DukeSnd.INTRO4_B + 1, + 12, DukeSnd.SHORT_CIRCUIT + 1, + 18, DukeSnd.INTRO4_5 + 1, + 34, DukeSnd.SHORT_CIRCUIT + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol41a1.anm", soundinfo, 0, 10, 10, 10)); + + soundinfo.Pushv( + 1, DukeSnd.INTRO4_1 + 1, + 7, DukeSnd.INTRO4_3 + 1, + 12, DukeSnd.INTRO4_2 + 1, + 26, DukeSnd.INTRO4_4 + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol42a.anm", soundinfo, 0, 14, 14, 14)); + + soundinfo.Pushv( + 10, DukeSnd.INTRO4_6 + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("vol43a.anm", soundinfo, 0, 10, 10, 10)); + + runner.skipall = true; + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildMPSummary(ScreenJobRunner runner, int playerswhenstarted) + { + runner.Append(new("DukeMultiplayerBonusScreen").Init(playerswhenstarted)); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildSPSummary(ScreenJobRunner runner, MapRecord map, int kills_, int maxkills_, int secrets_, int maxsecrets_, int supersecrets_, int time_, bool cheated) + { + let screen = SummaryScreenBase(new("DukeLevelSummaryScreen").Init()); + if (screen) screen.SetParameters(map, kills_, maxkills_, secrets_, maxsecrets_, supersecrets_, time_, cheated); + runner.Append(screen); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildSharewareExit(ScreenJobRunner runner) + { + runner.Append(ImageScreen.CreateNamed("SWEXIT1")); + runner.Append(ImageScreen.CreateNamed("SWEXIT2")); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildSharewareOrder(ScreenJobRunner runner) + { + runner.Append(ImageScreen.CreateNamed("ORDERING")); + runner.Append(ImageScreen.CreateNamed("ORDERING1")); + runner.Append(ImageScreen.CreateNamed("ORDERING2")); + runner.Append(ImageScreen.CreateNamed("ORDERING3")); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildLoading(ScreenJobRunner runner, MapRecord map) + { + runner.Append(new("DukeLoadScreen").Init(map)); + } + } diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 9fd418dfb..e41f62dab 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -349,7 +349,7 @@ class ScreenJobRunner : Object DeleteJobs(); } - void DeleteJobs() + protected void DeleteJobs() { // Free all allocated resources now. for (int i = 0; i < jobs.Size(); i++) @@ -359,13 +359,18 @@ class ScreenJobRunner : Object jobs.Clear(); } + void Append(ScreenJob job) + { + jobs.Push(job); + } + //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- - void AdvanceJob(bool skip) + protected void AdvanceJob(bool skip) { if (index == jobs.Size()-1) { From 21aa5c92349d5d9194273098160ed2b1caa246eb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 01:24:57 +0200 Subject: [PATCH 23/86] - added game flags for all supported add-ons. --- source/core/gamecontrol.h | 11 +++++++++-- source/core/searchpaths.cpp | 6 ++++++ source/games/duke/src/2d_r.cpp | 17 ---------------- wadsrc/static/engine/grpinfo.txt | 32 +++++++++++++++---------------- wadsrc/static/zscript/razebase.zs | 10 ++++++++-- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 6d6188af9..7f4a48774 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -99,8 +99,15 @@ enum GAMEFLAG_POWERSLAVE = 0x00002000, GAMEFLAG_EXHUMED = 0x00004000, GAMEFLAG_PSEXHUMED = GAMEFLAG_POWERSLAVE | GAMEFLAG_EXHUMED, // the two games really are the same, except for the name and the publisher. - GAMEFLAG_WORLDTOUR = 0x00008000, - GAMEFLAG_DUKEDC = 0x00010000, + GAMEFLAG_WORLDTOUR = 0x00008000, + GAMEFLAG_DUKEDC = 0x00010000, + GAMEFLAG_DUKENW = 0x00020000, + GAMEFLAG_DUKEVACA = 0x00040000, + GAMEFLAG_BLOODCP = 0x00080000, + GAMEFLAG_ROUTE66 = 0x00100000, + GAMEFLAG_SWWANTON = 0x00200000, + GAMEFLAG_SWTWINDRAG = 0x00400000, + GAMEFLAG_DUKECOMPAT = GAMEFLAG_DUKE | GAMEFLAG_NAM | GAMEFLAG_NAPALM | GAMEFLAG_WW2GI | GAMEFLAG_RRALL, GAMEFLAGMASK = 0x0000FFFF, // flags allowed from grpinfo diff --git a/source/core/searchpaths.cpp b/source/core/searchpaths.cpp index dd3a73af9..d449adf40 100644 --- a/source/core/searchpaths.cpp +++ b/source/core/searchpaths.cpp @@ -398,6 +398,12 @@ static TArray ParseGrpInfo(const char *fn, FileReader &fr, TMap jobs(1, true); - - jobs[0] = Create(rec); - RunScreenJob(jobs, func); -} -#endif - void PrintPaused_r() { BigText(160, 100, GStrings("Game Paused"), 0); diff --git a/wadsrc/static/engine/grpinfo.txt b/wadsrc/static/engine/grpinfo.txt index 9f487418b..7c0bc7f73 100644 --- a/wadsrc/static/engine/grpinfo.txt +++ b/wadsrc/static/engine/grpinfo.txt @@ -249,7 +249,7 @@ grpinfo name "Duke Caribbean: Life's a Beach" size 22213819 crc DUKECB_CRC - flags GAMEFLAG_DUKE|GAMEFLAG_ADDON + flags GAMEFLAG_DUKE|GAMEFLAG_ADDON|GAMEFLAG_DUKEVACA dependency DUKE15_CRC gamefilter "Duke.Vacation" FgColor 0x00004f @@ -263,7 +263,7 @@ grpinfo scriptname "VACATION.CON" size 22397273 crc 0x65B5F690 - flags GAMEFLAG_DUKE|GAMEFLAG_ADDON + flags GAMEFLAG_DUKE|GAMEFLAG_ADDON|GAMEFLAG_DUKEVACA dependency DUKE15_CRC gamefilter "Duke.Vacation" FgColor 0x00004f @@ -277,7 +277,7 @@ grpinfo scriptname "NWINTER.CON" size 16169365 crc DUKENW_CRC - flags GAMEFLAG_DUKE|GAMEFLAG_ADDON + flags GAMEFLAG_DUKE|GAMEFLAG_ADDON|GAMEFLAG_DUKENW dependency DUKE15_CRC gamefilter "Duke.NWinter" FgColor 0 @@ -291,7 +291,7 @@ grpinfo scriptname "NWINTER.CON" size 10965909 crc 0xC7EFBFA9 - flags GAMEFLAG_DUKE|GAMEFLAG_ADDON + flags GAMEFLAG_DUKE|GAMEFLAG_ADDON|GAMEFLAG_DUKENW dependency DUKE15_CRC gamefilter "Duke.NWinter" FgColor 0 @@ -423,7 +423,7 @@ grpinfo name "BLOOD: Cryptic Passage" scriptname "CRYPTIC.INI" mustcontain "CRYPTIC.INI", "CP01.MAP", "CP02.MAP" - flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON + flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON|GAMEFLAG_BLOODCP dependency BLOOD_CRC loadart "CPART07.AR_", "CPART15.AR_" gamefilter "Blood.Cryptic" @@ -436,7 +436,7 @@ addon name "BLOOD: Cryptic Passage" scriptname "CRYPTIC.INI" mustcontain "CRYPTIC.INI", "CP01.MAP", "CP02.MAP" - flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON + flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON|GAMEFLAG_BLOODCP dependency BLOOD_CRC loadart "CPART07.AR_", "CPART15.AR_" gamefilter "Blood.Cryptic" @@ -450,7 +450,7 @@ addon scriptname "CRYPTIC.INI" mustcontain "cryptic/CRYPTIC.INI", "cryptic/CP01.MAP", "cryptic/CP02.MAP" loadgrp "cryptic" - flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON + flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON|GAMEFLAG_BLOODCP dependency BLOOD_CRC loadart "CPART07.AR_", "CPART15.AR_" gamefilter "Blood.Cryptic" @@ -464,7 +464,7 @@ addon scriptname "CRYPTIC.INI" mustcontain "addons/Cryptic Passage/CRYPTIC.INI", "addons/Cryptic Passage/CP01.MAP", "addons/Cryptic Passage/CP02.MAP" loadgrp "addons/Cryptic Passage" - flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON + flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON|GAMEFLAG_BLOODCP dependency BLOOD_CRC gamefilter "Blood.Cryptic" GameID "CrypticPassage" @@ -573,7 +573,7 @@ grpinfo grpinfo { name "Shadow Warrior: Wanton Destruction" - flags GAMEFLAG_SW|GAMEFLAG_ADDON + flags GAMEFLAG_SW|GAMEFLAG_ADDON|GAMEFLAG_SWWANTON crc SWWD_CRC size 48698128 defname "sw.def" @@ -585,7 +585,7 @@ grpinfo grpinfo { name "Shadow Warrior: Wanton Destruction" - flags GAMEFLAG_SW|GAMEFLAG_ADDON + flags GAMEFLAG_SW|GAMEFLAG_ADDON|GAMEFLAG_SWWANTON crc 0x8B6E8011 size 48698128 defname "sw.def" @@ -597,7 +597,7 @@ grpinfo grpinfo { name "Shadow Warrior: Wanton Destruction (ProAsm)" - flags GAMEFLAG_SW|GAMEFLAG_ADDON + flags GAMEFLAG_SW|GAMEFLAG_ADDON|GAMEFLAG_SWWANTON crc 0x39893EF4 size 9562689 defname "sw.def" @@ -610,7 +610,7 @@ grpinfo grpinfo { name "Shadow Warrior: Twin Dragon" - flags GAMEFLAG_SW|GAMEFLAG_ADDON + flags GAMEFLAG_SW|GAMEFLAG_ADDON|GAMEFLAG_SWTWINDRAG crc SWTD_CRC size 12499012 defname "twindrag.def" @@ -623,7 +623,7 @@ grpinfo grpinfo { name "Shadow Warrior: Twin Dragon" - flags GAMEFLAG_SW|GAMEFLAG_ADDON + flags GAMEFLAG_SW|GAMEFLAG_ADDON|GAMEFLAG_SWTWINDRAG crc 0xB5B71277 size 6236287 defname "twindrag.def" @@ -635,7 +635,7 @@ grpinfo grpinfo { name "Shadow Warrior: Twin Dragon" - flags GAMEFLAG_SW|GAMEFLAG_ADDON + flags GAMEFLAG_SW|GAMEFLAG_ADDON|GAMEFLAG_SWTWINDRAG crc 0xACC8DCDE size 6235578 defname "twindrag.def" @@ -678,7 +678,7 @@ grpinfo name "Redneck Rampage: Suckin' Grits on Route 66" scriptname "GAME66.CON" mustcontain "TILESA66.ART", "TILESB66.ART", "ROUTE66/CARNIVAL.MAP", "ROUTE66/TRUCKSTP.MAP", "GAME66.CON" - flags GAMEFLAG_RR|GAMEFLAG_ADDON + flags GAMEFLAG_RR|GAMEFLAG_ADDON|GAMEFLAG_ROUTE66 dependency RR_CRC loadart "TILESA66.ART", "TILESB66.ART" // replaces TILES009 and TILES023. gamefilter "Redneck.Route66" @@ -692,7 +692,7 @@ addon name "Redneck Rampage: Suckin' Grits on Route 66" scriptname "GAME66.CON" mustcontain "TILESA66.ART", "TILESB66.ART", "ROUTE66/CARNIVAL.MAP", "ROUTE66/TRUCKSTP.MAP", "GAME66.CON" - flags GAMEFLAG_RR|GAMEFLAG_ADDON + flags GAMEFLAG_RR|GAMEFLAG_ADDON|GAMEFLAG_ROUTE66 dependency RR_CRC loadart "TILESA66.ART", "TILESB66.ART" // replaces TILES009 and TILES023. gamefilter "Redneck.Route66" diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index 9ca6c734f..a7dcd3254 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -17,8 +17,14 @@ enum EGameType GAMEFLAG_POWERSLAVE = 0x00002000, GAMEFLAG_EXHUMED = 0x00004000, GAMEFLAG_PSEXHUMED = GAMEFLAG_POWERSLAVE | GAMEFLAG_EXHUMED, // the two games really are the same, except for the name and the publisher. - GAMEFLAG_WORLDTOUR = 0x00008000, - GAMEFLAG_DUKEDC = 0x00010000, + GAMEFLAG_WORLDTOUR = 0x00008000, + GAMEFLAG_DUKEDC = 0x00010000, + GAMEFLAG_DUKENW = 0x00020000, + GAMEFLAG_DUKEVACA = 0x00040000, + GAMEFLAG_BLOODCP = 0x00080000, + GAMEFLAG_ROUTE66 = 0x00100000, + GAMEFLAG_SWWANTON = 0x00200000, + GAMEFLAG_SWTWINDRAG = 0x00400000, GAMEFLAGMASK = 0x0000FFFF, // flags allowed from grpinfo // We still need these for the parsers. From f077359196556481b5c008c5769dc21d40f32524 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 01:27:04 +0200 Subject: [PATCH 24/86] - merge DukeDC's end of episode cutscene into BuildE3End. This will make things a bit easier on the setup side because it eliminates the need for mission pack specific definitions. --- .../static/zscript/games/duke/ui/cutscenes.zs | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index abe63c188..dba1c0e51 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -98,33 +98,29 @@ class DukeCutscenes static void BuildE3End(ScreenJobRunner runner) { - Array soundinfo; - soundinfo.Pushv( - 1, DukeSnd.WIND_REPEAT + 1, - 98, DukeSnd.DUKE_GRUNT + 1, - 102, DukeSnd.THUD + 1, - 102, DukeSnd.SQUISHED + 1, - 124, DukeSnd.ENDSEQVOL3SND3 + 1, - 134, DukeSnd.ENDSEQVOL3SND2 + 1, - 158, DukeSnd.PIPEBOMB_EXPLODE + 1); + if (gameinfo.gameType & GAMEFLAG_DUKEDC) + { + Array soundinfo; + soundinfo.Pushv(144, DukeSnd.ENDSEQVOL3SND3 + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("radlogo.anm", soundinfo, 0, 10, 10, 10)); + } + else + { + Array soundinfo; + soundinfo.Pushv( + 1, DukeSnd.WIND_REPEAT + 1, + 98, DukeSnd.DUKE_GRUNT + 1, + 102, DukeSnd.THUD + 1, + 102, DukeSnd.SQUISHED + 1, + 124, DukeSnd.ENDSEQVOL3SND3 + 1, + 134, DukeSnd.ENDSEQVOL3SND2 + 1, + 158, DukeSnd.PIPEBOMB_EXPLODE + 1); - runner.Append(MoviePlayerJob.CreateWithSoundinfo("cineov3.anm", soundinfo, 0, 10, 10, 10)); - runner.Append(BlackScreen.Create(200, ScreenJob.stopsound)); - runner.Append(new("Episode3End").Init()); - if (!Raze.isPlutoPak()) runner.Append(ImageScreen.CreateNamed("DUKETEAM.ANM", ScreenJob.fadein | ScreenJob.fadeout | ScreenJob.stopsound, 0x7fffffff)); - } - - //--------------------------------------------------------------------------- - // - // - // - //--------------------------------------------------------------------------- - - static void BuildDCEnd(ScreenJobRunner runner) - { - Array soundinfo; - soundinfo.Pushv(144, DukeSnd.ENDSEQVOL3SND3 + 1); - runner.Append(MoviePlayerJob.CreateWithSoundinfo("radlogo.anm", soundinfo, 0, 10, 10, 10)); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("cineov3.anm", soundinfo, 0, 10, 10, 10)); + runner.Append(BlackScreen.Create(200, ScreenJob.stopsound)); + runner.Append(new("Episode3End").Init()); + if (!Raze.isPlutoPak()) runner.Append(ImageScreen.CreateNamed("DUKETEAM.ANM", ScreenJob.fadein | ScreenJob.fadeout | ScreenJob.stopsound, 0x7fffffff)); + } } //--------------------------------------------------------------------------- From 57853bf8fe1e7bb8ec3a277a9197a1d2a51b162b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 01:35:16 +0200 Subject: [PATCH 25/86] - RR Cutscene generators. --- wadsrc/static/zscript/games/duke/dukegame.zs | 8 +- .../static/zscript/games/duke/ui/cutscenes.zs | 105 +++++++++++++++++- 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index 189f4e85e..e5632eff1 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -522,9 +522,15 @@ struct RRSnd native BUB_HRT3 = 24 , GASP = 25 , BUB_HRT4 = 26 , - MIRROR1 = 27 , + + ONECART = 27 , // RR + MINEWIND = 28 , + URANUS = 29 , + + MIRROR1 = 27 , // RRRA MIRROR2 = 28 , MIRROR3 = 29 , + COMPUTER = 30 , NEON = 31 , VX_FINAL = 32 , diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index dba1c0e51..df0c93413 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -36,9 +36,6 @@ class DukeCutscenes static void BuildIntro(ScreenJobRunner runner) { - Raze.StopMusic(); - Raze.StopAllSounds(); - if (!userConfig.nologo) { if (!Raze.isShareware()) @@ -174,7 +171,7 @@ class DukeCutscenes // //--------------------------------------------------------------------------- - static void BuildE4Intro(ScreenJobRunner runner) + static void BuildE4Intro(ScreenJobRunner runner, MapRecord map) { Array soundinfo; @@ -263,3 +260,103 @@ class DukeCutscenes } +class RRCutscenes +{ + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildIntro(ScreenJobRunner runner) + { + if (!userConfig.nologo) + { + if (!Raze.isRRRA()) + { + soundinfo.Pushv(1, RRSnd.URANUS + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("rr_intro.anm", soundinfo, 0, 9, 9, 9)); + + soundinfo.Pushv(1, RRSnd.REDNECK2 + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("redneck.anm", soundinfo, 0, 14, 14, 14)); + + soundinfo.Pushv(1, RRSnd.XATRIX + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("xatlogo.anm", soundinfo, 0, 10, 10, 10)); + } + else + { + runner.Append(MoviePlayerJob.Create("redint.mve"), 0); + } + } + } + + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildE1End(ScreenJobRunner runner) + { + soundinfo.Pushv(1, RRSnd.CHKAMMO + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("turdmov.anm", soundinfo, 0, 9, 9, 9)); + } + + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildE2End(ScreenJobRunner runner) + { + soundinfo.Pushv(1, RRSnd.LN_FINAL + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("rr_outro.anm", soundinfo, 0, 9, 9, 9)); + runner.Append(ImageScreen.CreateNamed("TENSCREEN")); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildRRRAEnd(ScreenJobRunner runner) + { + runner.Append(new("RRRAEndOfGame").Init()); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildSPSummary(ScreenJobRunner runner, MapRecord map, int kills_, int maxkills_, int secrets_, int maxsecrets_, int supersecrets_, int time_, bool cheated) + { + let screen = SummaryScreenBase(new("RRLevelSummaryScreen").Init(!isRRRA() || map.flags & MapRecord.FORCEEOG)); + if (screen) screen.SetParameters(map, kills_, maxkills_, secrets_, maxsecrets_, supersecrets_, time_, cheated); + runner.Append(screen); + } + + //--------------------------------------------------------------------------- + // + // + // + //--------------------------------------------------------------------------- + + static void BuildMapIntro(ScreenJobRunner runner, MapRecord map) + { + int ln = map.levelnumber; + if (ln == 0) return; + if (ln > 1000) ln -= 1000-7; + + let fn = String.Format("lvl%d.anm", ln); + Array soundinfo; + runner.Append(MoviePlayerJob.CreateWithSoundinfo(fn, soundinfo, 0, 20, 20, 7200)); // wait for one minute on the final frame so that the video doesn't stop before the user notices. + } + +} \ No newline at end of file From e05f900315deeaa107b5f9481ebae2d4f61e4aaf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 01:45:16 +0200 Subject: [PATCH 26/86] - added the data structures to hold the cutscene data. --- source/build/src/defs.cpp | 7 ++- source/common/engine/sc_man.cpp | 36 ++++++++++++ source/common/engine/sc_man.h | 25 +++++++++ source/core/gamecontrol.cpp | 9 +-- source/core/mapinfo.cpp | 29 ++++------ source/core/mapinfo.h | 46 ++++++++++++++-- source/core/menu/razemenu.cpp | 13 +++-- source/core/parsefuncs.h | 88 +++++++++++++++++++++++++++++- source/core/statusbar2.cpp | 2 +- source/games/blood/src/credits.cpp | 4 +- source/games/blood/src/levels.cpp | 10 ++-- source/games/blood/src/levels.h | 4 +- source/games/duke/src/funct.h | 1 + source/games/duke/src/game.cpp | 1 + source/games/duke/src/gamedef.cpp | 59 +++++++++++--------- source/games/sw/src/scrip2.cpp | 4 +- 16 files changed, 267 insertions(+), 71 deletions(-) diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index d141f2219..b629626be 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -207,7 +207,7 @@ enum scripttoken_t T_RFFDEFINEID, T_EXTRA, T_ROTATE, - T_SURFACE, T_VIEW, + T_SURFACE, T_VIEW, T_MAP, T_DEFINECUTSCENE, }; static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0; @@ -360,6 +360,8 @@ static int32_t defsparser(scriptfile *script) { "shadefactor", T_SHADEFACTOR }, { "newgamechoices", T_NEWGAMECHOICES }, { "rffdefineid", T_RFFDEFINEID }, // dummy + { "map", T_MAP }, + { "definecutscene", T_DEFINECUTSCENE }, }; script->SetNoOctals(true); @@ -376,6 +378,9 @@ static int32_t defsparser(scriptfile *script) auto pos = scriptfile_getposition(script); switch (tokn) { + case T_DEFINECUTSCENE: + parseDefineCutscene(*script, pos); + break; case T_ERROR: pos.Message(MSG_ERROR, "Unknown error"); break; diff --git a/source/common/engine/sc_man.cpp b/source/common/engine/sc_man.cpp index fa9a2f6c4..f24f25d92 100644 --- a/source/common/engine/sc_man.cpp +++ b/source/common/engine/sc_man.cpp @@ -1287,6 +1287,42 @@ void FScanner::AddSymbol(const char* name, double value) symbols.Insert(name, sym); } +//========================================================================== +// +// +// +//========================================================================== + +int FScanner::StartBraces(FScanner::SavedPos* braceend) +{ + if (CheckString("{")) + { + auto here = SavePos(); + SkipToEndOfBlock(); + *braceend = SavePos(); + RestorePos(here); + return 0; + } + else + { + ScriptError("'{' expected"); + return -1; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +bool FScanner::FoundEndBrace(FScanner::SavedPos& braceend) +{ + auto here = SavePos(); + return here.SavedScriptPtr >= braceend.SavedScriptPtr; +} + + //========================================================================== // // a class that remembers a parser position diff --git a/source/common/engine/sc_man.h b/source/common/engine/sc_man.h index 3a894fcb3..56a4a8d82 100644 --- a/source/common/engine/sc_man.h +++ b/source/common/engine/sc_man.h @@ -94,6 +94,8 @@ public: inline void AddSymbol(const char* name, uint32_t value) { return AddSymbol(name, uint64_t(value)); } void AddSymbol(const char* name, double value); void SkipToEndOfBlock(); + int StartBraces(FScanner::SavedPos* braceend); + bool FoundEndBrace(FScanner::SavedPos& braceend); static FString TokenName(int token, const char *string=NULL); @@ -120,7 +122,30 @@ public: return true; } + bool GetNumber(int64_t& var, bool evaluate = false) + { + if (!GetNumber(evaluate)) return false; + var = BigNumber; + return true; + } + + bool GetString(FString& var) + { + if (!GetString()) return false; + var = String; + return true; + } + bool GetFloat(bool evaluate = false); + + bool GetFloat(double& var, bool evaluate = false) + { + if (!GetFloat(evaluate)) return false; + var = Float; + return true; + } + + void MustGetFloat(bool evaluate = false); bool CheckFloat(bool evaluate = false); diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 2b475f59e..3f1778cea 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -599,15 +599,16 @@ void SetDefaultStrings() if ((g_gameType & GAMEFLAG_DUKE) && fileSystem.FindFile("E4L1.MAP") < 0) { // Pre-Atomic releases do not define this. - gVolumeNames[0] = "$L.A. Meltdown"; - gVolumeNames[1] = "$Lunar Apocalypse"; - gVolumeNames[2] = "$Shrapnel City"; - if (g_gameType & GAMEFLAG_SHAREWARE) gVolumeNames[3] = "$The Birth"; + volumeList[0].name = "$L.A. Meltdown"; + volumeList[1].name = "$Lunar Apocalypse"; + volumeList[2].name = "$Shrapnel City"; + if (g_gameType & GAMEFLAG_SHAREWARE) volumeList[3].name = "$The Birth"; gSkillNames[0] = "$Piece of Cake"; gSkillNames[1] = "$Let's Rock"; gSkillNames[2] = "$Come get Some"; gSkillNames[3] = "$Damn I'm Good"; } + if (g_gameType & GAMEFLAG_RR) volumeList[0].flags |= EF_GOTONEXTVOLUME; // Blood hard codes its skill names, so we have to define them manually. if (isBlood()) { diff --git a/source/core/mapinfo.cpp b/source/core/mapinfo.cpp index 609081f7f..3f23bca6c 100644 --- a/source/core/mapinfo.cpp +++ b/source/core/mapinfo.cpp @@ -41,30 +41,28 @@ #include "raze_sound.h" FString gSkillNames[MAXSKILLS]; -FString gVolumeNames[MAXVOLUMES]; -FString gVolumeSubtitles[MAXVOLUMES]; -int32_t gVolumeFlags[MAXVOLUMES]; int gDefaultVolume = 0, gDefaultSkill = 1; -MapRecord mapList[512]; // Due to how this gets used it needs to be static. EDuke defines 7 episode plus one spare episode with 64 potential levels each and relies on the static array which is freely accessible by scripts. -MapRecord *currentLevel; // level that is currently played. (The real level, not what script hacks modfifying the current level index can pretend.) +GlobalCutscenes globalCutscenes; +VolumeRecord volumeList[MAXVOLUMES]; +TArray mapList; +MapRecord *currentLevel; // level that is currently played. MapRecord* lastLevel; // Same here, for the last level. -unsigned int numUsedSlots; CCMD(listmaps) { - for (unsigned int i = 0; i < numUsedSlots; i++) + for (auto& map : mapList) { - int lump = fileSystem.FindFile(mapList[i].fileName); + int lump = fileSystem.FindFile(map.fileName); if (lump >= 0) { int rfnum = fileSystem.GetFileContainer(lump); - Printf("%s - %s (%s)\n", mapList[i].fileName.GetChars(), mapList[i].DisplayName(), fileSystem.GetResourceFileName(rfnum)); + Printf("%s - %s (%s)\n", map.fileName.GetChars(), map.DisplayName(), fileSystem.GetResourceFileName(rfnum)); } else { - Printf("%s - %s (defined but does not exist)\n", mapList[i].fileName.GetChars(), mapList[i].DisplayName()); + Printf("%s - %s (defined but does not exist)\n", map.fileName.GetChars(), map.DisplayName()); } } } @@ -72,9 +70,8 @@ CCMD(listmaps) MapRecord *FindMapByName(const char *nm) { - for (unsigned i = 0; i < numUsedSlots; i++) + for (auto& map : mapList) { - auto &map = mapList[i]; if (map.labelName.CompareNoCase(nm) == 0) { return ↦ @@ -86,9 +83,8 @@ MapRecord *FindMapByName(const char *nm) MapRecord *FindMapByLevelNum(int num) { - for (unsigned i = 0; i < numUsedSlots; i++) + for (auto& map : mapList) { - auto &map = mapList[i]; if (map.levelNumber == num) { return ↦ @@ -142,15 +138,14 @@ bool SetMusicForMap(const char* mapname, const char* music, bool namehack) MapRecord *AllocateMap() { - return &mapList[numUsedSlots++]; + return &mapList[mapList.Reserve(1)]; } MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic) { - for (unsigned i = 0; i < numUsedSlots; i++) + for (auto& map : mapList) { - auto &map = mapList[i]; if (map.fileName.CompareNoCase(boardfilename) == 0) { return ↦ diff --git a/source/core/mapinfo.h b/source/core/mapinfo.h index 9a1e0050d..8b09db4ce 100644 --- a/source/core/mapinfo.h +++ b/source/core/mapinfo.h @@ -18,13 +18,11 @@ enum EMax enum EVolFlags { EF_HIDEFROMSP = 1, + EF_GOTONEXTVOLUME = 2, // for RR which continues the game in the next volume }; // These get filled in by the map definition parsers of the front ends. extern FString gSkillNames[MAXSKILLS]; -extern FString gVolumeNames[MAXVOLUMES]; -extern FString gVolumeSubtitles[MAXVOLUMES]; -extern int32_t gVolumeFlags[MAXVOLUMES]; extern int gDefaultVolume, gDefaultSkill; @@ -46,6 +44,42 @@ enum { MAX_MESSAGES = 32 }; +// Cutscene rules for maps are as follows: +// * when an episode is started, the episode intro will play, if none is defined, the map's intro will play. +// * when an episde is ended, the episode outro will play after the summary screen. +// * when a map ends, its own outro scene will play before the summary screen, if none is defined, use the default map outro handler. +// * when a new map starts after the summary screen, its own intro scene will play, if none is defined, use the default map intro handler. +// * setting any of these fields to 'none' will override any default and play nothing, even if a default is set. +class DObject; + +struct CutsceneDef +{ + FString video; + FString function; + int sound = 0; + int framespersec = 0; // only relevant for ANM. + + void Create(DObject* runner); +}; + +struct GlobalCutscenes +{ + CutsceneDef Intro; + CutsceneDef DefaultMapIntro; + CutsceneDef DefaultMapOutro; + FString MPSummaryScreen; + FString SummaryScreen; +}; + +struct VolumeRecord +{ + FString name; + FString subtitle; + CutsceneDef intro; + CutsceneDef outro; + int32_t flags = 0; +}; + struct MapRecord { int parTime = 0; @@ -54,6 +88,8 @@ struct MapRecord FString labelName; FString name; FString music; + CutsceneDef intro; + CutsceneDef outro; int cdSongId = -1; int flags = 0; int levelNumber = -1; @@ -101,8 +137,8 @@ struct MapRecord }; - -extern MapRecord mapList[512]; +extern GlobalCutscenes globalCutscenes; +extern VolumeRecord volumeList[MAXVOLUMES]; extern MapRecord *currentLevel; bool SetMusicForMap(const char* mapname, const char* music, bool namehack = false); diff --git a/source/core/menu/razemenu.cpp b/source/core/menu/razemenu.cpp index ddbf0be9e..89f8857cc 100644 --- a/source/core/menu/razemenu.cpp +++ b/source/core/menu/razemenu.cpp @@ -121,7 +121,7 @@ bool M_SetSpecialMenu(FName& menu, int param) if (gi->StartGame(NewGameStartupInfo)) { M_ClearMenus(); - STAT_StartNewGame(gVolumeNames[NewGameStartupInfo.Episode], NewGameStartupInfo.Skill); + STAT_StartNewGame(volumeList[NewGameStartupInfo.Episode].name, NewGameStartupInfo.Skill); inputState.ClearAllInput(); } return false; @@ -387,20 +387,21 @@ static void BuildEpisodeMenu() for (int i = 0; i < MAXVOLUMES; i++) { - if (gVolumeNames[i].IsNotEmpty() && !(gVolumeFlags[i] & EF_HIDEFROMSP)) + auto& vol = volumeList[i]; + if (vol.name.IsNotEmpty() && !(vol.flags & EF_HIDEFROMSP)) { int isShareware = ((g_gameType & GAMEFLAG_DUKE) && (g_gameType & GAMEFLAG_SHAREWARE) && i > 0); - auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing, gVolumeNames[i][0], - gVolumeNames[i], ld->mFont, CR_UNTRANSLATED, isShareware, NAME_Skillmenu, i); // font colors are not used, so hijack one for the shareware flag. + auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing, vol.name[0], + vol.name, ld->mFont, CR_UNTRANSLATED, isShareware, NAME_Skillmenu, i); // font colors are not used, so hijack one for the shareware flag. y += ld->mLinespacing; ld->mItems.Push(it); addedVolumes++; - if (gVolumeSubtitles[i].IsNotEmpty()) + if (vol.subtitle.IsNotEmpty()) { auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing * 6 / 10, 1, - gVolumeSubtitles[i], SmallFont, CR_GRAY, false, NAME_None, i); + vol.subtitle, SmallFont, CR_GRAY, false, NAME_None, i); y += ld->mLinespacing * 6 / 10; ld->mItems.Push(it); textadded = true; diff --git a/source/core/parsefuncs.h b/source/core/parsefuncs.h index 05b3aa87b..5c23b6e02 100644 --- a/source/core/parsefuncs.h +++ b/source/core/parsefuncs.h @@ -35,7 +35,6 @@ ** */ - void parseAnimTileRange(FScanner& sc, FScriptPosition& pos) { SetAnim set; @@ -46,3 +45,90 @@ void parseAnimTileRange(FScanner& sc, FScriptPosition& pos) processSetAnim("animtilerange", pos, set); } +//=========================================================================== +// +// +// +//=========================================================================== + +static void parseCutscene(FScanner& sc, CutsceneDef& cdef) +{ + FScanner::SavedPos eblockend; + + if (sc.StartBraces(&eblockend)) return; + FString sound; + while (!sc.FoundEndBrace(eblockend)) + { + sc.MustGetString(); + if (sc.Compare("video")) { sc.GetString(cdef.video); cdef.function = ""; } + else if (sc.Compare("function")) { sc.GetString(cdef.function); cdef.video = ""; } + else if (sc.Compare("sound")) sc.GetString(sound); + else if (sc.Compare("clear")) { cdef.function = "none"; cdef.video = ""; } // this means 'play nothing', not 'not defined'. + } + if (sound.IsNotEmpty()) + { + + } +} + +void parseDefineCutscene(FScanner& sc, FScriptPosition& pos) +{ + int scenenum = -1; + + if (!sc.GetString()) return; + + if (sc.Compare("intro")) + { + parseCutscene(sc, globalCutscenes.Intro); + } + if (sc.Compare("mapintro")) // sets the global default for a map entry handler. + { + parseCutscene(sc, globalCutscenes.DefaultMapIntro); + } + if (sc.Compare("mapoutro")) // sets the global default for a map exit handler. + { + parseCutscene(sc, globalCutscenes.DefaultMapOutro); + } + else if (sc.Compare("episode")) + { + FScanner::SavedPos eblockend; + sc.MustGetNumber(); + if (sc.Number < 1 || sc.Number > MAXVOLUMES) + { + sc.ScriptError("episode number %d out of range. Must be positive", sc.Number); + return; + } + int vol = sc.Number - 1; + + if (sc.StartBraces(&eblockend)) return; + while (!sc.FoundEndBrace(eblockend)) + { + sc.MustGetString(); + if (sc.Compare("intro")) parseCutscene(sc, volumeList[vol].intro); + else if (sc.Compare("outro")) parseCutscene(sc, volumeList[vol].outro); + else if (sc.Compare("flags")) sc.GetNumber(volumeList[vol].flags); + } + } + else if (sc.Compare("map")) + { + FScanner::SavedPos eblockend; + sc.MustGetString(); + auto maprec = FindMapByName(sc.String); + if (!maprec) + { + sc.ScriptError("%s: map not found", sc.String); + return; + } + if (sc.StartBraces(&eblockend)) return; + while (!sc.FoundEndBrace(eblockend)) + { + sc.MustGetString(); + if (sc.Compare("intro")) parseCutscene(sc, maprec->intro); + else if (sc.Compare("outro")) parseCutscene(sc, maprec->outro); + } + } + else if (sc.Compare("summary")) sc.GetString(globalCutscenes.SummaryScreen); + else if (sc.Compare("mpsummary")) sc.GetString(globalCutscenes.MPSummaryScreen); + +} + diff --git a/source/core/statusbar2.cpp b/source/core/statusbar2.cpp index 7ba06d80a..a4b9f68e8 100644 --- a/source/core/statusbar2.cpp +++ b/source/core/statusbar2.cpp @@ -240,7 +240,7 @@ void DBaseStatusBar::PrintAutomapInfo(FLevelStats& stats, bool forcetextfont) { y = 200 - stats.screenbottomspace - spacing; } - const auto &volname = gVolumeNames[volfromlevelnum(lev->levelNumber)]; + const auto &volname = volumeList[volfromlevelnum(lev->levelNumber)].name; if (volname.IsEmpty() && am_nameontop) y = 1; DrawText(twod, stats.font, stats.standardColor, 2 * hud_statscale, y, mapname, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, diff --git a/source/games/blood/src/credits.cpp b/source/games/blood/src/credits.cpp index 43f30c6d4..2fa3fa12c 100644 --- a/source/games/blood/src/credits.cpp +++ b/source/games/blood/src/credits.cpp @@ -144,7 +144,7 @@ void levelPlayIntroScene(int nEpisode, CompletionFunc completion) ambKillAll(); seqKillAll(); EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode]; - playSmk(pEpisode->cutsceneAName, pEpisode->cutsceneASound, pEpisode->at9028, completion); + playSmk(pEpisode->cutsceneAName, pEpisode->cutsceneASound, pEpisode->cutsceneAWave, completion); } void levelPlayEndScene(int nEpisode, CompletionFunc completion) @@ -156,7 +156,7 @@ void levelPlayEndScene(int nEpisode, CompletionFunc completion) ambKillAll(); seqKillAll(); EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode]; - playSmk(pEpisode->cutsceneBName, pEpisode->cutsceneBSound, pEpisode->at902c, completion); + playSmk(pEpisode->cutsceneBName, pEpisode->cutsceneBSound, pEpisode->cutsceneBWave, completion); } diff --git a/source/games/blood/src/levels.cpp b/source/games/blood/src/levels.cpp index 34f1c6d40..21286c08a 100644 --- a/source/games/blood/src/levels.cpp +++ b/source/games/blood/src/levels.cpp @@ -157,16 +157,16 @@ void levelLoadDefaults(void) break; EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[i]; auto ep_str = BloodINI->GetKeyString(buffer, "Title", buffer); - gVolumeNames[i] = ep_str; // only keep one table for the names. Todo: Consolidate this across games. + volumeList[i].name = ep_str; strncpy(pEpisodeInfo->cutsceneAName, BloodINI->GetKeyString(buffer, "CutSceneA", ""), BMAX_PATH); - pEpisodeInfo->at9028 = BloodINI->GetKeyInt(buffer, "CutWavA", -1); - if (pEpisodeInfo->at9028 == 0) + pEpisodeInfo->cutsceneAWave = BloodINI->GetKeyInt(buffer, "CutWavA", -1); + if (pEpisodeInfo->cutsceneAWave == 0) strncpy(pEpisodeInfo->cutsceneASound, BloodINI->GetKeyString(buffer, "CutWavA", ""), BMAX_PATH); else pEpisodeInfo->cutsceneASound[0] = 0; strncpy(pEpisodeInfo->cutsceneBName, BloodINI->GetKeyString(buffer, "CutSceneB", ""), BMAX_PATH); - pEpisodeInfo->at902c = BloodINI->GetKeyInt(buffer, "CutWavB", -1); - if (pEpisodeInfo->at902c == 0) + pEpisodeInfo->cutsceneBWave = BloodINI->GetKeyInt(buffer, "CutWavB", -1); + if (pEpisodeInfo->cutsceneBWave == 0) strncpy(pEpisodeInfo->cutsceneBSound, BloodINI->GetKeyString(buffer, "CutWavB", ""), BMAX_PATH); else pEpisodeInfo->cutsceneBSound[0] = 0; diff --git a/source/games/blood/src/levels.h b/source/games/blood/src/levels.h index 27d65964d..eb707c396 100644 --- a/source/games/blood/src/levels.h +++ b/source/games/blood/src/levels.h @@ -79,8 +79,8 @@ struct EPISODEINFO unsigned int cutALevel : 4; char cutsceneAName[BMAX_PATH]; char cutsceneBName[BMAX_PATH]; - int at9028; - int at902c; + int cutsceneAWave; + int cutsceneBWave; char cutsceneASound[BMAX_PATH]; char cutsceneBSound[BMAX_PATH]; }; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 1785fabce..9beaf03eb 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -233,6 +233,7 @@ void PlayerColorChanged(void); bool movementBlocked(player_struct *p); void loadcons(); void recordoldspritepos(); +void FixMapinfo(); int* animateptr(int i); diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index da5c038cf..8e580c9f0 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -325,6 +325,7 @@ void GameInterface::app_init() screenpeek = myconnectindex; LoadDefinitions(); + FixMapinfo(); // Add some corrections. Can only be done after .def has been parsed. fi.InitFonts(); SetTileNames(); TileFiles.SetBackup(); diff --git a/source/games/duke/src/gamedef.cpp b/source/games/duke/src/gamedef.cpp index 830e83496..687d3dca6 100644 --- a/source/games/duke/src/gamedef.cpp +++ b/source/games/duke/src/gamedef.cpp @@ -1658,7 +1658,7 @@ int ConCompiler::parsecommand() textptr++, i++; } parsebuffer.Push(0); - gVolumeNames[j] = FStringTable::MakeMacro(parsebuffer.Data(), i); + volumeList[j].name = FStringTable::MakeMacro(parsebuffer.Data(), i); return 0; case concmd_defineskillname: popscriptvalue(); @@ -3206,8 +3206,16 @@ void loadcons() InitGameVarPointers(); ResetSystemDefaults(); S_WorldTourMappingsForOldSounds(); // create a sound mapping for World Tour. + S_CacheAllSounds(); + comp.setmusic(); +} + +void FixMapinfo() +{ + // todo: export this to proper map definition features. if (isWorldTour()) { + // fix broken secret exit in WT's super secret map. int num = fileSystem.CheckNumForName("e1l7.map"); int file = fileSystem.GetFileContainer(num); if (file <= fileSystem.GetMaxIwadNum()) @@ -3216,35 +3224,36 @@ void loadcons() if (maprec) maprec->nextLevel = levelnum(0, 4); } } - else if (isRRRA()) - { - // RRRA goes directly to the second episode after E1L7 to continue the game. - int num = fileSystem.CheckNumForName("e1l7.map"); - int file = fileSystem.GetFileContainer(num); - if (file <= fileSystem.GetMaxIwadNum()) - { - auto maprec = FindMapByName("e1l7"); - if (maprec) maprec->nextLevel = levelnum(1, 0); - } - } else if (isRR()) { - // RR does not define its final level and crudely hacked it into the progression. This puts it into the E2L8 slot so that the game can naturally progress there. - auto maprec1 = FindMapByLevelNum(levelnum(1, 6)); - auto maprec2 = FindMapByLevelNum(levelnum(1, 7)); - auto maprec3 = FindMapByName("endgame"); - int num3 = fileSystem.FindFile("endgame.map"); - if (maprec1 && !maprec2 && !maprec3 && num3 >= 0) + if (volumeList[0].flags & EF_GOTONEXTVOLUME) { - auto maprec = AllocateMap(); - maprec->designerTime = 0; - maprec->parTime = 0; - maprec->SetFileName("endgame.map"); - maprec->SetName("$TXT_CLOSEENCOUNTERS"); - maprec->levelNumber = levelnum(1, 7); + // RR goes directly to the second episode after E1L7 to continue the game. + auto maprec1 = FindMapByLevelNum(levelnum(0, 6)); // E1L7 must exist + auto maprec2 = FindMapByLevelNum(levelnum(0, 7)); // E1L8 must not exist + if (maprec1 && !maprec2) + { + maprec1->nextLevel = levelnum(1, 0); + } + } + if (!isRRRA()) + { + // RR does not define its final level and crudely hacked it into the progression. This puts it into the E2L8 slot so that the game can naturally progress there. + auto maprec1 = FindMapByLevelNum(levelnum(1, 6)); // E2L7 must exist + auto maprec2 = FindMapByLevelNum(levelnum(1, 7)); // E2L8 must not exist + auto maprec3 = FindMapByName("endgame"); // endgame must not have a map record already + int num3 = fileSystem.FindFile("endgame.map"); // endgame.map must exist. + if (maprec1 && !maprec2 && !maprec3 && num3 >= 0) + { + auto maprec = AllocateMap(); + maprec->designerTime = 0; + maprec->parTime = 0; + maprec->SetFileName("endgame.map"); + maprec->SetName("$TXT_CLOSEENCOUNTERS"); + maprec->levelNumber = levelnum(1, 7); + } } } - comp.setmusic(); } END_DUKE_NS diff --git a/source/games/sw/src/scrip2.cpp b/source/games/sw/src/scrip2.cpp index 30774a115..c6be81a83 100644 --- a/source/games/sw/src/scrip2.cpp +++ b/source/games/sw/src/scrip2.cpp @@ -523,13 +523,13 @@ void LoadCustomInfoFromScript(const char *filename) case CM_TITLE: { sc.MustGetString(); - if (curep != -1) gVolumeNames[curep] = sc.String; + if (curep != -1) volumeList[curep].name = sc.String; break; } case CM_SUBTITLE: { sc.MustGetString(); - if (curep != -1) gVolumeSubtitles[curep] = sc.String; + if (curep != -1) volumeList[curep].subtitle = sc.String; break; } default: From 021f1b7832f5f761b83d9715b3332d8bca397428 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 02:00:40 +0200 Subject: [PATCH 27/86] - make SummaryInfo a struct instead of passing a list of values to the script classes. --- source/common/scripting/backend/codegen.cpp | 2 +- source/core/gamecontrol.cpp | 9 +++++++ source/core/mapinfo.h | 12 ++++++++++ .../static/zscript/games/duke/ui/cutscenes.zs | 24 +++++++++++-------- .../static/zscript/games/duke/ui/screens.zs | 24 +++++++++---------- wadsrc/static/zscript/razebase.zs | 11 +++++++++ wadsrc/static/zscript/screenjob.zs | 15 +++--------- 7 files changed, 62 insertions(+), 35 deletions(-) diff --git a/source/common/scripting/backend/codegen.cpp b/source/common/scripting/backend/codegen.cpp index f6f52f0bc..eaafaba98 100644 --- a/source/common/scripting/backend/codegen.cpp +++ b/source/common/scripting/backend/codegen.cpp @@ -8706,7 +8706,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) bool writable; ArgList[i] = ArgList[i]->Resolve(ctx); // must be resolved before the address is requested. - if (ArgList[i]->ValueType->isRealPointer()) + if (ArgList[i] && ArgList[i]->ValueType->isRealPointer()) { auto pointedType = ArgList[i]->ValueType->toPointer()->PointedType; if (pointedType && pointedType->isDynArray()) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 3f1778cea..396abc5de 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1501,3 +1501,12 @@ DEFINE_FIELD_X(MapRecord, MapRecord, nextLevel) DEFINE_FIELD_X(MapRecord, MapRecord, nextSecret) //native readonly String messages[MAX_MESSAGES]; DEFINE_FIELD_X(MapRecord, MapRecord, author) + +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, kills) +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, maxkills) +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, secrets) +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, maxsecrets) +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, supersecrets) +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, time) +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, cheated) +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, endofgame) diff --git a/source/core/mapinfo.h b/source/core/mapinfo.h index 8b09db4ce..039d3d264 100644 --- a/source/core/mapinfo.h +++ b/source/core/mapinfo.h @@ -137,6 +137,18 @@ struct MapRecord }; +struct SummaryInfo +{ + int kills; + int maxkills; + int secrets; + int maxsecrets; + int supersecrets; + int time; + bool cheated; + bool endofgame; +}; + extern GlobalCutscenes globalCutscenes; extern VolumeRecord volumeList[MAXVOLUMES]; extern MapRecord *currentLevel; diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index df0c93413..d8592bdd3 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -26,7 +26,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms */ //------------------------------------------------------------------------- -class DukeCutscenes +struct DukeCutscenes { //--------------------------------------------------------------------------- // @@ -171,7 +171,7 @@ class DukeCutscenes // //--------------------------------------------------------------------------- - static void BuildE4Intro(ScreenJobRunner runner, MapRecord map) + static void BuildE4Intro(ScreenJobRunner runner) { Array soundinfo; @@ -214,10 +214,10 @@ class DukeCutscenes // //--------------------------------------------------------------------------- - static void BuildSPSummary(ScreenJobRunner runner, MapRecord map, int kills_, int maxkills_, int secrets_, int maxsecrets_, int supersecrets_, int time_, bool cheated) + static void BuildSPSummary(ScreenJobRunner runner, MapRecord map, SummaryInfo stats) { let screen = SummaryScreenBase(new("DukeLevelSummaryScreen").Init()); - if (screen) screen.SetParameters(map, kills_, maxkills_, secrets_, maxsecrets_, supersecrets_, time_, cheated); + if (screen) screen.SetParameters(map, stats); runner.Append(screen); } @@ -260,7 +260,7 @@ class DukeCutscenes } -class RRCutscenes +struct RRCutscenes { //--------------------------------------------------------------------------- @@ -275,6 +275,7 @@ class RRCutscenes { if (!Raze.isRRRA()) { + Array soundinfo; soundinfo.Pushv(1, RRSnd.URANUS + 1); runner.Append(MoviePlayerJob.CreateWithSoundinfo("rr_intro.anm", soundinfo, 0, 9, 9, 9)); @@ -286,7 +287,7 @@ class RRCutscenes } else { - runner.Append(MoviePlayerJob.Create("redint.mve"), 0); + runner.Append(MoviePlayerJob.Create("redint.mve", 0)); } } } @@ -300,6 +301,7 @@ class RRCutscenes static void BuildE1End(ScreenJobRunner runner) { + Array soundinfo; soundinfo.Pushv(1, RRSnd.CHKAMMO + 1); runner.Append(MoviePlayerJob.CreateWithSoundinfo("turdmov.anm", soundinfo, 0, 9, 9, 9)); } @@ -313,6 +315,7 @@ class RRCutscenes static void BuildE2End(ScreenJobRunner runner) { + Array soundinfo; soundinfo.Pushv(1, RRSnd.LN_FINAL + 1); runner.Append(MoviePlayerJob.CreateWithSoundinfo("rr_outro.anm", soundinfo, 0, 9, 9, 9)); runner.Append(ImageScreen.CreateNamed("TENSCREEN")); @@ -335,11 +338,12 @@ class RRCutscenes // //--------------------------------------------------------------------------- - static void BuildSPSummary(ScreenJobRunner runner, MapRecord map, int kills_, int maxkills_, int secrets_, int maxsecrets_, int supersecrets_, int time_, bool cheated) + static void BuildSPSummary(ScreenJobRunner runner, MapRecord map, SummaryInfo stats) { - let screen = SummaryScreenBase(new("RRLevelSummaryScreen").Init(!isRRRA() || map.flags & MapRecord.FORCEEOG)); - if (screen) screen.SetParameters(map, kills_, maxkills_, secrets_, maxsecrets_, supersecrets_, time_, cheated); - runner.Append(screen); + let sumscreen = new("RRLevelSummaryScreen").Init(!Raze.isRRRA() || stats.endOfGame); + let sumscreens = SummaryScreenBase(sumscreen); + if (sumscreens) sumscreens.SetParameters(map, stats); + runner.Append(sumscreen); } //--------------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/games/duke/ui/screens.zs b/wadsrc/static/zscript/games/duke/ui/screens.zs index 6bf32bbb8..2fa3743c9 100644 --- a/wadsrc/static/zscript/games/duke/ui/screens.zs +++ b/wadsrc/static/zscript/games/duke/ui/screens.zs @@ -683,7 +683,7 @@ class DukeLevelSummaryScreen : SummaryScreenBase if (displaystate & printTimeVal) { - tempbuf = FormatTime(playtime); + tempbuf = FormatTime(stats.time); Duke.GameText((320 >> 2) + 71, 59 + 9, tempbuf, 0); tempbuf = FormatTime(level.parTime); @@ -705,16 +705,16 @@ class DukeLevelSummaryScreen : SummaryScreenBase if (displaystate & printKillsVal) { - tempbuf = String.Format("%-3d", kills); + tempbuf = String.Format("%-3d", stats.kills); Duke.GameText((320 >> 2) + 70, 94 + 9, tempbuf, 0); - if (maxkills < 0) + if (stats.maxkills < 0) { tempbuf = "$TXT_N_A"; } else { - tempbuf = String.Format("%-3d", max(0, maxkills - kills)); + tempbuf = String.Format("%-3d", max(0, stats.maxkills - stats.kills)); } Duke.GameText((320 >> 2) + 70, 104 + 9, tempbuf, 0); } @@ -728,9 +728,9 @@ class DukeLevelSummaryScreen : SummaryScreenBase if (displaystate & printSecretsVal) { - tempbuf = String.Format("%-3d", secrets); + tempbuf = String.Format("%-3d", stats.secrets); Duke.GameText((320 >> 2) + 70, 119 + 9, tempbuf, 0); - tempbuf = String.Format("%-3d", max(0, maxsecrets - secrets)); + tempbuf = String.Format("%-3d", max(0, stats.maxsecrets - stats.secrets)); Duke.GameText((320 >> 2) + 70, 129 + 9, tempbuf, 0); } } @@ -918,7 +918,7 @@ class RRLevelSummaryScreen : SummaryScreenBase if (displaystate & printTimeVal) { - tempbuf = FormatTime(playtime); + tempbuf = FormatTime(stats.time); Duke.BigText(191, 48, tempbuf, -1); tempbuf = FormatTime(level.parTime); @@ -937,15 +937,15 @@ class RRLevelSummaryScreen : SummaryScreenBase if (displaystate & printKillsVal) { - tempbuf.Format("%-3d", kills); + tempbuf.Format("%-3d", stats.kills); Duke.BigText(231, 112, tempbuf, -1); - if (maxkills < 0) + if (stats.maxkills < 0) { tempbuf = "$TXT_N_A"; } else { - tempbuf = String.Format("%-3d", max(0, maxkills - kills)); + tempbuf = String.Format("%-3d", max(0, stats.maxkills - stats.kills)); } Duke.BigText(231, 128, tempbuf, -1); } @@ -959,9 +959,9 @@ class RRLevelSummaryScreen : SummaryScreenBase if (displaystate & printSecretsVal) { - tempbuf = String.Format("%-3d", secrets); + tempbuf = String.Format("%-3d", stats.secrets); Duke.BigText(231, 144, tempbuf, -1); - tempbuf = String.Format("%-3d", max(0, maxsecrets - secrets)); + tempbuf = String.Format("%-3d", max(0, stats.maxsecrets - stats.secrets)); Duke.BigText(231, 160, tempbuf, -1); } } diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index a7dcd3254..6346a4e7a 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -87,6 +87,17 @@ struct MapRecord native } } +struct SummaryInfo native +{ + native readonly int kills; + native readonly int maxkills; + native readonly int secrets; + native readonly int maxsecrets; + native readonly int supersecrets; + native readonly int time; + native readonly bool cheated; + native readonly bool endofgame; +} struct Raze { diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index e41f62dab..8ae6e6f3a 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -198,21 +198,12 @@ class ImageScreen : SkippableScreenJob class SummaryScreenBase : ScreenJob { MapRecord level; - int kills, maxkills; - int secrets, maxsecrets, supersecrets; - int playtime; - bool cheatflag; + SummaryInfo stats; - void SetParameters(MapRecord map, int kills_, int maxkills_, int secrets_, int maxsecrets_, int supersecrets_, int time_, bool cheated) + void SetParameters(MapRecord map, SummaryInfo thestats) { level = map; - kills = kills_; - maxkills = maxkills_; - secrets = secrets_; - maxsecrets = maxsecrets_; - supersecrets = supersecrets_; - playtime = time_; - cheatflag = cheated; + stats = thestats; } String FormatTime(int time) From ef6d8c2c674f87e432b483a136a9dd8252db07fe Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 19:16:45 +0200 Subject: [PATCH 28/86] - added cutscene definitions for Duke and finalized the definecutscene parser. --- source/build/src/defs.cpp | 1 + source/core/parsefuncs.h | 12 +++-- wadsrc/static/filter/duke/engine/engine.def | 53 +++++++++++++++++++ .../static/zscript/games/duke/ui/cutscenes.zs | 1 + 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 wadsrc/static/filter/duke/engine/engine.def diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index b629626be..732dd6c41 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -17,6 +17,7 @@ #include "gamecontrol.h" #include "palettecontainer.h" #include "mapinfo.h" +#include "s_soundinternal.h" #include "parsefuncs.h" int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags); diff --git a/source/core/parsefuncs.h b/source/core/parsefuncs.h index 5c23b6e02..778ea2532 100644 --- a/source/core/parsefuncs.h +++ b/source/core/parsefuncs.h @@ -67,7 +67,13 @@ static void parseCutscene(FScanner& sc, CutsceneDef& cdef) } if (sound.IsNotEmpty()) { - + cdef.sound = soundEngine->FindSound(sound); + if (cdef.sound == 0) + { + int lump = fileSystem.FindFile(sound); + if (lump < 0) return; + cdef.sound = FSoundID(soundEngine->AddSoundLump(sound, lump, 0)); + } } } @@ -81,11 +87,11 @@ void parseDefineCutscene(FScanner& sc, FScriptPosition& pos) { parseCutscene(sc, globalCutscenes.Intro); } - if (sc.Compare("mapintro")) // sets the global default for a map entry handler. + else if (sc.Compare("mapintro")) // sets the global default for a map entry handler. { parseCutscene(sc, globalCutscenes.DefaultMapIntro); } - if (sc.Compare("mapoutro")) // sets the global default for a map exit handler. + else if (sc.Compare("mapoutro")) // sets the global default for a map exit handler. { parseCutscene(sc, globalCutscenes.DefaultMapOutro); } diff --git a/wadsrc/static/filter/duke/engine/engine.def b/wadsrc/static/filter/duke/engine/engine.def new file mode 100644 index 000000000..8adfcea29 --- /dev/null +++ b/wadsrc/static/filter/duke/engine/engine.def @@ -0,0 +1,53 @@ +// Cutscene definitions for Duke + +definecutscene intro +{ + function DukeCutscenes.BuildIntro +} + +definecutscene episode 1 +{ + outro + { + function DukeCutscenes.BuildE1End + } +} + +definecutscene episode 2 +{ + outro + { + function DukeCutscenes.BuildE2End + } +} + +definecutscene episode 3 +{ + outro + { + function DukeCutscenes.BuildE3End + } +} + +definecutscene episode 4 +{ + intro + { + function DukeCutscenes.BuildE4Intro + } + outro + { + function DukeCutscenes.BuildE4End + } +} + +definecutscene episode 5 +{ + outro + { + function DukeCutscenes.BuildE5End + } +} + +definecutscene summary DukeCutscenes.BuildSPSummary +definecutscene mpsummary DukeCutscenes.BuildMPSummary diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index d8592bdd3..ed90b8149 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -354,6 +354,7 @@ struct RRCutscenes static void BuildMapIntro(ScreenJobRunner runner, MapRecord map) { + if (!raze.isRRRA()) return; int ln = map.levelnumber; if (ln == 0) return; if (ln > 1000) ln -= 1000-7; From af8d06994a34cafb4779afc4dd6dd7277a644345 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 21:13:11 +0200 Subject: [PATCH 29/86] - implemented the scripting interface layer. --- source/common/engine/namedef.h | 2 +- source/core/gamecontrol.cpp | 1 + source/core/mainloop.cpp | 6 +- source/core/mapinfo.h | 1 + source/core/parsefuncs.h | 1 + source/core/screenjob.cpp | 571 ++++++------------ source/core/screenjob.h | 14 +- .../static/zscript/games/duke/ui/cutscenes.zs | 37 +- wadsrc/static/zscript/razebase.zs | 1 + wadsrc/static/zscript/screenjob.zs | 15 +- 10 files changed, 226 insertions(+), 423 deletions(-) diff --git a/source/common/engine/namedef.h b/source/common/engine/namedef.h index cf8b8da62..8ec5d4081 100644 --- a/source/common/engine/namedef.h +++ b/source/common/engine/namedef.h @@ -1107,4 +1107,4 @@ xy(menu_change, "menu/change") xy(menu_advance, "menu/advance") xx(zoomsize) - +xx(ScreenJobRunner) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 396abc5de..0e2435321 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1507,6 +1507,7 @@ DEFINE_FIELD_X(SummaryInfo, SummaryInfo, maxkills) DEFINE_FIELD_X(SummaryInfo, SummaryInfo, secrets) DEFINE_FIELD_X(SummaryInfo, SummaryInfo, maxsecrets) DEFINE_FIELD_X(SummaryInfo, SummaryInfo, supersecrets) +DEFINE_FIELD_X(SummaryInfo, SummaryInfo, playercount) DEFINE_FIELD_X(SummaryInfo, SummaryInfo, time) DEFINE_FIELD_X(SummaryInfo, SummaryInfo, cheated) DEFINE_FIELD_X(SummaryInfo, SummaryInfo, endofgame) diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 7a65c950d..da2d99565 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -331,7 +331,11 @@ static void GameTicker() break; case GS_INTERMISSION: case GS_INTRO: - ScreenJobTick(); + if (ScreenJobTick()) + { + // synchronize termination with the playsim. + Net_WriteByte(DEM_ENDSCREENJOB); + } break; } diff --git a/source/core/mapinfo.h b/source/core/mapinfo.h index 039d3d264..cdd607daf 100644 --- a/source/core/mapinfo.h +++ b/source/core/mapinfo.h @@ -145,6 +145,7 @@ struct SummaryInfo int maxsecrets; int supersecrets; int time; + int playercount; bool cheated; bool endofgame; }; diff --git a/source/core/parsefuncs.h b/source/core/parsefuncs.h index 778ea2532..888df2157 100644 --- a/source/core/parsefuncs.h +++ b/source/core/parsefuncs.h @@ -63,6 +63,7 @@ static void parseCutscene(FScanner& sc, CutsceneDef& cdef) if (sc.Compare("video")) { sc.GetString(cdef.video); cdef.function = ""; } else if (sc.Compare("function")) { sc.GetString(cdef.function); cdef.video = ""; } else if (sc.Compare("sound")) sc.GetString(sound); + else if (sc.Compare("fps")) sc.GetNumber(cdef.framespersec); else if (sc.Compare("clear")) { cdef.function = "none"; cdef.video = ""; } // this means 'play nothing', not 'not defined'. } if (sound.IsNotEmpty()) diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 33de0a84e..8f8c5e342 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -52,411 +52,186 @@ #include #include "raze_music.h" #include "vm.h" +#include "mapinfo.h" +static DObject* runner; +static SummaryInfo sinfo; +static PClass* runnerclass; +static PType* runnerclasstype; +static PType* maprecordtype; +static PType* summaryinfotype; +static CompletionFunc completion; +static int ticks; -#if 0 -IMPLEMENT_CLASS(DScreenJob, true, false) -IMPLEMENT_CLASS(DSkippableScreenJob, true, false) -IMPLEMENT_CLASS(DBlackScreen, true, false) -IMPLEMENT_CLASS(DImageScreen, true, false) +//============================================================================= +// +// +// +//============================================================================= -DEFINE_FIELD(DScreenJob, flags) -DEFINE_FIELD(DScreenJob, fadetime) -DEFINE_FIELD_NAMED(DScreenJob, state, jobstate) -DEFINE_FIELD(DScreenJob, fadestate) -DEFINE_FIELD(DScreenJob, ticks) -DEFINE_FIELD(DScreenJob, pausable) - -DEFINE_FIELD(DBlackScreen, wait) -DEFINE_FIELD(DBlackScreen, cleared) - -DEFINE_FIELD(DImageScreen, tilenum) -DEFINE_FIELD(DImageScreen, trans) -DEFINE_FIELD(DImageScreen, waittime) -DEFINE_FIELD(DImageScreen, cleared) -DEFINE_FIELD(DImageScreen, texid) - -DEFINE_ACTION_FUNCTION(DScreenJob, Init) +static void Job_Init() { - // todo - return 0; -} - -DEFINE_ACTION_FUNCTION(DScreenJob, ProcessInput) -{ - PARAM_SELF_PROLOGUE(DScreenJob); - ACTION_RETURN_BOOL(self->ProcessInput()); -} - -DEFINE_ACTION_FUNCTION(DScreenJob, Start) -{ - PARAM_SELF_PROLOGUE(DScreenJob); - self->Start(); - return 0; -} - -DEFINE_ACTION_FUNCTION(DScreenJob, OnEvent) -{ - PARAM_SELF_PROLOGUE(DScreenJob); - PARAM_POINTER(evt, FInputEvent); - if (evt->Type != EV_KeyDown) + static bool done = false; + if (!done) { - // not needed in the transition phase - ACTION_RETURN_BOOL(false); + done = true; + GC::AddMarkerFunc([] { GC::Mark(runner); }); } - event_t ev = {}; - ev.type = EV_KeyDown; - ev.data1 = evt->KeyScan; - ACTION_RETURN_BOOL(self->OnEvent(&ev)); + runnerclass = PClass::FindClass("ScreenJobRunner"); + if (!runnerclass) I_FatalError("ScreenJobRunner not defined"); + runnerclasstype = NewPointer(runnerclass); + + maprecordtype = NewPointer(NewStruct("MapRecord", nullptr, true)); + summaryinfotype = NewPointer(NewStruct("SummaryInfo", nullptr, true)); } -DEFINE_ACTION_FUNCTION(DScreenJob, OnTick) +//============================================================================= +// +// +// +//============================================================================= + +static VMFunction* LookupFunction(const char* qname, bool validate = true) { - PARAM_SELF_PROLOGUE(DScreenJob); - self->OnTick(); - return 0; -} + int p = strcspn(qname, "."); + if (p == 0) I_Error("Call to undefined function %s", qname); + FString clsname(qname, p); + FString funcname = qname + p + 1; -DEFINE_ACTION_FUNCTION(DScreenJob, Draw) -{ - PARAM_SELF_PROLOGUE(DScreenJob); - PARAM_FLOAT(smooth); - self->Draw(smooth); - return 0; -} - -DEFINE_ACTION_FUNCTION(DSkippableScreenJob, Init) -{ - // todo - return 0; -} - -DEFINE_ACTION_FUNCTION(DSkippableScreenJob, Skipped) -{ - PARAM_SELF_PROLOGUE(DSkippableScreenJob); - self->Skipped(); - return 0; -} - -DEFINE_ACTION_FUNCTION(DBlackScreen, Init) -{ - // todo - return 0; -} - -DEFINE_ACTION_FUNCTION(DImageScreen, Init) -{ - // todo - return 0; -} - - - - -void DScreenJob::OnDestroy() -{ - if (flags & stopmusic) Mus_Stop(); - if (flags & stopsound) FX_StopAllSounds(); -} - -bool DSkippableScreenJob::OnEvent(event_t* evt) -{ - if (evt->type == EV_KeyDown && !specialKeyEvent(evt)) + auto func = PClass::FindFunction(clsname, funcname); + if (func == nullptr) I_Error("Call to undefined function %s", qname); + if (validate) { - state = skipped; - Skipped(); + // these conditions must be met by all functions for this interface. + if (func->Proto->ReturnTypes.Size() != 0) I_Error("Bad cutscene function %s. Return value not allowed", qname); + if (func->ImplicitArgs != 0) I_Error("Bad cutscene function %s. Must be static", qname); } - return true; + return func; } -void DBlackScreen::OnTick() +//============================================================================= +// +// +// +//============================================================================= + +void CallCreateFunction(const char* qname, DObject* runner) { - if (cleared) + auto func = LookupFunction(qname); + if (func->Proto->ArgumentTypes.Size() != 1) I_Error("Bad cutscene function %s. Must receive precisely one argument.", qname); + if (func->Proto->ArgumentTypes[0] != runnerclasstype) I_Error("Bad cutscene function %s. Must receive ScreenJobRunner reference.", qname); + VMValue val = runner; + VMCall(func, &val, 1, nullptr, 0); +} + +//============================================================================= +// +// +// +//============================================================================= + +void CallCreateMapFunction(const char* qname, DObject* runner, MapRecord* map) +{ + auto func = LookupFunction(qname); + if (func->Proto->ArgumentTypes.Size() != 2) I_Error("Bad map-cutscene function %s. Must receive precisely two arguments.", qname); + if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != maprecordtype) + I_Error("Bad cutscene function %s. Must receive ScreenJobRunner and MapRecord reference.", qname); + VMValue val[2] = { runner, map }; + VMCall(func, val, 2, nullptr, 0); +} + +//============================================================================= +// +// +// +//============================================================================= + +void CallCreateSummaryFunction(const char* qname, DObject* runner, MapRecord* map, SummaryInfo* info) +{ + auto func = LookupFunction(qname); + if (func->Proto->ArgumentTypes.Size() != 3) I_Error("Bad map-cutscene function %s. Must receive precisely three arguments.", qname); + if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != maprecordtype && func->Proto->ArgumentTypes[2] != summaryinfotype) + I_Error("Bad cutscene function %s. Must receive ScreenJobRunner, MapRecord and SummaryInfo reference.", qname); + VMValue val[3] = { runner, map, info }; + VMCall(func, val, 3, nullptr, 0); +} + +//============================================================================= +// +// +// +//============================================================================= + +DObject* CreateRunner(bool clearbefore = true) +{ + auto obj = runnerclass->CreateNew(); + auto func = LookupFunction("ScreenJobRunner.Init", false); + VMValue val[3] = { obj, clearbefore, false }; + VMCall(func, val, 3, nullptr, 0); + return obj; +} + +//============================================================================= +// +// +// +//============================================================================= + +void AddGenericVideo(DObject* runner, const FString& fn, int soundid, int fps) +{ + auto obj = runnerclass->CreateNew(); + auto func = LookupFunction("ScreenJobRunner.AddGenericVideo", false); + VMValue val[] = { runner, &fn, soundid, fps }; + VMCall(func, val, 4, nullptr, 0); +} + +//============================================================================= +// +// +// +//============================================================================= + +void CutsceneDef::Create(DObject* runner) +{ + if (function.CompareNoCase("none") != 0) { - int span = ticks * 1000 / GameTicRate; - if (span > wait) state = finished; - } -} - -void DBlackScreen::Draw(double) -{ - cleared = true; - twod->ClearScreen(); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void DImageScreen::OnTick() -{ - if (cleared) - { - int span = ticks * 1000 / GameTicRate; - if (span > waittime) state = finished; - } -} - - -void DImageScreen::Draw(double smoothratio) -{ - if (tilenum > 0) tex = tileGetTexture(tilenum, true); - twod->ClearScreen(); - if (tex) DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, DTA_TranslationIndex, trans, TAG_DONE); - cleared = true; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -ScreenJobRunner::ScreenJobRunner(TArray& jobs_, CompletionFunc completion_, bool clearbefore_, bool skipall_) - : completion(std::move(completion_)), clearbefore(clearbefore_), skipall(skipall_) -{ - jobs = std::move(jobs_); - // Release all jobs from the garbage collector - the code as it is cannot deal with them getting collected. This should be removed later once the GC is working. - for (unsigned i = 0; i < jobs.Size(); i++) - { - jobs[i]->Release(); - } - AdvanceJob(false); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -ScreenJobRunner::~ScreenJobRunner() -{ - DeleteJobs(); -} - -void ScreenJobRunner::DeleteJobs() -{ - for (auto& job : jobs) - { - job->ObjectFlags |= OF_YesReallyDelete; - delete job; - } - jobs.Clear(); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void ScreenJobRunner::AdvanceJob(bool skip) -{ - if (index >= 0) - { - //if (jobs[index].postAction) jobs[index].postAction(); - jobs[index]->Destroy(); - } - index++; - while (index < jobs.Size() && (jobs[index] == nullptr || (skip && skipall))) - { - if (jobs[index] != nullptr) jobs[index]->Destroy(); - index++; - } - actionState = clearbefore ? State_Clear : State_Run; - if (index < jobs.Size()) - { - jobs[index]->fadestate = !paused && jobs[index]->flags & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible; - jobs[index]->Start(); - } - inputState.ClearAllInput(); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -int ScreenJobRunner::DisplayFrame(double smoothratio) -{ - auto& job = jobs[index]; - auto now = I_GetTimeNS(); - bool processed = job->ProcessInput(); - - if (job->fadestate == DScreenJob::fadein) - { - double ms = (job->ticks + smoothratio) * 1000 / GameTicRate / job->fadetime; - float screenfade = (float)clamp(ms, 0., 1.); - twod->SetScreenFade(screenfade); - if (screenfade == 1.f) job->fadestate = DScreenJob::visible; - } - int state = job->DrawFrame(smoothratio); - twod->SetScreenFade(1.f); - return state; -} - -int ScreenJobRunner::FadeoutFrame(double smoothratio) -{ - auto& job = jobs[index]; - double ms = (fadeticks + smoothratio) * 1000 / GameTicRate / job->fadetime; - float screenfade = 1.f - (float)clamp(ms, 0., 1.); - twod->SetScreenFade(screenfade); - job->DrawFrame(1.); - return (screenfade > 0.f); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -bool ScreenJobRunner::OnEvent(event_t* ev) -{ - if (paused || index >= jobs.Size()) return false; - - if (jobs[index]->state != DScreenJob::running) return false; - - return jobs[index]->OnEvent(ev); -} - -void ScreenJobRunner::OnFinished() -{ - if (completion) completion(false); - completion = nullptr; // only finish once. -} - -void ScreenJobRunner::OnTick() -{ - if (paused) return; - if (index >= jobs.Size()) - { - //DeleteJobs(); - //twod->SetScreenFade(1); - //twod->ClearScreen(); // This must not leave the 2d buffer empty. - //if (gamestate == GS_INTRO) OnFinished(); - //else Net_WriteByte(DEM_ENDSCREENJOB); // intermissions must be terminated synchronously. - } - else - { - if (jobs[index]->state == DScreenJob::running) + if (function.IsNotEmpty()) { - jobs[index]->ticks++; - jobs[index]->OnTick(); + CallCreateFunction(function, runner); } - else if (jobs[index]->state == DScreenJob::stopping) + else if (video.IsNotEmpty()) { - fadeticks++; + AddGenericVideo(runner, video, sound, framespersec); } } } - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- -bool ScreenJobRunner::RunFrame() +//============================================================================= +// +// +// +//============================================================================= + +void StartCutscene(CutsceneDef& cs, int flags, CompletionFunc completion_) { - if (index >= jobs.Size()) - { - DeleteJobs(); - twod->SetScreenFade(1); - twod->ClearScreen(); // This must not leave the 2d buffer empty. - if (completion) completion(false); - return false; - } - - // ensure that we won't go back in time if the menu is dismissed without advancing our ticker - bool menuon = paused; - if (menuon) last_paused_tic = jobs[index]->ticks; - else if (last_paused_tic == jobs[index]->ticks) menuon = true; - double smoothratio = menuon ? 1. : I_GetTimeFrac(); - - if (actionState == State_Clear) - { - actionState = State_Run; - twod->ClearScreen(); - } - else if (actionState == State_Run) - { - terminateState = DisplayFrame(smoothratio); - if (terminateState < 1) - { - // Must lock before displaying. - if (jobs[index]->flags & DScreenJob::fadeout) - { - jobs[index]->fadestate = DScreenJob::fadeout; - jobs[index]->state = DScreenJob::stopping; - actionState = State_Fadeout; - fadeticks = 0; - } - else - { - AdvanceJob(terminateState < 0); - } - } - } - else if (actionState == State_Fadeout) - { - int ended = FadeoutFrame(smoothratio); - if (ended < 1) - { - jobs[index]->state = DScreenJob::stopped; - AdvanceJob(terminateState < 0); - } - } - return true; + completion = completion_; + runner = CreateRunner(); + cs.Create(runner); + gameaction = (flags & SJ_BLOCKUI) ? ga_intro : ga_intermission; } -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -ScreenJobRunner *runner; - -#endif - - -#if 0 -void RunScreenJob(TArray& jobs, CompletionFunc completion, int flags) -{ - assert(completion != nullptr); - videoclearFade(); - if (jobs.Size()) - { - runner = new ScreenJobRunner(jobs, completion, !(flags & SJ_DONTCLEAR), !!(flags & SJ_SKIPALL)); - gameaction = (flags & SJ_BLOCKUI)? ga_intro : ga_intermission; - } - else - { - completion(false); - } -} -#endif void DeleteScreenJob() { - /* - if (runner) - { - delete runner; - runner = nullptr; - } - twod->SetScreenFade(1);*/ + runner->Destroy(); + runner = nullptr; } void EndScreenJob() { - //if (runner) runner->OnFinished(); DeleteScreenJob(); + if (completion) completion(false); + completion = nullptr; } @@ -472,33 +247,47 @@ bool ScreenJobResponder(event_t* ev) return true; } } - - //if (runner) return runner->OnEvent(ev); + FInputEvent evt = ev; + if (runner) + { + IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, OnEvent) + { + int result = 0; + VMValue parm[] = { runner, &evt }; + VMReturn ret(&result); + VMCall(func, parm, 2, &ret, 1); + return result; + } + } return false; } -void ScreenJobTick() +bool ScreenJobTick() { - //if (runner) runner->OnTick(); + ticks++; + if (runner) + { + IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, OnTick) + { + int result = 0; + VMValue parm[] = { runner }; + VMCall(func, parm, 1, nullptr, 0); + return result; + } + } + return false; } -bool ScreenJobDraw() +void ScreenJobDraw() { - // we cannot recover from this because we have no completion callback to call. - /* - if (!runner) + double smoothratio = I_GetTimeFrac(); + + if (runner) { - // We can get here before a gameaction has been processed. In that case just draw a black screen and wait. - if (gameaction == ga_nothing) I_Error("Trying to run a non-existent screen job"); - twod->ClearScreen(); - return false; + IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, RunFrame) + { + VMValue parm[] = { runner, smoothratio }; + VMCall(func, parm, 2, nullptr, 0); + } } - auto res = runner->RunFrame(); - */ int res = 0; - if (!res) - { - assert((gamestate != GS_INTERMISSION && gamestate != GS_INTRO) || gameaction != ga_nothing); - DeleteScreenJob(); - } - return res; } diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 2f5d2a6d1..91fd47c71 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -181,23 +181,17 @@ public: #endif -#if 0 enum { - SJ_DONTCLEAR = 1, - SJ_BLOCKUI = 2, - SJ_SKIPALL = 4 + SJ_BLOCKUI = 1, }; +#if 0 void RunScreenJob(TArray& jobs, CompletionFunc completion, int flags = 0); #endif void EndScreenJob(); void DeleteScreenJob(); bool ScreenJobResponder(event_t* ev); -void ScreenJobTick(); -bool ScreenJobDraw(); - -#if 0 -DScreenJob *PlayVideo(const char *filename, const AnimSound *ans = nullptr, const int *frameticks = nullptr, bool nosoundstop = false); -#endif \ No newline at end of file +bool ScreenJobTick(); +void ScreenJobDraw(); diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index ed90b8149..6c3796187 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -203,7 +203,7 @@ struct DukeCutscenes // //--------------------------------------------------------------------------- - static void BuildMPSummary(ScreenJobRunner runner, int playerswhenstarted) + static void BuildMPSummary(ScreenJobRunner runner, MapRecord map, SummaryInfo stats) { runner.Append(new("DukeMultiplayerBonusScreen").Init(playerswhenstarted)); } @@ -301,9 +301,12 @@ struct RRCutscenes static void BuildE1End(ScreenJobRunner runner) { - Array soundinfo; - soundinfo.Pushv(1, RRSnd.CHKAMMO + 1); - runner.Append(MoviePlayerJob.CreateWithSoundinfo("turdmov.anm", soundinfo, 0, 9, 9, 9)); + if (!isRRRA()) + { + Array soundinfo; + soundinfo.Pushv(1, RRSnd.CHKAMMO + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("turdmov.anm", soundinfo, 0, 9, 9, 9)); + } } @@ -315,21 +318,17 @@ struct RRCutscenes static void BuildE2End(ScreenJobRunner runner) { - Array soundinfo; - soundinfo.Pushv(1, RRSnd.LN_FINAL + 1); - runner.Append(MoviePlayerJob.CreateWithSoundinfo("rr_outro.anm", soundinfo, 0, 9, 9, 9)); - runner.Append(ImageScreen.CreateNamed("TENSCREEN")); - } - - //--------------------------------------------------------------------------- - // - // - // - //--------------------------------------------------------------------------- - - static void BuildRRRAEnd(ScreenJobRunner runner) - { - runner.Append(new("RRRAEndOfGame").Init()); + if (!isRRRA()) + { + Array soundinfo; + soundinfo.Pushv(1, RRSnd.LN_FINAL + 1); + runner.Append(MoviePlayerJob.CreateWithSoundinfo("rr_outro.anm", soundinfo, 0, 9, 9, 9)); + runner.Append(ImageScreen.CreateNamed("TENSCREEN")); + } + else + { + runner.Append(new("RRRAEndOfGame").Init()); + } } //--------------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index 6346a4e7a..c2da19342 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -95,6 +95,7 @@ struct SummaryInfo native native readonly int maxsecrets; native readonly int supersecrets; native readonly int time; + native readonly int playercount; native readonly bool cheated; native readonly bool endofgame; } diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 8ae6e6f3a..91ccba7dd 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -326,7 +326,7 @@ class ScreenJobRunner : Object int fadeticks; int last_paused_tic; - void Init(bool clearbefore_ = true, bool skipall_ = false) + void Init(bool clearbefore_, bool skipall_) { clearbefore = clearbefore_; skipall = skipall_; @@ -392,6 +392,11 @@ class ScreenJobRunner : Object virtual int DisplayFrame(double smoothratio) { + if (jobs.Size() == 0) + { + screen.ClearScreen(); + return 1; + } int x = index >= jobs.Size()? jobs.Size()-1 : index; let job = jobs[x]; bool processed = job.ProcessInput(); @@ -448,6 +453,7 @@ class ScreenJobRunner : Object virtual bool OnTick() { if (paused) return false; + if (jobs.Size() == 0) return true; if (advance) { advance = false; @@ -517,4 +523,11 @@ class ScreenJobRunner : Object } return true; } + + void AddGenericVideo(String fn, int snd, int framerate) + { + Array sounds; + if (snd > 0) sounds.Pushv(1, snd); + Append(MoviePlayerJob.CreateWithSoundInfo(fn, sounds, 0, framerate)); + } } From 1166b00af2ec3464857abb6e52698408e50dc3b5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 22:56:37 +0200 Subject: [PATCH 30/86] - switched intro movie playing over to the new system Not tested yet. --- source/core/screenjob.cpp | 75 ++++++++++++++++++++++----- source/core/screenjob.h | 3 ++ source/games/blood/src/blood.cpp | 6 +-- source/games/duke/src/2d_d.cpp | 33 ------------ source/games/duke/src/2d_r.cpp | 53 ------------------- source/games/duke/src/dispatch.cpp | 4 -- source/games/duke/src/duke3d.h | 1 - source/games/duke/src/gameloop.cpp | 3 +- source/games/exhumed/src/gameloop.cpp | 3 +- source/games/sw/src/game.cpp | 6 +-- wadsrc/static/zscript/screenjob.zs | 2 +- 11 files changed, 69 insertions(+), 120 deletions(-) diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 8f8c5e342..467b04cd0 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -193,16 +193,13 @@ void AddGenericVideo(DObject* runner, const FString& fn, int soundid, int fps) void CutsceneDef::Create(DObject* runner) { - if (function.CompareNoCase("none") != 0) + if (function.IsNotEmpty()) { - if (function.IsNotEmpty()) - { - CallCreateFunction(function, runner); - } - else if (video.IsNotEmpty()) - { - AddGenericVideo(runner, video, sound, framespersec); - } + CallCreateFunction(function, runner); + } + else if (video.IsNotEmpty()) + { + AddGenericVideo(runner, video, sound, framespersec); } } @@ -212,12 +209,17 @@ void CutsceneDef::Create(DObject* runner) // //============================================================================= -void StartCutscene(CutsceneDef& cs, int flags, CompletionFunc completion_) +bool StartCutscene(CutsceneDef& cs, int flags, CompletionFunc completion_) { - completion = completion_; - runner = CreateRunner(); - cs.Create(runner); - gameaction = (flags & SJ_BLOCKUI) ? ga_intro : ga_intermission; + if (cs.function.CompareNoCase("none") != 0) + { + completion = completion_; + runner = CreateRunner(); + cs.Create(runner); + gameaction = (flags & SJ_BLOCKUI) ? ga_intro : ga_intermission; + return true; + } + return false; } @@ -291,3 +293,48 @@ void ScreenJobDraw() } } } + + +void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic) +{ + Mus_Stop(); + FX_StopAllSounds(); // JBF 20031228 + if (userConfig.nologo) + { + gameaction = def_ga; + } + else + { + if (!StartCutscene(globalCutscenes.Intro, SJ_BLOCKUI, [=](bool) { gameaction = complete_ga; })) gameaction = def_ga; + } +} + +/* +Duke: + if (!userConfig.nologo) fi.ShowLogo([](bool) { gameaction = ga_mainmenunostopsound; }); + else gameaction = ga_mainmenunostopsound; + + +Blood: + if (!userConfig.nologo && gGameOptions.nGameType == 0) playlogos(); + else + { + gameaction = ga_mainmenu; + } + RunScreenJob(jobs, [](bool) { + Mus_Stop(); + gameaction = ga_mainmenu; + }, SJ_BLOCKUI); + +Exhumed: + if (!userConfig.nologo) DoTitle([](bool) { gameaction = ga_mainmenu; }); + else gameaction = ga_mainmenu; + +SW: + if (!userConfig.nologo) Logo([](bool) + { + gameaction = ga_mainmenunostopsound; + }); + else gameaction = ga_mainmenu; + +*/ \ No newline at end of file diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 91fd47c71..53c1e08d7 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -4,6 +4,7 @@ #include "v_2ddrawer.h" #include "d_eventbase.h" #include "s_soundinternal.h" +#include "gamestate.h" using CompletionFunc = std::function; struct JobDesc; @@ -195,3 +196,5 @@ void DeleteScreenJob(); bool ScreenJobResponder(event_t* ev); bool ScreenJobTick(); void ScreenJobDraw(); + +void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic); diff --git a/source/games/blood/src/blood.cpp b/source/games/blood/src/blood.cpp index 0c7d38cd2..f4ca01954 100644 --- a/source/games/blood/src/blood.cpp +++ b/source/games/blood/src/blood.cpp @@ -528,11 +528,7 @@ void GameInterface::Startup() } else { - if (!userConfig.nologo && gGameOptions.nGameType == 0) playlogos(); - else - { - gameaction = ga_mainmenu; - } + PlayLogos(ga_mainmenu, ga_mainmenu, true); } } diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index 3ec25ccaa..100ba4964 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -145,39 +145,6 @@ static void BigText(double x, double y, const char* text, int align = -1, double DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Alpha, alpha, TAG_DONE); } -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void Logo_d(const CompletionFunc &completion) -{ -#if 0 - Mus_Stop(); - FX_StopAllSounds(); // JBF 20031228 - - static const AnimSound logosound[] = - { - { 1, FLY_BY+1 }, - { 19, PIPEBOMB_EXPLODE+1 }, - { -1, -1 } - }; - static const int logoframetimes[] = { 9, 9, 9 }; - - TArray jobs; - int job = 0; - if (!userConfig.nologo) - { - if (!isShareware()) jobs.Push(PlayVideo("logo.anm", logosound, logoframetimes)); - if (!isNam()) jobs.Push(Create()); - } - jobs.Push(Create()); - RunScreenJob(jobs, completion, SJ_BLOCKUI); -#endif -} - - //--------------------------------------------------------------------------- // // diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index d64a0e355..7aef5a9a3 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -139,59 +139,6 @@ static void BigText(double x, double y, const char* text, int align, double alph } -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void Logo_r(const CompletionFunc& completion) -{ -#if 0 - Mus_Stop(); - FX_StopAllSounds(); // JBF 20031228 - - static const AnimSound introsound[] = - { - { 1, 29+1 }, - { -1, -1 } - }; - - static const AnimSound rednecksound[] = - { - { 1, 478+1 }, - { -1, -1 } - }; - - static const AnimSound xatrixsound[] = - { - { 1, 479+1 }, - { -1, -1 } - }; - - static const int framespeed[] = { 9, 9, 9 }; // same for all 3 anims - - TArray jobs; - - if (userConfig.nologo) - { - completion(false); - return; - } - else if (!isRRRA()) - { - jobs.Push(PlayVideo("rr_intro.anm", introsound, framespeed)); - jobs.Push(PlayVideo("redneck.anm", rednecksound, framespeed)); - jobs.Push(PlayVideo("xatlogo.anm", xatrixsound, framespeed)); - } - else - { - jobs.Push(PlayVideo("redint.mve")); - } - RunScreenJob(jobs, completion, SJ_BLOCKUI); -#endif -} - #if 0 //--------------------------------------------------------------------------- // diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index 7e9ae2675..bf5918bb0 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -105,8 +105,6 @@ void think_r(); void animatesprites_d(int x, int y, int a, int smoothratio); void animatesprites_r(int x, int y, int a, int smoothratio); -void Logo_d(const CompletionFunc&); -void Logo_r(const CompletionFunc&); void InitFonts_d(); void InitFonts_r(); void PrintPaused_d(); @@ -120,7 +118,6 @@ void SetDispatcher() if (!isRR()) { fi = { - Logo_d, InitFonts_d, PrintPaused_d, @@ -167,7 +164,6 @@ void SetDispatcher() else { fi = { - Logo_r, InitFonts_r, PrintPaused_r, diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 8628373d7..4f31aef02 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -71,7 +71,6 @@ struct GameInterface : public ::GameInterface struct Dispatcher { // global stuff - void (*ShowLogo)(const CompletionFunc& completion); void (*InitFonts)(); void (*PrintPaused)(); diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 3b5791477..2c5b20025 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -133,8 +133,7 @@ void GameInterface::Startup() } else { - if (!userConfig.nologo) fi.ShowLogo([](bool) { gameaction = ga_mainmenunostopsound; }); - else gameaction = ga_mainmenunostopsound; + PlayLogos(ga_mainmenunostopsound, ga_mainmenunostopsound, false); } } diff --git a/source/games/exhumed/src/gameloop.cpp b/source/games/exhumed/src/gameloop.cpp index c741d2a5e..50ff8a55c 100644 --- a/source/games/exhumed/src/gameloop.cpp +++ b/source/games/exhumed/src/gameloop.cpp @@ -167,8 +167,7 @@ void GameInterface::Startup() } else { - if (!userConfig.nologo) DoTitle([](bool) { gameaction = ga_mainmenu; }); - else gameaction = ga_mainmenu; + PlayLogos(ga_mainmenu, ga_mainmenu, false); } } diff --git a/source/games/sw/src/game.cpp b/source/games/sw/src/game.cpp index 0c3af8e89..c228e73fe 100644 --- a/source/games/sw/src/game.cpp +++ b/source/games/sw/src/game.cpp @@ -650,11 +650,7 @@ void GameInterface::Startup() } else { - if (!userConfig.nologo) Logo([](bool) - { - gameaction = ga_mainmenunostopsound; - }); - else gameaction = ga_mainmenu; + PlayLogos(ga_mainmenunostopsound, ga_mainmenu, false); } } diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 91ccba7dd..088a4ce2a 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -47,7 +47,7 @@ class ScreenJob : Object int DrawFrame(double smoothratio) { - if (jobstate != running) smoothratio = 1; // this is necessary because the ticker won't be incremented anymore to avoid having a negative time span. + if (jobstate != running) smoothratio = 1; // this is necessary to avoid having a negative time span because the ticker won't be incremented anymore. Draw(smoothratio); if (jobstate == skipped) return -1; if (jobstate == finished) return 0; From 26a7700579ffe15542c1b9260e5cbaa7c4a1f577 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 23:10:38 +0200 Subject: [PATCH 31/86] - Duke's intro works, without fading. --- source/core/gamecontrol.cpp | 1 + source/core/mainloop.cpp | 1 + source/core/movie/movieplayer.cpp | 7 +-- source/core/screenjob.cpp | 6 ++- source/core/screenjob.h | 3 ++ .../static/zscript/games/duke/ui/cutscenes.zs | 10 ++-- wadsrc/static/zscript/screenjob.zs | 54 +++++++++++++------ 7 files changed, 56 insertions(+), 26 deletions(-) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 0e2435321..95930737e 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -948,6 +948,7 @@ int RunGame() LoadScripts(); StartScreen->Progress(); SetDefaultStrings(); + Job_Init(); if (Args->CheckParm("-sounddebug")) C_DoCommand("stat sounddebug"); diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index da2d99565..649a6c137 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -333,6 +333,7 @@ static void GameTicker() case GS_INTRO: if (ScreenJobTick()) { + Printf("Sending event\n"); // synchronize termination with the playsim. Net_WriteByte(DEM_ENDSCREENJOB); } diff --git a/source/core/movie/movieplayer.cpp b/source/core/movie/movieplayer.cpp index 5ab569472..813ee0062 100644 --- a/source/core/movie/movieplayer.cpp +++ b/source/core/movie/movieplayer.cpp @@ -86,14 +86,15 @@ class AnmPlayer : public MoviePlayer int nextframetime = 0; AnimTextures animtex; const TArray animSnd; - const int* frameTicks; + int frameTicks[3]; public: bool isvalid() { return numframes > 0; } AnmPlayer(FileReader& fr, TArray& ans, const int *frameticks, int flags_) - : animSnd(std::move(ans)), frameTicks(frameticks) + : animSnd(std::move(ans)) { + memcpy(frameTicks, frameticks, 3 * sizeof(int)); flags = flags_; buffer = fr.ReadPadded(1); fr.Close(); @@ -798,7 +799,7 @@ DEFINE_ACTION_FUNCTION(_MoviePlayer, Frame) { PARAM_SELF_STRUCT_PROLOGUE(MoviePlayer); PARAM_FLOAT(clock); - self->Frame(int64_t(clock)); + ACTION_RETURN_INT(self->Frame(int64_t(clock))); return 0; } diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 467b04cd0..297e3ae66 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -69,7 +69,7 @@ static int ticks; // //============================================================================= -static void Job_Init() +void Job_Init() { static bool done = false; if (!done) @@ -215,6 +215,7 @@ bool StartCutscene(CutsceneDef& cs, int flags, CompletionFunc completion_) { completion = completion_; runner = CreateRunner(); + GC::WriteBarrier(runner); cs.Create(runner); gameaction = (flags & SJ_BLOCKUI) ? ga_intro : ga_intermission; return true; @@ -225,12 +226,13 @@ bool StartCutscene(CutsceneDef& cs, int flags, CompletionFunc completion_) void DeleteScreenJob() { - runner->Destroy(); + if (runner) runner->Destroy(); runner = nullptr; } void EndScreenJob() { + Printf("EndScreenJob\n"); DeleteScreenJob(); if (completion) completion(false); completion = nullptr; diff --git a/source/core/screenjob.h b/source/core/screenjob.h index 53c1e08d7..4e5264b7e 100644 --- a/source/core/screenjob.h +++ b/source/core/screenjob.h @@ -10,6 +10,9 @@ using CompletionFunc = std::function; struct JobDesc; class ScreenJobRunner; +void Job_Init(); + + #if 0 class DScreenJob : public DObject { diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index 6c3796187..b21c665c6 100644 --- a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs +++ b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs @@ -26,7 +26,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms */ //------------------------------------------------------------------------- -struct DukeCutscenes +class DukeCutscenes // Note: must be class, not struct, otherwise we cannot easily look up the methods from C++. { //--------------------------------------------------------------------------- // @@ -205,7 +205,7 @@ struct DukeCutscenes static void BuildMPSummary(ScreenJobRunner runner, MapRecord map, SummaryInfo stats) { - runner.Append(new("DukeMultiplayerBonusScreen").Init(playerswhenstarted)); + runner.Append(new("DukeMultiplayerBonusScreen").Init(stats.playercount)); } //--------------------------------------------------------------------------- @@ -260,7 +260,7 @@ struct DukeCutscenes } -struct RRCutscenes +class RRCutscenes { //--------------------------------------------------------------------------- @@ -301,7 +301,7 @@ struct RRCutscenes static void BuildE1End(ScreenJobRunner runner) { - if (!isRRRA()) + if (!Raze.isRRRA()) { Array soundinfo; soundinfo.Pushv(1, RRSnd.CHKAMMO + 1); @@ -318,7 +318,7 @@ struct RRCutscenes static void BuildE2End(ScreenJobRunner runner) { - if (!isRRRA()) + if (!Raze.isRRRA()) { Array soundinfo; soundinfo.Pushv(1, RRSnd.LN_FINAL + 1); diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 088a4ce2a..5404e3de0 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -7,15 +7,14 @@ class ScreenJob : Object int ticks; int jobstate; - bool pausable; enum EJobState { - 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. + running = 0, // normal operation + skipped = 1, // finished by user skipping + finished = 2, // finished by completing its sequence + stopping = 3, // running ending animations / fadeout, etc. Will not accept more input. + stopped = 4, // we're done here. }; enum EJobFlags { @@ -31,7 +30,6 @@ class ScreenJob : Object flags = fadet; fadetime = fadet; jobstate = running; - pausable = true; } virtual bool ProcessInput() @@ -78,8 +76,10 @@ class SkippableScreenJob : ScreenJob override bool OnEvent(InputEvent evt) { + Console.Printf("OnEvent"); if (evt.type == InputEvent.Type_KeyDown && !Raze.specialKeyEvent(evt)) { + Console.Printf("Skip requested"); jobstate = skipped; OnSkip(); } @@ -230,7 +230,7 @@ struct MoviePlayer native native static MoviePlayer Create(String filename, Array soundinfo, int flags, int frametime, int firstframetime, int lastframetime); native void Start(); native bool Frame(double clock); - native bool Destroy(); + native void Destroy(); } //--------------------------------------------------------------------------- @@ -246,8 +246,8 @@ class MoviePlayerJob : SkippableScreenJob ScreenJob Init(MoviePlayer mp) { + Super.Init(); player = mp; - pausable = false; return self; } @@ -272,19 +272,25 @@ class MoviePlayerJob : SkippableScreenJob override void Draw(double smoothratio) { + Console.Printf("MoviePlayer.Draw state = %d", jobstate); + if (!player) { + Console.Printf("MoviePlayer.Draw: end"); jobstate = stopped; return; } if (!started) { + Console.Printf("MoviePlayer.Draw: start"); started = true; player.Start(); } double clock = (ticks + smoothratio) * 1000000000. / GameTicRate; + Console.Printf("MoviePlayer.Frame %d %f", ticks, clock); if (jobstate == running && !player.Frame(clock)) { + Console.Printf("MoviePlayer.finish"); jobstate = finished; } } @@ -352,6 +358,7 @@ class ScreenJobRunner : Object void Append(ScreenJob job) { + Console.Printf("Appending job of type " .. job.GetClassName() ); jobs.Push(job); } @@ -365,6 +372,7 @@ class ScreenJobRunner : Object { if (index == jobs.Size()-1) { + Console.Printf("AdvanceJob: reached end of list"); index++; return; // we need to retain the last element until the runner is done. } @@ -379,6 +387,7 @@ class ScreenJobRunner : Object actionState = clearbefore ? State_Clear : State_Run; if (index < jobs.Size()) { + Console.Printf("AdvanceJob: starting job at index %d, type %s", index, jobs[index].GetClassName()); jobs[index].fadestate = !paused && jobs[index].flags & ScreenJob.fadein? ScreenJob.fadein : ScreenJob.visible; jobs[index].Start(); } @@ -406,6 +415,7 @@ class ScreenJobRunner : Object double ms = (job.ticks + smoothratio) * 1000 / GameTicRate / job.fadetime; double screenfade = clamp(ms, 0., 1.); Screen.SetScreenFade(screenfade); + Console.Printf("DisplayFrame: fading in %s with %f", job.GetClassName(), screenfade); if (screenfade == 1.) job.fadestate = ScreenJob.visible; } int state = job.DrawFrame(smoothratio); @@ -428,6 +438,7 @@ class ScreenJobRunner : Object Screen.SetScreenFade(screenfade); job.DrawFrame(1.); Screen.SetScreenFade(1.); + Console.Printf("FadeoutFrame: fading out %s with %f", job.GetClassName(), screenfade); return (screenfade > 0.); } @@ -441,6 +452,7 @@ class ScreenJobRunner : Object { if (paused || index >= jobs.Size()) return false; if (jobs[index].jobstate != ScreenJob.running) return false; + if (ev.type == InputEvent.Type_KeyDown) Console.Printf("OnEvent: dispatching key %d to job %s", ev.keyScan, jobs[index].GetClassName()); return jobs[index].OnEvent(ev); } @@ -453,23 +465,26 @@ class ScreenJobRunner : Object virtual bool OnTick() { if (paused) return false; - if (jobs.Size() == 0) return true; - if (advance) + if (index >= jobs.Size() || jobs.Size() == 0) return true; + if (advance || index < 0) { advance = false; AdvanceJob(terminateState < 0); if (index >= jobs.Size()) { + Console.Printf("OnTick: done"); return true; } } if (jobs[index].jobstate == ScreenJob.running) { jobs[index].ticks++; + Console.Printf("OnTick: job %s, ticks = %d", jobs[index].GetClassName(), jobs[index].ticks); jobs[index].OnTick(); } else if (jobs[index].jobstate == ScreenJob.stopping) { + Console.Printf("OnTick: fadeticks for %s", jobs[index].GetClassName()); fadeticks++; } return false; @@ -482,12 +497,16 @@ class ScreenJobRunner : Object //--------------------------------------------------------------------------- virtual bool RunFrame(double smoothratio) - { + { // ensure that we won't go back in time if the menu is dismissed without advancing our ticker - bool menuon = paused; - if (menuon) last_paused_tic = jobs[index].ticks; - else if (last_paused_tic == jobs[index].ticks) menuon = true; - if (menuon || index >= jobs.Size()) smoothratio = 1.; + if (index < jobs.Size()) + { + bool menuon = paused; + if (menuon) last_paused_tic = jobs[index].ticks; + else if (last_paused_tic == jobs[index].ticks) menuon = true; + if (menuon) smoothratio = 1.; + } + else smoothratio = 1.; if (actionState == State_Clear) { @@ -499,6 +518,8 @@ class ScreenJobRunner : Object terminateState = DisplayFrame(smoothratio); if (terminateState < 1 && index < jobs.Size()) { + Console.Printf("RunFrame: job %s, state %d", jobs[index].GetClassName(), terminateState); + if (jobs[index].flags & ScreenJob.fadeout) { jobs[index].fadestate = ScreenJob.fadeout; @@ -508,6 +529,7 @@ class ScreenJobRunner : Object } else { + Console.Printf("RunState: advancing"); advance = true; } } From 06abc0cfe281026f69a52921b93578fce9692ca3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 26 Apr 2021 23:21:16 +0200 Subject: [PATCH 32/86] - removed debug output and fixed fade flag setup and missing OnTick return --- source/core/mainloop.cpp | 1 - source/core/screenjob.cpp | 4 ++-- wadsrc/static/zscript/screenjob.zs | 26 +++----------------------- 3 files changed, 5 insertions(+), 26 deletions(-) diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 649a6c137..da2d99565 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -333,7 +333,6 @@ static void GameTicker() case GS_INTRO: if (ScreenJobTick()) { - Printf("Sending event\n"); // synchronize termination with the playsim. Net_WriteByte(DEM_ENDSCREENJOB); } diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index 297e3ae66..71f71322f 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -232,7 +232,6 @@ void DeleteScreenJob() void EndScreenJob() { - Printf("EndScreenJob\n"); DeleteScreenJob(); if (completion) completion(false); completion = nullptr; @@ -275,7 +274,8 @@ bool ScreenJobTick() { int result = 0; VMValue parm[] = { runner }; - VMCall(func, parm, 1, nullptr, 0); + VMReturn ret(&result); + VMCall(func, parm, 1, &ret, 1); return result; } } diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 5404e3de0..58d3fe20f 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -25,9 +25,9 @@ class ScreenJob : Object stopsound = 8, }; - void Init(int flags = 0, float fadet = 250.f) + void Init(int fflags = 0, float fadet = 250.f) { - flags = fadet; + flags = fflags; fadetime = fadet; jobstate = running; } @@ -76,10 +76,8 @@ class SkippableScreenJob : ScreenJob override bool OnEvent(InputEvent evt) { - Console.Printf("OnEvent"); if (evt.type == InputEvent.Type_KeyDown && !Raze.specialKeyEvent(evt)) { - Console.Printf("Skip requested"); jobstate = skipped; OnSkip(); } @@ -272,25 +270,19 @@ class MoviePlayerJob : SkippableScreenJob override void Draw(double smoothratio) { - Console.Printf("MoviePlayer.Draw state = %d", jobstate); - if (!player) { - Console.Printf("MoviePlayer.Draw: end"); jobstate = stopped; return; } if (!started) { - Console.Printf("MoviePlayer.Draw: start"); started = true; player.Start(); } double clock = (ticks + smoothratio) * 1000000000. / GameTicRate; - Console.Printf("MoviePlayer.Frame %d %f", ticks, clock); if (jobstate == running && !player.Frame(clock)) { - Console.Printf("MoviePlayer.finish"); jobstate = finished; } } @@ -358,7 +350,6 @@ class ScreenJobRunner : Object void Append(ScreenJob job) { - Console.Printf("Appending job of type " .. job.GetClassName() ); jobs.Push(job); } @@ -372,7 +363,6 @@ class ScreenJobRunner : Object { if (index == jobs.Size()-1) { - Console.Printf("AdvanceJob: reached end of list"); index++; return; // we need to retain the last element until the runner is done. } @@ -387,7 +377,6 @@ class ScreenJobRunner : Object actionState = clearbefore ? State_Clear : State_Run; if (index < jobs.Size()) { - Console.Printf("AdvanceJob: starting job at index %d, type %s", index, jobs[index].GetClassName()); jobs[index].fadestate = !paused && jobs[index].flags & ScreenJob.fadein? ScreenJob.fadein : ScreenJob.visible; jobs[index].Start(); } @@ -415,7 +404,6 @@ class ScreenJobRunner : Object double ms = (job.ticks + smoothratio) * 1000 / GameTicRate / job.fadetime; double screenfade = clamp(ms, 0., 1.); Screen.SetScreenFade(screenfade); - Console.Printf("DisplayFrame: fading in %s with %f", job.GetClassName(), screenfade); if (screenfade == 1.) job.fadestate = ScreenJob.visible; } int state = job.DrawFrame(smoothratio); @@ -438,7 +426,6 @@ class ScreenJobRunner : Object Screen.SetScreenFade(screenfade); job.DrawFrame(1.); Screen.SetScreenFade(1.); - Console.Printf("FadeoutFrame: fading out %s with %f", job.GetClassName(), screenfade); return (screenfade > 0.); } @@ -452,7 +439,6 @@ class ScreenJobRunner : Object { if (paused || index >= jobs.Size()) return false; if (jobs[index].jobstate != ScreenJob.running) return false; - if (ev.type == InputEvent.Type_KeyDown) Console.Printf("OnEvent: dispatching key %d to job %s", ev.keyScan, jobs[index].GetClassName()); return jobs[index].OnEvent(ev); } @@ -472,19 +458,16 @@ class ScreenJobRunner : Object AdvanceJob(terminateState < 0); if (index >= jobs.Size()) { - Console.Printf("OnTick: done"); return true; } } if (jobs[index].jobstate == ScreenJob.running) { jobs[index].ticks++; - Console.Printf("OnTick: job %s, ticks = %d", jobs[index].GetClassName(), jobs[index].ticks); jobs[index].OnTick(); } else if (jobs[index].jobstate == ScreenJob.stopping) { - Console.Printf("OnTick: fadeticks for %s", jobs[index].GetClassName()); fadeticks++; } return false; @@ -497,7 +480,7 @@ class ScreenJobRunner : Object //--------------------------------------------------------------------------- virtual bool RunFrame(double smoothratio) - { + { // ensure that we won't go back in time if the menu is dismissed without advancing our ticker if (index < jobs.Size()) { @@ -518,8 +501,6 @@ class ScreenJobRunner : Object terminateState = DisplayFrame(smoothratio); if (terminateState < 1 && index < jobs.Size()) { - Console.Printf("RunFrame: job %s, state %d", jobs[index].GetClassName(), terminateState); - if (jobs[index].flags & ScreenJob.fadeout) { jobs[index].fadestate = ScreenJob.fadeout; @@ -529,7 +510,6 @@ class ScreenJobRunner : Object } else { - Console.Printf("RunState: advancing"); advance = true; } } From 3c27ec8cbde1ddf36b850fd13edb855e6ab0888c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Apr 2021 00:01:25 +0200 Subject: [PATCH 33/86] - tested all of Duke's and RR's cutscenes. --- source/common/audio/music/music.cpp | 4 +++ source/common/scripting/core/dynarrays.cpp | 4 +-- .../common/scripting/interface/vmnatives.cpp | 3 +- source/core/screenjob.cpp | 29 +++++++++++++++++++ source/core/screenjob.h | 3 ++ source/games/duke/src/2d_d.cpp | 28 ------------------ source/games/duke/src/funct.h | 3 -- source/games/duke/src/game_misc.cpp | 18 ++++++------ source/games/duke/src/premap.cpp | 3 +- .../static/filter/redneck/engine/engine.def | 25 ++++++++++++++++ .../static/zscript/games/duke/ui/cutscenes.zs | 6 ++-- .../static/zscript/games/duke/ui/screens.zs | 10 +++---- wadsrc/static/zscript/screenjob.zs | 6 +++- 13 files changed, 86 insertions(+), 56 deletions(-) create mode 100644 wadsrc/static/filter/redneck/engine/engine.def diff --git a/source/common/audio/music/music.cpp b/source/common/audio/music/music.cpp index c1c8290f6..f81b2396c 100644 --- a/source/common/audio/music/music.cpp +++ b/source/common/audio/music/music.cpp @@ -138,6 +138,10 @@ void S_StopCustomStream(SoundStream *stream) void S_PauseAllCustomStreams(bool on) { + static bool paused = false; + + if (paused == on) return; + paused = on; for (auto s : customStreams) { s->SetPaused(on); diff --git a/source/common/scripting/core/dynarrays.cpp b/source/common/scripting/core/dynarrays.cpp index 4182d1d95..6be216c12 100644 --- a/source/common/scripting/core/dynarrays.cpp +++ b/source/common/scripting/core/dynarrays.cpp @@ -416,10 +416,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_I32, Push, ArrayPush