mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-31 12:30:40 +00:00
- another backend update from GZDoom.
This commit is contained in:
parent
f599040212
commit
998def2487
4 changed files with 100 additions and 75 deletions
|
@ -54,10 +54,7 @@
|
||||||
|
|
||||||
CVAR(Bool, inter_subtitles, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
CVAR(Bool, inter_subtitles, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
|
|
||||||
DObject* runner;
|
CutsceneState cutscene;
|
||||||
PClass* runnerclass;
|
|
||||||
PType* runnerclasstype;
|
|
||||||
CompletionFunc completion;
|
|
||||||
static int ticks;
|
static int ticks;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -72,11 +69,11 @@ void Job_Init()
|
||||||
if (!done)
|
if (!done)
|
||||||
{
|
{
|
||||||
done = true;
|
done = true;
|
||||||
GC::AddMarkerFunc([] { GC::Mark(runner); });
|
GC::AddMarkerFunc([] { GC::Mark(cutscene.runner); });
|
||||||
}
|
}
|
||||||
runnerclass = PClass::FindClass("ScreenJobRunner");
|
cutscene.runnerclass = PClass::FindClass("ScreenJobRunner");
|
||||||
if (!runnerclass) I_FatalError("ScreenJobRunner not defined");
|
if (!cutscene.runnerclass) I_FatalError("ScreenJobRunner not defined");
|
||||||
runnerclasstype = NewPointer(runnerclass);
|
cutscene.runnerclasstype = NewPointer(cutscene.runnerclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -115,7 +112,7 @@ void CallCreateFunction(const char* qname, DObject* runner)
|
||||||
{
|
{
|
||||||
auto func = LookupFunction(qname);
|
auto func = LookupFunction(qname);
|
||||||
if (func->Proto->ArgumentTypes.Size() != 1) I_Error("Bad cutscene function %s. Must receive precisely one argument.", qname);
|
if (func->Proto->ArgumentTypes.Size() != 1) I_Error("Bad cutscene function %s. Must receive precisely one argument.", qname);
|
||||||
if (func->Proto->ArgumentTypes[0] != runnerclasstype) I_Error("Bad cutscene function %s. Must receive ScreenJobRunner reference.", qname);
|
if (func->Proto->ArgumentTypes[0] != cutscene.runnerclasstype) I_Error("Bad cutscene function %s. Must receive ScreenJobRunner reference.", qname);
|
||||||
VMValue val = runner;
|
VMValue val = runner;
|
||||||
VMCall(func, &val, 1, nullptr, 0);
|
VMCall(func, &val, 1, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
@ -128,7 +125,7 @@ void CallCreateFunction(const char* qname, DObject* runner)
|
||||||
|
|
||||||
DObject* CreateRunner(bool clearbefore)
|
DObject* CreateRunner(bool clearbefore)
|
||||||
{
|
{
|
||||||
auto obj = runnerclass->CreateNew();
|
auto obj = cutscene.runnerclass->CreateNew();
|
||||||
auto func = LookupFunction("ScreenJobRunner.Init", false);
|
auto func = LookupFunction("ScreenJobRunner.Init", false);
|
||||||
VMValue val[3] = { obj, clearbefore, false };
|
VMValue val[3] = { obj, clearbefore, false };
|
||||||
VMCall(func, val, 3, nullptr, 0);
|
VMCall(func, val, 3, nullptr, 0);
|
||||||
|
@ -182,15 +179,15 @@ void CutsceneDef::Create(DObject* runner)
|
||||||
|
|
||||||
void DeleteScreenJob()
|
void DeleteScreenJob()
|
||||||
{
|
{
|
||||||
if (runner) runner->Destroy();
|
if (cutscene.runner) cutscene.runner->Destroy();
|
||||||
runner = nullptr;
|
cutscene.runner = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndScreenJob()
|
void EndScreenJob()
|
||||||
{
|
{
|
||||||
DeleteScreenJob();
|
DeleteScreenJob();
|
||||||
if (completion) completion(false);
|
if (cutscene.completion) cutscene.completion(false);
|
||||||
completion = nullptr;
|
cutscene.completion = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,12 +210,12 @@ bool ScreenJobResponder(event_t* ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FInputEvent evt = ev;
|
FInputEvent evt = ev;
|
||||||
if (runner)
|
if (cutscene.runner)
|
||||||
{
|
{
|
||||||
IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, OnEvent)
|
IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, OnEvent)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
VMValue parm[] = { runner, &evt };
|
VMValue parm[] = { cutscene.runner, &evt };
|
||||||
VMReturn ret(&result);
|
VMReturn ret(&result);
|
||||||
VMCall(func, parm, 2, &ret, 1);
|
VMCall(func, parm, 2, &ret, 1);
|
||||||
return result;
|
return result;
|
||||||
|
@ -236,12 +233,12 @@ bool ScreenJobResponder(event_t* ev)
|
||||||
bool ScreenJobTick()
|
bool ScreenJobTick()
|
||||||
{
|
{
|
||||||
ticks++;
|
ticks++;
|
||||||
if (runner)
|
if (cutscene.runner)
|
||||||
{
|
{
|
||||||
IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, OnTick)
|
IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, OnTick)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
VMValue parm[] = { runner };
|
VMValue parm[] = { cutscene.runner };
|
||||||
VMReturn ret(&result);
|
VMReturn ret(&result);
|
||||||
VMCall(func, parm, 1, &ret, 1);
|
VMCall(func, parm, 1, &ret, 1);
|
||||||
return result;
|
return result;
|
||||||
|
@ -260,12 +257,12 @@ void ScreenJobDraw()
|
||||||
{
|
{
|
||||||
double smoothratio = I_GetTimeFrac();
|
double smoothratio = I_GetTimeFrac();
|
||||||
|
|
||||||
if (runner)
|
if (cutscene.runner)
|
||||||
{
|
{
|
||||||
twod->ClearScreen();
|
twod->ClearScreen();
|
||||||
IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, RunFrame)
|
IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, RunFrame)
|
||||||
{
|
{
|
||||||
VMValue parm[] = { runner, smoothratio };
|
VMValue parm[] = { cutscene.runner, smoothratio };
|
||||||
VMCall(func, parm, 2, nullptr, 0);
|
VMCall(func, parm, 2, nullptr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,12 +276,12 @@ void ScreenJobDraw()
|
||||||
|
|
||||||
bool ScreenJobValidate()
|
bool ScreenJobValidate()
|
||||||
{
|
{
|
||||||
if (runner)
|
if (cutscene.runner)
|
||||||
{
|
{
|
||||||
IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, Validate)
|
IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, Validate)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
VMValue parm[] = { runner };
|
VMValue parm[] = { cutscene.runner };
|
||||||
VMReturn ret(&res);
|
VMReturn ret(&res);
|
||||||
VMCall(func, parm, 1, &ret, 1);
|
VMCall(func, parm, 1, &ret, 1);
|
||||||
I_ResetFrameTime();
|
I_ResetFrameTime();
|
||||||
|
@ -304,12 +301,12 @@ bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_
|
||||||
{
|
{
|
||||||
if ((cs.function.IsNotEmpty() || cs.video.IsNotEmpty()) && cs.function.CompareNoCase("none") != 0)
|
if ((cs.function.IsNotEmpty() || cs.video.IsNotEmpty()) && cs.function.CompareNoCase("none") != 0)
|
||||||
{
|
{
|
||||||
completion = completion_;
|
cutscene.completion = completion_;
|
||||||
runner = CreateRunner();
|
cutscene.runner = CreateRunner();
|
||||||
GC::WriteBarrier(runner);
|
GC::WriteBarrier(cutscene.runner);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cs.Create(runner);
|
cs.Create(cutscene.runner);
|
||||||
if (!ScreenJobValidate())
|
if (!ScreenJobValidate())
|
||||||
{
|
{
|
||||||
DeleteScreenJob();
|
DeleteScreenJob();
|
||||||
|
@ -349,6 +346,26 @@ DEFINE_ACTION_FUNCTION(DScreenJobRunner, setTransition)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// to block wipes on cutscenes that cannot handle it
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
bool CanWipe()
|
||||||
|
{
|
||||||
|
if (cutscene.runner == nullptr) return true;
|
||||||
|
IFVM(ScreenJobRunner, CanWipe)
|
||||||
|
{
|
||||||
|
int can;
|
||||||
|
VMReturn ret(&can);
|
||||||
|
VMValue param = cutscene.runner;
|
||||||
|
VMCall(func, ¶m, 1, &ret, 1);
|
||||||
|
return can;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -43,14 +43,19 @@ bool ScreenJobValidate();
|
||||||
struct CutsceneDef;
|
struct CutsceneDef;
|
||||||
bool StartCutscene(const char* s, int flags, const CompletionFunc& completion);
|
bool StartCutscene(const char* s, int flags, const CompletionFunc& completion);
|
||||||
bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_);
|
bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_);
|
||||||
|
bool CanWipe();
|
||||||
|
|
||||||
VMFunction* LookupFunction(const char* qname, bool validate = true);
|
VMFunction* LookupFunction(const char* qname, bool validate = true);
|
||||||
void CallCreateFunction(const char* qname, DObject* runner);
|
void CallCreateFunction(const char* qname, DObject* runner);
|
||||||
DObject* CreateRunner(bool clearbefore = true);
|
DObject* CreateRunner(bool clearbefore = true);
|
||||||
void AddGenericVideo(DObject* runner, const FString& fn, int soundid, int fps);
|
void AddGenericVideo(DObject* runner, const FString& fn, int soundid, int fps);
|
||||||
|
|
||||||
|
struct CutsceneState
|
||||||
|
{
|
||||||
|
DObject* runner;
|
||||||
|
PClass* runnerclass;
|
||||||
|
PType* runnerclasstype;
|
||||||
|
CompletionFunc completion;
|
||||||
|
};
|
||||||
|
|
||||||
extern DObject* runner;
|
extern CutsceneState cutscene;
|
||||||
extern PClass* runnerclass;
|
|
||||||
extern PType* runnerclasstype;
|
|
||||||
extern CompletionFunc completion;
|
|
||||||
|
|
|
@ -180,29 +180,21 @@ class TObjPtr
|
||||||
DObject *o;
|
DObject *o;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
TObjPtr() = default;
|
|
||||||
TObjPtr(const TObjPtr<T> &q) = default;
|
|
||||||
|
|
||||||
#if 0 // Courtesy of GCC being stupid and not fully recognizing TobjPtr as trivial. GZDoom needs this constructor, but it breaks compilation in Raze, but only with GCC.
|
constexpr TObjPtr<T>& operator=(T q) noexcept
|
||||||
TObjPtr(T q) noexcept
|
|
||||||
: pp(q)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
T operator=(T q)
|
|
||||||
{
|
{
|
||||||
pp = q;
|
pp = q;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator=(std::nullptr_t nul)
|
constexpr TObjPtr<T>& operator=(std::nullptr_t nul) noexcept
|
||||||
{
|
{
|
||||||
o = nullptr;
|
o = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// To allow NULL, too.
|
// To allow NULL, too.
|
||||||
T operator=(const int val)
|
TObjPtr<T>& operator=(const int val) noexcept
|
||||||
{
|
{
|
||||||
assert(val == 0);
|
assert(val == 0);
|
||||||
o = nullptr;
|
o = nullptr;
|
||||||
|
@ -210,42 +202,42 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// To allow NULL, too. In Clang NULL is a long.
|
// To allow NULL, too. In Clang NULL is a long.
|
||||||
T operator=(const long val)
|
TObjPtr<T>& operator=(const long val) noexcept
|
||||||
{
|
{
|
||||||
assert(val == 0);
|
assert(val == 0);
|
||||||
o = nullptr;
|
o = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T Get() noexcept
|
constexpr T Get() noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(pp);
|
return GC::ReadBarrier(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
T ForceGet() noexcept //for situations where the read barrier needs to be skipped.
|
constexpr T ForceGet() noexcept //for situations where the read barrier needs to be skipped.
|
||||||
{
|
{
|
||||||
return pp;
|
return pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T() noexcept
|
constexpr operator T() noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(pp);
|
return GC::ReadBarrier(pp);
|
||||||
}
|
}
|
||||||
T &operator*() noexcept
|
constexpr T &operator*() noexcept
|
||||||
{
|
{
|
||||||
T q = GC::ReadBarrier(pp);
|
T q = GC::ReadBarrier(pp);
|
||||||
assert(q != NULL);
|
assert(q != NULL);
|
||||||
return *q;
|
return *q;
|
||||||
}
|
}
|
||||||
T operator->() noexcept
|
constexpr T operator->() noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(pp);
|
return GC::ReadBarrier(pp);
|
||||||
}
|
}
|
||||||
bool operator!=(T u) noexcept
|
constexpr bool operator!=(T u) noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(o) != u;
|
return GC::ReadBarrier(o) != u;
|
||||||
}
|
}
|
||||||
bool operator==(T u) noexcept
|
constexpr bool operator==(T u) noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(o) == u;
|
return GC::ReadBarrier(o) == u;
|
||||||
}
|
}
|
||||||
|
@ -257,6 +249,17 @@ public:
|
||||||
friend class DObject;
|
friend class DObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is only needed because some parts of GCC do not treat a class with any constructor as trivial.
|
||||||
|
// TObjPtr needs to be fully trivial, though - some parts in the engine depend on it.
|
||||||
|
template<class T>
|
||||||
|
constexpr TObjPtr<T> MakeObjPtr(T t) noexcept
|
||||||
|
{
|
||||||
|
// since this exists to replace the constructor we cannot initialize in the declaration as this would require the constructor we want to avoid.
|
||||||
|
TObjPtr<T> tt;
|
||||||
|
tt = t;
|
||||||
|
return tt;
|
||||||
|
}
|
||||||
|
|
||||||
// Use barrier_cast instead of static_cast when you need to cast
|
// Use barrier_cast instead of static_cast when you need to cast
|
||||||
// the contents of a TObjPtr to a related type.
|
// the contents of a TObjPtr to a related type.
|
||||||
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
|
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
|
||||||
|
|
|
@ -77,7 +77,7 @@ static void CallCreateMapFunction(const char* qname, DObject* runner, MapRecord*
|
||||||
auto func = LookupFunction(qname);
|
auto func = LookupFunction(qname);
|
||||||
if (func->Proto->ArgumentTypes.Size() == 1) return CallCreateFunction(qname, runner); // accept functions without map parameter as well here.
|
if (func->Proto->ArgumentTypes.Size() == 1) return CallCreateFunction(qname, runner); // accept functions without map parameter as well here.
|
||||||
if (func->Proto->ArgumentTypes.Size() != 2) I_Error("Bad map-cutscene function %s. Must receive precisely two arguments.", qname);
|
if (func->Proto->ArgumentTypes.Size() != 2) I_Error("Bad map-cutscene function %s. Must receive precisely two arguments.", qname);
|
||||||
if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != maprecordtype)
|
if (func->Proto->ArgumentTypes[0] != cutscene.runnerclasstype && func->Proto->ArgumentTypes[1] != maprecordtype)
|
||||||
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner and MapRecord reference.", qname);
|
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner and MapRecord reference.", qname);
|
||||||
VMValue val[2] = { runner, map };
|
VMValue val[2] = { runner, map };
|
||||||
VMCall(func, val, 2, nullptr, 0);
|
VMCall(func, val, 2, nullptr, 0);
|
||||||
|
@ -96,7 +96,7 @@ void CallCreateSummaryFunction(const char* qname, DObject* runner, MapRecord* ma
|
||||||
auto s = func->Proto->ArgumentTypes.Size();
|
auto s = func->Proto->ArgumentTypes.Size();
|
||||||
auto at = func->Proto->ArgumentTypes.Data();
|
auto at = func->Proto->ArgumentTypes.Data();
|
||||||
if (s != 3 && s != 4) I_Error("Bad map-cutscene function %s. Must receive precisely three or four arguments.", qname);
|
if (s != 3 && s != 4) I_Error("Bad map-cutscene function %s. Must receive precisely three or four arguments.", qname);
|
||||||
if (at[0] != runnerclasstype && at[1] != maprecordtype && at[2] != summaryinfotype && (s == 3 || at[3] == maprecordtype))
|
if (at[0] != cutscene.runnerclasstype && at[1] != maprecordtype && at[2] != summaryinfotype && (s == 3 || at[3] == maprecordtype))
|
||||||
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner, MapRecord and SummaryInfo reference,", qname);
|
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner, MapRecord and SummaryInfo reference,", qname);
|
||||||
if (info) summaryinfo = *info; // must be copied to a persistent location.
|
if (info) summaryinfo = *info; // must be copied to a persistent location.
|
||||||
else summaryinfo = {};
|
else summaryinfo = {};
|
||||||
|
@ -158,24 +158,24 @@ void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic)
|
||||||
|
|
||||||
void ShowScoreboard(int numplayers, const CompletionFunc& completion_)
|
void ShowScoreboard(int numplayers, const CompletionFunc& completion_)
|
||||||
{
|
{
|
||||||
completion = completion_;
|
cutscene.completion = completion_;
|
||||||
runner = CreateRunner();
|
cutscene.runner = CreateRunner();
|
||||||
Printf("Created runner at %p\n", runner);
|
Printf("Created runner at %p\n", cutscene.runner);
|
||||||
GC::WriteBarrier(runner);
|
GC::WriteBarrier(cutscene.runner);
|
||||||
|
|
||||||
const char* qname = globalCutscenes.MPSummaryScreen;
|
const char* qname = globalCutscenes.MPSummaryScreen;
|
||||||
auto func = LookupFunction(qname);
|
auto func = LookupFunction(qname);
|
||||||
if (func->Proto->ArgumentTypes.Size() != 2) I_Error("Bad map-cutscene function %s. Must receive precisely two arguments.", qname);
|
if (func->Proto->ArgumentTypes.Size() != 2) I_Error("Bad map-cutscene function %s. Must receive precisely two arguments.", qname);
|
||||||
if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != TypeSInt32)
|
if (func->Proto->ArgumentTypes[0] != cutscene.runnerclasstype && func->Proto->ArgumentTypes[1] != TypeSInt32)
|
||||||
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner reference and integer.", qname);
|
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner reference and integer.", qname);
|
||||||
VMValue val[2] = { runner, numplayers };
|
VMValue val[2] = { cutscene.runner, numplayers };
|
||||||
VMCall(func, val, 2, nullptr, 0);
|
VMCall(func, val, 2, nullptr, 0);
|
||||||
if (!ScreenJobValidate())
|
if (!ScreenJobValidate())
|
||||||
{
|
{
|
||||||
runner->Destroy();
|
cutscene.runner->Destroy();
|
||||||
runner = nullptr;
|
cutscene.runner = nullptr;
|
||||||
if (completion) completion(false);
|
if (cutscene.completion) cutscene.completion(false);
|
||||||
completion = nullptr;
|
cutscene.completion = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gameaction = ga_intermission;
|
gameaction = ga_intermission;
|
||||||
|
@ -189,7 +189,7 @@ void ShowScoreboard(int numplayers, const CompletionFunc& completion_)
|
||||||
|
|
||||||
void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, CompletionFunc completion_)
|
void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, CompletionFunc completion_)
|
||||||
{
|
{
|
||||||
if (runner != nullptr)
|
if (cutscene.runner != nullptr)
|
||||||
return; // protection against double exits.
|
return; // protection against double exits.
|
||||||
if (fromMap == toMap)
|
if (fromMap == toMap)
|
||||||
{
|
{
|
||||||
|
@ -200,17 +200,17 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C
|
||||||
bool bossexit = g_bossexit;
|
bool bossexit = g_bossexit;
|
||||||
g_bossexit = false;
|
g_bossexit = false;
|
||||||
|
|
||||||
completion = completion_;
|
cutscene.completion = completion_;
|
||||||
runner = CreateRunner();
|
cutscene.runner = CreateRunner();
|
||||||
GC::WriteBarrier(runner);
|
GC::WriteBarrier(cutscene.runner);
|
||||||
|
|
||||||
// retrieve cluster relations for cluster-based cutscenes.
|
// retrieve cluster relations for cluster-based cutscene.
|
||||||
ClusterDef* fromcluster = nullptr, *tocluster = nullptr;
|
ClusterDef* fromcluster = nullptr, *tocluster = nullptr;
|
||||||
if (fromMap) fromcluster = FindCluster(fromMap->cluster);
|
if (fromMap) fromcluster = FindCluster(fromMap->cluster);
|
||||||
if (toMap) tocluster = FindCluster(toMap->cluster);
|
if (toMap) tocluster = FindCluster(toMap->cluster);
|
||||||
if (fromcluster == tocluster) fromcluster = tocluster = nullptr;
|
if (fromcluster == tocluster) fromcluster = tocluster = nullptr;
|
||||||
|
|
||||||
|
auto runner = cutscene.runner;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (fromMap && (!(fromMap->gameflags & LEVEL_BOSSONLYCUTSCENE) || bossexit))
|
if (fromMap && (!(fromMap->gameflags & LEVEL_BOSSONLYCUTSCENE) || bossexit))
|
||||||
|
@ -245,9 +245,9 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C
|
||||||
if (!ScreenJobValidate())
|
if (!ScreenJobValidate())
|
||||||
{
|
{
|
||||||
runner->Destroy();
|
runner->Destroy();
|
||||||
runner = nullptr;
|
cutscene.runner = nullptr;
|
||||||
if (completion) completion(false);
|
if (cutscene.completion) cutscene.completion(false);
|
||||||
completion = nullptr;
|
cutscene.completion = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gameaction = ga_intermission;
|
gameaction = ga_intermission;
|
||||||
|
@ -255,7 +255,7 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
if (runner) runner->Destroy();
|
if (runner) runner->Destroy();
|
||||||
runner = nullptr;
|
cutscene.runner = nullptr;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue