mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-05-31 00:51:21 +00:00
- scriptified a_strifeitems.cpp and a_debris.cpp.
- Changed the glass shards so that they do not have to override FloorBounceMissile. It was the only place where this was virtually overridden and provided little usefulness. - made 'out' variables work. - fixed virtual call handling for HandlePickup.
This commit is contained in:
parent
55b549c0c6
commit
3af9232fca
29 changed files with 374 additions and 528 deletions
|
@ -5822,10 +5822,30 @@ bool FxLocalVariable::RequestAddress(FCompileContext &ctx, bool *writable)
|
|||
|
||||
ExpEmit FxLocalVariable::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
ExpEmit ret(Variable->RegNum + RegOffset, Variable->ValueType->GetRegType(), false, true);
|
||||
ret.RegCount = ValueType->GetRegCount();
|
||||
if (AddressRequested) ret.Target = true;
|
||||
return ret;
|
||||
// 'Out' variables are actually pointers but this fact must be hidden to the script.
|
||||
if (Variable->VarFlags & VARF_Out)
|
||||
{
|
||||
if (!AddressRequested)
|
||||
{
|
||||
ExpEmit reg(build, ValueType->GetRegType(), ValueType->GetRegCount());
|
||||
build->Emit(ValueType->GetLoadOp(), reg.RegNum, Variable->RegNum, build->GetConstantInt(RegOffset));
|
||||
return reg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RegOffset == 0) return ExpEmit(Variable->RegNum, REGT_POINTER, false, true);
|
||||
ExpEmit reg(build, REGT_POINTER);
|
||||
build->Emit(OP_ADDA_RK, reg.RegNum, Variable->RegNum, build->GetConstantInt(RegOffset));
|
||||
return reg;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExpEmit ret(Variable->RegNum + RegOffset, Variable->ValueType->GetRegType(), false, true);
|
||||
ret.RegCount = ValueType->GetRegCount();
|
||||
if (AddressRequested) ret.Target = true;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -7781,7 +7801,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
|
||||
FxExpression *x;
|
||||
if (!(flag & VARF_Ref))
|
||||
if (!(flag & (VARF_Ref|VARF_Out)))
|
||||
{
|
||||
x = new FxTypeCast(ArgList[i], type, false);
|
||||
x = x->Resolve(ctx);
|
||||
|
@ -7793,7 +7813,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (ArgList[i] != nullptr && ArgList[i]->ValueType != TypeNullPtr)
|
||||
{
|
||||
ArgList[i]->RequestAddress(ctx, &writable);
|
||||
ArgList[i]->ValueType = NewPointer(ArgList[i]->ValueType);
|
||||
if (flag & VARF_Ref) ArgList[i]->ValueType = NewPointer(ArgList[i]->ValueType);
|
||||
// For a reference argument the types must match 100%.
|
||||
if (type != ArgList[i]->ValueType)
|
||||
{
|
||||
|
@ -9917,10 +9937,15 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
if (Init == nullptr)
|
||||
{
|
||||
if (RegNum == -1) RegNum = build->Registers[ValueType->GetRegType()].Get(RegCount);
|
||||
if (RegNum == -1)
|
||||
{
|
||||
if (!(VarFlags & VARF_Out)) RegNum = build->Registers[ValueType->GetRegType()].Get(RegCount);
|
||||
else RegNum = build->Registers[REGT_POINTER].Get(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!(VarFlags & VARF_Out)); // 'out' variables should never be initialized, they can only exist as function parameters.
|
||||
ExpEmit emitval = Init->Emit(build);
|
||||
|
||||
int regtype = emitval.RegType;
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "p_terrain.h"
|
||||
#include "gstrings.h"
|
||||
#include "zstring.h"
|
||||
#include "d_event.h"
|
||||
|
||||
static TArray<FPropertyInfo*> properties;
|
||||
static TArray<AFuncDesc> AFTable;
|
||||
|
@ -743,6 +744,12 @@ void InitThingdef()
|
|||
playerf = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
|
||||
playerf = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
|
||||
playerf = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
|
||||
// Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag.
|
||||
// It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution'
|
||||
// is to create a static variable from it and reference that in the script. Yuck!!!
|
||||
|
|
|
@ -2169,17 +2169,16 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
{
|
||||
auto type = DetermineType(c->Type(), p, f->Name, p->Type, false, false);
|
||||
int flags = 0;
|
||||
if (p->Flags & ZCC_In) flags |= VARF_In;
|
||||
if (p->Flags & ZCC_Out) flags |= VARF_Out;
|
||||
if ((type->IsA(RUNTIME_CLASS(PStruct))) || (flags & VARF_Out))
|
||||
if (type->IsA(RUNTIME_CLASS(PStruct)) && type != TypeVector2 && type != TypeVector3)
|
||||
{
|
||||
// 'out' parameters and all structs except vectors are passed by reference
|
||||
if ((flags & VARF_Out) || (type != TypeVector2 && type != TypeVector3))
|
||||
{
|
||||
type = NewPointer(type);
|
||||
flags |= VARF_Ref;
|
||||
}
|
||||
else if (type == TypeVector2)
|
||||
// Structs are being passed by pointer, but unless marked 'out' that pointer must be readonly.
|
||||
type = NewPointer(type /*, !(p->Flags & ZCC_Out)*/);
|
||||
flags |= VARF_Ref;
|
||||
}
|
||||
else if (type->GetRegType() != REGT_NIL)
|
||||
{
|
||||
if (p->Flags & ZCC_Out) flags |= VARF_Out;
|
||||
if (type == TypeVector2)
|
||||
{
|
||||
elementcount = 2;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue