mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-12 23:54:37 +00:00
- rewrote the ScreenJob player as a class that can be called by an asynchronous dispatcher.
Works, except for timing issues with ANMs.
This commit is contained in:
parent
2ce612e8ab
commit
31b9995406
9 changed files with 263 additions and 114 deletions
|
@ -67,95 +67,6 @@ int DImageScreen::Frame(uint64_t clock, bool skiprequest)
|
||||||
return skiprequest ? -1 : 1;
|
return skiprequest ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore)
|
|
||||||
{
|
|
||||||
// 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++)
|
|
||||||
{
|
|
||||||
jobs[i].job->Release();
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -305,3 +216,235 @@ DScreenJob *PlayVideo(const char* filename, const AnimSound* ans, const int* fra
|
||||||
return nothing();
|
return nothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class ScreenJobRunner
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
State_Clear,
|
||||||
|
State_Run,
|
||||||
|
State_Fadeout
|
||||||
|
};
|
||||||
|
TArray<JobDesc> jobs;
|
||||||
|
CompletionFunc completion;
|
||||||
|
int index = -1;
|
||||||
|
float screenfade;
|
||||||
|
bool clearbefore;
|
||||||
|
bool skipped = false;
|
||||||
|
uint64_t startTime;
|
||||||
|
int actionState;
|
||||||
|
int terminateState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScreenJobRunner(JobDesc* jobs_, int count, CompletionFunc completion_, bool clearbefore_)
|
||||||
|
: completion(std::move(completion_)), clearbefore(clearbefore_)
|
||||||
|
{
|
||||||
|
jobs.Resize(count);
|
||||||
|
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.
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
jobs[i].job->Release();
|
||||||
|
}
|
||||||
|
AdvanceJob(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvanceJob(bool skip)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && jobs[index].ignoreifskipped))) index++;
|
||||||
|
actionState = clearbefore ? State_Clear : State_Run;
|
||||||
|
if (index < jobs.Size()) screenfade = jobs[index].job->fadestyle & DScreenJob::fadein ? 0.f : 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisplayFrame()
|
||||||
|
{
|
||||||
|
auto& job = jobs[index];
|
||||||
|
auto now = I_nsTime();
|
||||||
|
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;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FadeoutFrame()
|
||||||
|
{
|
||||||
|
auto now = I_nsTime();
|
||||||
|
auto clock = now - startTime;
|
||||||
|
float ms = (clock / 1'000'000) / jobs[index].job->fadetime;
|
||||||
|
float screenfade2 = clamp(screenfade - ms, 0.f, 1.f);
|
||||||
|
twod->SetScreenFade(screenfade2);
|
||||||
|
if (screenfade2 <= 0.f)
|
||||||
|
{
|
||||||
|
twod->Unlock(); // must unlock before displaying.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RunFrame()
|
||||||
|
{
|
||||||
|
if (index >= jobs.Size())
|
||||||
|
{
|
||||||
|
for (auto& job : jobs)
|
||||||
|
{
|
||||||
|
job.job->Destroy();
|
||||||
|
job.job->ObjectFlags |= OF_YesReallyDelete;
|
||||||
|
delete job.job;
|
||||||
|
}
|
||||||
|
twod->SetScreenFade(1);
|
||||||
|
if (completion) completion(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
handleevents();
|
||||||
|
if (actionState == State_Clear)
|
||||||
|
{
|
||||||
|
actionState = State_Run;
|
||||||
|
twod->ClearScreen();
|
||||||
|
}
|
||||||
|
else if (actionState == State_Run)
|
||||||
|
{
|
||||||
|
terminateState = DisplayFrame();
|
||||||
|
if (terminateState < 1)
|
||||||
|
{
|
||||||
|
// Must lock before displaying.
|
||||||
|
if (jobs[index].job->fadestyle & DScreenJob::fadeout)
|
||||||
|
{
|
||||||
|
twod->Lock();
|
||||||
|
startTime = I_nsTime();
|
||||||
|
jobs[index].job->fadestate = DScreenJob::fadeout;
|
||||||
|
actionState = State_Fadeout;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AdvanceJob(terminateState < 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (actionState == State_Fadeout)
|
||||||
|
{
|
||||||
|
int ended = FadeoutFrame();
|
||||||
|
if (ended < 1)
|
||||||
|
{
|
||||||
|
AdvanceJob(terminateState < 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore)
|
||||||
|
{
|
||||||
|
ScreenJobRunner runner(jobs, count, completion, clearbefore);
|
||||||
|
|
||||||
|
while (runner.RunFrame())
|
||||||
|
{
|
||||||
|
videoNextPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RunScreenJobSync(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore)
|
||||||
|
{
|
||||||
|
// 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++)
|
||||||
|
{
|
||||||
|
jobs[i].job->Release();
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
using CompletionFunc = std::function<void(bool)>;
|
using CompletionFunc = std::function<void(bool)>;
|
||||||
struct JobDesc;
|
struct JobDesc;
|
||||||
|
class ScreenJobRunner;
|
||||||
|
|
||||||
class DScreenJob : public DObject
|
class DScreenJob : public DObject
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,7 @@ class DScreenJob : public DObject
|
||||||
int fadestate = fadein;
|
int fadestate = fadein;
|
||||||
|
|
||||||
friend void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore);
|
friend void RunScreenJob(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore);
|
||||||
|
friend class ScreenJobRunner;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum
|
enum
|
||||||
|
@ -79,6 +81,7 @@ struct JobDesc
|
||||||
|
|
||||||
|
|
||||||
void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore = true);
|
void RunScreenJob(JobDesc *jobs, int count, CompletionFunc completion, bool clearbefore = true);
|
||||||
|
void RunScreenJobSync(JobDesc* jobs, int count, CompletionFunc completion, bool clearbefore = true);
|
||||||
|
|
||||||
struct AnimSound
|
struct AnimSound
|
||||||
{
|
{
|
||||||
|
|
|
@ -253,7 +253,7 @@ public:
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void Logo_d(CompletionFunc completion)
|
void Logo_d(const CompletionFunc &completion)
|
||||||
{
|
{
|
||||||
Mus_Stop();
|
Mus_Stop();
|
||||||
FX_StopAllSounds(); // JBF 20031228
|
FX_StopAllSounds(); // JBF 20031228
|
||||||
|
@ -636,7 +636,7 @@ static void bonussequence_d(int num, JobDesc *jobs, int &job)
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void showtwoscreens(CompletionFunc completion)
|
void showtwoscreens(const CompletionFunc& completion)
|
||||||
{
|
{
|
||||||
JobDesc jobs[2];
|
JobDesc jobs[2];
|
||||||
int job = 0;
|
int job = 0;
|
||||||
|
@ -646,7 +646,7 @@ void showtwoscreens(CompletionFunc completion)
|
||||||
RunScreenJob(jobs, job, completion);
|
RunScreenJob(jobs, job, completion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void doorders(CompletionFunc completion)
|
void doorders(const CompletionFunc& completion)
|
||||||
{
|
{
|
||||||
JobDesc jobs[4];
|
JobDesc jobs[4];
|
||||||
int job = 0;
|
int job = 0;
|
||||||
|
@ -956,7 +956,7 @@ public:
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void dobonus_d(bool bonusonly, CompletionFunc completion)
|
void dobonus_d(bool bonusonly, const CompletionFunc& completion)
|
||||||
{
|
{
|
||||||
JobDesc jobs[20];
|
JobDesc jobs[20];
|
||||||
int job = 0;
|
int job = 0;
|
||||||
|
@ -988,7 +988,7 @@ void dobonus_d(bool bonusonly, CompletionFunc completion)
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void e4intro(CompletionFunc completion)
|
void e4intro(const CompletionFunc& completion)
|
||||||
{
|
{
|
||||||
JobDesc jobs[5];
|
JobDesc jobs[5];
|
||||||
int job = 0;
|
int job = 0;
|
||||||
|
|
|
@ -164,7 +164,7 @@ static void MiniText(double x, double y, const char* t, int shade, int align = -
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void Logo_r(CompletionFunc completion)
|
void Logo_r(const CompletionFunc& completion)
|
||||||
{
|
{
|
||||||
Mus_Stop();
|
Mus_Stop();
|
||||||
FX_StopAllSounds(); // JBF 20031228
|
FX_StopAllSounds(); // JBF 20031228
|
||||||
|
@ -552,7 +552,7 @@ public:
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void dobonus_r(bool bonusonly, CompletionFunc completion)
|
void dobonus_r(bool bonusonly, const CompletionFunc& completion)
|
||||||
{
|
{
|
||||||
JobDesc jobs[20];
|
JobDesc jobs[20];
|
||||||
int job = 0;
|
int job = 0;
|
||||||
|
|
|
@ -114,8 +114,8 @@ void think_r();
|
||||||
void animatesprites_d(int x, int y, int a, int smoothratio);
|
void animatesprites_d(int x, int y, int a, int smoothratio);
|
||||||
void animatesprites_r(int x, int y, int a, int smoothratio);
|
void animatesprites_r(int x, int y, int a, int smoothratio);
|
||||||
|
|
||||||
void Logo_d(CompletionFunc);
|
void Logo_d(const CompletionFunc&);
|
||||||
void Logo_r(CompletionFunc);
|
void Logo_r(const CompletionFunc&);
|
||||||
void InitFonts_d();
|
void InitFonts_d();
|
||||||
void InitFonts_r();
|
void InitFonts_r();
|
||||||
void PrintPaused_d();
|
void PrintPaused_d();
|
||||||
|
|
|
@ -69,7 +69,7 @@ struct GameInterface : ::GameInterface
|
||||||
struct Dispatcher
|
struct Dispatcher
|
||||||
{
|
{
|
||||||
// global stuff
|
// global stuff
|
||||||
void (*ShowLogo)(CompletionFunc completion);
|
void (*ShowLogo)(const CompletionFunc& completion);
|
||||||
void (*InitFonts)();
|
void (*InitFonts)();
|
||||||
void (*PrintPaused)();
|
void (*PrintPaused)();
|
||||||
|
|
||||||
|
|
|
@ -156,8 +156,8 @@ void setsectinterpolate(int sprnum);
|
||||||
int LocateTheLocator(int const tag, int const sectnum);
|
int LocateTheLocator(int const tag, int const sectnum);
|
||||||
void clearcamera(player_struct* ps);
|
void clearcamera(player_struct* ps);
|
||||||
|
|
||||||
void showtwoscreens(CompletionFunc func);
|
void showtwoscreens(const CompletionFunc& func);
|
||||||
void doorders(CompletionFunc func);
|
void doorders(const CompletionFunc& func);
|
||||||
|
|
||||||
void execute(int s, int p, int d);
|
void execute(int s, int p, int d);
|
||||||
void makeitfall(int s);
|
void makeitfall(int s);
|
||||||
|
@ -208,9 +208,9 @@ void drawstatusbar_d(int snum);
|
||||||
void drawstatusbar_r(int snum);
|
void drawstatusbar_r(int snum);
|
||||||
void drawoverheadmap(int cposx, int cposy, int czoom, int cang);
|
void drawoverheadmap(int cposx, int cposy, int czoom, int cang);
|
||||||
void cameratext(int i);
|
void cameratext(int i);
|
||||||
void dobonus(int bonusonly, CompletionFunc completion);
|
void dobonus(int bonusonly, const CompletionFunc& completion);
|
||||||
void dobonus_d(bool bonusonly, CompletionFunc completion);
|
void dobonus_d(bool bonusonly, const CompletionFunc& completion);
|
||||||
void dobonus_r(bool bonusonly, CompletionFunc completion);
|
void dobonus_r(bool bonusonly, const CompletionFunc& completion);
|
||||||
|
|
||||||
void displayrest(int32_t smoothratio);
|
void displayrest(int32_t smoothratio);
|
||||||
void drawbackground(void);
|
void drawbackground(void);
|
||||||
|
@ -221,11 +221,10 @@ void resettimevars();
|
||||||
bool setnextmap(bool checksecretexit);
|
bool setnextmap(bool checksecretexit);
|
||||||
void prelevel_d(int g);
|
void prelevel_d(int g);
|
||||||
void prelevel_r(int g);
|
void prelevel_r(int g);
|
||||||
void e4intro(CompletionFunc completion);
|
void e4intro(const CompletionFunc& completion);
|
||||||
void clearfrags(void);
|
void clearfrags(void);
|
||||||
void exitlevel();
|
void exitlevel();
|
||||||
int enterlevel(MapRecord* mi, int gm);
|
int enterlevel(MapRecord* mi, int gm);
|
||||||
void newgame(MapRecord* mi, int sk, CompletionFunc completion);
|
|
||||||
void donewgame(MapRecord* map, int sk);
|
void donewgame(MapRecord* map, int sk);
|
||||||
void startnewgame(MapRecord* map, int skill);
|
void startnewgame(MapRecord* map, int skill);
|
||||||
void setlocalplayerinput(player_struct *pp);
|
void setlocalplayerinput(player_struct *pp);
|
||||||
|
|
|
@ -109,22 +109,25 @@ void setmapfog(int fogtype)
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
static void runbonus(CompletionFunc completion)
|
template<class func>
|
||||||
|
void runbonus(func completion)
|
||||||
{
|
{
|
||||||
// MP scoreboard
|
// MP scoreboard
|
||||||
if (playerswhenstarted > 1 && ps[myconnectindex].gm & MODE_GAME && !ud.coop)
|
if (playerswhenstarted > 1 && ps[myconnectindex].gm & MODE_GAME && !ud.coop)
|
||||||
{
|
{
|
||||||
dobonus(1, completion);
|
dobonus(1, completion);
|
||||||
}
|
}
|
||||||
else if (completion) completion(false);
|
else completion(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
static void runtwoscreens(CompletionFunc completion)
|
|
||||||
|
template <class func>
|
||||||
|
void runtwoscreens(func completion)
|
||||||
{
|
{
|
||||||
// shareware and TEN screens
|
// shareware and TEN screens
|
||||||
if (!VOLUMEALL && !isRR())
|
if (!VOLUMEALL && !isRR())
|
||||||
showtwoscreens(completion);
|
showtwoscreens(completion);
|
||||||
else if (completion) completion(false);
|
else completion(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void endthegame(bool)
|
static void endthegame(bool)
|
||||||
|
@ -722,7 +725,7 @@ void cameratext(int i)
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void dobonus(int bonusonly, CompletionFunc completion)
|
void dobonus(int bonusonly, const CompletionFunc& completion)
|
||||||
{
|
{
|
||||||
if (isRRRA()) { if (completion) completion(false); }
|
if (isRRRA()) { if (completion) completion(false); }
|
||||||
else if (isRR()) dobonus_r(bonusonly, completion);
|
else if (isRR()) dobonus_r(bonusonly, completion);
|
||||||
|
|
|
@ -837,7 +837,8 @@ void donewgame(MapRecord* map, int sk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void newgame(MapRecord* map, int sk, CompletionFunc completion)
|
template<class func>
|
||||||
|
void newgame(MapRecord* map, int sk, func completion)
|
||||||
{
|
{
|
||||||
handleevents();
|
handleevents();
|
||||||
ready2send = 0;
|
ready2send = 0;
|
||||||
|
@ -846,12 +847,12 @@ void newgame(MapRecord* map, int sk, CompletionFunc completion)
|
||||||
{
|
{
|
||||||
if (!isRR() && map->levelNumber == levelnum(3, 0) && (ud.multimode < 2))
|
if (!isRR() && map->levelNumber == levelnum(3, 0) && (ud.multimode < 2))
|
||||||
{
|
{
|
||||||
e4intro([=](bool) { donewgame(map, sk); if (completion) completion(res); });
|
e4intro([=](bool) { donewgame(map, sk); completion(res); });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
donewgame(map, sk);
|
donewgame(map, sk);
|
||||||
if (completion) completion(res);
|
completion(res);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue