diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 043abb067..dd4af7e72 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -153,6 +153,10 @@ struct walltype uint8_t portalflags; uint16_t portalnum; + // Blood is the only game which extends the wall struct. + Blood::XWALL* _xw; + vec2_t baseWall; + int xpan() const { return int(xpan_); } int ypan() const { return int(ypan_); } void setxpan(float add) { xpan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets @@ -168,9 +172,9 @@ struct walltype int deltay() const { return point2Wall()->y - y; } bool twoSided() const { return nextsector >= 0; } - // These will unfortunately have to be within the base struct to refactor Blood properly. They can later be removed again, once everything is done. - Blood::XWALL& xw() const; - bool hasX() const { return extra > 0; } // 0 is invalid! + Blood::XWALL& xw() const { return *_xw; } + bool hasX() const { return _xw != nullptr; } + void allocX(); #if 0 // make sure we do not accidentally copy this diff --git a/source/common/engine/serializer.cpp b/source/common/engine/serializer.cpp index a8e15e974..fcdf49b54 100644 --- a/source/common/engine/serializer.cpp +++ b/source/common/engine/serializer.cpp @@ -290,6 +290,28 @@ bool FSerializer::BeginObject(const char *name) // //========================================================================== +bool FSerializer::HasObject(const char* name) +{ + if (isReading()) + { + auto val = r->FindKey(name); + if (val != nullptr) + { + if (val->IsObject()) + { + return true; + } + } + } + return false; +} + +//========================================================================== +// +// +// +//========================================================================== + void FSerializer::EndObject() { if (isWriting()) diff --git a/source/common/engine/serializer.h b/source/common/engine/serializer.h index 400a6f4aa..714c0d168 100644 --- a/source/common/engine/serializer.h +++ b/source/common/engine/serializer.h @@ -85,6 +85,7 @@ public: void ReadObjects(bool hubtravel); bool BeginObject(const char *name); void EndObject(); + bool HasObject(const char* name); bool BeginArray(const char *name); void EndArray(); unsigned GetSize(const char *group); diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index 485d1b833..c65a2a561 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -46,6 +46,7 @@ #include "render.h" #include "hw_sections.h" #include "interpolate.h" +#include "games/blood/src/mapstructs.h" // needed for skipping over to get the map size first. enum @@ -58,6 +59,16 @@ enum wallsize7 = 32, }; +// This arena stores the larger allocated game-specific extension data. Since this can be freed in bulk a memory arena is better suited than malloc. +static FMemArena mapDataArena; + +void walltype::allocX() +{ + using XWALL = BLD_NS::XWALL; + _xw = (XWALL*)mapDataArena.Alloc(sizeof(XWALL)); + memset(_xw, 0, sizeof(XWALL)); +} + static void ReadSectorV7(FileReader& fr, sectortype& sect) { diff --git a/source/core/ns.h b/source/core/ns.h index 82d397fd3..78aa9e9b0 100644 --- a/source/core/ns.h +++ b/source/core/ns.h @@ -2,35 +2,27 @@ #ifndef NO_NAMESPACE -#define BEGIN_DUKE_NS namespace Duke3d { +#define DUKE_NS Duke3d +#define BEGIN_DUKE_NS namespace DUKE_NS { #define END_DUKE_NS } -#define BEGIN_EDUKE_NS namespace Duke { -#define END_EDUKE_NS } - -#define BEGIN_RR_NS namespace Redneck { -#define END_RR_NS } - -#define BEGIN_BLD_NS namespace Blood { +#define BLD_NS Blood +#define BEGIN_BLD_NS namespace BLD_NS { #define END_BLD_NS } -#define BEGIN_SW_NS namespace ShadowWarrior { +#define SW_NS ShadowWarrior +#define BEGIN_SW_NS namespace SW_NS { #define END_SW_NS } -#define BEGIN_PS_NS namespace Exhumed { +#define PS_NS Exhumed +#define BEGIN_PS_NS namespace PS_NS { #define END_PS_NS } #else -#define BEGIN_EDUKE_NS -#define END_EDUKE_NS - #define BEGIN_DUKE_NS #define END_DUKE_NS -#define BEGIN_RR_NS -#define END_RR_NS - #define BEGIN_BLD_NS #define END_BLD_NS diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index e6e5c5d57..a6fa8df99 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -60,6 +60,8 @@ #include "hw_sections.h" #include "sectorgeometry.h" #include "d_net.h" +#include "ns.h" +#include "games/blood/src/mapstructs.h" #include @@ -75,7 +77,13 @@ int SaveVersion; void SerializeMap(FSerializer &arc); FixedBitArray activeSprites; -CVAR(String, cl_savedir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR(String, cl_savedir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + +BEGIN_BLD_NS + +FSerializer& Serialize(FSerializer& arc, const char* keyname, XWALL& w, XWALL* def); + +END_BLD_NS //============================================================================= // @@ -555,8 +563,30 @@ FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype ("hitag", c.hitag, def->hitag) ("extra", c.extra, def->extra) ("portalflags", c.portalflags, def->portalflags) - ("portalnum", c.portalnum, def->portalnum) - .EndObject(); + ("portalnum", c.portalnum, def->portalnum); + + // Save the blood-specific extensions only when playing Blood + if (isBlood()) + { + arc("wallbase", c.baseWall, def->baseWall); + if (arc.isWriting()) + { + if (c.hasX()) + { + BLD_NS::Serialize(arc, "xwall", *c._xw, nullptr); + } + } + else + { + if (arc.HasObject("xwall")) + { + c.allocX(); + BLD_NS::Serialize(arc, "xwall", *c._xw, nullptr); + } + } + } + + arc.EndObject(); } return arc; } diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index 0b1dd7e07..950104403 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -556,7 +556,6 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int int nAnim = 0; switch (picanm[nTile].extra & 7) { case 0: - //assert(nXSprite > 0 && nXSprite < kMaxXSprites); if (pTXSprite == nullptr) break; switch (pTSprite->type) { case kSwitchToggle: diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 6165a8080..24d917a31 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -45,9 +45,7 @@ bool gModernMap = false; unsigned int gStatCount[kMaxStatus + 1]; XSECTOR xsector[kMaxXSectors]; -XWALL xwall[kMaxXWalls]; - -int XWallsUsed, XSectorsUsed; +int XSectorsUsed; @@ -252,18 +250,6 @@ void InitFreeList(unsigned short* pList, int nCount) } -unsigned int dbInsertXWall(int nWall) -{ - int nXWall = XWallsUsed++; - if (nXWall >= kMaxXWalls) - { - I_Error("Out of free XWalls"); - } - memset(&xwall[nXWall], 0, sizeof(XWALL)); - wall[nWall].extra = nXWall; - return nXWall; -} - unsigned int dbInsertXSector(int nSector) { int nXSector = XSectorsUsed++; @@ -278,7 +264,7 @@ unsigned int dbInsertXSector(int nSector) void dbInit(void) { - XWallsUsed = XSectorsUsed = 1; // 0 is not usable because it's the default for 'extra' and some code actually uses it to clobber the contents in here. :( + XSectorsUsed = 1; // 0 is not usable because it's the default for 'extra' and some code actually uses it to clobber the contents in here. :( initspritelists(); for (int i = 0; i < kMaxSprites; i++) { @@ -715,12 +701,11 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, int* pWall->yrepeat = load.yrepeat; pWall->ypan_ = load.ypanning; - if (wall[i].extra > 0) + if (pWall->extra > 0) { char pBuffer[nXWallSize]; - int nXWall = dbInsertXWall(i); - XWALL* pXWall = &xwall[nXWall]; - memset(pXWall, 0, sizeof(XWALL)); + pWall->allocX(); + XWALL* pXWall = &pWall->xw(); int nCount; if (!encrypted) { diff --git a/source/games/blood/src/db.h b/source/games/blood/src/db.h index 9e249fe95..68b73f384 100644 --- a/source/games/blood/src/db.h +++ b/source/games/blood/src/db.h @@ -22,13 +22,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //------------------------------------------------------------------------- #pragma once +#include "mapstructs.h" + BEGIN_BLD_NS enum { - kMaxXSprites = 16384, - kMaxXWalls = 512, kMaxXSectors = 512 }; @@ -44,218 +44,10 @@ enum }; -// by NoOne: functions to quckly check range of specifical arrays -inline bool xsectRangeIsFine(int nXindex) { - return (nXindex >= 0 && nXindex < kMaxXSectors); -} - -inline bool xwallRangeIsFine(int nXindex) { - return (nXindex >= 0 && nXindex < kMaxXWalls); -} #pragma pack(push, 1) struct AISTATE; -struct XSPRITE { - - AISTATE* aiState; // ai - union - { - uint32_t flags; - struct { - unsigned int state : 1; // State 0 - unsigned int triggerOn : 1; // going ON - unsigned int triggerOff : 1; // going OFF - unsigned int restState : 1; // restState - unsigned int Interrutable : 1; // Interruptable - unsigned int Decoupled : 1; // Decoupled - unsigned int triggerOnce : 1; // 1-shot - unsigned int isTriggered : 1; // works in case if triggerOnce selected - unsigned int Push : 1; // Push - unsigned int Vector : 1; // Vector - unsigned int Impact : 1; // Impact - unsigned int Pickup : 1; // Pickup - unsigned int Touch : 1; // Touch - unsigned int Sight : 1; // Sight - unsigned int Proximity : 1; // Proximity - unsigned int lS : 1; // Single - unsigned int lB : 1; // Bloodbath - unsigned int lT : 1; // Launch Team - unsigned int lC : 1; // Coop - unsigned int DudeLockout : 1; // DudeLockout - unsigned int locked : 1; // Locked - unsigned int dudeDeaf : 1; // dudeDeaf - unsigned int dudeAmbush : 1; // dudeAmbush - unsigned int dudeGuard : 1; // dudeGuard - unsigned int dudeFlag4 : 1; // unused - unsigned int wave : 2; // Wave - unsigned int medium : 2; // medium - unsigned int respawn : 2; // Respawn option - unsigned int unused2 : 1; // (new) patrol state - }; - }; - - DBloodActor* target; // target sprite - - int32_t targetX; // target x - int32_t targetY; // target y - int32_t targetZ; // target z - int32_t sysData1; // used to keep here various system data, so user can't change it in map editor - int32_t sysData2; // - int32_t scale; // used for scaling SEQ size on sprites - uint32_t physAttr; // currently used by additional physics sprites to keep it's attributes. - uint32_t health; - uint32_t busy; - - int16_t data1; // Data 1 - int16_t data2; // Data 2 - int16_t data3; // Data 3 - int16_t burnSource; - uint16_t txID; // TX ID - uint16_t rxID; // RX ID - uint16_t command; // Cmd - uint16_t busyTime; // busyTime - uint16_t waitTime; // waitTime - uint16_t data4; // Data 4 - uint16_t goalAng; // Dude goal ang - uint16_t burnTime; - uint16_t height; - uint16_t stateTimer; // ai timer - - uint8_t respawnPending; // respawnPending - uint8_t dropMsg; // Drop Item - uint8_t key; // Key - uint8_t lSkill; // Launch 12345 - uint8_t lockMsg; // Lock msg - int8_t dodgeDir; // Dude dodge direction - uint8_t unused1; // modern flags - uint8_t unused3; // something about sight checks - uint8_t unused4; // patrol turn delay - -}; - -struct XSECTOR { - - union - { - uint64_t flags; - struct { - unsigned int state : 1; // State - unsigned int triggerOn : 1; // Send at ON - unsigned int triggerOff : 1; // Send at OFF - unsigned int restState : 1; - unsigned int interruptable : 1; // Interruptable - unsigned int reTriggerA : 1; // OFF->ON wait - unsigned int reTriggerB : 1; // ON->OFF wait - unsigned int shadeAlways : 1; // Lighting shadeAlways - unsigned int shadeFloor : 1; // Lighting floor - unsigned int shadeCeiling : 1; // Lighting ceiling - unsigned int shadeWalls : 1; // Lighting walls - unsigned int panAlways : 1; // Pan always - unsigned int panFloor : 1; // Pan floor - unsigned int panCeiling : 1; // Pan ceiling - unsigned int Drag : 1; // Pan drag - unsigned int Underwater : 1; // Underwater - unsigned int decoupled : 1; // Decoupled - unsigned int triggerOnce : 1; // 1-shot - unsigned int isTriggered : 1; - unsigned int Push : 1; // Push - unsigned int Vector : 1; // Vector - unsigned int Reserved : 1; // Reserved - unsigned int Enter : 1; // Enter - unsigned int Exit : 1; // Exit - unsigned int Wallpush : 1; // WallPush - unsigned int color : 1; // Color Lights - unsigned int stopOn : 1; - unsigned int stopOff : 1; - unsigned int Crush : 1; // Crush - unsigned int locked : 1; // Locked - unsigned int windAlways : 1; // Wind always - unsigned int dudeLockout : 1; - unsigned int bobAlways : 1; // Motion always - unsigned int bobFloor : 1; // Motion bob floor - unsigned int bobCeiling : 1; // Motion bob ceiling - unsigned int bobRotate : 1; // Motion rotate - unsigned int unused1 : 1; // (new) pause motion - - }; - }; - - uint32_t busy; - int32_t offCeilZ; - int32_t onCeilZ; - int32_t offFloorZ; - int32_t onFloorZ; - uint32_t windVel; // Wind vel (changed from 10 bit to use higher velocity values) - - uint16_t data; // Data - uint16_t txID; // TX ID - uint16_t rxID; // RX ID - uint16_t busyTimeA; // OFF->ON busyTime - uint16_t waitTimeA; // OFF->ON waitTime - uint16_t panAngle; // Motion angle - uint16_t busyTimeB; // ON->OFF busyTime - uint16_t waitTimeB; // ON->OFF waitTime - DBloodActor* marker0; - DBloodActor* marker1; - DBloodActor* basePath; - DBloodActor* actordata; - uint16_t windAng; // Wind ang - uint16_t bobTheta; // Motion Theta - int16_t bobSpeed; // Motion speed - - uint8_t busyWaveA; // OFF->ON wave - uint8_t busyWaveB; // ON->OFF wave - uint8_t command; // Cmd - int8_t amplitude; // Lighting amplitude - uint8_t freq; // Lighting freq - uint8_t phase; // Lighting phase - uint8_t wave; // Lighting wave - int8_t shade; // Lighting value - uint8_t panVel; // Motion speed - uint8_t Depth; // Depth - uint8_t Key; // Key - uint8_t ceilpal; // Ceil pal2 - uint8_t damageType; // DamageType - uint8_t floorpal; // Floor pal2 - uint8_t bobZRange; // Motion Z range -}; - -struct XWALL { - - union - { - uint32_t flags; - struct { - unsigned int state : 1; // State - unsigned int triggerOn : 1; // going ON - unsigned int triggerOff : 1; // going OFF - unsigned int restState : 1; // restState - unsigned int interruptable : 1; // Interruptable - unsigned int panAlways : 1; // panAlways - unsigned int decoupled : 1; // Decoupled - unsigned int triggerOnce : 1; // 1-shot - unsigned int isTriggered : 1; - unsigned int triggerPush : 1; // Push - unsigned int triggerVector : 1; // Vector - unsigned int triggerTouch : 1; // by NoOne: renamed from Reserved to Touch as it works with Touch now. - unsigned int locked : 1; // Locked - unsigned int dudeLockout : 1; // DudeLockout - }; - }; - uint32_t busy; - - int16_t data; // Data - uint16_t txID; // TX ID - uint16_t rxID; // RX ID - uint16_t busyTime; // busyTime - uint16_t waitTime; // waitTime - - uint8_t command; // Cmd - int8_t panXVel; // panX - int8_t panYVel; // panY - uint8_t key; // Key -}; struct MAPSIGNATURE { char signature[4]; @@ -294,7 +86,6 @@ extern bool drawtile2048, encrypted; extern MAPHEADER2 byte_19AE44; extern XSECTOR xsector[kMaxXSectors]; -extern XWALL xwall[kMaxXWalls]; extern uint8_t qsector_filler[kMaxSectors]; @@ -304,7 +95,7 @@ extern const char *gItemText[]; extern const char *gAmmoText[]; extern const char *gWeaponText[]; -extern int XWallsUsed, XSectorsUsed; +extern int XSectorsUsed; static inline int GetWallType(int nWall) { @@ -358,11 +149,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, int* END_BLD_NS // refactoring aids. -inline Blood::XWALL& walltype::xw() const -{ - return Blood::xwall[extra]; -} - inline Blood::XSECTOR& sectortype::xs() const { return Blood::xsector[extra]; diff --git a/source/games/blood/src/loadsave.cpp b/source/games/blood/src/loadsave.cpp index 2b0f9b846..ce24b52eb 100644 --- a/source/games/blood/src/loadsave.cpp +++ b/source/games/blood/src/loadsave.cpp @@ -710,7 +710,6 @@ void SerializeState(FSerializer& arc) .Array("velceil", velCeil, numsectors) ("hitinfo", gHitInfo) .Array("statcount", gStatCount, kMaxStatus + 1) - ("xwallsused", XWallsUsed) ("xsectorsused", XSectorsUsed) ("fogmode", gFogMode) #ifdef NOONE_EXTENSIONS @@ -725,7 +724,6 @@ void SerializeState(FSerializer& arc) ("numtiles", pSky->lognumtiles) ("gameoptions", gGameOptions) - .Array("xwall", xwall, XWallsUsed) // todo .Array("xsector", xsector, XSectorsUsed) .SparseArray("actors", bloodActors, kMaxSprites, activeSprites); diff --git a/source/games/blood/src/mapstructs.h b/source/games/blood/src/mapstructs.h new file mode 100644 index 000000000..7ba121be8 --- /dev/null +++ b/source/games/blood/src/mapstructs.h @@ -0,0 +1,211 @@ +// This is separate because the map loader needs knowledge about these types to allocate their instances. +#pragma once +#include "ns.h" + +BEGIN_BLD_NS + +class DBloodActor; +struct AISTATE; + +struct XSPRITE { + + AISTATE* aiState; // ai + union + { + uint32_t flags; + struct { + unsigned int state : 1; // State 0 + unsigned int triggerOn : 1; // going ON + unsigned int triggerOff : 1; // going OFF + unsigned int restState : 1; // restState + unsigned int Interrutable : 1; // Interruptable + unsigned int Decoupled : 1; // Decoupled + unsigned int triggerOnce : 1; // 1-shot + unsigned int isTriggered : 1; // works in case if triggerOnce selected + unsigned int Push : 1; // Push + unsigned int Vector : 1; // Vector + unsigned int Impact : 1; // Impact + unsigned int Pickup : 1; // Pickup + unsigned int Touch : 1; // Touch + unsigned int Sight : 1; // Sight + unsigned int Proximity : 1; // Proximity + unsigned int lS : 1; // Single + unsigned int lB : 1; // Bloodbath + unsigned int lT : 1; // Launch Team + unsigned int lC : 1; // Coop + unsigned int DudeLockout : 1; // DudeLockout + unsigned int locked : 1; // Locked + unsigned int dudeDeaf : 1; // dudeDeaf + unsigned int dudeAmbush : 1; // dudeAmbush + unsigned int dudeGuard : 1; // dudeGuard + unsigned int dudeFlag4 : 1; // unused + unsigned int wave : 2; // Wave + unsigned int medium : 2; // medium + unsigned int respawn : 2; // Respawn option + unsigned int unused2 : 1; // (new) patrol state + }; + }; + + DBloodActor* target; // target sprite + + int32_t targetX; // target x + int32_t targetY; // target y + int32_t targetZ; // target z + int32_t sysData1; // used to keep here various system data, so user can't change it in map editor + int32_t sysData2; // + int32_t scale; // used for scaling SEQ size on sprites + uint32_t physAttr; // currently used by additional physics sprites to keep its attributes. + uint32_t health; + uint32_t busy; + + int16_t data1; // Data 1 + int16_t data2; // Data 2 + int16_t data3; // Data 3 + int16_t burnSource; + uint16_t txID; // TX ID + uint16_t rxID; // RX ID + uint16_t command; // Cmd + uint16_t busyTime; // busyTime + uint16_t waitTime; // waitTime + uint16_t data4; // Data 4 + uint16_t goalAng; // Dude goal ang + uint16_t burnTime; + uint16_t height; + uint16_t stateTimer; // ai timer + + uint8_t respawnPending; // respawnPending + uint8_t dropMsg; // Drop Item + uint8_t key; // Key + uint8_t lSkill; // Launch 12345 + uint8_t lockMsg; // Lock msg + int8_t dodgeDir; // Dude dodge direction + uint8_t unused1; // modern flags + uint8_t unused3; // something about sight checks + uint8_t unused4; // patrol turn delay + +}; + +struct XSECTOR { + + union + { + uint64_t flags; + struct { + unsigned int state : 1; // State + unsigned int triggerOn : 1; // Send at ON + unsigned int triggerOff : 1; // Send at OFF + unsigned int restState : 1; + unsigned int interruptable : 1; // Interruptable + unsigned int reTriggerA : 1; // OFF->ON wait + unsigned int reTriggerB : 1; // ON->OFF wait + unsigned int shadeAlways : 1; // Lighting shadeAlways + unsigned int shadeFloor : 1; // Lighting floor + unsigned int shadeCeiling : 1; // Lighting ceiling + unsigned int shadeWalls : 1; // Lighting walls + unsigned int panAlways : 1; // Pan always + unsigned int panFloor : 1; // Pan floor + unsigned int panCeiling : 1; // Pan ceiling + unsigned int Drag : 1; // Pan drag + unsigned int Underwater : 1; // Underwater + unsigned int decoupled : 1; // Decoupled + unsigned int triggerOnce : 1; // 1-shot + unsigned int isTriggered : 1; + unsigned int Push : 1; // Push + unsigned int Vector : 1; // Vector + unsigned int Reserved : 1; // Reserved + unsigned int Enter : 1; // Enter + unsigned int Exit : 1; // Exit + unsigned int Wallpush : 1; // WallPush + unsigned int color : 1; // Color Lights + unsigned int stopOn : 1; + unsigned int stopOff : 1; + unsigned int Crush : 1; // Crush + unsigned int locked : 1; // Locked + unsigned int windAlways : 1; // Wind always + unsigned int dudeLockout : 1; + unsigned int bobAlways : 1; // Motion always + unsigned int bobFloor : 1; // Motion bob floor + unsigned int bobCeiling : 1; // Motion bob ceiling + unsigned int bobRotate : 1; // Motion rotate + unsigned int unused1 : 1; // (new) pause motion + + }; + }; + DBloodActor* marker0; + DBloodActor* marker1; + DBloodActor* basePath; + DBloodActor* actordata; + + uint32_t busy; + int32_t offCeilZ; + int32_t onCeilZ; + int32_t offFloorZ; + int32_t onFloorZ; + uint32_t windVel; // Wind vel (changed from 10 bit to use higher velocity values) + + uint16_t data; // Data + uint16_t txID; // TX ID + uint16_t rxID; // RX ID + uint16_t busyTimeA; // OFF->ON busyTime + uint16_t waitTimeA; // OFF->ON waitTime + uint16_t panAngle; // Motion angle + uint16_t busyTimeB; // ON->OFF busyTime + uint16_t waitTimeB; // ON->OFF waitTime + uint16_t windAng; // Wind ang + uint16_t bobTheta; // Motion Theta + int16_t bobSpeed; // Motion speed + + uint8_t busyWaveA; // OFF->ON wave + uint8_t busyWaveB; // ON->OFF wave + uint8_t command; // Cmd + int8_t amplitude; // Lighting amplitude + uint8_t freq; // Lighting freq + uint8_t phase; // Lighting phase + uint8_t wave; // Lighting wave + int8_t shade; // Lighting value + uint8_t panVel; // Motion speed + uint8_t Depth; // Depth + uint8_t Key; // Key + uint8_t ceilpal; // Ceil pal2 + uint8_t damageType; // DamageType + uint8_t floorpal; // Floor pal2 + uint8_t bobZRange; // Motion Z range +}; + +struct XWALL { + + union + { + uint32_t flags; + struct { + unsigned int state : 1; // State + unsigned int triggerOn : 1; // going ON + unsigned int triggerOff : 1; // going OFF + unsigned int restState : 1; // restState + unsigned int interruptable : 1; // Interruptable + unsigned int panAlways : 1; // panAlways + unsigned int decoupled : 1; // Decoupled + unsigned int triggerOnce : 1; // 1-shot + unsigned int isTriggered : 1; + unsigned int triggerPush : 1; // Push + unsigned int triggerVector : 1; // Vector + unsigned int triggerTouch : 1; // by NoOne: renamed from Reserved to Touch as it works with Touch now. + unsigned int locked : 1; // Locked + unsigned int dudeLockout : 1; // DudeLockout + }; + }; + uint32_t busy; + + int16_t data; // Data + uint16_t txID; // TX ID + uint16_t rxID; // RX ID + uint16_t busyTime; // busyTime + uint16_t waitTime; // waitTime + + uint8_t command; // Cmd + int8_t panXVel; // panX + int8_t panYVel; // panY + uint8_t key; // Key +}; + +END_BLD_NS \ No newline at end of file