mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-13 07:31:04 +00:00
- first stage of migrating intermissions to screenjobs.
This commit is contained in:
parent
d994369fd0
commit
390bf58698
15 changed files with 171 additions and 329 deletions
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
219
src/g_level.cpp
219
src/g_level.cpp
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1282,9 +1393,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//====================================================================
|
//====================================================================
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue