mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- backend update from GZDoom.
This commit is contained in:
parent
30b81c0920
commit
eb8fae761e
25 changed files with 416 additions and 94 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -115,6 +115,8 @@ xx(State)
|
|||
xx(Fixed)
|
||||
xx(Vector2)
|
||||
xx(Vector3)
|
||||
xx(FVector2)
|
||||
xx(FVector3)
|
||||
xx(let)
|
||||
|
||||
xx(Min)
|
||||
|
|
|
@ -326,6 +326,16 @@ inline FSerializer &Serialize(FSerializer &arc, const char *key, DVector2 &p, DV
|
|||
return arc.Array<double>(key, &p[0], def? &(*def)[0] : nullptr, 2, true);
|
||||
}
|
||||
|
||||
inline FSerializer& Serialize(FSerializer& arc, const char* key, FVector3& p, FVector3* def)
|
||||
{
|
||||
return arc.Array<float>(key, &p[0], def ? &(*def)[0] : nullptr, 3, true);
|
||||
}
|
||||
|
||||
inline FSerializer& Serialize(FSerializer& arc, const char* key, FVector2& p, FVector2* def)
|
||||
{
|
||||
return arc.Array<float>(key, &p[0], def ? &(*def)[0] : nullptr, 2, true);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline FSerializer &Serialize(FSerializer &arc, const char *key, TAngle<T> &p, TAngle<T> *def)
|
||||
{
|
||||
|
|
|
@ -175,7 +175,7 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
GLRenderer->Initialize(GetWidth(), GetHeight());
|
||||
static_cast<GLDataBuffer*>(mLights->GetBuffer())->BindBase();
|
||||
|
||||
mDebug = std::make_shared<FGLDebug>();
|
||||
mDebug = std::make_unique<FGLDebug>();
|
||||
mDebug->Update();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<void()> &afterBloomDrawEndScene2D) override;
|
||||
|
||||
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
||||
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
||||
std::unique_ptr<FGLDebug> mDebug; // Debug API
|
||||
|
||||
FTexture *WipeStartScreen() override;
|
||||
FTexture *WipeEndScreen() override;
|
||||
|
|
|
@ -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<void()> &afterBloomDrawEndScene2D) override;
|
||||
|
||||
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
||||
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
||||
|
||||
FTexture *WipeStartScreen() override;
|
||||
FTexture *WipeEndScreen() override;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,9 +64,8 @@ public:
|
|||
// Working buffer used by the tilted (sloped) span drawer
|
||||
const uint8_t *tiltlighting[MAXWIDTH];
|
||||
|
||||
std::shared_ptr<PolyTriangleThreadData> poly;
|
||||
std::shared_ptr<swrenderer::WallColumnDrawerArgs> columndrawer;
|
||||
|
||||
std::unique_ptr<PolyTriangleThreadData> poly;
|
||||
|
||||
size_t debug_draw_pos = 0;
|
||||
|
||||
// Checks if a line is rendered by this thread
|
||||
|
|
|
@ -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<FxVMFunctionCall *>(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;
|
||||
|
|
|
@ -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()); }
|
||||
|
|
|
@ -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<PField>(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<PSymbolType>(NAME_sByte, TypeSInt8));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Byte, TypeUInt8));
|
||||
|
@ -366,6 +390,8 @@ void PType::StaticInit()
|
|||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_State, TypeState));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Vector2, TypeVector2));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Vector3, TypeVector3));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_FVector2, TypeFVector2));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_FVector3, TypeFVector3));
|
||||
}
|
||||
|
||||
|
||||
|
@ -2321,6 +2347,29 @@ PStruct *NewStruct(FName name, PTypeBase *outer, bool native)
|
|||
PPrototype::PPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<decltype(t)>(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<FxVectorValue *>(x)->isConstVector(2))
|
||||
if ((type == TypeVector2 || type == TypeFVector2) && x->ExprType == EFX_VectorValue && static_cast<FxVectorValue *>(x)->isConstVector(2))
|
||||
{
|
||||
auto vx = static_cast<FxVectorValue *>(x);
|
||||
vmval[0] = static_cast<FxConstant *>(vx->xyz[0])->GetValue().GetFloat();
|
||||
vmval[1] = static_cast<FxConstant *>(vx->xyz[1])->GetValue().GetFloat();
|
||||
}
|
||||
else if (type == TypeVector3 && x->ExprType == EFX_VectorValue && static_cast<FxVectorValue *>(x)->isConstVector(3))
|
||||
else if ((type == TypeVector3 || type == TypeFVector3) && x->ExprType == EFX_VectorValue && static_cast<FxVectorValue *>(x)->isConstVector(3))
|
||||
{
|
||||
auto vx = static_cast<FxVectorValue *>(x);
|
||||
vmval[0] = static_cast<FxConstant *>(vx->xyz[0])->GetValue().GetFloat();
|
||||
|
|
|
@ -45,14 +45,58 @@
|
|||
TArray<FString> Includes;
|
||||
TArray<FScriptPosition> 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());
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue