From 956304530501b82f8c96fad9c6b56bb3d2238498 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 4 Nov 2016 00:19:36 +0100 Subject: [PATCH] - moved declaration of native fields into the respective class definitions. This bypasses a declaration in the script in favor of a simpler implementation. In order to work it is always necessary to have an offset table to map the variables to, but doing it fully on the native side only requires adding the type to the declaration. --- src/actor.h | 2 + src/dobject.cpp | 13 ++++ src/dobject.h | 25 ++++++-- src/dobjtype.cpp | 9 ++- src/g_level.cpp | 23 +++---- src/p_acs.cpp | 4 +- src/p_mobj.cpp | 108 +++++++++++++++++++++++++++++++- src/scripting/thingdef.cpp | 2 - src/scripting/thingdef_data.cpp | 108 ++++---------------------------- 9 files changed, 170 insertions(+), 124 deletions(-) diff --git a/src/actor.h b/src/actor.h index df5ef3c175..833cd2c0ab 100644 --- a/src/actor.h +++ b/src/actor.h @@ -565,6 +565,7 @@ class DDropItem : public DObject { DECLARE_CLASS(DDropItem, DObject) HAS_OBJECT_POINTERS + HAS_FIELDS public: DDropItem *Next; FName Name; @@ -578,6 +579,7 @@ const double MinVel = EQUAL_EPSILON; class AActor : public DThinker { DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor) + HAS_FIELDS HAS_OBJECT_POINTERS public: AActor () throw(); diff --git a/src/dobject.cpp b/src/dobject.cpp index beef73c89d..56d12787f4 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -62,6 +62,7 @@ ClassReg DObject::RegistrationInfo = NULL, // ParentType NULL, // Pointers &DObject::InPlaceConstructor, // ConstructNative + &DObject::InitNativeFields, sizeof(DObject), // SizeOf CLASSREG_PClass, // MetaClassNum }; @@ -344,6 +345,18 @@ DObject::~DObject () // //========================================================================== +void DObject::InitNativeFields() +{ + auto meta = RUNTIME_CLASS(DObject); + meta->AddNativeField("bDestroyed", TypeSInt32, myoffsetof(DObject, ObjectFlags), VARF_ReadOnly, OF_EuthanizeMe); +} + +//========================================================================== +// +// +// +//========================================================================== + void DObject::Destroy () { ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe; diff --git a/src/dobject.h b/src/dobject.h index 91a80f9d07..ea0a44a85c 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -111,6 +111,7 @@ struct ClassReg ClassReg *ParentType; const size_t *Pointers; void (*ConstructNative)(void *); + void(*InitNatives)(); unsigned int SizeOf:28; unsigned int MetaClassNum:4; @@ -147,6 +148,9 @@ protected: \ #define HAS_OBJECT_POINTERS \ static const size_t PointerOffsets[]; +#define HAS_FIELDS \ + static void InitNativeFields(); + // Taking the address of a field in an object at address 1 instead of // address 0 keeps GCC from complaining about possible misuse of offsetof. #define DECLARE_POINTER(field) (size_t)&((ThisClass*)1)->field - 1, @@ -159,13 +163,14 @@ protected: \ # define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo; #endif -#define _IMP_PCLASS(cls,ptrs,create) \ +#define _IMP_PCLASS(cls,ptrs,create, initn) \ ClassReg cls::RegistrationInfo = {\ NULL, \ #cls, \ &cls::Super::RegistrationInfo, \ ptrs, \ create, \ + initn, \ sizeof(cls), \ cls::MetaClassNum }; \ _DECLARE_TI(cls) \ @@ -176,18 +181,27 @@ protected: \ #define IMPLEMENT_POINTY_CLASS(cls) \ _IMP_CREATE_OBJ(cls) \ - _IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor) \ + _IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor, nullptr) \ + const size_t cls::PointerOffsets[] = { + +#define IMPLEMENT_POINTY_CLASS_WITH_FIELDS(cls) \ + _IMP_CREATE_OBJ(cls) \ + _IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor, cls::InitNativeFields) \ const size_t cls::PointerOffsets[] = { #define IMPLEMENT_CLASS(cls) \ _IMP_CREATE_OBJ(cls) \ - _IMP_PCLASS(cls,NULL,cls::InPlaceConstructor) + _IMP_PCLASS(cls,nullptr,cls::InPlaceConstructor, nullptr) + +#define IMPLEMENT_CLASS_WITH_FIELDS(cls) \ + _IMP_CREATE_OBJ(cls) \ + _IMP_PCLASS(cls,nullptr,cls::InPlaceConstructor, cls::InitNativeFields) #define IMPLEMENT_ABSTRACT_CLASS(cls) \ - _IMP_PCLASS(cls,NULL,NULL) + _IMP_PCLASS(cls,nullptr,nullptr,nullptr) #define IMPLEMENT_ABSTRACT_POINTY_CLASS(cls) \ - _IMP_PCLASS(cls,cls::PointerOffsets,NULL) \ + _IMP_PCLASS(cls,cls::PointerOffsets,nullptr,nullptr) \ const size_t cls::PointerOffsets[] = { enum EObjectFlags @@ -438,6 +452,7 @@ public: virtual PClass *StaticType() const { return RegistrationInfo.MyClass; } static ClassReg RegistrationInfo, * const RegistrationInfoPtr; static void InPlaceConstructor (void *mem); + static void InitNativeFields(); typedef PClass MetaClass; private: typedef DObject ThisClass; diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 53eedc4568..631a7e6eee 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2309,13 +2309,18 @@ PField::PField() { } + PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue) : PSymbol(name), Offset(offset), Type(type), Flags(flags) { BitValue = bitvalue; - if (bitvalue > -1) + if (bitvalue != -1) { - if (type->IsA(RUNTIME_CLASS(PInt)) && unsigned(bitvalue) < 8 * type->Size) + BitValue = 0; + unsigned val = bitvalue; + while ((val >>= 1)) BitValue++; + + if (type->IsA(RUNTIME_CLASS(PInt)) && unsigned(BitValue) < 8u * type->Size) { // map to the single bytes in the actual variable. The internal bit instructions operate on 8 bit values. #ifndef __BIG_ENDIAN__ diff --git a/src/g_level.cpp b/src/g_level.cpp index 5b0c46fa2b..b13a39e20b 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1856,13 +1856,6 @@ void FLevelLocals::AddScroller (int secnum) // //========================================================================== -inline int val2bit(int val) -{ - int bit = 0; - while ((val >>= 1)) bit++; - return bit; -} - void G_InitLevelLocalsForScript() { PStruct *lstruct = NewStruct("LevelLocals", nullptr); @@ -1884,14 +1877,14 @@ void G_InitLevelLocalsForScript() lstruct->AddNativeField("nextmap", TypeString, myoffsetof(FLevelLocals, NextMap)); lstruct->AddNativeField("nextsecretmap", TypeString, myoffsetof(FLevelLocals, NextSecretMap)); lstruct->AddNativeField("maptype", TypeSInt32, myoffsetof(FLevelLocals, maptype), VARF_ReadOnly); - lstruct->AddNativeField("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_MONSTERSTELEFRAG)); - lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_ACTOWNSPECIAL)); - lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_SNDSEQTOTALCTRL)); - lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_ALLMAP)); - lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MISSILESACTIVATEIMPACT)); - lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MONSTERFALLINGDAMAGE)); - lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_CHECKSWITCHRANGE)); - lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_POLYGRIND)); + lstruct->AddNativeField("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_MONSTERSTELEFRAG); + lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_ACTOWNSPECIAL); + lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_SNDSEQTOTALCTRL); + lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, (LEVEL2_ALLMAP)); + lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_MISSILESACTIVATEIMPACT); + lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_MONSTERFALLINGDAMAGE); + lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_CHECKSWITCHRANGE); + lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_POLYGRIND); lstruct->AddNativeField("music", TypeString, myoffsetof(FLevelLocals, Music), VARF_ReadOnly); lstruct->AddNativeField("musicorder", TypeSInt32, myoffsetof(FLevelLocals, musicorder), VARF_ReadOnly); lstruct->AddNativeField("total_secrets", TypeSInt32, myoffsetof(FLevelLocals, total_secrets), VARF_ReadOnly); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index a6197e9a66..4024bc9f9f 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5389,11 +5389,11 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) { if (!looping) { - S_PlaySound(spot, chan, sid, vol, atten, local); + S_PlaySound(spot, chan, sid, vol, atten, !!local); } else if (!S_IsActorPlayingSomething(spot, chan & 7, sid)) { - S_PlaySound(spot, chan | CHAN_LOOP, sid, vol, atten, local); + S_PlaySound(spot, chan | CHAN_LOOP, sid, vol, atten, !!local); } } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 08b6627679..cf0a033b31 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -131,7 +131,7 @@ CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE); // CODE -------------------------------------------------------------------- -IMPLEMENT_POINTY_CLASS (AActor) +IMPLEMENT_POINTY_CLASS_WITH_FIELDS (AActor) DECLARE_POINTER (target) DECLARE_POINTER (lastenemy) DECLARE_POINTER (tracer) @@ -151,6 +151,99 @@ AActor::~AActor () // Use Destroy() instead. } +extern FFlagDef InternalActorFlagDefs[]; +extern FFlagDef ActorFlagDefs[]; + +void AActor::InitNativeFields() +{ + PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor)); + PType *TypeInventory = NewPointer(RUNTIME_CLASS(AInventory)); + PStruct *sstruct = NewStruct("Sector", nullptr); + auto TypeSector = NewPointer(sstruct); + PType *array5 = NewArray(TypeSInt32, 5); + + auto meta = RUNTIME_CLASS(AActor); + + // Define the member variables we feel like exposing to the user + meta->AddNativeField(NAME_Alpha, TypeFloat64, myoffsetof(AActor, Alpha)); + meta->AddNativeField(NAME_Angle, TypeFloat64, myoffsetof(AActor, Angles.Yaw)); + meta->AddNativeField(NAME_Args, array5, myoffsetof(AActor, args)); + meta->AddNativeField(NAME_CeilingZ, TypeFloat64, myoffsetof(AActor, ceilingz), VARF_ReadOnly); + meta->AddNativeField(NAME_FloorZ, TypeFloat64, myoffsetof(AActor, floorz), VARF_ReadOnly); + meta->AddNativeField(NAME_Health, TypeSInt32, myoffsetof(AActor, health), VARF_ReadOnly); + meta->AddNativeField(NAME_Mass, TypeSInt32, myoffsetof(AActor, Mass)); + meta->AddNativeField(NAME_Pitch, TypeFloat64, myoffsetof(AActor, Angles.Pitch)); + meta->AddNativeField(NAME_Roll, TypeFloat64, myoffsetof(AActor, Angles.Roll)); + meta->AddNativeField(NAME_Special, TypeSInt32, myoffsetof(AActor, special)); + meta->AddNativeField(NAME_TID, TypeSInt32, myoffsetof(AActor, tid), VARF_ReadOnly); + meta->AddNativeField(NAME_TIDtoHate, TypeSInt32, myoffsetof(AActor, TIDtoHate), VARF_ReadOnly); + meta->AddNativeField(NAME_WaterLevel, TypeSInt32, myoffsetof(AActor, waterlevel), VARF_ReadOnly); + meta->AddNativeField(NAME_X, TypeFloat64, myoffsetof(AActor, __Pos.X), VARF_ReadOnly | VARF_Deprecated); // must remain read-only! + meta->AddNativeField(NAME_Y, TypeFloat64, myoffsetof(AActor, __Pos.Y), VARF_ReadOnly | VARF_Deprecated); // must remain read-only! + meta->AddNativeField(NAME_Z, TypeFloat64, myoffsetof(AActor, __Pos.Z), VARF_ReadOnly | VARF_Deprecated); // must remain read-only! + meta->AddNativeField(NAME_VelX, TypeFloat64, myoffsetof(AActor, Vel.X), VARF_ReadOnly | VARF_Deprecated); + meta->AddNativeField(NAME_VelY, TypeFloat64, myoffsetof(AActor, Vel.Y), VARF_ReadOnly | VARF_Deprecated); + meta->AddNativeField(NAME_VelZ, TypeFloat64, myoffsetof(AActor, Vel.Z), VARF_ReadOnly | VARF_Deprecated); + meta->AddNativeField(NAME_MomX, TypeFloat64, myoffsetof(AActor, Vel.X), VARF_ReadOnly | VARF_Deprecated); + meta->AddNativeField(NAME_MomY, TypeFloat64, myoffsetof(AActor, Vel.Y), VARF_ReadOnly | VARF_Deprecated); + meta->AddNativeField(NAME_MomZ, TypeFloat64, myoffsetof(AActor, Vel.Z), VARF_ReadOnly | VARF_Deprecated); + meta->AddNativeField(NAME_ScaleX, TypeFloat64, myoffsetof(AActor, Scale.X), VARF_Deprecated); + meta->AddNativeField(NAME_ScaleY, TypeFloat64, myoffsetof(AActor, Scale.Y), VARF_Deprecated); + meta->AddNativeField(NAME_Score, TypeSInt32, myoffsetof(AActor, Score)); + meta->AddNativeField(NAME_Accuracy, TypeSInt32, myoffsetof(AActor, accuracy)); + meta->AddNativeField(NAME_Stamina, TypeSInt32, myoffsetof(AActor, stamina)); + meta->AddNativeField(NAME_Height, TypeFloat64, myoffsetof(AActor, Height)); + meta->AddNativeField(NAME_Radius, TypeFloat64, myoffsetof(AActor, radius), VARF_ReadOnly); + meta->AddNativeField(NAME_ReactionTime, TypeSInt32, myoffsetof(AActor, reactiontime)); + meta->AddNativeField(NAME_MeleeRange, TypeFloat64, myoffsetof(AActor, meleerange)); + meta->AddNativeField(NAME_Speed, TypeFloat64, myoffsetof(AActor, Speed)); + meta->AddNativeField("FloatSpeed", TypeFloat64, myoffsetof(AActor, FloatSpeed)); + meta->AddNativeField("PainThreshold", TypeSInt32, myoffsetof(AActor, PainThreshold)); + meta->AddNativeField("spriteAngle", TypeFloat64, myoffsetof(AActor, SpriteAngle)); + meta->AddNativeField("spriteRotation", TypeFloat64, myoffsetof(AActor, SpriteRotation)); + meta->AddNativeField(NAME_Threshold, TypeSInt32, myoffsetof(AActor, threshold)); + meta->AddNativeField(NAME_DefThreshold, TypeSInt32, myoffsetof(AActor, DefThreshold), VARF_ReadOnly); + meta->AddNativeField(NAME_Damage, TypeSInt32, myoffsetof(AActor, DamageVal), VARF_ReadOnly); + meta->AddNativeField("visdir", TypeSInt32, myoffsetof(AActor, visdir)); + meta->AddNativeField("Gravity", TypeFloat64, myoffsetof(AActor, Gravity)); + meta->AddNativeField("FloorClip", TypeFloat64, myoffsetof(AActor, Floorclip)); + meta->AddNativeField("DamageType", TypeName, myoffsetof(AActor, DamageType)); + meta->AddNativeField("FloatBobPhase", TypeUInt8, myoffsetof(AActor, FloatBobPhase)); + meta->AddNativeField("tics", TypeSInt32, myoffsetof(AActor, tics)); + meta->AddNativeField("RipperLevel", TypeSInt32, myoffsetof(AActor, RipperLevel)); + meta->AddNativeField("RipLevelMin", TypeSInt32, myoffsetof(AActor, RipLevelMin)); + meta->AddNativeField("RipLevelMax", TypeSInt32, myoffsetof(AActor, RipLevelMax)); + meta->AddNativeField("special2", TypeSInt32, myoffsetof(AActor, special2)); + meta->AddNativeField(NAME_VisibleStartAngle, TypeFloat64, myoffsetof(AActor, VisibleStartAngle)); + meta->AddNativeField(NAME_VisibleStartPitch, TypeFloat64, myoffsetof(AActor, VisibleStartPitch)); + meta->AddNativeField(NAME_VisibleEndAngle, TypeFloat64, myoffsetof(AActor, VisibleEndAngle)); + meta->AddNativeField(NAME_VisibleEndPitch, TypeFloat64, myoffsetof(AActor, VisibleEndPitch)); + meta->AddNativeField("AttackSound", TypeSound, myoffsetof(AActor, AttackSound)); + meta->AddNativeField("DeathSound", TypeSound, myoffsetof(AActor, DeathSound)); + meta->AddNativeField("SeeSound", TypeSound, myoffsetof(AActor, SeeSound)); + meta->AddNativeField("Pos", TypeVector3, myoffsetof(AActor, __Pos), VARF_ReadOnly); + meta->AddNativeField("Vel", TypeVector3, myoffsetof(AActor, Vel)); + meta->AddNativeField("Scale", TypeVector2, myoffsetof(AActor, Scale)); + meta->AddNativeField("CurState", TypeState, myoffsetof(AActor, state), VARF_ReadOnly); // has to be renamed on the script side because it clashes with the same named type. + meta->AddNativeField("SeeState", TypeState, myoffsetof(AActor, SeeState), VARF_ReadOnly); + meta->AddNativeField(NAME_Target, TypeActor, myoffsetof(AActor, target)); + meta->AddNativeField(NAME_Master, TypeActor, myoffsetof(AActor, master)); + meta->AddNativeField(NAME_Tracer, TypeActor, myoffsetof(AActor, tracer)); + meta->AddNativeField("LastHeard", TypeActor, myoffsetof(AActor, LastHeard)); + meta->AddNativeField("LastEnemy", TypeActor, myoffsetof(AActor, lastenemy)); + meta->AddNativeField("Sector", TypeSector, myoffsetof(AActor, Sector)); + + // synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them. + for (size_t i = 0; ActorFlagDefs[i].flagbit != 0xffffffff; i++) + { + meta->AddNativeField(FStringf("b%s", ActorFlagDefs[i].name), (ActorFlagDefs[i].fieldsize == 4? TypeSInt32 : TypeSInt16), ActorFlagDefs[i].structoffset, ActorFlagDefs[i].varflags, ActorFlagDefs[i].flagbit); + } + for (size_t i = 0; InternalActorFlagDefs[i].flagbit != 0xffffffff; i++) + { + meta->AddNativeField(FStringf("b%s", InternalActorFlagDefs[i].name), (InternalActorFlagDefs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), InternalActorFlagDefs[i].structoffset, InternalActorFlagDefs[i].varflags, InternalActorFlagDefs[i].flagbit); + } +} + //========================================================================== // // AActor :: Serialize @@ -6707,10 +6800,21 @@ DEFINE_ACTION_FUNCTION(AActor, Vec2OffsetZ) // DropItem handling // //---------------------------------------------------------------------------- -IMPLEMENT_POINTY_CLASS(DDropItem) +IMPLEMENT_POINTY_CLASS_WITH_FIELDS(DDropItem) DECLARE_POINTER(Next) END_POINTERS +void DDropItem::InitNativeFields() +{ + auto meta = RUNTIME_CLASS(DDropItem); + PType *TypeDropItem = NewPointer(RUNTIME_CLASS(DDropItem)); + meta->AddNativeField("Next", TypeDropItem, myoffsetof(DDropItem, Next), VARF_ReadOnly); + meta->AddNativeField("Name", TypeName, myoffsetof(DDropItem, Name), VARF_ReadOnly); + meta->AddNativeField("Probability", TypeSInt32, myoffsetof(DDropItem, Probability), VARF_ReadOnly); + meta->AddNativeField("Amount", TypeSInt32, myoffsetof(DDropItem, Amount)); +} + + void PrintMiscActorInfo(AActor *query) { if (query) diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index 38bf2bcf6c..8c42e8987d 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -215,7 +215,6 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id, //========================================================================== void ParseScripts(); void ParseAllDecorate(); -void G_InitLevelLocalsForScript(); void LoadActors () { @@ -224,7 +223,6 @@ void LoadActors () timer.Reset(); timer.Clock(); FScriptPosition::ResetErrorCounter(); - G_InitLevelLocalsForScript(); InitThingdef(); FScriptPosition::StrictErrors = true; ParseScripts(); diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 4d18a083bc..f628dec3c1 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -62,7 +62,7 @@ static TArray AFTable; #define DEFINE_DUMMY_FLAG(name, deprec) { DEPF_UNUSED, #name, -1, 0, deprec? VARF_Deprecated:0 } // internal flags. These do not get exposed to actor definitions but scripts need to be able to access them as variables. -static FFlagDef InternalActorFlagDefs[]= +FFlagDef InternalActorFlagDefs[]= { DEFINE_FLAG(MF, INCHASE, AActor, flags), DEFINE_FLAG(MF, UNMORPHED, AActor, flags), @@ -91,10 +91,11 @@ static FFlagDef InternalActorFlagDefs[]= DEFINE_FLAG(MF6, INTRYMOVE, AActor, flags6), DEFINE_FLAG(MF7, HANDLENODELAY, AActor, flags7), DEFINE_FLAG(MF7, FLYCHEAT, AActor, flags7), + { 0xffffffff } }; -static FFlagDef ActorFlagDefs[]= +FFlagDef ActorFlagDefs[]= { DEFINE_FLAG(MF, PICKUP, APlayerPawn, flags), DEFINE_FLAG(MF, SPECIAL, APlayerPawn, flags), @@ -328,6 +329,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), + { 0xffffffff } }; // These won't be accessible through bitfield variables @@ -433,7 +435,7 @@ static FFlagDef PowerSpeedFlagDefs[] = static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; } FlagLists[] = { - { &RUNTIME_CLASS_CASTLESS(AActor), ActorFlagDefs, countof(ActorFlagDefs) }, + { &RUNTIME_CLASS_CASTLESS(AActor), ActorFlagDefs, countof(ActorFlagDefs)-1 }, // -1 to account for the terminator { &RUNTIME_CLASS_CASTLESS(AActor), MoreFlagDefs, countof(MoreFlagDefs) }, { &RUNTIME_CLASS_CASTLESS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs) }, { &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs) }, @@ -634,6 +636,7 @@ static int funccmp(const void * a, const void * b) // Initialization // //========================================================================== +void G_InitLevelLocalsForScript(); void InitThingdef() { @@ -679,101 +682,14 @@ void InitThingdef() auto sptr = NewPointer(sstruct); sstruct->AddNativeField("soundtarget", TypeActor, myoffsetof(sector_t, SoundTarget)); - // Define some member variables we feel like exposing to the user - PSymbolTable &symt = RUNTIME_CLASS(AActor)->Symbols; - PType *array5 = NewArray(TypeSInt32, 5); - symt.AddSymbol(new PField("sector", sptr, VARF_Native, myoffsetof(AActor, Sector))); - symt.AddSymbol(new PField(NAME_Alpha, TypeFloat64, VARF_Native, myoffsetof(AActor, Alpha))); - symt.AddSymbol(new PField(NAME_Angle, TypeFloat64, VARF_Native, myoffsetof(AActor, Angles.Yaw))); - symt.AddSymbol(new PField(NAME_Args, array5, VARF_Native, myoffsetof(AActor, args))); - symt.AddSymbol(new PField(NAME_CeilingZ, TypeFloat64, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, ceilingz))); - symt.AddSymbol(new PField(NAME_FloorZ, TypeFloat64, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, floorz))); - symt.AddSymbol(new PField(NAME_Health, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, health))); - symt.AddSymbol(new PField(NAME_Mass, TypeSInt32, VARF_Native, myoffsetof(AActor, Mass))); - symt.AddSymbol(new PField(NAME_Pitch, TypeFloat64, VARF_Native, myoffsetof(AActor, Angles.Pitch))); - symt.AddSymbol(new PField(NAME_Roll, TypeFloat64, VARF_Native, myoffsetof(AActor, Angles.Roll))); - symt.AddSymbol(new PField(NAME_Special, TypeSInt32, VARF_Native, myoffsetof(AActor, special))); - symt.AddSymbol(new PField(NAME_TID, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, tid))); - symt.AddSymbol(new PField(NAME_TIDtoHate, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, TIDtoHate))); - symt.AddSymbol(new PField(NAME_WaterLevel, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, waterlevel))); - symt.AddSymbol(new PField(NAME_X, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, __Pos.X))); // must remain read-only! - symt.AddSymbol(new PField(NAME_Y, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, __Pos.Y))); // must remain read-only! - symt.AddSymbol(new PField(NAME_Z, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, __Pos.Z))); // must remain read-only! - symt.AddSymbol(new PField(NAME_VelX, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.X))); - symt.AddSymbol(new PField(NAME_VelY, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Y))); - symt.AddSymbol(new PField(NAME_VelZ, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Z))); - symt.AddSymbol(new PField(NAME_MomX, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.X))); - symt.AddSymbol(new PField(NAME_MomY, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Y))); - symt.AddSymbol(new PField(NAME_MomZ, TypeFloat64, VARF_Native|VARF_ReadOnly|VARF_Deprecated, myoffsetof(AActor, Vel.Z))); - symt.AddSymbol(new PField(NAME_ScaleX, TypeFloat64, VARF_Native|VARF_Deprecated, myoffsetof(AActor, Scale.X))); - symt.AddSymbol(new PField(NAME_ScaleY, TypeFloat64, VARF_Native|VARF_Deprecated, myoffsetof(AActor, Scale.Y))); - symt.AddSymbol(new PField(NAME_Score, TypeSInt32, VARF_Native, myoffsetof(AActor, Score))); - symt.AddSymbol(new PField(NAME_Accuracy, TypeSInt32, VARF_Native, myoffsetof(AActor, accuracy))); - symt.AddSymbol(new PField(NAME_Stamina, TypeSInt32, VARF_Native, myoffsetof(AActor, stamina))); - symt.AddSymbol(new PField(NAME_Height, TypeFloat64, VARF_Native, myoffsetof(AActor, Height))); - symt.AddSymbol(new PField(NAME_Radius, TypeFloat64, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, radius))); - symt.AddSymbol(new PField(NAME_ReactionTime, TypeSInt32, VARF_Native, myoffsetof(AActor, reactiontime))); - symt.AddSymbol(new PField(NAME_MeleeRange, TypeFloat64, VARF_Native, myoffsetof(AActor, meleerange))); - symt.AddSymbol(new PField(NAME_Speed, TypeFloat64, VARF_Native, myoffsetof(AActor, Speed))); - symt.AddSymbol(new PField("FloatSpeed", TypeFloat64, VARF_Native, myoffsetof(AActor, FloatSpeed))); - symt.AddSymbol(new PField("PainThreshold", TypeSInt32, VARF_Native, myoffsetof(AActor, PainThreshold))); - symt.AddSymbol(new PField("spriteAngle", TypeFloat64, VARF_Native, myoffsetof(AActor, SpriteAngle))); - symt.AddSymbol(new PField("spriteRotation", TypeFloat64, VARF_Native, myoffsetof(AActor, SpriteRotation))); - symt.AddSymbol(new PField(NAME_Threshold, TypeSInt32, VARF_Native, myoffsetof(AActor, threshold))); - symt.AddSymbol(new PField(NAME_DefThreshold, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DefThreshold))); - symt.AddSymbol(new PField(NAME_Damage, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DamageVal))); - symt.AddSymbol(new PField("visdir", TypeSInt32, VARF_Native, myoffsetof(AActor, visdir))); - symt.AddSymbol(new PField("Gravity", TypeFloat64, VARF_Native, myoffsetof(AActor, Gravity))); - symt.AddSymbol(new PField("FloorClip", TypeFloat64, VARF_Native, myoffsetof(AActor, Floorclip))); - symt.AddSymbol(new PField("DamageType", TypeName, VARF_Native, myoffsetof(AActor, DamageType))); - symt.AddSymbol(new PField("FloatBobPhase", TypeUInt8, VARF_Native, myoffsetof(AActor, FloatBobPhase))); - symt.AddSymbol(new PField("tics", TypeSInt32, VARF_Native, myoffsetof(AActor, tics))); - symt.AddSymbol(new PField("RipperLevel", TypeSInt32, VARF_Native, myoffsetof(AActor, RipperLevel))); - symt.AddSymbol(new PField("RipLevelMin", TypeSInt32, VARF_Native, myoffsetof(AActor, RipLevelMin))); - symt.AddSymbol(new PField("RipLevelMax", TypeSInt32, VARF_Native, myoffsetof(AActor, RipLevelMax))); - symt.AddSymbol(new PField("special2", TypeSInt32, VARF_Native, myoffsetof(AActor, special2))); - symt.AddSymbol(new PField(NAME_VisibleStartAngle, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleStartAngle))); - symt.AddSymbol(new PField(NAME_VisibleStartPitch, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleStartPitch))); - symt.AddSymbol(new PField(NAME_VisibleEndAngle, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleEndAngle))); - symt.AddSymbol(new PField(NAME_VisibleEndPitch, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleEndPitch))); - symt.AddSymbol(new PField("AttackSound", TypeSound, VARF_Native, myoffsetof(AActor, AttackSound))); - symt.AddSymbol(new PField("DeathSound", TypeSound, VARF_Native, myoffsetof(AActor, DeathSound))); - symt.AddSymbol(new PField("SeeSound", TypeSound, VARF_Native, myoffsetof(AActor, SeeSound))); - symt.AddSymbol(new PField("Pos", TypeVector3, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, __Pos))); - symt.AddSymbol(new PField("Vel", TypeVector3, VARF_Native, myoffsetof(AActor, Vel))); - symt.AddSymbol(new PField("Scale", TypeVector2, VARF_Native, myoffsetof(AActor, Scale))); - symt.AddSymbol(new PField("CurState", TypeState, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, state))); // has to be renamed on the script side because it clashes with the same named type. - symt.AddSymbol(new PField("SeeState", TypeState, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, SeeState))); - symt.AddSymbol(new PField(NAME_Target, TypeActor, VARF_Native, myoffsetof(AActor, target))); - symt.AddSymbol(new PField(NAME_Master, TypeActor, VARF_Native, myoffsetof(AActor, master))); - symt.AddSymbol(new PField(NAME_Tracer, TypeActor, VARF_Native, myoffsetof(AActor, tracer))); - symt.AddSymbol(new PField("LastHeard", TypeActor, VARF_Native, myoffsetof(AActor, LastHeard))); - symt.AddSymbol(new PField("LastEnemy", TypeActor, VARF_Native, myoffsetof(AActor, lastenemy))); + G_InitLevelLocalsForScript(); - // synthesize a symbol for each flag. - for (size_t i = 0; i < countof(ActorFlagDefs); i++) + FAutoSegIterator probe(CRegHead, CRegTail); + + while (*++probe != NULL) { - int bit = 0; - unsigned val = ActorFlagDefs[i].flagbit; - while ((val >>= 1)) bit++; - symt.AddSymbol(new PField(FStringf("b%s", ActorFlagDefs[i].name), (ActorFlagDefs[i].fieldsize == 4? TypeSInt32 : TypeSInt16), ActorFlagDefs[i].varflags, ActorFlagDefs[i].structoffset, bit)); + if (((ClassReg *)*probe)->InitNatives) + ((ClassReg *)*probe)->InitNatives(); } - for (size_t i = 0; i < countof(InternalActorFlagDefs); i++) - { - int bit = 0; - unsigned val = InternalActorFlagDefs[i].flagbit; - while ((val >>= 1)) bit++; - symt.AddSymbol(new PField(FStringf("b%s", InternalActorFlagDefs[i].name), (InternalActorFlagDefs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), InternalActorFlagDefs[i].varflags, InternalActorFlagDefs[i].structoffset, bit)); - } - - PSymbolTable &symt2 = RUNTIME_CLASS(DDropItem)->Symbols; - PType *TypeDropItem = NewPointer(RUNTIME_CLASS(DDropItem)); - symt2.AddSymbol(new PField("Next", TypeDropItem, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Next))); - symt2.AddSymbol(new PField("Name", TypeName, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Name))); - symt2.AddSymbol(new PField("Probability", TypeSInt32, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Probability))); - symt2.AddSymbol(new PField("Amount", TypeSInt32, VARF_Native, myoffsetof(DDropItem, Amount))); - - PSymbolTable &symt3 = RUNTIME_CLASS(DObject)->Symbols; - symt3.AddSymbol(new PField("bDestroyed", TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(DObject, ObjectFlags), 5/*OF_EuthanizeMe*/)); }