- first stage of migrating intermissions to screenjobs.

This commit is contained in:
Christoph Oelckers 2022-04-10 08:54:45 +02:00
parent d994369fd0
commit 390bf58698
15 changed files with 171 additions and 329 deletions

View file

@ -15,7 +15,6 @@ enum gamestate_t : int
GS_TITLELEVEL, // [RH] A combination of GS_LEVEL and GS_DEMOSCREEN GS_TITLELEVEL, // [RH] A combination of GS_LEVEL and GS_DEMOSCREEN
GS_INTRO, GS_INTRO,
GS_CUTSCENE, GS_CUTSCENE,
GS_MENUSCREEN = GS_DEMOSCREEN, GS_MENUSCREEN = GS_DEMOSCREEN,
GS_FORCEWIPE = -1, GS_FORCEWIPE = -1,

View file

@ -240,11 +240,14 @@ void CT_Drawer (void)
if (players[consoleplayer].camera != NULL && if (players[consoleplayer].camera != NULL &&
(buttonMap.ButtonDown(Button_ShowScores) || (buttonMap.ButtonDown(Button_ShowScores) ||
players[consoleplayer].camera->health <= 0 || players[consoleplayer].camera->health <= 0 ||
SB_ForceActive) && SB_ForceActive))
// Don't draw during intermission, since it has its own scoreboard in wi_stuff.cpp.
gamestate != GS_INTERMISSION)
{ {
HU_DrawScores (&players[consoleplayer]); bool skipit = false;
if (gamestate == GS_CUTSCENE)
{
// todo: check for summary screen
}
if (!skipit) HU_DrawScores (&players[consoleplayer]);
} }
if (chatmodeon) if (chatmodeon)
{ {

View file

@ -118,6 +118,7 @@
#include "hw_clock.h" #include "hw_clock.h"
#include "hwrenderer/scene/hw_drawinfo.h" #include "hwrenderer/scene/hw_drawinfo.h"
#include "doomfont.h" #include "doomfont.h"
#include "screenjob.h"
#ifdef __unix__ #ifdef __unix__
#include "i_system.h" // for SHARE_DIR #include "i_system.h" // for SHARE_DIR
@ -1018,18 +1019,20 @@ void D_Display ()
End2DAndUpdate (); End2DAndUpdate ();
return; return;
case GS_INTERMISSION:
WI_Drawer ();
break;
case GS_FINALE:
F_Drawer ();
break;
case GS_DEMOSCREEN: case GS_DEMOSCREEN:
D_PageDrawer (); D_PageDrawer ();
break; break;
case GS_CUTSCENE:
case GS_INTRO:
if (ScreenJobTick())
{
// synchronize termination with the playsim.
Net_WriteByte(DEM_ENDSCREENJOB);
}
break;
default: default:
break; break;
} }
@ -1168,7 +1171,6 @@ void D_ErrorCleanup ()
{ {
menuactive = MENU_Off; menuactive = MENU_Off;
} }
if (gamestate == GS_INTERMISSION) gamestate = GS_DEMOSCREEN;
insave = false; insave = false;
ClearGlobalVMStack(); ClearGlobalVMStack();
} }
@ -2735,7 +2737,7 @@ static bool System_CaptureModeInGame()
case 0: case 0:
return gamestate == GS_LEVEL; return gamestate == GS_LEVEL;
case 1: case 1:
return gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE; return gamestate == GS_LEVEL || gamestate == GS_CUTSCENE;
case 2: case 2:
return true; return true;
} }
@ -2975,7 +2977,6 @@ extern DThinker* NextToThink;
static void GC_MarkGameRoots() static void GC_MarkGameRoots()
{ {
GC::Mark(DIntermissionController::CurrentIntermission);
GC::Mark(staticEventManager.FirstEventHandler); GC::Mark(staticEventManager.FirstEventHandler);
GC::Mark(staticEventManager.LastEventHandler); GC::Mark(staticEventManager.LastEventHandler);
for (auto Level : AllLevels()) for (auto Level : AllLevels())
@ -3694,7 +3695,6 @@ void D_Cleanup()
G_ClearMapinfo(); G_ClearMapinfo();
M_ClearMenus(); // close menu if open M_ClearMenus(); // close menu if open
F_EndFinale(); // If an intermission is active, end it now
AM_ClearColorsets(); AM_ClearColorsets();
DeinitSWColorMaps(); DeinitSWColorMaps();
FreeSBarInfoScript(); FreeSBarInfoScript();

View file

@ -68,6 +68,7 @@
#include "vm.h" #include "vm.h"
#include "gstrings.h" #include "gstrings.h"
#include "s_music.h" #include "s_music.h"
#include "screenjob.h"
EXTERN_CVAR (Int, disableautosave) EXTERN_CVAR (Int, disableautosave)
EXTERN_CVAR (Int, autosavecount) EXTERN_CVAR (Int, autosavecount)
@ -1851,7 +1852,7 @@ void TryRunTics (void)
int counts; int counts;
int numplaying; int numplaying;
bool doWait = (cl_capfps || pauseext || (r_NoInterpolate && !M_IsAnimated() /*&& gamestate != GS_INTERMISSION && gamestate != GS_INTRO*/)); bool doWait = (cl_capfps || pauseext || (r_NoInterpolate && !M_IsAnimated()));
// get real tics // get real tics
if (doWait) if (doWait)
@ -2696,10 +2697,6 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
players[player].MaxPitch = (double)ReadByte(stream); // down players[player].MaxPitch = (double)ReadByte(stream); // down
break; break;
case DEM_ADVANCEINTER:
F_AdvanceIntermission();
break;
case DEM_REVERTCAMERA: case DEM_REVERTCAMERA:
players[player].camera = players[player].mo; players[player].camera = players[player].mo;
break; break;
@ -2721,6 +2718,10 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
} }
break; break;
case DEM_ENDSCREENJOB:
EndScreenJob();
break;
default: default:
I_Error ("Unknown net command: %d", type); I_Error ("Unknown net command: %d", type);
break; break;

View file

@ -162,6 +162,7 @@ enum EDemoCommand
DEM_NETEVENT, // 70 String: Event name, Byte: Arg count; each arg is a 4-byte int DEM_NETEVENT, // 70 String: Event name, Byte: Arg count; each arg is a 4-byte int
DEM_MDK, // 71 String: Damage type DEM_MDK, // 71 String: Damage type
DEM_SETINV, // 72 SetInventory DEM_SETINV, // 72 SetInventory
DEM_ENDSCREENJOB,
}; };
// The following are implemented by cht_DoCheat in m_cheat.cpp // The following are implemented by cht_DoCheat in m_cheat.cpp

View file

@ -1018,11 +1018,6 @@ bool G_Responder (event_t *ev)
if (!viewactive && primaryLevel->automap && primaryLevel->automap->Responder (ev, false)) if (!viewactive && primaryLevel->automap && primaryLevel->automap->Responder (ev, false))
return true; // automap ate it return true; // automap ate it
} }
else if (gamestate == GS_FINALE)
{
if (F_Responder (ev))
return true; // finale ate the event
}
switch (ev->type) switch (ev->type)
{ {
@ -1204,14 +1199,6 @@ void G_Ticker ()
C_AdjustBottom (); C_AdjustBottom ();
} }
if (oldgamestate != gamestate)
{
if (oldgamestate == GS_FINALE)
{
F_EndFinale ();
}
}
// get commands, check consistancy, and build new consistancy check // get commands, check consistancy, and build new consistancy check
int buf = (gametic/ticdup)%BACKUPTICS; int buf = (gametic/ticdup)%BACKUPTICS;
@ -1294,14 +1281,6 @@ void G_Ticker ()
P_Ticker (); P_Ticker ();
break; break;
case GS_INTERMISSION:
WI_Ticker ();
break;
case GS_FINALE:
F_Ticker ();
break;
case GS_DEMOSCREEN: case GS_DEMOSCREEN:
D_PageTicker (); D_PageTicker ();
break; break;

View file

@ -828,6 +828,114 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SecretExitLevel, LevelLocals_SecretE
//========================================================================== //==========================================================================
static wbstartstruct_t staticWmInfo; static wbstartstruct_t staticWmInfo;
DIntermissionController* FLevelLocals::CreateIntermission()
{
DIntermissionController* controller;
cluster_info_t *nextcluster;
cluster_info_t *thiscluster;
if (flags & LEVEL_CHANGEMAPCHEAT)
return nullptr;
thiscluster = FindClusterInfo (cluster);
if (strncmp (nextlevel, "enDSeQ", 6) == 0)
{
FName endsequence = ENamedName(strtoll(nextlevel.GetChars()+6, NULL, 16));
// Strife needs a special case here to choose between good and sad ending. Bad is handled elsewhere.
if (endsequence == NAME_Inter_Strife)
{
if (Players[0]->mo->FindInventory (NAME_QuestItem25) ||
Players[0]->mo->FindInventory (NAME_QuestItem28))
{
endsequence = NAME_Inter_Strife_Good;
}
else
{
endsequence = NAME_Inter_Strife_Sad;
}
}
auto ext = info->ExitMapTexts.CheckKey(flags3 & LEVEL3_EXITSECRETUSED ? NAME_Secret : NAME_Normal);
if (ext != nullptr && (ext->mDefined & FExitText::DEF_TEXT))
{
controller = F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic,
ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder,
-1, 0,
ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat,
ext->mText,
false,
ext->mDefined & FExitText::DEF_PIC,
ext->mDefined & FExitText::DEF_LOOKUP,
true, endsequence);
}
else if (!(info->flags2 & LEVEL2_NOCLUSTERTEXT))
{
controller = F_StartFinale(thiscluster->MessageMusic, thiscluster->musicorder,
thiscluster->cdtrack, thiscluster->cdid,
thiscluster->FinaleFlat, thiscluster->ExitText,
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
thiscluster->flags & CLUSTER_FINALEPIC,
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
true, endsequence);
}
}
else if (!deathmatch)
{
FExitText *ext = nullptr;
if (flags3 & LEVEL3_EXITSECRETUSED) ext = info->ExitMapTexts.CheckKey(NAME_Secret);
else if (flags3 & LEVEL3_EXITNORMALUSED) ext = info->ExitMapTexts.CheckKey(NAME_Normal);
if (ext == nullptr) ext = info->ExitMapTexts.CheckKey(nextlevel);
if (ext != nullptr)
{
if ((ext->mDefined & FExitText::DEF_TEXT))
{
controller = F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic,
ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder,
-1, 0,
ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat,
ext->mText,
false,
ext->mDefined & FExitText::DEF_PIC,
ext->mDefined & FExitText::DEF_LOOKUP,
false);
}
return controller;
}
nextcluster = FindClusterInfo (FindLevelInfo (nextlevel)->cluster);
if (nextcluster->cluster != cluster && !(info->flags2 & LEVEL2_NOCLUSTERTEXT))
{
// Only start the finale if the next level's cluster is different
// than the current one and we're not in deathmatch.
if (nextcluster->EnterText.IsNotEmpty())
{
controller = F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder,
nextcluster->cdtrack, nextcluster->cdid,
nextcluster->FinaleFlat, nextcluster->EnterText,
nextcluster->flags & CLUSTER_ENTERTEXTINLUMP,
nextcluster->flags & CLUSTER_FINALEPIC,
nextcluster->flags & CLUSTER_LOOKUPENTERTEXT,
false);
}
else if (thiscluster->ExitText.IsNotEmpty())
{
controller = F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
thiscluster->cdtrack, nextcluster->cdid,
thiscluster->FinaleFlat, thiscluster->ExitText,
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
thiscluster->flags & CLUSTER_FINALEPIC,
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
false);
}
}
}
return controller;
}
void G_DoCompleted (void) void G_DoCompleted (void)
{ {
gameaction = ga_nothing; gameaction = ga_nothing;
@ -860,9 +968,10 @@ void G_DoCompleted (void)
SN_StopAllSequences(Level); SN_StopAllSequences(Level);
} }
// todo: create end of level screenjob
DObject* statusScreen = nullptr, *intermissionScreen = nullptr;
if (playinter) if (playinter)
{ {
gamestate = GS_INTERMISSION;
viewactive = false; viewactive = false;
automapactive = false; automapactive = false;
@ -870,8 +979,10 @@ void G_DoCompleted (void)
// if (statcopy) // if (statcopy)
// memcpy (statcopy, &wminfo, sizeof(wminfo)); // memcpy (statcopy, &wminfo, sizeof(wminfo));
WI_Start (&staticWmInfo); statusScreen = WI_Start (&staticWmInfo);
} }
intermissionScreen = primaryLevel->CreateIntermission();
// todo: create start of level screenjob.
} }
//========================================================================== //==========================================================================
@ -1281,10 +1392,7 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au
//========================================================================== //==========================================================================
void FLevelLocals::WorldDone (void) void FLevelLocals::WorldDone (void)
{ {
cluster_info_t *nextcluster;
cluster_info_t *thiscluster;
gameaction = ga_worlddone; gameaction = ga_worlddone;
@ -1294,110 +1402,11 @@ void FLevelLocals::WorldDone (void)
BotInfo.RemoveAllBots(this, consoleplayer != Net_Arbitrator); BotInfo.RemoveAllBots(this, consoleplayer != Net_Arbitrator);
} }
if (flags & LEVEL_CHANGEMAPCHEAT) }
return;
thiscluster = FindClusterInfo (cluster);
if (strncmp (nextlevel, "enDSeQ", 6) == 0)
{
FName endsequence = ENamedName(strtoll(nextlevel.GetChars()+6, NULL, 16));
// Strife needs a special case here to choose between good and sad ending. Bad is handled elsewhere.
if (endsequence == NAME_Inter_Strife)
{
if (Players[0]->mo->FindInventory (NAME_QuestItem25) ||
Players[0]->mo->FindInventory (NAME_QuestItem28))
{
endsequence = NAME_Inter_Strife_Good;
}
else
{
endsequence = NAME_Inter_Strife_Sad;
}
}
auto ext = info->ExitMapTexts.CheckKey(flags3 & LEVEL3_EXITSECRETUSED ? NAME_Secret : NAME_Normal);
if (ext != nullptr && (ext->mDefined & FExitText::DEF_TEXT))
{
F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic,
ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder,
-1, 0,
ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat,
ext->mText,
false,
ext->mDefined & FExitText::DEF_PIC,
ext->mDefined & FExitText::DEF_LOOKUP,
true, endsequence);
}
else if (!(info->flags2 & LEVEL2_NOCLUSTERTEXT))
{
F_StartFinale(thiscluster->MessageMusic, thiscluster->musicorder,
thiscluster->cdtrack, thiscluster->cdid,
thiscluster->FinaleFlat, thiscluster->ExitText,
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
thiscluster->flags & CLUSTER_FINALEPIC,
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
true, endsequence);
}
}
else if (!deathmatch)
{
FExitText *ext = nullptr;
if (flags3 & LEVEL3_EXITSECRETUSED) ext = info->ExitMapTexts.CheckKey(NAME_Secret);
else if (flags3 & LEVEL3_EXITNORMALUSED) ext = info->ExitMapTexts.CheckKey(NAME_Normal);
if (ext == nullptr) ext = info->ExitMapTexts.CheckKey(nextlevel);
if (ext != nullptr)
{
if ((ext->mDefined & FExitText::DEF_TEXT))
{
F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic,
ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder,
-1, 0,
ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat,
ext->mText,
false,
ext->mDefined & FExitText::DEF_PIC,
ext->mDefined & FExitText::DEF_LOOKUP,
false);
}
return;
}
nextcluster = FindClusterInfo (FindLevelInfo (nextlevel)->cluster);
if (nextcluster->cluster != cluster && !(info->flags2 & LEVEL2_NOCLUSTERTEXT))
{
// Only start the finale if the next level's cluster is different
// than the current one and we're not in deathmatch.
if (nextcluster->EnterText.IsNotEmpty())
{
F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder,
nextcluster->cdtrack, nextcluster->cdid,
nextcluster->FinaleFlat, nextcluster->EnterText,
nextcluster->flags & CLUSTER_ENTERTEXTINLUMP,
nextcluster->flags & CLUSTER_FINALEPIC,
nextcluster->flags & CLUSTER_LOOKUPENTERTEXT,
false);
}
else if (thiscluster->ExitText.IsNotEmpty())
{
F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
thiscluster->cdtrack, nextcluster->cdid,
thiscluster->FinaleFlat, thiscluster->ExitText,
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
thiscluster->flags & CLUSTER_FINALEPIC,
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
false);
}
}
}
}
DEFINE_ACTION_FUNCTION(FLevelLocals, WorldDone) DEFINE_ACTION_FUNCTION(FLevelLocals, WorldDone)
{ {
primaryLevel->WorldDone(); // This is just a dummy to make old status screens happy.
return 0; return 0;
} }

View file

@ -102,6 +102,7 @@ struct EventManager;
typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS) typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS)
typedef TMap<FName, int> FDialogueMap; // maps actor class names to dialogue array index typedef TMap<FName, int> FDialogueMap; // maps actor class names to dialogue array index
typedef TMap<int, FUDMFKeys> FUDMFKeyMap; typedef TMap<int, FUDMFKeys> FUDMFKeyMap;
class DIntermissionController;
struct FLevelLocals struct FLevelLocals
{ {
@ -122,6 +123,7 @@ struct FLevelLocals
friend class MapLoader; friend class MapLoader;
DIntermissionController* CreateIntermission();
void Tick(); void Tick();
void Mark(); void Mark();
void AddScroller(int secnum); void AddScroller(int secnum);

View file

@ -589,7 +589,7 @@ CCMD(printstats)
CCMD(finishgame) CCMD(finishgame)
{ {
bool gamestatecheck = gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE; bool gamestatecheck = gamestate == GS_LEVEL || gamestate == GS_CUTSCENE;
if (!gamestatecheck) if (!gamestatecheck)
{ {
Printf("Cannot use 'finishgame' while not in a game!\n"); Printf("Cannot use 'finishgame' while not in a game!\n");

View file

@ -835,8 +835,6 @@ void DIntermissionScreenScroller::Drawer ()
// //
//========================================================================== //==========================================================================
DIntermissionController *DIntermissionController::CurrentIntermission;
DIntermissionController::DIntermissionController(FIntermissionDescriptor *Desc, bool DeleteDesc, uint8_t state) DIntermissionController::DIntermissionController(FIntermissionDescriptor *Desc, bool DeleteDesc, uint8_t state)
{ {
mDesc = Desc; mDesc = Desc;
@ -932,10 +930,9 @@ bool DIntermissionController::Responder (event_t *ev)
if (mScreen->mTicker < 2) return false; // prevent some leftover events from auto-advancing if (mScreen->mTicker < 2) return false; // prevent some leftover events from auto-advancing
int res = mScreen->Responder(ev); int res = mScreen->Responder(ev);
if (res == -1 && !mSentAdvance) if (res == -1)
{ {
Net_WriteByte(DEM_ADVANCEINTER); mAdvance = true;
mSentAdvance = true;
} }
return !!res; return !!res;
} }
@ -995,7 +992,6 @@ void DIntermissionController::OnDestroy ()
if (mScreen != NULL) mScreen->Destroy(); if (mScreen != NULL) mScreen->Destroy();
if (mDeleteDesc) delete mDesc; if (mDeleteDesc) delete mDesc;
mDesc = NULL; mDesc = NULL;
if (CurrentIntermission == this) CurrentIntermission = NULL;
} }
@ -1005,28 +1001,25 @@ void DIntermissionController::OnDestroy ()
// //
//========================================================================== //==========================================================================
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state) DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state)
{ {
ScaleOverrider s(twod); ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Destroy();
}
S_StopAllChannels (); S_StopAllChannels ();
gameaction = ga_nothing; gameaction = ga_nothing;
gamestate = GS_FINALE; gamestate = GS_FINALE;
if (state == FSTATE_InLevel) wipegamestate = GS_FINALE; // don't wipe when within a level. if (state == FSTATE_InLevel) wipegamestate = GS_FINALE; // don't wipe when within a level.
viewactive = false; viewactive = false;
automapactive = false; automapactive = false;
DIntermissionController::CurrentIntermission = Create<DIntermissionController>(desc, deleteme, state); auto CurrentIntermission = Create<DIntermissionController>(desc, deleteme, state);
// If the intermission finishes straight away then cancel the wipe. // If the intermission finishes straight away then cancel the wipe.
if (!DIntermissionController::CurrentIntermission->NextPage()) if (!CurrentIntermission->NextPage())
{ {
wipegamestate = GS_FINALE; CurrentIntermission->Destroy();
} }
GC::WriteBarrier(DIntermissionController::CurrentIntermission); GC::WriteBarrier(CurrentIntermission);
return CurrentIntermission;
} }
@ -1036,12 +1029,12 @@ void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t s
// //
//========================================================================== //==========================================================================
void F_StartIntermission(FName seq, uint8_t state) DIntermissionController* F_StartIntermission(FName seq, uint8_t state)
{ {
FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(seq); FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(seq);
if (pdesc == nullptr) if (pdesc == nullptr)
{ {
gameaction = ga_nothing; return nullptr;
} }
else else
{ {
@ -1049,83 +1042,6 @@ void F_StartIntermission(FName seq, uint8_t state)
} }
} }
//==========================================================================
//
// Called by main loop.
//
//==========================================================================
bool F_Responder (event_t* ev)
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
return DIntermissionController::CurrentIntermission->Responder(ev);
}
return false;
}
//==========================================================================
//
// Called by main loop.
//
//==========================================================================
void F_Ticker ()
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Ticker();
}
}
//==========================================================================
//
// Called by main loop.
//
//==========================================================================
void F_Drawer ()
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Drawer();
}
}
//==========================================================================
//
// Called by main loop.
//
//==========================================================================
void F_EndFinale ()
{
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Destroy();
DIntermissionController::CurrentIntermission = NULL;
}
}
//==========================================================================
//
// Called by net loop.
//
//==========================================================================
void F_AdvanceIntermission()
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->mAdvance = true;
}
}
#include "c_dispatch.h" #include "c_dispatch.h"
CCMD(measureintermissions) CCMD(measureintermissions)

View file

@ -299,8 +299,6 @@ class DIntermissionController : public DObject
uint8_t mGameState; uint8_t mGameState;
int mIndex; int mIndex;
bool NextPage();
public: public:
static DIntermissionController *CurrentIntermission; static DIntermissionController *CurrentIntermission;
@ -309,23 +307,18 @@ public:
void Ticker (); void Ticker ();
void Drawer (); void Drawer ();
void OnDestroy() override; void OnDestroy() override;
bool NextPage();
friend void F_AdvanceIntermission(); friend DIntermissionController* F_StartIntermission(FIntermissionDescriptor *, bool, uint8_t);
friend void F_StartIntermission(FIntermissionDescriptor *, bool, uint8_t);
}; };
// Interface for main loop // Interface for main loop
bool F_Responder (event_t* ev); DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state);
void F_Ticker (); DIntermissionController* F_StartIntermission(FName desc, uint8_t state);
void F_Drawer ();
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state);
void F_StartIntermission(FName desc, uint8_t state);
void F_EndFinale ();
void F_AdvanceIntermission();
// Create an intermission from old cluster data // Create an intermission from old cluster data
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat, DIntermissionController* F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText, const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText,
bool ending, FName endsequence = NAME_None); bool ending, FName endsequence = NAME_None);

View file

@ -849,7 +849,7 @@ FName FMapInfoParser::CheckEndSequence()
// //
//========================================================================== //==========================================================================
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat, DIntermissionController* F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText, const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText,
bool ending, FName endsequence) bool ending, FName endsequence)
{ {
@ -909,16 +909,17 @@ void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int
desc->mActions.Push(wiper); desc->mActions.Push(wiper);
} }
F_StartIntermission(desc, true, ending? FSTATE_EndingGame : FSTATE_ChangingLevel); return F_StartIntermission(desc, true, ending? FSTATE_EndingGame : FSTATE_ChangingLevel);
} }
else if (ending) else if (ending)
{ {
FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(endsequence); FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(endsequence);
if (pdesc != NULL) if (pdesc != NULL)
{ {
F_StartIntermission(*pdesc, false, ending? FSTATE_EndingGame : FSTATE_ChangingLevel); return F_StartIntermission(*pdesc, false, ending? FSTATE_EndingGame : FSTATE_ChangingLevel);
} }
} }
return nullptr;
} }
@ -952,5 +953,6 @@ CCMD(testfinale)
return; return;
} }
F_StartFinale(gameinfo.finaleMusic, gameinfo.finaleOrder, -1, 0, gameinfo.FinaleFlat, text, false, false, true, true); auto controller = F_StartFinale(gameinfo.finaleMusic, gameinfo.finaleOrder, -1, 0, gameinfo.FinaleFlat, text, false, false, true, true);
// todo: play it
} }

View file

@ -155,7 +155,7 @@ CVAR (Int, bot_next_color, 11, 0)
CCMD (addbot) CCMD (addbot)
{ {
if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION) if (gamestate != GS_LEVEL)
{ {
Printf ("Bots cannot be added when not in a game!\n"); Printf ("Bots cannot be added when not in a game!\n");
return; return;

View file

@ -708,66 +708,13 @@ DEFINE_ACTION_FUNCTION(DInterBackground, drawBackground)
IMPLEMENT_CLASS(DInterBackground, true, false) IMPLEMENT_CLASS(DInterBackground, true, false)
DObject *WI_Screen;
//====================================================================
//
//
//
//====================================================================
void WI_Ticker()
{
if (WI_Screen)
{
ScaleOverrider s(twod);
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Ticker)
{
VMValue self = WI_Screen;
VMCall(func, &self, 1, nullptr, 0);
}
}
}
//====================================================================
//
// Called by main loop,
// draws the intermission directly into the screen buffer.
//
//====================================================================
void WI_Drawer()
{
if (WI_Screen)
{
ScaleOverrider s(twod);
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Drawer)
{
twod->ClearClipRect();
twod->ClearScreen();
VMValue self = WI_Screen;
VMCall(func, &self, 1, nullptr, 0);
twod->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
// The internal handling here is somewhat poor. After being set to 'LeavingIntermission'
// the screen is needed for one more draw operation so we cannot delete it right away but only here.
if (WI_Screen->IntVar("CurState") == LeavingIntermission)
{
WI_Screen->Destroy();
GC::DelSoftRoot(WI_Screen);
WI_Screen = nullptr;
}
}
}
}
//==================================================================== //====================================================================
// //
// Setup for an intermission screen. // Setup for an intermission screen.
// //
//==================================================================== //====================================================================
void WI_Start(wbstartstruct_t *wbstartstruct) DObject* WI_Start(wbstartstruct_t *wbstartstruct)
{ {
FName screenclass = deathmatch ? gameinfo.statusscreen_dm : multiplayer ? gameinfo.statusscreen_coop : gameinfo.statusscreen_single; FName screenclass = deathmatch ? gameinfo.statusscreen_dm : multiplayer ? gameinfo.statusscreen_coop : gameinfo.statusscreen_single;
auto cls = PClass::FindClass(screenclass); auto cls = PClass::FindClass(screenclass);
@ -784,7 +731,7 @@ void WI_Start(wbstartstruct_t *wbstartstruct)
} }
} }
WI_Screen = cls->CreateNew(); auto WI_Screen = cls->CreateNew();
ScaleOverrider s(twod); ScaleOverrider s(twod);
@ -814,7 +761,7 @@ void WI_Start(wbstartstruct_t *wbstartstruct)
} }
} }
GC::AddSoftRoot(WI_Screen); return WI_Screen;
} }
//==================================================================== //====================================================================

View file

@ -81,17 +81,7 @@ struct wbstartstruct_t
}; };
// Intermission stats.
// Parameters for world map / intermission.
// Called by main loop, animate the intermission.
void WI_Ticker ();
// Called by main loop,
// draws the intermission directly into the screen buffer.
void WI_Drawer ();
// Setup for an intermission screen. // Setup for an intermission screen.
void WI_Start (wbstartstruct_t *wbstartstruct); DObject* WI_Start (wbstartstruct_t *wbstartstruct);
#endif #endif