mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-25 05:21:02 +00:00
- added per-channel access for color variables. However, since they are locally stored in registers, it required a minor bit of fudging for this case.
- make sure that a PFunction's implementation is always initialized before starting the code generator.
This commit is contained in:
parent
393bcf9e91
commit
de2eb18727
6 changed files with 48 additions and 1 deletions
|
@ -85,6 +85,7 @@ PStatePointer *TypeState;
|
||||||
PStateLabel *TypeStateLabel;
|
PStateLabel *TypeStateLabel;
|
||||||
PStruct *TypeVector2;
|
PStruct *TypeVector2;
|
||||||
PStruct *TypeVector3;
|
PStruct *TypeVector3;
|
||||||
|
PStruct *TypeColorStruct;
|
||||||
PPointer *TypeNullPtr;
|
PPointer *TypeNullPtr;
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
@ -578,6 +579,19 @@ void PType::StaticInit()
|
||||||
TypeTable.AddType(TypeStateLabel = new PStateLabel);
|
TypeTable.AddType(TypeStateLabel = new PStateLabel);
|
||||||
TypeTable.AddType(TypeNullPtr = new PPointer);
|
TypeTable.AddType(TypeNullPtr = new PPointer);
|
||||||
|
|
||||||
|
TypeColorStruct = new PStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value.
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
TypeColorStruct->AddField(NAME_a, TypeUInt8);
|
||||||
|
TypeColorStruct->AddField(NAME_r, TypeUInt8);
|
||||||
|
TypeColorStruct->AddField(NAME_g, TypeUInt8);
|
||||||
|
TypeColorStruct->AddField(NAME_b, TypeUInt8);
|
||||||
|
#else
|
||||||
|
TypeColorStruct->AddField(NAME_b, TypeUInt8);
|
||||||
|
TypeColorStruct->AddField(NAME_g, TypeUInt8);
|
||||||
|
TypeColorStruct->AddField(NAME_r, TypeUInt8);
|
||||||
|
TypeColorStruct->AddField(NAME_a, TypeUInt8);
|
||||||
|
#endif
|
||||||
|
|
||||||
TypeVector2 = new PStruct(NAME_Vector2, nullptr);
|
TypeVector2 = new PStruct(NAME_Vector2, nullptr);
|
||||||
TypeVector2->AddField(NAME_X, TypeFloat64);
|
TypeVector2->AddField(NAME_X, TypeFloat64);
|
||||||
TypeVector2->AddField(NAME_Y, TypeFloat64);
|
TypeVector2->AddField(NAME_Y, TypeFloat64);
|
||||||
|
|
|
@ -919,6 +919,7 @@ extern PSound *TypeSound;
|
||||||
extern PColor *TypeColor;
|
extern PColor *TypeColor;
|
||||||
extern PStruct *TypeVector2;
|
extern PStruct *TypeVector2;
|
||||||
extern PStruct *TypeVector3;
|
extern PStruct *TypeVector3;
|
||||||
|
extern PStruct *TypeColorStruct;
|
||||||
extern PStatePointer *TypeState;
|
extern PStatePointer *TypeState;
|
||||||
extern PStateLabel *TypeStateLabel;
|
extern PStateLabel *TypeStateLabel;
|
||||||
extern PPointer *TypeNullPtr;
|
extern PPointer *TypeNullPtr;
|
||||||
|
|
|
@ -750,3 +750,9 @@ xx(A_FirePlasma)
|
||||||
xx(A_FireBFG)
|
xx(A_FireBFG)
|
||||||
xx(A_FireOldBFG)
|
xx(A_FireOldBFG)
|
||||||
xx(A_FireRailgun)
|
xx(A_FireRailgun)
|
||||||
|
|
||||||
|
// color channels
|
||||||
|
xx(a)
|
||||||
|
xx(r)
|
||||||
|
xx(g)
|
||||||
|
xx(b)
|
||||||
|
|
|
@ -5652,6 +5652,10 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
|
||||||
|
|
||||||
SAFE_RESOLVE(Object, ctx);
|
SAFE_RESOLVE(Object, ctx);
|
||||||
|
|
||||||
|
// allow accessing the color chanels by mapping the type to a matching struct which defines them.
|
||||||
|
if (Object->ValueType == TypeColor)
|
||||||
|
Object->ValueType = TypeColorStruct;
|
||||||
|
|
||||||
if (Object->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
|
if (Object->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
|
||||||
{
|
{
|
||||||
auto ptype = static_cast<PPointer *>(Object->ValueType)->PointedType;
|
auto ptype = static_cast<PPointer *>(Object->ValueType)->PointedType;
|
||||||
|
@ -6305,6 +6309,26 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
||||||
delete this;
|
delete this;
|
||||||
return locvar;
|
return locvar;
|
||||||
}
|
}
|
||||||
|
else if (classx->ExprType == EFX_LocalVariable && classx->ValueType == TypeColorStruct)
|
||||||
|
{
|
||||||
|
// This needs special treatment because it'd require accessing the register via address.
|
||||||
|
// Fortunately this is the only place where this kind of access is ever needed so an explicit handling is acceptable.
|
||||||
|
int bits;
|
||||||
|
switch (membervar->SymbolName.GetIndex())
|
||||||
|
{
|
||||||
|
case NAME_a: bits = 24; break;
|
||||||
|
case NAME_r: bits = 16; break;
|
||||||
|
case NAME_g: bits = 8; break;
|
||||||
|
case NAME_b: default: bits = 0; break;
|
||||||
|
}
|
||||||
|
classx->ValueType = TypeColor; // need to set it back.
|
||||||
|
FxExpression *x = classx;
|
||||||
|
if (bits > 0) x = new FxShift(TK_URShift, x, new FxConstant(bits, ScriptPosition));
|
||||||
|
x = new FxBitOp('&', x, new FxConstant(255, ScriptPosition));
|
||||||
|
classx = nullptr;
|
||||||
|
delete this;
|
||||||
|
return x->Resolve(ctx);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(classx->RequestAddress(ctx, &AddressWritable)))
|
if (!(classx->RequestAddress(ctx, &AddressWritable)))
|
||||||
|
|
|
@ -785,6 +785,8 @@ VMFunction *FFunctionBuildList::AddFunction(PFunction *functype, FxExpression *c
|
||||||
it.StateIndex = stateindex;
|
it.StateIndex = stateindex;
|
||||||
it.StateCount = statecount;
|
it.StateCount = statecount;
|
||||||
it.Lump = lumpnum;
|
it.Lump = lumpnum;
|
||||||
|
assert(it.Func->Variants.Size() == 1);
|
||||||
|
it.Func->Variants[0].Implementation = it.Function;
|
||||||
|
|
||||||
// set prototype for named functions.
|
// set prototype for named functions.
|
||||||
if (it.Func->SymbolName != NAME_None)
|
if (it.Func->SymbolName != NAME_None)
|
||||||
|
|
|
@ -2272,7 +2272,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
auto code = ConvertAST(c->Type(), f->Body);
|
auto code = ConvertAST(c->Type(), f->Body);
|
||||||
if (code != nullptr)
|
if (code != nullptr)
|
||||||
{
|
{
|
||||||
sym->Variants[0].Implementation = FunctionBuildList.AddFunction(sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
|
FunctionBuildList.AddFunction(sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue