- Make the autosegs read-only.

- Derive PClass from dobject.cpp. This has one major ramification: Since the PClass
  is not allocated until runtime, you cannot initialize any static/global data
  structures with pointers to PClasses using RUNTIME_CLASS. Attempting to do so
  will just initialize with a NULL pointer. Instead, you can initialize using
  the address of the pointer returned by RUNTIME_CLASS and dereference that. By
  the time you have an opportunity to dereference it, it will no longer be NULL.
- Sync CmakeLists.txt.
- Random fixes for problems GCC spotted.

SVN r1852 (scripting)
This commit is contained in:
Randy Heit 2009-09-17 01:36:14 +00:00
parent 92766165f5
commit 1eb7912bd8
35 changed files with 258 additions and 207 deletions

View file

@ -771,6 +771,9 @@ add_executable( zdoom WIN32
timidity/resample.cpp
timidity/timidity.cpp
xlat/parse_xlat.cpp
zscript/vmdisasm.cpp
zscript/vmexec.cpp
zscript/vmframe.cpp
autozend.cpp )
set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" )
@ -790,6 +793,7 @@ include_directories( .
thingdef
timidity
xlat
zscript
../game-music-emu/gme
../gdtoa
../dumb/include

View file

@ -36,7 +36,7 @@
#define AUTOSEGS_H
#define REGMARKER(x) (x)
typedef void *REGINFO;
typedef void * const REGINFO;
// List of Action functons
extern REGINFO ARegHead;

View file

@ -46,24 +46,29 @@
#if defined(_MSC_VER)
#pragma comment(linker, "/merge:.areg=.data /merge:.creg=.data /merge:.greg=.data /merge:.mreg=.data /merge:.yreg=.data")
// The various reg sections are used to group pointers spread across multiple
// source files into cohesive arrays in the final executable. We don't
// actually care about these sections themselves and merge them all into
// a single section during the final link. (.rdata is the standard section
// for initialized read-only data.)
#pragma data_seg(".areg$a")
void *ARegHead = 0;
#pragma comment(linker, "/merge:.areg=.rdata /merge:.creg=.rdata /merge:.greg=.rdata")
#pragma comment(linker, "/merge:.mreg=.rdata /merge:.yreg=.rdata")
#pragma data_seg(".creg$a")
void *CRegHead = 0;
#pragma section(".areg$a",read)
__declspec(allocate(".areg$a")) void *const ARegHead = 0;
#pragma data_seg(".greg$a")
void *GRegHead = 0;
#pragma section(".creg$a",read)
__declspec(allocate(".creg$a")) void *const CRegHead = 0;
#pragma data_seg(".mreg$a")
void *MRegHead = 0;
#pragma section(".greg$a",read)
__declspec(allocate(".greg$a")) void *const GRegHead = 0;
#pragma data_seg(".yreg$a")
void *YRegHead = 0;
#pragma section(".mreg$a",read)
__declspec(allocate(".mreg$a")) void *const MRegHead = 0;
#pragma data_seg()
#pragma section(".yreg$a",read)
__declspec(allocate(".yreg$a")) void *const YRegHead = 0;
// We want visual styles support under XP
#if defined _M_IX86
@ -88,11 +93,16 @@ void *YRegHead = 0;
#include "doomtype.h"
void *ARegHead __attribute__((section(SECTION_AREG))) = 0;
void *CRegHead __attribute__((section(SECTION_CREG))) = 0;
void *GRegHead __attribute__((section(SECTION_GREG))) = 0;
void *MRegHead __attribute__((section(SECTION_MREG))) = 0;
void *YRegHead __attribute__((section(SECTION_YREG))) = 0;
// I don't know of an easy way to merge sections together with the GNU linker,
// so GCC users will see all of these sections appear in the final executable.
// (There are linker scripts, but that apparently involves extracting the
// default script from ld and then modifying it.)
void *ARegHead const __attribute__((section(SECTION_AREG))) = 0;
void *CRegHead const __attribute__((section(SECTION_CREG))) = 0;
void *GRegHead const __attribute__((section(SECTION_GREG))) = 0;
void *MRegHead const __attribute__((section(SECTION_MREG))) = 0;
void *YRegHead const __attribute__((section(SECTION_YREG))) = 0;
#else

View file

@ -37,34 +37,31 @@
#if defined(_MSC_VER)
#pragma data_seg(".areg$z")
void *ARegTail = 0;
#pragma section(".areg$z",read)
__declspec(allocate(".areg$z")) void *const ARegTail = 0;
#pragma data_seg(".creg$z")
void *CRegTail = 0;
#pragma section(".creg$z",read)
__declspec(allocate(".creg$z")) void *const CRegTail = 0;
#pragma data_seg(".greg$z")
void *GRegTail = 0;
#pragma section(".greg$z",read)
__declspec(allocate(".greg$z")) void *const GRegTail = 0;
#pragma data_seg(".mreg$z")
void *MRegTail = 0;
#pragma data_seg(".yreg$z")
void *YRegTail = 0;
#pragma data_seg()
#pragma section(".mreg$z",read)
__declspec(allocate(".mreg$z")) void *const MRegTail = 0;
#pragma section(".yreg$z",read)
__declspec(allocate(".yreg$z")) void *const YRegTail = 0;
#elif defined(__GNUC__)
#include "doomtype.h"
void *ARegTail __attribute__((section(SECTION_AREG))) = 0;
void *CRegTail __attribute__((section(SECTION_CREG))) = 0;
void *GRegTail __attribute__((section(SECTION_GREG))) = 0;
void *MRegTail __attribute__((section(SECTION_MREG))) = 0;
void *YRegTail __attribute__((section(SECTION_YREG))) = 0;
void *const ARegTail __attribute__((section(SECTION_AREG))) = 0;
void *const CRegTail __attribute__((section(SECTION_CREG))) = 0;
void *const GRegTail __attribute__((section(SECTION_GREG))) = 0;
void *const MRegTail __attribute__((section(SECTION_MREG))) = 0;
void *const YRegTail __attribute__((section(SECTION_YREG))) = 0;
#else

View file

@ -1760,16 +1760,16 @@ static int PatchMisc (int dummy)
"Minotaur",
NULL
};
static const PClass * const types[] =
static const PClass * const *types[] =
{
RUNTIME_CLASS(APowerInvulnerable),
RUNTIME_CLASS(APowerStrength),
RUNTIME_CLASS(APowerInvisibility),
RUNTIME_CLASS(APowerIronFeet),
RUNTIME_CLASS(APowerLightAmp),
RUNTIME_CLASS(APowerWeaponLevel2),
RUNTIME_CLASS(APowerSpeed),
RUNTIME_CLASS(APowerMinotaur)
&RUNTIME_CLASS(APowerInvulnerable),
&RUNTIME_CLASS(APowerStrength),
&RUNTIME_CLASS(APowerInvisibility),
&RUNTIME_CLASS(APowerIronFeet),
&RUNTIME_CLASS(APowerLightAmp),
&RUNTIME_CLASS(APowerWeaponLevel2),
&RUNTIME_CLASS(APowerSpeed),
&RUNTIME_CLASS(APowerMinotaur)
};
int i;
@ -1795,7 +1795,7 @@ static int PatchMisc (int dummy)
}
else
{
static_cast<APowerup *>(GetDefaultByType (types[i]))->BlendColor = PalEntry(
static_cast<APowerup *>(GetDefaultByType (*types[i]))->BlendColor = PalEntry(
BYTE(clamp(a,0.f,1.f)*255.f),
clamp(r,0,255),
clamp(g,0,255),

View file

@ -1691,12 +1691,10 @@ void D_DoomMain (void)
execFiles = new DArgs;
GameConfig->AddAutoexec (execFiles, GameNames[gameinfo.gametype]);
D_MultiExec (execFiles, true);
execFiles->Destroy();
// Run .cfg files at the start of the command line.
execFiles = Args->GatherFiles (NULL, ".cfg", false);
D_MultiExec (execFiles, true);
execFiles->Destroy();
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
@ -1730,10 +1728,6 @@ void D_DoomMain (void)
D_AddWildFile (files3->GetArg (i));
}
}
files->Destroy();
files1->Destroy();
files2->Destroy();
files3->Destroy();
Printf ("W_Init: Init WADfiles.\n");
Wads.InitMultipleFiles (&wadfiles);

View file

@ -43,7 +43,7 @@
class FScanner;
class FDecalTemplate;
struct FDecalAnimator;
struct PClass;
class PClass;
class DBaseDecal;
struct side_t;

View file

@ -48,10 +48,9 @@
#include "a_sharedglobal.h"
#include "dsectoreffect.h"
PClass DObject::_StaticType;
ClassReg DObject::RegistrationInfo =
{
&DObject::_StaticType, // MyClass
NULL, // MyClass
"DObject", // Name
NULL, // ParentType
sizeof(DObject), // SizeOf
@ -458,9 +457,12 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
int i;
// Go through all objects.
i = 0;DObject *last=0;
for (probe = GC::Root; probe != NULL; probe = probe->ObjNext)
{
i++;
changed += probe->PointerSubstitution(old, notOld);
last = probe;
}
// Go through the bodyque.

View file

@ -37,7 +37,7 @@
#include <stdlib.h>
#include "doomtype.h"
struct PClass;
class PClass;
class FArchive;
@ -130,29 +130,28 @@ private:
void CopyMeta (const FMetaTable *other);
};
#define RUNTIME_TYPE(object) (object->GetClass()) // Passed an object, returns the type of that object
#define RUNTIME_CLASS(cls) (&cls::_StaticType) // Passed a class name, returns a PClass representing that class
#define NATIVE_TYPE(object) (object->StaticType()) // Passed an object, returns the type of the C++ class representing the object
#define RUNTIME_TYPE(object) (object->GetClass()) // Passed an object, returns the type of that object
#define RUNTIME_CLASS(cls) (cls::RegistrationInfo.MyClass) // Passed a native class name, returns a PClass representing that class
#define NATIVE_TYPE(object) (object->StaticType()) // Passed an object, returns the type of the C++ class representing the object
struct ClassReg
{
PClass *MyClass;
const char *Name;
PClass *ParentType;
ClassReg *ParentType;
unsigned int SizeOf;
const size_t *Pointers;
void (*ConstructNative)(void *);
void RegisterClass() const;
PClass *RegisterClass();
};
enum EInPlace { EC_InPlace };
#define DECLARE_ABSTRACT_CLASS(cls,parent) \
public: \
static PClass _StaticType; \
virtual PClass *StaticType() const { return &_StaticType; } \
static ClassReg RegistrationInfo, *RegistrationInfoPtr; \
virtual PClass *StaticType() const { return RegistrationInfo.MyClass; } \
static ClassReg RegistrationInfo, * const RegistrationInfoPtr; \
private: \
typedef parent Super; \
typedef cls ThisClass;
@ -170,19 +169,17 @@ private: \
#define END_POINTERS ~(size_t)0 };
#if defined(_MSC_VER)
# pragma data_seg(".creg$u")
# pragma data_seg()
# define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg *cls::RegistrationInfoPtr = &cls::RegistrationInfo;
# pragma section(".creg$u",read)
# define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg * const cls::RegistrationInfoPtr = &cls::RegistrationInfo;
#else
# define _DECLARE_TI(cls) ClassReg *cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
# define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
#endif
#define _IMP_PCLASS(cls,ptrs,create) \
PClass cls::_StaticType; \
ClassReg cls::RegistrationInfo = {\
RUNTIME_CLASS(cls), \
NULL, \
#cls, \
RUNTIME_CLASS(cls::Super), \
&cls::Super::RegistrationInfo, \
sizeof(cls), \
ptrs, \
create }; \
@ -263,6 +260,9 @@ namespace GC
// Size of GC steps.
extern int StepMul;
// Is this the final collection just before exit?
extern bool FinalGC;
// Current white value for known-dead objects.
static inline uint32 OtherWhite()
{
@ -433,9 +433,8 @@ template<class T> inline void GC::Mark(TObjPtr<T> &obj)
class DObject
{
public:
static PClass _StaticType;
virtual PClass *StaticType() const { return &_StaticType; }
static ClassReg RegistrationInfo, *RegistrationInfoPtr;
virtual PClass *StaticType() const { return RegistrationInfo.MyClass; }
static ClassReg RegistrationInfo, * const RegistrationInfoPtr;
static void InPlaceConstructor (void *mem);
private:
typedef DObject ThisClass;

View file

@ -147,6 +147,7 @@ int Pause = DEFAULT_GCPAUSE;
int StepMul = DEFAULT_GCMUL;
int StepCount;
size_t Dept;
bool FinalGC;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -239,8 +240,8 @@ static DObject **SweepList(DObject **p, size_t count, size_t *finalize_count)
// be in a thinker list, then I need to add write barriers for every time a
// thinker pointer is changed. This seems easier and perfectly reasonable, since
// a live thinker that isn't on a thinker list isn't much of a thinker.
assert(!curr->IsKindOf(RUNTIME_CLASS(DThinker)) || (curr->ObjectFlags & OF_Sentinel));
assert(!curr->IsKindOf(RUNTIME_CLASS(DInterpolation)));
assert(FinalGC || !curr->IsKindOf(RUNTIME_CLASS(DThinker)) || (curr->ObjectFlags & OF_Sentinel));
assert(FinalGC || !curr->IsKindOf(RUNTIME_CLASS(DInterpolation)));
curr->Destroy();
}
curr->ObjectFlags |= OF_Cleanup;
@ -327,14 +328,10 @@ static void MarkRoot()
SectorMarker->SecNum = 0;
}
Mark(SectorMarker);
// Mark symbol tables
// Mark classes
for (unsigned j = 0; j < PClass::m_Types.Size(); ++j)
{
PClass *cls = PClass::m_Types[j];
if (cls != NULL)
{
cls->Symbols.MarkSymbols();
}
Mark(PClass::m_Types[j]);
}
// Mark bot stuff.
Mark(bglobal.firstthing);

View file

@ -38,6 +38,10 @@
#include "templates.h"
#include "autosegs.h"
IMPLEMENT_POINTY_CLASS(PClass)
DECLARE_POINTER(ParentClass)
END_POINTERS
TArray<PClass *> PClass::m_RuntimeActors;
TArray<PClass *> PClass::m_Types;
PClass *PClass::TypeHash[PClass::HASH_SIZE];
@ -48,35 +52,29 @@ static const size_t TheEnd = ~(size_t)0;
static int STACK_ARGS cregcmp (const void *a, const void *b)
{
// VC++ introduces NULLs in the sequence. GCC seems to work as expected and not do it.
const ClassReg *class1 = *(const ClassReg **)a;
const ClassReg *class2 = *(const ClassReg **)b;
if (class1 == NULL) return 1;
if (class2 == NULL) return -1;
return strcmp (class1->Name, class2->Name);
const PClass *class1 = *(const PClass **)a;
const PClass *class2 = *(const PClass **)b;
return strcmp(class1->TypeName, class2->TypeName);
}
void PClass::StaticInit ()
{
atterm (StaticShutdown);
// Sort classes by name to remove dependance on how the compiler ordered them.
REGINFO *head = &CRegHead;
REGINFO *tail = &CRegTail;
// MinGW's linker is linking the object files backwards for me now...
if (head > tail)
{
swap (head, tail);
}
qsort (head + 1, tail - head - 1, sizeof(REGINFO), cregcmp);
FAutoSegIterator probe(CRegHead, CRegTail);
while (*++probe != NULL)
{
((ClassReg *)*probe)->RegisterClass ();
}
// Keep actors in consistant order. I did this before, though I'm not
// sure if this is really necessary to maintain any sort of sync.
qsort(&m_Types[0], m_Types.Size(), sizeof(m_Types[0]), cregcmp);
for (unsigned int i = 0; i < m_Types.Size(); ++i)
{
m_Types[i]->ClassIndex = i;
}
}
void PClass::StaticShutdown ()
@ -114,6 +112,24 @@ void PClass::StaticShutdown ()
bShutdown = true;
}
PClass::PClass()
{
Size = sizeof(DObject);
ParentClass = NULL;
Pointers = NULL;
FlatPointers = NULL;
ActorInfo = NULL;
HashNext = NULL;
Defaults = NULL;
bRuntimeClass = false;
ClassIndex = ~0;
}
PClass::~PClass()
{
Symbols.ReleaseSymbols();
}
void PClass::StaticFreeData (PClass *type)
{
if (type->Defaults != NULL)
@ -142,7 +158,7 @@ void PClass::StaticFreeData (PClass *type)
}
delete type->ActorInfo;
type->ActorInfo = NULL;
}
}/*
if (type->bRuntimeClass)
{
delete type;
@ -150,22 +166,32 @@ void PClass::StaticFreeData (PClass *type)
else
{
type->Symbols.ReleaseSymbols();
}
}*/
}
void ClassReg::RegisterClass () const
PClass *ClassReg::RegisterClass()
{
assert (MyClass != NULL);
// MyClass may have already been created by a previous recursive call.
// Or this may be a recursive call for a previously created class.
if (MyClass != NULL)
{
return MyClass;
}
// Add type to list
MyClass->ClassIndex = PClass::m_Types.Push (MyClass);
MyClass->TypeName = FName(Name+1);
MyClass->ParentClass = ParentType;
MyClass->Size = SizeOf;
MyClass->Pointers = Pointers;
MyClass->ConstructNative = ConstructNative;
MyClass->InsertIntoHash ();
PClass *cls = new PClass;
MyClass = cls;
PClass::m_Types.Push(cls);
cls->TypeName = FName(Name+1);
if (ParentType != NULL)
{
cls->ParentClass = ParentType->RegisterClass();
}
cls->Size = SizeOf;
cls->Pointers = Pointers;
cls->ConstructNative = ConstructNative;
cls->InsertIntoHash();
return cls;
}
void PClass::InsertIntoHash ()
@ -465,6 +491,28 @@ const PClass *PClass::NativeClass() const
return cls;
}
size_t PClass::PropagateMark()
{
size_t marked;
// Mark symbols
marked = Symbols.MarkSymbols();
// Mark state functions
if (ActorInfo != NULL)
{
for (int i = 0; i < ActorInfo->NumOwnedStates; ++i)
{
if (ActorInfo->OwnedStates[i].ActionFunc != NULL)
{
GC::Mark(ActorInfo->OwnedStates[i].ActionFunc);
}
}
// marked += ActorInfo->NumOwnedStates * sizeof(FState);
}
return marked + Super::PropagateMark();
}
// Symbol tables ------------------------------------------------------------
IMPLEMENT_ABSTRACT_CLASS(PSymbol);
@ -486,12 +534,13 @@ PSymbolTable::~PSymbolTable ()
ReleaseSymbols();
}
void PSymbolTable::MarkSymbols()
size_t PSymbolTable::MarkSymbols()
{
for (unsigned int i = 0; i < Symbols.Size(); ++i)
{
GC::Mark(Symbols[i]);
}
return Symbols.Size() * sizeof(Symbols[0]);
}
void PSymbolTable::ReleaseSymbols()

View file

@ -101,7 +101,7 @@ struct PSymbolTable
PSymbolTable();
~PSymbolTable();
void MarkSymbols();
size_t MarkSymbols();
// Sets the table to use for searches if this one doesn't contain the
// requested symbol.
@ -126,8 +126,11 @@ private:
// Meta-info for every class derived from DObject ---------------------------
struct PClass
class PClass : public DObject
{
DECLARE_CLASS(PClass, DObject);
HAS_OBJECT_POINTERS;
public:
static void StaticInit ();
static void StaticShutdown ();
static void StaticFreeData (PClass *type);
@ -149,6 +152,8 @@ struct PClass
void (*ConstructNative)(void *);
// The rest are all functions and static data ----------------
PClass();
~PClass();
void InsertIntoHash ();
DObject *CreateNew () const;
PClass *CreateDerivedClass (FName name, unsigned int size);
@ -156,6 +161,7 @@ struct PClass
void BuildFlatPointers ();
void FreeStateList();
const PClass *NativeClass() const;
size_t PropagateMark();
// Returns true if this type is an ancestor of (or same as) the passed type.
bool IsAncestorOf (const PClass *ti) const

View file

@ -44,9 +44,7 @@ struct cluster_info_t;
class FScanner;
#if defined(_MSC_VER)
#pragma data_seg(".yreg$u")
#pragma data_seg()
#pragma section(".yreg$u",read)
#define MSVC_YSEG __declspec(allocate(".yreg$u"))
#define GCC_YSEG
#else

View file

@ -357,7 +357,7 @@ fixed_t DBaseDecal::GetRealZ (const side_t *wall) const
void DBaseDecal::CalcFracPos (side_t *wall, fixed_t x, fixed_t y)
{
line_t *line = line = wall->linedef;
line_t *line = wall->linedef;
vertex_t *v1, *v2;
if (line->sidedef[0] == wall)
@ -390,7 +390,7 @@ void DBaseDecal::CalcFracPos (side_t *wall, fixed_t x, fixed_t y)
static void GetWallStuff (side_t *wall, vertex_t *&v1, fixed_t &ldx, fixed_t &ldy)
{
line_t *line = line = wall->linedef;
line_t *line = wall->linedef;
if (line->sidedef[0] == wall)
{
v1 = line->v1;
@ -412,7 +412,7 @@ static fixed_t Length (fixed_t dx, fixed_t dy)
static side_t *NextWall (const side_t *wall)
{
line_t *line = line = wall->linedef;;
line_t *line = wall->linedef;;
if (line->sidedef[0] == wall)
{

View file

@ -25,7 +25,7 @@ enum
MORPH_UNDOBYDEATHSAVES = 0x00000800, // Actor (if unmorphed when killed) regains their health and doesn't die
};
struct PClass;
class PClass;
class AActor;
class player_t;
class AMorphedMonster;

View file

@ -39,9 +39,8 @@
#include "m_fixed.h"
#include "c_dispatch.h"
#include "d_net.h"
#include "gi.h"
#include "vm.h"
#include "actor.h"
#include "r_state.h"
#include "i_system.h"
@ -52,6 +51,21 @@
extern void LoadActors ();
bool FState::CallAction(AActor *self, AActor *stateowner, StateCallData *statecall)
{
if (ActionFunc != NULL)
{
//ActionFunc(self, stateowner, this, ParameterIndex-1, statecall);
VMFrameStack stack;
VMValue params[5] = { self, stateowner, this, ParameterIndex - 1, VMValue(statecall, ATAG_STATE) };
stack.Call(ActionFunc, params, countof(params), NULL, 0, NULL);
return true;
}
else
{
return false;
}
}
//==========================================================================
//

View file

@ -43,6 +43,7 @@
#include "dobject.h"
#include "doomdef.h"
#include "vm.h"
const BYTE SF_FULLBRIGHT = 0x40;
@ -60,7 +61,7 @@ struct FState
BYTE Frame;
BYTE DefineFlags; // Unused byte so let's use it during state creation.
FState *NextState;
actionf_p ActionFunc;
VMFunction *ActionFunc;
int ParameterIndex;
inline int GetFrame() const
@ -93,29 +94,20 @@ struct FState
}
void SetAction(PSymbolActionFunction *func, bool setdefaultparams = true)
{
#if 0
if (func != NULL)
{
ActionFunc = func->Function;
if (setdefaultparams) ParameterIndex = func->defaultparameterindex+1;
}
else
#endif
{
ActionFunc = NULL;
if (setdefaultparams) ParameterIndex = 0;
}
}
inline bool CallAction(AActor *self, AActor *stateowner, StateCallData *statecall = NULL)
{
if (ActionFunc != NULL)
{
ActionFunc(self, stateowner, this, ParameterIndex-1, statecall);
return true;
}
else
{
return false;
}
}
bool CallAction(AActor *self, AActor *stateowner, StateCallData *statecall = NULL);
static const PClass *StaticFindStateOwner (const FState *state);
static const PClass *StaticFindStateOwner (const FState *state, const FActorInfo *info);
};

View file

@ -52,17 +52,17 @@
void cht_DoCheat (player_t *player, int cheat)
{
static const PClass *BeholdPowers[9] =
static const PClass *const *BeholdPowers[9] =
{
RUNTIME_CLASS(APowerInvulnerable),
RUNTIME_CLASS(APowerStrength),
RUNTIME_CLASS(APowerInvisibility),
RUNTIME_CLASS(APowerIronFeet),
&RUNTIME_CLASS(APowerInvulnerable),
&RUNTIME_CLASS(APowerStrength),
&RUNTIME_CLASS(APowerInvisibility),
&RUNTIME_CLASS(APowerIronFeet),
NULL, // MapRevealer
RUNTIME_CLASS(APowerLightAmp),
RUNTIME_CLASS(APowerShadow),
RUNTIME_CLASS(APowerMask),
RUNTIME_CLASS(APowerTargeter)
&RUNTIME_CLASS(APowerLightAmp),
&RUNTIME_CLASS(APowerShadow),
&RUNTIME_CLASS(APowerMask),
&RUNTIME_CLASS(APowerTargeter)
};
const PClass *type;
AInventory *item;
@ -248,12 +248,12 @@ void cht_DoCheat (player_t *player, int cheat)
}
else if (player->mo != NULL && player->health >= 0)
{
item = player->mo->FindInventory (BeholdPowers[i]);
item = player->mo->FindInventory (*BeholdPowers[i]);
if (item == NULL)
{
if (i != 0)
{
player->mo->GiveInventoryType (BeholdPowers[i]);
player->mo->GiveInventoryType (*BeholdPowers[i]);
if (cheat == CHT_BEHOLDS)
{
P_GiveBody (player->mo, -100);

View file

@ -29,7 +29,7 @@
// [RH] Functions that actually perform the cheating
class player_t;
struct PClass;
class PClass;
void cht_DoCheat (player_t *player, int cheat);
void cht_Give (player_t *player, const char *item, int amount=1);
void cht_Take (player_t *player, const char *item, int amount=1);

View file

@ -624,11 +624,11 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec)
int sidenum = int(intptr_t(lines[linenum].sidedef[1]));
if (bsec->floorstat & 64)
{ // floor is aligned to first wall
R_AlignFlat (linenum, sidenum == (DWORD)bsec->wallptr, 0);
R_AlignFlat (linenum, (DWORD)sidenum == (DWORD)bsec->wallptr, 0);
}
if (bsec->ceilingstat & 64)
{ // ceiling is aligned to first wall
R_AlignFlat (linenum, sidenum == (DWORD)bsec->wallptr, 0);
R_AlignFlat (linenum, (DWORD)sidenum == (DWORD)bsec->wallptr, 0);
}
}
for(i = 0; i < numsides; i++)

View file

@ -6,7 +6,7 @@
struct sector_t;
class AActor;
class AInventory;
struct PClass;
class PClass;
enum dirtype_t

View file

@ -2504,19 +2504,19 @@ FUNC(LS_SetPlayerProperty)
// Add or remove a power
if (arg2 >= PROP_INVULNERABILITY && arg2 <= PROP_SPEED)
{
static const PClass *powers[11] =
static const PClass * const *powers[11] =
{
RUNTIME_CLASS(APowerInvulnerable),
RUNTIME_CLASS(APowerStrength),
RUNTIME_CLASS(APowerInvisibility),
RUNTIME_CLASS(APowerIronFeet),
&RUNTIME_CLASS(APowerInvulnerable),
&RUNTIME_CLASS(APowerStrength),
&RUNTIME_CLASS(APowerInvisibility),
&RUNTIME_CLASS(APowerIronFeet),
NULL, // MapRevealer
RUNTIME_CLASS(APowerLightAmp),
RUNTIME_CLASS(APowerWeaponLevel2),
RUNTIME_CLASS(APowerFlight),
&RUNTIME_CLASS(APowerLightAmp),
&RUNTIME_CLASS(APowerWeaponLevel2),
&RUNTIME_CLASS(APowerFlight),
NULL,
NULL,
RUNTIME_CLASS(APowerSpeed)
&RUNTIME_CLASS(APowerSpeed)
};
int power = arg2 - PROP_INVULNERABILITY;
@ -2531,7 +2531,7 @@ FUNC(LS_SetPlayerProperty)
{ // Give power to activator
if (power != 4)
{
APowerup *item = static_cast<APowerup*>(it->GiveInventoryType (powers[power]));
APowerup *item = static_cast<APowerup*>(it->GiveInventoryType (*powers[power]));
if (item != NULL && power == 0) item->BlendColor = INVERSECOLOR;
}
else if (it->player - players == consoleplayer)
@ -2543,7 +2543,7 @@ FUNC(LS_SetPlayerProperty)
{ // Take power from activator
if (power != 4)
{
AInventory *item = it->FindInventory (powers[power]);
AInventory *item = it->FindInventory (*powers[power]);
if (item != NULL)
{
item->Destroy ();
@ -2568,7 +2568,7 @@ FUNC(LS_SetPlayerProperty)
{ // Give power
if (power != 4)
{
players[i].mo->GiveInventoryType (powers[power]);
players[i].mo->GiveInventoryType (*powers[power]);
}
else if (i == consoleplayer)
{
@ -2579,7 +2579,7 @@ FUNC(LS_SetPlayerProperty)
{ // Take power
if (power != 4)
{
AInventory *item = players[i].mo->FindInventory (powers[power]);
AInventory *item = players[i].mo->FindInventory (*powers[power]);
if (item != NULL)
{
item->Destroy ();

View file

@ -4906,7 +4906,7 @@ msecnode_t *P_AddSecnode (sector_t *s, AActor *thing, msecnode_t *nextnode)
if (s == 0)
{
I_FatalError ("AddSecnode of 0 for %s\n", thing->_StaticType.TypeName.GetChars());
I_FatalError ("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars());
}
node = nextnode;

View file

@ -1332,7 +1332,7 @@ static void P_SpawnScrollers(void)
if (special != 0)
{
int max = LineSpecialsInfo[special] != NULL ? LineSpecialsInfo[special]->map_args : countof(l->args);
for (int arg = max; arg < countof(l->args); ++arg)
for (int arg = max; arg < (int)countof(l->args); ++arg)
{
if (l->args[arg] != 0)
{

View file

@ -37,7 +37,7 @@
#include "s_sound.h"
#include "textures/textures.h"
struct PClass;
class PClass;
// This is just a wrapper class so that I don't have to expose FTextureID's implementation
// to anything that doesn't really need it.

View file

@ -140,6 +140,7 @@ void STACK_ARGS call_terms ()
static void FinalGC()
{
GC::FinalGC = true;
Args = NULL;
GC::FullGC();
}

View file

@ -7,7 +7,7 @@ class FBitmap;
struct FRemapTable;
struct FCopyInfo;
class FScanner;
struct PClass;
class PClass;
class FArchive;
// Texture IDs

View file

@ -243,10 +243,9 @@ enum EDefinitionType
};
#if defined(_MSC_VER)
#pragma data_seg(".areg$u")
#pragma data_seg(".greg$u")
#pragma data_seg(".mreg$u")
#pragma data_seg()
#pragma section(".areg$u",read)
#pragma section(".greg$u",read)
#pragma section(".mreg$u",read)
#define MSVC_ASEG __declspec(allocate(".areg$u"))
#define GCC_ASEG
@ -283,7 +282,7 @@ struct FPropertyInfo
{
const char *name;
const char *params;
const PClass *cls;
const PClass * const *cls;
PropHandler Handler;
int category;
};
@ -292,7 +291,7 @@ struct FVariableInfo
{
const char *name;
intptr_t address;
const PClass *owner;
const PClass * const *owner;
};
@ -304,14 +303,14 @@ int MatchString (const char *in, const char **strings);
#define DEFINE_PROPERTY_BASE(name, paramlist, clas, cat) \
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, FActorInfo *info, Baggage &bag, FPropParam *params); \
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
{ #name, #paramlist, RUNTIME_CLASS(A##clas), (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
{ #name, #paramlist, &RUNTIME_CLASS(A##clas), (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
MSVC_PSEG FPropertyInfo *infoptr_##name##_##paramlist##_##clas GCC_PSEG = &Prop_##name##_##paramlist##_##clas; \
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, FActorInfo *info, Baggage &bag, FPropParam *params)
#define DEFINE_PREFIXED_PROPERTY_BASE(prefix, name, paramlist, clas, cat) \
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, FActorInfo *info, Baggage &bag, FPropParam *params); \
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
{ #prefix"."#name, #paramlist, RUNTIME_CLASS(A##clas), (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
{ #prefix"."#name, #paramlist, &RUNTIME_CLASS(A##clas), (PropHandler)Handler_##name##_##paramlist##_##clas, cat }; \
MSVC_PSEG FPropertyInfo *infoptr_##name##_##paramlist##_##clas GCC_PSEG = &Prop_##name##_##paramlist##_##clas; \
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, FActorInfo *info, Baggage &bag, FPropParam *params)
@ -340,16 +339,12 @@ int MatchString (const char *in, const char **strings);
int var = params[(no)+1].i== 0? params[(no)+2].i : V_GetColor(NULL, params[(no)+2].s);
#define DEFINE_GLOBAL_VARIABLE(name) \
static FVariableInfo GlobalDef__##name = { #name, intptr_t(&name), NULL }; \
MSVC_MSEG FVariableInfo *infoptr_GlobalDef__##name GCC_MSEG = &GlobalDef__##name;
#define DEFINE_MEMBER_VARIABLE(name, cls) \
static FVariableInfo GlobalDef__##name = { #name, myoffsetof(cls, name), RUNTIME_CLASS(cls) }; \
static FVariableInfo GlobalDef__##name = { #name, myoffsetof(cls, name), &RUNTIME_CLASS(cls) }; \
MSVC_MSEG FVariableInfo *infoptr_GlobalDef__##name GCC_MSEG = &GlobalDef__##name;
#define DEFINE_MEMBER_VARIABLE_ALIAS(name, alias, cls) \
static FVariableInfo GlobalDef__##name = { #name, myoffsetof(cls, alias), RUNTIME_CLASS(cls) }; \
static FVariableInfo GlobalDef__##name = { #name, myoffsetof(cls, alias), &RUNTIME_CLASS(cls) }; \
MSVC_MSEG FVariableInfo *infoptr_GlobalDef__##name GCC_MSEG = &GlobalDef__##name;

View file

@ -311,12 +311,12 @@ static FFlagDef PlayerPawnFlags[] =
DEFINE_FLAG(PPF, NOTHRUSTWHENINVUL, APlayerPawn, PlayerFlags),
};
static const struct FFlagList { const PClass *Type; FFlagDef *Defs; int NumDefs; } FlagLists[] =
static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; } FlagLists[] =
{
{ RUNTIME_CLASS(AActor), ActorFlags, countof(ActorFlags) },
{ RUNTIME_CLASS(AInventory), InventoryFlags, countof(InventoryFlags) },
{ RUNTIME_CLASS(AWeapon), WeaponFlags, countof(WeaponFlags) },
{ RUNTIME_CLASS(APlayerPawn), PlayerPawnFlags,countof(PlayerPawnFlags) },
{ &RUNTIME_CLASS(AActor), ActorFlags, countof(ActorFlags) },
{ &RUNTIME_CLASS(AInventory), InventoryFlags, countof(InventoryFlags) },
{ &RUNTIME_CLASS(AWeapon), WeaponFlags, countof(WeaponFlags) },
{ &RUNTIME_CLASS(APlayerPawn), PlayerPawnFlags,countof(PlayerPawnFlags) },
};
#define NUM_FLAG_LISTS (countof(FlagLists))
@ -364,7 +364,7 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2)
{ // Search all lists
for (i = 0; i < NUM_FLAG_LISTS; ++i)
{
if (type->IsDescendantOf (FlagLists[i].Type))
if (type->IsDescendantOf (*FlagLists[i].Type))
{
def = FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part1);
if (def != NULL)
@ -378,9 +378,9 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2)
{ // Search just the named list
for (i = 0; i < NUM_FLAG_LISTS; ++i)
{
if (stricmp (FlagLists[i].Type->TypeName.GetChars(), part1) == 0)
if (stricmp ((*FlagLists[i].Type)->TypeName.GetChars(), part1) == 0)
{
if (type->IsDescendantOf (FlagLists[i].Type))
if (type->IsDescendantOf (*FlagLists[i].Type))
{
return FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part2);
}
@ -403,7 +403,7 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2)
const char *GetFlagName(int flagnum, int flagoffset)
{
for(int i=0; i<countof(ActorFlags); i++)
for(size_t i = 0; i < countof(ActorFlags); i++)
{
if (ActorFlags[i].flagbit == flagnum && ActorFlags[i].structoffset == flagoffset)
{
@ -489,8 +489,8 @@ FVariableInfo *FindVariable(const char * string, const PClass *cls)
int mid = (min + max) / 2;
int lexval;
if (cls < variables[mid]->owner) lexval = -1;
else if (cls > variables[mid]->owner) lexval = 1;
if (cls < *variables[mid]->owner) lexval = -1;
else if (cls > *variables[mid]->owner) lexval = 1;
else lexval = stricmp (string, variables[mid]->name);
if (lexval == 0)

View file

@ -50,9 +50,6 @@
#include "doomstat.h"
#include "thingdef_exp.h"
int testglobalvar = 1337; // just for having one global variable to test with
DEFINE_GLOBAL_VARIABLE(testglobalvar)
// Accessible actor member variables
DEFINE_MEMBER_VARIABLE(alpha, AActor)
DEFINE_MEMBER_VARIABLE(angle, AActor)

View file

@ -733,13 +733,13 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag)
if (prop != NULL)
{
if (bag.Info->Class->IsDescendantOf(prop->cls))
if (bag.Info->Class->IsDescendantOf(*prop->cls))
{
ParsePropertyParams(sc, prop, (AActor *)bag.Info->Class->Defaults, bag);
}
else
{
sc.ScriptMessage("\"%s\" requires an actor of type \"%s\"\n", propname.GetChars(), prop->cls->TypeName.GetChars());
sc.ScriptMessage("\"%s\" requires an actor of type \"%s\"\n", propname.GetChars(), (*prop->cls)->TypeName.GetChars());
FScriptPosition::ErrorCounter++;
}
}

View file

@ -262,6 +262,7 @@ static void UnWTS (void)
static void FinalGC()
{
GC::FinalGC = true;
Args = NULL;
GC::FullGC();
}

View file

@ -409,13 +409,12 @@ struct VMValue
Type = REGT_POINTER;
return *this;
}
VMValue &operator=(void *v)
void SetPointer(void *v, VM_UBYTE atag=ATAG_GENERIC)
{
Kill();
a = v;
atag = ATAG_GENERIC;
Type = REGT_POINTER;
return *this;
atag = atag;
Type = atag;
}
void SetNil()
{

View file

@ -540,7 +540,7 @@ begin:
}
if (B & REGT_FINAL)
{
return MIN(numret, a + 1);
return a < numret ? a + 1 : numret;
}
NEXTOP;
OP(RESULT):

View file

@ -99,7 +99,3 @@ const float ATTN_NONE = 0;
const float ATTN_NORM = 1;
const float ATTN_IDLE = 1.001;
const float ATTN_STATIC = 3;
// This is only here to provide one global variable for testing.
native int testglobalvar;