Skip to content

Commit

Permalink
- another backend update from GZDoom.
Browse files Browse the repository at this point in the history
  • Loading branch information
coelckers committed Jun 6, 2022
1 parent f599040 commit 998def2
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 75 deletions.
77 changes: 47 additions & 30 deletions source/common/cutscenes/screenjob.cpp
Expand Up @@ -54,10 +54,7 @@

CVAR(Bool, inter_subtitles, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);

DObject* runner;
PClass* runnerclass;
PType* runnerclasstype;
CompletionFunc completion;
CutsceneState cutscene;
static int ticks;

//=============================================================================
Expand All @@ -72,11 +69,11 @@ void Job_Init()
if (!done)
{
done = true;
GC::AddMarkerFunc([] { GC::Mark(runner); });
GC::AddMarkerFunc([] { GC::Mark(cutscene.runner); });
}
runnerclass = PClass::FindClass("ScreenJobRunner");
if (!runnerclass) I_FatalError("ScreenJobRunner not defined");
runnerclasstype = NewPointer(runnerclass);
cutscene.runnerclass = PClass::FindClass("ScreenJobRunner");
if (!cutscene.runnerclass) I_FatalError("ScreenJobRunner not defined");
cutscene.runnerclasstype = NewPointer(cutscene.runnerclass);
}

//=============================================================================
Expand Down Expand Up @@ -115,7 +112,7 @@ void CallCreateFunction(const char* qname, DObject* runner)
{
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[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;
VMCall(func, &val, 1, nullptr, 0);
}
Expand All @@ -128,7 +125,7 @@ void CallCreateFunction(const char* qname, DObject* runner)

DObject* CreateRunner(bool clearbefore)
{
auto obj = runnerclass->CreateNew();
auto obj = cutscene.runnerclass->CreateNew();
auto func = LookupFunction("ScreenJobRunner.Init", false);
VMValue val[3] = { obj, clearbefore, false };
VMCall(func, val, 3, nullptr, 0);
Expand Down Expand Up @@ -182,15 +179,15 @@ void CutsceneDef::Create(DObject* runner)

void DeleteScreenJob()
{
if (runner) runner->Destroy();
runner = nullptr;
if (cutscene.runner) cutscene.runner->Destroy();
cutscene.runner = nullptr;
}

void EndScreenJob()
{
DeleteScreenJob();
if (completion) completion(false);
completion = nullptr;
if (cutscene.completion) cutscene.completion(false);
cutscene.completion = nullptr;
}


Expand All @@ -213,12 +210,12 @@ bool ScreenJobResponder(event_t* ev)
}
}
FInputEvent evt = ev;
if (runner)
if (cutscene.runner)
{
IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, OnEvent)
IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, OnEvent)
{
int result = 0;
VMValue parm[] = { runner, &evt };
VMValue parm[] = { cutscene.runner, &evt };
VMReturn ret(&result);
VMCall(func, parm, 2, &ret, 1);
return result;
Expand All @@ -236,12 +233,12 @@ bool ScreenJobResponder(event_t* ev)
bool ScreenJobTick()
{
ticks++;
if (runner)
if (cutscene.runner)
{
IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, OnTick)
IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, OnTick)
{
int result = 0;
VMValue parm[] = { runner };
VMValue parm[] = { cutscene.runner };
VMReturn ret(&result);
VMCall(func, parm, 1, &ret, 1);
return result;
Expand All @@ -260,12 +257,12 @@ void ScreenJobDraw()
{
double smoothratio = I_GetTimeFrac();

if (runner)
if (cutscene.runner)
{
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);
}
}
Expand All @@ -279,12 +276,12 @@ void ScreenJobDraw()

bool ScreenJobValidate()
{
if (runner)
if (cutscene.runner)
{
IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, Validate)
IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, Validate)
{
int res;
VMValue parm[] = { runner };
VMValue parm[] = { cutscene.runner };
VMReturn ret(&res);
VMCall(func, parm, 1, &ret, 1);
I_ResetFrameTime();
Expand All @@ -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)
{
completion = completion_;
runner = CreateRunner();
GC::WriteBarrier(runner);
cutscene.completion = completion_;
cutscene.runner = CreateRunner();
GC::WriteBarrier(cutscene.runner);
try
{
cs.Create(runner);
cs.Create(cutscene.runner);
if (!ScreenJobValidate())
{
DeleteScreenJob();
Expand Down Expand Up @@ -349,6 +346,26 @@ DEFINE_ACTION_FUNCTION(DScreenJobRunner, setTransition)
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, &param, 1, &ret, 1);
return can;
}
return true;
}

//=============================================================================
//
//
Expand Down
13 changes: 9 additions & 4 deletions source/common/cutscenes/screenjob.h
Expand Up @@ -43,14 +43,19 @@ bool ScreenJobValidate();
struct CutsceneDef;
bool StartCutscene(const char* s, int flags, const CompletionFunc& completion);
bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_);
bool CanWipe();

VMFunction* LookupFunction(const char* qname, bool validate = true);
void CallCreateFunction(const char* qname, DObject* runner);
DObject* CreateRunner(bool clearbefore = true);
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 PClass* runnerclass;
extern PType* runnerclasstype;
extern CompletionFunc completion;
extern CutsceneState cutscene;
41 changes: 22 additions & 19 deletions source/common/objects/dobjgc.h
Expand Up @@ -180,72 +180,64 @@ class TObjPtr
DObject *o;
};
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.
TObjPtr(T q) noexcept
: pp(q)
{
}
#endif
T operator=(T q)
constexpr TObjPtr<T>& operator=(T q) noexcept
{
pp = q;
return *this;
}

T operator=(std::nullptr_t nul)
constexpr TObjPtr<T>& operator=(std::nullptr_t nul) noexcept
{
o = nullptr;
return *this;
}

// To allow NULL, too.
T operator=(const int val)
TObjPtr<T>& operator=(const int val) noexcept
{
assert(val == 0);
o = nullptr;
return *this;
}

// 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);
o = nullptr;
return *this;
}

T Get() noexcept
constexpr T Get() noexcept
{
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;
}

operator T() noexcept
constexpr operator T() noexcept
{
return GC::ReadBarrier(pp);
}
T &operator*() noexcept
constexpr T &operator*() noexcept
{
T q = GC::ReadBarrier(pp);
assert(q != NULL);
return *q;
}
T operator->() noexcept
constexpr T operator->() noexcept
{
return GC::ReadBarrier(pp);
}
bool operator!=(T u) noexcept
constexpr bool operator!=(T u) noexcept
{
return GC::ReadBarrier(o) != u;
}
bool operator==(T u) noexcept
constexpr bool operator==(T u) noexcept
{
return GC::ReadBarrier(o) == u;
}
Expand All @@ -257,6 +249,17 @@ class TObjPtr
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
// the contents of a TObjPtr to a related type.
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
Expand Down

0 comments on commit 998def2

Please sign in to comment.