- got rid of JobDesc.

This commit is contained in:
Christoph Oelckers 2021-04-22 00:51:14 +02:00
parent 805b91b721
commit 4a7430c8e4
10 changed files with 165 additions and 174 deletions

View file

@ -117,15 +117,14 @@ void DImageScreen::Draw(double smoothratio)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
ScreenJobRunner::ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_, bool skipall_) ScreenJobRunner::ScreenJobRunner(TArray<DScreenJob*>& jobs_, CompletionFunc completion_, bool clearbefore_, bool skipall_)
: completion(std::move(completion_)), clearbefore(clearbefore_), skipall(skipall_) : completion(std::move(completion_)), clearbefore(clearbefore_), skipall(skipall_)
{ {
jobs.Resize(count); jobs = std::move(jobs_);
memcpy(jobs.Data(), jobs_, count * sizeof(JobDesc));
// Release all jobs from the garbage collector - the code as it is cannot deal with them getting collected. This should be removed later once the GC is working. // Release all jobs from the garbage collector - the code as it is cannot deal with them getting collected. This should be removed later once the GC is working.
for (int i = 0; i < count; i++) for (unsigned i = 0; i < jobs.Size(); i++)
{ {
jobs[i].job->Release(); jobs[i]->Release();
} }
AdvanceJob(false); AdvanceJob(false);
} }
@ -145,8 +144,8 @@ void ScreenJobRunner::DeleteJobs()
{ {
for (auto& job : jobs) for (auto& job : jobs)
{ {
job.job->ObjectFlags |= OF_YesReallyDelete; job->ObjectFlags |= OF_YesReallyDelete;
delete job.job; delete job;
} }
jobs.Clear(); jobs.Clear();
} }
@ -162,19 +161,19 @@ void ScreenJobRunner::AdvanceJob(bool skip)
if (index >= 0) if (index >= 0)
{ {
//if (jobs[index].postAction) jobs[index].postAction(); //if (jobs[index].postAction) jobs[index].postAction();
jobs[index].job->Destroy(); jobs[index]->Destroy();
} }
index++; index++;
while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && skipall))) while (index < jobs.Size() && (jobs[index] == nullptr || (skip && skipall)))
{ {
if (jobs[index].job != nullptr) jobs[index].job->Destroy(); if (jobs[index] != nullptr) jobs[index]->Destroy();
index++; index++;
} }
actionState = clearbefore ? State_Clear : State_Run; actionState = clearbefore ? State_Clear : State_Run;
if (index < jobs.Size()) if (index < jobs.Size())
{ {
jobs[index].job->fadestate = !paused && jobs[index].job->flags & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible; jobs[index]->fadestate = !paused && jobs[index]->flags & DScreenJob::fadein? DScreenJob::fadein : DScreenJob::visible;
jobs[index].job->Start(); jobs[index]->Start();
} }
inputState.ClearAllInput(); inputState.ClearAllInput();
} }
@ -189,16 +188,16 @@ int ScreenJobRunner::DisplayFrame(double smoothratio)
{ {
auto& job = jobs[index]; auto& job = jobs[index];
auto now = I_GetTimeNS(); auto now = I_GetTimeNS();
bool processed = job.job->ProcessInput(); bool processed = job->ProcessInput();
if (job.job->fadestate == DScreenJob::fadein) if (job->fadestate == DScreenJob::fadein)
{ {
double ms = (job.job->ticks + smoothratio) * 1000 / GameTicRate / job.job->fadetime; double ms = (job->ticks + smoothratio) * 1000 / GameTicRate / job->fadetime;
float screenfade = (float)clamp(ms, 0., 1.); float screenfade = (float)clamp(ms, 0., 1.);
twod->SetScreenFade(screenfade); twod->SetScreenFade(screenfade);
if (screenfade == 1.f) job.job->fadestate = DScreenJob::visible; if (screenfade == 1.f) job->fadestate = DScreenJob::visible;
} }
int state = job.job->DrawFrame(smoothratio); int state = job->DrawFrame(smoothratio);
twod->SetScreenFade(1.f); twod->SetScreenFade(1.f);
return state; return state;
} }
@ -206,10 +205,10 @@ int ScreenJobRunner::DisplayFrame(double smoothratio)
int ScreenJobRunner::FadeoutFrame(double smoothratio) int ScreenJobRunner::FadeoutFrame(double smoothratio)
{ {
auto& job = jobs[index]; auto& job = jobs[index];
double ms = (fadeticks + smoothratio) * 1000 / GameTicRate / job.job->fadetime; double ms = (fadeticks + smoothratio) * 1000 / GameTicRate / job->fadetime;
float screenfade = 1.f - (float)clamp(ms, 0., 1.); float screenfade = 1.f - (float)clamp(ms, 0., 1.);
twod->SetScreenFade(screenfade); twod->SetScreenFade(screenfade);
job.job->DrawFrame(1.); job->DrawFrame(1.);
return (screenfade > 0.f); return (screenfade > 0.f);
} }
@ -234,9 +233,9 @@ bool ScreenJobRunner::OnEvent(event_t* ev)
} }
} }
if (jobs[index].job->state != DScreenJob::running) return false; if (jobs[index]->state != DScreenJob::running) return false;
return jobs[index].job->OnEvent(ev); return jobs[index]->OnEvent(ev);
} }
void ScreenJobRunner::OnFinished() void ScreenJobRunner::OnFinished()
@ -258,12 +257,12 @@ void ScreenJobRunner::OnTick()
} }
else else
{ {
if (jobs[index].job->state == DScreenJob::running) if (jobs[index]->state == DScreenJob::running)
{ {
jobs[index].job->ticks++; jobs[index]->ticks++;
jobs[index].job->OnTick(); jobs[index]->OnTick();
} }
else if (jobs[index].job->state == DScreenJob::stopping) else if (jobs[index]->state == DScreenJob::stopping)
{ {
fadeticks++; fadeticks++;
} }
@ -289,8 +288,8 @@ bool ScreenJobRunner::RunFrame()
// ensure that we won't go back in time if the menu is dismissed without advancing our ticker // ensure that we won't go back in time if the menu is dismissed without advancing our ticker
bool menuon = paused; bool menuon = paused;
if (menuon) last_paused_tic = jobs[index].job->ticks; if (menuon) last_paused_tic = jobs[index]->ticks;
else if (last_paused_tic == jobs[index].job->ticks) menuon = true; else if (last_paused_tic == jobs[index]->ticks) menuon = true;
double smoothratio = menuon ? 1. : I_GetTimeFrac(); double smoothratio = menuon ? 1. : I_GetTimeFrac();
if (actionState == State_Clear) if (actionState == State_Clear)
@ -304,10 +303,10 @@ bool ScreenJobRunner::RunFrame()
if (terminateState < 1) if (terminateState < 1)
{ {
// Must lock before displaying. // Must lock before displaying.
if (jobs[index].job->flags & DScreenJob::fadeout) if (jobs[index]->flags & DScreenJob::fadeout)
{ {
jobs[index].job->fadestate = DScreenJob::fadeout; jobs[index]->fadestate = DScreenJob::fadeout;
jobs[index].job->state = DScreenJob::stopping; jobs[index]->state = DScreenJob::stopping;
actionState = State_Fadeout; actionState = State_Fadeout;
fadeticks = 0; fadeticks = 0;
} }
@ -322,7 +321,7 @@ bool ScreenJobRunner::RunFrame()
int ended = FadeoutFrame(smoothratio); int ended = FadeoutFrame(smoothratio);
if (ended < 1) if (ended < 1)
{ {
jobs[index].job->state = DScreenJob::stopped; jobs[index]->state = DScreenJob::stopped;
AdvanceJob(terminateState < 0); AdvanceJob(terminateState < 0);
} }
} }
@ -337,13 +336,13 @@ bool ScreenJobRunner::RunFrame()
ScreenJobRunner *runner; ScreenJobRunner *runner;
void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, int flags) void RunScreenJob(TArray<DScreenJob*>& jobs, CompletionFunc completion, int flags)
{ {
assert(completion != nullptr); assert(completion != nullptr);
videoclearFade(); videoclearFade();
if (count) if (jobs.Size())
{ {
runner = new ScreenJobRunner(jobs, count, completion, !(flags & SJ_DONTCLEAR), !!(flags & SJ_SKIPALL)); runner = new ScreenJobRunner(jobs, completion, !(flags & SJ_DONTCLEAR), !!(flags & SJ_SKIPALL));
gameaction = (flags & SJ_BLOCKUI)? ga_intro : ga_intermission; gameaction = (flags & SJ_BLOCKUI)? ga_intro : ga_intermission;
} }
else else

View file

@ -138,12 +138,6 @@ public:
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
struct JobDesc
{
DScreenJob* job;
};
class ScreenJobRunner class ScreenJobRunner
{ {
enum enum
@ -152,7 +146,7 @@ class ScreenJobRunner
State_Run, State_Run,
State_Fadeout State_Fadeout
}; };
TArray<JobDesc> jobs; TArray<DScreenJob*> jobs;
CompletionFunc completion; CompletionFunc completion;
int index = -1; int index = -1;
float screenfade; float screenfade;
@ -164,7 +158,7 @@ class ScreenJobRunner
int last_paused_tic = -1; int last_paused_tic = -1;
public: public:
ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_, bool skipall_); ScreenJobRunner(TArray<DScreenJob*>& jobs, CompletionFunc completion_, bool clearbefore_, bool skipall_);
~ScreenJobRunner(); ~ScreenJobRunner();
void DeleteJobs(); void DeleteJobs();
void AdvanceJob(bool skip); void AdvanceJob(bool skip);
@ -186,7 +180,7 @@ enum
}; };
void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, int flags = 0); void RunScreenJob(TArray<DScreenJob*>& jobs, CompletionFunc completion, int flags = 0);
void EndScreenJob(); void EndScreenJob();
void DeleteScreenJob(); void DeleteScreenJob();
bool ScreenJobResponder(event_t* ev); bool ScreenJobResponder(event_t* ev);

View file

@ -59,8 +59,7 @@ public:
void playlogos() void playlogos()
{ {
JobDesc jobs[6]; TArray<DScreenJob*> jobs;
int job = 0;
static AnimSound logosound[] = static AnimSound logosound[] =
{ {
{ 1, -1 }, { 1, -1 },
@ -80,25 +79,25 @@ void playlogos()
{ {
if (fileSystem.FindFile("logo.smk") != -1) if (fileSystem.FindFile("logo.smk") != -1)
{ {
jobs[job++] = { PlayVideo("logo.smk", &logosound[0], 0) }; jobs.Push(PlayVideo("logo.smk", &logosound[0], 0));
} }
else else
{ {
jobs[job++] = { Create<DBloodIntroImage>(2050) }; jobs.Push(Create<DBloodIntroImage>(2050));
} }
if (fileSystem.FindFile("gti.smk") != -1) if (fileSystem.FindFile("gti.smk") != -1)
{ {
jobs[job++] = { PlayVideo("gti.smk", &logosound[2], 0) }; jobs.Push(PlayVideo("gti.smk", &logosound[2], 0));
} }
else else
{ {
jobs[job++] = { Create<DBloodIntroImage>(2052) }; jobs.Push(Create<DBloodIntroImage>(2052));
} }
} }
jobs[job++] = { Create<DBlackScreen>(1) }; jobs.Push(Create<DBlackScreen>(1));
jobs[job++] = { Create<DBloodIntroImage>(2518, DScreenJob::fadein, true) }; jobs.Push(Create<DBloodIntroImage>(2518, DScreenJob::fadein, true));
RunScreenJob(jobs, job, [](bool) { RunScreenJob(jobs, [](bool) {
Mus_Stop(); Mus_Stop();
gameaction = ga_mainmenu; gameaction = ga_mainmenu;
}, SJ_BLOCKUI); }, SJ_BLOCKUI);
@ -106,7 +105,7 @@ void playlogos()
void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func) void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func)
{ {
JobDesc jobs{}; TArray<DScreenJob*> jobs;
static AnimSound smksound[] = static AnimSound smksound[] =
{ {
{ 1, -1 }, { 1, -1 },
@ -127,8 +126,8 @@ void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func)
FString smkk = smk; FString smkk = smk;
FixPathSeperator(smkk); FixPathSeperator(smkk);
smksound[0].soundnum = id; smksound[0].soundnum = id;
jobs.job = PlayVideo(smkk, smksound, nullptr); jobs.Push(PlayVideo(smkk, smksound, nullptr));
RunScreenJob(&jobs, 1, func); RunScreenJob(jobs, func);
} }
void levelPlayIntroScene(int nEpisode, CompletionFunc completion) void levelPlayIntroScene(int nEpisode, CompletionFunc completion)

View file

@ -173,10 +173,11 @@ class DBloodSummaryScreen : public DSkippableScreenJob
void GameInterface::LevelCompleted(MapRecord *map, int skill) void GameInterface::LevelCompleted(MapRecord *map, int skill)
{ {
JobDesc job = { Create<DBloodSummaryScreen>() }; TArray<DScreenJob*> job(1, true);
job[0] = Create<DBloodSummaryScreen>();
sndStartSample(268, 128, -1, false, CHANF_UI); sndStartSample(268, 128, -1, false, CHANF_UI);
Mus_Stop(); Mus_Stop();
RunScreenJob(&job, 1, [=](bool) RunScreenJob(job, [=](bool)
{ {
soundEngine->StopAllChannels(); soundEngine->StopAllChannels();
gameaction = ga_nextlevel; gameaction = ga_nextlevel;
@ -301,8 +302,9 @@ public:
void loadscreen(const char *caption, MapRecord* rec, CompletionFunc func) void loadscreen(const char *caption, MapRecord* rec, CompletionFunc func)
{ {
JobDesc job = { Create<DBloodLoadScreen>(caption, rec) }; TArray<DScreenJob*> job(1, true);
RunScreenJob(&job, 1, func); job[0] = Create<DBloodLoadScreen>(caption, rec);
RunScreenJob(job, func);
} }

View file

@ -312,15 +312,15 @@ void Logo_d(const CompletionFunc &completion)
}; };
static const int logoframetimes[] = { 9, 9, 9 }; static const int logoframetimes[] = { 9, 9, 9 };
JobDesc jobs[3]; TArray<DScreenJob*> jobs;
int job = 0; int job = 0;
if (!userConfig.nologo) if (!userConfig.nologo)
{ {
if (!isShareware()) jobs[job++] = { PlayVideo("logo.anm", logosound, logoframetimes) }; if (!isShareware()) jobs.Push(PlayVideo("logo.anm", logosound, logoframetimes));
if (!isNam()) jobs[job++] = { Create<DDRealmsScreen>(), }; if (!isNam()) jobs.Push(Create<DDRealmsScreen>());
} }
jobs[job++] = { Create<DTitleScreen>() }; jobs.Push(Create<DTitleScreen>());
RunScreenJob(jobs, job, completion, SJ_BLOCKUI); RunScreenJob(jobs, completion, SJ_BLOCKUI);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -612,7 +612,7 @@ public:
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void bonussequence_d(int num, JobDesc *jobs, int &job) static void bonussequence_d(int num, TArray<DScreenJob*>& jobs)
{ {
static const AnimSound cineov2sound[] = static const AnimSound cineov2sound[] =
{ {
@ -679,45 +679,45 @@ static void bonussequence_d(int num, JobDesc *jobs, int &job)
switch (num) switch (num)
{ {
case 0: case 0:
jobs[job++] = { Create<DEpisode1End1>() }; jobs.Push(Create<DEpisode1End1>());
jobs[job++] = { Create<DImageScreen>(E1ENDSCREEN, DScreenJob::fadein|DScreenJob::fadeout|DScreenJob::stopmusic, 0x7fffffff) }; jobs.Push(Create<DImageScreen>(E1ENDSCREEN, DScreenJob::fadein|DScreenJob::fadeout|DScreenJob::stopmusic, 0x7fffffff));
break; break;
case 1: case 1:
Mus_Stop(); Mus_Stop();
jobs[job++] = { PlayVideo("cineov2.anm", cineov2sound, framespeed_18) }; jobs.Push(PlayVideo("cineov2.anm", cineov2sound, framespeed_18));
jobs[job++] = { Create<DE2EndScreen>() }; jobs.Push(Create<DE2EndScreen>());
break; break;
case 2: case 2:
Mus_Stop(); Mus_Stop();
if (g_gameType & GAMEFLAG_DUKEDC) if (g_gameType & GAMEFLAG_DUKEDC)
{ {
jobs[job++] = { PlayVideo("radlogo.anm", dukedcsound, framespeed_10) }; jobs.Push(PlayVideo("radlogo.anm", dukedcsound, framespeed_10));
} }
else else
{ {
jobs[job++] = { PlayVideo("cineov3.anm", cineov3sound, framespeed_10) }; jobs.Push(PlayVideo("cineov3.anm", cineov3sound, framespeed_10));
jobs[job++] = { Create<DBlackScreen>(200, DScreenJob::stopsound) }; jobs.Push(Create<DBlackScreen>(200, DScreenJob::stopsound));
jobs[job++] = { Create<DEpisode3End>() }; jobs.Push(Create<DEpisode3End>());
if (!isPlutoPak()) jobs[job++] = { Create<DImageScreen>(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), if (!isPlutoPak()) jobs.Push(Create<DImageScreen>(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup),
DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff) }; DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff));
} }
break; break;
case 3: case 3:
Mus_Stop(); Mus_Stop();
jobs[job++] = { PlayVideo("vol4e1.anm", vol4e1, framespeed_10) }; jobs.Push(PlayVideo("vol4e1.anm", vol4e1, framespeed_10));
jobs[job++] = { PlayVideo("vol4e2.anm", vol4e2, framespeed_10) }; jobs.Push(PlayVideo("vol4e2.anm", vol4e2, framespeed_10));
jobs[job++] = { PlayVideo("vol4e3.anm", vol4e3, framespeed_10) }; jobs.Push(PlayVideo("vol4e3.anm", vol4e3, framespeed_10));
jobs[job++] = { Create<DEpisode4Text>() }; jobs.Push(Create<DEpisode4Text>());
jobs[job++] = { Create<DImageScreen>(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup), jobs.Push(Create<DImageScreen>(TexMan.GetGameTextureByName("DUKETEAM.ANM", false, FTextureManager::TEXMAN_ForceLookup),
DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff) }; DScreenJob::fadein | DScreenJob::fadeout | DScreenJob::stopsound, 0x7fffffff));
break; break;
case 4: case 4:
Mus_Stop(); Mus_Stop();
jobs[job++] = { Create<DEpisode5End>() }; jobs.Push(Create<DEpisode5End>());
break; break;
} }
} }
@ -730,22 +730,20 @@ static void bonussequence_d(int num, JobDesc *jobs, int &job)
void showtwoscreens(const CompletionFunc& completion) void showtwoscreens(const CompletionFunc& completion)
{ {
JobDesc jobs[2]; TArray<DScreenJob*> jobs;
int job = 0;
jobs[job++] = { Create<DImageScreen>(3291) }; jobs.Push(Create<DImageScreen>(3291));
jobs[job++] = { Create<DImageScreen>(3290) }; jobs.Push(Create<DImageScreen>(3290));
RunScreenJob(jobs, job, completion); RunScreenJob(jobs, completion);
} }
void doorders(const CompletionFunc& completion) void doorders(const CompletionFunc& completion)
{ {
JobDesc jobs[4]; TArray<DScreenJob*> jobs;
int job = 0;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
jobs[job++] = { Create<DImageScreen>(ORDERING + i) }; jobs.Push(Create<DImageScreen>(ORDERING + i));
RunScreenJob(jobs, job, completion); RunScreenJob(jobs, completion);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1097,29 +1095,28 @@ public:
void dobonus_d(int bonusonly, const CompletionFunc& completion) void dobonus_d(int bonusonly, const CompletionFunc& completion)
{ {
JobDesc jobs[20]; TArray<DScreenJob*> jobs;
int job = 0;
FX_StopAllSounds(); FX_StopAllSounds();
if (bonusonly < 0 && numplayers < 2 && ud.from_bonus == 0) if (bonusonly < 0 && numplayers < 2 && ud.from_bonus == 0)
{ {
bonussequence_d(volfromlevelnum(currentLevel->levelNumber), jobs, job); bonussequence_d(volfromlevelnum(currentLevel->levelNumber), jobs);
} }
else else
Mus_Stop(); Mus_Stop();
if (playerswhenstarted > 1 && ud.coop != 1) if (playerswhenstarted > 1 && ud.coop != 1)
{ {
jobs[job++] = { Create<DDukeMultiplayerBonusScreen>(playerswhenstarted) }; jobs.Push(Create<DDukeMultiplayerBonusScreen>(playerswhenstarted));
} }
else if (bonusonly <= 0 && ud.multimode <= 1) else if (bonusonly <= 0 && ud.multimode <= 1)
{ {
jobs[job++] = { Create<DDukeLevelSummaryScreen>() }; jobs.Push(Create<DDukeLevelSummaryScreen>());
} }
if (job) if (jobs.Size())
{ {
RunScreenJob(jobs, job, completion); RunScreenJob(jobs, completion);
} }
else if (completion) completion(false); else if (completion) completion(false);
} }
@ -1132,8 +1129,7 @@ void dobonus_d(int bonusonly, const CompletionFunc& completion)
void e4intro(const CompletionFunc& completion) void e4intro(const CompletionFunc& completion)
{ {
JobDesc jobs[5]; TArray<DScreenJob*> jobs;
int job = 0;
static const AnimSound vol42a[] = static const AnimSound vol42a[] =
{ {
@ -1163,10 +1159,10 @@ void e4intro(const CompletionFunc& completion)
static const int framespeed_14[] = { 14, 14, 14 }; static const int framespeed_14[] = { 14, 14, 14 };
S_PlaySpecialMusic(MUS_BRIEFING); S_PlaySpecialMusic(MUS_BRIEFING);
jobs[job++] = { PlayVideo("vol41a.anm", vol41a, framespeed_10) }; jobs.Push(PlayVideo("vol41a.anm", vol41a, framespeed_10));
jobs[job++] = { PlayVideo("vol42a.anm", vol42a, framespeed_14) }; jobs.Push(PlayVideo("vol42a.anm", vol42a, framespeed_14));
jobs[job++] = { PlayVideo("vol43a.anm", vol43a, framespeed_10) }; jobs.Push(PlayVideo("vol43a.anm", vol43a, framespeed_10));
RunScreenJob(jobs, job, completion, SJ_SKIPALL); RunScreenJob(jobs, completion, SJ_SKIPALL);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1194,8 +1190,10 @@ public:
void loadscreen_d(MapRecord *rec, CompletionFunc func) void loadscreen_d(MapRecord *rec, CompletionFunc func)
{ {
JobDesc job = { Create<DDukeLoadScreen>(rec) }; TArray<DScreenJob*> jobs(1, true);
RunScreenJob(&job, 1, func);
jobs[0] = Create<DDukeLoadScreen>(rec);
RunScreenJob(jobs, func);
} }
void PrintPaused_d() void PrintPaused_d()

View file

@ -186,8 +186,7 @@ void Logo_r(const CompletionFunc& completion)
static const int framespeed[] = { 9, 9, 9 }; // same for all 3 anims static const int framespeed[] = { 9, 9, 9 }; // same for all 3 anims
JobDesc jobs[3]; TArray<DScreenJob*> jobs;
int job = 0;
if (userConfig.nologo) if (userConfig.nologo)
{ {
@ -196,15 +195,15 @@ void Logo_r(const CompletionFunc& completion)
} }
else if (!isRRRA()) else if (!isRRRA())
{ {
jobs[job++] = { PlayVideo("rr_intro.anm", introsound, framespeed) }; jobs.Push(PlayVideo("rr_intro.anm", introsound, framespeed));
jobs[job++] = { PlayVideo("redneck.anm", rednecksound, framespeed) }; jobs.Push(PlayVideo("redneck.anm", rednecksound, framespeed));
jobs[job++] = { PlayVideo("xatlogo.anm", xatrixsound, framespeed) }; jobs.Push(PlayVideo("xatlogo.anm", xatrixsound, framespeed));
} }
else else
{ {
jobs[job++] = { PlayVideo("redint.mve") }; jobs.Push(PlayVideo("redint.mve"));
} }
RunScreenJob(jobs, job, completion, SJ_BLOCKUI); RunScreenJob(jobs, completion, SJ_BLOCKUI);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -213,7 +212,7 @@ void Logo_r(const CompletionFunc& completion)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void bonussequence_r(int num, JobDesc* jobs, int& job) static void bonussequence_r(int num, TArray<DScreenJob*>& jobs)
{ {
static const AnimSound turdmov[] = static const AnimSound turdmov[] =
{ {
@ -235,13 +234,13 @@ static void bonussequence_r(int num, JobDesc* jobs, int& job)
switch (num) switch (num)
{ {
case 0: case 0:
jobs[job++] = { PlayVideo("turdmov.anm", turdmov, framespeed) }; jobs.Push(PlayVideo("turdmov.anm", turdmov, framespeed));
jobs[job++] = { Create<DImageScreen>(TENSCREEN) }; jobs.Push(Create<DImageScreen>(TENSCREEN));
break; break;
case 1: case 1:
jobs[job++] = { PlayVideo("rr_outro.anm", rr_outro, framespeed) }; jobs.Push(PlayVideo("rr_outro.anm", rr_outro, framespeed));
jobs[job++] = { Create<DImageScreen>(TENSCREEN) }; jobs.Push(Create<DImageScreen>(TENSCREEN));
break; break;
default: default:
@ -594,8 +593,7 @@ public:
void dobonus_r(int bonusonly, const CompletionFunc& completion) void dobonus_r(int bonusonly, const CompletionFunc& completion)
{ {
JobDesc jobs[20]; TArray<DScreenJob*> jobs;
int job = 0;
FX_StopAllSounds(); FX_StopAllSounds();
Mus_Stop(); Mus_Stop();
@ -603,32 +601,32 @@ void dobonus_r(int bonusonly, const CompletionFunc& completion)
if (bonusonly < 0 && !isRRRA() && numplayers < 2 && ud.from_bonus == 0) if (bonusonly < 0 && !isRRRA() && numplayers < 2 && ud.from_bonus == 0)
{ {
int vol = volfromlevelnum(currentLevel->levelNumber); int vol = volfromlevelnum(currentLevel->levelNumber);
bonussequence_r(vol, jobs, job); bonussequence_r(vol, jobs);
} }
if (playerswhenstarted > 1 && ud.coop != 1) if (playerswhenstarted > 1 && ud.coop != 1)
{ {
jobs[job++] = { Create<DRRMultiplayerBonusScreen>(playerswhenstarted) }; jobs.Push(Create<DRRMultiplayerBonusScreen>(playerswhenstarted));
} }
else if (bonusonly <= 0 && ud.multimode <= 1) else if (bonusonly <= 0 && ud.multimode <= 1)
{ {
if (isRRRA() && !(currentLevel->flags & MI_USERMAP) && currentLevel->levelNumber < 106) // fixme: The logic here is awful. Shift more control to the map records. if (isRRRA() && !(currentLevel->flags & MI_USERMAP) && currentLevel->levelNumber < 106) // fixme: The logic here is awful. Shift more control to the map records.
{ {
jobs[job++] = { Create<DRRLevelSummaryScreen>(true) }; jobs.Push(Create<DRRLevelSummaryScreen>(true));
int levnum = clamp((currentLevel->levelNumber / 100) * 7 + (currentLevel->levelNumber % 100), 0, 13); int levnum = clamp((currentLevel->levelNumber / 100) * 7 + (currentLevel->levelNumber % 100), 0, 13);
char fn[20]; char fn[20];
mysnprintf(fn, 20, "lvl%d.anm", levnum + 1); mysnprintf(fn, 20, "lvl%d.anm", levnum + 1);
static const int framespeed[] = { 20, 20, 7200 }; // wait for one minute on the final frame so that the video doesn't stop before the user notices. static const int framespeed[] = { 20, 20, 7200 }; // wait for one minute on the final frame so that the video doesn't stop before the user notices.
jobs[job++] = { PlayVideo(fn, nullptr, framespeed) }; jobs.Push(PlayVideo(fn, nullptr, framespeed));
if (bonusonly < 0 && currentLevel->levelNumber > 100) if (bonusonly < 0 && currentLevel->levelNumber > 100)
{ {
jobs[job++] = { Create<DRRRAEndOfGame>() }; jobs.Push(Create<DRRRAEndOfGame>());
} }
} }
else jobs[job++] = { Create<DRRLevelSummaryScreen>(false) }; else jobs.Push(Create<DRRLevelSummaryScreen>(false));
} }
if (job) if (jobs.Size())
RunScreenJob(jobs, job, completion); RunScreenJob(jobs, completion);
else if (completion) completion(false); else if (completion) completion(false);
} }
@ -658,8 +656,10 @@ public:
void loadscreen_r(MapRecord* rec, CompletionFunc func) void loadscreen_r(MapRecord* rec, CompletionFunc func)
{ {
JobDesc job = { Create<DRRLoadScreen>(rec) }; TArray<DScreenJob*> jobs(1, true);
RunScreenJob(&job, 1, func);
jobs[0] = Create<DRRLoadScreen>(rec);
RunScreenJob(jobs, func);
} }
void PrintPaused_r() void PrintPaused_r()

View file

@ -520,15 +520,14 @@ DScreenJob *PlayMovie(const char* fileName);
void DoTitle(CompletionFunc completion) void DoTitle(CompletionFunc completion)
{ {
JobDesc jobs[5]; TArray<DScreenJob*> jobs;
int job = 0;
jobs[job++] = { Create<DImageScreen>(tileGetTexture(PublisherLogo()), DScreenJob::fadein | DScreenJob::fadeout) }; jobs.Push(Create<DImageScreen>(tileGetTexture(PublisherLogo()), DScreenJob::fadein | DScreenJob::fadeout));
jobs[job++] = { Create<DLobotomyScreen>(tileGetTexture(seq_GetSeqPicnum(kSeqScreens, 0, 0)), DScreenJob::fadein | DScreenJob::fadeout) }; jobs.Push(Create<DLobotomyScreen>(tileGetTexture(seq_GetSeqPicnum(kSeqScreens, 0, 0)), DScreenJob::fadein | DScreenJob::fadeout));
jobs[job++] = { PlayMovie("book.mov") }; jobs.Push(PlayMovie("book.mov"));
jobs[job++] = { Create<DMainTitle>() }; jobs.Push(Create<DMainTitle>());
RunScreenJob(jobs, job, completion, SJ_BLOCKUI); RunScreenJob(jobs, completion, SJ_BLOCKUI);
} }
@ -815,7 +814,7 @@ public:
} }
}; };
void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray<JobDesc> &jobs) void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray<DScreenJob*> &jobs)
{ {
if (nLevel > kMap20 || nLevelNew > kMap20) // max single player levels if (nLevel > kMap20 || nLevelNew > kMap20) // max single player levels
{ {
@ -829,7 +828,7 @@ public:
if (nLevelNew < 1) nLevelNew = nLevel; if (nLevelNew < 1) nLevelNew = nLevel;
// 0-offset the level numbers // 0-offset the level numbers
jobs.Push( { Create<DMapScreen>(nLevel-1, nLevelNew-1, nLevelBest-1) }); jobs.Push(Create<DMapScreen>(nLevel-1, nLevelNew-1, nLevelBest-1));
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1346,37 +1345,37 @@ public:
void DoGameOverScene(bool finallevel) void DoGameOverScene(bool finallevel)
{ {
JobDesc job; TArray<DScreenJob*> jobs(1, true);
if (finallevel) if (finallevel)
{ {
job = { Create<DCinema>(CINEMA_LOSE_SCENE) }; jobs[0] = Create<DCinema>(CINEMA_LOSE_SCENE);
} }
else else
{ {
StopCD(); StopCD();
PlayGameOverSound(); PlayGameOverSound();
job = { Create<DImageScreen>(tileGetTexture(kTile3591), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff, TRANSLATION(Translation_BasePalettes, 16)) }; jobs[0] = Create<DImageScreen>(tileGetTexture(kTile3591), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff, TRANSLATION(Translation_BasePalettes, 16));
} }
RunScreenJob(&job, 1, [](bool) { gameaction = ga_mainmenu; }); RunScreenJob(jobs, [](bool) { gameaction = ga_mainmenu; });
} }
void DoAfterCinemaScene(int nLevel, TArray<JobDesc>& jobs) void DoAfterCinemaScene(int nLevel, TArray<DScreenJob*>& jobs)
{ {
int scene = -1; int scene = -1;
if (nLevel == 10) scene = CINEMA_AFTER_LEVEL_10; if (nLevel == 10) scene = CINEMA_AFTER_LEVEL_10;
if (nLevel == 15) scene = CINEMA_AFTER_LEVEL_15; if (nLevel == 15) scene = CINEMA_AFTER_LEVEL_15;
if (nLevel == 20) scene = CINEMA_AFTER_LEVEL_20; if (nLevel == 20) scene = CINEMA_AFTER_LEVEL_20;
if (scene > 0) jobs.Push({ Create<DCinema>(scene) }); if (scene > 0) jobs.Push(Create<DCinema>(scene));
if (nLevel == 19) { jobs.Push({ Create<DLastLevelCinema>() }); selectedlevelnew = 20; } if (nLevel == 19) { jobs.Push(Create<DLastLevelCinema>()); selectedlevelnew = 20; }
if (nLevel == 20) jobs.Push({ Create<DExCredits>() }); if (nLevel == 20) jobs.Push(Create<DExCredits>());
} }
void DoBeforeCinemaScene(int nLevel, TArray<JobDesc>& jobs) void DoBeforeCinemaScene(int nLevel, TArray<DScreenJob*>& jobs)
{ {
if (nLevel == 5) jobs.Push({ Create<DCinema>(CINEMA_BEFORE_LEVEL_5) }); if (nLevel == 5) jobs.Push(Create<DCinema>(CINEMA_BEFORE_LEVEL_5));
else if (nLevel == 11) jobs.Push({ Create<DCinema>(CINEMA_BEFORE_LEVEL_11, 11) }); else if (nLevel == 11) jobs.Push(Create<DCinema>(CINEMA_BEFORE_LEVEL_11, 11));
} }
END_PS_NS END_PS_NS

View file

@ -54,8 +54,8 @@ void SetHiRes();
void BlackOut(); void BlackOut();
void DoGameOverScene(bool finallevel); void DoGameOverScene(bool finallevel);
void DoAfterCinemaScene(int nLevel, TArray<JobDesc> &jobs); void DoAfterCinemaScene(int nLevel, TArray<DScreenJob*> &jobs);
void DoBeforeCinemaScene(int nLevel, TArray<JobDesc>& jobs); void DoBeforeCinemaScene(int nLevel, TArray<DScreenJob*>& jobs);
int Query(short n, short l, ...); int Query(short n, short l, ...);
@ -88,7 +88,7 @@ void InitNewGame();
int showmap(short nLevel, short nLevelNew, short nLevelBest); int showmap(short nLevel, short nLevelNew, short nLevelBest);
void menu_DoPlasma(); void menu_DoPlasma();
void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray<JobDesc>& jobs); void menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest, TArray<DScreenJob*>& jobs);
void DoEnergyTile(); void DoEnergyTile();
void InitEnergyTile(); void InitEnergyTile();

View file

@ -62,7 +62,7 @@ void DrawClock();
double calc_smoothratio(); double calc_smoothratio();
void DoTitle(CompletionFunc completion); void DoTitle(CompletionFunc completion);
static void showmap(short nLevel, short nLevelNew, short nLevelBest, TArray<JobDesc> &jobs) static void showmap(short nLevel, short nLevelNew, short nLevelBest, TArray<DScreenJob*> &jobs)
{ {
if (nLevelNew == 5 && !(nCinemaSeen & 1)) { if (nLevelNew == 5 && !(nCinemaSeen & 1)) {
nCinemaSeen |= 1; nCinemaSeen |= 1;
@ -135,7 +135,7 @@ void GameInterface::DrawBackground()
static void Intermission(MapRecord *from_map, MapRecord *to_map) static void Intermission(MapRecord *from_map, MapRecord *to_map)
{ {
TArray<JobDesc> jobs; TArray<DScreenJob*> jobs;
if (from_map) StopAllSounds(); if (from_map) StopAllSounds();
bCamera = false; bCamera = false;
@ -167,7 +167,7 @@ static void Intermission(MapRecord *from_map, MapRecord *to_map)
showmap(from_map ? from_map->levelNumber : -1, to_map->levelNumber, nBestLevel, jobs); showmap(from_map ? from_map->levelNumber : -1, to_map->levelNumber, nBestLevel, jobs);
} }
else else
jobs.Push({ Create<DBlackScreen>(1) }); // we need something in here even in the multiplayer case. jobs.Push(Create<DBlackScreen>(1)); // we need something in here even in the multiplayer case.
} }
} }
else else
@ -179,7 +179,7 @@ static void Intermission(MapRecord *from_map, MapRecord *to_map)
if (jobs.Size() > 0) if (jobs.Size() > 0)
{ {
RunScreenJob(jobs.Data(), jobs.Size(), [=](bool) RunScreenJob(jobs, [=](bool)
{ {
if (!to_map) gameaction = ga_startup; // this was the end of the game if (!to_map) gameaction = ga_startup; // this was the end of the game
else else

View file

@ -88,11 +88,10 @@ void Logo(const CompletionFunc& completion)
if (!userConfig.nologo) if (!userConfig.nologo)
{ {
JobDesc jobs[3]; TArray<DScreenJob*> jobs;
int job = 0; jobs.Push(Create<DSWDRealmsScreen>());
jobs[job++] = { Create<DSWDRealmsScreen>() }; jobs.Push(PlayVideo("sw.anm", logosound, logoframetimes, true));
jobs[job++] = { PlayVideo("sw.anm", logosound, logoframetimes, true)}; RunScreenJob(jobs, completion, SJ_BLOCKUI);
RunScreenJob(jobs, job, completion, SJ_BLOCKUI);
} }
else completion(false); else completion(false);
} }
@ -606,26 +605,25 @@ class DSWMultiSummaryScreen : public DSkippableScreenJob
void StatScreen(int FinishAnim, CompletionFunc completion) void StatScreen(int FinishAnim, CompletionFunc completion)
{ {
JobDesc jobs[5]; TArray<DScreenJob*> jobs;
int job = 0;
if (FinishAnim) if (FinishAnim)
{ {
StopSound(); StopSound();
jobs[job++] = { GetFinishAnim(FinishAnim) }; jobs.Push(GetFinishAnim(FinishAnim));
jobs[job++] = { Create<DSWLevelSummaryScreen>() }; jobs.Push(Create<DSWLevelSummaryScreen>());
if (FinishAnim == ANIM_ZILLA) if (FinishAnim == ANIM_ZILLA)
jobs[job++] = { Create<DSWCreditsScreen>() }; jobs.Push(Create<DSWCreditsScreen>());
} }
else if (gNet.MultiGameType != MULTI_GAME_COMMBAT) else if (gNet.MultiGameType != MULTI_GAME_COMMBAT)
{ {
jobs[job++] = { Create<DSWLevelSummaryScreen>() }; jobs.Push(Create<DSWLevelSummaryScreen>());
} }
else else
{ {
jobs[job++] = { Create<DSWMultiSummaryScreen>() }; jobs.Push(Create<DSWMultiSummaryScreen>());
} }
RunScreenJob(jobs, job, completion); RunScreenJob(jobs, completion);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -639,8 +637,9 @@ void SybexScreen(CompletionFunc completion)
if (!SW_SHAREWARE || CommEnabled) completion(false); if (!SW_SHAREWARE || CommEnabled) completion(false);
else else
{ {
JobDesc job = { Create<DImageScreen>(tileGetTexture(5261), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff) }; TArray<DScreenJob*> jobs(1, true);
RunScreenJob(&job, 1, completion, SJ_BLOCKUI); jobs[0] = Create<DImageScreen>(tileGetTexture(5261), DScreenJob::fadein | DScreenJob::fadeout, 0x7fffffff);
RunScreenJob(jobs, completion, SJ_BLOCKUI);
} }
} }
@ -670,8 +669,9 @@ public:
void loadscreen(MapRecord* rec, CompletionFunc func) void loadscreen(MapRecord* rec, CompletionFunc func)
{ {
JobDesc job = { Create<DSWLoadScreen>(rec) }; TArray<DScreenJob*> jobs(1, true);
RunScreenJob(&job, 1, func); jobs[0] = Create<DSWLoadScreen>(rec);
RunScreenJob(jobs, func);
} }
END_SW_NS END_SW_NS