From e639030276599fa6da0e91c07ef689d26a70b222 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 May 2022 00:04:44 +0200 Subject: [PATCH] - fixed music in intermissions. The starting of the first screen's music must be delayed until the playback of this screen actually starts. Since the controller objects are created up front it cannot be done in the Init() method anymore. --- src/intermission/intermission.cpp | 40 +++++++++++++++++++----- src/intermission/intermission.h | 6 ++++ wadsrc/static/zscript/ui/intermission.zs | 2 ++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 0efbf37295..2ce6296b2b 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -144,12 +144,7 @@ void DrawFullscreenSubtitle(FFont* font, const char *text) void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) { - if (desc->mMusic.IsEmpty()) - { - // only start the default music if this is the first action in an intermission - if (first) S_ChangeMusic (gameinfo.finaleMusic, gameinfo.finaleOrder, desc->mMusicLooping); - } - else + if (!first && desc->mMusic.IsNotEmpty()) { S_ChangeMusic (desc->mMusic, desc->mMusicOrder, desc->mMusicLooping); } @@ -193,8 +188,27 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) } mTicker = 0; mSubtitle = desc->mSubtitle; + mFirst = first; + // If this is the first element of an intermission we must delay starting the music until Start() is called. + mMusic = desc->mMusic; + mMusicLooping = desc->mMusicLooping; + mMusicOrder = desc->mMusicOrder; } +void DIntermissionScreen::Start() +{ + if (mFirst) + { + if (mMusic.IsEmpty()) + { + S_ChangeMusic(gameinfo.finaleMusic, gameinfo.finaleOrder, mMusicLooping); + } + else + { + S_ChangeMusic(mMusic, mMusicOrder, mMusicLooping); + } + } +} int DIntermissionScreen::Responder (FInputEvent *ev) { @@ -900,6 +914,11 @@ again: return false; } +void DIntermissionController::Start() +{ + if (mScreen) mScreen->Start(); +} + bool DIntermissionController::Responder (FInputEvent *ev) { if (mScreen != NULL) @@ -1042,10 +1061,17 @@ DEFINE_ACTION_FUNCTION(DIntermissionController, Ticker) ACTION_RETURN_BOOL(self->Ticker()); } +DEFINE_ACTION_FUNCTION(DIntermissionController, Start) +{ + PARAM_SELF_PROLOGUE(DIntermissionController); + self->Start(); + return 0; +} + DEFINE_ACTION_FUNCTION(DIntermissionController, Drawer) { PARAM_SELF_PROLOGUE(DIntermissionController); - self->Drawer (); + self->Drawer(); return 0; } diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index db2e76ecb0..e25354c875 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -166,7 +166,11 @@ protected: int mDuration; FTextureID mBackground; FString mSubtitle; + FString mMusic; + int mMusicOrder; + bool mMusicLooping; bool mFlatfill; + bool mFirst; TArray mOverlays; bool CheckOverlay(int i); @@ -176,6 +180,7 @@ public: DIntermissionScreen() {} virtual void Init(FIntermissionAction *desc, bool first); + virtual void Start(); virtual int Responder (FInputEvent *ev); virtual int Ticker (); virtual void Drawer (); @@ -304,6 +309,7 @@ public: DIntermissionController(FIntermissionDescriptor *mDesc = NULL, bool mDeleteDesc = false, bool ending = false); bool Responder (FInputEvent *ev); bool Ticker (); + void Start(); void Drawer (); void OnDestroy() override; bool NextPage(); diff --git a/wadsrc/static/zscript/ui/intermission.zs b/wadsrc/static/zscript/ui/intermission.zs index f6a762f1b0..cdf4ce03cd 100644 --- a/wadsrc/static/zscript/ui/intermission.zs +++ b/wadsrc/static/zscript/ui/intermission.zs @@ -5,6 +5,7 @@ class IntermissionController native ui // This is mostly a black box to the native intermission code. // May be scriptified later, but right now we do not need it. + native void Start(); native bool Responder(InputEvent ev); native bool Ticker(); native void Drawer(); @@ -24,6 +25,7 @@ class IntermissionScreenJob : ScreenJob return self; } + override void Start() { controller.Start(); } override bool OnEvent(InputEvent evt) { return controller.Responder(evt); } override void OnTick() { if (!controller.Ticker()) jobstate = finished; } override void Draw(double smoothratio) { controller.Drawer(); }