Merge remote-tracking branch 'gz/master' into gz_master2
This commit is contained in:
commit
723f9770a4
211 changed files with 10321 additions and 9256 deletions
|
|
@ -1562,7 +1562,7 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
|||
SAFE_RESOLVE(basex, ctx);
|
||||
|
||||
// first deal with the simple types
|
||||
if (ValueType == TypeError || basex->ValueType == TypeError)
|
||||
if (ValueType == TypeError || basex->ValueType == TypeError || basex->ValueType == nullptr)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Trying to cast to invalid type.");
|
||||
delete this;
|
||||
|
|
@ -6142,10 +6142,81 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
|
|||
|
||||
if (Object->ExprType == EFX_Identifier)
|
||||
{
|
||||
auto id = static_cast<FxIdentifier *>(Object)->Identifier;
|
||||
// If the left side is a class name for a static member function call it needs to be resolved manually
|
||||
// because the resulting value type would cause problems in nearly every other place where identifiers are being used.
|
||||
ccls = FindStructType(static_cast<FxIdentifier *>(Object)->Identifier, ctx);
|
||||
if (ccls != nullptr) static_cast<FxIdentifier *>(Object)->noglobal = true;
|
||||
ccls = FindStructType(id, ctx);
|
||||
if (ccls != nullptr)
|
||||
{
|
||||
static_cast<FxIdentifier *>(Object)->noglobal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
PType *type;
|
||||
// Another special case to deal with here is constants assigned to non-struct types. The code below cannot deal with them so it needs to be done here explicitly.
|
||||
// Thanks to the messed up search logic of the type system, which doesn't allow any search by type name for the basic types at all,
|
||||
// we have to do this manually, though and check for all types that may have values attached explicitly.
|
||||
// (What's the point of attached fields to types if you cannot even search for the types...???)
|
||||
switch (id)
|
||||
{
|
||||
default:
|
||||
type = nullptr;
|
||||
break;
|
||||
|
||||
case NAME_Byte:
|
||||
case NAME_uint8:
|
||||
type = TypeUInt8;
|
||||
break;
|
||||
|
||||
case NAME_sByte:
|
||||
case NAME_int8:
|
||||
type = TypeSInt8;
|
||||
break;
|
||||
|
||||
case NAME_uShort:
|
||||
case NAME_uint16:
|
||||
type = TypeUInt16;
|
||||
break;
|
||||
|
||||
case NAME_Short:
|
||||
case NAME_int16:
|
||||
type = TypeSInt16;
|
||||
break;
|
||||
|
||||
case NAME_Int:
|
||||
type = TypeSInt32;
|
||||
break;
|
||||
|
||||
case NAME_uInt:
|
||||
type = TypeUInt32;
|
||||
break;
|
||||
|
||||
case NAME_Float:
|
||||
type = TypeFloat32;
|
||||
break;
|
||||
|
||||
case NAME_Double:
|
||||
type = TypeFloat64;
|
||||
break;
|
||||
}
|
||||
if (type != nullptr)
|
||||
{
|
||||
auto sym = type->Symbols.FindSymbol(Identifier, true);
|
||||
if (sym != nullptr)
|
||||
{
|
||||
// non-struct symbols must be constant numbers and can only be defined internally.
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolConstNumeric)));
|
||||
auto sn = static_cast<PSymbolConstNumeric*>(sym);
|
||||
|
||||
VMValue vmv;
|
||||
if (sn->ValueType->IsKindOf(RUNTIME_CLASS(PInt))) vmv = sn->Value;
|
||||
else vmv = sn->Float;
|
||||
auto x = new FxConstant(sn->ValueType, vmv, ScriptPosition);
|
||||
delete this;
|
||||
return x->Resolve(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_RESOLVE(Object, ctx);
|
||||
|
|
@ -6420,7 +6491,7 @@ ExpEmit FxClassDefaults::Emit(VMFunctionBuilder *build)
|
|||
ExpEmit ob = obj->Emit(build);
|
||||
ob.Free(build);
|
||||
ExpEmit meta(build, REGT_POINTER);
|
||||
build->Emit(OP_META, meta.RegNum, ob.RegNum);
|
||||
build->Emit(OP_CLSS, meta.RegNum, ob.RegNum);
|
||||
build->Emit(OP_LOS, meta.RegNum, meta.RegNum, build->GetConstantInt(myoffsetof(PClass, Defaults)));
|
||||
return meta;
|
||||
|
||||
|
|
@ -6571,7 +6642,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
|
|||
|
||||
case CVAR_String:
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FStringCVar *>(CVar)->Value, ATAG_GENERIC));
|
||||
build->Emit(OP_LS, dest.RegNum, addr.RegNum, nul);
|
||||
build->Emit(OP_LCS, dest.RegNum, addr.RegNum, nul);
|
||||
break;
|
||||
|
||||
case CVAR_DummyBool:
|
||||
|
|
@ -9013,7 +9084,7 @@ ExpEmit FxGetClass::Emit(VMFunctionBuilder *build)
|
|||
ExpEmit op = Self->Emit(build);
|
||||
op.Free(build);
|
||||
ExpEmit to(build, REGT_POINTER);
|
||||
build->Emit(OP_META, to.RegNum, op.RegNum);
|
||||
build->Emit(OP_CLSS, to.RegNum, op.RegNum);
|
||||
return to;
|
||||
}
|
||||
|
||||
|
|
@ -9054,7 +9125,7 @@ ExpEmit FxGetParentClass::Emit(VMFunctionBuilder *build)
|
|||
if (Self->IsObject())
|
||||
{
|
||||
ExpEmit to(build, REGT_POINTER);
|
||||
build->Emit(OP_META, to.RegNum, op.RegNum);
|
||||
build->Emit(OP_CLSS, to.RegNum, op.RegNum);
|
||||
op = to;
|
||||
op.Free(build);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -846,6 +846,7 @@ void FFunctionBuildList::Build()
|
|||
{
|
||||
int errorcount = 0;
|
||||
int codesize = 0;
|
||||
int datasize = 0;
|
||||
FILE *dump = nullptr;
|
||||
|
||||
if (Args->CheckParm("-dumpdisasm")) dump = fopen("disasm.txt", "w");
|
||||
|
|
@ -927,6 +928,8 @@ void FFunctionBuildList::Build()
|
|||
{
|
||||
DumpFunction(dump, sfunc, item.PrintableName.GetChars(), (int)item.PrintableName.Len());
|
||||
codesize += sfunc->CodeSize;
|
||||
datasize += sfunc->LineInfoCount * sizeof(FStatementInfo) + sfunc->ExtraSpace + sfunc->NumKonstD * sizeof(int) +
|
||||
sfunc->NumKonstA * sizeof(void*) + sfunc->NumKonstF * sizeof(double) + sfunc->NumKonstS * sizeof(FString);
|
||||
}
|
||||
sfunc->Unsafe = ctx.Unsafe;
|
||||
}
|
||||
|
|
@ -944,10 +947,11 @@ void FFunctionBuildList::Build()
|
|||
}
|
||||
if (dump != nullptr)
|
||||
{
|
||||
fprintf(dump, "\n*************************************************************************\n%i code bytes\n", codesize * 4);
|
||||
fprintf(dump, "\n*************************************************************************\n%i code bytes\n%i data bytes", codesize * 4, datasize);
|
||||
fclose(dump);
|
||||
}
|
||||
FScriptPosition::StrictErrors = false;
|
||||
mItems.Clear();
|
||||
mItems.ShrinkToFit();
|
||||
FxAlloc.FreeAllBlocks();
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def, PNamespace *ns)
|
|||
{
|
||||
extra.DeathHeight = ((AActor*)(type->Defaults))->Height;
|
||||
}
|
||||
type->DeathHeight = extra.DeathHeight;
|
||||
((AActor*)(type->Defaults))->FloatVar("DeathHeight") = extra.DeathHeight;
|
||||
}
|
||||
bag.statedef.SetStateLabel("Death", &type->OwnedStates[extra.DeathStart]);
|
||||
}
|
||||
|
|
@ -262,7 +262,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def, PNamespace *ns)
|
|||
}
|
||||
|
||||
if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->Height;
|
||||
type->BurnHeight = extra.BurnHeight;
|
||||
((AActor*)(type->Defaults))->FloatVar("BurnHeight") = extra.BurnHeight;
|
||||
|
||||
bag.statedef.SetStateLabel("Burn", &type->OwnedStates[extra.FireDeathStart]);
|
||||
}
|
||||
|
|
@ -445,18 +445,18 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
|||
else if (def == DEF_Projectile && sc.Compare ("ExplosionRadius"))
|
||||
{
|
||||
sc.MustGetNumber ();
|
||||
bag.Info->ExplosionRadius = sc.Number;
|
||||
defaults->IntVar(NAME_ExplosionRadius) = sc.Number;
|
||||
extra.bExplosive = true;
|
||||
}
|
||||
else if (def == DEF_Projectile && sc.Compare ("ExplosionDamage"))
|
||||
{
|
||||
sc.MustGetNumber ();
|
||||
bag.Info->ExplosionDamage = sc.Number;
|
||||
defaults->IntVar(NAME_ExplosionDamage) = sc.Number;
|
||||
extra.bExplosive = true;
|
||||
}
|
||||
else if (def == DEF_Projectile && sc.Compare ("DoNotHurtShooter"))
|
||||
{
|
||||
bag.Info->DontHurtShooter = true;
|
||||
defaults->BoolVar(NAME_DontHurtShooter) = true;
|
||||
}
|
||||
else if (def == DEF_Projectile && sc.Compare ("Damage"))
|
||||
{
|
||||
|
|
@ -483,7 +483,7 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
|||
else if (sc.Compare ("Mass"))
|
||||
{
|
||||
sc.MustGetFloat ();
|
||||
defaults->Mass = SDWORD(sc.Float);
|
||||
defaults->Mass = int32_t(sc.Float);
|
||||
}
|
||||
else if (sc.Compare ("Translation1"))
|
||||
{
|
||||
|
|
@ -541,11 +541,11 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
|||
else if (def == DEF_Pickup && sc.Compare ("PickupMessage"))
|
||||
{
|
||||
sc.MustGetString ();
|
||||
bag.Info->PickupMsg = sc.String;
|
||||
inv->StringVar(NAME_PickupMsg) = sc.String;
|
||||
}
|
||||
else if (def == DEF_Pickup && sc.Compare ("Respawns"))
|
||||
{
|
||||
inv->BoolVar("Respawnable") = true;
|
||||
inv->BoolVar(NAME_Respawnable) = true;
|
||||
}
|
||||
else if (def == DEF_BreakableDecoration && sc.Compare ("SolidOnDeath"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
#include "backend/codegen.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_video.h"
|
||||
#include "version.h"
|
||||
#include "v_text.h"
|
||||
#include "m_argv.h"
|
||||
|
||||
|
|
@ -828,7 +827,7 @@ static void DispatchScriptProperty(FScanner &sc, PProperty *prop, AActor *defaul
|
|||
if (i > 0) sc.MustGetStringName(",");
|
||||
if (f->Flags & VARF_Meta)
|
||||
{
|
||||
addr = ((char*)bag.Info) + f->Offset;
|
||||
addr = ((char*)bag.Info->Meta) + f->Offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -868,7 +867,7 @@ static void DispatchScriptProperty(FScanner &sc, PProperty *prop, AActor *defaul
|
|||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PString)))
|
||||
{
|
||||
sc.MustGetString();
|
||||
*(FString*)addr = sc.String;
|
||||
*(FString*)addr = strbin1(sc.String);
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@
|
|||
#include "i_system.h"
|
||||
#include "colormatcher.h"
|
||||
#include "backend/codegen.h"
|
||||
#include "version.h"
|
||||
#include "templates.h"
|
||||
#include "backend/vmbuilder.h"
|
||||
|
||||
|
|
@ -316,9 +315,7 @@ do_stop:
|
|||
do
|
||||
{
|
||||
sc.MustGetString();
|
||||
#ifdef DYNLIGHT
|
||||
AddStateLight(&state, sc.String);
|
||||
#endif
|
||||
AddStateLight(&state, sc.String);
|
||||
}
|
||||
while (sc.CheckString(","));
|
||||
sc.MustGetStringName(")");
|
||||
|
|
|
|||
|
|
@ -57,10 +57,16 @@
|
|||
#include "v_video.h"
|
||||
#include "c_bind.h"
|
||||
#include "menu/menu.h"
|
||||
#include "teaminfo.h"
|
||||
#include "r_data/sprites.h"
|
||||
#include "serializer.h"
|
||||
|
||||
static TArray<FPropertyInfo*> properties;
|
||||
static TArray<AFuncDesc> AFTable;
|
||||
static TArray<FieldDesc> FieldTable;
|
||||
extern int BackbuttonTime;
|
||||
extern float BackbuttonAlpha;
|
||||
static AWeapon *wpnochg;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
@ -311,6 +317,9 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(MF7, SPRITEANGLE, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, SMASHABLE, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, NOSHIELDREFLECT, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, FORCEZERORADIUSDMG, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, NOINFIGHTSPECIES, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, FORCEINFIGHTING, AActor, flags7),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
|
@ -331,6 +340,7 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(RF, XFLIP, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, YFLIP, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, INTERPOLATEANGLES, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, DONTINTERPOLATE, AActor, renderflags),
|
||||
|
||||
// Bounce flags
|
||||
DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),
|
||||
|
|
@ -347,6 +357,7 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG2(BOUNCE_MBF, MBFBOUNCER, AActor, BounceFlags),
|
||||
DEFINE_FLAG2(BOUNCE_AutoOffFloorOnly, BOUNCEAUTOOFFFLOORONLY, AActor, BounceFlags),
|
||||
DEFINE_FLAG2(BOUNCE_UseBounceState, USEBOUNCESTATE, AActor, BounceFlags),
|
||||
DEFINE_FLAG2(BOUNCE_NotOnShootables, DONTBOUNCEONSHOOTABLES, AActor, BounceFlags),
|
||||
};
|
||||
|
||||
// These won't be accessible through bitfield variables
|
||||
|
|
@ -420,6 +431,8 @@ static FFlagDef InventoryFlagDefs[] =
|
|||
DEFINE_FLAG(IF, TRANSFER, AInventory, ItemFlags),
|
||||
DEFINE_FLAG(IF, NOTELEPORTFREEZE, AInventory, ItemFlags),
|
||||
DEFINE_FLAG(IF, NOSCREENBLINK, AInventory, ItemFlags),
|
||||
DEFINE_FLAG(IF, ISARMOR, AInventory, ItemFlags),
|
||||
DEFINE_FLAG(IF, ISHEALTH, AInventory, ItemFlags),
|
||||
|
||||
DEFINE_DUMMY_FLAG(FORCERESPAWNINSURVIVAL, false),
|
||||
|
||||
|
|
@ -729,7 +742,7 @@ static int fieldcmp(const void * a, const void * b)
|
|||
void InitThingdef()
|
||||
{
|
||||
// Create all global variables here because this cannot be done on the script side and really isn't worth adding support for.
|
||||
// Also create all special fields here that cannot be declared by script syntax.
|
||||
// Also create all special fields here that cannot be declared by script syntax plus the pointer serializers. Doing all these with class overrides would be a bit messy.
|
||||
|
||||
auto secplanestruct = NewNativeStruct("Secplane", nullptr);
|
||||
secplanestruct->Size = sizeof(secplane_t);
|
||||
|
|
@ -738,18 +751,62 @@ void InitThingdef()
|
|||
auto sectorstruct = NewNativeStruct("Sector", nullptr);
|
||||
sectorstruct->Size = sizeof(sector_t);
|
||||
sectorstruct->Align = alignof(sector_t);
|
||||
NewPointer(sectorstruct, false)->InstallHandlers(
|
||||
[](FSerializer &ar, const char *key, const void *addr)
|
||||
{
|
||||
ar(key, *(sector_t **)addr);
|
||||
},
|
||||
[](FSerializer &ar, const char *key, void *addr)
|
||||
{
|
||||
Serialize<sector_t>(ar, key, *(sector_t **)addr, nullptr);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
auto linestruct = NewNativeStruct("Line", nullptr);
|
||||
linestruct->Size = sizeof(line_t);
|
||||
linestruct->Align = alignof(line_t);
|
||||
NewPointer(linestruct, false)->InstallHandlers(
|
||||
[](FSerializer &ar, const char *key, const void *addr)
|
||||
{
|
||||
ar(key, *(line_t **)addr);
|
||||
},
|
||||
[](FSerializer &ar, const char *key, void *addr)
|
||||
{
|
||||
Serialize<line_t>(ar, key, *(line_t **)addr, nullptr);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
auto sidestruct = NewNativeStruct("Side", nullptr);
|
||||
sidestruct->Size = sizeof(side_t);
|
||||
sidestruct->Align = alignof(side_t);
|
||||
NewPointer(sidestruct, false)->InstallHandlers(
|
||||
[](FSerializer &ar, const char *key, const void *addr)
|
||||
{
|
||||
ar(key, *(side_t **)addr);
|
||||
},
|
||||
[](FSerializer &ar, const char *key, void *addr)
|
||||
{
|
||||
Serialize<side_t>(ar, key, *(side_t **)addr, nullptr);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
auto vertstruct = NewNativeStruct("Vertex", nullptr);
|
||||
vertstruct->Size = sizeof(vertex_t);
|
||||
vertstruct->Align = alignof(vertex_t);
|
||||
NewPointer(vertstruct, false)->InstallHandlers(
|
||||
[](FSerializer &ar, const char *key, const void *addr)
|
||||
{
|
||||
ar(key, *(vertex_t **)addr);
|
||||
},
|
||||
[](FSerializer &ar, const char *key, void *addr)
|
||||
{
|
||||
Serialize<vertex_t>(ar, key, *(vertex_t **)addr, nullptr);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
auto sectorportalstruct = NewNativeStruct("SectorPortal", nullptr);
|
||||
sectorportalstruct->Size = sizeof(FSectorPortal);
|
||||
|
|
@ -759,6 +816,44 @@ void InitThingdef()
|
|||
playerclassstruct->Size = sizeof(FPlayerClass);
|
||||
playerclassstruct->Align = alignof(FPlayerClass);
|
||||
|
||||
auto playerskinstruct = NewNativeStruct("PlayerSkin", nullptr);
|
||||
playerskinstruct->Size = sizeof(FPlayerSkin);
|
||||
playerskinstruct->Align = alignof(FPlayerSkin);
|
||||
|
||||
auto teamstruct = NewNativeStruct("Team", nullptr);
|
||||
teamstruct->Size = sizeof(FTeam);
|
||||
teamstruct->Align = alignof(FTeam);
|
||||
|
||||
PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr);
|
||||
pstruct->Size = sizeof(player_t);
|
||||
pstruct->Align = alignof(player_t);
|
||||
NewPointer(pstruct, false)->InstallHandlers(
|
||||
[](FSerializer &ar, const char *key, const void *addr)
|
||||
{
|
||||
ar(key, *(player_t **)addr);
|
||||
},
|
||||
[](FSerializer &ar, const char *key, void *addr)
|
||||
{
|
||||
Serialize<player_t>(ar, key, *(player_t **)addr, nullptr);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
auto fontstruct = NewNativeStruct("FFont", nullptr);
|
||||
fontstruct->Size = sizeof(FFont);
|
||||
fontstruct->Align = alignof(FFont);
|
||||
NewPointer(fontstruct, false)->InstallHandlers(
|
||||
[](FSerializer &ar, const char *key, const void *addr)
|
||||
{
|
||||
ar(key, *(FFont **)addr);
|
||||
},
|
||||
[](FSerializer &ar, const char *key, void *addr)
|
||||
{
|
||||
Serialize<FFont>(ar, key, *(FFont **)addr, nullptr);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
// set up the lines array in the sector struct. This is a bit messy because the type system is not prepared to handle a pointer to an array of pointers to a native struct even remotely well...
|
||||
// As a result, the size has to be set to something large and arbritrary because it can change between maps. This will need some serious improvement when things get cleaned up.
|
||||
sectorstruct->AddNativeField("lines", NewPointer(NewResizableArray(NewPointer(linestruct, false)), false), myoffsetof(sector_t, Lines), VARF_Native);
|
||||
|
|
@ -798,6 +893,14 @@ void InitThingdef()
|
|||
PField *plrclsf = new PField("PlayerClasses", plrcls, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&PlayerClasses);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(plrclsf);
|
||||
|
||||
auto plrskn = NewPointer(NewResizableArray(playerskinstruct), false);
|
||||
PField *plrsknf = new PField("PlayerSkins", plrskn, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Skins);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(plrsknf);
|
||||
|
||||
auto teamst = NewPointer(NewResizableArray(teamstruct), false);
|
||||
PField *teamf = new PField("Teams", teamst, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Teams);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(teamf);
|
||||
|
||||
auto bindcls = NewNativeStruct("KeyBindings", nullptr);
|
||||
PField *binding = new PField("Bindings", bindcls, VARF_Native | VARF_Static, (intptr_t)&Bindings);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(binding);
|
||||
|
|
@ -815,9 +918,6 @@ void InitThingdef()
|
|||
Namespaces.GlobalNamespace->Symbols.AddSymbol(gi);
|
||||
|
||||
// set up a variable for the global players array.
|
||||
PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr);
|
||||
pstruct->Size = sizeof(player_t);
|
||||
pstruct->Align = alignof(player_t);
|
||||
PArray *parray = NewArray(pstruct, MAXPLAYERS);
|
||||
PField *fieldptr = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
|
@ -829,7 +929,10 @@ void InitThingdef()
|
|||
fieldptr = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
fieldptr = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction);
|
||||
fieldptr = new PField("gameaction", TypeUInt32, VARF_Native | VARF_Static, (intptr_t)&gameaction);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
fieldptr = new PField("gamestate", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gamestate);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
fieldptr = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum);
|
||||
|
|
@ -888,11 +991,23 @@ void InitThingdef()
|
|||
fieldptr = new PField("OptionMenuSettings", NewStruct("FOptionMenuSettings", nullptr), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&OptionSettings);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
|
||||
fieldptr = new PField("gametic", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gametic);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
fieldptr = new PField("demoplayback", TypeBool, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&demoplayback);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
fieldptr = new PField("BackbuttonTime", TypeSInt32, VARF_Native | VARF_Static, (intptr_t)&BackbuttonTime);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
fieldptr = new PField("BackbuttonAlpha", TypeFloat32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&BackbuttonAlpha);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
|
||||
// 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!!!
|
||||
static AWeapon *wpnochg = WP_NOCHANGE;
|
||||
wpnochg = WP_NOCHANGE;
|
||||
fieldptr = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
|
|
@ -1195,10 +1310,20 @@ DEFINE_ACTION_FUNCTION(FStringStruct, Mid)
|
|||
ACTION_RETURN_STRING(s);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Len)
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Left)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||
ACTION_RETURN_INT((int)self->Len());
|
||||
PARAM_UINT(len);
|
||||
FString s = self->Left(len);
|
||||
ACTION_RETURN_STRING(s);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Truncate)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||
PARAM_UINT(len);
|
||||
self->Truncate(len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CharAt and CharCodeAt is how JS does it, and JS is similar here in that it doesn't have char type as int.
|
||||
|
|
@ -1221,3 +1346,10 @@ DEFINE_ACTION_FUNCTION(FStringStruct, CharCodeAt)
|
|||
ACTION_RETURN_INT(0);
|
||||
ACTION_RETURN_INT((*self)[pos]);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Filter)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||
ACTION_RETURN_STRING(strbin1(*self));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -592,24 +592,13 @@ DEFINE_PROPERTY(health, I, Actor)
|
|||
defaults->health=id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(gibhealth, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->GibHealth = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(woundhealth, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->WoundHealth = id;
|
||||
defaults->WoundHealth = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -888,16 +877,6 @@ DEFINE_PROPERTY(activesound, S, Actor)
|
|||
defaults->ActiveSound = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(howlsound, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->HowlSound = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
@ -981,75 +960,6 @@ DEFINE_PROPERTY(alpha, F, Actor)
|
|||
defaults->Alpha = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(obituary, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->Obituary = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(hitobituary, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->HitObituary = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(donthurtshooter, 0, Actor)
|
||||
{
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->DontHurtShooter = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(explosionradius, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->ExplosionRadius = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(explosiondamage, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->ExplosionDamage = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(deathheight, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(h, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->DeathHeight = MAX(0., h);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(burnheight, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(h, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->BurnHeight = MAX(0., h);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
@ -1068,16 +978,6 @@ DEFINE_PROPERTY(meleethreshold, F, Actor)
|
|||
defaults->meleethreshold = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(meleedamage, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->MeleeDamage = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
@ -1087,36 +987,6 @@ DEFINE_PROPERTY(meleerange, F, Actor)
|
|||
defaults->meleerange = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(meleesound, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->MeleeSound = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(missiletype, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->MissileName = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(missileheight, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(id, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->MissileHeight = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
@ -1183,13 +1053,11 @@ DEFINE_PROPERTY(bloodcolor, C, Actor)
|
|||
{
|
||||
PROP_COLOR_PARM(color, 0);
|
||||
|
||||
PalEntry pe = color;
|
||||
pe.a = CreateBloodTranslation(pe);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->BloodColor = pe;
|
||||
defaults->BloodColor = color;
|
||||
defaults->BloodColor.a = 255; // a should not be 0.
|
||||
defaults->BloodTranslation = TRANSLATION(TRANSLATION_Blood, CreateBloodTranslation(color));
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
@ -1199,26 +1067,23 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor)
|
|||
PROP_STRING_PARM(str1, 1)
|
||||
PROP_STRING_PARM(str2, 2)
|
||||
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
PClassActor *ainfo = static_cast<PClassActor *>(info);
|
||||
|
||||
FName blood = str;
|
||||
// normal blood
|
||||
ainfo->BloodType = blood;
|
||||
defaults->NameVar("BloodType") = blood;
|
||||
|
||||
if (PROP_PARM_COUNT > 1)
|
||||
{
|
||||
blood = str1;
|
||||
}
|
||||
// blood splatter
|
||||
ainfo->BloodType2 = blood;
|
||||
defaults->NameVar("BloodType2") = blood;
|
||||
|
||||
if (PROP_PARM_COUNT > 2)
|
||||
{
|
||||
blood = str2;
|
||||
}
|
||||
// axe blood
|
||||
ainfo->BloodType3 = blood;
|
||||
defaults->NameVar("BloodType3") = blood;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -1413,21 +1278,28 @@ DEFINE_PROPERTY(poisondamagetype, S, Actor)
|
|||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(fastspeed, F, Actor)
|
||||
DEFINE_PROPERTY(radiusdamagefactor, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(i, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->FastSpeed = i;
|
||||
defaults->RadiusDamageFactor = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(radiusdamagefactor, F, Actor)
|
||||
DEFINE_PROPERTY(selfdamagefactor, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(i, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->RDFactor = i;
|
||||
defaults->SelfDamageFactor = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(stealthalpha, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(i, 0);
|
||||
defaults->StealthAlpha = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -1436,8 +1308,7 @@ DEFINE_PROPERTY(radiusdamagefactor, F, Actor)
|
|||
DEFINE_PROPERTY(cameraheight, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(i, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->CameraHeight = i;
|
||||
defaults->CameraHeight = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -1811,16 +1682,6 @@ DEFINE_CLASS_PROPERTY(pickupflash, S, Inventory)
|
|||
defaults->PickupFlash = FindClassTentative(str, RUNTIME_CLASS(AActor));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(pickupmessage, T, Inventory)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->PickupMsg = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
@ -1855,15 +1716,6 @@ DEFINE_CLASS_PROPERTY(usesound, S, Inventory)
|
|||
defaults->UseSound = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(givequest, I, Inventory)
|
||||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
defaults->GiveQuest = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
@ -2698,24 +2550,6 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, startitem, S_i, PlayerPawn)
|
|||
bag.DropItemList = di;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY_PREFIX(player, invulnerabilitymode, S, PlayerPawn)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->InvulMode = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY_PREFIX(player, healradiustype, S, PlayerPawn)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->HealingRadiusType = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
// these are used in vmexec.h
|
||||
void FScopeBarrier_ValidateNew(PClass* cls, PFunction* callingfunc);
|
||||
void FScopeBarrier_ValidateCall(PFunction* calledfunc, PFunction* callingfunc, PClass* selftype);
|
||||
class DObject;
|
||||
|
||||
extern FMemArena ClassDataAllocator;
|
||||
|
||||
|
|
@ -1035,6 +1036,7 @@ void NullParam(const char *varname);
|
|||
#define PARAM_STATE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, self->GetClass());
|
||||
#define PARAM_STATE_ACTION_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, stateowner->GetClass());
|
||||
#define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)param[p].a;
|
||||
#define PARAM_POINTERTYPE_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type x = (type )param[p].a;
|
||||
#define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type)));
|
||||
#define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base)));
|
||||
#define PARAM_POINTER_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x);
|
||||
|
|
@ -1079,6 +1081,7 @@ void NullParam(const char *varname);
|
|||
#define PARAM_STATE(x) ++paramnum; PARAM_STATE_AT(paramnum,x)
|
||||
#define PARAM_STATE_ACTION(x) ++paramnum; PARAM_STATE_ACTION_AT(paramnum,x)
|
||||
#define PARAM_POINTER(x,type) ++paramnum; PARAM_POINTER_AT(paramnum,x,type)
|
||||
#define PARAM_POINTERTYPE(x,type) ++paramnum; PARAM_POINTERTYPE_AT(paramnum,x,type)
|
||||
#define PARAM_OBJECT(x,type) ++paramnum; PARAM_OBJECT_AT(paramnum,x,type)
|
||||
#define PARAM_CLASS(x,base) ++paramnum; PARAM_CLASS_AT(paramnum,x,base)
|
||||
#define PARAM_POINTER_NOT_NULL(x,type) ++paramnum; PARAM_POINTER_NOT_NULL_AT(paramnum,x,type)
|
||||
|
|
|
|||
|
|
@ -109,12 +109,18 @@ begin:
|
|||
reg.atag[a] = ATAG_GENERIC; // using ATAG_FRAMEPOINTER will cause endless asserts.
|
||||
NEXTOP;
|
||||
|
||||
OP(META):
|
||||
OP(CLSS):
|
||||
ASSERTA(a); ASSERTO(B);
|
||||
reg.a[a] = ((DObject*)reg.a[B])->GetClass(); // I wish this could be done without a special opcode but there's really no good way to guarantee initialization of the Class pointer...
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
|
||||
OP(META):
|
||||
ASSERTA(a); ASSERTO(B);
|
||||
reg.a[a] = ((DObject*)reg.a[B])->GetClass()->Meta; // I wish this could be done without a special opcode but there's really no good way to guarantee initialization of the Class pointer...
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
|
||||
OP(LB):
|
||||
ASSERTD(a); ASSERTA(B); ASSERTKD(C);
|
||||
GETADDR(PB,KC,X_READ_NIL);
|
||||
|
|
@ -197,6 +203,16 @@ begin:
|
|||
GETADDR(PB,RC,X_READ_NIL);
|
||||
reg.s[a] = *(FString *)ptr;
|
||||
NEXTOP;
|
||||
OP(LCS):
|
||||
ASSERTS(a); ASSERTA(B); ASSERTKD(C);
|
||||
GETADDR(PB,KC,X_READ_NIL);
|
||||
reg.s[a] = *(const char **)ptr;
|
||||
NEXTOP;
|
||||
OP(LCS_R):
|
||||
ASSERTS(a); ASSERTA(B); ASSERTD(C);
|
||||
GETADDR(PB,RC,X_READ_NIL);
|
||||
reg.s[a] = *(const char **)ptr;
|
||||
NEXTOP;
|
||||
OP(LO):
|
||||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||
GETADDR(PB,KC,X_READ_NIL);
|
||||
|
|
|
|||
|
|
@ -446,7 +446,8 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur
|
|||
{
|
||||
auto code = static_cast<VMScriptFunction *>(func)->Code;
|
||||
// handle empty functions consisting of a single return explicitly so that empty virtual callbacks do not need to set up an entire VM frame.
|
||||
if (code->word == 0x0080804e)
|
||||
// code cann be null here in case of some non-fatal DECORATE errors.
|
||||
if (code == nullptr || code->word == 0x0080804e)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ xx(LKF_R, lk, RFRII8, NOP, 0, 0), // load float constant indexed
|
|||
xx(LKS_R, lk, RSRII8, NOP, 0, 0), // load string constant indexed
|
||||
xx(LKP_R, lk, RPRII8, NOP, 0, 0), // load pointer constant indexed
|
||||
xx(LFP, lf, LFP, NOP, 0, 0), // load frame pointer
|
||||
xx(META, meta, RPRP, NOP, 0, 0), // load a class's meta class address
|
||||
xx(META, meta, RPRP, NOP, 0, 0), // load a class's meta data address
|
||||
xx(CLSS, clss, RPRP, NOP, 0, 0), // load a class's descriptor address
|
||||
|
||||
// Load from memory. rA = *(rB + rkC)
|
||||
xx(LB, lb, RIRPKI, LB_R, 4, REGT_INT), // load byte
|
||||
|
|
@ -52,6 +53,8 @@ xx(LV2, lv2, RVRPKI, LV2_R, 4, REGT_INT), // load vector2
|
|||
xx(LV2_R, lv2, RVRPRI, NOP, 0, 0),
|
||||
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(LBIT, lbit, RIRPI8, NOP, 0, 0), // rA = !!(*rB & C) -- *rB is a byte
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@
|
|||
#include "i_system.h"
|
||||
#include "gdtoa.h"
|
||||
#include "backend/vmbuilder.h"
|
||||
#include "version.h"
|
||||
|
||||
static int GetIntConst(FxExpression *ex, FCompileContext &ctx)
|
||||
{
|
||||
|
|
@ -1040,6 +1039,11 @@ void ZCCCompiler::CompileAllFields()
|
|||
type->Size = Classes[i]->Type()->ParentClass->Size;
|
||||
}
|
||||
}
|
||||
if (Classes[i]->Type()->ParentClass)
|
||||
type->MetaSize = Classes[i]->Type()->ParentClass->MetaSize;
|
||||
else
|
||||
type->MetaSize = 0;
|
||||
|
||||
if (CompileFields(type, Classes[i]->Fields, nullptr, &Classes[i]->TreeNodes, false, !!HasNativeChildren.CheckKey(type)))
|
||||
{
|
||||
// Remove from the list if all fields got compiled.
|
||||
|
|
@ -1130,11 +1134,6 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fiel
|
|||
if (field->Flags & ZCC_Meta)
|
||||
{
|
||||
varflags |= VARF_Meta | VARF_Static | VARF_ReadOnly; // metadata implies readonly
|
||||
if (!(field->Flags & ZCC_Native))
|
||||
{
|
||||
// Non-native meta data is not implemented yet and requires some groundwork in the class copy code.
|
||||
Error(field, "Metadata member %s must be native", FName(field->Names->Name).GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
if (field->Type->ArraySize != nullptr)
|
||||
|
|
@ -1155,22 +1154,28 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fiel
|
|||
|
||||
if (varflags & VARF_Native)
|
||||
{
|
||||
auto querytype = (varflags & VARF_Meta) ? type->GetClass() : type;
|
||||
fd = FindField(querytype, FName(name->Name).GetChars());
|
||||
if (fd == nullptr)
|
||||
if (varflags & VARF_Meta)
|
||||
{
|
||||
Error(field, "The member variable '%s.%s' has not been exported from the executable", type->TypeName.GetChars(), FName(name->Name).GetChars());
|
||||
Error(field, "Native meta variable %s not allowed", FName(name->Name).GetChars());
|
||||
}
|
||||
else if (thisfieldtype->Size != fd->FieldSize && fd->BitValue == 0)
|
||||
{
|
||||
Error(field, "The member variable '%s.%s' has mismatching sizes in internal and external declaration (Internal = %d, External = %d)", type->TypeName.GetChars(), FName(name->Name).GetChars(), fd->FieldSize, thisfieldtype->Size);
|
||||
}
|
||||
// Q: Should we check alignment, too? A mismatch may be an indicator for bad assumptions.
|
||||
else
|
||||
{
|
||||
// for bit fields the type must point to the source variable.
|
||||
if (fd->BitValue != 0) thisfieldtype = fd->FieldSize == 1 ? TypeUInt8 : fd->FieldSize == 2 ? TypeUInt16 : TypeUInt32;
|
||||
type->AddNativeField(name->Name, thisfieldtype, fd->FieldOffset, varflags, fd->BitValue);
|
||||
fd = FindField(type, FName(name->Name).GetChars());
|
||||
if (fd == nullptr)
|
||||
{
|
||||
Error(field, "The member variable '%s.%s' has not been exported from the executable.", type->TypeName.GetChars(), FName(name->Name).GetChars());
|
||||
}
|
||||
else if (thisfieldtype->Size != fd->FieldSize && fd->BitValue == 0)
|
||||
{
|
||||
Error(field, "The member variable '%s.%s' has mismatching sizes in internal and external declaration. (Internal = %d, External = %d)", type->TypeName.GetChars(), FName(name->Name).GetChars(), fd->FieldSize, thisfieldtype->Size);
|
||||
}
|
||||
// Q: Should we check alignment, too? A mismatch may be an indicator for bad assumptions.
|
||||
else
|
||||
{
|
||||
// for bit fields the type must point to the source variable.
|
||||
if (fd->BitValue != 0) thisfieldtype = fd->FieldSize == 1 ? TypeUInt8 : fd->FieldSize == 2 ? TypeUInt16 : TypeUInt32;
|
||||
type->AddNativeField(name->Name, thisfieldtype, fd->FieldOffset, varflags, fd->BitValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hasnativechildren)
|
||||
|
|
@ -1248,8 +1253,10 @@ bool ZCCCompiler::CompileProperties(PClass *type, TArray<ZCC_Property *> &Proper
|
|||
FString qualifiedname;
|
||||
// Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen.
|
||||
// All these will be removed from the symbol table after the compiler finishes to free up the allocated space.
|
||||
if (prefix == NAME_None) qualifiedname.Format("@property@%s", FName(p->NodeName).GetChars());
|
||||
else qualifiedname.Format("@property@%s.%s", prefix.GetChars(), FName(p->NodeName).GetChars());
|
||||
FName name = FName(p->NodeName);
|
||||
if (prefix == NAME_None) qualifiedname.Format("@property@%s", name.GetChars());
|
||||
else qualifiedname.Format("@property@%s.%s", prefix.GetChars(), name.GetChars());
|
||||
|
||||
fields.ShrinkToFit();
|
||||
if (!type->Symbols.AddSymbol(new PProperty(qualifiedname, fields)))
|
||||
{
|
||||
|
|
@ -1420,22 +1427,19 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
break;
|
||||
|
||||
case AST_DynArrayType:
|
||||
if (allowarraytypes)
|
||||
{
|
||||
auto atype = static_cast<ZCC_DynArrayType *>(ztype);
|
||||
auto ftype = DetermineType(outertype, field, name, atype->ElementType, false, true);
|
||||
if (ftype->GetRegType() == REGT_NIL || ftype->GetRegCount() > 1)
|
||||
{
|
||||
auto atype = static_cast<ZCC_DynArrayType *>(ztype);
|
||||
auto ftype = DetermineType(outertype, field, name, atype->ElementType, false, true);
|
||||
if (ftype->GetRegType() == REGT_NIL || ftype->GetRegCount() > 1)
|
||||
{
|
||||
Error(field, "%s: Base type for dynamic array types nust be integral, but got %s", name.GetChars(), ftype->DescriptiveName());
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = NewDynArray(ftype);
|
||||
}
|
||||
break;
|
||||
Error(field, "%s: Base type for dynamic array types nust be integral, but got %s", name.GetChars(), ftype->DescriptiveName());
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = NewDynArray(ftype);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
case AST_ClassType:
|
||||
{
|
||||
auto ctype = static_cast<ZCC_ClassType *>(ztype);
|
||||
|
|
@ -1755,7 +1759,7 @@ void ZCCCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *prop
|
|||
|
||||
if (f->Flags & VARF_Meta)
|
||||
{
|
||||
addr = ((char*)bag.Info) + f->Offset;
|
||||
addr = ((char*)bag.Info->Meta) + f->Offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2250,7 +2254,7 @@ 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 (type->IsA(RUNTIME_CLASS(PStruct)) && type != TypeVector2 && type != TypeVector3)
|
||||
if ((type->IsA(RUNTIME_CLASS(PStruct)) && type != TypeVector2 && type != TypeVector3) || type->IsA(RUNTIME_CLASS(PDynArray)))
|
||||
{
|
||||
// Structs are being passed by pointer, but unless marked 'out' that pointer must be readonly.
|
||||
type = NewPointer(type /*, !(p->Flags & ZCC_Out)*/);
|
||||
|
|
@ -2711,7 +2715,7 @@ void ZCCCompiler::CompileStates()
|
|||
state.Misc1 = IntConstFromNode(sl->Offset, c->Type());
|
||||
state.Misc2 = IntConstFromNode(static_cast<ZCC_Expression *>(sl->Offset->SiblingNext), c->Type());
|
||||
}
|
||||
#ifdef DYNLIGHT
|
||||
|
||||
if (sl->Lights != nullptr)
|
||||
{
|
||||
auto l = sl->Lights;
|
||||
|
|
@ -2721,7 +2725,6 @@ void ZCCCompiler::CompileStates()
|
|||
l = static_cast<decltype(l)>(l->SiblingNext);
|
||||
} while (l != sl->Lights);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sl->Action != nullptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ static void ParseSingleFile(const char *filename, int lump, void *parser, ZCCPar
|
|||
tokentype = ZCC_FLOATCONST;
|
||||
break;
|
||||
|
||||
case TK_None: // 'NONE' is a token for SBARINFO but not here.
|
||||
case TK_Identifier:
|
||||
value.Int = FName(sc.String);
|
||||
tokentype = ZCC_IDENTIFIER;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue