- 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.
This commit is contained in:
Christoph Oelckers 2016-11-04 00:19:36 +01:00
parent c9dad70408
commit 9563045305
9 changed files with 170 additions and 124 deletions

View file

@ -565,6 +565,7 @@ class DDropItem : public DObject
{ {
DECLARE_CLASS(DDropItem, DObject) DECLARE_CLASS(DDropItem, DObject)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
HAS_FIELDS
public: public:
DDropItem *Next; DDropItem *Next;
FName Name; FName Name;
@ -578,6 +579,7 @@ const double MinVel = EQUAL_EPSILON;
class AActor : public DThinker class AActor : public DThinker
{ {
DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor) DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor)
HAS_FIELDS
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
AActor () throw(); AActor () throw();

View file

@ -62,6 +62,7 @@ ClassReg DObject::RegistrationInfo =
NULL, // ParentType NULL, // ParentType
NULL, // Pointers NULL, // Pointers
&DObject::InPlaceConstructor, // ConstructNative &DObject::InPlaceConstructor, // ConstructNative
&DObject::InitNativeFields,
sizeof(DObject), // SizeOf sizeof(DObject), // SizeOf
CLASSREG_PClass, // MetaClassNum 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 () void DObject::Destroy ()
{ {
ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe; ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe;

View file

@ -111,6 +111,7 @@ struct ClassReg
ClassReg *ParentType; ClassReg *ParentType;
const size_t *Pointers; const size_t *Pointers;
void (*ConstructNative)(void *); void (*ConstructNative)(void *);
void(*InitNatives)();
unsigned int SizeOf:28; unsigned int SizeOf:28;
unsigned int MetaClassNum:4; unsigned int MetaClassNum:4;
@ -147,6 +148,9 @@ protected: \
#define HAS_OBJECT_POINTERS \ #define HAS_OBJECT_POINTERS \
static const size_t PointerOffsets[]; 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 // 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. // address 0 keeps GCC from complaining about possible misuse of offsetof.
#define DECLARE_POINTER(field) (size_t)&((ThisClass*)1)->field - 1, #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; # define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
#endif #endif
#define _IMP_PCLASS(cls,ptrs,create) \ #define _IMP_PCLASS(cls,ptrs,create, initn) \
ClassReg cls::RegistrationInfo = {\ ClassReg cls::RegistrationInfo = {\
NULL, \ NULL, \
#cls, \ #cls, \
&cls::Super::RegistrationInfo, \ &cls::Super::RegistrationInfo, \
ptrs, \ ptrs, \
create, \ create, \
initn, \
sizeof(cls), \ sizeof(cls), \
cls::MetaClassNum }; \ cls::MetaClassNum }; \
_DECLARE_TI(cls) \ _DECLARE_TI(cls) \
@ -176,18 +181,27 @@ protected: \
#define IMPLEMENT_POINTY_CLASS(cls) \ #define IMPLEMENT_POINTY_CLASS(cls) \
_IMP_CREATE_OBJ(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[] = { const size_t cls::PointerOffsets[] = {
#define IMPLEMENT_CLASS(cls) \ #define IMPLEMENT_CLASS(cls) \
_IMP_CREATE_OBJ(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) \ #define IMPLEMENT_ABSTRACT_CLASS(cls) \
_IMP_PCLASS(cls,NULL,NULL) _IMP_PCLASS(cls,nullptr,nullptr,nullptr)
#define IMPLEMENT_ABSTRACT_POINTY_CLASS(cls) \ #define IMPLEMENT_ABSTRACT_POINTY_CLASS(cls) \
_IMP_PCLASS(cls,cls::PointerOffsets,NULL) \ _IMP_PCLASS(cls,cls::PointerOffsets,nullptr,nullptr) \
const size_t cls::PointerOffsets[] = { const size_t cls::PointerOffsets[] = {
enum EObjectFlags enum EObjectFlags
@ -438,6 +452,7 @@ public:
virtual PClass *StaticType() const { return RegistrationInfo.MyClass; } virtual PClass *StaticType() const { return RegistrationInfo.MyClass; }
static ClassReg RegistrationInfo, * const RegistrationInfoPtr; static ClassReg RegistrationInfo, * const RegistrationInfoPtr;
static void InPlaceConstructor (void *mem); static void InPlaceConstructor (void *mem);
static void InitNativeFields();
typedef PClass MetaClass; typedef PClass MetaClass;
private: private:
typedef DObject ThisClass; typedef DObject ThisClass;

View file

@ -2309,13 +2309,18 @@ PField::PField()
{ {
} }
PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue) PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue)
: PSymbol(name), Offset(offset), Type(type), Flags(flags) : PSymbol(name), Offset(offset), Type(type), Flags(flags)
{ {
BitValue = bitvalue; 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. // map to the single bytes in the actual variable. The internal bit instructions operate on 8 bit values.
#ifndef __BIG_ENDIAN__ #ifndef __BIG_ENDIAN__

View file

@ -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() void G_InitLevelLocalsForScript()
{ {
PStruct *lstruct = NewStruct("LevelLocals", nullptr); PStruct *lstruct = NewStruct("LevelLocals", nullptr);
@ -1884,14 +1877,14 @@ void G_InitLevelLocalsForScript()
lstruct->AddNativeField("nextmap", TypeString, myoffsetof(FLevelLocals, NextMap)); lstruct->AddNativeField("nextmap", TypeString, myoffsetof(FLevelLocals, NextMap));
lstruct->AddNativeField("nextsecretmap", TypeString, myoffsetof(FLevelLocals, NextSecretMap)); lstruct->AddNativeField("nextsecretmap", TypeString, myoffsetof(FLevelLocals, NextSecretMap));
lstruct->AddNativeField("maptype", TypeSInt32, myoffsetof(FLevelLocals, maptype), VARF_ReadOnly); lstruct->AddNativeField("maptype", TypeSInt32, myoffsetof(FLevelLocals, maptype), VARF_ReadOnly);
lstruct->AddNativeField("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_MONSTERSTELEFRAG)); lstruct->AddNativeField("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_MONSTERSTELEFRAG);
lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_ACTOWNSPECIAL)); lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_ACTOWNSPECIAL);
lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_SNDSEQTOTALCTRL)); lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_SNDSEQTOTALCTRL);
lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_ALLMAP)); lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, (LEVEL2_ALLMAP));
lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MISSILESACTIVATEIMPACT)); lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_MISSILESACTIVATEIMPACT);
lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MONSTERFALLINGDAMAGE)); lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_MONSTERFALLINGDAMAGE);
lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_CHECKSWITCHRANGE)); lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_CHECKSWITCHRANGE);
lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_POLYGRIND)); lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_POLYGRIND);
lstruct->AddNativeField("music", TypeString, myoffsetof(FLevelLocals, Music), VARF_ReadOnly); lstruct->AddNativeField("music", TypeString, myoffsetof(FLevelLocals, Music), VARF_ReadOnly);
lstruct->AddNativeField("musicorder", TypeSInt32, myoffsetof(FLevelLocals, musicorder), VARF_ReadOnly); lstruct->AddNativeField("musicorder", TypeSInt32, myoffsetof(FLevelLocals, musicorder), VARF_ReadOnly);
lstruct->AddNativeField("total_secrets", TypeSInt32, myoffsetof(FLevelLocals, total_secrets), VARF_ReadOnly); lstruct->AddNativeField("total_secrets", TypeSInt32, myoffsetof(FLevelLocals, total_secrets), VARF_ReadOnly);

View file

@ -5389,11 +5389,11 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
{ {
if (!looping) 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)) 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);
} }
} }
} }

View file

@ -131,7 +131,7 @@ CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE);
// CODE -------------------------------------------------------------------- // CODE --------------------------------------------------------------------
IMPLEMENT_POINTY_CLASS (AActor) IMPLEMENT_POINTY_CLASS_WITH_FIELDS (AActor)
DECLARE_POINTER (target) DECLARE_POINTER (target)
DECLARE_POINTER (lastenemy) DECLARE_POINTER (lastenemy)
DECLARE_POINTER (tracer) DECLARE_POINTER (tracer)
@ -151,6 +151,99 @@ AActor::~AActor ()
// Use Destroy() instead. // 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 // AActor :: Serialize
@ -6707,10 +6800,21 @@ DEFINE_ACTION_FUNCTION(AActor, Vec2OffsetZ)
// DropItem handling // DropItem handling
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
IMPLEMENT_POINTY_CLASS(DDropItem) IMPLEMENT_POINTY_CLASS_WITH_FIELDS(DDropItem)
DECLARE_POINTER(Next) DECLARE_POINTER(Next)
END_POINTERS 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) void PrintMiscActorInfo(AActor *query)
{ {
if (query) if (query)

View file

@ -215,7 +215,6 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id,
//========================================================================== //==========================================================================
void ParseScripts(); void ParseScripts();
void ParseAllDecorate(); void ParseAllDecorate();
void G_InitLevelLocalsForScript();
void LoadActors () void LoadActors ()
{ {
@ -224,7 +223,6 @@ void LoadActors ()
timer.Reset(); timer.Clock(); timer.Reset(); timer.Clock();
FScriptPosition::ResetErrorCounter(); FScriptPosition::ResetErrorCounter();
G_InitLevelLocalsForScript();
InitThingdef(); InitThingdef();
FScriptPosition::StrictErrors = true; FScriptPosition::StrictErrors = true;
ParseScripts(); ParseScripts();

View file

@ -62,7 +62,7 @@ static TArray<AFuncDesc> AFTable;
#define DEFINE_DUMMY_FLAG(name, deprec) { DEPF_UNUSED, #name, -1, 0, deprec? VARF_Deprecated:0 } #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. // 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, INCHASE, AActor, flags),
DEFINE_FLAG(MF, UNMORPHED, AActor, flags), DEFINE_FLAG(MF, UNMORPHED, AActor, flags),
@ -91,10 +91,11 @@ static FFlagDef InternalActorFlagDefs[]=
DEFINE_FLAG(MF6, INTRYMOVE, AActor, flags6), DEFINE_FLAG(MF6, INTRYMOVE, AActor, flags6),
DEFINE_FLAG(MF7, HANDLENODELAY, AActor, flags7), DEFINE_FLAG(MF7, HANDLENODELAY, AActor, flags7),
DEFINE_FLAG(MF7, FLYCHEAT, AActor, flags7), DEFINE_FLAG(MF7, FLYCHEAT, AActor, flags7),
{ 0xffffffff }
}; };
static FFlagDef ActorFlagDefs[]= FFlagDef ActorFlagDefs[]=
{ {
DEFINE_FLAG(MF, PICKUP, APlayerPawn, flags), DEFINE_FLAG(MF, PICKUP, APlayerPawn, flags),
DEFINE_FLAG(MF, SPECIAL, 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_MBF, MBFBOUNCER, AActor, BounceFlags),
DEFINE_FLAG2(BOUNCE_AutoOffFloorOnly, BOUNCEAUTOOFFFLOORONLY, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_AutoOffFloorOnly, BOUNCEAUTOOFFFLOORONLY, AActor, BounceFlags),
DEFINE_FLAG2(BOUNCE_UseBounceState, USEBOUNCESTATE, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_UseBounceState, USEBOUNCESTATE, AActor, BounceFlags),
{ 0xffffffff }
}; };
// These won't be accessible through bitfield variables // 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[] = 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(AActor), MoreFlagDefs, countof(MoreFlagDefs) },
{ &RUNTIME_CLASS_CASTLESS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs) }, { &RUNTIME_CLASS_CASTLESS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs) },
{ &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs) }, { &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs) },
@ -634,6 +636,7 @@ static int funccmp(const void * a, const void * b)
// Initialization // Initialization
// //
//========================================================================== //==========================================================================
void G_InitLevelLocalsForScript();
void InitThingdef() void InitThingdef()
{ {
@ -679,101 +682,14 @@ void InitThingdef()
auto sptr = NewPointer(sstruct); auto sptr = NewPointer(sstruct);
sstruct->AddNativeField("soundtarget", TypeActor, myoffsetof(sector_t, SoundTarget)); sstruct->AddNativeField("soundtarget", TypeActor, myoffsetof(sector_t, SoundTarget));
// Define some member variables we feel like exposing to the user G_InitLevelLocalsForScript();
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)));
// synthesize a symbol for each flag. FAutoSegIterator probe(CRegHead, CRegTail);
for (size_t i = 0; i < countof(ActorFlagDefs); i++)
while (*++probe != NULL)
{ {
int bit = 0; if (((ClassReg *)*probe)->InitNatives)
unsigned val = ActorFlagDefs[i].flagbit; ((ClassReg *)*probe)->InitNatives();
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));
}
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*/));
} }