Screenjob WIP stuff

This commit is contained in:
Christoph Oelckers 2022-04-11 13:12:37 +02:00
commit 1bb750c061
13 changed files with 161 additions and 132 deletions

View file

@ -143,7 +143,6 @@ extern bool playedtitlemusic;
gameaction_t gameaction;
gamestate_t gamestate = GS_STARTUP;
FName SelectedSlideshow; // what to start when ga_slideshow
int paused;
bool pauseext;
@ -1169,9 +1168,6 @@ void G_Ticker ()
case ga_completed:
G_DoCompleted ();
break;
case ga_slideshow:
if (gamestate == GS_LEVEL) F_StartIntermission(SelectedSlideshow, FSTATE_InLevel);
break;
case ga_worlddone:
G_DoWorldDone ();
break;
@ -1192,6 +1188,11 @@ void G_Ticker ()
P_ResumeConversation ();
gameaction = ga_nothing;
break;
case ga_intermission:
gamestate = GS_CUTSCENE;
break;
default:
case ga_nothing:
break;
@ -3058,8 +3059,16 @@ bool G_CheckDemoStatus (void)
void G_StartSlideshow(FLevelLocals *Level, FName whichone)
{
gameaction = ga_slideshow;
SelectedSlideshow = whichone == NAME_None ? Level->info->slideshow : whichone;
auto SelectedSlideshow = whichone == NAME_None ? Level->info->slideshow : whichone;
auto slide = F_StartIntermission(SelectedSlideshow);
RunIntermission(slide, nullptr, [](bool)
{
primaryLevel->SetMusic();
gamestate = GS_LEVEL;
wipegamestate = GS_LEVEL;
gameaction = ga_resumeconversation;
});
}
DEFINE_ACTION_FUNCTION(FLevelLocals, StartSlideshow)

View file

@ -106,6 +106,8 @@ void G_AddViewAngle (int yaw, bool mouse = false);
class FBaseCVar;
FBaseCVar* G_GetUserCVar(int playernum, const char* cvarname);
void RunIntermission(DIntermissionController* intermissionScreen, DObject* statusScreen, std::function<void(bool)> completionf);
extern const AActor *SendItemUse, *SendItemDrop;
extern int SendItemDropAmount;

View file

@ -839,7 +839,8 @@ DIntermissionController* FLevelLocals::CreateIntermission()
thiscluster = FindClusterInfo (cluster);
if (strncmp (nextlevel, "enDSeQ", 6) == 0)
bool endgame = strncmp (nextlevel, "enDSeQ", 6) == 0;
if (endgame)
{
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.
@ -902,6 +903,7 @@ DIntermissionController* FLevelLocals::CreateIntermission()
ext->mDefined & FExitText::DEF_LOOKUP,
false);
}
if (controller) controller->mEndGame = false;
return controller;
}
@ -933,9 +935,35 @@ DIntermissionController* FLevelLocals::CreateIntermission()
}
}
}
if (controller) controller->mEndGame = endgame;
return controller;
}
void RunIntermission(DIntermissionController* intermissionScreen, DObject* statusScreen, std::function<void(bool)> completionf)
{
runner = CreateRunner();
GC::WriteBarrier(runner);
completion = std::move(completionf);
auto func = LookupFunction("DoomCutscenes.BuildMapTransition");
if (func == nullptr)
{
I_Error("Script function 'DoomCutscenes.BuildMapTransition' not found");
}
VMValue val[3] = { runner, intermissionScreen, statusScreen };
VMCall(func, val, 3, nullptr, 0);
if (!ScreenJobValidate())
{
runner->Destroy();
runner = nullptr;
if (completion) completion(false);
completion = nullptr;
return;
}
gameaction = ga_intermission;
}
void G_DoCompleted (void)
{
gameaction = ga_nothing;
@ -972,17 +1000,16 @@ void G_DoCompleted (void)
DObject* statusScreen = nullptr, *intermissionScreen = nullptr;
if (playinter)
{
viewactive = false;
automapactive = false;
// [RH] If you ever get a statistics driver operational, adapt this.
// if (statcopy)
// memcpy (statcopy, &wminfo, sizeof(wminfo));
statusScreen = WI_Start (&staticWmInfo);
}
bool endgame = intermissionScreen && intermissionScreen->mEndGame;
intermissionScreen = primaryLevel->CreateIntermission();
// todo: create start of level screenjob.
RunIntermission(intermissionScreen, statusScreen, [=](bool) { if (!endgame) primaryLevel->WorldDone(); }
)
}
//==========================================================================

View file

@ -196,9 +196,9 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first)
}
int DIntermissionScreen::Responder (event_t *ev)
int DIntermissionScreen::Responder (FInputEvent *ev)
{
if (ev->type == EV_KeyDown)
if (ev->Type == EV_KeyDown)
{
return -1;
}
@ -275,9 +275,9 @@ void DIntermissionScreenFader::Init(FIntermissionAction *desc, bool first)
//
//===========================================================================
int DIntermissionScreenFader::Responder (event_t *ev)
int DIntermissionScreenFader::Responder (FInputEvent *ev)
{
if (ev->type == EV_KeyDown)
if (ev->Type == EV_KeyDown)
{
return -1;
}
@ -367,9 +367,9 @@ void DIntermissionScreenText::Init(FIntermissionAction *desc, bool first)
if (mDuration > 0) mDuration += mTextDelay + mTextSpeed * mTextLen;
}
int DIntermissionScreenText::Responder (event_t *ev)
int DIntermissionScreenText::Responder (FInputEvent *ev)
{
if (ev->type == EV_KeyDown)
if (ev->Type == EV_KeyDown)
{
if (mTicker < mTextDelay + (mTextLen * mTextSpeed))
{
@ -517,9 +517,9 @@ void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first)
}
}
int DIntermissionScreenCast::Responder (event_t *ev)
int DIntermissionScreenCast::Responder (FInputEvent *ev)
{
if (ev->type != EV_KeyDown) return 0;
if (ev->Type != EV_KeyDown) return 0;
if (castdeath)
return 1; // already in dying frames
@ -715,7 +715,7 @@ void DIntermissionScreenScroller::Init(FIntermissionAction *desc, bool first)
mScrollDir = static_cast<FIntermissionActionScroller*>(desc)->mScrollDir;
}
int DIntermissionScreenScroller::Responder (event_t *ev)
int DIntermissionScreenScroller::Responder (FInputEvent *ev)
{
int res = Super::Responder(ev);
if (res == -1 && !nointerscrollabort)
@ -835,7 +835,7 @@ void DIntermissionScreenScroller::Drawer ()
//
//==========================================================================
DIntermissionController::DIntermissionController(FIntermissionDescriptor *Desc, bool DeleteDesc, uint8_t state)
DIntermissionController::DIntermissionController(FIntermissionDescriptor *Desc, bool DeleteDesc)
{
mDesc = Desc;
mDeleteDesc = DeleteDesc;
@ -844,7 +844,6 @@ DIntermissionController::DIntermissionController(FIntermissionDescriptor *Desc,
mSentAdvance = false;
mScreen = nullptr;
mFirst = true;
mGameState = state;
}
bool DIntermissionController::NextPage ()
@ -903,13 +902,13 @@ again:
return false;
}
bool DIntermissionController::Responder (event_t *ev)
bool DIntermissionController::Responder (FInputEvent *ev)
{
if (mScreen != NULL)
{
if (ev->type == EV_KeyDown)
if (ev->Type == EV_KeyDown)
{
const char *cmd = Bindings.GetBind (ev->data1);
const char *cmd = Bindings.GetBind (ev->KeyScan);
if (cmd != nullptr)
{
@ -954,25 +953,6 @@ void DIntermissionController::Ticker ()
mAdvance = false;
if (!NextPage())
{
switch (mGameState)
{
case FSTATE_InLevel:
primaryLevel->SetMusic();
gamestate = GS_LEVEL;
wipegamestate = GS_LEVEL;
gameaction = ga_resumeconversation;
viewactive = true;
Destroy();
break;
case FSTATE_ChangingLevel:
gameaction = ga_worlddone;
Destroy();
break;
default:
break;
}
}
}
}
@ -1001,16 +981,14 @@ void DIntermissionController::OnDestroy ()
//
//==========================================================================
DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state)
DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme)
{
ScaleOverrider s(twod);
S_StopAllChannels ();
gameaction = ga_nothing;
gamestate = GS_FINALE;
if (state == FSTATE_InLevel) wipegamestate = GS_FINALE; // don't wipe when within a level.
viewactive = false;
automapactive = false;
auto CurrentIntermission = Create<DIntermissionController>(desc, deleteme, state);
//if (state == FSTATE_InLevel) wipegamestate = GS_FINALE; // don't wipe when within a level.
auto CurrentIntermission = Create<DIntermissionController>(desc, deleteme);
// If the intermission finishes straight away then cancel the wipe.
if (!CurrentIntermission->NextPage())
@ -1029,7 +1007,7 @@ DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool
//
//==========================================================================
DIntermissionController* F_StartIntermission(FName seq, uint8_t state)
DIntermissionController* F_StartIntermission(FName seq)
{
FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(seq);
if (pdesc == nullptr)
@ -1038,10 +1016,38 @@ DIntermissionController* F_StartIntermission(FName seq, uint8_t state)
}
else
{
F_StartIntermission(*pdesc, false, state);
return F_StartIntermission(*pdesc, false);
}
}
DEFINE_ACTION_FUNCTION(DIntermissionController, Responder)
{
PARAM_SELF_PROLOGUE(DIntermissionController);
PARAM_POINTER(evt, FInputEvent);
ACTION_RETURN_BOOL(self->Responder(evt));
}
DEFINE_ACTION_FUNCTION(DIntermissionController, Ticker)
{
PARAM_SELF_PROLOGUE(DIntermissionController);
self->Ticker();
ACTION_RETURN_BOOL(true);
}
DEFINE_ACTION_FUNCTION(DIntermissionController, Drawer)
{
PARAM_SELF_PROLOGUE(DIntermissionController);
self->Ticker();
return 0;
}
DEFINE_ACTION_FUNCTION(DIntermissionController, NextPage)
{
PARAM_SELF_PROLOGUE(DIntermissionController);
ACTION_RETURN_BOOL(self->NextPage());
}
#include "c_dispatch.h"
CCMD(measureintermissions)

View file

@ -10,7 +10,7 @@
#include "g_game.h"
#include "v_text.h"
struct event_t;
struct FInputEvent;
struct FState;
#define DECLARE_SUPER_CLASS(cls,parent) \
@ -176,7 +176,7 @@ public:
DIntermissionScreen() {}
virtual void Init(FIntermissionAction *desc, bool first);
virtual int Responder (event_t *ev);
virtual int Responder (FInputEvent *ev);
virtual int Ticker ();
virtual void Drawer ();
void OnDestroy() override;
@ -202,7 +202,7 @@ public:
DIntermissionScreenFader() {}
virtual void Init(FIntermissionAction *desc, bool first);
virtual int Responder (event_t *ev);
virtual int Responder (FInputEvent *ev);
virtual int Ticker ();
virtual void Drawer ();
};
@ -227,7 +227,7 @@ public:
DIntermissionScreenText() {}
virtual void Init(FIntermissionAction *desc, bool first);
virtual int Responder (event_t *ev);
virtual int Responder (FInputEvent *ev);
virtual void Drawer ();
};
@ -256,7 +256,7 @@ public:
DIntermissionScreenCast() {}
virtual void Init(FIntermissionAction *desc, bool first);
virtual int Responder (event_t *ev);
virtual int Responder (FInputEvent *ev);
virtual int Ticker ();
virtual void Drawer ();
};
@ -275,7 +275,7 @@ public:
DIntermissionScreenScroller() {}
virtual void Init(FIntermissionAction *desc, bool first);
virtual int Responder (event_t *ev);
virtual int Responder (FInputEvent *ev);
virtual void Drawer ();
};
@ -296,14 +296,13 @@ class DIntermissionController : public DObject
bool mDeleteDesc;
bool mFirst;
bool mAdvance, mSentAdvance;
uint8_t mGameState;
int mIndex;
public:
static DIntermissionController *CurrentIntermission;
bool mEndGame;
DIntermissionController(FIntermissionDescriptor *mDesc = NULL, bool mDeleteDesc = false, uint8_t state = FSTATE_ChangingLevel);
bool Responder (event_t *ev);
DIntermissionController(FIntermissionDescriptor *mDesc = NULL, bool mDeleteDesc = false);
bool Responder (FInputEvent *ev);
void Ticker ();
void Drawer ();
void OnDestroy() override;
@ -314,8 +313,8 @@ public:
// Interface for main loop
DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state);
DIntermissionController* F_StartIntermission(FName desc, uint8_t state);
DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme);
DIntermissionController* F_StartIntermission(FName desc);
// Create an intermission from old cluster data
DIntermissionController* F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,

View file

@ -41,6 +41,7 @@
#include "c_dispatch.h"
#include "gstrings.h"
#include "gi.h"
#include "screenjob.h"
static void ReplaceIntermission(FName intname,FIntermissionDescriptor *desc)
@ -922,7 +923,6 @@ DIntermissionController* F_StartFinale (const char *music, int musicorder, int c
return nullptr;
}
CCMD(testfinale)
{
if (argv.argc() < 2)
@ -954,5 +954,6 @@ CCMD(testfinale)
}
auto controller = F_StartFinale(gameinfo.finaleMusic, gameinfo.finaleOrder, -1, 0, gameinfo.FinaleFlat, text, false, false, true, true);
// todo: play it
RunIntermission(controller, nullptr, [=](bool) { gameaction = ga_nothing; });
}

View file

@ -33,6 +33,7 @@
*/
#include <assert.h>
#include <stdint.h>
#include "actor.h"
#include "p_conversation.h"
@ -489,7 +490,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
if (!(npc->flags8 & MF8_DONTFACETALKER))
npc->Angles.Yaw = player->ConversationNPCAngle;
npc->flags5 &= ~MF5_INCONVERSATION;
if (gameaction != ga_slideshow) ClearConversationStuff(player);
if (gameaction != ga_intermission) ClearConversationStuff(player);
return;
}
@ -507,7 +508,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
if (!(npc->flags8 & MF8_DONTFACETALKER))
npc->Angles.Yaw = player->ConversationNPCAngle;
npc->flags5 &= ~MF5_INCONVERSATION;
if (gameaction != ga_slideshow) ClearConversationStuff(player);
if (gameaction != ga_intermission) ClearConversationStuff(player);
return;
}
}
@ -548,7 +549,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
}
if (reply->GiveType->IsDescendantOf("SlideshowStarter"))
gameaction = ga_slideshow;
G_StartSlideshow(primaryLevel, NAME_None);
}
else
{
@ -617,7 +618,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
if (!(reply->CloseDialog))
{
if (gameaction != ga_slideshow)
if (gameaction != ga_intermission)
{
P_StartConversation (npc, player->mo, player->ConversationFaceTalker, false);
return;
@ -643,7 +644,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
// [CW] Set these to NULL because we're not using to them
// anymore. However, this can interfere with slideshows
// so we don't set them to NULL in that case.
if (gameaction != ga_slideshow)
if (gameaction != ga_intermission)
{
npc->flags5 &= ~MF5_INCONVERSATION;
ClearConversationStuff(player);