- cleaned up and renamed buildtypes.h.

Content was reordered so that the file can contain the inlines belonging to the map data types that previously had to be stored elsewhere.
Also moved out of the Build folder because virtually everything in here can be traced to content available in Duke Nukem 3D's and Shadow Warrior's source releases.
This commit is contained in:
Christoph Oelckers 2021-12-17 20:24:48 +01:00
parent 4a5de6f56e
commit dddf48fd3e
23 changed files with 725 additions and 753 deletions

View file

@ -86,7 +86,7 @@ enum {
RS_CENTERORIGIN = (1<<30),
};
#include "buildtypes.h"
#include "maptypes.h"
using uspriteptr_t = spritetype const *;
using uwallptr_t = walltype const *;
@ -100,28 +100,38 @@ using tspriteptr_t = tspritetype *;
int32_t getwalldist(vec2_t const in, int const wallnum);
int32_t getwalldist(vec2_t const in, int const wallnum, vec2_t * const out);
typedef struct {
enum
{
SPREXT_NOTMD = 1,
SPREXT_NOMDANIM = 2,
SPREXT_AWAY1 = 4,
SPREXT_AWAY2 = 8,
SPREXT_TSPRACCESS = 16,
SPREXT_TEMPINVISIBLE = 32,
};
struct spriteext_t
{
uint32_t mdanimtims;
int16_t mdanimcur;
int16_t angoff, pitch, roll;
vec3_t pivot_offset, position_offset;
uint8_t flags;
float alpha;
} spriteext_t;
};
typedef struct {
struct spritesmooth_t
{
float smoothduration;
int16_t mdcurframe, mdoldframe;
int16_t mdsmooth;
uint8_t filler[2];
} spritesmooth_t;
};
#define SPREXT_NOTMD 1
#define SPREXT_NOMDANIM 2
#define SPREXT_AWAY1 4
#define SPREXT_AWAY2 8
#define SPREXT_TSPRACCESS 16
#define SPREXT_TEMPINVISIBLE 32
struct SpawnSpriteDef
{
TArray<spritetype> sprites;
TArray<spriteext_t> sprext;
};
// using the clipdist field
enum
@ -139,31 +149,14 @@ struct usermaphack_t
uint8_t md4[16]{};
};
extern TArray<sectortype> sector;
extern TArray<walltype> wall;
EXTERN int leveltimer;
extern TArray<sectortype> sectorbackup;
extern TArray<walltype> wallbackup;
EXTERN int32_t xdim, ydim;
EXTERN int32_t yxaspect, viewingrange;
EXTERN int32_t Numsprites;
EXTERN int numsectors, numwalls;
EXTERN int32_t display_mirror;
inline bool validSectorIndex(int sectnum)
{
return sectnum >= 0 && sectnum < numsectors;
}
inline bool validWallIndex(int wallnum)
{
return wallnum >= 0 && wallnum < numwalls;
}
EXTERN int32_t randomseed;
EXTERN uint8_t paletteloaded;
@ -238,14 +231,6 @@ extern uint32_t drawlinepat;
extern uint8_t globalr, globalg, globalb;
enum {
GLOBAL_NO_GL_TILESHADES = 1<<0,
GLOBAL_NO_GL_FULLBRIGHT = 1<<1,
GLOBAL_NO_GL_FOGSHADE = 1<<2,
};
EXTERN int32_t editorzrange[2];
enum {
ENGINECOMPATIBILITY_NONE = 0,
ENGINECOMPATIBILITY_19950829, // Powerslave/Exhumed
@ -259,22 +244,6 @@ EXTERN int32_t enginecompatibility_mode;
int32_t engineInit(void);
void engineUnInit(void);
struct SpawnSpriteDef
{
TArray<spritetype> sprites;
TArray<spriteext_t> sprext;
};
[[deprecated]]
void insertAllSprites(SpawnSpriteDef& sprites);
void allocateMapArrays(int numsprites);
void ValidateSprite(spritetype& spr, int secno, int index);
void fixSectors();
void engineLoadBoard(const char *filename, int flags, vec3_t *dapos, int16_t *daang, int *dacursectnum, SpawnSpriteDef& sprites);
void loadMapBackup(const char* filename);
void G_LoadMapHack(const char* filename, const unsigned char*, SpawnSpriteDef& sprites);
void videoSetCorrectedAspect();
void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
void renderSetAspect(int32_t daxrange, int32_t daaspect);
@ -531,93 +500,4 @@ inline bool testgotpic(int32_t tilenume, bool reset = false)
return res;
}
inline sectortype* spritetypebase::sector() const
{
return sectp;
}
inline int spritetypebase::sectno() const
{
return sectp? ::sector.IndexOf(sectp) : -1;
}
inline void spritetypebase::setsector(sectortype* sect)
{
// place for asserts.
sectp = sect;
}
inline void spritetypebase::setsector(int sec)
{
// place for asserts.
sectp = validSectorIndex(sec)? &::sector[sec] : nullptr;
}
inline bool spritetypebase::insector() const
{
return sectp != nullptr;
}
inline sectortype* walltype::nextSector() const
{
return !validSectorIndex(nextsector)? nullptr : &::sector[nextsector];
}
inline walltype* walltype::nextWall() const
{
return !validWallIndex(nextwall)? nullptr : &::wall[nextwall];
}
inline sectortype* walltype::sectorp() const
{
return &::sector[sector]; // cannot be -1 in a proper map.
}
inline walltype* walltype::lastWall() const
{
int index = wall.IndexOf(this);
if (index > 0 && wall[index - 1].point2 == index) return &wall[index - 1];
int check = index;
for (int i = 0; i < numwalls; i++)
{
int next = wall[check].point2;
if (next == index) return &wall[check];
check = next;
}
return nullptr;
}
inline walltype* walltype::point2Wall() const
{
return &::wall[point2]; // cannot be -1 in a proper map.
}
inline walltype* sectortype::firstWall() const
{
return &wall[wallptr]; // cannot be -1 in a proper map
}
inline walltype* sectortype::lastWall() const
{
return &wall[wallptr + wallnum - 1]; // cannot be -1 in a proper map
}
inline void walltype::moved()
{
lengthflags = 3;
sectorp()->dirty = EDirty::AllDirty;
}
inline void walltype::move(int newx, int newy)
{
pos.x = newx;
pos.y = newy;
lengthflags = 3;
sectorp()->dirty = EDirty::AllDirty;
}
#endif // build_h_

View file

@ -1,535 +0,0 @@
#ifndef buildtypes_h__
#define buildtypes_h__
#include "ns.h"
//ceilingstat/floorstat:
// bit 0: 1 = parallaxing, 0 = not "P"
// bit 1: 1 = sloped, 0 = not
// bit 2: 1 = swap x&y, 0 = not "F"
// bit 3: 1 = double smooshiness "E"
// bit 4: 1 = x-flip "F"
// bit 5: 1 = y-flip "F"
// bit 6: 1 = Align texture to first wall of sector "R"
// bits 8-7: "T"
// 00 = normal floors
// 01 = masked floors
// 10 = transluscent masked floors
// 11 = reverse transluscent masked floors
// bit 9: 1 = blocking ceiling/floor
// bit 10: 1 = YAX'ed ceiling/floor
// bit 11: 1 = hitscan-sensitive ceiling/floor
// bits 12-14: reserved
// bit 15: SW: block FAF hitscans
//////////////////// Version 7 map format ////////////////////
enum
{
CSTAT_SECTOR_SKY = 1,
CSTAT_SECTOR_SLOPE = 2,
CSTAT_SECTOR_SWAPXY = 4,
CSTAT_SECTOR_TEXHALF = 8,
CSTAT_SECTOR_XFLIP = 16,
CSTAT_SECTOR_YFLIP = 32,
CSTAT_SECTOR_ALIGN = 64,
CSTAT_SECTOR_TRANS = 128,
CSTAT_SECTOR_TRANS_INVERT = 256,
CSTAT_SECTOR_METHOD = 384,
SECTOREX_CLOUDSCROLL = 1,
};
enum
{
PORTAL_SECTOR_FLOOR = 1,
PORTAL_SECTOR_CEILING = 2,
PORTAL_SECTOR_FLOOR_REFLECT = 3,
PORTAL_SECTOR_CEILING_REFLECT = 4,
PORTAL_WALL_VIEW = 5,
PORTAL_WALL_MIRROR = 6,
PORTAL_WALL_TO_SPRITE = 7,
PORTAL_SECTOR_GEOMETRY = 8,
};
enum EDirty
{
FloorDirty = 1,
CeilingDirty = 2,
GeometryDirty = 4,
AllDirty = 7
};
BEGIN_BLD_NS
struct XWALL;
struct XSECTOR;
END_BLD_NS
//40 bytes
class DCoreActor;
struct walltype;
struct sectortype
{
DCoreActor* firstEntry, * lastEntry;
int32_t wallptr;
int32_t ceilingz, floorz;
int16_t wallnum;
uint16_t ceilingstat, floorstat;
int16_t ceilingpicnum, ceilingheinum;
int16_t floorpicnum, floorheinum;
int8_t ceilingshade;
uint8_t ceilingpal; /*CM_FLOORZ:*/
int8_t floorshade;
uint8_t floorpal;;
uint8_t /*CM_CEILINGZ:*/ visibility, fogpal;
union {
int16_t lotag, type;
};
int16_t hitag;
int16_t extra;
uint8_t dirty;
uint8_t exflags;
uint8_t portalflags;
int8_t portalnum;
float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_;
// section reference (not written to a savegame
int numsections;
int* sections;
// Game specific extensions. Due to how sectors are used they need to be defined in the global class. :(
union
{
struct // DukeRR
{
uint8_t keyinfo;
uint8_t shadedsector;
TObjPtr<DCoreActor*> hitagactor; // we need this because Duke stores an actor in the hitag field. Is really a DDukeActor, but cannot be declared here safely.
};
struct // Blood
{
BLD_NS::XSECTOR* _xs;
TObjPtr<DCoreActor*> upperLink, lowerLink;
int baseFloor, baseCeil;
int velFloor, velCeil;
uint8_t slopewallofs;
};
struct // Exhumed
{
sectortype* pSoundSect;
sectortype* pAbove, * pBelow;
int Depth;
short Sound;
short Flag;
short Damage;
short Speed;
};
struct // SW
{
// No need to allocate this on demand as it is smaller than what Blood needs.
int flags;
int depth_fixed;
short stag; // ST? tag number - for certain things it helps to know it
short ang;
short height;
short speed;
short damage;
short number; // usually used for matching number
bool u_defined;
uint8_t flags2;
};
};
int ceilingxpan() const { return int(ceilingxpan_); }
int ceilingypan() const { return int(ceilingypan_); }
int floorxpan() const { return int(floorxpan_); }
int floorypan() const { return int(floorypan_); }
void setfloorxpan(float val) { floorxpan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setfloorypan(float val) { floorypan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setceilingxpan(float val) { ceilingxpan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setceilingypan(float val) { ceilingypan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void addfloorxpan(float add) { floorxpan_ = fmodf(floorxpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addfloorypan(float add) { floorypan_ = fmodf(floorypan_ + add + 512, 256); } // +512 is for handling negative offsets
void addceilingxpan(float add) { ceilingxpan_ = fmodf(ceilingxpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addceilingypan(float add) { ceilingypan_ = fmodf(ceilingypan_ + add + 512, 256); } // +512 is for handling negative offsets
walltype* firstWall() const;
walltype* lastWall() const;
// 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::XSECTOR& xs() const { return *_xs; }
bool hasX() const { return _xs != nullptr; } // 0 is invalid!
void allocX();
// same for SW
bool hasU() const { return u_defined; }
};
//cstat:
// bit 0: 1 = Blocking wall (use with clipmove, getzrange) "B"
// bit 1: 1 = bottoms of invisible walls swapped, 0 = not "2"
// bit 2: 1 = align picture on bottom (for doors), 0 = top "O"
// bit 3: 1 = x-flipped, 0 = normal "F"
// bit 4: 1 = masking wall, 0 = not "M"
// bit 5: 1 = 1-way wall, 0 = not "1"
// bit 6: 1 = Blocking wall (use with hitscan / cliptype 1) "H"
// bit 7: 1 = Transluscence, 0 = not "T"
// bit 8: 1 = y-flipped, 0 = normal "F"
// bit 9: 1 = Transluscence reversing, 0 = normal "T"
// bits 10 and 11: reserved (in use by YAX)
// bits 12-15: reserved (14: temp use by editor)
//32 bytes
struct walltype
{
union {
struct
{
int32_t x, y;
};
vec2_t pos;
};
int32_t point2, nextwall, sector, nextsector;
uint16_t cstat;
int16_t picnum, overpicnum;
int8_t shade;
uint8_t pal, xrepeat, yrepeat;
union {
int16_t lotag, type;
};
int16_t hitag;
int16_t extra;
uint16_t portalnum;
float xpan_, ypan_;
binangle clipangle;
uint8_t portalflags;
uint8_t lengthflags;
int length; // cached value to avoid calling sqrt repeatedly.
// 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
void setypan(float add) { ypan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets
void addxpan(float add) { xpan_ = fmodf(xpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addypan(float add) { ypan_ = fmodf(ypan_ + add + 512, 256); } // +512 is for handling negative offsets
sectortype* nextSector() const;
sectortype* sectorp() const;
walltype* nextWall() const;
walltype* lastWall() const;
walltype* point2Wall() const;
vec2_t delta() const { return point2Wall()->pos - pos; }
vec2_t center() const { return(point2Wall()->pos + pos) / 2; }
int deltax() const { return point2Wall()->x - x; }
int deltay() const { return point2Wall()->y - y; }
bool twoSided() const { return nextsector >= 0; }
void move(int newx, int newy);
void moved();
Blood::XWALL& xw() const { return *_xw; }
bool hasX() const { return _xw != nullptr; }
void allocX();
#if 0
// make sure we do not accidentally copy this
walltype() = default;
walltype(const walltypev7&) = delete;
walltype& operator=(const walltypev7&) = delete;
#endif
};
//cstat:
// bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B"
// bit 1: 1 = transluscence, 0 = normal "T"
// bit 2: 1 = x-flipped, 0 = normal "F"
// bit 3: 1 = y-flipped, 0 = normal "F"
// bits 5-4: 00 = FACE sprite (default) "R"
// 01 = WALL sprite (like masked walls)
// 10 = FLOOR sprite (parallel to ceilings&floors)
// bit 6: 1 = 1-sided sprite, 0 = normal "1"
// bit 7: 1 = Real centered centering, 0 = foot center "C"
// bit 8: 1 = Blocking sprite (use with hitscan / cliptype 1) "H"
// bit 9: 1 = Transluscence reversing, 0 = normal "T"
// bit 10: reserved (in use by a renderer hack, see CSTAT_SPRITE_MDHACK)
// bit 11: 1 = determine shade based only on its own shade member (see CON's spritenoshade command), i.e.
// don't take over shade from parallaxed ceiling/nonparallaxed floor
// (NOTE: implemented on the game side)
// bit 12: reserved
// bit 13: 1 = does not cast shadow
// bit 14: 1 = invisible but casts shadow
// bit 15: 1 = Invisible sprite, 0 = not invisible
#ifndef buildtypes_h__enums
enum
{
CSTAT_SPRITE_BLOCK = 1u,
CSTAT_SPRITE_TRANSLUCENT = 1u<<1u,
CSTAT_SPRITE_XFLIP = 1u<<2u,
CSTAT_SPRITE_YFLIP = 1u<<3u,
CSTAT_SPRITE_ALIGNMENT = 1u<<4u | 1u<<5u, // (cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_xxxxxx can be used to check sprite alignment
CSTAT_SPRITE_ONE_SIDED = 1u<<6u,
CSTAT_SPRITE_YCENTER = 1u<<7u,
CSTAT_SPRITE_BLOCK_HITSCAN = 1u<<8u,
CSTAT_SPRITE_BLOCK_ALL = CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_BLOCK,
CSTAT_SPRITE_TRANSLUCENT_INVERT = 1u<<9u,
CSTAT_SPRITE_RESERVED1 = 1u<<10u, // used by Duke 3D (Polymost)
CSTAT_SPRITE_RESERVED2 = 1u<<11u, // used by Duke 3D (EDuke32 game code extension)
CSTAT_SPRITE_RESERVED3 = 1u<<12u, // used by Shadow Warrior, Blood
CSTAT_SPRITE_RESERVED4 = 1u<<13u, // used by Duke 3D (Polymer), Shadow Warrior, Blood
CSTAT_SPRITE_RESERVED5 = 1u<<14u, // used by Duke 3D (Polymer), Shadow Warrior, Blood
CSTAT_SPRITE_INVISIBLE = 1u<<15u,
};
enum
{
CSTAT2_SPRITE_MDLROTATE = 1, // Only for tsprites: rotate if this is a model or voxel.
CSTAT2_SPRITE_NOFIND = 2, // Invisible to neartag and hitscan
CSTAT2_SPRITE_MAPPED = 4, // sprite was mapped for automap
};
enum
{
CSTAT_SPRITE_ALIGNMENT_FACING = 0,
CSTAT_SPRITE_ALIGNMENT_WALL = 1u<<4u,
CSTAT_SPRITE_ALIGNMENT_FLOOR = 1u<<5u,
CSTAT_SPRITE_ALIGNMENT_SLAB = 1u<<4u | 1u<<5u,
CSTAT_SPRITE_ALIGNMENT_SLOPE = 1u << 4u | 1u << 5u,
CSTAT_SPRITE_ALIGNMENT_MASK = 1u<<4u | 1u<<5u,
};
enum
{
CSTAT_WALL_BLOCK = 1u,
CSTAT_WALL_BOTTOM_SWAP = 1u<<1u,
CSTAT_WALL_ALIGN_BOTTOM = 1u<<2u,
CSTAT_WALL_XFLIP = 1u<<3u,
CSTAT_WALL_MASKED = 1u<<4u,
CSTAT_WALL_1WAY = 1u<<5u,
CSTAT_WALL_BLOCK_HITSCAN = 1u<<6u,
CSTAT_WALL_TRANSLUCENT = 1u<<7u,
CSTAT_WALL_YFLIP = 1u<<8u,
CSTAT_WALL_TRANS_FLIP = 1u<<9u,
CSTAT_WALL_YAX_UPWALL = 1u<<10u, // EDuke32 extension
CSTAT_WALL_YAX_DOWNWALL = 1u<<11u, // EDuke32 extension
CSTAT_WALL_ROTATE_90 = 1u<<12u, // EDuke32 extension
CSTAT_WALL_RESERVED1 = 1u<<13u,
CSTAT_WALL_RESERVED2 = 1u<<14u, // used by Shadow Warrior, Blood
CSTAT_WALL_RESERVED3 = 1u<<15u, // used by Shadow Warrior, Blood
};
#endif
#ifndef buildtypes_h__enums
struct spritetypebase
{
union {
struct
{
int32_t x, y, z;
};
vec3_t pos;
};
union {
struct
{
int32_t ox, oy, oz;
};
vec3_t opos;
};
sectortype* sectp;
uint16_t cstat;
int16_t picnum;
int8_t shade;
uint8_t pal, clipdist, blend;
uint8_t xrepeat, yrepeat;
int8_t xoffset, yoffset;
int16_t statnum;
int16_t oang, ang;
int16_t xvel;
int16_t yvel;
union {
int16_t zvel, inittype;
};
union {
int16_t lotag, type;
};
union {
int16_t hitag, flags;
};
int16_t extra;
int16_t detail;
int time;
uint16_t cstat2;
void setpos(const vec3_t& newpos)
{
pos = newpos;
}
int32_t interpolatedx(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(ox, x, smoothratio, scale);
}
int32_t interpolatedy(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(oy, y, smoothratio, scale);
}
int32_t interpolatedz(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(oz, z, smoothratio, scale);
}
vec2_t interpolatedvec2(double const smoothratio, int const scale = 16)
{
return
{
interpolatedx(smoothratio, scale),
interpolatedy(smoothratio, scale)
};
}
vec3_t interpolatedvec3(double const smoothratio, int const scale = 16)
{
return
{
interpolatedx(smoothratio, scale),
interpolatedy(smoothratio, scale),
interpolatedz(smoothratio, scale)
};
}
int16_t interpolatedang(double const smoothratio)
{
return interpolatedangle(oang, ang, smoothratio, 16);
}
sectortype* sector() const;
int sectno() const;
bool insector() const;
void setsector(sectortype*);
void setsector(int);
};
struct spritetype : public spritetypebase
{
int16_t owner;
int16_t detail;
int16_t wall;
int8_t wdist;
void clear()
{
auto sect = sectp;
int stat = statnum;
int save = time; // this may not be cleared ever!!!
memset(this, 0, sizeof(*this));
time = save;
sectp = sect;
statnum = stat;
}
void backupx()
{
opos.x = pos.x;
}
void backupy()
{
opos.y = pos.y;
}
void backupz()
{
opos.z = pos.z;
}
void backupvec2()
{
opos.vec2 = pos.vec2;
}
void backuppos()
{
opos = pos;
}
void backupang()
{
oang = ang;
}
void backuploc()
{
backuppos();
backupang();
}
};
// This is mostly the same, but it omits the 'owner' field in favor of a full actor pointer.
// Incompatibility with spritetype regarding assignments is deliberate as these serve a fundamentally different purpose!
struct tspritetype : public spritetypebase
{
DCoreActor* ownerActor;
void copyfrom(spritetype* spr)
{
pos = spr->pos;
opos = spr->opos;
cstat = spr->cstat;
picnum = spr->picnum;
shade = spr->shade;
pal = spr->pal;
clipdist = spr->clipdist;
blend = spr->blend;
xrepeat = spr->xrepeat;
yrepeat = spr->yrepeat;
xoffset = spr->xoffset;
yoffset = spr->yoffset;
sectp = spr->sectp;
statnum = spr->statnum;
ang = spr->ang;
oang = spr->oang;
xvel = spr->xvel;
yvel = spr->yvel;
zvel = spr->zvel;
lotag = spr->lotag;
hitag = spr->hitag;
extra = spr->extra;
time = spr->time;
cstat2 = spr->cstat2;
ownerActor = nullptr;
}
};
#endif
//////////////////// END Version 7 map format ////////////////
#ifndef buildtypes_h__enums
#define buildtypes_h__enums
#endif
#endif // buildtypes_h__

View file

@ -41,9 +41,6 @@
#include "gl_renderer.h"
#endif
TArray<sectortype> sector;
TArray<walltype> wall;
int32_t mdtims, omdtims;
float fcosglobalang, fsinglobalang;

View file

@ -3902,8 +3902,8 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
FRenderStyle RenderStyle;
if (trans)
{
RenderStyle = GetRenderStyle(0, !!(tspr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
alpha = GetAlphaFromBlend((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
RenderStyle = GetRenderStyle(0, !!(tspr->cstat & CSTAT_SPRITE_TRANS_FLIP));
alpha = GetAlphaFromBlend((tspr->cstat & CSTAT_SPRITE_TRANS_FLIP) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
}
else
{

View file

@ -570,7 +570,7 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR)
{
if ((spr->cstat & (CSTAT_SPRITE_ONE_SIDED | CSTAT_SPRITE_YFLIP)) == (CSTAT_SPRITE_ONE_SIDED | CSTAT_SPRITE_YFLIP))
if ((spr->cstat & (CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_YFLIP)) == (CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_YFLIP))
continue; // upside down
floorsprites.Push(spr);
}
@ -639,8 +639,8 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
float alpha = 1;
if (spr->cstat & CSTAT_SPRITE_TRANSLUCENT)
{
rs = GetRenderStyle(0, !!(spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
alpha = GetAlphaFromBlend((spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
rs = GetRenderStyle(0, !!(spr->cstat & CSTAT_SPRITE_TRANS_FLIP));
alpha = GetAlphaFromBlend((spr->cstat & CSTAT_SPRITE_TRANS_FLIP) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
color.a = uint8_t(alpha * 255);
}

View file

@ -380,7 +380,7 @@ static int32_t LoadMapHack(const char *filename, SpawnSpriteDef& sprites)
return 0;
}
void G_LoadMapHack(const char* filename, const unsigned char* md4, SpawnSpriteDef& sprites)
void loadMapHack(const char* filename, const unsigned char* md4, SpawnSpriteDef& sprites)
{
hw_ClearSplitSector();
blockingpairs.Reset();

View file

@ -51,6 +51,14 @@
extern BitArray clipsectormap;
int numsectors, numwalls; // not really needed anymore, need to be refactored out (58x numsectors, 48x numwalls)
TArray<sectortype> sector;
TArray<walltype> wall;
// for differential savegames.
TArray<sectortype> sectorbackup;
TArray<walltype> wallbackup;
// needed for skipping over to get the map size first.
enum
{
@ -239,7 +247,7 @@ static void SetWallPalV5()
}
}
void ValidateSprite(spritetype& spr, int sectnum, int index)
void validateSprite(spritetype& spr, int sectnum, int index)
{
bool bugged = false;
if ((unsigned)spr.statnum >= MAXSTATUS)
@ -401,7 +409,7 @@ void fixSectors()
}
}
void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, int* cursectnum, SpawnSpriteDef& sprites)
void loadMap(const char* filename, int flags, vec3_t* pos, int16_t* ang, int* cursectnum, SpawnSpriteDef& sprites)
{
inputState.ClearAllInput();
@ -472,7 +480,7 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang,
case 6: ReadSpriteV6(fr, sprites.sprites[i], secno); break;
default: ReadSpriteV7(fr, sprites.sprites[i], secno); break;
}
ValidateSprite(sprites.sprites[i], secno, i);
validateSprite(sprites.sprites[i], secno, i);
}
@ -486,7 +494,7 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang,
auto buffer = fr.Read();
unsigned char md4[16];
md4once(buffer.Data(), buffer.Size(), md4);
G_LoadMapHack(filename, md4, sprites);
loadMapHack(filename, md4, sprites);
setWallSectors();
hw_CreateSections();
sectionGeometry.SetSize(sections.Size());
@ -514,7 +522,7 @@ void loadMapBackup(const char* filename)
}
else
{
engineLoadBoard(filename, 0, &pos, &scratch, &scratch2, scratch3);
loadMap(filename, 0, &pos, &scratch, &scratch2, scratch3);
}
}

663
source/core/maptypes.h Normal file
View file

@ -0,0 +1,663 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2020, 2021 - Christoph Oelckers
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under 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 program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#pragma once
#include <stdint.h>
#include "ns.h"
#include "tarray.h"
//=============================================================================
//
// Constants
//
//=============================================================================
// the various portal types
enum EPortalBits
{
PORTAL_SECTOR_FLOOR = 1,
PORTAL_SECTOR_CEILING = 2,
PORTAL_SECTOR_FLOOR_REFLECT = 3,
PORTAL_SECTOR_CEILING_REFLECT = 4,
PORTAL_WALL_VIEW = 5,
PORTAL_WALL_MIRROR = 6,
PORTAL_WALL_TO_SPRITE = 7,
PORTAL_SECTOR_GEOMETRY = 8,
};
// Original Build sector bit flags.
enum ESectorBits
{
CSTAT_SECTOR_SKY = 1,
CSTAT_SECTOR_SLOPE = 2,
CSTAT_SECTOR_SWAPXY = 4,
CSTAT_SECTOR_TEXHALF = 8,
CSTAT_SECTOR_XFLIP = 16,
CSTAT_SECTOR_YFLIP = 32,
CSTAT_SECTOR_ALIGN = 64,
CSTAT_SECTOR_TRANS = 128,
CSTAT_SECTOR_TRANS_INVERT = 256,
CSTAT_SECTOR_METHOD = 384,
};
// Extended sector bit flags.
enum ESectorExBits
{
SECTOREX_CLOUDSCROLL = 1,
};
// Flags for retriangulation
enum EDirty
{
FloorDirty = 1,
CeilingDirty = 2,
GeometryDirty = 4,
AllDirty = 7
};
enum EWallBits // names are from Shadow Warrior
{
CSTAT_WALL_BLOCK = 1, // bit 0: 1 = Blocking wall (use with clipmove, getzrange) "B"
CSTAT_WALL_BOTTOM_SWAP = 2, // bit 1: 1 = bottoms of invisible walls swapped, 0 = not "2"
CSTAT_WALL_ALIGN_BOTTOM = 4, // bit 2: 1 = align picture on bottom (for doors), 0 = top "O"
CSTAT_WALL_XFLIP = 8, // bit 3: 1 = x-flipped, 0 = normal "F"
CSTAT_WALL_MASKED = 16, // bit 4: 1 = masking wall, 0 = not "M"
CSTAT_WALL_1WAY = 32, // bit 5: 1 = 1-way wall, 0 = not "1"
CSTAT_WALL_BLOCK_HITSCAN = 64, // bit 6: 1 = Blocking wall (use with hitscan / cliptype 1) "H"
CSTAT_WALL_TRANSLUCENT = 128, // bit 7: 1 = Transluscence, 0 = not "T"
CSTAT_WALL_YFLIP = 256, // bit 8: 1 = y-flipped, 0 = normal "F"
CSTAT_WALL_TRANS_FLIP = 512, // bit 9: 1 = Transluscence reversing, 0 = normal "T"
CSTAT_WALL_ROTATE_90 = 1<<12, // EDuke32 extension supported by Raze
CSTAT_WALL_BLOCK_ACTOR = 1<<14, // SW specific. Also used by Blood for different purposes
CSTAT_WALL_WARP_HITSCAN = 1<<15, // SW specific. Also used by Blood for different purposes
};
enum ESpriteBits // names mostly from SW.
{
CSTAT_SPRITE_BLOCK = 1, // bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B"
CSTAT_SPRITE_TRANSLUCENT = 2, // bit 1: 1 = transluscence, 0 = normal "T"
CSTAT_SPRITE_XFLIP = 4, // bit 2: 1 = x-flipped, 0 = normal "F"
CSTAT_SPRITE_YFLIP = 8, // bit 3: 1 = y-flipped, 0 = normal "F"
CSTAT_SPRITE_ALIGNMENT_FACING = 0, // bits 5-4: 00 = FACE sprite (default) "R"
CSTAT_SPRITE_ALIGNMENT_WALL = 16, // 01 = WALL sprite (like masked walls)
CSTAT_SPRITE_ALIGNMENT_FLOOR = 32, // 10 = FLOOR sprite (parallel to ceilings&floors)
CSTAT_SPRITE_ALIGNMENT_SLAB = 48, // 11 = either voxel or slope sprite, depending on the situation
CSTAT_SPRITE_ALIGNMENT_SLOPE = 48,
CSTAT_SPRITE_ALIGNMENT_MASK = 48,
CSTAT_SPRITE_ALIGNMENT = 48,
CSTAT_SPRITE_ONE_SIDE = 64, // bit 6: 1 = 1-sided sprite, 0 = normal "1"
CSTAT_SPRITE_YCENTER = 128, // bit 7: 1 = Real centered centering, 0 = foot center "C"
CSTAT_SPRITE_BLOCK_HITSCAN = 256, // bit 8: 1 = Blocking sprite (use with hitscan / cliptype 1) "H"
CSTAT_SPRITE_TRANS_FLIP = 512, // bit 9: 1 = Transluscence reversing, 0 = normal "T"
CSTAT_SPRITE_BLOCK_ALL = CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_BLOCK, // 257
CSTAT_SPRITE_RESTORE = 1<<12, // SW specific
CSTAT_SPRITE_CLOSE_FLOOR = 1<<13, // SW specific - tells whether a sprite started out close to a ceiling or floor
CSTAT_SPRITE_BLOCK_MISSILE = 1<<14, // SW specific
CSTAT_SPRITE_BREAKABLE = CSTAT_SPRITE_BLOCK_HITSCAN|CSTAT_SPRITE_BLOCK_MISSILE,
CSTAT_SPRITE_INVISIBLE = 32768, // bit 15: 1 = Invisible sprite, 0 = not invisible
};
enum ESpriteBits2
{
CSTAT2_SPRITE_MDLROTATE = 1, // Only for tsprites: rotate if this is a model or voxel.
CSTAT2_SPRITE_NOFIND = 2, // Invisible to neartag and hitscan
CSTAT2_SPRITE_MAPPED = 4, // sprite was mapped for automap
};
//=============================================================================
//
// external references
//
//=============================================================================
// For Blood we need to pull in some game specific references.
BEGIN_BLD_NS
struct XWALL;
struct XSECTOR;
END_BLD_NS
class DCoreActor;
struct walltype;
//=============================================================================
//
// internal sector struct - no longer identical with on-disk format
//
//=============================================================================
struct sectortype
{
// Fields were reordered by size, some also enlarged.
DCoreActor* firstEntry, * lastEntry;
int32_t wallptr;
int32_t ceilingz;
int32_t floorz;
// panning byte fields were promoted to full floats to enable panning interpolation.
float ceilingxpan_;
float ceilingypan_;
float floorxpan_;
float floorypan_;
int16_t wallnum;
uint16_t ceilingstat;
uint16_t floorstat;
int16_t ceilingpicnum;
int16_t ceilingheinum;
int16_t floorpicnum;
int16_t floorheinum;
union { int16_t lotag, type; }; // type is for Blood.
int16_t hitag;
int16_t extra;
int8_t ceilingshade;
uint8_t ceilingpal;
int8_t floorshade;
uint8_t floorpal;;
uint8_t visibility;
uint8_t fogpal; // EDuke32 extension - was originally a filler byte
// new additions not from the binary map format.
uint8_t dirty;
uint8_t exflags;
uint8_t portalflags;
int8_t portalnum;
// Game specific extensions. Due to how sectors are used they need to be defined in the global class. :(
union
{
struct // DukeRR
{
uint8_t keyinfo; // This was originally the repurposed filler byte.
uint8_t shadedsector;
TObjPtr<DCoreActor*> hitagactor; // we need this because Duke stores an actor in the hitag field. Is really a DDukeActor, but cannot be declared here safely.
};
struct // Blood
{
BLD_NS::XSECTOR* _xs;
TObjPtr<DCoreActor*> upperLink;
TObjPtr<DCoreActor*> lowerLink;
int baseFloor;
int baseCeil;
int velFloor;
int velCeil;
uint8_t slopewallofs; // This was originally the repurposed filler byte.
};
struct // Exhumed
{
sectortype* pSoundSect;
sectortype* pAbove;
sectortype* pBelow;
int Depth;
short Sound;
short Flag;
short Damage;
short Speed;
};
struct // SW
{
// No need to allocate this on demand as it is smaller than what Blood needs.
int flags;
int depth_fixed;
short stag; // ST? tag number - for certain things it helps to know it
short ang;
short height;
short speed;
short damage;
short number; // usually used for matching number
bool u_defined;
uint8_t flags2;
};
};
int ceilingxpan() const { return int(ceilingxpan_); }
int ceilingypan() const { return int(ceilingypan_); }
int floorxpan() const { return int(floorxpan_); }
int floorypan() const { return int(floorypan_); }
void setfloorxpan(float val) { floorxpan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setfloorypan(float val) { floorypan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setceilingxpan(float val) { ceilingxpan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setceilingypan(float val) { ceilingypan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void addfloorxpan(float add) { floorxpan_ = fmodf(floorxpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addfloorypan(float add) { floorypan_ = fmodf(floorypan_ + add + 512, 256); } // +512 is for handling negative offsets
void addceilingxpan(float add) { ceilingxpan_ = fmodf(ceilingxpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addceilingypan(float add) { ceilingypan_ = fmodf(ceilingypan_ + add + 512, 256); } // +512 is for handling negative offsets
walltype* firstWall() const;
walltype* lastWall() const;
// 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::XSECTOR& xs() const { return *_xs; }
bool hasX() const { return _xs != nullptr; } // 0 is invalid!
void allocX();
// same for SW
bool hasU() const { return u_defined; }
};
//=============================================================================
//
// internal wall struct - no longer identical with on-disk format
//
//=============================================================================
struct walltype
{
// todo: get rid of the single variables!
union {
struct { int32_t x, y; };
vec2_t pos;
};
int32_t point2;
int32_t nextwall;
int32_t sector; // Build never had this...
int32_t nextsector;
// Again, panning fields extended for interpolation.
float xpan_;
float ypan_;
uint16_t cstat;
int16_t picnum;
int16_t overpicnum;
union { int16_t lotag, type; }; // type is for Blood
int16_t hitag;
int16_t extra;
int8_t shade;
uint8_t pal;
uint8_t xrepeat;
uint8_t yrepeat;
// extensions not from the binary map format.
binangle clipangle;
int length; // cached value to avoid calling sqrt repeatedly.
uint16_t portalnum;
uint8_t portalflags;
uint8_t lengthflags;
// 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
void setypan(float add) { ypan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets
void addxpan(float add) { xpan_ = fmodf(xpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addypan(float add) { ypan_ = fmodf(ypan_ + add + 512, 256); } // +512 is for handling negative offsets
sectortype* nextSector() const;
sectortype* sectorp() const;
walltype* nextWall() const;
walltype* lastWall() const;
walltype* point2Wall() const;
vec2_t delta() const { return point2Wall()->pos - pos; }
vec2_t center() const { return(point2Wall()->pos + pos) / 2; }
int deltax() const { return point2Wall()->x - x; }
int deltay() const { return point2Wall()->y - y; }
bool twoSided() const { return nextsector >= 0; }
void move(int newx, int newy);
void moved();
Blood::XWALL& xw() const { return *_xw; }
bool hasX() const { return _xw != nullptr; }
void allocX();
};
//=============================================================================
//
// internal sprite struct - no longer identical with on-disk format
//
//=============================================================================
struct spritetypebase
{
// todo: get rid of the single variables!
union {
struct { int32_t x, y, z; };
vec3_t pos;
};
union {
struct { int32_t ox, oy, oz; };
vec3_t opos;
};
sectortype* sectp;
uint16_t cstat;
int16_t picnum;
int16_t statnum;
int16_t ang;
int16_t oang;
int16_t xvel;
int16_t yvel;
union { int16_t zvel, inittype; }; // inittype, type and flags are for Blood.
union { int16_t lotag, type; };
union { int16_t hitag, flags; };
int16_t extra;
int16_t detail;
int8_t shade;
uint8_t pal;
uint8_t clipdist;
uint8_t blend;
uint8_t xrepeat;
uint8_t yrepeat;
int8_t xoffset;
int8_t yoffset;
// extensions not from the binary map format.
int time;
uint16_t cstat2;
void setpos(const vec3_t& newpos)
{
pos = newpos;
}
int32_t interpolatedx(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(ox, x, smoothratio, scale);
}
int32_t interpolatedy(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(oy, y, smoothratio, scale);
}
int32_t interpolatedz(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(oz, z, smoothratio, scale);
}
vec2_t interpolatedvec2(double const smoothratio, int const scale = 16)
{
return
{
interpolatedx(smoothratio, scale),
interpolatedy(smoothratio, scale)
};
}
vec3_t interpolatedvec3(double const smoothratio, int const scale = 16)
{
return
{
interpolatedx(smoothratio, scale),
interpolatedy(smoothratio, scale),
interpolatedz(smoothratio, scale)
};
}
int16_t interpolatedang(double const smoothratio)
{
return interpolatedangle(oang, ang, smoothratio, 16);
}
void backupx()
{
opos.x = pos.x;
}
void backupy()
{
opos.y = pos.y;
}
void backupz()
{
opos.z = pos.z;
}
void backupvec2()
{
opos.vec2 = pos.vec2;
}
void backuppos()
{
opos = pos;
}
void backupang()
{
oang = ang;
}
void backuploc()
{
backuppos();
backupang();
}
sectortype* sector() const;
int sectno() const;
bool insector() const;
void setsector(sectortype*);
void setsector(int);
};
struct spritetype : public spritetypebase
{
int16_t owner;
int16_t detail;
int16_t wall; // wall and wdist are for Polymost only.
int8_t wdist;
void clear()
{
auto sect = sectp;
int stat = statnum;
int save = time; // this may not be cleared ever!!!
memset(this, 0, sizeof(*this));
time = save;
sectp = sect;
statnum = stat;
}
};
//=============================================================================
//
// This is mostly the same, but it omits the 'owner' field in favor of a full actor pointer.
// Incompatibility with spritetype regarding assignments is deliberate as these serve a fundamentally different purpose!
//
//=============================================================================
struct tspritetype : public spritetypebase
{
DCoreActor* ownerActor;
void copyfrom(spritetype* spr)
{
pos = spr->pos;
opos = spr->opos;
cstat = spr->cstat;
picnum = spr->picnum;
shade = spr->shade;
pal = spr->pal;
clipdist = spr->clipdist;
blend = spr->blend;
xrepeat = spr->xrepeat;
yrepeat = spr->yrepeat;
xoffset = spr->xoffset;
yoffset = spr->yoffset;
sectp = spr->sectp;
statnum = spr->statnum;
ang = spr->ang;
oang = spr->oang;
xvel = spr->xvel;
yvel = spr->yvel;
zvel = spr->zvel;
lotag = spr->lotag;
hitag = spr->hitag;
extra = spr->extra;
time = spr->time;
cstat2 = spr->cstat2;
ownerActor = nullptr;
}
};
extern TArray<sectortype> sector;
extern TArray<walltype> wall;
extern TArray<sectortype> sectorbackup;
extern TArray<walltype> wallbackup;
extern int numsectors, numwalls;
//=============================================================================
//
// inlines
//
//=============================================================================
inline bool validSectorIndex(int sectnum)
{
return sectnum >= 0 && sectnum < numsectors;
}
inline bool validWallIndex(int wallnum)
{
return wallnum >= 0 && wallnum < numwalls;
}
inline sectortype* spritetypebase::sector() const
{
return sectp;
}
inline int spritetypebase::sectno() const
{
return sectp? ::sector.IndexOf(sectp) : -1;
}
inline void spritetypebase::setsector(sectortype* sect)
{
// place for asserts.
sectp = sect;
}
inline void spritetypebase::setsector(int sec)
{
// place for asserts.
sectp = validSectorIndex(sec)? &::sector[sec] : nullptr;
}
inline bool spritetypebase::insector() const
{
return sectp != nullptr;
}
inline sectortype* walltype::nextSector() const
{
return !validSectorIndex(nextsector)? nullptr : &::sector[nextsector];
}
inline walltype* walltype::nextWall() const
{
return !validWallIndex(nextwall)? nullptr : &::wall[nextwall];
}
inline sectortype* walltype::sectorp() const
{
return &::sector[sector]; // cannot be -1 in a proper map.
}
inline walltype* walltype::lastWall() const
{
int index = wall.IndexOf(this);
if (index > 0 && wall[index - 1].point2 == index) return &wall[index - 1];
int check = index;
for (int i = 0; i < numwalls; i++)
{
int next = wall[check].point2;
if (next == index) return &wall[check];
check = next;
}
return nullptr;
}
inline walltype* walltype::point2Wall() const
{
return &::wall[point2]; // cannot be -1 in a proper map.
}
inline walltype* sectortype::firstWall() const
{
return &wall[wallptr]; // cannot be -1 in a proper map
}
inline walltype* sectortype::lastWall() const
{
return &wall[wallptr + wallnum - 1]; // cannot be -1 in a proper map
}
inline void walltype::moved()
{
lengthflags = 3;
sectorp()->dirty = EDirty::AllDirty;
}
inline void walltype::move(int newx, int newy)
{
pos.x = newx;
pos.y = newy;
lengthflags = 3;
sectorp()->dirty = EDirty::AllDirty;
}
//=============================================================================
//
// Map loader stuff
//
//=============================================================================
struct SpawnSpriteDef;
void allocateMapArrays(int numsprites);
void validateSprite(spritetype& spr, int secno, int index);
void fixSectors();
void loadMap(const char *filename, int flags, vec3_t *pos, int16_t *ang, int *cursectnum, SpawnSpriteDef& sprites);
void loadMapBackup(const char* filename);
void loadMapHack(const char* filename, const unsigned char*, SpawnSpriteDef& sprites);

View file

@ -584,7 +584,7 @@ void BunchDrawer::ProcessSection(int sectionnum, bool portal)
// this checks if the sprite is it behind the camera, which will not work if the pitch is high enough to necessitate a FOV of more than 180°.
//if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) || (hw_models && tile2model[spr->picnum].modelid >= 0) || ((sx * gcosang) + (sy * gsinang) > 0))
{
if ((spr->cstat & (CSTAT_SPRITE_ONE_SIDED | CSTAT_SPRITE_ALIGNMENT_MASK)) != (CSTAT_SPRITE_ONE_SIDED | CSTAT_SPRITE_ALIGNMENT_WALL) ||
if ((spr->cstat & (CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_ALIGNMENT_MASK)) != (CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_ALIGNMENT_WALL) ||
(r_voxels && tiletovox[spr->picnum] >= 0 && voxmodels[tiletovox[spr->picnum]]) ||
(r_voxels && gi->Voxelize(spr->picnum) > -1) ||
DMulScale(bcos(spr->ang), -sx, bsin(spr->ang), -sy, 6) > 0)

View file

@ -388,8 +388,8 @@ inline void SetSpriteTranslucency(const tspritetype* sprite, float& alpha, FRend
bool trans = (sprite->cstat & CSTAT_SPRITE_TRANSLUCENT);
if (trans)
{
RenderStyle = GetRenderStyle(0, !!(sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
alpha = GetAlphaFromBlend((sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
RenderStyle = GetRenderStyle(0, !!(sprite->cstat & CSTAT_SPRITE_TRANS_FLIP));
alpha = GetAlphaFromBlend((sprite->cstat & CSTAT_SPRITE_TRANS_FLIP) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
}
else
{

View file

@ -367,7 +367,7 @@ void HWFlat::ProcessFlatSprite(HWDrawInfo* di, tspritetype* sprite, sectortype*
visibility = sectorVisibility(sector) *(4.f / 5.f); // The factor comes directly from Polymost. What is it with Build and these magic factors?
// Weird Build logic that really makes no sense.
if ((sprite->cstat & CSTAT_SPRITE_ONE_SIDED) != 0 && (di->Viewpoint.Pos.Z < z) == ((sprite->cstat & CSTAT_SPRITE_YFLIP) == 0))
if ((sprite->cstat & CSTAT_SPRITE_ONE_SIDE) != 0 && (di->Viewpoint.Pos.Z < z) == ((sprite->cstat & CSTAT_SPRITE_YFLIP) == 0))
return;
if (texture && texture->isValid())

View file

@ -1141,7 +1141,7 @@ void HWWall::ProcessWallSprite(HWDrawInfo* di, tspritetype* spr, sectortype* sec
glseg.x2 = pos[1].x * (1 / 16.f);
glseg.y2 = pos[1].y * (1 / -16.f);
if (spr->cstat & CSTAT_SPRITE_ONE_SIDED)
if (spr->cstat & CSTAT_SPRITE_ONE_SIDE)
{
if (PointOnLineSide(di->Viewpoint.Pos.X, di->Viewpoint.Pos.Y, glseg.x1, glseg.y1, glseg.x2 - glseg.x1, glseg.y2 - glseg.y1) <= 0)
{

View file

@ -66,9 +66,6 @@
#include <zlib.h>
TArray<sectortype> sectorbackup;
TArray<walltype> wallbackup;
void WriteSavePic(FileWriter* file, int width, int height);
bool WriteZip(const char* filename, TArray<FString>& filenames, TArray<FCompressedBuffer>& content);
extern FString savename;

View file

@ -548,7 +548,7 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
pSprite->shade = load.shade;
pSprite->blend = 0;
pSprite->time = i;
ValidateSprite(*pSprite, secno, i);
validateSprite(*pSprite, secno, i);
if (pSprite->extra > 0)
{
@ -649,7 +649,7 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
auto buffer = fr.Read();
uint8_t md4[16];
md4once(buffer.Data(), buffer.Size(), md4);
G_LoadMapHack(mapname, md4, sprites);
loadMapHack(mapname, md4, sprites);
if (CalcCRC32(buffer.Data(), buffer.Size() - 4) != nCRC)
{

View file

@ -3181,8 +3181,8 @@ void useEffectGen(DBloodActor* sourceactor, DBloodActor* actor)
pEffectSpr->cstat &= ~CSTAT_SPRITE_INVISIBLE;
}
if (pEffectSpr->cstat & CSTAT_SPRITE_ONE_SIDED)
pEffectSpr->cstat &= ~CSTAT_SPRITE_ONE_SIDED;
if (pEffectSpr->cstat & CSTAT_SPRITE_ONE_SIDE)
pEffectSpr->cstat &= ~CSTAT_SPRITE_ONE_SIDE;
}
}
}

View file

@ -670,7 +670,7 @@ void viewDrawScreen(bool sceneonly)
{
fixedhoriz deliriumPitchI = q16horiz(interpolatedvalue(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate));
int bakCstat = gView->pSprite->cstat;
gView->pSprite->cstat |= (gViewPos == 0) ? CSTAT_SPRITE_INVISIBLE : CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANSLUCENT_INVERT;
gView->pSprite->cstat |= (gViewPos == 0) ? CSTAT_SPRITE_INVISIBLE : CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANS_FLIP;
render_drawrooms(gView->pSprite, { cX, cY, cZ }, sectnum(pSector), cA, cH + deliriumPitchI, rotscrnang, gInterpolate);
gView->pSprite->cstat = bakCstat;
}

View file

@ -975,7 +975,7 @@ static int LoadTheMap(MapRecord *mi, struct player_struct *p, int gamemode)
currentLevel = mi;
int sect;
SpawnSpriteDef sprites;
engineLoadBoard(mi->fileName, isShareware(), &p->pos, &lbang, &sect, sprites);
loadMap(mi->fileName, isShareware(), &p->pos, &lbang, &sect, sprites);
p->cursector = &sector[sect];
SECRET_SetMapName(mi->DisplayName(), mi->name);

View file

@ -141,7 +141,7 @@ uint8_t LoadLevel(MapRecord* map)
vec3_t startPos;
int initsect;
SpawnSpriteDef spawned;
engineLoadBoard(currentLevel->fileName, 0, &startPos, &inita, &initsect, spawned);
loadMap(currentLevel->fileName, 0, &startPos, &inita, &initsect, spawned);
initx = startPos.x;
inity = startPos.y;
initz = startPos.z;

View file

@ -415,7 +415,7 @@ void DoMotionBlur(tspritetype* tsprite, int& spritesortcnt, tspritetype const *
{
tspriteptr_t tSpr = &tsprite[spritesortcnt];
*tSpr = *tsp;
SET(tSpr->cstat, CSTAT_SPRITE_TRANSLUCENT|CSTAT_SPRITE_TRANSLUCENT_INVERT);
SET(tSpr->cstat, CSTAT_SPRITE_TRANSLUCENT|CSTAT_SPRITE_TRANS_FLIP);
tSpr->x += dx;
tSpr->y += dy;

View file

@ -400,7 +400,7 @@ void InitLevel(MapRecord *maprec)
currentLevel = maprec;
int cursect;
SpawnSpriteDef sprites;
engineLoadBoard(maprec->fileName, SW_SHAREWARE ? 1 : 0, &Player[0].pos, &ang, &cursect, sprites);
loadMap(maprec->fileName, SW_SHAREWARE ? 1 : 0, &Player[0].pos, &ang, &cursect, sprites);
spawnactors(sprites);
Player[0].cursector = &sector[cursect];

View file

@ -359,44 +359,6 @@ inline int SPRITEp_SIZE_BOS(const tspritetype* sp)
#define FLOOR_STAT_TRANS_FLIP (BIT(7)|BIT(8))
#define FLOOR_STAT_FAF_BLOCK_HITSCAN BIT(15)
#define CSTAT_WALL_BLOCK BIT(0)
#define CSTAT_WALL_BOTTOM_SWAP BIT(1)
#define CSTAT_WALL_ALIGN_BOTTOM BIT(2)
#define CSTAT_WALL_XFLIP BIT(3)
#define CSTAT_WALL_MASKED BIT(4)
#define CSTAT_WALL_1WAY BIT(5)
#define CSTAT_WALL_BLOCK_HITSCAN BIT(6)
#define CSTAT_WALL_TRANSLUCENT BIT(7)
#define CSTAT_WALL_YFLIP BIT(8)
#define CSTAT_WALL_TRANS_FLIP BIT(9)
#define CSTAT_WALL_BLOCK_ACTOR (BIT(14)) // my def
#define CSTAT_WALL_WARP_HITSCAN (BIT(15)) // my def
//cstat, bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B"
// bit 1: 1 = 50/50 transluscence, 0 = normal "T"
// bit 2: 1 = x-flipped, 0 = normal "F"
// bit 3: 1 = y-flipped, 0 = normal "F"
// bits 5-4: 00 = FACE sprite (default) "R"
// 01 = WALL sprite (like masked walls)
// 10 = FLOOR sprite (parallel to ceilings&floors)
// 11 = SPIN sprite (face sprite that can spin 2draw style - not done yet)
// bit 6: 1 = 1-sided sprite, 0 = normal "1"
// bit 7: 1 = Real centered centering, 0 = foot center "C"
// bit 8: 1 = Blocking sprite (use with hitscan) "H"
// bit 9: reserved
// bit 10: reserved
// bit 11: reserved
// bit 12: reserved
// bit 13: reserved
// bit 14: reserved
// bit 15: 1 = Invisible sprite, 0 = not invisible
#define CSTAT_SPRITE_RESTORE BIT(12) // my def
#define CSTAT_SPRITE_CLOSE_FLOOR BIT(13) // my def - tells whether a sprite
// started out close to a ceiling or floor
#define CSTAT_SPRITE_BLOCK_MISSILE BIT(14) // my def
#define CSTAT_SPRITE_BREAKABLE (CSTAT_SPRITE_BLOCK_HITSCAN|CSTAT_SPRITE_BLOCK_MISSILE)
#undef CLIPMASK0 // defined in build.h
#undef CLIPMASK1

View file

@ -965,7 +965,7 @@ bool IconSpawn(SPRITEp sp)
if (numplayers <= 1 || gNet.MultiGameType == MULTI_GAME_COOPERATIVE)
return false;
}
sp->cstat &= ~(CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_ONE_SIDED | CSTAT_SPRITE_ALIGNMENT_FLOOR);
sp->cstat &= ~(CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_ALIGNMENT_FLOOR);
return true;
}
@ -2908,7 +2908,7 @@ KeyMain:
RESET(picanm[sp->picnum].sf, PICANM_ANIMTYPE_MASK);
RESET(picanm[sp->picnum + 1].sf, PICANM_ANIMTYPE_MASK);
change_actor_stat(actor, STAT_ITEM);
RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_ONE_SIDED);
RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN | CSTAT_SPRITE_ONE_SIDE);
u->Radius = 500;
sp->hitag = LUMINOUS; //Set so keys over ride colored lighting

View file

@ -16087,7 +16087,7 @@ DSWActor* SpawnWallHole(sectortype* hit_sect, walltype* hit_wall, int hit_x, int
//SET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT|CSTAT_SPRITE_ALIGNMENT_WALL);
SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDED);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDE);
wall_ang = NORM_ANGLE(getangle(hit_wall->delta())-512);
@ -18629,7 +18629,7 @@ void QueueHole(sectortype* hit_sect, walltype* hit_wall, int hit_x, int hit_y, i
ASSERT(sp->statnum != MAXSTATUS);
SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDED);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDE);
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
wall_ang = NORM_ANGLE(getangle(hit_wall->delta())+512);
@ -18710,7 +18710,7 @@ int QueueFloorBlood(DSWActor* actor)
sp->shade -= 5; // Brighten it up just a bit
SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_FLOOR);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDED);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDE);
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
RESET(u->Flags, SPR_SHADOW);
@ -18832,7 +18832,7 @@ int QueueFootPrint(DSWActor* actor)
if (left_foot)
SET(sp->cstat, CSTAT_SPRITE_XFLIP);
SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_FLOOR);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDED);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDE);
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
return 0;
@ -18959,7 +18959,7 @@ DSWActor* QueueWallBlood(DSWActor* actor, short ang)
spawnedActor->tempwall = hit.hitWall; // pass hitinfo.wall
SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDED);
SET(sp->cstat, CSTAT_SPRITE_ONE_SIDE);
SET(sp->cstat, CSTAT_SPRITE_YCENTER);
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);