mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 08:52:00 +00:00
- implemented running screen jobs from the main loop.
The entire game now has only one single place where videoNextPage gets called.
This commit is contained in:
parent
e2e9c8ad01
commit
f9842fc4a8
6 changed files with 68 additions and 105 deletions
|
@ -66,6 +66,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "startupinfo.h"
|
||||
#include "mapinfo.h"
|
||||
#include "menustate.h"
|
||||
#include "screenjob.h"
|
||||
|
||||
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
@ -518,6 +519,7 @@ int GameMain()
|
|||
I_ShowFatalError(err.what());
|
||||
r = -1;
|
||||
}
|
||||
DeleteScreenJob();
|
||||
M_ClearMenus(true);
|
||||
if (gi)
|
||||
{
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "v_draw.h"
|
||||
#include "s_soundinternal.h"
|
||||
#include "animtexture.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLASS(DScreenJob, true, false)
|
||||
|
@ -258,6 +259,22 @@ public:
|
|||
AdvanceJob(false);
|
||||
}
|
||||
|
||||
~ScreenJobRunner()
|
||||
{
|
||||
DeleteJobs();
|
||||
}
|
||||
|
||||
void DeleteJobs()
|
||||
{
|
||||
for (auto& job : jobs)
|
||||
{
|
||||
job.job->Destroy();
|
||||
job.job->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete job.job;
|
||||
}
|
||||
jobs.Clear();
|
||||
}
|
||||
|
||||
void AdvanceJob(bool skip)
|
||||
{
|
||||
index++;
|
||||
|
@ -307,12 +324,7 @@ public:
|
|||
{
|
||||
if (index >= jobs.Size())
|
||||
{
|
||||
for (auto& job : jobs)
|
||||
{
|
||||
job.job->Destroy();
|
||||
job.job->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete job.job;
|
||||
}
|
||||
DeleteJobs();
|
||||
twod->SetScreenFade(1);
|
||||
if (completion) completion(false);
|
||||
return false;
|
||||
|
@ -354,102 +366,32 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
ScreenJobRunner *runner;
|
||||
|
||||
void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore)
|
||||
{
|
||||
ScreenJobRunner runner(jobs, count, completion, clearbefore);
|
||||
|
||||
while (runner.RunFrame())
|
||||
assert(completion != nullptr);
|
||||
if (count)
|
||||
{
|
||||
videoNextPage();
|
||||
runner = new ScreenJobRunner(jobs, count, completion, clearbefore);
|
||||
gamestate = GS_INTERMISSION;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void RunScreenJobSync(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore)
|
||||
void DeleteScreenJob()
|
||||
{
|
||||
// Release all jobs from the garbage collector - the code as it is cannot deal with them getting collected.
|
||||
for (int i = 0; i < count; i++)
|
||||
if (runner)
|
||||
{
|
||||
jobs[i].job->Release();
|
||||
delete runner;
|
||||
runner = nullptr;
|
||||
}
|
||||
bool skipped = false;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
auto job = jobs[i];
|
||||
if (job.job != nullptr && (!skipped || !job.ignoreifskipped))
|
||||
{
|
||||
skipped = false;
|
||||
if (clearbefore)
|
||||
{
|
||||
twod->ClearScreen();
|
||||
videoNextPage();
|
||||
}
|
||||
|
||||
auto startTime = I_nsTime();
|
||||
|
||||
// Input later needs to be event based so that these screens can do more than be skipped.
|
||||
inputState.ClearAllInput();
|
||||
|
||||
float screenfade = job.job->fadestyle & DScreenJob::fadein ? 0.f : 1.f;
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto now = I_nsTime();
|
||||
handleevents();
|
||||
bool skiprequest = inputState.CheckAllInput();
|
||||
auto clock = now - startTime;
|
||||
if (screenfade < 1.f)
|
||||
{
|
||||
float ms = (clock / 1'000'000) / job.job->fadetime;
|
||||
screenfade = clamp(ms, 0.f, 1.f);
|
||||
twod->SetScreenFade(screenfade);
|
||||
job.job->fadestate = DScreenJob::fadein;
|
||||
}
|
||||
else job.job->fadestate = DScreenJob::visible;
|
||||
job.job->SetClock(clock);
|
||||
int state = job.job->Frame(clock, skiprequest);
|
||||
startTime -= job.job->GetClock() - clock;
|
||||
// Must lock before displaying.
|
||||
if (state < 1 && job.job->fadestyle & DScreenJob::fadeout)
|
||||
twod->Lock();
|
||||
|
||||
videoNextPage();
|
||||
if (state < 1)
|
||||
{
|
||||
if (job.job->fadestyle & DScreenJob::fadeout)
|
||||
{
|
||||
job.job->fadestate = DScreenJob::fadeout;
|
||||
startTime = now;
|
||||
float screenfade2;
|
||||
do
|
||||
{
|
||||
now = I_nsTime();
|
||||
auto clock = now - startTime;
|
||||
float ms = (clock / 1'000'000) / job.job->fadetime;
|
||||
screenfade2 = clamp(screenfade - ms, 0.f, 1.f);
|
||||
twod->SetScreenFade(screenfade2);
|
||||
if (screenfade2 <= 0.f) twod->Unlock(); // must unlock before displaying.
|
||||
videoNextPage();
|
||||
|
||||
} while (screenfade2 > 0.f);
|
||||
}
|
||||
skipped = state < 0;
|
||||
job.job->Destroy();
|
||||
job.job->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete job.job;
|
||||
twod->SetScreenFade(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (job.postAction) job.postAction();
|
||||
}
|
||||
if (completion) completion(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
void RunScreenJobFrame()
|
||||
{
|
||||
// we cannot recover from this because we have no completion callback to call.
|
||||
if (!runner) I_Error("Trying to run a non-existent screen job");
|
||||
auto res = runner->RunFrame();
|
||||
if (!res) DeleteScreenJob();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ class DScreenJob : public DObject
|
|||
const float fadetime; // in milliseconds
|
||||
int fadestate = fadein;
|
||||
|
||||
friend void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore);
|
||||
friend class ScreenJobRunner;
|
||||
|
||||
public:
|
||||
|
@ -81,7 +80,8 @@ struct JobDesc
|
|||
|
||||
|
||||
void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore = true);
|
||||
void RunScreenJobSync(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore = true);
|
||||
void DeleteScreenJob();
|
||||
void RunScreenJobFrame();
|
||||
|
||||
struct AnimSound
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
|
|||
#include "buildtiles.h"
|
||||
#include "mapinfo.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
BEGIN_DUKE_NS
|
||||
|
||||
|
@ -1077,6 +1078,15 @@ CCMD(testscreen)
|
|||
C_HideConsole();
|
||||
FX_StopAllSounds();
|
||||
Mus_Stop();
|
||||
|
||||
auto gs = gamestate;
|
||||
auto completion = [=](bool)
|
||||
{
|
||||
if (gs == GS_LEVEL || gs == GS_DEMOSCREEN) gamestate = gs;
|
||||
else gamestate = GS_STARTUP;
|
||||
};
|
||||
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
int screen = strtol(argv[1], nullptr, 0);
|
||||
|
@ -1088,7 +1098,7 @@ CCMD(testscreen)
|
|||
case 3:
|
||||
case 4:
|
||||
bonussequence_d(screen, jobs, job);
|
||||
RunScreenJob(jobs, job, nullptr);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
|
@ -1097,7 +1107,7 @@ CCMD(testscreen)
|
|||
|
||||
case 6:
|
||||
jobs[job++] = { Create<DDukeMultiplayerBonusScreen>(6) };
|
||||
RunScreenJob(jobs, job, nullptr);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
|
@ -1110,13 +1120,13 @@ CCMD(testscreen)
|
|||
|
||||
case 9:
|
||||
jobs[job++] = { Create<DDukeLevelSummaryScreen>() };
|
||||
RunScreenJob(jobs, job, nullptr);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
ud.eog = true;
|
||||
jobs[job++] = { Create<DDukeLevelSummaryScreen>() };
|
||||
RunScreenJob(jobs, job, nullptr);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
ud.eog = false;
|
||||
break;
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
|
|||
#include "screenjob.h"
|
||||
#include "texturemanager.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
BEGIN_DUKE_NS
|
||||
|
||||
|
@ -644,6 +645,14 @@ CCMD(testrscreen)
|
|||
C_HideConsole();
|
||||
FX_StopAllSounds();
|
||||
Mus_Stop();
|
||||
|
||||
auto gs = gamestate;
|
||||
auto completion = [=](bool)
|
||||
{
|
||||
if (gs == GS_LEVEL || gs == GS_DEMOSCREEN) gamestate = gs;
|
||||
else gamestate = GS_STARTUP;
|
||||
};
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
int screen = strtol(argv[1], nullptr, 0);
|
||||
|
@ -654,23 +663,23 @@ CCMD(testrscreen)
|
|||
if (!isRRRA())
|
||||
{
|
||||
bonussequence_r(screen, jobs, job);
|
||||
RunScreenJob(jobs, job, nullptr);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
jobs[job++] = { Create<DRRMultiplayerBonusScreen>(6) };
|
||||
RunScreenJob(jobs, job, nullptr);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
jobs[job++] = { Create<DRRLevelSummaryScreen>() };
|
||||
RunScreenJob(jobs, job, nullptr);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
jobs[job++] = { Create<DRRRAEndOfGame>() };
|
||||
RunScreenJob(jobs, job, nullptr);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -435,7 +435,7 @@ void app_loop()
|
|||
break;
|
||||
|
||||
case GS_INTERMISSION:
|
||||
// todo: run screen jobs here
|
||||
RunScreenJobFrame(); // This handles continuation through its completion callback.
|
||||
break;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue