From eb8fae761e53a7f2385df3d77dd6ee2c3e6ad199 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Jun 2022 10:39:49 +0200 Subject: [PATCH] - backend update from GZDoom. --- source/common/2d/v_draw.cpp | 27 ++++-- source/common/2d/v_draw.h | 7 +- source/common/console/c_console.cpp | 7 +- source/common/cutscenes/screenjob.cpp | 9 ++ source/common/engine/namedef.h | 2 + source/common/engine/serializer.h | 10 ++ source/common/rendering/gl/gl_framebuffer.cpp | 2 +- source/common/rendering/gl/gl_framebuffer.h | 3 +- .../common/rendering/gles/gles_framebuffer.h | 2 - .../rendering/hwrenderer/data/hw_skydome.cpp | 5 +- .../rendering/hwrenderer/data/hw_skydome.h | 8 +- source/common/rendering/r_thread.h | 5 +- source/common/scripting/backend/codegen.cpp | 36 ++++++-- source/common/scripting/backend/codegen.h | 4 +- source/common/scripting/core/types.cpp | 49 ++++++++++ source/common/scripting/core/types.h | 6 +- .../common/scripting/frontend/zcc_compile.cpp | 20 ++-- .../common/scripting/frontend/zcc_parser.cpp | 89 +++++++++--------- .../common/scripting/interface/vmnatives.cpp | 7 +- source/common/scripting/jit/jit.cpp | 4 +- source/common/scripting/jit/jit_load.cpp | 48 ++++++++++ source/common/scripting/jit/jit_store.cpp | 58 ++++++++++++ source/common/scripting/vm/vmexec.h | 92 +++++++++++++++++-- source/common/scripting/vm/vmops.h | 8 ++ .../common/startscreen/startscreen_hexen.cpp | 2 +- 25 files changed, 416 insertions(+), 94 deletions(-) diff --git a/source/common/2d/v_draw.cpp b/source/common/2d/v_draw.cpp index 1ff348bc7..55521e78b 100644 --- a/source/common/2d/v_draw.cpp +++ b/source/common/2d/v_draw.cpp @@ -163,7 +163,7 @@ int GetConScale(F2DDrawer* drawer, int altval) else if (uiscale == 0) { // Default should try to scale to 640x400 - int vscale = drawer->GetHeight() / 800; + int vscale = drawer->GetHeight() / 720; int hscale = drawer->GetWidth() / 1280; scaleval = max(1, min(vscale, hscale)); } @@ -194,10 +194,8 @@ int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1; // //========================================================================== -void DrawTexture(F2DDrawer *drawer, FGameTexture* img, double x, double y, int tags_first, ...) +static void DoDrawTexture(F2DDrawer *drawer, FGameTexture* img, double x, double y, int tags_first, Va_List& tags) { - Va_List tags; - va_start(tags.list, tags_first); DrawParms parms; if (!img || !img->isValid()) return; @@ -210,6 +208,23 @@ void DrawTexture(F2DDrawer *drawer, FGameTexture* img, double x, double y, int t drawer->AddTexture(img, parms); } + +void DrawTexture(F2DDrawer *drawer, FGameTexture* img, double x, double y, int tags_first, ...) +{ + Va_List tags; + va_start(tags.list, tags_first); + DoDrawTexture(drawer, img, x, y, tags_first, tags); +} + +void DrawTexture(F2DDrawer *drawer, FTextureID texid, bool animate, double x, double y, int tags_first, ...) +{ + Va_List tags; + va_start(tags.list, tags_first); + auto img = TexMan.GetGameTexture(texid, animate); + DoDrawTexture(drawer, img, x, y, tags_first, tags); +} + + //========================================================================== // // ZScript texture drawing function @@ -218,7 +233,7 @@ void DrawTexture(F2DDrawer *drawer, FGameTexture* img, double x, double y, int t int ListGetInt(VMVa_List &tags); -static void DrawTexture(F2DDrawer *drawer, FGameTexture *img, double x, double y, VMVa_List &args) +static void DoDrawTexture(F2DDrawer *drawer, FGameTexture *img, double x, double y, VMVa_List &args) { DrawParms parms; uint32_t tag = ListGetInt(args); @@ -242,7 +257,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawTexture) auto tex = TexMan.GameByIndex(texid, animate); VMVa_List args = { param + 4, 0, numparam - 5, va_reginfo + 4 }; - DrawTexture(twod, tex, x, y, args); + DoDrawTexture(twod, tex, x, y, args); return 0; } diff --git a/source/common/2d/v_draw.h b/source/common/2d/v_draw.h index 673460848..7b1dfa9b6 100644 --- a/source/common/2d/v_draw.h +++ b/source/common/2d/v_draw.h @@ -247,13 +247,11 @@ int GetUIScale(F2DDrawer* drawer, int altval); int GetConScale(F2DDrawer* drawer, int altval); EXTERN_CVAR(Int, uiscale); +EXTERN_CVAR(Int, con_scale); inline int active_con_scale(F2DDrawer *drawer) { - // this sets the threshold for upscaling the console font to 2560 x 1440. - int vscale = drawer->GetHeight() / 720; - int hscale = drawer->GetWidth() / 1280; - return max(1, min(vscale, hscale)); + return GetConScale(drawer, con_scale); } #ifdef DrawText @@ -274,6 +272,7 @@ void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double void DrawChar(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, int character, int tag_first, ...); void DrawTexture(F2DDrawer* drawer, FGameTexture* img, double x, double y, int tags_first, ...); +void DrawTexture(F2DDrawer *drawer, FTextureID texid, bool animate, double x, double y, int tags_first, ...); void DoDim(F2DDrawer* drawer, PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr); void Dim(F2DDrawer* drawer, PalEntry color, float damount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr); diff --git a/source/common/console/c_console.cpp b/source/common/console/c_console.cpp index 3d54e6adb..fb7fe077d 100644 --- a/source/common/console/c_console.cpp +++ b/source/common/console/c_console.cpp @@ -128,6 +128,11 @@ static GameAtExit *ExitCmdList; static char *work = NULL; static int worklen = 0; +CUSTOM_CVAR(Int, con_scale, 0, CVAR_ARCHIVE) +{ + if (self < 0) self = 0; +} + CUSTOM_CVAR(Float, con_alpha, 0.75f, CVAR_ARCHIVE) { if (self < 0.f) self = 0.f; @@ -600,7 +605,7 @@ void C_DrawConsole () if (conback.isValid() && gamestate != GS_FULLCONSOLE) { - DrawTexture (twod, TexMan.GetGameTexture(conback), 0, visheight - screen->GetHeight(), + DrawTexture (twod, conback, false, 0, visheight - screen->GetHeight(), DTA_DestWidth, twod->GetWidth(), DTA_DestHeight, twod->GetHeight(), DTA_ColorOverlay, conshade, diff --git a/source/common/cutscenes/screenjob.cpp b/source/common/cutscenes/screenjob.cpp index 901cf5f7d..de929e9bf 100644 --- a/source/common/cutscenes/screenjob.cpp +++ b/source/common/cutscenes/screenjob.cpp @@ -208,10 +208,16 @@ bool ScreenJobResponder(event_t* ev) C_ToggleConsole(); return true; } + if (binding.CompareNoCase("screenshot") == 0) + { + C_DoCommand("screenshot"); + return true; + } } FInputEvent evt = ev; if (cutscene.runner) { + ScaleOverrider ovr(twod); IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, OnEvent) { int result = 0; @@ -235,6 +241,7 @@ bool ScreenJobTick() ticks++; if (cutscene.runner) { + ScaleOverrider ovr(twod); IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, OnTick) { int result = 0; @@ -260,6 +267,7 @@ void ScreenJobDraw() if (cutscene.runner) { twod->ClearScreen(); + ScaleOverrider ovr(twod); IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, RunFrame) { VMValue parm[] = { cutscene.runner, smoothratio }; @@ -278,6 +286,7 @@ bool ScreenJobValidate() { if (cutscene.runner) { + ScaleOverrider ovr(twod); IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, Validate) { int res; diff --git a/source/common/engine/namedef.h b/source/common/engine/namedef.h index 3c67191cd..7f9024538 100644 --- a/source/common/engine/namedef.h +++ b/source/common/engine/namedef.h @@ -115,6 +115,8 @@ xx(State) xx(Fixed) xx(Vector2) xx(Vector3) +xx(FVector2) +xx(FVector3) xx(let) xx(Min) diff --git a/source/common/engine/serializer.h b/source/common/engine/serializer.h index b114923df..a16d348a4 100644 --- a/source/common/engine/serializer.h +++ b/source/common/engine/serializer.h @@ -326,6 +326,16 @@ inline FSerializer &Serialize(FSerializer &arc, const char *key, DVector2 &p, DV return arc.Array(key, &p[0], def? &(*def)[0] : nullptr, 2, true); } +inline FSerializer& Serialize(FSerializer& arc, const char* key, FVector3& p, FVector3* def) +{ + return arc.Array(key, &p[0], def ? &(*def)[0] : nullptr, 3, true); +} + +inline FSerializer& Serialize(FSerializer& arc, const char* key, FVector2& p, FVector2* def) +{ + return arc.Array(key, &p[0], def ? &(*def)[0] : nullptr, 2, true); +} + template inline FSerializer &Serialize(FSerializer &arc, const char *key, TAngle &p, TAngle *def) { diff --git a/source/common/rendering/gl/gl_framebuffer.cpp b/source/common/rendering/gl/gl_framebuffer.cpp index e4d9f09ad..52cf004d0 100644 --- a/source/common/rendering/gl/gl_framebuffer.cpp +++ b/source/common/rendering/gl/gl_framebuffer.cpp @@ -175,7 +175,7 @@ void OpenGLFrameBuffer::InitializeState() GLRenderer->Initialize(GetWidth(), GetHeight()); static_cast(mLights->GetBuffer())->BindBase(); - mDebug = std::make_shared(); + mDebug = std::make_unique(); mDebug->Update(); } diff --git a/source/common/rendering/gl/gl_framebuffer.h b/source/common/rendering/gl/gl_framebuffer.h index 84242d792..06492fd9d 100644 --- a/source/common/rendering/gl/gl_framebuffer.h +++ b/source/common/rendering/gl/gl_framebuffer.h @@ -20,7 +20,6 @@ class OpenGLFrameBuffer : public SystemGLFrameBuffer public: - explicit OpenGLFrameBuffer() {} OpenGLFrameBuffer(void *hMonitor, bool fullscreen) ; ~OpenGLFrameBuffer(); bool CompileNextShader() override; @@ -66,7 +65,7 @@ public: void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) override; bool HWGammaActive = false; // Are we using hardware or software gamma? - std::shared_ptr mDebug; // Debug API + std::unique_ptr mDebug; // Debug API FTexture *WipeStartScreen() override; FTexture *WipeEndScreen() override; diff --git a/source/common/rendering/gles/gles_framebuffer.h b/source/common/rendering/gles/gles_framebuffer.h index 9e7d14fdc..d7c7587f8 100644 --- a/source/common/rendering/gles/gles_framebuffer.h +++ b/source/common/rendering/gles/gles_framebuffer.h @@ -10,7 +10,6 @@ namespace OpenGLESRenderer { class FHardwareTexture; -class FGLDebug; class OpenGLFrameBuffer : public SystemGLFrameBuffer { @@ -61,7 +60,6 @@ public: void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) override; bool HWGammaActive = false; // Are we using hardware or software gamma? - std::shared_ptr mDebug; // Debug API FTexture *WipeStartScreen() override; FTexture *WipeEndScreen() override; diff --git a/source/common/rendering/hwrenderer/data/hw_skydome.cpp b/source/common/rendering/hwrenderer/data/hw_skydome.cpp index aa726d02b..837f4023e 100644 --- a/source/common/rendering/hwrenderer/data/hw_skydome.cpp +++ b/source/common/rendering/hwrenderer/data/hw_skydome.cpp @@ -127,9 +127,10 @@ FSkyVertexBuffer::FSkyVertexBuffer() static const FVertexBufferAttribute format[] = { { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FSkyVertex, x) }, { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FSkyVertex, u) }, - { 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(FSkyVertex, color) } + { 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(FSkyVertex, color) }, + { 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FSkyVertex, lu) }, }; - mVertexBuffer->SetFormat(1, 3, sizeof(FSkyVertex), format); + mVertexBuffer->SetFormat(1, 4, sizeof(FSkyVertex), format); mVertexBuffer->SetData(mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], BufferUsageType::Static); } diff --git a/source/common/rendering/hwrenderer/data/hw_skydome.h b/source/common/rendering/hwrenderer/data/hw_skydome.h index 0016b3138..f794e96bb 100644 --- a/source/common/rendering/hwrenderer/data/hw_skydome.h +++ b/source/common/rendering/hwrenderer/data/hw_skydome.h @@ -16,7 +16,7 @@ const int skyoffsetfactor = 57; struct FSkyVertex { - float x, y, z, u, v; + float x, y, z, u, v, lu, lv, lindex; PalEntry color; void Set(float xx, float zz, float yy, float uu=0, float vv=0, PalEntry col=0xffffffff) @@ -26,6 +26,9 @@ struct FSkyVertex y = yy; u = uu; v = vv; + lu = 0.0f; + lv = 0.0f; + lindex = -1.0f; color = col; } @@ -36,6 +39,9 @@ struct FSkyVertex z = zz; u = uu; v = vv; + lu = 0.0f; + lv = 0.0f; + lindex = -1.0f; color = col; } diff --git a/source/common/rendering/r_thread.h b/source/common/rendering/r_thread.h index f8db730cd..33d7c0c0a 100644 --- a/source/common/rendering/r_thread.h +++ b/source/common/rendering/r_thread.h @@ -64,9 +64,8 @@ public: // Working buffer used by the tilted (sloped) span drawer const uint8_t *tiltlighting[MAXWIDTH]; - std::shared_ptr poly; - std::shared_ptr columndrawer; - + std::unique_ptr poly; + size_t debug_draw_pos = 0; // Checks if a line is rendered by this thread diff --git a/source/common/scripting/backend/codegen.cpp b/source/common/scripting/backend/codegen.cpp index 0fd13f9ce..9232a6589 100644 --- a/source/common/scripting/backend/codegen.cpp +++ b/source/common/scripting/backend/codegen.cpp @@ -1688,6 +1688,13 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx) delete this; return x; } + else if ((basex->IsVector2() && IsVector2()) || (basex->IsVector3() && IsVector3())) + { + auto x = basex; + basex = nullptr; + delete this; + return x; + } // todo: pointers to class objects. // All other types are only compatible to themselves and have already been handled above by the equality check. // Anything that falls through here is not compatible and must print an error. @@ -2587,6 +2594,12 @@ FxExpression *FxMultiAssign::Resolve(FCompileContext &ctx) } auto VMRight = static_cast(Right); auto rets = VMRight->GetReturnTypes(); + if (Base.Size() == 1) + { + Right->ScriptPosition.Message(MSG_ERROR, "Multi-assignment with only one element", VMRight->Function->SymbolName.GetChars()); + delete this; + return nullptr; + } if (rets.Size() < Base.Size()) { Right->ScriptPosition.Message(MSG_ERROR, "Insufficient returns in function %s", VMRight->Function->SymbolName.GetChars()); @@ -2764,7 +2777,7 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx) else if (left->IsVector() && right->IsVector()) { // a vector2 can be added to or subtracted from a vector 3 but it needs to be the right operand. - if (left->ValueType == right->ValueType || (left->ValueType == TypeVector3 && right->ValueType == TypeVector2)) + if (left->ValueType == right->ValueType || (left->IsVector3() && right->IsVector2())) { ValueType = left->ValueType; } @@ -2857,8 +2870,9 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build) if (IsVector()) { assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT); - build->Emit(right->ValueType == TypeVector2? OP_ADDV2_RR : OP_ADDV3_RR, to.RegNum, op1.RegNum, op2.RegNum); - if (left->ValueType == TypeVector3 && right->ValueType == TypeVector2 && to.RegNum != op1.RegNum) + + build->Emit(right->IsVector2() ? OP_ADDV2_RR : OP_ADDV3_RR, to.RegNum, op1.RegNum, op2.RegNum); + if (left->IsVector3() && right->IsVector2() && to.RegNum != op1.RegNum) { // must move the z-coordinate build->Emit(OP_MOVEF, to.RegNum + 2, op1.RegNum + 2); @@ -2890,7 +2904,7 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build) if (IsVector()) { assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT); - build->Emit(right->ValueType == TypeVector2 ? OP_SUBV2_RR : OP_SUBV3_RR, to.RegNum, op1.RegNum, op2.RegNum); + build->Emit(right->IsVector2() ? OP_SUBV2_RR : OP_SUBV3_RR, to.RegNum, op1.RegNum, op2.RegNum); return to; } else if (ValueType->GetRegType() == REGT_FLOAT) @@ -3093,11 +3107,11 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build) int op; if (op2.Konst) { - op = Operator == '*' ? (ValueType == TypeVector2 ? OP_MULVF2_RK : OP_MULVF3_RK) : (ValueType == TypeVector2 ? OP_DIVVF2_RK : OP_DIVVF3_RK); + op = Operator == '*' ? (IsVector2() ? OP_MULVF2_RK : OP_MULVF3_RK) : (IsVector2() ? OP_DIVVF2_RK : OP_DIVVF3_RK); } else { - op = Operator == '*' ? (ValueType == TypeVector2 ? OP_MULVF2_RR : OP_MULVF3_RR) : (ValueType == TypeVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR); + op = Operator == '*' ? (IsVector2() ? OP_MULVF2_RR : OP_MULVF3_RR) : (IsVector2() ? OP_DIVVF2_RR : OP_DIVVF3_RR); } op1.Free(build); op2.Free(build); @@ -9067,13 +9081,13 @@ ExpEmit FxVectorBuiltin::Emit(VMFunctionBuilder *build) ExpEmit op = Self->Emit(build); if (Function == NAME_Length) { - build->Emit(Self->ValueType == TypeVector2 ? OP_LENV2 : OP_LENV3, to.RegNum, op.RegNum); + build->Emit(Self->ValueType == TypeVector2 || Self->ValueType == TypeFVector2 ? OP_LENV2 : OP_LENV3, to.RegNum, op.RegNum); } else { ExpEmit len(build, REGT_FLOAT); - build->Emit(Self->ValueType == TypeVector2 ? OP_LENV2 : OP_LENV3, len.RegNum, op.RegNum); - build->Emit(Self->ValueType == TypeVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR, to.RegNum, op.RegNum, len.RegNum); + build->Emit(Self->ValueType == TypeVector2 || Self->ValueType == TypeFVector2 ? OP_LENV2 : OP_LENV3, len.RegNum, op.RegNum); + build->Emit(Self->ValueType == TypeVector2 || Self->ValueType == TypeFVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR, to.RegNum, op.RegNum, len.RegNum); len.Free(build); } op.Free(build); @@ -10734,6 +10748,10 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build) FxLocalVariableDeclaration::FxLocalVariableDeclaration(PType *type, FName name, FxExpression *initval, int varflags, const FScriptPosition &p) :FxExpression(EFX_LocalVariableDeclaration, p) { + // Local FVector isn't different from Vector + if (type == TypeFVector2) type = TypeVector2; + else if (type == TypeFVector3) type = TypeVector3; + ValueType = type; VarFlags = varflags; Name = name; diff --git a/source/common/scripting/backend/codegen.h b/source/common/scripting/backend/codegen.h index 43fb7f061..0bf71e5a5 100644 --- a/source/common/scripting/backend/codegen.h +++ b/source/common/scripting/backend/codegen.h @@ -336,7 +336,9 @@ public: bool IsFloat() const { return ValueType->isFloat(); } bool IsInteger() const { return ValueType->isNumeric() && ValueType->isIntCompatible(); } bool IsPointer() const { return ValueType->isPointer(); } - bool IsVector() const { return ValueType == TypeVector2 || ValueType == TypeVector3; }; + bool IsVector() const { return ValueType == TypeVector2 || ValueType == TypeVector3 || ValueType == TypeFVector2 || ValueType == TypeFVector3; }; + bool IsVector2() const { return ValueType == TypeVector2 || ValueType == TypeFVector2; }; + bool IsVector3() const { return ValueType == TypeVector3 || ValueType == TypeFVector3; }; bool IsBoolCompat() const { return ValueType->isScalar(); } bool IsObject() const { return ValueType->isObjectPointer(); } bool IsArray() const { return ValueType->isArray() || (ValueType->isPointer() && ValueType->toPointer()->PointedType->isArray()); } diff --git a/source/common/scripting/core/types.cpp b/source/common/scripting/core/types.cpp index c98cc7435..01f83ba89 100644 --- a/source/common/scripting/core/types.cpp +++ b/source/common/scripting/core/types.cpp @@ -61,6 +61,8 @@ PPointer *TypeFont; PStateLabel *TypeStateLabel; PStruct *TypeVector2; PStruct *TypeVector3; +PStruct* TypeFVector2; +PStruct* TypeFVector3; PStruct *TypeColorStruct; PStruct *TypeStringStruct; PPointer *TypeNullPtr; @@ -347,6 +349,28 @@ void PType::StaticInit() TypeVector3->RegCount = 3; + TypeFVector2 = new PStruct(NAME_FVector2, nullptr); + TypeFVector2->AddField(NAME_X, TypeFloat32); + TypeFVector2->AddField(NAME_Y, TypeFloat32); + TypeTable.AddType(TypeFVector2, NAME_Struct); + TypeFVector2->loadOp = OP_LFV2; + TypeFVector2->storeOp = OP_SFV2; + TypeFVector2->moveOp = OP_MOVEV2; + TypeFVector2->RegType = REGT_FLOAT; + TypeFVector2->RegCount = 2; + + TypeFVector3 = new PStruct(NAME_FVector3, nullptr); + TypeFVector3->AddField(NAME_X, TypeFloat32); + TypeFVector3->AddField(NAME_Y, TypeFloat32); + TypeFVector3->AddField(NAME_Z, TypeFloat32); + // allow accessing xy as a vector2 + TypeFVector3->Symbols.AddSymbol(Create(NAME_XY, TypeFVector2, VARF_Transient, 0)); + TypeTable.AddType(TypeFVector3, NAME_Struct); + TypeFVector3->loadOp = OP_LFV3; + TypeFVector3->storeOp = OP_SFV3; + TypeFVector3->moveOp = OP_MOVEV3; + TypeFVector3->RegType = REGT_FLOAT; + TypeFVector3->RegCount = 3; Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_sByte, TypeSInt8)); Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Byte, TypeUInt8)); @@ -366,6 +390,8 @@ void PType::StaticInit() Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_State, TypeState)); Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Vector2, TypeVector2)); Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Vector3, TypeVector3)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_FVector2, TypeFVector2)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_FVector3, TypeFVector3)); } @@ -2321,6 +2347,29 @@ PStruct *NewStruct(FName name, PTypeBase *outer, bool native) PPrototype::PPrototype(const TArray &rettypes, const TArray &argtypes) : ArgumentTypes(argtypes), ReturnTypes(rettypes) { + for (auto& type: ArgumentTypes) + { + if (type == TypeFVector2) + { + type = TypeVector2; + } + else if (type == TypeFVector3) + { + type = TypeVector3; + } + } + + for (auto& type : ReturnTypes) + { + if (type == TypeFVector2) + { + type = TypeVector2; + } + else if (type == TypeFVector3) + { + type = TypeVector3; + } + } } //========================================================================== diff --git a/source/common/scripting/core/types.h b/source/common/scripting/core/types.h index ae423af9d..e8d07e91a 100644 --- a/source/common/scripting/core/types.h +++ b/source/common/scripting/core/types.h @@ -612,8 +612,10 @@ extern PSound *TypeSound; extern PColor *TypeColor; extern PTextureID *TypeTextureID; extern PSpriteID *TypeSpriteID; -extern PStruct *TypeVector2; -extern PStruct *TypeVector3; +extern PStruct* TypeVector2; +extern PStruct* TypeVector3; +extern PStruct* TypeFVector2; +extern PStruct* TypeFVector3; extern PStruct *TypeColorStruct; extern PStruct *TypeStringStruct; extern PStatePointer *TypeState; diff --git a/source/common/scripting/frontend/zcc_compile.cpp b/source/common/scripting/frontend/zcc_compile.cpp index 8fc0bbe24..9e3daeaef 100644 --- a/source/common/scripting/frontend/zcc_compile.cpp +++ b/source/common/scripting/frontend/zcc_compile.cpp @@ -2026,7 +2026,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool do { auto type = DetermineType(c->Type(), f, f->Name, t, false, false); - if (type->isContainer() && type != TypeVector2 && type != TypeVector3) + if (type->isContainer() && type != TypeVector2 && type != TypeVector3 && type != TypeFVector2 && type != TypeFVector3) { // structs and classes only get passed by pointer. type = NewPointer(type); @@ -2036,6 +2036,14 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool Error(f, "The return type of a function cannot be a dynamic array"); break; } + else if (type == TypeFVector2) + { + type = TypeVector2; + } + else if (type == TypeFVector3) + { + type = TypeVector3; + } // TBD: disallow certain types? For now, let everything pass that isn't an array. rets.Push(type); t = static_cast(t->SiblingNext); @@ -2222,16 +2230,16 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool else if (type->GetRegType() != REGT_NIL) { if (p->Flags & ZCC_Out) flags |= VARF_Out; - if (type == TypeVector2) + if (type == TypeVector2 || type == TypeFVector2) { elementcount = 2; } - else if (type == TypeVector3) + else if (type == TypeVector3 || type == TypeFVector3) { elementcount = 3; } } - if (type->GetRegType() == REGT_NIL && type != TypeVector2 && type != TypeVector3) + if (type->GetRegType() == REGT_NIL && type != TypeVector2 && type != TypeVector3 && type != TypeFVector2 && type != TypeFVector3) { Error(p, "Invalid type %s for function parameter", type->DescriptiveName()); } @@ -2268,13 +2276,13 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool if (x != nullptr) { // Vectors need special treatment because they use more than one entry in the Defaults and do not report as actual constants - if (type == TypeVector2 && x->ExprType == EFX_VectorValue && static_cast(x)->isConstVector(2)) + if ((type == TypeVector2 || type == TypeFVector2) && x->ExprType == EFX_VectorValue && static_cast(x)->isConstVector(2)) { auto vx = static_cast(x); vmval[0] = static_cast(vx->xyz[0])->GetValue().GetFloat(); vmval[1] = static_cast(vx->xyz[1])->GetValue().GetFloat(); } - else if (type == TypeVector3 && x->ExprType == EFX_VectorValue && static_cast(x)->isConstVector(3)) + else if ((type == TypeVector3 || type == TypeFVector3) && x->ExprType == EFX_VectorValue && static_cast(x)->isConstVector(3)) { auto vx = static_cast(x); vmval[0] = static_cast(vx->xyz[0])->GetValue().GetFloat(); diff --git a/source/common/scripting/frontend/zcc_parser.cpp b/source/common/scripting/frontend/zcc_parser.cpp index cae956672..be94887ea 100644 --- a/source/common/scripting/frontend/zcc_parser.cpp +++ b/source/common/scripting/frontend/zcc_parser.cpp @@ -45,14 +45,58 @@ TArray Includes; TArray IncludeLocs; +static FString ResolveIncludePath(const FString &path,const FString &lumpname){ + if (path.IndexOf("./") == 0 || path.IndexOf("../") == 0) // relative path resolving + { + auto start = lumpname.LastIndexOf(":"); // find find separator between wad and path + + auto end = lumpname.LastIndexOf("/"); // find last '/' + + FString fullPath = lumpname.Mid(start + 1, end - start - 1); // get path from lumpname (format 'wad:filepath/filename') + + if (start != -1 && end != -1) + { + FString relativePath = path; + if ( relativePath.IndexOf("./") == 0 ) // strip initial marker + { + relativePath = relativePath.Mid(2); + } + + bool pathOk = true; + + while (relativePath.IndexOf("../") == 0) // go back one folder for each '..' + { + relativePath = relativePath.Mid(3); + auto slash_index = fullPath.LastIndexOf("/"); + if (slash_index != -1) { + fullPath = fullPath.Mid(0, slash_index); + } else { + pathOk = false; + break; + } + } + if (pathOk) // if '..' parsing was successful + { + return fullPath + "/" + relativePath; + } + } + } + return path; +} + static FString ZCCTokenName(int terminal); void AddInclude(ZCC_ExprConstant *node) { assert(node->Type == TypeString); - if (Includes.Find(*node->StringVal) >= Includes.Size()) + + FScriptPosition pos(*node); + + FString path = ResolveIncludePath(*node->StringVal, pos.FileName.GetChars()); + + if (Includes.Find(path) >= Includes.Size()) { - Includes.Push(*node->StringVal); - IncludeLocs.Push(*node); + Includes.Push(path); + IncludeLocs.Push(pos); } } @@ -421,45 +465,6 @@ PNamespace *ParseOneScript(const int baselump, ZCCParseState &state) for (unsigned i = 0; i < Includes.Size(); i++) { lumpnum = fileSystem.CheckNumForFullName(Includes[i], true); - if (lumpnum == -1 && ( Includes[i].IndexOf("./") == 0 || Includes[i].IndexOf("../") == 0 ) ) // relative path resolving - { - FString fullPath = IncludeLocs[i].FileName.GetChars(); // get full path, format 'wad:filepath/filename' - - auto start = fullPath.IndexOf(":"); // find first ':' - - auto end = fullPath.LastIndexOf("/"); // find last '/' - - if (start!=-1&&end!=-1) - { - FString resolvedPath = fullPath.Mid(start + 1, end - start - 1); // extract filepath from string - FString relativePath = Includes[i]; - if ( relativePath.IndexOf("./") == 0 ) // strip initial marker - { - relativePath = relativePath.Mid(2); - } - - bool pathOk = true; - - while (relativePath.IndexOf("../") == 0) // go back one folder for each '..' - { - relativePath = relativePath.Mid(3); - auto slash_index = resolvedPath.LastIndexOf("/"); - if (slash_index != -1) { - resolvedPath = resolvedPath.Mid(0,slash_index); - } else { - pathOk = false; - break; - } - } - if ( pathOk ) // if '..' parsing was successful - { - resolvedPath += "/" + relativePath; // add relative path - - lumpnum = fileSystem.CheckNumForFullName(resolvedPath, true); // check for relative include - } - } - - } if (lumpnum == -1) { IncludeLocs[i].Message(MSG_ERROR, "Include script lump %s not found", Includes[i].GetChars()); diff --git a/source/common/scripting/interface/vmnatives.cpp b/source/common/scripting/interface/vmnatives.cpp index c326b2e1b..079cd78ae 100644 --- a/source/common/scripting/interface/vmnatives.cpp +++ b/source/common/scripting/interface/vmnatives.cpp @@ -1055,7 +1055,12 @@ DEFINE_ACTION_FUNCTION_NATIVE(_System, MusicEnabled, MusicEnabled) ACTION_RETURN_INT(MusicEnabled()); } -DEFINE_ACTION_FUNCTION_NATIVE(_System, GetTimeFrac, I_GetTimeFrac) +static double Jit_GetTimeFrac() // cannot use I_GetTimwfrac directly due to default arguments. +{ + return I_GetTimeFrac(); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_System, GetTimeFrac, Jit_GetTimeFrac) { ACTION_RETURN_FLOAT(I_GetTimeFrac()); } diff --git a/source/common/scripting/jit/jit.cpp b/source/common/scripting/jit/jit.cpp index 9823a6029..8937fa1e0 100644 --- a/source/common/scripting/jit/jit.cpp +++ b/source/common/scripting/jit/jit.cpp @@ -304,12 +304,12 @@ void JitCompiler::SetupSimpleFrame() { cc.mov(regA[rega++], x86::ptr(args, argsPos++ * sizeof(VMValue) + offsetof(VMValue, a))); } - else if (type == TypeVector2) + else if (type == TypeVector2 || type == TypeFVector2) { cc.movsd(regF[regf++], x86::qword_ptr(args, argsPos++ * sizeof(VMValue) + offsetof(VMValue, f))); cc.movsd(regF[regf++], x86::qword_ptr(args, argsPos++ * sizeof(VMValue) + offsetof(VMValue, f))); } - else if (type == TypeVector3) + else if (type == TypeVector3 || type == TypeFVector3) { cc.movsd(regF[regf++], x86::qword_ptr(args, argsPos++ * sizeof(VMValue) + offsetof(VMValue, f))); cc.movsd(regF[regf++], x86::qword_ptr(args, argsPos++ * sizeof(VMValue) + offsetof(VMValue, f))); diff --git a/source/common/scripting/jit/jit_load.cpp b/source/common/scripting/jit/jit_load.cpp index 0881cfd21..ec5f795df 100644 --- a/source/common/scripting/jit/jit_load.cpp +++ b/source/common/scripting/jit/jit_load.cpp @@ -325,6 +325,54 @@ void JitCompiler::EmitLV3_R() cc.movsd(regF[A + 2], asmjit::x86::qword_ptr(tmp, 16)); } +void JitCompiler::EmitLFV2() +{ + EmitNullPointerThrow(B, X_READ_NIL); + auto tmp = newTempIntPtr(); + cc.lea(tmp, asmjit::x86::qword_ptr(regA[B], konstd[C])); + cc.movss(regF[A], asmjit::x86::qword_ptr(tmp)); + cc.movss(regF[A + 1], asmjit::x86::qword_ptr(tmp, 4)); + cc.cvtss2sd(regF[A], regF[A]); + cc.cvtss2sd(regF[A + 1], regF[A + 1]); +} + +void JitCompiler::EmitLFV2_R() +{ + EmitNullPointerThrow(B, X_READ_NIL); + auto tmp = newTempIntPtr(); + cc.lea(tmp, asmjit::x86::qword_ptr(regA[B], regD[C])); + cc.movss(regF[A], asmjit::x86::qword_ptr(tmp)); + cc.movss(regF[A + 1], asmjit::x86::qword_ptr(tmp, 4)); + cc.cvtss2sd(regF[A], regF[A]); + cc.cvtss2sd(regF[A + 1], regF[A + 1]); +} + +void JitCompiler::EmitLFV3() +{ + EmitNullPointerThrow(B, X_READ_NIL); + auto tmp = newTempIntPtr(); + cc.lea(tmp, asmjit::x86::qword_ptr(regA[B], konstd[C])); + cc.movss(regF[A], asmjit::x86::qword_ptr(tmp)); + cc.movss(regF[A + 1], asmjit::x86::qword_ptr(tmp, 4)); + cc.movss(regF[A + 2], asmjit::x86::qword_ptr(tmp, 8)); + cc.cvtss2sd(regF[A], regF[A]); + cc.cvtss2sd(regF[A + 1], regF[A + 1]); + cc.cvtss2sd(regF[A + 2], regF[A + 2]); +} + +void JitCompiler::EmitLFV3_R() +{ + EmitNullPointerThrow(B, X_READ_NIL); + auto tmp = newTempIntPtr(); + cc.lea(tmp, asmjit::x86::qword_ptr(regA[B], regD[C])); + cc.movss(regF[A], asmjit::x86::qword_ptr(tmp)); + cc.movss(regF[A + 1], asmjit::x86::qword_ptr(tmp, 4)); + cc.movss(regF[A + 2], asmjit::x86::qword_ptr(tmp, 8)); + cc.cvtss2sd(regF[A], regF[A]); + cc.cvtss2sd(regF[A + 1], regF[A + 1]); + cc.cvtss2sd(regF[A + 2], regF[A + 2]); +} + static void SetString(FString *to, char **from) { *to = *from; diff --git a/source/common/scripting/jit/jit_store.cpp b/source/common/scripting/jit/jit_store.cpp index 6dc1a45a9..2bce22566 100644 --- a/source/common/scripting/jit/jit_store.cpp +++ b/source/common/scripting/jit/jit_store.cpp @@ -161,6 +161,64 @@ void JitCompiler::EmitSV3_R() cc.movsd(asmjit::x86::qword_ptr(tmp, 16), regF[B + 2]); } +void JitCompiler::EmitSFV2() +{ + EmitNullPointerThrow(A, X_WRITE_NIL); + auto tmp = newTempIntPtr(); + cc.mov(tmp, regA[A]); + cc.add(tmp, konstd[C]); + + auto tmpF = newTempXmmSs(); + cc.cvtsd2ss(tmpF, regF[B]); + cc.movss(asmjit::x86::qword_ptr(tmp), tmpF); + cc.cvtsd2ss(tmpF, regF[B + 1]); + cc.movss(asmjit::x86::qword_ptr(tmp, 4), tmpF); +} + +void JitCompiler::EmitSFV2_R() +{ + EmitNullPointerThrow(A, X_WRITE_NIL); + auto tmp = newTempIntPtr(); + cc.mov(tmp, regA[A]); + cc.add(tmp, regD[C]); + + auto tmpF = newTempXmmSs(); + cc.cvtsd2ss(tmpF, regF[B]); + cc.movss(asmjit::x86::qword_ptr(tmp), tmpF); + cc.cvtsd2ss(tmpF, regF[B + 1]); + cc.movss(asmjit::x86::qword_ptr(tmp, 4), tmpF); +} + +void JitCompiler::EmitSFV3() +{ + EmitNullPointerThrow(A, X_WRITE_NIL); + auto tmp = newTempIntPtr(); + cc.mov(tmp, regA[A]); + cc.add(tmp, konstd[C]); + auto tmpF = newTempXmmSs(); + cc.cvtsd2ss(tmpF, regF[B]); + cc.movss(asmjit::x86::qword_ptr(tmp), tmpF); + cc.cvtsd2ss(tmpF, regF[B + 1]); + cc.movss(asmjit::x86::qword_ptr(tmp, 4), tmpF); + cc.cvtsd2ss(tmpF, regF[B + 2]); + cc.movss(asmjit::x86::qword_ptr(tmp, 8), tmpF); +} + +void JitCompiler::EmitSFV3_R() +{ + EmitNullPointerThrow(A, X_WRITE_NIL); + auto tmp = newTempIntPtr(); + cc.mov(tmp, regA[A]); + cc.add(tmp, regD[C]); + auto tmpF = newTempXmmSs(); + cc.cvtsd2ss(tmpF, regF[B]); + cc.movss(asmjit::x86::qword_ptr(tmp), tmpF); + cc.cvtsd2ss(tmpF, regF[B + 1]); + cc.movss(asmjit::x86::qword_ptr(tmp, 4), tmpF); + cc.cvtsd2ss(tmpF, regF[B + 2]); + cc.movss(asmjit::x86::qword_ptr(tmp, 8), tmpF); +} + void JitCompiler::EmitSBIT() { EmitNullPointerThrow(A, X_WRITE_NIL); diff --git a/source/common/scripting/vm/vmexec.h b/source/common/scripting/vm/vmexec.h index a4d666dcc..0e4b50b63 100644 --- a/source/common/scripting/vm/vmexec.h +++ b/source/common/scripting/vm/vmexec.h @@ -263,39 +263,77 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) GETADDR(PB,RC,X_READ_NIL); reg.a[a] = *(void **)ptr; NEXTOP; - OP(LV2): + OP(LV2) : + ASSERTF(a + 1); ASSERTA(B); ASSERTKD(C); + GETADDR(PB, KC, X_READ_NIL); + { + auto v = (double*)ptr; + reg.f[a] = v[0]; + reg.f[a + 1] = v[1]; + } + NEXTOP; + OP(LV2_R) : + ASSERTF(a + 1); ASSERTA(B); ASSERTD(C); + GETADDR(PB, RC, X_READ_NIL); + { + auto v = (double*)ptr; + reg.f[a] = v[0]; + reg.f[a + 1] = v[1]; + } + NEXTOP; + OP(LV3) : + ASSERTF(a + 2); ASSERTA(B); ASSERTKD(C); + GETADDR(PB, KC, X_READ_NIL); + { + auto v = (double*)ptr; + reg.f[a] = v[0]; + reg.f[a + 1] = v[1]; + reg.f[a + 2] = v[2]; + } + NEXTOP; + OP(LV3_R) : + ASSERTF(a + 2); ASSERTA(B); ASSERTD(C); + GETADDR(PB, RC, X_READ_NIL); + { + auto v = (double*)ptr; + reg.f[a] = v[0]; + reg.f[a + 1] = v[1]; + reg.f[a + 2] = v[2]; + } + NEXTOP; + OP(LFV2): ASSERTF(a+1); ASSERTA(B); ASSERTKD(C); GETADDR(PB,KC,X_READ_NIL); { - auto v = (double *)ptr; + auto v = (float *)ptr; reg.f[a] = v[0]; reg.f[a+1] = v[1]; } NEXTOP; - OP(LV2_R): + OP(LFV2_R): ASSERTF(a+1); ASSERTA(B); ASSERTD(C); GETADDR(PB,RC,X_READ_NIL); { - auto v = (double *)ptr; + auto v = (float *)ptr; reg.f[a] = v[0]; reg.f[a+1] = v[1]; } NEXTOP; - OP(LV3): + OP(LFV3): ASSERTF(a+2); ASSERTA(B); ASSERTKD(C); GETADDR(PB,KC,X_READ_NIL); { - auto v = (double *)ptr; + auto v = (float *)ptr; reg.f[a] = v[0]; reg.f[a+1] = v[1]; reg.f[a+2] = v[2]; } NEXTOP; - OP(LV3_R): + OP(LFV3_R): ASSERTF(a+2); ASSERTA(B); ASSERTD(C); GETADDR(PB,RC,X_READ_NIL); { - auto v = (double *)ptr; + auto v = (float *)ptr; reg.f[a] = v[0]; reg.f[a+1] = v[1]; reg.f[a+2] = v[2]; @@ -430,6 +468,44 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) v[2] = reg.f[B+2]; } NEXTOP; + OP(SFV2): + ASSERTA(a); ASSERTF(B+1); ASSERTKD(C); + GETADDR(PA,KC,X_WRITE_NIL); + { + auto v = (float *)ptr; + v[0] = (float)reg.f[B]; + v[1] = (float)reg.f[B+1]; + } + NEXTOP; + OP(SFV2_R): + ASSERTA(a); ASSERTF(B+1); ASSERTD(C); + GETADDR(PA,RC,X_WRITE_NIL); + { + auto v = (float *)ptr; + v[0] = (float)reg.f[B]; + v[1] = (float)reg.f[B+1]; + } + NEXTOP; + OP(SFV3): + ASSERTA(a); ASSERTF(B+2); ASSERTKD(C); + GETADDR(PA,KC,X_WRITE_NIL); + { + auto v = (float *)ptr; + v[0] = (float)reg.f[B]; + v[1] = (float)reg.f[B+1]; + v[2] = (float)reg.f[B+2]; + } + NEXTOP; + OP(SFV3_R): + ASSERTA(a); ASSERTF(B+2); ASSERTD(C); + GETADDR(PA,RC,X_WRITE_NIL); + { + auto v = (float *)ptr; + v[0] = (float)reg.f[B]; + v[1] = (float)reg.f[B+1]; + v[2] = (float)reg.f[B+2]; + } + NEXTOP; OP(SBIT): ASSERTA(a); ASSERTD(B); GETADDR(PA,0,X_WRITE_NIL); diff --git a/source/common/scripting/vm/vmops.h b/source/common/scripting/vm/vmops.h index 82b3cabc4..af7fb233b 100644 --- a/source/common/scripting/vm/vmops.h +++ b/source/common/scripting/vm/vmops.h @@ -53,6 +53,10 @@ xx(LV3, lv3, RVRPKI, LV3_R, 4, REGT_INT) // load vector3 xx(LV3_R, lv3, RVRPRI, NOP, 0, 0) xx(LCS, lcs, RSRPKI, LCS_R, 4, REGT_INT) // load string from char ptr. xx(LCS_R, lcs, RSRPRI, NOP, 0, 0) +xx(LFV2, lfv2, RVRPKI, LFV2_R, 4, REGT_INT) // load fvector2 +xx(LFV2_R, lfv2, RVRPRI, NOP, 0, 0) +xx(LFV3, lfv3, RVRPKI, LFV3_R, 4, REGT_INT) // load fvector3 +xx(LFV3_R, lfv3, RVRPRI, NOP, 0, 0) xx(LBIT, lbit, RIRPI8, NOP, 0, 0) // rA = !!(*rB & C) -- *rB is a byte @@ -77,6 +81,10 @@ xx(SV2, sv2, RPRVKI, SV2_R, 4, REGT_INT) // store vector2 xx(SV2_R, sv2, RPRVRI, NOP, 0, 0) xx(SV3, sv3, RPRVKI, SV3_R, 4, REGT_INT) // store vector3 xx(SV3_R, sv3, RPRVRI, NOP, 0, 0) +xx(SFV2, sfv2, RPRVKI, SFV2_R, 4, REGT_INT) // store fvector2 +xx(SFV2_R, sfv2, RPRVRI, NOP, 0, 0) +xx(SFV3, sfv3, RPRVKI, SFV3_R, 4, REGT_INT) // store fvector3 +xx(SFV3_R, sfv3, RPRVRI, NOP, 0, 0) xx(SBIT, sbit, RPRII8, NOP, 0, 0) // *rA |= C if rB is true, *rA &= ~C otherwise diff --git a/source/common/startscreen/startscreen_hexen.cpp b/source/common/startscreen/startscreen_hexen.cpp index 122b6f362..6eef73599 100644 --- a/source/common/startscreen/startscreen_hexen.cpp +++ b/source/common/startscreen/startscreen_hexen.cpp @@ -141,7 +141,7 @@ bool FHexenStartScreen::DoProgress(int advance) { int notch_pos, x, y; - if (CurPos < MaxPos) + if (CurPos <= MaxPos) { int numnotches = (16 * 32) / NotchBits.GetWidth(); notch_pos = ((CurPos + 1) * numnotches) / MaxPos;