From 0dc670da8e2a488675e8ed450c82c01a57f4b784 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 25 Apr 2022 17:26:17 +0200 Subject: [PATCH] - added wipe transitions to screen job Mainly to have the crossfade, the other styles are mostly bonus. This also adds proper scoping to the cutscene code, which needs to run in UI scope. --- source/common/2d/wipe.cpp | 7 ++- source/common/cutscenes/screenjob.cpp | 15 +++++++ source/common/engine/i_interface.h | 1 + source/core/gamecontrol.cpp | 8 ++++ source/core/mainloop.cpp | 45 +++++++++++++------ source/glbackend/glbackend.cpp | 3 +- source/glbackend/glbackend.h | 2 +- wadsrc/static/zscript/engine/inputevents.zs | 8 ++-- wadsrc/static/zscript/engine/screenjob.zs | 20 +++++++-- .../static/zscript/games/blood/ui/screens.zs | 4 +- .../static/zscript/games/duke/ui/cutscenes.zs | 4 +- .../zscript/games/exhumed/ui/screens.zs | 2 +- wadsrc/static/zscript/games/sw/ui/screens.zs | 2 +- 13 files changed, 86 insertions(+), 35 deletions(-) diff --git a/source/common/2d/wipe.cpp b/source/common/2d/wipe.cpp index 7de5f1cf7..78079f47a 100755 --- a/source/common/2d/wipe.cpp +++ b/source/common/2d/wipe.cpp @@ -279,7 +279,7 @@ Wiper_Melt::Wiper_Melt() bool Wiper_Melt::Run(int ticks) { - bool done; + bool done = false; DrawTexture(twod, endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE); // Copy the old screen in vertical strips on top of the new one. @@ -366,14 +366,13 @@ Wiper_Burn::~Wiper_Burn() bool Wiper_Burn::Run(int ticks) { - bool done; - + bool done = false; + BurnTime += ticks; ticks *= 2; // Make the fire burn - done = false; while (!done && ticks--) { Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density); diff --git a/source/common/cutscenes/screenjob.cpp b/source/common/cutscenes/screenjob.cpp index 28e0d682c..840b9f55e 100644 --- a/source/common/cutscenes/screenjob.cpp +++ b/source/common/cutscenes/screenjob.cpp @@ -334,6 +334,21 @@ bool StartCutscene(const char* s, int flags, const CompletionFunc& completion) return StartCutscene(def, flags, completion); } +//============================================================================= +// +// initiates a screen wipe. Needs to call the game code for it. +// +//============================================================================= + +DEFINE_ACTION_FUNCTION(DScreenJobRunner, setTransition) +{ + PARAM_PROLOGUE; + PARAM_INT(type); + + if (type && sysCallbacks.SetTransition) sysCallbacks.SetTransition(type); + return 0; +} + //============================================================================= // // diff --git a/source/common/engine/i_interface.h b/source/common/engine/i_interface.h index dd3ea5862..be3651886 100644 --- a/source/common/engine/i_interface.h +++ b/source/common/engine/i_interface.h @@ -34,6 +34,7 @@ struct SystemCallbacks void (*FontCharCreated)(FGameTexture* base, FGameTexture* untranslated); void (*ToggleFullConsole)(); void (*StartCutscene)(bool blockui); + void (*SetTransition)(int type); }; extern SystemCallbacks sysCallbacks; diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index fd091c1c7..fbb324aeb 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -79,6 +79,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "hw_palmanager.h" #include "razefont.h" #include "coreactor.h" +#include "wipe.h" CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -182,6 +183,7 @@ bool pausedWithKey; bool gamesetinput = false; int PlayClock; +extern int nextwipe; CUSTOM_CVAR(Int, cl_gender, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { @@ -542,6 +544,11 @@ static void System_StartCutscene(bool blockui) gameaction = blockui ? ga_intro : ga_intermission; } +static void System_SetTransition(int type) +{ + nextwipe = type; +} + void I_StartupJoysticks(); void I_ShutdownInput(); int RunGame(); @@ -579,6 +586,7 @@ int GameMain() FontCharCreated, System_ToggleFullConsole, System_StartCutscene, + System_SetTransition, }; try diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 7926f9653..70bc47ed9 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -88,6 +88,7 @@ #include "savegamehelp.h" #include "v_draw.h" #include "gamehud.h" +#include "wipe.h" CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -104,6 +105,7 @@ bool r_NoInterpolate; int entertic; int oldentertics; int gametic; +int nextwipe = wipe_None; FString savename; FString BackupSaveGame; @@ -375,6 +377,21 @@ static void GameTicker() } +void DrawOverlays() +{ + NetUpdate(); // send out any new accumulation + + if (gamestate != GS_INTRO) // do not draw overlays on the intros + { + // Draw overlay elements + CT_Drawer(); + C_DrawConsole(); + M_Drawer(); + FStat::PrintStat(twod); + } + DrawRateStuff(); +} + //========================================================================== // // Display @@ -388,6 +405,12 @@ void Display() { return; } + + FTexture* wipestart = nullptr; + if (nextwipe != wipe_None) + { + wipestart = screen->WipeStartScreen(); + } screen->FrameTime = I_msTimeFS(); tileUpdateAnimations(); @@ -408,7 +431,6 @@ void Display() case GS_INTRO: case GS_CUTSCENE: - // screen jobs are not bound by the game ticker so they need to be ticked in the display loop. ScreenJobDraw(); break; @@ -420,6 +442,7 @@ void Display() screen->SetSceneRenderTarget(gl_ssao != 0); updateModelInterpolation(); gi->Render(); + if (vid_renderer == 0) videoShowFrame(); DrawFullscreenBlends(); drawMapTitle(); break; @@ -430,21 +453,15 @@ void Display() twod->ClearScreen(); break; } - - NetUpdate(); // send out any new accumulation - - if (gamestate != GS_INTRO) // do not draw overlays on the intros + + if (nextwipe == wipe_None) + DrawOverlays(); + else { - // Draw overlay elements - CT_Drawer(); - C_DrawConsole(); - M_Drawer(); - FStat::PrintStat(twod); + PerformWipe(wipestart, screen->WipeEndScreen(), nextwipe, true, DrawOverlays); + nextwipe = wipe_None; } - DrawRateStuff(); - - if (vid_renderer == 0) videoShowFrame(1); - else screen->Update(); + screen->Update(); } //========================================================================== diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 0c7ae95b2..144eba78d 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -417,7 +417,7 @@ int32_t r_scenebrightness = 0; -void videoShowFrame(int32_t w) +void videoShowFrame() { int oldssao = gl_ssao; @@ -428,7 +428,6 @@ void videoShowFrame(int32_t w) screen->PostProcessScene(false, 0, Brightness, []() { Draw2D(&twodpsp, *screen->RenderState()); // draws the weapon sprites }); - screen->Update(); screen->mVertexData->Reset(); screen->mViewpoints->Clear(); diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index e8f2042d7..dcfdfa1ee 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -310,4 +310,4 @@ void renderSetVisibility(float v); void renderSetViewpoint(float x, float y, float z); void renderBeginScene(); void renderFinishScene(); -void videoShowFrame(int32_t); +void videoShowFrame(); diff --git a/wadsrc/static/zscript/engine/inputevents.zs b/wadsrc/static/zscript/engine/inputevents.zs index 3c56e1178..ba63b59e9 100644 --- a/wadsrc/static/zscript/engine/inputevents.zs +++ b/wadsrc/static/zscript/engine/inputevents.zs @@ -29,7 +29,7 @@ struct UiEvent native ui version("2.4") Type_FwdButtonUp, // ??? Type_LastMouseEvent } - + // for KeyDown, KeyRepeat, KeyUp enum ESpecialGUIKeys { @@ -67,7 +67,7 @@ struct UiEvent native ui version("2.4") Key_Back = 30, // browser back key Key_CEscape = 31 // color escape } - + // native readonly EGUIEvent Type; // @@ -93,7 +93,7 @@ struct InputEvent native play version("2.4") Type_GUI, // unused, kept for completeness Type_DeviceChange } - + // ew. enum EDoomInputKeys { @@ -237,7 +237,7 @@ struct InputEvent native play version("2.4") Num_Keys = 0x1C4 } - + // native readonly EGenericEvent Type; // diff --git a/wadsrc/static/zscript/engine/screenjob.zs b/wadsrc/static/zscript/engine/screenjob.zs index 776cafc00..c65091c6e 100644 --- a/wadsrc/static/zscript/engine/screenjob.zs +++ b/wadsrc/static/zscript/engine/screenjob.zs @@ -1,5 +1,5 @@ -class ScreenJob : Object +class ScreenJob : Object UI { int flags; float fadetime; // in milliseconds @@ -25,6 +25,11 @@ class ScreenJob : Object fadeout = 2, stopmusic = 4, stopsound = 8, + transition_shift = 4, + transition_mask = 48, + transition_melt = 16, + transition_burn = 32, + transition_crossfade = 48, }; void Init(int fflags = 0, float fadet = 250.f) @@ -60,6 +65,7 @@ class ScreenJob : Object if (flags & stopmusic) System.StopMusic(); if (flags & stopsound) System.StopAllSounds(); } + } //--------------------------------------------------------------------------- @@ -244,12 +250,12 @@ class MoviePlayerJob : SkippableScreenJob empty.Push(int(soundname)); return CreateWithSoundInfo(filename, empty, flags, frametime); } - + virtual void DrawFrame() { let tex = player.GetTexture(); let size = TexMan.GetScaledSize(tex); - + if (!(flag & MoviePlayer.FIXEDVIEWPORT) || (size.x <= 320 && size.y <= 200) || size.x >= 640 || size.y >= 480) { Screen.DrawTexture(tex, false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Masked, false); @@ -298,7 +304,7 @@ class MoviePlayerJob : SkippableScreenJob // //--------------------------------------------------------------------------- -class ScreenJobRunner : Object +class ScreenJobRunner : Object UI { enum ERunState { @@ -317,6 +323,8 @@ class ScreenJobRunner : Object int terminateState; int fadeticks; int last_paused_tic; + + native static void setTransition(int type); void Init(bool clearbefore_, bool skipall_) { @@ -378,6 +386,10 @@ class ScreenJobRunner : Object { jobs[index].fadestate = !paused && jobs[index].flags & ScreenJob.fadein? ScreenJob.fadein : ScreenJob.visible; jobs[index].Start(); + if (jobs[index].flags & ScreenJob.transition_mask) + { + setTransition((jobs[index].flags & ScreenJob.transition_mask) >> ScreenJob.Transition_Shift); + } } } diff --git a/wadsrc/static/zscript/games/blood/ui/screens.zs b/wadsrc/static/zscript/games/blood/ui/screens.zs index c0e1f20da..d3c22dea7 100644 --- a/wadsrc/static/zscript/games/blood/ui/screens.zs +++ b/wadsrc/static/zscript/games/blood/ui/screens.zs @@ -41,7 +41,7 @@ class BloodIntroImage : ImageScreen } } -struct BloodScreen +struct BloodScreen ui { enum EConstants { @@ -289,7 +289,7 @@ class BloodLoadScreen : ScreenJob // //--------------------------------------------------------------------------- -class BloodCutscenes +class BloodCutscenes ui { static void BuildIntro(ScreenJobRunner runner) { diff --git a/wadsrc/static/zscript/games/duke/ui/cutscenes.zs b/wadsrc/static/zscript/games/duke/ui/cutscenes.zs index 398362d24..d80cd5e86 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 // Note: must be class, not struct, otherwise we cannot easily look up the methods from C++. +class DukeCutscenes ui // Note: must be class, not struct, otherwise we cannot easily look up the methods from C++. { //--------------------------------------------------------------------------- // @@ -261,7 +261,7 @@ class DukeCutscenes // Note: must be class, not struct, otherwise we cannot easi } -class RRCutscenes +class RRCutscenes ui { //--------------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/games/exhumed/ui/screens.zs b/wadsrc/static/zscript/games/exhumed/ui/screens.zs index f5c096808..32d6f6009 100644 --- a/wadsrc/static/zscript/games/exhumed/ui/screens.zs +++ b/wadsrc/static/zscript/games/exhumed/ui/screens.zs @@ -784,7 +784,7 @@ class ExCredits : ScreenJob } } -class ExhumedCutscenes +class ExhumedCutscenes ui { //--------------------------------------------------------------------------- // diff --git a/wadsrc/static/zscript/games/sw/ui/screens.zs b/wadsrc/static/zscript/games/sw/ui/screens.zs index 66d6c142c..9ae4e279f 100644 --- a/wadsrc/static/zscript/games/sw/ui/screens.zs +++ b/wadsrc/static/zscript/games/sw/ui/screens.zs @@ -361,7 +361,7 @@ class SWLoadScreen : ScreenJob } -class SWCutscenes +class SWCutscenes ui { //--------------------------------------------------------------------------- //