mirror of
https://github.com/ZDoom/Raze.git
synced 2025-03-13 04:24:39 +00:00
- added all parts needed to implement the actor property parser.
Not hooked up yet with the rest of the code, this just adds the needed files in compilable form.
This commit is contained in:
parent
b5a5d24bf4
commit
0398ba4ff0
12 changed files with 1666 additions and 4 deletions
|
@ -1012,6 +1012,9 @@ set (PCH_SOURCES
|
|||
build/src/mdsprite.cpp
|
||||
build/src/polymost.cpp
|
||||
|
||||
core/actorinfo.cpp
|
||||
core/zcc_compile_raze.cpp
|
||||
core/thingdef_data.cpp
|
||||
core/actorlist.cpp
|
||||
core/automap.cpp
|
||||
core/cheats.cpp
|
||||
|
|
|
@ -43,7 +43,6 @@ enum
|
|||
MAXWALLSB = 6144,
|
||||
|
||||
MAXVOXELS = 1024,
|
||||
MAXSTATUS = 1024,
|
||||
// Maximum number of component tiles in a multi-psky:
|
||||
MAXSPRITESONSCREEN = 4096,
|
||||
MAXUNIQHUDID = 256, //Extra slots so HUD models can store animation state without messing game sprites
|
||||
|
|
230
source/core/actorinfo.cpp
Normal file
230
source/core/actorinfo.cpp
Normal file
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
** actorinfo.cpp
|
||||
** Keeps track of available actors and their states
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2006 Randy Heit
|
||||
** Copyright 2005-2022 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "actorinfo.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "d_net.h"
|
||||
#include "v_text.h"
|
||||
|
||||
#include "gi.h"
|
||||
#include "coreactor.h"
|
||||
#include "stats.h"
|
||||
#include "types.h"
|
||||
#include "filesystem.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
extern void LoadActors ();
|
||||
|
||||
cycle_t ActionCycles;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// special type for the native ActorInfo. This allows to let this struct
|
||||
// be handled by the generic object constructors for the VM.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class PActorInfo : public PCompoundType
|
||||
{
|
||||
public:
|
||||
PActorInfo()
|
||||
:PCompoundType(sizeof(FActorInfo), alignof(FActorInfo))
|
||||
{
|
||||
}
|
||||
|
||||
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) override
|
||||
{
|
||||
if (base != nullptr) new((uint8_t *)base + offset) FActorInfo;
|
||||
if (special != nullptr)
|
||||
{
|
||||
special->Push(std::make_pair(this, offset));
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeValue(void *addr, const void *def) const override
|
||||
{
|
||||
new(addr) FActorInfo;
|
||||
}
|
||||
|
||||
void DestroyValue(void *addr) const override
|
||||
{
|
||||
FActorInfo *self = (FActorInfo*)addr;
|
||||
self->~FActorInfo();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void AddActorInfo(PClass *cls)
|
||||
{
|
||||
auto type = new PActorInfo;
|
||||
TypeTable.AddType(type, NAME_Actor);
|
||||
cls->AddField("*", type, VARF_Meta);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: StaticInit STATIC
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClassActor::StaticInit()
|
||||
{
|
||||
for (auto cls : AllClasses)
|
||||
{
|
||||
if (cls->IsDescendantOf(RUNTIME_CLASS(DCoreActor)))
|
||||
{
|
||||
AllActorClasses.Push(static_cast<PClassActor*>(cls));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: SetReplacement
|
||||
//
|
||||
// Sets as a replacement class for another class.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool PClassActor::SetReplacement(FName replaceName)
|
||||
{
|
||||
// Check for "replaces"
|
||||
if (replaceName != NAME_None)
|
||||
{
|
||||
// Get actor name
|
||||
PClassActor *replacee = PClass::FindActor(replaceName);
|
||||
|
||||
if (replacee == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (replacee != nullptr)
|
||||
{
|
||||
replacee->ActorInfo()->Replacement = this;
|
||||
ActorInfo()->Replacee = replacee;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: InitializeNativeDefaults
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClassActor::InitializeDefaults()
|
||||
{
|
||||
if (IsDescendantOf(RUNTIME_CLASS(DCoreActor)))
|
||||
{
|
||||
assert(Defaults == nullptr);
|
||||
Defaults = (uint8_t*)M_Malloc(Size);
|
||||
|
||||
ConstructNative(Defaults);
|
||||
// We must unlink the defaults from the class list because it's just a static block of data to the engine.
|
||||
DObject* optr = (DObject*)Defaults;
|
||||
GC::Root = optr->ObjNext;
|
||||
optr->ObjNext = nullptr;
|
||||
optr->SetClass(this);
|
||||
|
||||
// Copy the defaults from the parent but leave the DObject part alone because it contains important data.
|
||||
if (ParentClass->Defaults != nullptr)
|
||||
{
|
||||
memcpy(Defaults + sizeof(DObject), ParentClass->Defaults + sizeof(DObject), ParentClass->Size - sizeof(DObject));
|
||||
if (Size > ParentClass->Size)
|
||||
{
|
||||
memset(Defaults + ParentClass->Size, 0, Size - ParentClass->Size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(Defaults + sizeof(DObject), 0, Size - sizeof(DObject));
|
||||
}
|
||||
|
||||
assert(MetaSize >= ParentClass->MetaSize);
|
||||
if (MetaSize != 0)
|
||||
{
|
||||
Meta = (uint8_t*)M_Malloc(MetaSize);
|
||||
|
||||
// Copy the defaults from the parent but leave the DObject part alone because it contains important data.
|
||||
if (ParentClass->Meta != nullptr)
|
||||
{
|
||||
memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
if (MetaSize > ParentClass->MetaSize)
|
||||
{
|
||||
memset(Meta + ParentClass->MetaSize, 0, MetaSize - ParentClass->MetaSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(Meta, 0, MetaSize);
|
||||
}
|
||||
|
||||
if (MetaSize > 0) memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
else memset(Meta, 0, MetaSize);
|
||||
}
|
||||
}
|
||||
PClass::InitializeDefaults();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: GetReplacement
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PClassActor *PClassActor::GetReplacement()
|
||||
{
|
||||
PClassActor *Replacement = ActorInfo()->Replacement;
|
||||
if (Replacement == nullptr) return this;
|
||||
return Replacement;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: GetReplacee
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PClassActor *PClassActor::GetReplacee()
|
||||
{
|
||||
PClassActor *Replacee = ActorInfo()->Replacee;
|
||||
if (Replacee == nullptr) return this;
|
||||
return Replacee;
|
||||
}
|
||||
|
48
source/core/actorinfo.h
Normal file
48
source/core/actorinfo.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "dobject.h"
|
||||
#include "m_fixed.h"
|
||||
#include "m_random.h"
|
||||
|
||||
class FScanner;
|
||||
class FInternalLightAssociation;
|
||||
|
||||
struct FActorInfo
|
||||
{
|
||||
TArray<FInternalLightAssociation *> LightAssociations;
|
||||
PClassActor *Replacement = nullptr;
|
||||
PClassActor *Replacee = nullptr;
|
||||
int TypeNum = -1;
|
||||
|
||||
FActorInfo() = default;
|
||||
FActorInfo(const FActorInfo & other) = delete;
|
||||
};
|
||||
|
||||
// No objects of this type will be created ever - its only use is to static_cast
|
||||
// PClass to it.
|
||||
class PClassActor : public PClass
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
static void StaticInit ();
|
||||
|
||||
void BuildDefaults();
|
||||
void ApplyDefaults(uint8_t *defaults);
|
||||
bool SetReplacement(FName replaceName);
|
||||
void InitializeDefaults();
|
||||
|
||||
FActorInfo *ActorInfo() const
|
||||
{
|
||||
return (FActorInfo*)Meta;
|
||||
}
|
||||
|
||||
PClassActor *GetReplacement();
|
||||
PClassActor *GetReplacee();
|
||||
|
||||
// For those times when being able to scan every kind of actor is convenient
|
||||
inline static TArray<PClassActor *> AllActorClasses;
|
||||
};
|
||||
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "maptypes.h"
|
||||
#include "build.h"
|
||||
#include "actorinfo.h"
|
||||
|
||||
enum
|
||||
{
|
||||
MAXSTATUS = 1024
|
||||
};
|
||||
|
||||
class DCoreActor : public DObject
|
||||
{
|
||||
|
@ -292,7 +299,6 @@ struct ActorStatList
|
|||
|
||||
extern ActorStatList statList[MAXSTATUS];
|
||||
|
||||
// Iterator wrappers that return an actor pointer, not an index.
|
||||
template<class TActor>
|
||||
class TStatIterator
|
||||
{
|
||||
|
@ -432,3 +438,9 @@ inline void validateTSpriteSize(tspritetype*& tsprite, int& spritesortcnt)
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
inline PClassActor* PClass::FindActor(FName name)
|
||||
{
|
||||
auto cls = FindClass(name);
|
||||
return cls && cls->IsDescendantOf(RUNTIME_CLASS(DCoreActor)) ? static_cast<PClassActor*>(cls) : nullptr;
|
||||
}
|
||||
|
|
|
@ -143,7 +143,6 @@ void G_BuildTiccmd (ticcmd_t *cmd);
|
|||
void D_DoAdvanceDemo (void);
|
||||
|
||||
static void SendSetup (uint32_t playersdetected[MAXNETNODES], uint8_t gotsetup[MAXNETNODES], int len);
|
||||
static void RunScript(uint8_t **stream, AActor *pawn, int snum, int argn, int always);
|
||||
|
||||
int reboundpacket;
|
||||
uint8_t reboundstore[MAX_MSGLEN];
|
||||
|
|
|
@ -366,7 +366,7 @@ inline float Dist2(float x1,float y1,float x2,float y2)
|
|||
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
|
||||
}
|
||||
|
||||
void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata);
|
||||
//void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata);
|
||||
|
||||
extern const float LARGE_VALUE;
|
||||
|
||||
|
|
238
source/core/thingdef.h
Normal file
238
source/core/thingdef.h
Normal file
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
** thingdef.h
|
||||
**
|
||||
** Actor definitions
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2002-2008 Christoph Oelckers
|
||||
** Copyright 2004-2008 Randy Heit
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be
|
||||
** covered by the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or (at
|
||||
** your option) any later version.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __THINGDEF_H
|
||||
#define __THINGDEF_H
|
||||
|
||||
#include "sc_man.h"
|
||||
#include "cmdlib.h"
|
||||
#include "vm.h"
|
||||
#include "dobject.h"
|
||||
#include "coreactor.h"
|
||||
|
||||
|
||||
class FScanner;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A flag descriptor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct FFlagDef
|
||||
{
|
||||
unsigned int flagbit;
|
||||
const char *name;
|
||||
int structoffset;
|
||||
int fieldsize;
|
||||
int varflags;
|
||||
};
|
||||
|
||||
#if 0
|
||||
void FinalizeClass(PClass *cls);
|
||||
FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2, bool strict = false);
|
||||
void HandleDeprecatedFlags(DCoreActor *defaults, PClassActor *info, bool set, int index);
|
||||
bool CheckDeprecatedFlags(DCoreActor *actor, PClassActor *info, int index);
|
||||
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
||||
void ModActorFlag(DCoreActor *actor, FFlagDef *fd, bool set);
|
||||
bool ModActorFlag(DCoreActor *actor, const FString &flagname, bool set, bool printerror = true);
|
||||
INTBOOL CheckActorFlag(DCoreActor *actor, FFlagDef *fd);
|
||||
INTBOOL CheckActorFlag(DCoreActor *owner, const char *flagname, bool printerror = true);
|
||||
#endif
|
||||
|
||||
#define FLAG_NAME(flagnum, flagvar) GetFlagName(flagnum, myoffsetof(DCoreActor, flagvar))
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// State parser
|
||||
//
|
||||
//==========================================================================
|
||||
class FxExpression;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Extra info maintained while defining an actor.
|
||||
//
|
||||
//==========================================================================
|
||||
struct FDropItem;
|
||||
|
||||
struct Baggage
|
||||
{
|
||||
PNamespace *Namespace;
|
||||
PClassActor *Info;
|
||||
int Lumpnum;
|
||||
VersionInfo Version;
|
||||
|
||||
FScriptPosition ScriptPosition;
|
||||
};
|
||||
|
||||
inline void ResetBaggage (Baggage *bag, PClassActor *stateclass)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Property parser
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod);
|
||||
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type);
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
DEPF_UNUSED = 0,
|
||||
DEPF_FIREDAMAGE = 1,
|
||||
DEPF_ICEDAMAGE = 2,
|
||||
DEPF_LOWGRAVITY = 3,
|
||||
DEPF_LONGMELEERANGE = 4,
|
||||
DEPF_SHORTMISSILERANGE = 5,
|
||||
DEPF_PICKUPFLASH = 6,
|
||||
DEPF_QUARTERGRAVITY = 7,
|
||||
DEPF_FIRERESIST = 8,
|
||||
DEPF_HERETICBOUNCE = 9,
|
||||
DEPF_HEXENBOUNCE = 10,
|
||||
DEPF_DOOMBOUNCE = 11,
|
||||
DEPF_INTERHUBSTRIP = 12,
|
||||
DEPF_HIGHERMPROB = 13,
|
||||
};
|
||||
|
||||
// Types of old style decorations
|
||||
enum EDefinitionType
|
||||
{
|
||||
DEF_Decoration,
|
||||
DEF_BreakableDecoration,
|
||||
DEF_Pickup,
|
||||
DEF_Projectile,
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma section(SECTION_GREG,read)
|
||||
|
||||
#define MSVC_PSEG __declspec(allocate(SECTION_GREG))
|
||||
#define GCC_PSEG
|
||||
#else
|
||||
#define MSVC_PSEG
|
||||
#define GCC_PSEG __attribute__((section(SECTION_GREG))) __attribute__((used))
|
||||
#endif
|
||||
|
||||
|
||||
union FPropParam
|
||||
{
|
||||
int i;
|
||||
double d;
|
||||
const char *s;
|
||||
FxExpression *exp;
|
||||
};
|
||||
|
||||
typedef void (*PropHandler)(DCoreActor *defaults, PClassActor *info, Baggage &bag, FPropParam *params);
|
||||
|
||||
enum ECategory
|
||||
{
|
||||
CAT_PROPERTY, // Inheritable property
|
||||
CAT_INFO // non-inheritable info (spawn ID, Doomednum, game filter, conversation ID, not usable in ZScript)
|
||||
};
|
||||
|
||||
struct FPropertyInfo
|
||||
{
|
||||
const char *name;
|
||||
const char *params;
|
||||
const char *clsname;
|
||||
PropHandler Handler;
|
||||
int category;
|
||||
};
|
||||
|
||||
FPropertyInfo *FindProperty(const char * string);
|
||||
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, PClassActor *info, Baggage &bag, FPropParam *params); \
|
||||
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
|
||||
{ #name, #paramlist, #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, PClassActor *info, Baggage &bag, FPropParam *params)
|
||||
|
||||
#define DEFINE_PREFIXED_PROPERTY_BASE(prefix, name, paramlist, clas, cat) \
|
||||
static void Handler_##name##_##paramlist##_##clas(A##clas *defaults, PClassActor *info, Baggage &bag, FPropParam *params); \
|
||||
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
|
||||
{ #prefix"."#name, #paramlist, #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, PClassActor *info, Baggage &bag, FPropParam *params)
|
||||
|
||||
#define DEFINE_PREFIXED_SCRIPTED_PROPERTY_BASE(prefix, name, paramlist, clas, cat) \
|
||||
static void Handler_##name##_##paramlist##_##clas(DCoreActor *defaults, PClassActor *info, Baggage &bag, FPropParam *params); \
|
||||
static FPropertyInfo Prop_##name##_##paramlist##_##clas = \
|
||||
{ #prefix"."#name, #paramlist, #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(DCoreActor *defaults, PClassActor *info, Baggage &bag, FPropParam *params)
|
||||
|
||||
|
||||
#define DEFINE_PROPERTY(name, paramlist, clas) DEFINE_PROPERTY_BASE(name, paramlist, clas, CAT_PROPERTY)
|
||||
#define DEFINE_INFO_PROPERTY(name, paramlist, clas) DEFINE_PROPERTY_BASE(name, paramlist, clas, CAT_INFO)
|
||||
|
||||
#define DEFINE_CLASS_PROPERTY(name, paramlist, clas) DEFINE_PREFIXED_SCRIPTED_PROPERTY_BASE(clas, name, paramlist, clas, CAT_PROPERTY)
|
||||
#define DEFINE_CLASS_PROPERTY_PREFIX(prefix, name, paramlist, clas) DEFINE_PREFIXED_SCRIPTED_PROPERTY_BASE(prefix, name, paramlist, clas, CAT_PROPERTY)
|
||||
|
||||
#define PROP_PARM_COUNT (params[0].i)
|
||||
|
||||
#define PROP_STRING_PARM(var, no) \
|
||||
const char *var = params[(no)+1].s;
|
||||
|
||||
#define PROP_EXP_PARM(var, no) \
|
||||
FxExpression *var = params[(no)+1].exp;
|
||||
|
||||
#define PROP_INT_PARM(var, no) \
|
||||
int var = params[(no)+1].i;
|
||||
|
||||
#define PROP_FLOAT_PARM(var, no) \
|
||||
float var = float(params[(no)+1].d);
|
||||
|
||||
#define PROP_DOUBLE_PARM(var, no) \
|
||||
double var = params[(no)+1].d;
|
||||
|
||||
#define PROP_COLOR_PARM(var, no, scriptpos) \
|
||||
int var = params[(no)+1].i== 0? params[(no)+2].i : V_GetColor(params[(no)+2].s, scriptpos);
|
||||
|
||||
#endif
|
372
source/core/thingdef_data.cpp
Normal file
372
source/core/thingdef_data.cpp
Normal file
|
@ -0,0 +1,372 @@
|
|||
/*
|
||||
** thingdef_data.cpp
|
||||
**
|
||||
** DECORATE data tables
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2002-2008 Christoph Oelckers
|
||||
** Copyright 2004-2008 Randy Heit
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be
|
||||
** covered by the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or (at
|
||||
** your option) any later version.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "thingdef.h"
|
||||
#include "gi.h"
|
||||
#include "gstrings.h"
|
||||
#include "v_font.h"
|
||||
#include "menu.h"
|
||||
#include "types.h"
|
||||
#include "dictionary.h"
|
||||
#include "savegamehelp.h"
|
||||
|
||||
static TArray<FPropertyInfo*> properties;
|
||||
static TArray<AFuncDesc> AFTable;
|
||||
static TArray<FieldDesc> FieldTable;
|
||||
extern int BackbuttonTime;
|
||||
extern float BackbuttonAlpha;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// List of all flags
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
// [RH] Keep GCC quiet by not using offsetof on Actor types.
|
||||
#define DEFINE_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native }
|
||||
#define DEFINE_PROTECTED_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_ReadOnly|VARF_InternalAccess }
|
||||
#define DEFINE_FLAG2(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native }
|
||||
#define DEFINE_FLAG2_DEPRECATED(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_Deprecated }
|
||||
#define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1, 0, true }
|
||||
#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[]=
|
||||
{
|
||||
DEFINE_FLAG2(CSTAT2_SPRITE_NOFIND, BLOCK, DCoreActor, spr.cstat2)
|
||||
// todo
|
||||
};
|
||||
|
||||
|
||||
static FFlagDef ActorFlagDefs[]=
|
||||
{
|
||||
DEFINE_FLAG2(CSTAT_SPRITE_BLOCK, BLOCK, DCoreActor, spr.cstat),
|
||||
DEFINE_FLAG2(CSTAT_SPRITE_TRANSLUCENT, TRANSLUCENT, DCoreActor, spr.cstat),
|
||||
DEFINE_FLAG2(CSTAT_SPRITE_XFLIP, XFLIP, DCoreActor, spr.cstat),
|
||||
DEFINE_FLAG2(CSTAT_SPRITE_YFLIP, YFLIP, DCoreActor, spr.cstat),
|
||||
DEFINE_FLAG2(CSTAT_SPRITE_ONE_SIDE, ONE_SIDE, DCoreActor, spr.cstat),
|
||||
DEFINE_FLAG2(CSTAT_SPRITE_YCENTER, YCENTER, DCoreActor, spr.cstat),
|
||||
DEFINE_FLAG2(CSTAT_SPRITE_BLOCK_HITSCAN, BLOCK_HITSCAN, DCoreActor, spr.cstat),
|
||||
DEFINE_FLAG2(CSTAT_SPRITE_INVISIBLE, INVISIBLE, DCoreActor, spr.cstat),
|
||||
DEFINE_FLAG2(CSTAT2_SPRITE_MAPPED, MAPPED, DCoreActor, spr.cstat2),
|
||||
DEFINE_FLAG2(CSTAT2_SPRITE_NOSHADOW, NOSHADOW, DCoreActor, spr.cstat2),
|
||||
DEFINE_FLAG2(CSTAT2_SPRITE_DECAL, DECAL, DCoreActor, spr.cstat2),
|
||||
// todo: game specific flags
|
||||
};
|
||||
|
||||
|
||||
static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; int Use; } FlagLists[] =
|
||||
{
|
||||
{ &RUNTIME_CLASS_CASTLESS(DCoreActor), ActorFlagDefs, countof(ActorFlagDefs), 3 }, // -1 to account for the terminator
|
||||
{ &RUNTIME_CLASS_CASTLESS(DCoreActor), InternalActorFlagDefs, countof(InternalActorFlagDefs), 2 },
|
||||
};
|
||||
#define NUM_FLAG_LISTS (countof(FlagLists))
|
||||
|
||||
static FFlagDef forInternalFlags;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Find a flag by name using a binary search
|
||||
//
|
||||
//==========================================================================
|
||||
static FFlagDef *FindFlag (FFlagDef *flags, int numflags, const char *flag)
|
||||
{
|
||||
int min = 0, max = numflags - 1;
|
||||
|
||||
while (min <= max)
|
||||
{
|
||||
int mid = (min + max) / 2;
|
||||
int lexval = stricmp (flag, flags[mid].name);
|
||||
if (lexval == 0)
|
||||
{
|
||||
return &flags[mid];
|
||||
}
|
||||
else if (lexval > 0)
|
||||
{
|
||||
min = mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = mid - 1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Finds a flag that may have a qualified name
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2, bool strict)
|
||||
{
|
||||
|
||||
if (part2 == nullptr)
|
||||
{
|
||||
FStringf internalname("@flagdef@%s", part1);
|
||||
FName name(internalname, true);
|
||||
if (name != NAME_None)
|
||||
{
|
||||
auto field = dyn_cast<PPropFlag>(type->FindSymbol(name, true));
|
||||
if (field != nullptr && (!strict || !field->decorateOnly))
|
||||
{
|
||||
forInternalFlags.fieldsize = 4;
|
||||
forInternalFlags.name = "";
|
||||
forInternalFlags.flagbit = field->Offset? 1 << field->bitval : field->bitval;
|
||||
forInternalFlags.structoffset = field->Offset? (int)field->Offset->Offset : -1;
|
||||
forInternalFlags.varflags = field->Offset == nullptr && field->bitval > 0? VARF_Deprecated : 0;
|
||||
return &forInternalFlags;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FStringf internalname("@flagdef@%s.%s", part1, part2);
|
||||
FName name(internalname, true);
|
||||
if (name != NAME_None)
|
||||
{
|
||||
auto field = dyn_cast<PPropFlag>(type->FindSymbol(name, true));
|
||||
if (field != nullptr)
|
||||
{
|
||||
forInternalFlags.fieldsize = 4;
|
||||
forInternalFlags.name = "";
|
||||
forInternalFlags.flagbit = field->Offset ? 1 << field->bitval : field->bitval;
|
||||
forInternalFlags.structoffset = field->Offset ? (int)field->Offset->Offset : -1;
|
||||
forInternalFlags.varflags = field->Offset == nullptr && field->bitval > 0? VARF_Deprecated : 0;
|
||||
return &forInternalFlags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not found. Try the internal flag definitions.
|
||||
|
||||
|
||||
FFlagDef *def;
|
||||
|
||||
if (part2 == NULL)
|
||||
{ // Search all lists
|
||||
int max = strict ? 2 : NUM_FLAG_LISTS;
|
||||
for (int i = 0; i < max; ++i)
|
||||
{
|
||||
if ((FlagLists[i].Use & 1) && type->IsDescendantOf (*FlagLists[i].Type))
|
||||
{
|
||||
def = FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part1);
|
||||
if (def != NULL)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Search just the named list
|
||||
for (size_t i = 0; i < NUM_FLAG_LISTS; ++i)
|
||||
{
|
||||
if (stricmp ((*FlagLists[i].Type)->TypeName.GetChars(), part1) == 0)
|
||||
{
|
||||
if (type->IsDescendantOf (*FlagLists[i].Type))
|
||||
{
|
||||
return FindFlag (FlagLists[i].Defs, FlagLists[i].NumDefs, part2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Gets the name of an actor flag
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const char *GetFlagName(unsigned int flagnum, int flagoffset)
|
||||
{
|
||||
for(size_t i = 0; i < countof(ActorFlagDefs); i++)
|
||||
{
|
||||
if (ActorFlagDefs[i].flagbit == flagnum && ActorFlagDefs[i].structoffset == flagoffset)
|
||||
{
|
||||
return ActorFlagDefs[i].name;
|
||||
}
|
||||
}
|
||||
return "(unknown)"; // return something printable
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Find a property by name using a binary search
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FPropertyInfo *FindProperty(const char * string)
|
||||
{
|
||||
int min = 0, max = properties.Size()-1;
|
||||
|
||||
while (min <= max)
|
||||
{
|
||||
int mid = (min + max) / 2;
|
||||
int lexval = stricmp (string, properties[mid]->name);
|
||||
if (lexval == 0)
|
||||
{
|
||||
return properties[mid];
|
||||
}
|
||||
else if (lexval > 0)
|
||||
{
|
||||
min = mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = mid - 1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sorting helpers
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int flagcmp (const void * a, const void * b)
|
||||
{
|
||||
return stricmp( ((FFlagDef*)a)->name, ((FFlagDef*)b)->name);
|
||||
}
|
||||
|
||||
static int propcmp(const void * a, const void * b)
|
||||
{
|
||||
return stricmp( (*(FPropertyInfo**)a)->name, (*(FPropertyInfo**)b)->name);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Initialization
|
||||
//
|
||||
//==========================================================================
|
||||
void InitImports();
|
||||
|
||||
void InitThingdef()
|
||||
{
|
||||
// Some native types need size and serialization information added before the scripts get compiled.
|
||||
//auto secplanestruct = NewStruct("Secplane", nullptr, true);
|
||||
//secplanestruct->Size = sizeof(secplane_t);
|
||||
//secplanestruct->Align = alignof(secplane_t);
|
||||
|
||||
auto sectorstruct = NewStruct("Sector", nullptr, true);
|
||||
sectorstruct->Size = sizeof(sectortype);
|
||||
sectorstruct->Align = alignof(sectortype);
|
||||
NewPointer(sectorstruct, false)->InstallHandlers(
|
||||
[](FSerializer &ar, const char *key, const void *addr)
|
||||
{
|
||||
ar(key, *(sectortype **)addr);
|
||||
},
|
||||
[](FSerializer &ar, const char *key, void *addr)
|
||||
{
|
||||
Serialize<sectortype>(ar, key, *(sectortype **)addr, nullptr);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
auto linestruct = NewStruct("Wall", nullptr, true);
|
||||
linestruct->Size = sizeof(walltype);
|
||||
linestruct->Align = alignof(walltype);
|
||||
NewPointer(linestruct, false)->InstallHandlers(
|
||||
[](FSerializer &ar, const char *key, const void *addr)
|
||||
{
|
||||
ar(key, *(walltype **)addr);
|
||||
},
|
||||
[](FSerializer &ar, const char *key, void *addr)
|
||||
{
|
||||
Serialize<walltype>(ar, key, *(walltype **)addr, nullptr);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
auto sidestruct = NewStruct("TSprite", nullptr, true);
|
||||
sidestruct->Size = sizeof(tspritetype);
|
||||
sidestruct->Align = alignof(tspritetype);
|
||||
// This may not be serialized
|
||||
|
||||
// Sort the flag lists
|
||||
for (size_t i = 0; i < NUM_FLAG_LISTS; ++i)
|
||||
{
|
||||
qsort (FlagLists[i].Defs, FlagLists[i].NumDefs, sizeof(FFlagDef), flagcmp);
|
||||
}
|
||||
|
||||
// Create a sorted list of properties
|
||||
if (properties.Size() == 0)
|
||||
{
|
||||
AutoSegs::Properties.ForEach([](FPropertyInfo* propertyInfo)
|
||||
{
|
||||
properties.Push(propertyInfo);
|
||||
});
|
||||
|
||||
properties.ShrinkToFit();
|
||||
qsort(&properties[0], properties.Size(), sizeof(properties[0]), propcmp);
|
||||
}
|
||||
|
||||
InitImports();
|
||||
}
|
||||
|
||||
void SynthesizeFlagFields()
|
||||
{
|
||||
// synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them.
|
||||
for (auto &fl : FlagLists)
|
||||
{
|
||||
auto cls = const_cast<PClass*>(*fl.Type);
|
||||
if (fl.Use & 2)
|
||||
{
|
||||
for (int i = 0; i < fl.NumDefs; i++)
|
||||
{
|
||||
if (fl.Defs[i].structoffset > 0) // skip the deprecated entries in this list
|
||||
{
|
||||
cls->VMType->AddNativeField(FStringf("b%s", fl.Defs[i].name), (fl.Defs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), fl.Defs[i].structoffset, fl.Defs[i].varflags, fl.Defs[i].flagbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
728
source/core/zcc_compile_raze.cpp
Normal file
728
source/core/zcc_compile_raze.cpp
Normal file
|
@ -0,0 +1,728 @@
|
|||
/*
|
||||
** zcc_compile_raze.cpp
|
||||
**
|
||||
** contains the Raze specific parts of the script parser, i.e.
|
||||
** actor property definitions and associated content.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2016-2022 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "coreactor.h"
|
||||
#include "c_console.h"
|
||||
#include "filesystem.h"
|
||||
#include "zcc_parser.h"
|
||||
#include "zcc-parse.h"
|
||||
#include "zcc_compile_raze.h"
|
||||
#include "v_text.h"
|
||||
#include "v_video.h"
|
||||
#include "actorinfo.h"
|
||||
#include "thingdef.h"
|
||||
|
||||
|
||||
bool isActor(PContainerType *type);
|
||||
void AddActorInfo(PClass *cls);
|
||||
int GetIntConst(FxExpression* ex, FCompileContext& ctx);
|
||||
double GetFloatConst(FxExpression* ex, FCompileContext& ctx);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: Compile
|
||||
//
|
||||
// Compile everything defined at this level.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int ZCCRazeCompiler::Compile()
|
||||
{
|
||||
CreateClassTypes();
|
||||
CreateStructTypes();
|
||||
CompileAllConstants();
|
||||
CompileAllFields();
|
||||
CompileAllProperties();
|
||||
InitDefaults();
|
||||
InitFunctions();
|
||||
return FScriptPosition::ErrorCounter;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: CompileAllProperties
|
||||
//
|
||||
// builds the property lists of all actor classes
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCRazeCompiler::CompileAllProperties()
|
||||
{
|
||||
for (auto c : Classes)
|
||||
{
|
||||
if (c->Properties.Size() > 0)
|
||||
CompileProperties(c->ClassType(), c->Properties, c->Type()->TypeName);
|
||||
|
||||
if (c->FlagDefs.Size() > 0)
|
||||
CompileFlagDefs(c->ClassType(), c->FlagDefs, c->Type()->TypeName);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: CompileProperties
|
||||
//
|
||||
// builds the internal structure of a single class or struct
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool ZCCRazeCompiler::CompileProperties(PClass *type, TArray<ZCC_Property *> &Properties, FName prefix)
|
||||
{
|
||||
if (!type->IsDescendantOf(RUNTIME_CLASS(DCoreActor)))
|
||||
{
|
||||
Error(Properties[0], "Properties can only be defined for actors");
|
||||
return false;
|
||||
}
|
||||
for(auto p : Properties)
|
||||
{
|
||||
TArray<PField *> fields;
|
||||
ZCC_Identifier *id = (ZCC_Identifier *)p->Body;
|
||||
|
||||
if (FName(p->NodeName) == FName("prefix") && fileSystem.GetFileContainer(Lump) == 0)
|
||||
{
|
||||
// only for internal definitions: Allow setting a prefix. This is only for compatiblity with the old DECORATE property parser, but not for general use.
|
||||
prefix = id->Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
auto f = dyn_cast<PField>(type->FindSymbol(id->Id, true));
|
||||
if (f == nullptr)
|
||||
{
|
||||
Error(id, "Variable %s not found in %s", FName(id->Id).GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
fields.Push(f);
|
||||
id = (ZCC_Identifier*)id->SiblingNext;
|
||||
} while (id != p->Body);
|
||||
|
||||
FString qualifiedname;
|
||||
// Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen.
|
||||
// All these will be removed from the symbol table after the compiler finishes to free up the allocated space.
|
||||
FName name = FName(p->NodeName);
|
||||
if (prefix == NAME_None) qualifiedname.Format("@property@%s", name.GetChars());
|
||||
else qualifiedname.Format("@property@%s.%s", prefix.GetChars(), name.GetChars());
|
||||
|
||||
fields.ShrinkToFit();
|
||||
if (!type->VMType->Symbols.AddSymbol(Create<PProperty>(qualifiedname, fields)))
|
||||
{
|
||||
Error(id, "Unable to add property %s to class %s", FName(p->NodeName).GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: CompileProperties
|
||||
//
|
||||
// builds the internal structure of a single class or struct
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool ZCCRazeCompiler::CompileFlagDefs(PClass *type, TArray<ZCC_FlagDef *> &Properties, FName prefix)
|
||||
{
|
||||
if (!type->IsDescendantOf(RUNTIME_CLASS(DCoreActor)))
|
||||
{
|
||||
Error(Properties[0], "Flags can only be defined for actors");
|
||||
return false;
|
||||
}
|
||||
for (auto p : Properties)
|
||||
{
|
||||
PField *field;
|
||||
FName referenced = FName(p->RefName);
|
||||
|
||||
if (FName(p->NodeName) == FName("prefix") && fileSystem.GetFileContainer(Lump) == 0)
|
||||
{
|
||||
// only for internal definitions: Allow setting a prefix. This is only for compatiblity with the old DECORATE property parser, but not for general use.
|
||||
prefix = referenced;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (referenced != NAME_None)
|
||||
{
|
||||
field = dyn_cast<PField>(type->FindSymbol(referenced, true));
|
||||
if (field == nullptr)
|
||||
{
|
||||
Error(p, "Variable %s not found in %s", referenced.GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
else if (!field->Type->isInt() || field->Type->Size != 4)
|
||||
{
|
||||
Error(p, "Variable %s in %s must have a size of 4 bytes for use as flag storage", referenced.GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
else field = nullptr;
|
||||
|
||||
|
||||
FString qualifiedname;
|
||||
// Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen.
|
||||
// All these will be removed from the symbol table after the compiler finishes to free up the allocated space.
|
||||
FName name = FName(p->NodeName);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (i == 0) qualifiedname.Format("@flagdef@%s", name.GetChars());
|
||||
else
|
||||
{
|
||||
if (prefix == NAME_None) continue;
|
||||
qualifiedname.Format("@flagdef@%s.%s", prefix.GetChars(), name.GetChars());
|
||||
}
|
||||
|
||||
if (!type->VMType->Symbols.AddSymbol(Create<PPropFlag>(qualifiedname, field, p->BitValue, i == 0 && prefix != NAME_None)))
|
||||
{
|
||||
Error(p, "Unable to add flag definition %s to class %s", FName(p->NodeName).GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
if (field != nullptr)
|
||||
type->VMType->AddNativeField(FStringf("b%s", name.GetChars()), TypeSInt32, field->Offset, 0, 1 << p->BitValue);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Parses an actor property's parameters and calls the handler
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCRazeCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *property, DCoreActor *defaults, Baggage &bag)
|
||||
{
|
||||
static TArray<FPropParam> params;
|
||||
static TArray<FString> strings;
|
||||
|
||||
params.Clear();
|
||||
strings.Clear();
|
||||
params.Reserve(1);
|
||||
params[0].i = 0;
|
||||
if (prop->params[0] != '0')
|
||||
{
|
||||
if (property->Values == nullptr)
|
||||
{
|
||||
Error(property, "%s: arguments missing", prop->name);
|
||||
return;
|
||||
}
|
||||
const char * p = prop->params;
|
||||
auto exp = property->Values;
|
||||
|
||||
FCompileContext ctx(OutNamespace, bag.Info->VMType, false);
|
||||
while (true)
|
||||
{
|
||||
FPropParam conv;
|
||||
FPropParam pref;
|
||||
|
||||
FxExpression *ex = ConvertNode(exp);
|
||||
ex = ex->Resolve(ctx);
|
||||
if (ex == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (!ex->isConstant())
|
||||
{
|
||||
// If we get TypeError, there has already been a message from deeper down so do not print another one.
|
||||
if (exp->Type != TypeError) Error(exp, "%s: non-constant parameter", prop->name);
|
||||
return;
|
||||
}
|
||||
conv.s = nullptr;
|
||||
pref.s = nullptr;
|
||||
pref.i = -1;
|
||||
switch ((*p) & 223)
|
||||
{
|
||||
|
||||
case 'X': // Expression in parentheses or number. We only support the constant here. The function will have to be handled by a separate property to get past the parser.
|
||||
conv.i = GetIntConst(ex, ctx);
|
||||
params.Push(conv);
|
||||
conv.exp = nullptr;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
case 'M': // special case for morph styles in DECORATE . This expression-aware parser will not need this.
|
||||
case 'N': // special case for thing activations in DECORATE. This expression-aware parser will not need this.
|
||||
conv.i = GetIntConst(ex, ctx);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
conv.d = GetFloatConst(ex, ctx);
|
||||
break;
|
||||
|
||||
case 'Z': // an optional string. Does not allow any numeric value.
|
||||
if (ex->ValueType != TypeString)
|
||||
{
|
||||
// apply this expression to the next argument on the list.
|
||||
params.Push(conv);
|
||||
params[0].i++;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
conv.s = GetStringConst(ex, ctx);
|
||||
break;
|
||||
|
||||
case 'C': // this parser accepts colors only in string form.
|
||||
pref.i = 1;
|
||||
[[fallthrough]];
|
||||
case 'S':
|
||||
case 'T': // a filtered string (ZScript only parses filtered strings so there's nothing to do here.)
|
||||
conv.s = GetStringConst(ex, ctx);
|
||||
break;
|
||||
|
||||
case 'L': // Either a number or a list of strings
|
||||
if (ex->ValueType != TypeString)
|
||||
{
|
||||
pref.i = 0;
|
||||
conv.i = GetIntConst(ex, ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
pref.i = 1;
|
||||
params.Push(pref);
|
||||
params[0].i++;
|
||||
|
||||
do
|
||||
{
|
||||
conv.s = GetStringConst(ex, ctx);
|
||||
if (conv.s != nullptr)
|
||||
{
|
||||
params.Push(conv);
|
||||
params[0].i++;
|
||||
}
|
||||
exp = static_cast<ZCC_Expression *>(exp->SiblingNext);
|
||||
if (exp != property->Values)
|
||||
{
|
||||
ex = ConvertNode(exp);
|
||||
ex = ex->Resolve(ctx);
|
||||
if (ex == nullptr) return;
|
||||
}
|
||||
} while (exp != property->Values);
|
||||
goto endofparm;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
|
||||
}
|
||||
if (pref.i != -1)
|
||||
{
|
||||
params.Push(pref);
|
||||
params[0].i++;
|
||||
}
|
||||
params.Push(conv);
|
||||
params[0].i++;
|
||||
exp = static_cast<ZCC_Expression *>(exp->SiblingNext);
|
||||
endofparm:
|
||||
p++;
|
||||
// Skip the DECORATE 'no comma' marker
|
||||
if (*p == '_') p++;
|
||||
|
||||
if (*p == 0)
|
||||
{
|
||||
if (exp != property->Values)
|
||||
{
|
||||
Error(property, "Too many values for '%s'", prop->name);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (exp == property->Values)
|
||||
{
|
||||
if (*p < 'a')
|
||||
{
|
||||
Error(property, "Insufficient parameters for %s", prop->name);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// call the handler
|
||||
try
|
||||
{
|
||||
prop->Handler(defaults, bag.Info, bag, ¶ms[0]);
|
||||
}
|
||||
catch (CRecoverableError &error)
|
||||
{
|
||||
Error(property, "%s", error.GetMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Parses an actor property's parameters and calls the handler
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCRazeCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *property, DCoreActor *defaults, Baggage &bag)
|
||||
{
|
||||
ZCC_ExprConstant one;
|
||||
unsigned parmcount = 1;
|
||||
ZCC_TreeNode *x = property->Values;
|
||||
if (x == nullptr)
|
||||
{
|
||||
parmcount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (x->SiblingNext != property->Values)
|
||||
{
|
||||
x = x->SiblingNext;
|
||||
parmcount++;
|
||||
}
|
||||
}
|
||||
if (parmcount == 0 && prop->Variables.Size() == 1 && prop->Variables[0]->Type == TypeBool)
|
||||
{
|
||||
// allow boolean properties to have the parameter omitted
|
||||
memset(&one, 0, sizeof(one));
|
||||
one.SourceName = property->SourceName; // This may not be null!
|
||||
one.Operation = PEX_ConstValue;
|
||||
one.NodeType = AST_ExprConstant;
|
||||
one.Type = TypeBool;
|
||||
one.IntVal = 1;
|
||||
property->Values = &one;
|
||||
}
|
||||
else if (parmcount != prop->Variables.Size())
|
||||
{
|
||||
Error(x == nullptr? property : x, "Argument count mismatch: Got %u, expected %u", parmcount, prop->Variables.Size());
|
||||
return;
|
||||
}
|
||||
|
||||
auto exp = property->Values;
|
||||
FCompileContext ctx(OutNamespace, bag.Info->VMType, false);
|
||||
for (auto f : prop->Variables)
|
||||
{
|
||||
void *addr;
|
||||
if (f == nullptr)
|
||||
{
|
||||
// This variable was missing. The error had been reported for the property itself already.
|
||||
return;
|
||||
}
|
||||
|
||||
if (f->Flags & VARF_Meta)
|
||||
{
|
||||
addr = ((char*)bag.Info->Meta) + f->Offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = ((char*)defaults) + f->Offset;
|
||||
}
|
||||
|
||||
FxExpression *ex = ConvertNode(exp);
|
||||
ex = ex->Resolve(ctx);
|
||||
if (ex == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (!ex->isConstant())
|
||||
{
|
||||
// If we get TypeError, there has already been a message from deeper down so do not print another one.
|
||||
if (exp->Type != TypeError) Error(exp, "%s: non-constant parameter", prop->SymbolName.GetChars());
|
||||
return;
|
||||
}
|
||||
|
||||
if (f->Type == TypeBool)
|
||||
{
|
||||
static_cast<PBool*>(f->Type)->SetValue(addr, !!GetIntConst(ex, ctx));
|
||||
}
|
||||
else if (f->Type == TypeName)
|
||||
{
|
||||
*(FName*)addr = GetStringConst(ex, ctx);
|
||||
}
|
||||
else if (f->Type == TypeSound)
|
||||
{
|
||||
*(FSoundID*)addr = GetStringConst(ex, ctx);
|
||||
}
|
||||
else if (f->Type == TypeColor && ex->ValueType == TypeString) // colors can also be specified as ints.
|
||||
{
|
||||
*(PalEntry*)addr = V_GetColor(GetStringConst(ex, ctx), &ex->ScriptPosition);
|
||||
}
|
||||
else if (f->Type->isIntCompatible())
|
||||
{
|
||||
static_cast<PInt*>(f->Type)->SetValue(addr, GetIntConst(ex, ctx));
|
||||
}
|
||||
else if (f->Type->isFloat())
|
||||
{
|
||||
static_cast<PFloat*>(f->Type)->SetValue(addr, GetFloatConst(ex, ctx));
|
||||
}
|
||||
else if (f->Type == TypeString)
|
||||
{
|
||||
*(FString*)addr = GetStringConst(ex, ctx);
|
||||
}
|
||||
else if (f->Type->isClassPointer())
|
||||
{
|
||||
auto clsname = GetStringConst(ex, ctx);
|
||||
if (*clsname == 0 || !stricmp(clsname, "none"))
|
||||
{
|
||||
*(PClass**)addr = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto cls = PClass::FindClass(clsname);
|
||||
auto cp = static_cast<PClassPointer*>(f->Type);
|
||||
if (cls == nullptr)
|
||||
{
|
||||
cls = cp->ClassRestriction->FindClassTentative(clsname);
|
||||
}
|
||||
else if (!cls->IsDescendantOf(cp->ClassRestriction))
|
||||
{
|
||||
Error(property, "class %s is not compatible with property type %s", clsname, cp->ClassRestriction->TypeName.GetChars());
|
||||
}
|
||||
*(PClass**)addr = cls;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(property, "unhandled property type %s", f->Type->DescriptiveName());
|
||||
}
|
||||
exp->ToErrorNode(); // invalidate after processing.
|
||||
exp = static_cast<ZCC_Expression *>(exp->SiblingNext);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Parses an actor property
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCRazeCompiler::ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *prop, Baggage &bag)
|
||||
{
|
||||
auto namenode = prop->Prop;
|
||||
FString propname;
|
||||
|
||||
if (namenode->SiblingNext == namenode)
|
||||
{
|
||||
// a one-name property
|
||||
propname = FName(namenode->Id).GetChars();
|
||||
|
||||
}
|
||||
else if (namenode->SiblingNext->SiblingNext == namenode)
|
||||
{
|
||||
// a two-name property
|
||||
propname << FName(namenode->Id).GetChars() << "." << FName(static_cast<ZCC_Identifier *>(namenode->SiblingNext)->Id).GetChars();
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(prop, "Property name may at most contain two parts");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FPropertyInfo *property = FindProperty(propname);
|
||||
|
||||
if (property != nullptr && property->category != CAT_INFO)
|
||||
{
|
||||
auto pcls = PClass::FindActor(property->clsname);
|
||||
if (cls->IsDescendantOf(pcls))
|
||||
{
|
||||
DispatchProperty(property, prop, (DCoreActor *)bag.Info->Defaults, bag);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(prop, "'%s' requires an actor of type '%s'\n", propname.GetChars(), pcls->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
propname.Insert(0, "@property@");
|
||||
FName name(propname, true);
|
||||
if (name != NAME_None)
|
||||
{
|
||||
auto propp = dyn_cast<PProperty>(cls->FindSymbol(name, true));
|
||||
if (propp != nullptr)
|
||||
{
|
||||
DispatchScriptProperty(propp, prop, (DCoreActor *)bag.Info->Defaults, bag);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Error(prop, "'%s' is an unknown actor property\n", propname.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Finds a flag and sets or clears it
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCRazeCompiler::ProcessDefaultFlag(PClassActor *cls, ZCC_FlagStmt *flg)
|
||||
{
|
||||
auto namenode = flg->name;
|
||||
const char *n1 = FName(namenode->Id).GetChars(), *n2;
|
||||
|
||||
if (namenode->SiblingNext == namenode)
|
||||
{
|
||||
// a one-name flag
|
||||
n2 = nullptr;
|
||||
}
|
||||
else if (namenode->SiblingNext->SiblingNext == namenode)
|
||||
{
|
||||
// a two-name flag
|
||||
n2 = FName(static_cast<ZCC_Identifier *>(namenode->SiblingNext)->Id).GetChars();
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(flg, "Flag name may at most contain two parts");
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
auto fd = FindFlag(cls, n1, n2, true);
|
||||
if (fd != nullptr)
|
||||
{
|
||||
if (fd->varflags & VARF_Deprecated)
|
||||
{
|
||||
Warn(flg, "Deprecated flag '%s%s%s' used", n1, n2 ? "." : "", n2 ? n2 : "");
|
||||
}
|
||||
if (fd->structoffset == -1)
|
||||
{
|
||||
HandleDeprecatedFlags((DCoreActor*)cls->Defaults, cls, flg->set, fd->flagbit);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModActorFlag((DCoreActor*)cls->Defaults, fd, flg->set);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Error(flg, "Unknown flag '%s%s%s'", n1, n2 ? "." : "", n2 ? n2 : "");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Parses the default list
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCRazeCompiler::InitDefaults()
|
||||
{
|
||||
for (auto c : Classes)
|
||||
{
|
||||
// This may be removed if the conditions change, but right now only subclasses of Actor can define a Default block.
|
||||
if (!c->ClassType()->IsDescendantOf(RUNTIME_CLASS(DCoreActor)))
|
||||
{
|
||||
if (c->Defaults.Size()) Error(c->cls, "%s: Non-actor classes may not have defaults", c->ClassType()->TypeName.GetChars());
|
||||
if (c->ClassType()->ParentClass)
|
||||
{
|
||||
auto ti = c->ClassType();
|
||||
ti->InitializeDefaults();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto cls = c->ClassType();
|
||||
// This should never happen.
|
||||
if (cls->Defaults != nullptr)
|
||||
{
|
||||
Error(c->cls, "%s already has defaults", cls->TypeName.GetChars());
|
||||
}
|
||||
// This can only occur if a native parent is not initialized. In all other cases the sorting of the class list should prevent this from ever happening.
|
||||
else if (cls->ParentClass->Defaults == nullptr && cls != RUNTIME_CLASS(DCoreActor))
|
||||
{
|
||||
Error(c->cls, "Parent class %s of %s is not initialized", cls->ParentClass->TypeName.GetChars(), cls->TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the parent's defaults and meta data.
|
||||
auto ti = static_cast<PClassActor *>(cls);
|
||||
|
||||
ti->InitializeDefaults();
|
||||
|
||||
// Replacements require that the meta data has been allocated by InitializeDefaults.
|
||||
if (c->cls->Replaces != nullptr && !ti->SetReplacement(c->cls->Replaces->Id))
|
||||
{
|
||||
Warn(c->cls, "Replaced type '%s' not found for %s", FName(c->cls->Replaces->Id).GetChars(), ti->TypeName.GetChars());
|
||||
}
|
||||
|
||||
|
||||
Baggage bag;
|
||||
bag.Version = mVersion;
|
||||
bag.Namespace = OutNamespace;
|
||||
bag.Info = ti;
|
||||
bag.Lumpnum = c->cls->SourceLump;
|
||||
// The actual script position needs to be set per property.
|
||||
|
||||
for (auto d : c->Defaults)
|
||||
{
|
||||
auto content = d->Content;
|
||||
if (content != nullptr) do
|
||||
{
|
||||
switch (content->NodeType)
|
||||
{
|
||||
case AST_PropertyStmt:
|
||||
bag.ScriptPosition.FileName = *content->SourceName;
|
||||
bag.ScriptPosition.ScriptLine = content->SourceLoc;
|
||||
ProcessDefaultProperty(ti, static_cast<ZCC_PropertyStmt *>(content), bag);
|
||||
break;
|
||||
|
||||
case AST_FlagStmt:
|
||||
ProcessDefaultFlag(ti, static_cast<ZCC_FlagStmt *>(content));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
content = static_cast<decltype(content)>(content->SiblingNext);
|
||||
} while (content != d->Content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DCoreActor needs the actor info manually added to its meta data
|
||||
// before adding any scripted fields.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool ZCCRazeCompiler::PrepareMetaData(PClass *type)
|
||||
{
|
||||
if (type == RUNTIME_CLASS(DCoreActor))
|
||||
{
|
||||
assert(type->MetaSize == 0);
|
||||
AddActorInfo(type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
32
source/core/zcc_compile_raze.h
Normal file
32
source/core/zcc_compile_raze.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include "zcc_compile.h"
|
||||
|
||||
void SetImplicitArgs(TArray<PType*>* args, TArray<uint32_t>* argflags, TArray<FName>* argnames, PContainerType* cls, uint32_t funcflags, int useflags);
|
||||
|
||||
class ZCCRazeCompiler : public ZCCCompiler
|
||||
{
|
||||
public:
|
||||
ZCCRazeCompiler(ZCC_AST &tree, DObject *outer, PSymbolTable &symbols, PNamespace *outnamespace, int lumpnum, const VersionInfo & ver)
|
||||
: ZCCCompiler(tree, outer, symbols, outnamespace, lumpnum, ver)
|
||||
{}
|
||||
int Compile() override;
|
||||
protected:
|
||||
bool PrepareMetaData(PClass *type) override;
|
||||
void SetImplicitArgs(TArray<PType*>* args, TArray<uint32_t>* argflags, TArray<FName>* argnames, PContainerType* cls, uint32_t funcflags, int useflags) override
|
||||
{
|
||||
::SetImplicitArgs(args, argflags, argnames, cls, funcflags, useflags);
|
||||
}
|
||||
private:
|
||||
void CompileAllProperties();
|
||||
bool CompileProperties(PClass *type, TArray<ZCC_Property *> &Properties, FName prefix);
|
||||
bool CompileFlagDefs(PClass *type, TArray<ZCC_FlagDef *> &Properties, FName prefix);
|
||||
void DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *property, DCoreActor *defaults, Baggage &bag);
|
||||
void DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *property, DCoreActor *defaults, Baggage &bag);
|
||||
void ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *prop, Baggage &bag);
|
||||
void ProcessDefaultFlag(PClassActor *cls, ZCC_FlagStmt *flg);
|
||||
void InitDefaults() override final;
|
||||
int CheckActionKeyword(ZCC_FuncDeclarator *f, uint32_t &varflags, int useflags, ZCC_StructWork *c);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "tflags.h"
|
||||
#include "coreactor.h"
|
||||
|
||||
// all game constants got collected here.
|
||||
|
||||
|
|
Loading…
Reference in a new issue