mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +00:00
- implemented dot and cross products (not that I'd ever expect these to become useful in a game like Doom...)
This commit is contained in:
parent
594a0c2008
commit
b5222f08e8
3 changed files with 95 additions and 5 deletions
|
@ -3438,6 +3438,76 @@ ExpEmit FxBinaryLogical::Emit(VMFunctionBuilder *build)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
FxDotCross::FxDotCross(int o, FxExpression *l, FxExpression *r)
|
||||||
|
: FxExpression(EFX_DotCross, l->ScriptPosition)
|
||||||
|
{
|
||||||
|
Operator = o;
|
||||||
|
left = l;
|
||||||
|
right = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FxDotCross::~FxDotCross()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(left);
|
||||||
|
SAFE_DELETE(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FxExpression *FxDotCross::Resolve(FCompileContext& ctx)
|
||||||
|
{
|
||||||
|
CHECKRESOLVED();
|
||||||
|
RESOLVE(left, ctx);
|
||||||
|
RESOLVE(right, ctx);
|
||||||
|
ABORT(right && left);
|
||||||
|
|
||||||
|
if (!left->IsVector() || left->ValueType != right->ValueType || (Operator == TK_Cross && left->ValueType != TypeVector3))
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "Incompatible operants for %sproduct", Operator == TK_Cross ? "cross-" : "dot-");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
ValueType = Operator == TK_Cross ? (PType*)TypeVector3 : TypeFloat64;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
ExpEmit FxDotCross::Emit(VMFunctionBuilder *build)
|
||||||
|
{
|
||||||
|
// This is not the "right" way to do these, but it works for now.
|
||||||
|
// (Problem: No information sharing is done between nodes to reduce the
|
||||||
|
// code size if you have something like a1 && a2 && a3 && ... && an.)
|
||||||
|
ExpEmit to(build, ValueType->GetRegType(), ValueType->GetRegCount());
|
||||||
|
ExpEmit op1 = left->Emit(build);
|
||||||
|
ExpEmit op2 = right->Emit(build);
|
||||||
|
int op = Operator == TK_Cross ? OP_CROSSV_RR : left->ValueType == TypeVector3 ? OP_DOTV3_RR : OP_DOTV2_RR;
|
||||||
|
build->Emit(op, to.RegNum, op1.RegNum, op2.RegNum);
|
||||||
|
op1.Free(build);
|
||||||
|
op2.Free(build);
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
FxConditional::FxConditional(FxExpression *c, FxExpression *t, FxExpression *f)
|
FxConditional::FxConditional(FxExpression *c, FxExpression *t, FxExpression *f)
|
||||||
: FxExpression(EFX_Conditional, c->ScriptPosition)
|
: FxExpression(EFX_Conditional, c->ScriptPosition)
|
||||||
{
|
{
|
||||||
|
|
|
@ -228,6 +228,7 @@ enum EFxType
|
||||||
EFX_AssignSelf,
|
EFX_AssignSelf,
|
||||||
EFX_Binary, // one token fits all, the operator is enough to distinguish them.
|
EFX_Binary, // one token fits all, the operator is enough to distinguish them.
|
||||||
EFX_BinaryLogical,
|
EFX_BinaryLogical,
|
||||||
|
EFX_DotCross,
|
||||||
EFX_Conditional,
|
EFX_Conditional,
|
||||||
EFX_Abs,
|
EFX_Abs,
|
||||||
EFX_ATan2,
|
EFX_ATan2,
|
||||||
|
@ -905,6 +906,26 @@ public:
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FxBinaryLogical
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class FxDotCross : public FxExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int Operator;
|
||||||
|
FxExpression *left;
|
||||||
|
FxExpression *right;
|
||||||
|
|
||||||
|
FxDotCross(int, FxExpression*, FxExpression*);
|
||||||
|
~FxDotCross();
|
||||||
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
|
||||||
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FxConditional
|
// FxConditional
|
||||||
|
|
|
@ -2680,15 +2680,14 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
||||||
case PEX_ArrayAccess:
|
case PEX_ArrayAccess:
|
||||||
return new FxArrayElement(left, right);
|
return new FxArrayElement(left, right);
|
||||||
|
|
||||||
|
case PEX_CrossProduct:
|
||||||
|
case PEX_DotProduct:
|
||||||
|
return new FxDotCross(tok, left, right);
|
||||||
|
|
||||||
// todo: These do not have representations in DECORATE and no implementation exists yet.
|
// todo: These do not have representations in DECORATE and no implementation exists yet.
|
||||||
case PEX_Concat:
|
case PEX_Concat:
|
||||||
case PEX_Is:
|
case PEX_Is:
|
||||||
|
|
||||||
// vector operations will be done later.
|
|
||||||
case PEX_CrossProduct:
|
|
||||||
case PEX_DotProduct:
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
I_Error("Binary operator %d not implemented yet", op);
|
I_Error("Binary operator %d not implemented yet", op);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue