mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-19 07:01:09 +00:00
Merge commit 'fd0e9824b60a8cae288102551f0f3134a221cf3c' into whaven
# Conflicts: # source/build/include/build.h # source/build/src/engine.cpp # source/build/src/engine_priv.h
This commit is contained in:
commit
3e17f3cb97
59 changed files with 1478 additions and 1635 deletions
|
@ -48,11 +48,6 @@ enum
|
|||
|
||||
MAXVOXMIPS = 5,
|
||||
|
||||
MAXXDIM = 7680,
|
||||
MAXYDIM = 3200,
|
||||
MINXDIM = 640,
|
||||
MINYDIM = 480,
|
||||
|
||||
MAXWALLSB = ((MAXWALLS >> 2) + (MAXWALLS >> 3)),
|
||||
|
||||
MAXVOXELS = 1024,
|
||||
|
@ -101,24 +96,11 @@ enum {
|
|||
};
|
||||
|
||||
|
||||
enum {
|
||||
SPR_XFLIP = 4,
|
||||
SPR_YFLIP = 8,
|
||||
|
||||
SPR_WALL = 16,
|
||||
SPR_FLOOR = 32,
|
||||
SPR_ALIGN_MASK = 32+16,
|
||||
};
|
||||
|
||||
#include "buildtypes.h"
|
||||
|
||||
using usectortype = sectortype;
|
||||
using uwalltype = walltype;
|
||||
using uspritetype = spritetype;
|
||||
|
||||
using uspriteptr_t = uspritetype const *;
|
||||
using uwallptr_t = uwalltype const *;
|
||||
using usectorptr_t = usectortype const *;
|
||||
using uspriteptr_t = spritetype const *;
|
||||
using uwallptr_t = walltype const *;
|
||||
using usectorptr_t = sectortype const *;
|
||||
using tspriteptr_t = tspritetype *;
|
||||
|
||||
|
||||
|
@ -151,17 +133,11 @@ typedef struct {
|
|||
#define SPREXT_TSPRACCESS 16
|
||||
#define SPREXT_TEMPINVISIBLE 32
|
||||
|
||||
#define NEG_ALPHA_TO_BLEND(alpha, blend, orientation) do { \
|
||||
if ((alpha) < 0) { (blend) = -(alpha); (alpha) = 0; (orientation) |= RS_TRANS1; } \
|
||||
} while (0)
|
||||
|
||||
// using the clipdist field
|
||||
enum
|
||||
{
|
||||
TSPR_FLAGS_MDHACK = 1u<<0u,
|
||||
TSPR_FLAGS_DRAW_LAST = 1u<<1u,
|
||||
TSPR_FLAGS_NO_SHADOW = 1u<<2u,
|
||||
TSPR_FLAGS_INVISIBLE_WITH_SHADOW = 1u<<3u,
|
||||
};
|
||||
|
||||
EXTERN int32_t guniqhudid;
|
||||
|
@ -177,57 +153,44 @@ struct usermaphack_t
|
|||
EXTERN spriteext_t *spriteext;
|
||||
EXTERN spritesmooth_t *spritesmooth;
|
||||
|
||||
// Wrapper that makes an array of pointers look like an array of references. (Refactoring helper.)
|
||||
|
||||
template<class T, int size>
|
||||
class ReferenceArray
|
||||
{
|
||||
T* data[size];
|
||||
public:
|
||||
T& operator[](size_t index)
|
||||
{
|
||||
assert(index < size);
|
||||
return *data[index];
|
||||
}
|
||||
|
||||
void set(int pos, T* spr)
|
||||
{
|
||||
data[pos] = spr;
|
||||
}
|
||||
};
|
||||
|
||||
EXTERN sectortype *sector;
|
||||
EXTERN walltype *wall;
|
||||
EXTERN spritetype *sprite;
|
||||
EXTERN tspriteptr_t tsprite;
|
||||
EXTERN int leveltimer;
|
||||
|
||||
extern sectortype sectorbackup[MAXSECTORS];
|
||||
extern walltype wallbackup[MAXWALLS];
|
||||
|
||||
extern bool inpreparemirror;
|
||||
|
||||
|
||||
static inline tspriteptr_t renderMakeTSpriteFromSprite(tspriteptr_t const tspr, uint16_t const spritenum)
|
||||
inline tspriteptr_t renderAddNewTSprite()
|
||||
{
|
||||
auto const spr = &sprite[spritenum];
|
||||
|
||||
*tspr = *spr;
|
||||
|
||||
tspr->clipdist = 0;
|
||||
tspr->owner = spritenum;
|
||||
|
||||
auto tspr = &tsprite[spritesortcnt++];
|
||||
*tspr = {};
|
||||
return tspr;
|
||||
}
|
||||
|
||||
static inline tspriteptr_t renderAddTSpriteFromSprite(uint16_t const spritenum)
|
||||
inline tspriteptr_t renderAddTSpriteFromSprite(uint16_t const spritenum)
|
||||
{
|
||||
return renderMakeTSpriteFromSprite(&tsprite[spritesortcnt++], spritenum);
|
||||
auto tspr = &tsprite[spritesortcnt++];
|
||||
auto const spr = &sprite[spritenum];
|
||||
*tspr = *spr;
|
||||
tspr->clipdist = 0;
|
||||
tspr->owner = spritenum;
|
||||
return tspr;
|
||||
}
|
||||
|
||||
// returns: 0=continue sprite collecting;
|
||||
// 1=break out of sprite collecting;
|
||||
inline int32_t renderAddTsprite(int16_t z, int16_t sectnum)
|
||||
{
|
||||
if (spritesortcnt >= MAXSPRITESONSCREEN) return 1;
|
||||
renderAddTSpriteFromSprite(z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
EXTERN int16_t maskwall[MAXWALLSB], maskwallcnt;
|
||||
EXTERN int16_t thewall[MAXWALLSB];
|
||||
EXTERN tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
|
||||
|
||||
EXTERN int32_t xdim, ydim;
|
||||
EXTERN int32_t yxaspect, viewingrange;
|
||||
|
@ -238,19 +201,8 @@ EXTERN int32_t display_mirror;
|
|||
|
||||
EXTERN int32_t randomseed;
|
||||
|
||||
EXTERN int16_t numshades;
|
||||
EXTERN uint8_t paletteloaded;
|
||||
|
||||
// Return type is int because this gets passed to variadic functions where structs may produce undefined behavior.
|
||||
inline int shadeToLight(int shade)
|
||||
{
|
||||
shade = clamp(shade, 0, numshades-1);
|
||||
int light = Scale(numshades-1-shade, 255, numshades-1);
|
||||
return PalEntry(255,light,light,light);
|
||||
}
|
||||
|
||||
EXTERN int32_t maxspritesonscreen;
|
||||
|
||||
enum {
|
||||
PALETTE_MAIN = 1<<0,
|
||||
PALETTE_SHADE = 1<<1,
|
||||
|
@ -385,22 +337,8 @@ SPRITE VARIABLES:
|
|||
be in some sector, and must have some kind of status that you define.
|
||||
|
||||
|
||||
TILE VARIABLES:
|
||||
NUMTILES - the number of tiles found TILES.DAT.
|
||||
|
||||
TIMING VARIABLES:
|
||||
NUMFRAMES - The number of times the draw3dscreen function was called
|
||||
since the engine was initialized. This helps to determine frame
|
||||
rate. (Frame rate = numframes * 120 / I_GetBuildTime().)
|
||||
|
||||
OTHER VARIABLES:
|
||||
|
||||
STARTUMOST[320] is an array of the highest y-coordinates on each column
|
||||
that my engine is allowed to write to. You need to set it only
|
||||
once.
|
||||
STARTDMOST[320] is an array of the lowest y-coordinates on each column
|
||||
that my engine is allowed to write to. You need to set it only
|
||||
once.
|
||||
SINTABLE[2048] is a sin table with 2048 angles rather than the
|
||||
normal 360 angles for higher precision. Also since SINTABLE is in
|
||||
all integers, the range is multiplied by 16383, so instead of the
|
||||
|
@ -444,34 +382,14 @@ void renderSetAspect(int32_t daxrange, int32_t daaspect);
|
|||
void plotpixel(int32_t x, int32_t y, char col);
|
||||
FCanvasTexture *renderSetTarget(int16_t tilenume);
|
||||
void renderRestoreTarget();
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall,
|
||||
int32_t *tposx, int32_t *tposy, fixed_t *tang);
|
||||
void renderCompleteMirror(void);
|
||||
|
||||
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int16_t dacursectnum);
|
||||
|
||||
void renderDrawMasks(void);
|
||||
void setVideoMode();
|
||||
void videoInit();
|
||||
void videoClearViewableArea(int32_t dacol);
|
||||
void videoClearScreen(int32_t dacol);
|
||||
void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang);
|
||||
void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FGameTexture *pic = nullptr, int basepal = 0);
|
||||
|
||||
class F2DDrawer;
|
||||
void twod_rotatesprite(F2DDrawer* twod, int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2, FGameTexture* pic = nullptr, int basepal = 0);
|
||||
|
||||
////////// specialized rotatesprite wrappers for (very) often used cases //////////
|
||||
static FORCE_INLINE void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat,
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FGameTexture* pic = nullptr, int basepal = 0)
|
||||
{
|
||||
rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, cx1, cy1, cx2, cy2, pic, basepal);
|
||||
}
|
||||
|
||||
void getzrange(const vec3_t *pos, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz,
|
||||
int32_t *florhit, int32_t walldist, uint32_t cliptype) ATTRIBUTE((nonnull(1,3,4,5,6)));
|
||||
|
@ -519,13 +437,12 @@ void updatesectorneighbor(int32_t const x, int32_t const y, int16_t * const sect
|
|||
void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(4)));
|
||||
|
||||
int findwallbetweensectors(int sect1, int sect2);
|
||||
static FORCE_INLINE int sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(sect1, sect2) != -1; }
|
||||
inline int sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(sect1, sect2) != -1; }
|
||||
int32_t getsectordist(vec2_t const in, int const sectnum, vec2_t * const out = nullptr);
|
||||
extern const int16_t *chsecptr_onextwall;
|
||||
int32_t checksectorpointer(int16_t i, int16_t sectnum);
|
||||
|
||||
#if !KRANDDEBUG
|
||||
static FORCE_INLINE int32_t krand(void)
|
||||
inline int32_t krand(void)
|
||||
{
|
||||
randomseed = (randomseed * 1664525ul) + 221297ul;
|
||||
return ((uint32_t) randomseed)>>16;
|
||||
|
@ -542,12 +459,12 @@ inline int32_t ksqrt(uint32_t num)
|
|||
int32_t getangle(int32_t xvect, int32_t yvect);
|
||||
fixed_t gethiq16angle(int32_t xvect, int32_t yvect);
|
||||
|
||||
static FORCE_INLINE constexpr uint32_t uhypsq(int32_t const dx, int32_t const dy)
|
||||
inline constexpr uint32_t uhypsq(int32_t const dx, int32_t const dy)
|
||||
{
|
||||
return (uint32_t)dx*dx + (uint32_t)dy*dy;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t logapproach(int32_t const val, int32_t const targetval)
|
||||
inline int32_t logapproach(int32_t const val, int32_t const targetval)
|
||||
{
|
||||
int32_t const dif = targetval - val;
|
||||
return (dif>>1) ? val + (dif>>1) : targetval;
|
||||
|
@ -576,36 +493,36 @@ void yax_getzsofslope(int sectNum, int playerX, int playerY, int32_t* pCeilZ, in
|
|||
int32_t yax_getceilzofslope(int const sectnum, vec2_t const vect);
|
||||
int32_t yax_getflorzofslope(int const sectnum, vec2_t const vect);
|
||||
|
||||
static FORCE_INLINE int32_t getceilzofslope(int16_t sectnum, int32_t dax, int32_t day)
|
||||
inline int32_t getceilzofslope(int16_t sectnum, int32_t dax, int32_t day)
|
||||
{
|
||||
return getceilzofslopeptr((usectorptr_t)§or[sectnum], dax, day);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t getflorzofslope(int16_t sectnum, int32_t dax, int32_t day)
|
||||
inline int32_t getflorzofslope(int16_t sectnum, int32_t dax, int32_t day)
|
||||
{
|
||||
return getflorzofslopeptr((usectorptr_t)§or[sectnum], dax, day);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void getzsofslope(int16_t sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
|
||||
inline void getzsofslope(int16_t sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
|
||||
{
|
||||
getzsofslopeptr((usectorptr_t)§or[sectnum], dax, day, ceilz, florz);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void getcorrectzsofslope(int16_t sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
|
||||
inline void getcorrectzsofslope(int16_t sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
|
||||
{
|
||||
vec2_t closest = { dax, day };
|
||||
getsectordist(closest, sectnum, &closest);
|
||||
getzsofslopeptr((usectorptr_t)§or[sectnum], closest.x, closest.y, ceilz, florz);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t getcorrectceilzofslope(int16_t sectnum, int32_t dax, int32_t day)
|
||||
inline int32_t getcorrectceilzofslope(int16_t sectnum, int32_t dax, int32_t day)
|
||||
{
|
||||
vec2_t closest = { dax, day };
|
||||
getsectordist(closest, sectnum, &closest);
|
||||
return getceilzofslopeptr((usectorptr_t)§or[sectnum], closest.x, closest.y);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t getcorrectflorzofslope(int16_t sectnum, int32_t dax, int32_t day)
|
||||
inline int32_t getcorrectflorzofslope(int16_t sectnum, int32_t dax, int32_t day)
|
||||
{
|
||||
vec2_t closest = { dax, day };
|
||||
getsectordist(closest, sectnum, &closest);
|
||||
|
@ -614,12 +531,12 @@ static FORCE_INLINE int32_t getcorrectflorzofslope(int16_t sectnum, int32_t dax,
|
|||
|
||||
// Is <wal> a red wall in a safe fashion, i.e. only if consistency invariant
|
||||
// ".nextsector >= 0 iff .nextwall >= 0" holds.
|
||||
static FORCE_INLINE int32_t redwallp(uwallptr_t wal)
|
||||
inline int32_t redwallp(uwallptr_t wal)
|
||||
{
|
||||
return (wal->nextwall >= 0 && wal->nextsector >= 0);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t E_SpriteIsValid(const int32_t i)
|
||||
inline int32_t E_SpriteIsValid(const int32_t i)
|
||||
{
|
||||
return ((unsigned)i < MAXSPRITES && sprite[i].statnum != MAXSTATUS);
|
||||
}
|
||||
|
@ -662,23 +579,13 @@ inline void setspritepos(int spnum, int x, int y, int z)
|
|||
int32_t setspritez(int16_t spritenum, const vec3_t *) ATTRIBUTE((nonnull(2)));
|
||||
|
||||
int32_t spriteheightofsptr(uspriteptr_t spr, int32_t *height, int32_t alsotileyofs);
|
||||
static FORCE_INLINE int32_t spriteheightofs(int16_t i, int32_t *height, int32_t alsotileyofs)
|
||||
inline int32_t spriteheightofs(int16_t i, int32_t *height, int32_t alsotileyofs)
|
||||
{
|
||||
return spriteheightofsptr((uspriteptr_t)&sprite[i], height, alsotileyofs);
|
||||
}
|
||||
|
||||
int videoCaptureScreen();
|
||||
|
||||
// PLAG: line utility functions
|
||||
typedef struct s_equation
|
||||
{
|
||||
float a, b, c;
|
||||
} _equation;
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
void renderSetRollAngle(float rolla);
|
||||
#endif
|
||||
|
||||
void PrecacheHardwareTextures(int nTile);
|
||||
void Polymost_Startup();
|
||||
|
||||
|
@ -721,7 +628,7 @@ typedef struct
|
|||
int16_t framenum; // calculate the number from the name when declaring
|
||||
int16_t nexttile;
|
||||
uint16_t smoothduration;
|
||||
hudtyp *hudmem[2];
|
||||
hudtyp hudmem[2];
|
||||
int8_t skinnum;
|
||||
char pal;
|
||||
} tile2model_t;
|
||||
|
@ -731,13 +638,13 @@ typedef struct
|
|||
EXTERN int32_t mdinited;
|
||||
EXTERN tile2model_t tile2model[MAXTILES+EXTRATILES];
|
||||
|
||||
static FORCE_INLINE int32_t md_tilehasmodel(int32_t const tilenume, int32_t const pal)
|
||||
inline int32_t md_tilehasmodel(int32_t const tilenume, int32_t const pal)
|
||||
{
|
||||
return mdinited ? tile2model[Ptile2tile(tilenume,pal)].modelid : -1;
|
||||
}
|
||||
#endif // defined USE_OPENGL
|
||||
|
||||
static FORCE_INLINE int tilehasmodelorvoxel(int const tilenume, int pal)
|
||||
inline int tilehasmodelorvoxel(int const tilenume, int pal)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pal);
|
||||
return
|
||||
|
@ -766,7 +673,7 @@ extern int skiptile;
|
|||
|
||||
static vec2_t const zerovec = { 0, 0 };
|
||||
|
||||
static FORCE_INLINE int inside_p(int32_t const x, int32_t const y, int const sectnum) { return (sectnum >= 0 && inside(x, y, sectnum) == 1); }
|
||||
inline int inside_p(int32_t const x, int32_t const y, int const sectnum) { return (sectnum >= 0 && inside(x, y, sectnum) == 1); }
|
||||
|
||||
#define SET_AND_RETURN(Lval, Rval) \
|
||||
do \
|
||||
|
@ -878,7 +785,7 @@ inline void tileUpdatePicnum(int* const tileptr, int const obj, int stat)
|
|||
|
||||
inline void setgotpic(int32_t tilenume)
|
||||
{
|
||||
gotpic[tilenume >> 3] |= pow2char[tilenume & 7];
|
||||
gotpic[tilenume >> 3] |= 1 << (tilenume & 7);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ struct sectortype
|
|||
uint8_t dirty;
|
||||
float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_;
|
||||
uint8_t portalflags;
|
||||
uint8_t portalnum;
|
||||
int8_t portalnum;
|
||||
|
||||
int ceilingxpan() const { return int(ceilingxpan_); }
|
||||
int ceilingypan() const { return int(ceilingypan_); }
|
||||
|
@ -255,6 +255,7 @@ struct spritetype
|
|||
};
|
||||
int16_t extra;
|
||||
int16_t detail;
|
||||
int time;
|
||||
|
||||
#if 0
|
||||
// make sure we do not accidentally copy this
|
||||
|
|
|
@ -27,26 +27,6 @@
|
|||
#endif
|
||||
|
||||
|
||||
#ifndef MAY_ALIAS
|
||||
# ifdef _MSC_VER
|
||||
# define MAY_ALIAS
|
||||
# else
|
||||
# define MAY_ALIAS __attribute__((may_alias))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_INLINE
|
||||
# ifdef _MSC_VER
|
||||
# define FORCE_INLINE __forceinline
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FORCE_INLINE inline __attribute__((always_inline))
|
||||
# else
|
||||
# define FORCE_INLINE inline
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# define fallthrough__ [[fallthrough]]
|
||||
|
||||
////////// Architecture detection //////////
|
||||
|
@ -91,17 +71,12 @@
|
|||
|
||||
#include "engineerrors.h"
|
||||
|
||||
////////// DEPRECATED: Standard library prefixing //////////
|
||||
|
||||
typedef intptr_t ssize_t;
|
||||
|
||||
typedef ssize_t bssize_t;
|
||||
typedef intptr_t bssize_t;
|
||||
|
||||
#define BMAX_PATH 256
|
||||
|
||||
////////// Metaprogramming structs //////////
|
||||
|
||||
using std::enable_if_t;
|
||||
using native_t = intptr_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -121,44 +96,14 @@ typedef struct {
|
|||
|
||||
static_assert(sizeof(vec3f_t) == sizeof(float) * 3);
|
||||
|
||||
typedef struct {
|
||||
union { double x; double d; };
|
||||
union { double y; double u; };
|
||||
union { double z; double v; };
|
||||
} vec3d_t;
|
||||
|
||||
static_assert(sizeof(vec3d_t) == sizeof(double) * 3);
|
||||
|
||||
|
||||
////////// Language tricks that depend on size_t //////////
|
||||
|
||||
#include "basics.h"
|
||||
|
||||
////////// Pointer management //////////
|
||||
|
||||
#define DO_FREE_AND_NULL(var) do { \
|
||||
Xfree(var); (var) = NULL; \
|
||||
} while (0)
|
||||
|
||||
|
||||
////////// Abstract data operations //////////
|
||||
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
////////// Bitfield manipulation //////////
|
||||
|
||||
// This once was a static array, requiring a memory acces where a shift would suffice.
|
||||
// Revert the above to a real bit shift through some C++ operator magic. That saves me from reverting all the code that uses this construct.
|
||||
// Note: Only occurs 25 times in the code, should be removed for good.
|
||||
static struct
|
||||
{
|
||||
constexpr uint8_t operator[](int index) const { return 1 << index; };
|
||||
} pow2char;
|
||||
|
||||
|
||||
static FORCE_INLINE void bitmap_set(uint8_t *const ptr, int const n) { ptr[n>>3] |= 1 << (n&7); }
|
||||
static FORCE_INLINE char bitmap_test(uint8_t const *const ptr, int const n) { return ptr[n>>3] & (1 << (n&7)); }
|
||||
inline void bitmap_set(uint8_t *const ptr, int const n) { ptr[n>>3] |= 1 << (n&7); }
|
||||
inline char bitmap_test(uint8_t const *const ptr, int const n) { return ptr[n>>3] & (1 << (n&7)); }
|
||||
|
||||
////////// Utility functions //////////
|
||||
|
||||
|
@ -183,13 +128,4 @@ void bfirst_search_try(T *const list, uint8_t *const bitmap, T *const eltnumptr,
|
|||
}
|
||||
}
|
||||
|
||||
////////// PANICKING ALLOCATION WRAPPERS //////////
|
||||
|
||||
|
||||
#define Xstrdup(s) (strdup(s))
|
||||
#define Xmalloc(size) (M_Malloc(size))
|
||||
#define Xcalloc(nmemb, size) (M_Calloc(nmemb, size))
|
||||
#define Xrealloc(ptr, size) (M_Realloc(ptr, size))
|
||||
#define Xfree(ptr) (M_Free(ptr))
|
||||
|
||||
#endif // compat_h_
|
||||
|
|
|
@ -212,10 +212,6 @@ void voxfree(voxmodel_t *m);
|
|||
voxmodel_t *voxload(int lumpnum);
|
||||
int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr);
|
||||
|
||||
int md3postload_polymer(md3model_t* m);
|
||||
//int32_t md_thinoutmodel(int32_t modelid, uint8_t *usedframebitmap);
|
||||
EXTERN void md_freevbos(void);
|
||||
|
||||
#endif // defined USE_OPENGL
|
||||
|
||||
enum {
|
||||
|
|
|
@ -25,9 +25,9 @@ void polymost_completeMirror();
|
|||
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype);
|
||||
void polymost_deletesprite(int num);
|
||||
|
||||
int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall);
|
||||
int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr);
|
||||
int32_t polymost_spriteIsModelOrVoxel(tspritetype const * const tspr);
|
||||
int32_t polymost_maskWallHasTranslucency(walltype const * const wall);
|
||||
int32_t polymost_spriteHasTranslucency(spritetype const * const tspr);
|
||||
int32_t polymost_spriteIsModelOrVoxel(spritetype const * const tspr);
|
||||
|
||||
void polymost_glreset(void);
|
||||
void polymost_scansector(int32_t sectnum);
|
||||
|
@ -36,6 +36,23 @@ extern float curpolygonoffset;
|
|||
|
||||
}
|
||||
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall,
|
||||
int32_t* tposx, int32_t* tposy, fixed_t* tang);
|
||||
void renderCompleteMirror(void);
|
||||
|
||||
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int16_t dacursectnum);
|
||||
|
||||
void renderDrawMasks(void);
|
||||
|
||||
// PLAG: line utility functions
|
||||
typedef struct s_equation
|
||||
{
|
||||
float a, b, c;
|
||||
} _equation;
|
||||
|
||||
void renderSetRollAngle(float rolla);
|
||||
|
||||
|
||||
// these are defined in engine.cpp.
|
||||
extern int16_t globalpicnum;
|
||||
extern float fcosglobalang, fsinglobalang;
|
||||
|
|
|
@ -27,41 +27,9 @@ static uint8_t clipignore[(MAXCLIPNUM+7)>>3];
|
|||
|
||||
int32_t quickloadboard=0;
|
||||
|
||||
static int32_t numclipmaps;
|
||||
|
||||
static int32_t numclipsects; // number in sectq[]
|
||||
static int16_t *sectoidx;
|
||||
static int16_t *sectq; // [numsectors]
|
||||
static int16_t pictoidx[MAXTILES]; // maps tile num to clipinfo[] index
|
||||
static int16_t *tempictoidx;
|
||||
|
||||
static usectortype *loadsector;
|
||||
static uwalltype *loadwall, *loadwallinv;
|
||||
static uspritetype *loadsprite;
|
||||
|
||||
vec2_t hitscangoal = { (1<<29)-1, (1<<29)-1 };
|
||||
int32_t hitallsprites = 0;
|
||||
|
||||
void engineInitClipMaps()
|
||||
{
|
||||
numclipmaps = 0;
|
||||
numclipsects = 0;
|
||||
|
||||
DO_FREE_AND_NULL(sectq);
|
||||
DO_FREE_AND_NULL(sectoidx);
|
||||
DO_FREE_AND_NULL(tempictoidx);
|
||||
DO_FREE_AND_NULL(loadsector);
|
||||
DO_FREE_AND_NULL(loadwall);
|
||||
DO_FREE_AND_NULL(loadwallinv);
|
||||
DO_FREE_AND_NULL(loadsprite);
|
||||
|
||||
// two's complement trick, -1 = 0xff
|
||||
memset(&pictoidx, -1, sizeof(pictoidx));
|
||||
|
||||
numsectors = 0;
|
||||
numwalls = 0;
|
||||
}
|
||||
|
||||
////////// CLIPMOVE //////////
|
||||
|
||||
int32_t clipmoveboxtracenum = 3;
|
||||
|
@ -157,14 +125,14 @@ static void addclipline(int32_t dax1, int32_t day1, int32_t dax2, int32_t day2,
|
|||
clipit[clipnum].x2 = dax2; clipit[clipnum].y2 = day2;
|
||||
clipobjectval[clipnum] = daoval;
|
||||
|
||||
uint32_t const mask = pow2char[clipnum&7];
|
||||
uint32_t const mask = (1 << (clipnum&7));
|
||||
uint8_t &value = clipignore[clipnum>>3];
|
||||
value = (value & ~mask) | (-nofix & mask);
|
||||
|
||||
clipnum++;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void clipmove_tweak_pos(const vec3_t *pos, int32_t gx, int32_t gy, int32_t x1, int32_t y1, int32_t x2,
|
||||
inline void clipmove_tweak_pos(const vec3_t *pos, int32_t gx, int32_t gy, int32_t x1, int32_t y1, int32_t x2,
|
||||
int32_t y2, int32_t *daxptr, int32_t *dayptr)
|
||||
{
|
||||
int32_t daz;
|
||||
|
@ -530,7 +498,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
|
|||
|
||||
if (clipyou)
|
||||
{
|
||||
int16_t const objtype = curspr ? (int16_t)(curspr - (uspritetype *)sprite) + 49152 : (int16_t)j + 32768;
|
||||
int16_t const objtype = curspr ? (int16_t)(curspr - sprite) + 49152 : (int16_t)j + 32768;
|
||||
|
||||
//Add 2 boxes at endpoints
|
||||
int32_t bsz = walldist; if (diff.x < 0) bsz = -bsz;
|
||||
|
@ -1214,22 +1182,22 @@ static int32_t hitscan_trysector(const vec3_t *sv, usectorptr_t sec, hitdata_t *
|
|||
{
|
||||
if (tmp==NULL)
|
||||
{
|
||||
if (inside(x1,y1,sec-(usectortype *)sector) == 1)
|
||||
if (inside(x1,y1,sec-sector) == 1)
|
||||
{
|
||||
hit_set(hit, sec-(usectortype *)sector, -1, -1, x1, y1, z1);
|
||||
hit_set(hit, sec-sector, -1, -1, x1, y1, z1);
|
||||
hitscan_hitsectcf = (how+1)>>1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int32_t curidx=(int32_t)tmp[0];
|
||||
auto const curspr=(uspritetype *)tmp[1];
|
||||
auto const curspr=(spritetype *)tmp[1];
|
||||
const int32_t thislastsec = tmp[2];
|
||||
|
||||
if (!thislastsec)
|
||||
{
|
||||
if (inside(x1,y1,sec-(usectortype *)sector) == 1)
|
||||
hit_set(hit, curspr->sectnum, -1, curspr-(uspritetype *)sprite, x1, y1, z1);
|
||||
if (inside(x1,y1,sec-sector) == 1)
|
||||
hit_set(hit, curspr->sectnum, -1, curspr-sprite, x1, y1, z1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,8 +210,6 @@ enum scripttoken_t
|
|||
};
|
||||
|
||||
static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
|
||||
static char *faketilebuffer = NULL;
|
||||
static int32_t faketilebuffersiz = 0;
|
||||
|
||||
static const char *skyfaces[6] =
|
||||
{
|
||||
|
@ -1282,7 +1280,7 @@ static int32_t defsparser(scriptfile *script)
|
|||
break;
|
||||
default:
|
||||
if (framei >= 0 && framei<1024)
|
||||
usedframebitmap[framei>>3] |= pow2char[framei&7];
|
||||
usedframebitmap[framei>>3] |= (1 << (framei&7));
|
||||
}
|
||||
model_ok &= happy;
|
||||
}
|
||||
|
@ -1637,7 +1635,7 @@ static int32_t defsparser(scriptfile *script)
|
|||
}
|
||||
|
||||
case T_ROTATE:
|
||||
voxrotate[lastvoxid>>3] |= pow2char[lastvoxid&7];
|
||||
voxrotate[lastvoxid>>3] |= (1 << (lastvoxid&7));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3196,9 +3194,6 @@ int32_t loaddefinitionsfile(const char *fn, bool loadadds)
|
|||
if (script)
|
||||
scriptfile_close(script);
|
||||
|
||||
DO_FREE_AND_NULL(faketilebuffer);
|
||||
faketilebuffersiz = 0;
|
||||
|
||||
if (!script) return -1;
|
||||
|
||||
Printf(PRINT_NONOTIFY, "\n");
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||||
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||||
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
||||
// See the included license file "BUILDLIC.TXT" for license info.
|
||||
//
|
||||
|
@ -40,8 +41,6 @@
|
|||
#include "gl_renderer.h"
|
||||
#endif
|
||||
|
||||
float rollang;
|
||||
|
||||
int32_t r_rortexture = 0;
|
||||
int32_t r_rortexturerange = 0;
|
||||
int32_t r_rorphase = 0;
|
||||
|
@ -58,7 +57,7 @@ int16_t pskybits_override = -1;
|
|||
static TArray<TArray<uint8_t>> voxelmemory;
|
||||
|
||||
int16_t tiletovox[MAXTILES];
|
||||
char *voxfilenames[MAXVOXELS];
|
||||
int voxlumps[MAXVOXELS];
|
||||
char g_haveVoxels;
|
||||
//#define kloadvoxel loadvoxel
|
||||
|
||||
|
@ -82,7 +81,7 @@ int32_t showfirstwall=0;
|
|||
int32_t showheightindicators=1;
|
||||
int32_t circlewall=-1;
|
||||
|
||||
static fixed_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms)
|
||||
fixed_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms)
|
||||
|
||||
static FString printcoords(void)
|
||||
{
|
||||
|
@ -140,12 +139,6 @@ static void getclosestpointonwall_internal(vec2_t const p, int32_t const dawall,
|
|||
*closest = { (int32_t)(w.x + ((d.x * i) >> 30)), (int32_t)(w.y + ((d.y * i) >> 30)) };
|
||||
}
|
||||
|
||||
int16_t bunchp2[MAXWALLSB], thesector[MAXWALLSB];
|
||||
int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
||||
|
||||
|
||||
static vec3_t spritesxyz[MAXSPRITESONSCREEN+1];
|
||||
|
||||
int32_t xdimen = -1, xdimenscale, xdimscale;
|
||||
float fxdimen = -1.f;
|
||||
int32_t ydimen;
|
||||
|
@ -168,35 +161,17 @@ int16_t globalpicnum;
|
|||
|
||||
static int32_t globaly1, globalx2;
|
||||
|
||||
int16_t sectorborder[256];
|
||||
int16_t pointhighlight=-1, linehighlight=-1, highlightcnt=0;
|
||||
|
||||
static_assert(MAXWALLSB < INT16_MAX);
|
||||
int16_t numscans, numbunches;
|
||||
static int16_t numhits;
|
||||
|
||||
bool inpreparemirror = 0;
|
||||
static int32_t mirrorsx1, mirrorsy1, mirrorsx2, mirrorsy2;
|
||||
|
||||
|
||||
//
|
||||
// Internal Engine Functions
|
||||
//
|
||||
|
||||
// returns: 0=continue sprite collecting;
|
||||
// 1=break out of sprite collecting;
|
||||
int32_t renderAddTsprite(int16_t z, int16_t sectnum)
|
||||
{
|
||||
auto const spr = (uspriteptr_t)&sprite[z];
|
||||
if (spritesortcnt >= maxspritesonscreen)
|
||||
return 1;
|
||||
|
||||
renderAddTSpriteFromSprite(z);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// animateoffs (internal)
|
||||
|
@ -232,21 +207,6 @@ int32_t animateoffs(int const tilenum, int fakevar)
|
|||
return offs;
|
||||
}
|
||||
|
||||
static void renderDrawSprite(int32_t snum)
|
||||
{
|
||||
Polymost::polymost_drawsprite(snum);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// drawmaskwall (internal)
|
||||
//
|
||||
static void renderDrawMaskedWall(int16_t damaskwallcnt)
|
||||
{
|
||||
Polymost::polymost_drawmaskwall(damaskwallcnt); return;
|
||||
}
|
||||
|
||||
|
||||
static int32_t engineLoadTables(void)
|
||||
{
|
||||
static char tablesloaded = 0;
|
||||
|
@ -281,16 +241,10 @@ static int32_t engineLoadTables(void)
|
|||
|
||||
////////// SPRITE LIST MANIPULATION FUNCTIONS //////////
|
||||
|
||||
#ifdef NETCODE_DISABLE
|
||||
# define LISTFN_STATIC static
|
||||
#else
|
||||
# define LISTFN_STATIC
|
||||
#endif
|
||||
|
||||
///// sector lists of sprites /////
|
||||
|
||||
// insert sprite at the head of sector list, change .sectnum
|
||||
LISTFN_STATIC void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sectnum)
|
||||
static void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sectnum)
|
||||
{
|
||||
int16_t const ohead = headspritesect[sectnum];
|
||||
|
||||
|
@ -304,7 +258,7 @@ LISTFN_STATIC void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sect
|
|||
}
|
||||
|
||||
// remove sprite 'deleteme' from its sector list
|
||||
LISTFN_STATIC void do_deletespritesect(int16_t deleteme)
|
||||
static void do_deletespritesect(int16_t deleteme)
|
||||
{
|
||||
int32_t const sectnum = sprite[deleteme].sectnum;
|
||||
int32_t const prev = prevspritesect[deleteme];
|
||||
|
@ -321,7 +275,7 @@ LISTFN_STATIC void do_deletespritesect(int16_t deleteme)
|
|||
///// now, status lists /////
|
||||
|
||||
// insert sprite at head of status list, change .statnum
|
||||
LISTFN_STATIC void do_insertsprite_at_headofstat(int16_t spritenum, int16_t statnum)
|
||||
static void do_insertsprite_at_headofstat(int16_t spritenum, int16_t statnum)
|
||||
{
|
||||
int16_t const ohead = headspritestat[statnum];
|
||||
|
||||
|
@ -335,7 +289,7 @@ LISTFN_STATIC void do_insertsprite_at_headofstat(int16_t spritenum, int16_t stat
|
|||
}
|
||||
|
||||
// insertspritestat (internal)
|
||||
LISTFN_STATIC int32_t insertspritestat(int16_t statnum)
|
||||
static int32_t insertspritestat(int16_t statnum)
|
||||
{
|
||||
if ((statnum >= MAXSTATUS) || (headspritestat[MAXSTATUS] == -1))
|
||||
return -1; //list full
|
||||
|
@ -356,7 +310,7 @@ LISTFN_STATIC int32_t insertspritestat(int16_t statnum)
|
|||
}
|
||||
|
||||
// remove sprite 'deleteme' from its status list
|
||||
LISTFN_STATIC void do_deletespritestat(int16_t deleteme)
|
||||
static void do_deletespritestat(int16_t deleteme)
|
||||
{
|
||||
int32_t const sectnum = sprite[deleteme].statnum;
|
||||
int32_t const prev = prevspritestat[deleteme];
|
||||
|
@ -390,6 +344,7 @@ int32_t insertsprite(int16_t sectnum, int16_t statnum)
|
|||
Numsprites++;
|
||||
}
|
||||
|
||||
sprite[newspritenum].time = leveltimer++;
|
||||
return newspritenum;
|
||||
|
||||
}
|
||||
|
@ -735,40 +690,20 @@ int32_t engineInit(void)
|
|||
g_visibility = 512;
|
||||
parallaxvisibility = 512;
|
||||
|
||||
maxspritesonscreen = MAXSPRITESONSCREEN;
|
||||
|
||||
GPalette.Init(MAXPALOOKUPS + 1); // one slot for each translation, plus a separate one for the base palettes.
|
||||
gi->loadPalette();
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
if (!mdinited) mdinit();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// uninitengine
|
||||
//
|
||||
|
||||
void engineUnInit(void)
|
||||
{
|
||||
Polymost::polymost_glreset();
|
||||
freeallmodels();
|
||||
# ifdef POLYMER
|
||||
polymer_uninit();
|
||||
# endif
|
||||
|
||||
TileFiles.CloseAll();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// initspritelists
|
||||
//
|
||||
void (*initspritelists_replace)(void) = NULL;
|
||||
void initspritelists(void)
|
||||
{
|
||||
leveltimer = 0;
|
||||
if (initspritelists_replace)
|
||||
{
|
||||
initspritelists_replace();
|
||||
|
@ -818,463 +753,6 @@ void initspritelists(void)
|
|||
}
|
||||
|
||||
|
||||
void set_globalang(fixed_t const ang)
|
||||
{
|
||||
globalang = FixedToInt(ang)&2047;
|
||||
qglobalang = ang & 0x7FFFFFF;
|
||||
|
||||
float const f_ang = FixedToFloat(ang);
|
||||
float const fcosang = bcosf(f_ang);
|
||||
float const fsinang = bsinf(f_ang);
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
fcosglobalang = fcosang;
|
||||
fsinglobalang = fsinang;
|
||||
#endif
|
||||
|
||||
cosglobalang = (int)fcosang;
|
||||
singlobalang = (int)fsinang;
|
||||
|
||||
cosviewingrangeglobalang = MulScale(cosglobalang,viewingrange, 16);
|
||||
sinviewingrangeglobalang = MulScale(singlobalang,viewingrange, 16);
|
||||
}
|
||||
|
||||
//
|
||||
// drawrooms
|
||||
//
|
||||
EXTERN_CVAR(Int, gl_fogmode)
|
||||
CVAR(Bool, testnewrenderer, true, 0)
|
||||
|
||||
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
|
||||
fixed_t daang, fixed_t dahoriz, int16_t dacursectnum)
|
||||
{
|
||||
checkRotatedWalls();
|
||||
|
||||
if (gl_fogmode == 1) gl_fogmode = 2; // only radial fog works with Build's screwed up coordinate system.
|
||||
|
||||
// Update starting sector number (common to classic and Polymost).
|
||||
// ADJUST_GLOBALCURSECTNUM.
|
||||
if (dacursectnum >= MAXSECTORS)
|
||||
dacursectnum -= MAXSECTORS;
|
||||
else
|
||||
{
|
||||
int i = dacursectnum;
|
||||
updatesector(daposx, daposy, &dacursectnum);
|
||||
if (dacursectnum < 0) dacursectnum = i;
|
||||
|
||||
// PK 20110123: I'm not sure what the line above is supposed to do, but 'i'
|
||||
// *can* be negative, so let's just quit here in that case...
|
||||
if (dacursectnum < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_globalpos(daposx, daposy, daposz);
|
||||
set_globalang(daang);
|
||||
|
||||
global100horiz = dahoriz;
|
||||
|
||||
memset(gotsector, 0, sizeof(gotsector));
|
||||
qglobalhoriz = MulScale(dahoriz, DivScale(xdimenscale, viewingrange, 16), 16) + IntToFixed(ydimen >> 1);
|
||||
globalcursectnum = dacursectnum;
|
||||
Polymost::polymost_drawrooms();
|
||||
return inpreparemirror;
|
||||
}
|
||||
|
||||
// UTILITY TYPES AND FUNCTIONS FOR DRAWMASKS OCCLUSION TREE
|
||||
// typedef struct s_maskleaf
|
||||
// {
|
||||
// int32_t index;
|
||||
// _point2d p1, p2;
|
||||
// _equation maskeq, p1eq, p2eq;
|
||||
// struct s_maskleaf* branch[MAXWALLSB];
|
||||
// int32_t drawing;
|
||||
// } _maskleaf;
|
||||
//
|
||||
// _maskleaf maskleaves[MAXWALLSB];
|
||||
|
||||
// returns equation of a line given two points
|
||||
static inline _equation equation(float const x1, float const y1, float const x2, float const y2)
|
||||
{
|
||||
const float f = x2-x1;
|
||||
|
||||
// vertical
|
||||
if (f == 0.f)
|
||||
return { 1, 0, -x1 };
|
||||
else
|
||||
{
|
||||
float const ff = (y2 - y1) / f;
|
||||
return { ff, -1, (y1 - (ff * x1)) };
|
||||
}
|
||||
}
|
||||
|
||||
static inline int32_t sameside(const _equation *eq, const vec2f_t *p1, const vec2f_t *p2)
|
||||
{
|
||||
const float sign1 = (eq->a * p1->x) + (eq->b * p1->y) + eq->c;
|
||||
const float sign2 = (eq->a * p2->x) + (eq->b * p2->y) + eq->c;
|
||||
return (sign1 * sign2) > 0.f;
|
||||
}
|
||||
|
||||
|
||||
static inline int comparetsprites(int const k, int const l)
|
||||
{
|
||||
if ((tspriteptr[k]->cstat & 48) != (tspriteptr[l]->cstat & 48))
|
||||
return (tspriteptr[k]->cstat & 48) - (tspriteptr[l]->cstat & 48);
|
||||
|
||||
if ((tspriteptr[k]->cstat & 48) == 16 && tspriteptr[k]->ang != tspriteptr[l]->ang)
|
||||
return tspriteptr[k]->ang - tspriteptr[l]->ang;
|
||||
|
||||
if (tspriteptr[k]->statnum != tspriteptr[l]->statnum)
|
||||
return tspriteptr[k]->statnum - tspriteptr[l]->statnum;
|
||||
|
||||
if (tspriteptr[k]->x == tspriteptr[l]->x &&
|
||||
tspriteptr[k]->y == tspriteptr[l]->y &&
|
||||
tspriteptr[k]->z == tspriteptr[l]->z &&
|
||||
(tspriteptr[k]->cstat & 48) == (tspriteptr[l]->cstat & 48) &&
|
||||
tspriteptr[k]->owner != tspriteptr[l]->owner)
|
||||
return tspriteptr[k]->owner - tspriteptr[l]->owner;
|
||||
|
||||
if (abs(spritesxyz[k].z-globalposz) != abs(spritesxyz[l].z-globalposz))
|
||||
return abs(spritesxyz[k].z-globalposz)-abs(spritesxyz[l].z-globalposz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sortsprites(int const start, int const end)
|
||||
{
|
||||
int32_t i, gap, y, ys;
|
||||
|
||||
if (start >= end)
|
||||
return;
|
||||
|
||||
gap = 1; while (gap < end - start) gap = (gap<<1)+1;
|
||||
for (gap>>=1; gap>0; gap>>=1) //Sort sprite list
|
||||
for (i=start; i<end-gap; i++)
|
||||
for (bssize_t l=i; l>=start; l-=gap)
|
||||
{
|
||||
if (spritesxyz[l].y <= spritesxyz[l+gap].y) break;
|
||||
std::swap(tspriteptr[l],tspriteptr[l+gap]);
|
||||
std::swap(spritesxyz[l].x,spritesxyz[l+gap].x);
|
||||
std::swap(spritesxyz[l].y,spritesxyz[l+gap].y);
|
||||
}
|
||||
|
||||
ys = spritesxyz[start].y; i = start;
|
||||
for (bssize_t j=start+1; j<=end; j++)
|
||||
{
|
||||
if (j < end)
|
||||
{
|
||||
y = spritesxyz[j].y;
|
||||
if (y == ys)
|
||||
continue;
|
||||
|
||||
ys = y;
|
||||
}
|
||||
|
||||
if (j > i+1)
|
||||
{
|
||||
for (bssize_t k=i; k<j; k++)
|
||||
{
|
||||
auto const s = tspriteptr[k];
|
||||
|
||||
spritesxyz[k].z = s->z;
|
||||
if ((s->cstat&48) != 32)
|
||||
{
|
||||
int32_t yoff = tileTopOffset(s->picnum) + s->yoffset;
|
||||
int32_t yspan = (tileHeight(s->picnum) * s->yrepeat << 2);
|
||||
|
||||
spritesxyz[k].z -= (yoff*s->yrepeat)<<2;
|
||||
|
||||
if (!(s->cstat&128))
|
||||
spritesxyz[k].z -= (yspan>>1);
|
||||
if (abs(spritesxyz[k].z-globalposz) < (yspan>>1))
|
||||
spritesxyz[k].z = globalposz;
|
||||
}
|
||||
}
|
||||
|
||||
for (bssize_t k=i+1; k<j; k++)
|
||||
for (bssize_t l=i; l<k; l++)
|
||||
if (comparetsprites(k, l) < 0)
|
||||
{
|
||||
std::swap(tspriteptr[k], tspriteptr[l]);
|
||||
vec3_t tv3 = spritesxyz[k];
|
||||
spritesxyz[k] = spritesxyz[l];
|
||||
spritesxyz[l] = tv3;
|
||||
}
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// drawmasks
|
||||
//
|
||||
void renderDrawMasks(void)
|
||||
{
|
||||
# define debugmask_add(dispidx, idx) do {} while (0)
|
||||
int32_t i = spritesortcnt-1;
|
||||
int32_t numSprites = spritesortcnt;
|
||||
|
||||
spritesortcnt = 0;
|
||||
int32_t back = i;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (Polymost::polymost_spriteHasTranslucency(&tsprite[i]))
|
||||
{
|
||||
tspriteptr[spritesortcnt] = &tsprite[i];
|
||||
++spritesortcnt;
|
||||
} else
|
||||
{
|
||||
tspriteptr[back] = &tsprite[i];
|
||||
--back;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=numSprites-1; i>=0; --i)
|
||||
{
|
||||
const int32_t xs = tspriteptr[i]->x-globalposx, ys = tspriteptr[i]->y-globalposy;
|
||||
const int32_t yp = DMulScale(xs,cosviewingrangeglobalang,ys,sinviewingrangeglobalang, 6);
|
||||
const int32_t modelp = spriteIsModelOrVoxel(tspriteptr[i]);
|
||||
|
||||
if (yp > (4<<8))
|
||||
{
|
||||
const int32_t xp = DMulScale(ys,cosglobalang,-xs,singlobalang, 6);
|
||||
|
||||
if (MulScale(labs(xp+yp),xdimen, 24) >= yp)
|
||||
goto killsprite;
|
||||
|
||||
spritesxyz[i].x = Scale(xp+yp,xdimen<<7,yp);
|
||||
}
|
||||
else if ((tspriteptr[i]->cstat&48) == 0)
|
||||
{
|
||||
killsprite:
|
||||
if (!modelp)
|
||||
{
|
||||
//Delete face sprite if on wrong side!
|
||||
if (i >= spritesortcnt)
|
||||
{
|
||||
--numSprites;
|
||||
if (i != numSprites)
|
||||
{
|
||||
tspriteptr[i] = tspriteptr[numSprites];
|
||||
spritesxyz[i].x = spritesxyz[numSprites].x;
|
||||
spritesxyz[i].y = spritesxyz[numSprites].y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
--numSprites;
|
||||
--spritesortcnt;
|
||||
if (i != numSprites)
|
||||
{
|
||||
tspriteptr[i] = tspriteptr[spritesortcnt];
|
||||
spritesxyz[i].x = spritesxyz[spritesortcnt].x;
|
||||
spritesxyz[i].y = spritesxyz[spritesortcnt].y;
|
||||
tspriteptr[spritesortcnt] = tspriteptr[numSprites];
|
||||
spritesxyz[spritesortcnt].x = spritesxyz[numSprites].x;
|
||||
spritesxyz[spritesortcnt].y = spritesxyz[numSprites].y;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
spritesxyz[i].y = yp;
|
||||
}
|
||||
|
||||
sortsprites(0, spritesortcnt);
|
||||
sortsprites(spritesortcnt, numSprites);
|
||||
renderBeginScene();
|
||||
|
||||
GLInterface.EnableBlend(false);
|
||||
GLInterface.EnableAlphaTest(true);
|
||||
GLInterface.SetDepthBias(-2, -256);
|
||||
|
||||
if (spritesortcnt < numSprites)
|
||||
{
|
||||
i = spritesortcnt;
|
||||
for (bssize_t i = spritesortcnt; i < numSprites;)
|
||||
{
|
||||
int32_t py = spritesxyz[i].y;
|
||||
int32_t pcstat = tspriteptr[i]->cstat & 48;
|
||||
int32_t pangle = tspriteptr[i]->ang;
|
||||
int j = i + 1;
|
||||
if (!spriteIsModelOrVoxel(tspriteptr[i]))
|
||||
{
|
||||
while (j < numSprites && py == spritesxyz[j].y && pcstat == (tspriteptr[j]->cstat & 48) && (pcstat != 16 || pangle == tspriteptr[j]->ang)
|
||||
&& !spriteIsModelOrVoxel(tspriteptr[j]))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j - i == 1)
|
||||
{
|
||||
debugmask_add(i | 32768, tspriteptr[i]->owner);
|
||||
renderDrawSprite(i);
|
||||
tspriteptr[i] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
GLInterface.SetDepthMask(false);
|
||||
|
||||
for (bssize_t k = j-1; k >= i; k--)
|
||||
{
|
||||
debugmask_add(k | 32768, tspriteptr[k]->owner);
|
||||
renderDrawSprite(k);
|
||||
}
|
||||
|
||||
GLInterface.SetDepthMask(true);
|
||||
|
||||
GLInterface.SetColorMask(false);
|
||||
|
||||
for (bssize_t k = j-1; k >= i; k--)
|
||||
{
|
||||
renderDrawSprite(k);
|
||||
tspriteptr[k] = NULL;
|
||||
}
|
||||
|
||||
GLInterface.SetColorMask(true);
|
||||
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t numMaskWalls = maskwallcnt;
|
||||
maskwallcnt = 0;
|
||||
for (i = 0; i < numMaskWalls; i++)
|
||||
{
|
||||
if (Polymost::polymost_maskWallHasTranslucency((uwalltype *) &wall[thewall[maskwall[i]]]))
|
||||
{
|
||||
maskwall[maskwallcnt] = maskwall[i];
|
||||
maskwallcnt++;
|
||||
}
|
||||
else
|
||||
renderDrawMaskedWall(i);
|
||||
}
|
||||
|
||||
GLInterface.EnableBlend(true);
|
||||
GLInterface.EnableAlphaTest(true);
|
||||
GLInterface.SetDepthMask(false);
|
||||
|
||||
vec2f_t pos;
|
||||
|
||||
pos.x = fglobalposx;
|
||||
pos.y = fglobalposy;
|
||||
|
||||
// CAUTION: maskwallcnt and spritesortcnt may be zero!
|
||||
// Writing e.g. "while (maskwallcnt--)" is wrong!
|
||||
while (maskwallcnt)
|
||||
{
|
||||
// PLAG: sorting stuff
|
||||
const int32_t w = thewall[maskwall[maskwallcnt-1]];
|
||||
|
||||
maskwallcnt--;
|
||||
|
||||
vec2f_t dot = { (float)wall[w].x, (float)wall[w].y };
|
||||
vec2f_t dot2 = { (float)wall[wall[w].point2].x, (float)wall[wall[w].point2].y };
|
||||
vec2f_t middle = { (dot.x + dot2.x) * .5f, (dot.y + dot2.y) * .5f };
|
||||
|
||||
_equation maskeq = equation(dot.x, dot.y, dot2.x, dot2.y);
|
||||
_equation p1eq = equation(pos.x, pos.y, dot.x, dot.y);
|
||||
_equation p2eq = equation(pos.x, pos.y, dot2.x, dot2.y);
|
||||
|
||||
i = spritesortcnt;
|
||||
while (i)
|
||||
{
|
||||
i--;
|
||||
if (tspriteptr[i] != NULL)
|
||||
{
|
||||
vec2f_t spr;
|
||||
auto const tspr = tspriteptr[i];
|
||||
|
||||
spr.x = (float)tspr->x;
|
||||
spr.y = (float)tspr->y;
|
||||
|
||||
if (!sameside(&maskeq, &spr, &pos))
|
||||
{
|
||||
// Sprite and camera are on different sides of the
|
||||
// masked wall.
|
||||
|
||||
// Check if the sprite is inside the 'cone' given by
|
||||
// the rays from the camera to the two wall-points.
|
||||
const int32_t inleft = sameside(&p1eq, &middle, &spr);
|
||||
const int32_t inright = sameside(&p2eq, &middle, &spr);
|
||||
|
||||
int32_t ok = (inleft && inright);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
// If not, check if any of the border points are...
|
||||
vec2_t pp[4];
|
||||
int32_t numpts, jj;
|
||||
|
||||
const _equation pineq = inleft ? p1eq : p2eq;
|
||||
|
||||
if ((tspr->cstat & 48) == 32)
|
||||
{
|
||||
numpts = 4;
|
||||
GetFlatSpritePosition(tspr, tspr->pos.vec2, pp);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int32_t oang = tspr->ang;
|
||||
numpts = 2;
|
||||
|
||||
// Consider face sprites as wall sprites with camera ang.
|
||||
// XXX: factor 4/5 needed?
|
||||
if ((tspr->cstat & 48) != 16)
|
||||
tspriteptr[i]->ang = globalang;
|
||||
|
||||
GetWallSpritePosition(tspr, tspr->pos.vec2, pp);
|
||||
|
||||
if ((tspr->cstat & 48) != 16)
|
||||
tspriteptr[i]->ang = oang;
|
||||
}
|
||||
|
||||
for (jj=0; jj<numpts; jj++)
|
||||
{
|
||||
spr.x = (float)pp[jj].x;
|
||||
spr.y = (float)pp[jj].y;
|
||||
|
||||
if (!sameside(&maskeq, &spr, &pos)) // behind the maskwall,
|
||||
if ((sameside(&p1eq, &middle, &spr) && // inside the 'cone',
|
||||
sameside(&p2eq, &middle, &spr))
|
||||
|| !sameside(&pineq, &middle, &spr)) // or on the other outside.
|
||||
{
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
debugmask_add(i | 32768, tspr->owner);
|
||||
renderDrawSprite(i);
|
||||
|
||||
tspriteptr[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debugmask_add(maskwall[maskwallcnt], thewall[maskwall[maskwallcnt]]);
|
||||
renderDrawMaskedWall(maskwallcnt);
|
||||
}
|
||||
|
||||
while (spritesortcnt)
|
||||
{
|
||||
--spritesortcnt;
|
||||
if (tspriteptr[spritesortcnt] != NULL)
|
||||
{
|
||||
debugmask_add(i | 32768, tspriteptr[i]->owner);
|
||||
renderDrawSprite(spritesortcnt);
|
||||
tspriteptr[spritesortcnt] = NULL;
|
||||
}
|
||||
}
|
||||
renderFinishScene();
|
||||
GLInterface.SetDepthMask(true);
|
||||
GLInterface.SetDepthBias(0, 0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// qloadkvx
|
||||
|
@ -1307,16 +785,13 @@ int32_t qloadkvx(int32_t voxindex, const char *filename)
|
|||
}
|
||||
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
if (voxmodels[voxindex])
|
||||
{
|
||||
voxfree(voxmodels[voxindex]);
|
||||
voxmodels[voxindex] = NULL;
|
||||
}
|
||||
|
||||
Xfree(voxfilenames[voxindex]);
|
||||
voxfilenames[voxindex] = Xstrdup(filename);
|
||||
#endif
|
||||
voxlumps[voxindex] = fileSystem.FindFile(filename);
|
||||
|
||||
g_haveVoxels = 1;
|
||||
|
||||
|
@ -1325,21 +800,18 @@ int32_t qloadkvx(int32_t voxindex, const char *filename)
|
|||
|
||||
void vox_undefine(int32_t const tile)
|
||||
{
|
||||
ssize_t voxindex = tiletovox[tile];
|
||||
int voxindex = tiletovox[tile];
|
||||
if (voxindex < 0)
|
||||
return;
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
if (voxmodels[voxindex])
|
||||
{
|
||||
voxfree(voxmodels[voxindex]);
|
||||
voxmodels[voxindex] = NULL;
|
||||
}
|
||||
DO_FREE_AND_NULL(voxfilenames[voxindex]);
|
||||
#endif
|
||||
|
||||
voxscale[voxindex] = 65536;
|
||||
voxrotate[voxindex>>3] &= ~pow2char[voxindex&7];
|
||||
voxrotate[voxindex>>3] &= ~(1 << (voxindex&7));
|
||||
tiletovox[tile] = -1;
|
||||
|
||||
// TODO: nextvoxid
|
||||
|
@ -1683,7 +1155,7 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, in
|
|||
if (x1 == x2 && y1 == y2)
|
||||
return (sect1 == sect2);
|
||||
|
||||
sectbitmap[sect1>>3] |= pow2char[sect1&7];
|
||||
sectbitmap[sect1>>3] |= (1 << (sect1&7));
|
||||
clipsectorlist[0] = sect1; danum = 1;
|
||||
|
||||
for (dacnt=0; dacnt<danum; dacnt++)
|
||||
|
@ -1731,16 +1203,16 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, in
|
|||
if (z <= cfz[0] || z >= cfz[1])
|
||||
return 0;
|
||||
|
||||
if (!(sectbitmap[nexts>>3] & pow2char[nexts&7]))
|
||||
if (!(sectbitmap[nexts>>3] & (1 << (nexts&7))))
|
||||
{
|
||||
sectbitmap[nexts>>3] |= pow2char[nexts&7];
|
||||
sectbitmap[nexts>>3] |= (1 << (nexts&7));
|
||||
clipsectorlist[danum++] = nexts;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (sectbitmap[sect2>>3] & pow2char[sect2&7])
|
||||
if (sectbitmap[sect2>>3] & (1<<(sect2&7)))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
@ -1876,7 +1348,7 @@ void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags)
|
|||
sector[wall[w].sector].dirty = 255;
|
||||
wall[w].x = dax;
|
||||
wall[w].y = day;
|
||||
walbitmap[w>>3] |= pow2char[w&7];
|
||||
walbitmap[w>>3] |= (1<<(w&7));
|
||||
|
||||
if (!clockwise) //search points CCW
|
||||
{
|
||||
|
@ -1906,7 +1378,7 @@ void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags)
|
|||
break;
|
||||
}
|
||||
|
||||
if ((walbitmap[w>>3] & pow2char[w&7]))
|
||||
if ((walbitmap[w>>3] & (1<<(w&7))))
|
||||
{
|
||||
if (clockwise)
|
||||
break;
|
||||
|
@ -2033,35 +1505,10 @@ int findwallbetweensectors(int sect1, int sect2)
|
|||
//
|
||||
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum)
|
||||
{
|
||||
#if 0
|
||||
if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
|
||||
{
|
||||
if (inside_p(x, y, *sectnum))
|
||||
return;
|
||||
|
||||
if ((unsigned)*sectnum < (unsigned)numsectors)
|
||||
{
|
||||
const uwalltype *wal = (uwalltype *)&wall[sector[*sectnum].wallptr];
|
||||
int wallsleft = sector[*sectnum].wallnum;
|
||||
|
||||
do
|
||||
{
|
||||
int const next = wal->nextsector;
|
||||
if (inside_p(x, y, next))
|
||||
SET_AND_RETURN(*sectnum, next);
|
||||
wal++;
|
||||
}
|
||||
while (--wallsleft);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int16_t sect = *sectnum;
|
||||
updatesectorneighbor(x, y, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST);
|
||||
if (sect != -1)
|
||||
SET_AND_RETURN(*sectnum, sect);
|
||||
}
|
||||
int16_t sect = *sectnum;
|
||||
updatesectorneighbor(x, y, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST);
|
||||
if (sect != -1)
|
||||
SET_AND_RETURN(*sectnum, sect);
|
||||
|
||||
// we need to support passing in a sectnum of -1, unfortunately
|
||||
|
||||
|
@ -2077,7 +1524,6 @@ void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum)
|
|||
// as starting sector and the 'initial' z check is skipped
|
||||
// (not initial anymore because it follows the sector updating due to TROR)
|
||||
|
||||
// NOTE: This comes from Duke, therefore it's GPL!
|
||||
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum)
|
||||
{
|
||||
if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
|
||||
|
@ -2100,7 +1546,7 @@ void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t *
|
|||
if (inside_p(x, y, *sectnum))
|
||||
return;
|
||||
|
||||
uwalltype const * wal = (uwalltype *)&wall[sector[*sectnum].wallptr];
|
||||
walltype const * wal = &wall[sector[*sectnum].wallptr];
|
||||
int wallsleft = sector[*sectnum].wallnum;
|
||||
do
|
||||
{
|
||||
|
@ -2226,22 +1672,6 @@ void rotatepoint(vec2_t const pivot, vec2_t p, int16_t const daang, vec2_t * con
|
|||
p2->y = DMulScale(p.y, dacos, p.x, dasin, 14) + pivot.y;
|
||||
}
|
||||
|
||||
void videoSetCorrectedAspect()
|
||||
{
|
||||
// In DOS the game world is displayed with an aspect of 1.28 instead 1.333,
|
||||
// meaning we have to stretch it by a factor of 1.25 instead of 1.2
|
||||
// to get perfect squares
|
||||
int32_t yx = (65536 * 5) / 4;
|
||||
int32_t vr, y, x;
|
||||
|
||||
x = xdim;
|
||||
y = ydim;
|
||||
|
||||
vr = DivScale(x*3, y*4, 16);
|
||||
|
||||
renderSetAspect(vr, yx);
|
||||
}
|
||||
|
||||
//
|
||||
// setview
|
||||
//
|
||||
|
@ -2256,32 +1686,11 @@ void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
|
|||
ydimen = (y2-y1)+1;
|
||||
|
||||
fxdimen = (float) xdimen;
|
||||
#ifdef USE_OPENGL
|
||||
fydimen = (float) ydimen;
|
||||
#endif
|
||||
videoSetCorrectedAspect();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// setaspect
|
||||
//
|
||||
void renderSetAspect(int32_t daxrange, int32_t daaspect)
|
||||
{
|
||||
if (daxrange == 65536) daxrange--; // This doesn't work correctly with 65536. All other values are fine. No idea where this is evaluated wrong.
|
||||
viewingrange = daxrange;
|
||||
viewingrangerecip = DivScale(1,daxrange, 32);
|
||||
#ifdef USE_OPENGL
|
||||
fviewingrange = (float) daxrange;
|
||||
#endif
|
||||
|
||||
yxaspect = daaspect;
|
||||
xyaspect = DivScale(1,yxaspect, 32);
|
||||
xdimenscale = Scale(xdimen,yxaspect,320);
|
||||
xdimscale = Scale(320,xyaspect,xdimen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "v_2ddrawer.h"
|
||||
|
||||
|
@ -2355,41 +1764,6 @@ void renderRestoreTarget()
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// preparemirror
|
||||
//
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall,
|
||||
int32_t *tposx, int32_t *tposy, fixed_t *tang)
|
||||
{
|
||||
const int32_t x = wall[dawall].x, dx = wall[wall[dawall].point2].x-x;
|
||||
const int32_t y = wall[dawall].y, dy = wall[wall[dawall].point2].y-y;
|
||||
|
||||
const int32_t j = dx*dx + dy*dy;
|
||||
if (j == 0)
|
||||
return;
|
||||
|
||||
int i = ((dax-x)*dx + (day-y)*dy)<<1;
|
||||
|
||||
*tposx = (x<<1) + Scale(dx,i,j) - dax;
|
||||
*tposy = (y<<1) + Scale(dy,i,j) - day;
|
||||
*tang = ((gethiq16angle(dx, dy) << 1) - daang) & 0x7FFFFFF;
|
||||
|
||||
inpreparemirror = 1;
|
||||
|
||||
Polymost::polymost_prepareMirror(dax, day, daz, daang, dahoriz, dawall);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// completemirror
|
||||
//
|
||||
void renderCompleteMirror(void)
|
||||
{
|
||||
Polymost::polymost_completeMirror();
|
||||
inpreparemirror = 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
|
||||
{
|
||||
if (!(sec->ceilingstat&2))
|
||||
|
@ -2493,15 +1867,3 @@ void alignflorslope(int16_t dasect, int32_t x, int32_t y, int32_t z)
|
|||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// setrollangle
|
||||
//
|
||||
#ifdef USE_OPENGL
|
||||
void renderSetRollAngle(float rolla)
|
||||
{
|
||||
Polymost::gtang = rolla * BAngRadian;
|
||||
rollang = rolla * (BAngRadian * 180 / pi::pif());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -13,10 +13,7 @@
|
|||
#ifndef ENGINE_PRIV_H
|
||||
#define ENGINE_PRIV_H
|
||||
|
||||
extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB];
|
||||
extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
||||
extern int16_t maskwall[MAXWALLSB], maskwallcnt;
|
||||
extern tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
|
||||
extern int32_t globalpal, globalfloorpal;
|
||||
extern int32_t xdimen, xdimenscale, xdimscale, ydimen;
|
||||
extern float fxdimen;
|
||||
extern int32_t globalposx, globalposy, globalposz;
|
||||
|
@ -31,20 +28,11 @@ extern int16_t globalpicnum;
|
|||
|
||||
extern int32_t globalorientation;
|
||||
|
||||
extern int16_t sectorborder[256];
|
||||
extern int32_t hitallsprites;
|
||||
|
||||
extern int16_t bunchp2[MAXWALLSB];
|
||||
extern int16_t numscans, numbunches;
|
||||
|
||||
|
||||
// int32_t wallmost(int16_t *mostbuf, int32_t w, int32_t sectnum, char dastat);
|
||||
|
||||
void set_globalang(fixed_t const ang);
|
||||
|
||||
int32_t animateoffs(int tilenum, int fakevar);
|
||||
|
||||
static FORCE_INLINE int32_t bad_tspr(tspriteptr_t tspr)
|
||||
inline int32_t bad_tspr(tspriteptr_t tspr)
|
||||
{
|
||||
// NOTE: tspr->owner >= MAXSPRITES (could be model) has to be handled by
|
||||
// caller.
|
||||
|
|
|
@ -98,27 +98,23 @@ void freeallmodels()
|
|||
if (models)
|
||||
{
|
||||
for (i=0; i<nextmodelid; i++) mdfree(models[i]);
|
||||
DO_FREE_AND_NULL(models);
|
||||
M_Free(models);
|
||||
models = nullptr;
|
||||
nummodelsalloced = 0;
|
||||
nextmodelid = 0;
|
||||
}
|
||||
|
||||
memset(tile2model,-1,sizeof(tile2model));
|
||||
for (i=0; i<MAXTILES; i++)
|
||||
memset(tile2model[i].hudmem, 0, sizeof(tile2model[i].hudmem));
|
||||
|
||||
curextra=MAXTILES;
|
||||
|
||||
if (vertlist)
|
||||
{
|
||||
DO_FREE_AND_NULL(vertlist);
|
||||
M_Free(vertlist);
|
||||
vertlist = nullptr;
|
||||
allocmodelverts = maxmodelverts = 0;
|
||||
allocmodeltris = maxmodeltris = 0;
|
||||
}
|
||||
|
||||
#ifdef POLYMER
|
||||
DO_FREE_AND_NULL(tribuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mdinit()
|
||||
|
@ -135,7 +131,7 @@ int32_t md_loadmodel(const char *fn)
|
|||
|
||||
if (nextmodelid >= nummodelsalloced)
|
||||
{
|
||||
ml = (mdmodel_t **)Xrealloc(models,(nummodelsalloced+MODELALLOCGROUP)*sizeof(void *));
|
||||
ml = (mdmodel_t **)M_Realloc(models,(nummodelsalloced+MODELALLOCGROUP)*sizeof(void *));
|
||||
models = ml; nummodelsalloced += MODELALLOCGROUP;
|
||||
}
|
||||
|
||||
|
@ -247,7 +243,7 @@ int32_t md_defineanimation(int32_t modelid, const char *framestart, const char *
|
|||
ma.fpssc = fpssc;
|
||||
ma.flags = flags;
|
||||
|
||||
map = (mdanim_t *)Xmalloc(sizeof(mdanim_t));
|
||||
map = (mdanim_t *)M_Malloc(sizeof(mdanim_t));
|
||||
|
||||
memcpy(map, &ma, sizeof(ma));
|
||||
|
||||
|
@ -257,110 +253,6 @@ int32_t md_defineanimation(int32_t modelid, const char *framestart, const char *
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// FIXME: CURRENTLY DISABLED: interpolation may access frames we consider 'unused'?
|
||||
int32_t md_thinoutmodel(int32_t modelid, uint8_t *usedframebitmap)
|
||||
{
|
||||
md3model_t *m;
|
||||
md3surf_t *s;
|
||||
mdanim_t *anm;
|
||||
int32_t i, surfi, sub, usedframes;
|
||||
static int16_t otonframe[1024];
|
||||
|
||||
if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
|
||||
m = (md3model_t *)models[modelid];
|
||||
if (m->mdnum != 3) return -2;
|
||||
|
||||
for (anm=m->animations; anm; anm=anm->next)
|
||||
{
|
||||
if (anm->endframe <= anm->startframe)
|
||||
{
|
||||
// Printf("backward anim %d-%d\n", anm->startframe, anm->endframe);
|
||||
return -3;
|
||||
}
|
||||
|
||||
for (i=anm->startframe; i<anm->endframe; i++)
|
||||
usedframebitmap[i>>3] |= pow2char[i&7];
|
||||
}
|
||||
|
||||
sub = 0;
|
||||
for (i=0; i<m->numframes; i++)
|
||||
{
|
||||
if (!(usedframebitmap[i>>3]&pow2char[i&7]))
|
||||
{
|
||||
sub++;
|
||||
otonframe[i] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
otonframe[i] = i-sub;
|
||||
}
|
||||
|
||||
usedframes = m->numframes - sub;
|
||||
if (usedframes==0 || usedframes==m->numframes)
|
||||
return usedframes;
|
||||
|
||||
//// THIN OUT! ////
|
||||
|
||||
for (i=0; i<m->numframes; i++)
|
||||
{
|
||||
if (otonframe[i]>=0 && otonframe[i] != i)
|
||||
{
|
||||
if (m->muladdframes)
|
||||
memcpy(&m->muladdframes[2*otonframe[i]], &m->muladdframes[2*i], 2*sizeof(vec3f_t));
|
||||
memcpy(&m->head.frames[otonframe[i]], &m->head.frames[i], sizeof(md3frame_t));
|
||||
}
|
||||
}
|
||||
|
||||
for (surfi=0; surfi < m->head.numsurfs; surfi++)
|
||||
{
|
||||
s = &m->head.surfs[surfi];
|
||||
|
||||
for (i=0; i<m->numframes; i++)
|
||||
if (otonframe[i]>=0 && otonframe[i] != i)
|
||||
memcpy(&s->xyzn[otonframe[i]*s->numverts], &s->xyzn[i*s->numverts], s->numverts*sizeof(md3xyzn_t));
|
||||
}
|
||||
|
||||
////// tweak frame indices in various places
|
||||
|
||||
for (anm=m->animations; anm; anm=anm->next)
|
||||
{
|
||||
if (otonframe[anm->startframe]==-1 || otonframe[anm->endframe-1]==-1)
|
||||
Printf("md %d WTF: anm %d %d\n", modelid, anm->startframe, anm->endframe);
|
||||
|
||||
anm->startframe = otonframe[anm->startframe];
|
||||
anm->endframe = otonframe[anm->endframe-1];
|
||||
}
|
||||
|
||||
for (i=0; i<MAXTILES+EXTRATILES; i++)
|
||||
if (tile2model[i].modelid == modelid)
|
||||
{
|
||||
if (otonframe[tile2model[i].framenum]==-1)
|
||||
Printf("md %d WTF: tile %d, fr %d\n", modelid, i, tile2model[i].framenum);
|
||||
tile2model[i].framenum = otonframe[tile2model[i].framenum];
|
||||
}
|
||||
|
||||
////// realloc & change "numframes" everywhere
|
||||
|
||||
if (m->muladdframes)
|
||||
m->muladdframes = Xrealloc(m->muladdframes, 2*sizeof(vec3f_t)*usedframes);
|
||||
m->head.frames = Xrealloc(m->head.frames, sizeof(md3frame_t)*usedframes);
|
||||
|
||||
for (surfi=0; surfi < m->head.numsurfs; surfi++)
|
||||
{
|
||||
m->head.surfs[surfi].numframes = usedframes;
|
||||
// CAN'T do that because xyzn is offset from a larger block when loaded from md3:
|
||||
// m->head.surfs[surfi].xyzn = Xrealloc(m->head.surfs[surfi].xyzn, s->numverts*usedframes*sizeof(md3xyzn_t));
|
||||
}
|
||||
|
||||
m->head.numframes = usedframes;
|
||||
m->numframes = usedframes;
|
||||
|
||||
////////////
|
||||
return usedframes;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t md_defineskin(int32_t modelid, const char *skinfn, int32_t palnum, int32_t skinnum, int32_t surfnum, float param, float specpower, float specfactor, int32_t flags)
|
||||
{
|
||||
mdskinmap_t *sk, *skl;
|
||||
|
@ -382,7 +274,7 @@ int32_t md_defineskin(int32_t modelid, const char *skinfn, int32_t palnum, int32
|
|||
break;
|
||||
if (!sk)
|
||||
{
|
||||
sk = (mdskinmap_t *)Xcalloc(1,sizeof(mdskinmap_t));
|
||||
sk = (mdskinmap_t *)M_Calloc(1,sizeof(mdskinmap_t));
|
||||
|
||||
if (!skl) m->skinmap = sk;
|
||||
else skl->next = sk;
|
||||
|
@ -411,9 +303,7 @@ int32_t md_definehud(int32_t modelid, int32_t tilex, vec3f_t add, int32_t angadd
|
|||
if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
|
||||
if ((uint32_t)tilex >= (uint32_t)MAXTILES) return -2;
|
||||
|
||||
tile2model[tilex].hudmem[(flags>>2)&1] = (hudtyp *)Xmalloc(sizeof(hudtyp));
|
||||
|
||||
hudtyp * const hud = tile2model[tilex].hudmem[(flags>>2)&1];
|
||||
hudtyp * const hud = &tile2model[tilex].hudmem[(flags>>2)&1];
|
||||
|
||||
hud->add = add;
|
||||
hud->angadd = ((int16_t)angadd)|2048;
|
||||
|
@ -430,8 +320,6 @@ int32_t md_undefinetile(int32_t tile)
|
|||
|
||||
tile2model[tile].modelid = -1;
|
||||
tile2model[tile].nexttile = -1;
|
||||
DO_FREE_AND_NULL(tile2model[tile].hudmem[0]);
|
||||
DO_FREE_AND_NULL(tile2model[tile].hudmem[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -447,8 +335,6 @@ int32_t md_undefinemodel(int32_t modelid)
|
|||
if (tile2model[i].modelid == modelid)
|
||||
{
|
||||
tile2model[i].modelid = -1;
|
||||
DO_FREE_AND_NULL(tile2model[i].hudmem[0]);
|
||||
DO_FREE_AND_NULL(tile2model[i].hudmem[1]);
|
||||
}
|
||||
|
||||
if (models)
|
||||
|
@ -670,7 +556,7 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
|
||||
int32_t ournumskins, ournumglcmds;
|
||||
|
||||
m = (md2model_t *)Xcalloc(1,sizeof(md2model_t));
|
||||
m = (md2model_t *)M_Calloc(1,sizeof(md2model_t));
|
||||
m->mdnum = 2; m->scale = .01f;
|
||||
|
||||
fil.Read((char *)&head,sizeof(md2head_t));
|
||||
|
@ -686,7 +572,7 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
head.ofseof = LittleLong(head.ofseof);
|
||||
#endif
|
||||
|
||||
if ((head.id != IDP2_MAGIC) || (head.vers != 8)) { Xfree(m); return 0; } //"IDP2"
|
||||
if ((head.id != IDP2_MAGIC) || (head.vers != 8)) { M_Free(m); return 0; } //"IDP2"
|
||||
|
||||
ournumskins = head.numskins ? head.numskins : 1;
|
||||
ournumglcmds = head.numglcmds ? head.numglcmds : 1;
|
||||
|
@ -697,29 +583,29 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
m->numglcmds = head.numglcmds;
|
||||
m->framebytes = head.framebytes;
|
||||
|
||||
m->frames = (char *)Xmalloc(m->numframes*m->framebytes);
|
||||
m->glcmds = (int32_t *)Xmalloc(ournumglcmds*sizeof(int32_t));
|
||||
m->tris = (md2tri_t *)Xmalloc(head.numtris*sizeof(md2tri_t));
|
||||
m->uv = (md2uv_t *)Xmalloc(head.numuv*sizeof(md2uv_t));
|
||||
m->frames = (char *)M_Malloc(m->numframes*m->framebytes);
|
||||
m->glcmds = (int32_t *)M_Malloc(ournumglcmds*sizeof(int32_t));
|
||||
m->tris = (md2tri_t *)M_Malloc(head.numtris*sizeof(md2tri_t));
|
||||
m->uv = (md2uv_t *)M_Malloc(head.numuv*sizeof(md2uv_t));
|
||||
|
||||
fil.Seek(head.ofsframes,FileReader::SeekSet);
|
||||
if (fil.Read((char *)m->frames,m->numframes*m->framebytes) != m->numframes*m->framebytes)
|
||||
{ Xfree(m->uv); Xfree(m->tris); Xfree(m->glcmds); Xfree(m->frames); Xfree(m); return 0; }
|
||||
{ M_Free(m->uv); M_Free(m->tris); M_Free(m->glcmds); M_Free(m->frames); M_Free(m); return 0; }
|
||||
|
||||
if (m->numglcmds > 0)
|
||||
{
|
||||
fil.Seek(head.ofsglcmds,FileReader::SeekSet);
|
||||
if (fil.Read((char *)m->glcmds,m->numglcmds*sizeof(int32_t)) != (int32_t)(m->numglcmds*sizeof(int32_t)))
|
||||
{ Xfree(m->uv); Xfree(m->tris); Xfree(m->glcmds); Xfree(m->frames); Xfree(m); return 0; }
|
||||
{ M_Free(m->uv); M_Free(m->tris); M_Free(m->glcmds); M_Free(m->frames); M_Free(m); return 0; }
|
||||
}
|
||||
|
||||
fil.Seek(head.ofstris,FileReader::SeekSet);
|
||||
if (fil.Read((char *)m->tris,head.numtris*sizeof(md2tri_t)) != (int32_t)(head.numtris*sizeof(md2tri_t)))
|
||||
{ Xfree(m->uv); Xfree(m->tris); Xfree(m->glcmds); Xfree(m->frames); Xfree(m); return 0; }
|
||||
{ M_Free(m->uv); M_Free(m->tris); M_Free(m->glcmds); M_Free(m->frames); M_Free(m); return 0; }
|
||||
|
||||
fil.Seek(head.ofsuv,FileReader::SeekSet);
|
||||
if (fil.Read((char *)m->uv,head.numuv*sizeof(md2uv_t)) != (int32_t)(head.numuv*sizeof(md2uv_t)))
|
||||
{ Xfree(m->uv); Xfree(m->tris); Xfree(m->glcmds); Xfree(m->frames); Xfree(m); return 0; }
|
||||
{ M_Free(m->uv); M_Free(m->tris); M_Free(m->glcmds); M_Free(m->frames); M_Free(m); return 0; }
|
||||
|
||||
#if B_BIG_ENDIAN != 0
|
||||
{
|
||||
|
@ -761,15 +647,15 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
if ((st[i] == '/') || (st[i] == '\\')) { i++; break; }
|
||||
if (i<0) i=0;
|
||||
st[i] = 0;
|
||||
m->basepath = (char *)Xmalloc(i+1);
|
||||
m->basepath = (char *)M_Malloc(i+1);
|
||||
strcpy(m->basepath, st);
|
||||
|
||||
m->skinfn = (char *)Xmalloc(ournumskins*64);
|
||||
m->skinfn = (char *)M_Malloc(ournumskins*64);
|
||||
if (m->numskins > 0)
|
||||
{
|
||||
fil.Seek(head.ofsskins,FileReader::SeekSet);
|
||||
if (fil.Read(m->skinfn,64*m->numskins) != 64*m->numskins)
|
||||
{ Xfree(m->glcmds); Xfree(m->frames); Xfree(m); return 0; }
|
||||
{ M_Free(m->glcmds); M_Free(m->frames); M_Free(m); return 0; }
|
||||
}
|
||||
|
||||
maxmodelverts = max(maxmodelverts, m->numverts);
|
||||
|
@ -779,7 +665,7 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
|
||||
// the MD2 is now loaded internally - let's begin the MD3 conversion process
|
||||
//Printf("Beginning md3 conversion.\n");
|
||||
m3 = (md3model_t *)Xcalloc(1, sizeof(md3model_t));
|
||||
m3 = (md3model_t *)M_Calloc(1, sizeof(md3model_t));
|
||||
m3->mdnum = 3; m3->texture = nullptr; m3->scale = m->scale;
|
||||
m3->head.id = IDP3_MAGIC; m3->head.vers = 15;
|
||||
|
||||
|
@ -792,8 +678,8 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
m3->numskins = m3->head.numskins;
|
||||
m3->numframes = m3->head.numframes;
|
||||
|
||||
m3->head.frames = (md3frame_t *)Xcalloc(m3->head.numframes, sizeof(md3frame_t));
|
||||
m3->muladdframes = (vec3f_t *)Xcalloc(m->numframes * 2, sizeof(vec3f_t));
|
||||
m3->head.frames = (md3frame_t *)M_Calloc(m3->head.numframes, sizeof(md3frame_t));
|
||||
m3->muladdframes = (vec3f_t *)M_Calloc(m->numframes * 2, sizeof(vec3f_t));
|
||||
|
||||
f = (md2frame_t *)(m->frames);
|
||||
|
||||
|
@ -811,7 +697,7 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
|
||||
m3->head.tags = NULL;
|
||||
|
||||
m3->head.surfs = (md3surf_t *)Xcalloc(1, sizeof(md3surf_t));
|
||||
m3->head.surfs = (md3surf_t *)M_Calloc(1, sizeof(md3surf_t));
|
||||
s = m3->head.surfs;
|
||||
|
||||
// model converting
|
||||
|
@ -828,9 +714,9 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
|
||||
s->shaders = NULL;
|
||||
|
||||
s->tris = (md3tri_t *)Xcalloc(head.numtris, sizeof(md3tri_t));
|
||||
s->uv = (md3uv_t *)Xcalloc(s->numverts, sizeof(md3uv_t));
|
||||
s->xyzn = (md3xyzn_t *)Xcalloc(s->numverts * m->numframes, sizeof(md3xyzn_t));
|
||||
s->tris = (md3tri_t *)M_Calloc(head.numtris, sizeof(md3tri_t));
|
||||
s->uv = (md3uv_t *)M_Calloc(s->numverts, sizeof(md3uv_t));
|
||||
s->xyzn = (md3xyzn_t *)M_Calloc(s->numverts * m->numframes, sizeof(md3xyzn_t));
|
||||
|
||||
//memoryusage += (s->numverts * m->numframes * sizeof(md3xyzn_t));
|
||||
//Printf("Current model geometry memory usage : %i.\n", memoryusage);
|
||||
|
@ -875,7 +761,7 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
{
|
||||
mdskinmap_t *sk;
|
||||
|
||||
sk = (mdskinmap_t *)Xcalloc(1,sizeof(mdskinmap_t));
|
||||
sk = (mdskinmap_t *)M_Calloc(1,sizeof(mdskinmap_t));
|
||||
sk->palette = 0;
|
||||
sk->skinnum = 0;
|
||||
sk->surfnum = 0;
|
||||
|
@ -892,12 +778,12 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
|||
m3->skinmap = sk;
|
||||
}
|
||||
|
||||
m3->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * s->numtris);
|
||||
m3->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * s->numtris * 3);
|
||||
m3->maxdepths = (float *)Xmalloc(sizeof(float) * s->numtris);
|
||||
m3->indexes = (uint16_t *)M_Malloc(sizeof(uint16_t) * s->numtris);
|
||||
m3->vindexes = (uint16_t *)M_Malloc(sizeof(uint16_t) * s->numtris * 3);
|
||||
m3->maxdepths = (float *)M_Malloc(sizeof(float) * s->numtris);
|
||||
|
||||
// die MD2 ! DIE !
|
||||
Xfree(m->skinfn); Xfree(m->basepath); Xfree(m->uv); Xfree(m->tris); Xfree(m->glcmds); Xfree(m->frames); Xfree(m);
|
||||
M_Free(m->skinfn); M_Free(m->basepath); M_Free(m->uv); M_Free(m->tris); M_Free(m->glcmds); M_Free(m->frames); M_Free(m);
|
||||
|
||||
return ((md2model_t *)m3);
|
||||
}
|
||||
|
@ -949,7 +835,7 @@ static md3model_t *md3load(FileReader & fil)
|
|||
md3model_t *m;
|
||||
md3surf_t *s;
|
||||
|
||||
m = (md3model_t *)Xcalloc(1,sizeof(md3model_t));
|
||||
m = (md3model_t *)M_Calloc(1,sizeof(md3model_t));
|
||||
m->mdnum = 3; m->texture = nullptr; m->scale = .01f;
|
||||
|
||||
m->muladdframes = NULL;
|
||||
|
@ -965,7 +851,7 @@ static md3model_t *md3load(FileReader & fil)
|
|||
m->head.eof = LittleLong(m->head.eof);
|
||||
#endif
|
||||
|
||||
if ((m->head.id != IDP3_MAGIC) && (m->head.vers != 15)) { Xfree(m); return 0; } //"IDP3"
|
||||
if ((m->head.id != IDP3_MAGIC) && (m->head.vers != 15)) { M_Free(m); return 0; } //"IDP3"
|
||||
|
||||
m->numskins = m->head.numskins; //<- dead code?
|
||||
m->numframes = m->head.numframes;
|
||||
|
@ -973,19 +859,19 @@ static md3model_t *md3load(FileReader & fil)
|
|||
ofsurf = m->head.ofssurfs;
|
||||
|
||||
fil.Seek(m->head.ofsframes,FileReader::SeekSet); i = m->head.numframes*sizeof(md3frame_t);
|
||||
m->head.frames = (md3frame_t *)Xmalloc(i);
|
||||
m->head.frames = (md3frame_t *)M_Malloc(i);
|
||||
fil.Read(m->head.frames,i);
|
||||
|
||||
if (m->head.numtags == 0) m->head.tags = NULL;
|
||||
else
|
||||
{
|
||||
fil.Seek(m->head.ofstags,FileReader::SeekSet); i = m->head.numtags*sizeof(md3tag_t);
|
||||
m->head.tags = (md3tag_t *)Xmalloc(i);
|
||||
m->head.tags = (md3tag_t *)M_Malloc(i);
|
||||
fil.Read(m->head.tags,i);
|
||||
}
|
||||
|
||||
fil.Seek(m->head.ofssurfs,FileReader::SeekSet);
|
||||
m->head.surfs = (md3surf_t *)Xcalloc(m->head.numsurfs, sizeof(md3surf_t));
|
||||
m->head.surfs = (md3surf_t *)M_Calloc(m->head.numsurfs, sizeof(md3surf_t));
|
||||
// NOTE: We assume that NULL is represented by all-zeros.
|
||||
// surfs[0].geometry is for POLYMER_MD_PROCESS_CHECK (else: crashes).
|
||||
// surfs[i].geometry is for FREE_SURFS_GEOMETRY.
|
||||
|
@ -1038,7 +924,7 @@ static md3model_t *md3load(FileReader & fil)
|
|||
//memoryusage += (s->numverts * s->numframes * sizeof(md3xyzn_t));
|
||||
//Printf("Current model geometry memory usage : %i.\n", memoryusage);
|
||||
|
||||
s->tris = (md3tri_t *)Xmalloc((leng[0] + leng[1]) + (leng[2] + leng[3]));
|
||||
s->tris = (md3tri_t *)M_Malloc((leng[0] + leng[1]) + (leng[2] + leng[3]));
|
||||
|
||||
s->shaders = (md3shader_t *)(((intptr_t)s->tris)+leng[0]);
|
||||
s->uv = (md3uv_t *)(((intptr_t)s->shaders)+leng[1]);
|
||||
|
@ -1081,9 +967,9 @@ static md3model_t *md3load(FileReader & fil)
|
|||
ofsurf += s->ofsend;
|
||||
}
|
||||
|
||||
m->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf);
|
||||
m->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf * 3);
|
||||
m->maxdepths = (float *)Xmalloc(sizeof(float) * maxtrispersurf);
|
||||
m->indexes = (uint16_t *)M_Malloc(sizeof(uint16_t) * maxtrispersurf);
|
||||
m->vindexes = (uint16_t *)M_Malloc(sizeof(uint16_t) * maxtrispersurf * 3);
|
||||
m->maxdepths = (float *)M_Malloc(sizeof(float) * maxtrispersurf);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
@ -1556,12 +1442,12 @@ static void md3free(md3model_t *m)
|
|||
for (anim=m->animations; anim; anim=nanim)
|
||||
{
|
||||
nanim = anim->next;
|
||||
Xfree(anim);
|
||||
M_Free(anim);
|
||||
}
|
||||
for (sk=m->skinmap; sk; sk=nsk)
|
||||
{
|
||||
nsk = sk->next;
|
||||
Xfree(sk);
|
||||
M_Free(sk);
|
||||
}
|
||||
|
||||
if (m->head.surfs)
|
||||
|
@ -1569,21 +1455,21 @@ static void md3free(md3model_t *m)
|
|||
for (bssize_t surfi=m->head.numsurfs-1; surfi>=0; surfi--)
|
||||
{
|
||||
md3surf_t *s = &m->head.surfs[surfi];
|
||||
Xfree(s->tris);
|
||||
Xfree(s->geometry); // FREE_SURFS_GEOMETRY
|
||||
M_Free(s->tris);
|
||||
M_Free(s->geometry); // FREE_SURFS_GEOMETRY
|
||||
}
|
||||
Xfree(m->head.surfs);
|
||||
M_Free(m->head.surfs);
|
||||
}
|
||||
Xfree(m->head.tags);
|
||||
Xfree(m->head.frames);
|
||||
M_Free(m->head.tags);
|
||||
M_Free(m->head.frames);
|
||||
|
||||
Xfree(m->muladdframes);
|
||||
M_Free(m->muladdframes);
|
||||
|
||||
Xfree(m->indexes);
|
||||
Xfree(m->vindexes);
|
||||
Xfree(m->maxdepths);
|
||||
M_Free(m->indexes);
|
||||
M_Free(m->vindexes);
|
||||
M_Free(m->maxdepths);
|
||||
|
||||
Xfree(m);
|
||||
M_Free(m);
|
||||
}
|
||||
|
||||
//---------------------------------------- MD3 LIBRARY ENDS ----------------------------------------
|
||||
|
@ -1639,7 +1525,7 @@ int32_t polymost_mddraw(tspriteptr_t tspr)
|
|||
{
|
||||
if (maxmodelverts > allocmodelverts)
|
||||
{
|
||||
vertlist = (vec3f_t *) Xrealloc(vertlist, sizeof(vec3f_t)*maxmodelverts);
|
||||
vertlist = (vec3f_t *) M_Realloc(vertlist, sizeof(vec3f_t)*maxmodelverts);
|
||||
allocmodelverts = maxmodelverts;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,19 @@ Ken Silverman's official web site: http://www.advsys.net/ken
|
|||
#include "texturemanager.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "printf.h"
|
||||
#include "gamefuncs.h"
|
||||
#include "hw_drawinfo.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
union { double x; double d; };
|
||||
union { double y; double u; };
|
||||
union { double z; double v; };
|
||||
} vec3d_t;
|
||||
|
||||
static_assert(sizeof(vec3d_t) == sizeof(double) * 3);
|
||||
|
||||
|
||||
|
||||
int skiptile = -1;
|
||||
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap);
|
||||
|
@ -38,6 +51,19 @@ CVARD(Float, hw_shadescale, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "multiplier
|
|||
|
||||
// For testing - will be removed later.
|
||||
CVAR(Int, skytile, 0, 0)
|
||||
CVAR(Bool, testnewrenderer, true, 0)
|
||||
|
||||
extern fixed_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms)
|
||||
static vec3_t spritesxyz[MAXSPRITESONSCREEN + 1];
|
||||
static int16_t thewall[MAXWALLSB];
|
||||
static int16_t bunchp2[MAXWALLSB], thesector[MAXWALLSB];
|
||||
static int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
||||
static int16_t numscans, numbunches;
|
||||
static int16_t maskwall[MAXWALLSB], maskwallcnt;
|
||||
static int16_t sectorborder[256];
|
||||
static tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
|
||||
|
||||
|
||||
|
||||
namespace Polymost
|
||||
{
|
||||
|
@ -108,6 +134,27 @@ void polymost_outputGLDebugMessage(uint8_t severity, const char* format, ...)
|
|||
{
|
||||
}
|
||||
|
||||
static void set_globalang(fixed_t const ang)
|
||||
{
|
||||
globalang = FixedToInt(ang) & 2047;
|
||||
qglobalang = ang & 0x7FFFFFF;
|
||||
|
||||
float const f_ang = FixedToFloat(ang);
|
||||
float const fcosang = bcosf(f_ang);
|
||||
float const fsinang = bsinf(f_ang);
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
fcosglobalang = fcosang;
|
||||
fsinglobalang = fsinang;
|
||||
#endif
|
||||
|
||||
cosglobalang = (int)fcosang;
|
||||
singlobalang = (int)fsinang;
|
||||
|
||||
cosviewingrangeglobalang = MulScale(cosglobalang, viewingrange, 16);
|
||||
sinviewingrangeglobalang = MulScale(singlobalang, viewingrange, 16);
|
||||
}
|
||||
|
||||
static inline float polymost_invsqrt_approximation(float x)
|
||||
{
|
||||
// this is the comment
|
||||
|
@ -121,7 +168,7 @@ static float sectorVisibility(int sectnum)
|
|||
return v? ((uint8_t)(v + 16)) / 16.f : 1.f;
|
||||
}
|
||||
|
||||
template <typename T> static FORCE_INLINE void tileUpdatePicnum(T* const tileptr, int const obj)
|
||||
static void tileUpdatePicnum(short* const tileptr, int const obj)
|
||||
{
|
||||
auto& tile = *tileptr;
|
||||
|
||||
|
@ -216,7 +263,7 @@ static int32_t pow2xsplit = 0, skyzbufferhack = 0, flatskyrender = 0;
|
|||
static float drawpoly_alpha = 0.f;
|
||||
static uint8_t drawpoly_blend = 0;
|
||||
|
||||
int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall)
|
||||
int32_t polymost_maskWallHasTranslucency(walltype const * const wall)
|
||||
{
|
||||
if (wall->cstat & CSTAT_WALL_TRANSLUCENT)
|
||||
return true;
|
||||
|
@ -224,7 +271,7 @@ int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall)
|
|||
return checkTranslucentReplacement(tileGetTexture(wall->picnum)->GetID(), wall->pal);
|
||||
}
|
||||
|
||||
int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr)
|
||||
int32_t polymost_spriteHasTranslucency(spritetype const * const tspr)
|
||||
{
|
||||
if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || (tspr->clipdist & TSPR_FLAGS_DRAW_LAST) ||
|
||||
((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha))
|
||||
|
@ -1771,7 +1818,7 @@ static void polymost_drawalls(int32_t const bunch)
|
|||
domostpolymethod = DAMETH_NOMASK;
|
||||
|
||||
if (nextsectnum >= 0)
|
||||
if ((!(gotsector[nextsectnum>>3]&pow2char[nextsectnum&7])) && testvisiblemost(x0,x1))
|
||||
if ((!(gotsector[nextsectnum>>3]& (1<<(nextsectnum&7)))) && testvisiblemost(x0,x1))
|
||||
polymost_scansector(nextsectnum);
|
||||
}
|
||||
}
|
||||
|
@ -1872,7 +1919,7 @@ void polymost_scansector(int32_t sectnum)
|
|||
}
|
||||
}
|
||||
|
||||
gotsector[sectnum>>3] |= pow2char[sectnum&7];
|
||||
gotsector[sectnum>>3] |= 1<<(sectnum&7);
|
||||
|
||||
int const bunchfrst = numbunches;
|
||||
int const onumscans = numscans;
|
||||
|
@ -1895,7 +1942,7 @@ void polymost_scansector(int32_t sectnum)
|
|||
int const nextsectnum = wal->nextsector; //Scan close sectors
|
||||
|
||||
if (nextsectnum >= 0 && !(wal->cstat&32) && sectorbordercnt < countof(sectorborder))
|
||||
if ((gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0)
|
||||
if ((gotsector[nextsectnum>>3]&(1<<(nextsectnum&7))) == 0)
|
||||
{
|
||||
double const d = fp1.X* fp2.Y - fp2.X * fp1.Y;
|
||||
DVector2 const p1 = fp2 - fp1;
|
||||
|
@ -1905,7 +1952,7 @@ void polymost_scansector(int32_t sectnum)
|
|||
if (d*d < (p1.LengthSquared()) * 256.f)
|
||||
{
|
||||
sectorborder[sectorbordercnt++] = nextsectnum;
|
||||
gotsector[nextsectnum>>3] |= pow2char[nextsectnum&7];
|
||||
gotsector[nextsectnum>>3] |= 1<<(nextsectnum&7);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2570,7 +2617,7 @@ void polymost_deletesprite(int num)
|
|||
static inline int32_t polymost_findwall(tspritetype const * const tspr, vec2_t const * const tsiz, int32_t * rd)
|
||||
{
|
||||
int32_t dist = 4, closest = -1;
|
||||
auto const sect = (usectortype * )§or[tspr->sectnum];
|
||||
auto const sect = §or[tspr->sectnum];
|
||||
vec2_t n;
|
||||
|
||||
for (bssize_t i=sect->wallptr; i<sect->wallptr + sect->wallnum; i++)
|
||||
|
@ -3200,6 +3247,8 @@ _drawsprite_return:
|
|||
;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
static_assert((int)RS_YFLIP == (int)HUDFLAG_FLIPPED);
|
||||
|
||||
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
||||
|
@ -3209,9 +3258,9 @@ void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
|||
// basically this just means walls are repeating
|
||||
// while sprites are clamped
|
||||
|
||||
if ((dapalnum < (MAXPALOOKUPS - RESERVEDPALS)) && (!lookups.checkTable(dapalnum))) return;//dapalnum = 0;
|
||||
if ((dapalnum < (MAXPALOOKUPS - RESERVEDPALS)) && (!lookups.checkTable(dapalnum))) return;//dapalnum = 0;
|
||||
|
||||
//Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype);
|
||||
//Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype);
|
||||
hicprecaching = 1;
|
||||
int palid = TRANSLATION(Translation_Remap + curbasepal, dapalnum);
|
||||
auto tex = tileGetTexture(dapicnum);
|
||||
|
@ -3225,17 +3274,492 @@ void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
|||
|
||||
if (mid < 0 || models[mid]->mdnum < 2) return;
|
||||
|
||||
int const surfaces = (models[mid]->mdnum == 3) ? ((md3model_t *)models[mid])->head.numsurfs : 0;
|
||||
int const surfaces = (models[mid]->mdnum == 3) ? ((md3model_t*)models[mid])->head.numsurfs : 0;
|
||||
|
||||
for (int i = 0; i <= surfaces; i++)
|
||||
{
|
||||
auto tex = mdloadskin((md2model_t *)models[mid], 0, dapalnum, i, nullptr);
|
||||
{
|
||||
auto tex = mdloadskin((md2model_t*)models[mid], 0, dapalnum, i, nullptr);
|
||||
int palid = TRANSLATION(Translation_Remap + curbasepal, dapalnum);
|
||||
if (tex) GLInterface.SetTexture(tex, palid, CLAMP_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// preparemirror
|
||||
//
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall,
|
||||
int32_t* tposx, int32_t* tposy, fixed_t* tang)
|
||||
{
|
||||
const int32_t x = wall[dawall].x, dx = wall[wall[dawall].point2].x - x;
|
||||
const int32_t y = wall[dawall].y, dy = wall[wall[dawall].point2].y - y;
|
||||
|
||||
const int32_t j = dx * dx + dy * dy;
|
||||
if (j == 0)
|
||||
return;
|
||||
|
||||
int i = ((dax - x) * dx + (day - y) * dy) << 1;
|
||||
|
||||
*tposx = (x << 1) + Scale(dx, i, j) - dax;
|
||||
*tposy = (y << 1) + Scale(dy, i, j) - day;
|
||||
*tang = ((gethiq16angle(dx, dy) << 1) - daang) & 0x7FFFFFF;
|
||||
|
||||
inpreparemirror = 1;
|
||||
|
||||
Polymost::polymost_prepareMirror(dax, day, daz, daang, dahoriz, dawall);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// completemirror
|
||||
//
|
||||
void renderCompleteMirror(void)
|
||||
{
|
||||
Polymost::polymost_completeMirror();
|
||||
inpreparemirror = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// drawrooms
|
||||
//
|
||||
EXTERN_CVAR(Int, gl_fogmode)
|
||||
|
||||
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
|
||||
fixed_t daang, fixed_t dahoriz, int16_t dacursectnum)
|
||||
{
|
||||
checkRotatedWalls();
|
||||
|
||||
if (gl_fogmode == 1) gl_fogmode = 2; // only radial fog works with Build's screwed up coordinate system.
|
||||
|
||||
// Update starting sector number (common to classic and Polymost).
|
||||
// ADJUST_GLOBALCURSECTNUM.
|
||||
if (dacursectnum >= MAXSECTORS)
|
||||
dacursectnum -= MAXSECTORS;
|
||||
else
|
||||
{
|
||||
int i = dacursectnum;
|
||||
updatesector(daposx, daposy, &dacursectnum);
|
||||
if (dacursectnum < 0) dacursectnum = i;
|
||||
|
||||
// PK 20110123: I'm not sure what the line above is supposed to do, but 'i'
|
||||
// *can* be negative, so let's just quit here in that case...
|
||||
if (dacursectnum < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_globalpos(daposx, daposy, daposz);
|
||||
Polymost::set_globalang(daang);
|
||||
|
||||
global100horiz = dahoriz;
|
||||
|
||||
memset(gotsector, 0, sizeof(gotsector));
|
||||
qglobalhoriz = MulScale(dahoriz, DivScale(xdimenscale, viewingrange, 16), 16) + IntToFixed(ydimen >> 1);
|
||||
globalcursectnum = dacursectnum;
|
||||
Polymost::polymost_drawrooms();
|
||||
return inpreparemirror;
|
||||
}
|
||||
|
||||
// UTILITY TYPES AND FUNCTIONS FOR DRAWMASKS OCCLUSION TREE
|
||||
// typedef struct s_maskleaf
|
||||
// {
|
||||
// int32_t index;
|
||||
// _point2d p1, p2;
|
||||
// _equation maskeq, p1eq, p2eq;
|
||||
// struct s_maskleaf* branch[MAXWALLSB];
|
||||
// int32_t drawing;
|
||||
// } _maskleaf;
|
||||
//
|
||||
// _maskleaf maskleaves[MAXWALLSB];
|
||||
|
||||
// returns equation of a line given two points
|
||||
static inline _equation equation(float const x1, float const y1, float const x2, float const y2)
|
||||
{
|
||||
const float f = x2 - x1;
|
||||
|
||||
// vertical
|
||||
if (f == 0.f)
|
||||
return { 1, 0, -x1 };
|
||||
else
|
||||
{
|
||||
float const ff = (y2 - y1) / f;
|
||||
return { ff, -1, (y1 - (ff * x1)) };
|
||||
}
|
||||
}
|
||||
|
||||
static inline int32_t sameside(const _equation* eq, const vec2f_t* p1, const vec2f_t* p2)
|
||||
{
|
||||
const float sign1 = (eq->a * p1->x) + (eq->b * p1->y) + eq->c;
|
||||
const float sign2 = (eq->a * p2->x) + (eq->b * p2->y) + eq->c;
|
||||
return (sign1 * sign2) > 0.f;
|
||||
}
|
||||
|
||||
|
||||
static inline int comparetsprites(int const k, int const l)
|
||||
{
|
||||
if ((tspriteptr[k]->cstat & 48) != (tspriteptr[l]->cstat & 48))
|
||||
return (tspriteptr[k]->cstat & 48) - (tspriteptr[l]->cstat & 48);
|
||||
|
||||
if ((tspriteptr[k]->cstat & 48) == 16 && tspriteptr[k]->ang != tspriteptr[l]->ang)
|
||||
return tspriteptr[k]->ang - tspriteptr[l]->ang;
|
||||
|
||||
if (tspriteptr[k]->statnum != tspriteptr[l]->statnum)
|
||||
return tspriteptr[k]->statnum - tspriteptr[l]->statnum;
|
||||
|
||||
if (tspriteptr[k]->x == tspriteptr[l]->x &&
|
||||
tspriteptr[k]->y == tspriteptr[l]->y &&
|
||||
tspriteptr[k]->z == tspriteptr[l]->z &&
|
||||
(tspriteptr[k]->cstat & 48) == (tspriteptr[l]->cstat & 48) &&
|
||||
tspriteptr[k]->owner != tspriteptr[l]->owner)
|
||||
return tspriteptr[k]->owner - tspriteptr[l]->owner;
|
||||
|
||||
if (abs(spritesxyz[k].z - globalposz) != abs(spritesxyz[l].z - globalposz))
|
||||
return abs(spritesxyz[k].z - globalposz) - abs(spritesxyz[l].z - globalposz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sortsprites(int const start, int const end)
|
||||
{
|
||||
int32_t i, gap, y, ys;
|
||||
|
||||
if (start >= end)
|
||||
return;
|
||||
|
||||
gap = 1; while (gap < end - start) gap = (gap << 1) + 1;
|
||||
for (gap >>= 1; gap > 0; gap >>= 1) //Sort sprite list
|
||||
for (i = start; i < end - gap; i++)
|
||||
for (bssize_t l = i; l >= start; l -= gap)
|
||||
{
|
||||
if (spritesxyz[l].y <= spritesxyz[l + gap].y) break;
|
||||
std::swap(tspriteptr[l], tspriteptr[l + gap]);
|
||||
std::swap(spritesxyz[l].x, spritesxyz[l + gap].x);
|
||||
std::swap(spritesxyz[l].y, spritesxyz[l + gap].y);
|
||||
}
|
||||
|
||||
ys = spritesxyz[start].y; i = start;
|
||||
for (bssize_t j = start + 1; j <= end; j++)
|
||||
{
|
||||
if (j < end)
|
||||
{
|
||||
y = spritesxyz[j].y;
|
||||
if (y == ys)
|
||||
continue;
|
||||
|
||||
ys = y;
|
||||
}
|
||||
|
||||
if (j > i + 1)
|
||||
{
|
||||
for (bssize_t k = i; k < j; k++)
|
||||
{
|
||||
auto const s = tspriteptr[k];
|
||||
|
||||
spritesxyz[k].z = s->z;
|
||||
if ((s->cstat & 48) != 32)
|
||||
{
|
||||
int32_t yoff = tileTopOffset(s->picnum) + s->yoffset;
|
||||
int32_t yspan = (tileHeight(s->picnum) * s->yrepeat << 2);
|
||||
|
||||
spritesxyz[k].z -= (yoff * s->yrepeat) << 2;
|
||||
|
||||
if (!(s->cstat & 128))
|
||||
spritesxyz[k].z -= (yspan >> 1);
|
||||
if (abs(spritesxyz[k].z - globalposz) < (yspan >> 1))
|
||||
spritesxyz[k].z = globalposz;
|
||||
}
|
||||
}
|
||||
|
||||
for (bssize_t k = i + 1; k < j; k++)
|
||||
for (bssize_t l = i; l < k; l++)
|
||||
if (comparetsprites(k, l) < 0)
|
||||
{
|
||||
std::swap(tspriteptr[k], tspriteptr[l]);
|
||||
vec3_t tv3 = spritesxyz[k];
|
||||
spritesxyz[k] = spritesxyz[l];
|
||||
spritesxyz[l] = tv3;
|
||||
}
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// drawmasks
|
||||
//
|
||||
void renderDrawMasks(void)
|
||||
{
|
||||
# define debugmask_add(dispidx, idx) do {} while (0)
|
||||
int32_t i = spritesortcnt - 1;
|
||||
int32_t numSprites = spritesortcnt;
|
||||
|
||||
spritesortcnt = 0;
|
||||
int32_t back = i;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (Polymost::polymost_spriteHasTranslucency(&tsprite[i]))
|
||||
{
|
||||
tspriteptr[spritesortcnt] = &tsprite[i];
|
||||
++spritesortcnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
tspriteptr[back] = &tsprite[i];
|
||||
--back;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = numSprites - 1; i >= 0; --i)
|
||||
{
|
||||
const int32_t xs = tspriteptr[i]->x - globalposx, ys = tspriteptr[i]->y - globalposy;
|
||||
const int32_t yp = DMulScale(xs, cosviewingrangeglobalang, ys, sinviewingrangeglobalang, 6);
|
||||
const int32_t modelp = spriteIsModelOrVoxel(tspriteptr[i]);
|
||||
|
||||
if (yp > (4 << 8))
|
||||
{
|
||||
const int32_t xp = DMulScale(ys, cosglobalang, -xs, singlobalang, 6);
|
||||
|
||||
if (MulScale(labs(xp + yp), xdimen, 24) >= yp)
|
||||
goto killsprite;
|
||||
|
||||
spritesxyz[i].x = Scale(xp + yp, xdimen << 7, yp);
|
||||
}
|
||||
else if ((tspriteptr[i]->cstat & 48) == 0)
|
||||
{
|
||||
killsprite:
|
||||
if (!modelp)
|
||||
{
|
||||
//Delete face sprite if on wrong side!
|
||||
if (i >= spritesortcnt)
|
||||
{
|
||||
--numSprites;
|
||||
if (i != numSprites)
|
||||
{
|
||||
tspriteptr[i] = tspriteptr[numSprites];
|
||||
spritesxyz[i].x = spritesxyz[numSprites].x;
|
||||
spritesxyz[i].y = spritesxyz[numSprites].y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
--numSprites;
|
||||
--spritesortcnt;
|
||||
if (i != numSprites)
|
||||
{
|
||||
tspriteptr[i] = tspriteptr[spritesortcnt];
|
||||
spritesxyz[i].x = spritesxyz[spritesortcnt].x;
|
||||
spritesxyz[i].y = spritesxyz[spritesortcnt].y;
|
||||
tspriteptr[spritesortcnt] = tspriteptr[numSprites];
|
||||
spritesxyz[spritesortcnt].x = spritesxyz[numSprites].x;
|
||||
spritesxyz[spritesortcnt].y = spritesxyz[numSprites].y;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
spritesxyz[i].y = yp;
|
||||
}
|
||||
|
||||
sortsprites(0, spritesortcnt);
|
||||
sortsprites(spritesortcnt, numSprites);
|
||||
renderBeginScene();
|
||||
|
||||
GLInterface.EnableBlend(false);
|
||||
GLInterface.EnableAlphaTest(true);
|
||||
GLInterface.SetDepthBias(-2, -256);
|
||||
|
||||
if (spritesortcnt < numSprites)
|
||||
{
|
||||
i = spritesortcnt;
|
||||
for (bssize_t i = spritesortcnt; i < numSprites;)
|
||||
{
|
||||
int32_t py = spritesxyz[i].y;
|
||||
int32_t pcstat = tspriteptr[i]->cstat & 48;
|
||||
int32_t pangle = tspriteptr[i]->ang;
|
||||
int j = i + 1;
|
||||
if (!spriteIsModelOrVoxel(tspriteptr[i]))
|
||||
{
|
||||
while (j < numSprites && py == spritesxyz[j].y && pcstat == (tspriteptr[j]->cstat & 48) && (pcstat != 16 || pangle == tspriteptr[j]->ang)
|
||||
&& !spriteIsModelOrVoxel(tspriteptr[j]))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j - i == 1)
|
||||
{
|
||||
debugmask_add(i | 32768, tspriteptr[i]->owner);
|
||||
Polymost::polymost_drawsprite(i);
|
||||
tspriteptr[i] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
GLInterface.SetDepthMask(false);
|
||||
|
||||
for (bssize_t k = j - 1; k >= i; k--)
|
||||
{
|
||||
debugmask_add(k | 32768, tspriteptr[k]->owner);
|
||||
Polymost::polymost_drawsprite(k);
|
||||
}
|
||||
|
||||
GLInterface.SetDepthMask(true);
|
||||
|
||||
GLInterface.SetColorMask(false);
|
||||
|
||||
for (bssize_t k = j - 1; k >= i; k--)
|
||||
{
|
||||
Polymost::polymost_drawsprite(k);
|
||||
tspriteptr[k] = NULL;
|
||||
}
|
||||
|
||||
GLInterface.SetColorMask(true);
|
||||
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t numMaskWalls = maskwallcnt;
|
||||
maskwallcnt = 0;
|
||||
for (i = 0; i < numMaskWalls; i++)
|
||||
{
|
||||
if (Polymost::polymost_maskWallHasTranslucency(&wall[thewall[maskwall[i]]]))
|
||||
{
|
||||
maskwall[maskwallcnt] = maskwall[i];
|
||||
maskwallcnt++;
|
||||
}
|
||||
else
|
||||
Polymost::polymost_drawmaskwall(i);
|
||||
}
|
||||
|
||||
GLInterface.EnableBlend(true);
|
||||
GLInterface.EnableAlphaTest(true);
|
||||
GLInterface.SetDepthMask(false);
|
||||
|
||||
vec2f_t pos;
|
||||
|
||||
pos.x = fglobalposx;
|
||||
pos.y = fglobalposy;
|
||||
|
||||
// CAUTION: maskwallcnt and spritesortcnt may be zero!
|
||||
// Writing e.g. "while (maskwallcnt--)" is wrong!
|
||||
while (maskwallcnt)
|
||||
{
|
||||
// PLAG: sorting stuff
|
||||
const int32_t w = thewall[maskwall[maskwallcnt - 1]];
|
||||
|
||||
maskwallcnt--;
|
||||
|
||||
vec2f_t dot = { (float)wall[w].x, (float)wall[w].y };
|
||||
vec2f_t dot2 = { (float)wall[wall[w].point2].x, (float)wall[wall[w].point2].y };
|
||||
vec2f_t middle = { (dot.x + dot2.x) * .5f, (dot.y + dot2.y) * .5f };
|
||||
|
||||
_equation maskeq = equation(dot.x, dot.y, dot2.x, dot2.y);
|
||||
_equation p1eq = equation(pos.x, pos.y, dot.x, dot.y);
|
||||
_equation p2eq = equation(pos.x, pos.y, dot2.x, dot2.y);
|
||||
|
||||
i = spritesortcnt;
|
||||
while (i)
|
||||
{
|
||||
i--;
|
||||
if (tspriteptr[i] != NULL)
|
||||
{
|
||||
vec2f_t spr;
|
||||
auto const tspr = tspriteptr[i];
|
||||
|
||||
spr.x = (float)tspr->x;
|
||||
spr.y = (float)tspr->y;
|
||||
|
||||
if (!sameside(&maskeq, &spr, &pos))
|
||||
{
|
||||
// Sprite and camera are on different sides of the
|
||||
// masked wall.
|
||||
|
||||
// Check if the sprite is inside the 'cone' given by
|
||||
// the rays from the camera to the two wall-points.
|
||||
const int32_t inleft = sameside(&p1eq, &middle, &spr);
|
||||
const int32_t inright = sameside(&p2eq, &middle, &spr);
|
||||
|
||||
int32_t ok = (inleft && inright);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
// If not, check if any of the border points are...
|
||||
vec2_t pp[4];
|
||||
int32_t numpts, jj;
|
||||
|
||||
const _equation pineq = inleft ? p1eq : p2eq;
|
||||
|
||||
if ((tspr->cstat & 48) == 32)
|
||||
{
|
||||
numpts = 4;
|
||||
GetFlatSpritePosition(tspr, tspr->pos.vec2, pp);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int32_t oang = tspr->ang;
|
||||
numpts = 2;
|
||||
|
||||
// Consider face sprites as wall sprites with camera ang.
|
||||
// XXX: factor 4/5 needed?
|
||||
if ((tspr->cstat & 48) != 16)
|
||||
tspriteptr[i]->ang = globalang;
|
||||
|
||||
GetWallSpritePosition(tspr, tspr->pos.vec2, pp);
|
||||
|
||||
if ((tspr->cstat & 48) != 16)
|
||||
tspriteptr[i]->ang = oang;
|
||||
}
|
||||
|
||||
for (jj = 0; jj < numpts; jj++)
|
||||
{
|
||||
spr.x = (float)pp[jj].x;
|
||||
spr.y = (float)pp[jj].y;
|
||||
|
||||
if (!sameside(&maskeq, &spr, &pos)) // behind the maskwall,
|
||||
if ((sameside(&p1eq, &middle, &spr) && // inside the 'cone',
|
||||
sameside(&p2eq, &middle, &spr))
|
||||
|| !sameside(&pineq, &middle, &spr)) // or on the other outside.
|
||||
{
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
debugmask_add(i | 32768, tspr->owner);
|
||||
Polymost::polymost_drawsprite(i);
|
||||
|
||||
tspriteptr[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debugmask_add(maskwall[maskwallcnt], thewall[maskwall[maskwallcnt]]);
|
||||
Polymost::polymost_drawmaskwall(maskwallcnt);
|
||||
}
|
||||
|
||||
while (spritesortcnt)
|
||||
{
|
||||
--spritesortcnt;
|
||||
if (tspriteptr[spritesortcnt] != NULL)
|
||||
{
|
||||
debugmask_add(i | 32768, tspriteptr[i]->owner);
|
||||
Polymost::polymost_drawsprite(spritesortcnt);
|
||||
tspriteptr[spritesortcnt] = NULL;
|
||||
}
|
||||
}
|
||||
renderFinishScene();
|
||||
GLInterface.SetDepthMask(true);
|
||||
GLInterface.SetDepthBias(0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PrecacheHardwareTextures(int nTile)
|
||||
{
|
||||
// PRECACHE
|
||||
|
@ -3243,3 +3767,45 @@ void PrecacheHardwareTextures(int nTile)
|
|||
Polymost::polymost_precache(nTile, 0, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// setrollangle
|
||||
//
|
||||
void renderSetRollAngle(float rolla)
|
||||
{
|
||||
Polymost::gtang = rolla * BAngRadian;
|
||||
}
|
||||
|
||||
void videoSetCorrectedAspect()
|
||||
{
|
||||
// In DOS the game world is displayed with an aspect of 1.28 instead 1.333,
|
||||
// meaning we have to stretch it by a factor of 1.25 instead of 1.2
|
||||
// to get perfect squares
|
||||
int32_t yx = (65536 * 5) / 4;
|
||||
int32_t vr, y, x;
|
||||
|
||||
x = xdim;
|
||||
y = ydim;
|
||||
|
||||
vr = DivScale(x * 3, y * 4, 16);
|
||||
|
||||
renderSetAspect(vr, yx);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// setaspect
|
||||
//
|
||||
void renderSetAspect(int32_t daxrange, int32_t daaspect)
|
||||
{
|
||||
if (daxrange == 65536) daxrange--; // This doesn't work correctly with 65536. All other values are fine. No idea where this is evaluated wrong.
|
||||
viewingrange = daxrange;
|
||||
viewingrangerecip = DivScale(1, daxrange, 32);
|
||||
fviewingrange = (float)daxrange;
|
||||
|
||||
yxaspect = daaspect;
|
||||
xyaspect = DivScale(1, yxaspect, 32);
|
||||
xdimenscale = Scale(xdimen, yxaspect, 320);
|
||||
xdimscale = Scale(320, xyaspect, xdimen);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,10 +22,7 @@ using namespace Polymost;
|
|||
|
||||
void voxfree(voxmodel_t *m)
|
||||
{
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
Xfree(m);
|
||||
if (m) delete m;
|
||||
}
|
||||
|
||||
voxmodel_t *voxload(int lumpnum)
|
||||
|
@ -33,8 +30,8 @@ voxmodel_t *voxload(int lumpnum)
|
|||
FVoxel* voxel = R_LoadKVX(lumpnum);
|
||||
if (voxel != nullptr)
|
||||
{
|
||||
voxmodel_t* vm = (voxmodel_t*)Xmalloc(sizeof(voxmodel_t));
|
||||
memset(vm, 0, sizeof(voxmodel_t));
|
||||
voxmodel_t* vm = new voxmodel_t;
|
||||
*vm = {};
|
||||
auto pivot = voxel->Mips[0].Pivot;
|
||||
vm->mdnum = 1; //VOXel model id
|
||||
vm->scale = vm->bscale = 1.f;
|
||||
|
@ -53,7 +50,6 @@ voxmodel_t *voxload(int lumpnum)
|
|||
}
|
||||
|
||||
//Draw voxel model as perfect cubes
|
||||
// Note: This is a hopeless mess that totally forfeits any chance of using a vertex buffer with its messy coordinate adjustments. :(
|
||||
int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr)
|
||||
{
|
||||
float f, g, k0, zoff;
|
||||
|
@ -193,7 +189,7 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr)
|
|||
return 1;
|
||||
}
|
||||
|
||||
extern char* voxfilenames[MAXVOXELS];
|
||||
extern int voxlumps[MAXVOXELS];
|
||||
void (*PolymostProcessVoxels_Callback)(void) = NULL;
|
||||
void PolymostProcessVoxels(void)
|
||||
{
|
||||
|
@ -207,17 +203,16 @@ void PolymostProcessVoxels(void)
|
|||
|
||||
Printf(PRINT_NONOTIFY, "Generating voxel models for Polymost. This may take a while...\n");
|
||||
|
||||
for (bssize_t i = 0; i < MAXVOXELS; i++)
|
||||
for (int i = 0; i < MAXVOXELS; i++)
|
||||
{
|
||||
if (voxfilenames[i])
|
||||
int lumpnum = voxlumps[i];
|
||||
if (lumpnum > 0)
|
||||
{
|
||||
int lumpnum = fileSystem.FindFile(voxfilenames[i]);
|
||||
if (lumpnum >= 0)
|
||||
{
|
||||
voxmodels[i] = voxload(lumpnum);
|
||||
voxmodels[i] = voxload(lumpnum);
|
||||
if (voxmodels[i])
|
||||
voxmodels[i]->scale = voxscale[i] * (1.f / 65536.f);
|
||||
}
|
||||
DO_FREE_AND_NULL(voxfilenames[i]);
|
||||
else
|
||||
Printf("Unable to load voxel from %s\n", fileSystem.GetFileFullPath(lumpnum));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define MAXWIDTH 12000
|
||||
#define MAXHEIGHT 5000
|
||||
|
@ -101,3 +102,6 @@ enum EStateUseFlags
|
|||
SUF_WEAPON = 4,
|
||||
SUF_ITEM = 8,
|
||||
};
|
||||
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
|
|
@ -73,6 +73,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "automap.h"
|
||||
#include "v_draw.h"
|
||||
#include "gi.h"
|
||||
#include "gamefuncs.h"
|
||||
|
||||
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
@ -226,10 +227,11 @@ static IntRect System_GetSceneRect()
|
|||
{
|
||||
// Special handling so the view with a visible status bar displays properly
|
||||
int height = windowxy2.y - windowxy1.y + 1, width = windowxy2.x - windowxy1.x + 1;
|
||||
int bottomspace = screen->GetHeight() - windowxy2.y;
|
||||
|
||||
IntRect mSceneViewport;
|
||||
mSceneViewport.left = windowxy1.x;
|
||||
mSceneViewport.top = windowxy1.y;
|
||||
mSceneViewport.top = (bottomspace - windowxy1.y/2);
|
||||
mSceneViewport.width = width;
|
||||
mSceneViewport.height = height;
|
||||
return mSceneViewport;
|
||||
|
@ -579,7 +581,7 @@ int GameMain()
|
|||
TileFiles.CloseAll(); // delete the texture data before shutting down graphics.
|
||||
GLInterface.Deinit();
|
||||
I_ShutdownGraphics();
|
||||
engineUnInit();
|
||||
freeallmodels();
|
||||
if (gi)
|
||||
{
|
||||
delete gi;
|
||||
|
|
|
@ -262,7 +262,7 @@ void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// Check if some walls are set to be rotated textures.
|
||||
// Check if some walls are set to use rotated textures.
|
||||
// Ideally this should just have been done with texture rotation,
|
||||
// but the effects on the render code would be too severe due to the alignment mess.
|
||||
//
|
||||
|
|
|
@ -98,4 +98,14 @@ inline int sectorofwall(int wallNum)
|
|||
return -1;
|
||||
}
|
||||
|
||||
extern int numshades;
|
||||
|
||||
// Return type is int because this gets passed to variadic functions where structs may produce undefined behavior.
|
||||
inline int shadeToLight(int shade)
|
||||
{
|
||||
shade = clamp(shade, 0, numshades - 1);
|
||||
int light = Scale(numshades - 1 - shade, 255, numshades - 1);
|
||||
return PalEntry(255, light, light, light);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ bool System_WantGuiCapture(); // During playing this tells us whether the game m
|
|||
#include "inputstate.h"
|
||||
|
||||
class FSerializer;
|
||||
struct FRenderViewpoint;
|
||||
|
||||
struct GameStats
|
||||
{
|
||||
|
@ -101,7 +102,7 @@ struct GameInterface
|
|||
virtual int chaseCamX(binangle ang) { return 0; }
|
||||
virtual int chaseCamY(binangle ang) { return 0; }
|
||||
virtual int chaseCamZ(fixedhoriz horiz) { return 0; }
|
||||
virtual void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) {}
|
||||
virtual void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) = 0;
|
||||
|
||||
virtual FString statFPS()
|
||||
{
|
||||
|
|
|
@ -375,6 +375,9 @@ static void insertAllSprites(const char* filename, const vec3_t* pos, int16_t* c
|
|||
void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, int16_t* cursectnum)
|
||||
{
|
||||
inputState.ClearAllInput();
|
||||
memset(sector, 0, sizeof(*sector) * MAXSECTORS);
|
||||
memset(wall, 0, sizeof(*wall) * MAXWALLS);
|
||||
memset(sprite, 0, sizeof(*sector) * MAXSPRITES);
|
||||
|
||||
FileReader fr = fileSystem.OpenFileReader(filename);
|
||||
if (!fr.isOpen()) I_Error("Unable to open map %s", filename);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "../../glbackend/glbackend.h"
|
||||
|
||||
LookupTableInfo lookups;
|
||||
int numshades;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -136,7 +137,6 @@ void paletteLoadFromDisk(void)
|
|||
|
||||
void LookupTableInfo::postLoadTables(void)
|
||||
{
|
||||
globalpal = 0;
|
||||
GPalette.GenerateGlobalBrightmapFromColormap(getTable(0), numshades);
|
||||
|
||||
// Try to detect fullbright translations. Unfortunately this cannot be used to detect fade strength because of loss of color precision in the palette map.
|
||||
|
|
|
@ -165,7 +165,7 @@ inline void videoclearFade()
|
|||
|
||||
void videoTintBlood(int32_t r, int32_t g, int32_t b);
|
||||
|
||||
extern int32_t globalpal, globalfloorpal;
|
||||
extern int numshades;
|
||||
extern void paletteLoadFromDisk(void);
|
||||
|
||||
|
||||
|
|
|
@ -171,17 +171,18 @@ void RenderViewpoint(FRenderViewpoint& mainvp, IntRect* bounds, float fov, float
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FRenderViewpoint SetupView(spritetype* cam, const vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang)
|
||||
FRenderViewpoint SetupViewpoint(spritetype* cam, const vec3_t& position, int sectnum, binangle angle, fixedhoriz horizon, lookangle rollang)
|
||||
{
|
||||
FRenderViewpoint r_viewpoint{};
|
||||
r_viewpoint.CameraSprite = cam;
|
||||
r_viewpoint.SectNum = sectnum;
|
||||
r_viewpoint.SectNums = nullptr;
|
||||
r_viewpoint.SectCount = sectnum;
|
||||
r_viewpoint.Pos = { position.x / 16.f, position.y / -16.f, position.z / -256.f };
|
||||
r_viewpoint.HWAngles.Yaw = -90.f + q16ang(q16angle).asdeg();
|
||||
r_viewpoint.HWAngles.Pitch = -HorizToPitch(q16horizon);
|
||||
r_viewpoint.HWAngles.Roll = -rollang;
|
||||
r_viewpoint.HWAngles.Yaw = -90.f + angle.asdeg();
|
||||
r_viewpoint.HWAngles.Pitch = -horizon.aspitch();
|
||||
r_viewpoint.HWAngles.Roll = -rollang.asdeg();
|
||||
r_viewpoint.FieldOfView = (float)r_fov;
|
||||
r_viewpoint.RotAngle = q16ang(q16angle).asbam();
|
||||
r_viewpoint.RotAngle = angle.asbam();
|
||||
return r_viewpoint;
|
||||
}
|
||||
|
||||
|
@ -263,7 +264,7 @@ static void CheckTimer(FRenderState &state, uint64_t ShaderStartTime)
|
|||
}
|
||||
|
||||
|
||||
void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang)
|
||||
void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sectnum, binangle angle, fixedhoriz horizon, lookangle rollang)
|
||||
{
|
||||
checkRotatedWalls();
|
||||
|
||||
|
@ -278,7 +279,7 @@ void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sect
|
|||
RenderState->SetVertexBuffer(screen->mVertexData);
|
||||
screen->mVertexData->Reset();
|
||||
|
||||
FRenderViewpoint r_viewpoint = SetupView(playersprite, position, sectnum, q16angle, q16horizon, rollang);
|
||||
FRenderViewpoint r_viewpoint = SetupViewpoint(playersprite, position, sectnum, angle, horizon, rollang);
|
||||
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
||||
|
||||
checkBenchActive();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
class FSerializer;
|
||||
|
||||
void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang);
|
||||
void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sectnum, binangle angle, fixedhoriz horizon, lookangle rollang);
|
||||
|
||||
struct PortalDesc
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ inline int portalAdd(int type, int target, int dx = 0, int dy = 0, int dz = 0)
|
|||
{
|
||||
auto& pt = allPortals[allPortals.Reserve(1)];
|
||||
pt.type = type;
|
||||
pt.targets.Push(target);
|
||||
if (target >= 0) pt.targets.Push(target);
|
||||
pt.dx = dx;
|
||||
pt.dy = dy;
|
||||
pt.dz = dz;
|
||||
|
@ -50,7 +50,7 @@ inline void mergePortals()
|
|||
{
|
||||
auto& pt2 = allPortals[j];
|
||||
if (pt1.type != pt2.type || pt1.dx != pt2.dx || pt1.dy != pt2.dy || pt1.dz != pt2.dz) continue;
|
||||
for (unsigned s = 0; s < pt1.targets.Size(); s++)
|
||||
for (unsigned s = 0; s < pt1.targets.Size() && pt2.targets.Size(); s++)
|
||||
{
|
||||
for (unsigned t = 0; t < pt2.targets.Size(); t++)
|
||||
{
|
||||
|
@ -63,9 +63,9 @@ inline void mergePortals()
|
|||
{
|
||||
//Printf("Merged %d and %d\n", i, j);
|
||||
if (sector[n].portalnum == j) sector[n].portalnum = i;
|
||||
didsomething = true;
|
||||
break;
|
||||
}
|
||||
didsomething = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "hw_drawstructs.h"
|
||||
#include "automap.h"
|
||||
#include "gamefuncs.h"
|
||||
#include "hw_portal.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -52,8 +53,13 @@ void BunchDrawer::Init(HWDrawInfo *_di, Clipper* c, vec2_t& view)
|
|||
clipper = c;
|
||||
viewx = view.x * (1/ 16.f);
|
||||
viewy = view.y * -(1/ 16.f);
|
||||
iview = view;
|
||||
StartScene();
|
||||
clipper->SetViewpoint(view);
|
||||
|
||||
gcosang = bamang(di->Viewpoint.RotAngle).fcos();
|
||||
gsinang = bamang(di->Viewpoint.RotAngle).fsin();
|
||||
|
||||
for (int i = 0; i < numwalls; i++)
|
||||
{
|
||||
// Precalculate the clip angles to avoid doing this repeatedly during level traversal.
|
||||
|
@ -119,15 +125,6 @@ void BunchDrawer::DeleteBunch(int index)
|
|||
|
||||
bool BunchDrawer::CheckClip(walltype* wal)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (wal - wall == 843 || wal - wall == 847)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
auto pt2 = &wall[wal->point2];
|
||||
sectortype* backsector = §or[wal->nextsector];
|
||||
sectortype* frontsector = §or[wall[wal->nextwall].nextsector];
|
||||
|
@ -427,16 +424,41 @@ void BunchDrawer::ProcessSector(int sectnum)
|
|||
if (gotsector[sectnum]) return;
|
||||
gotsector.Set(sectnum);
|
||||
|
||||
Bsp.Clock();
|
||||
|
||||
auto sect = §or[sectnum];
|
||||
bool inbunch;
|
||||
binangle startangle;
|
||||
|
||||
SetupSprite.Clock();
|
||||
|
||||
int z;
|
||||
SectIterator it(sectnum);
|
||||
while ((z = it.NextIndex()) >= 0)
|
||||
{
|
||||
auto const spr = (uspriteptr_t)&sprite[z];
|
||||
|
||||
if ((spr->cstat & CSTAT_SPRITE_INVISIBLE) || spr->xrepeat == 0 || spr->yrepeat == 0) // skip invisible sprites
|
||||
continue;
|
||||
|
||||
int sx = spr->x - iview.x, sy = spr->y - int(iview.y);
|
||||
|
||||
// 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) ||
|
||||
(r_voxels && tiletovox[spr->picnum] >= 0 && voxmodels[tiletovox[spr->picnum]]) ||
|
||||
DMulScale(bcos(spr->ang), -sx, bsin(spr->ang), -sy, 6) > 0)
|
||||
if (renderAddTsprite(z, sectnum))
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetupSprite.Unclock();
|
||||
|
||||
|
||||
SetupFlat.Clock();
|
||||
HWFlat flat;
|
||||
flat.ProcessSector(di, §or[sectnum]);
|
||||
SetupFlat.Unclock();
|
||||
Bsp.Clock();
|
||||
|
||||
//Todo: process subsectors
|
||||
inbunch = false;
|
||||
|
@ -491,9 +513,10 @@ void BunchDrawer::ProcessSector(int sectnum)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void BunchDrawer::RenderScene(int viewsector)
|
||||
void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount)
|
||||
{
|
||||
ProcessSector(viewsector);
|
||||
for(unsigned i=0;i<sectcount;i++)
|
||||
ProcessSector(viewsectors[i]);
|
||||
while (Bunches.Size() > 0)
|
||||
{
|
||||
int closest = FindClosestBunch();
|
||||
|
|
|
@ -24,6 +24,8 @@ class BunchDrawer
|
|||
TArray<FBunch> Bunches;
|
||||
TArray<int> CompareData;
|
||||
double viewx, viewy;
|
||||
vec2_t iview;
|
||||
float gcosang, gsinang;
|
||||
FixedBitArray<MAXSECTORS> gotsector;
|
||||
|
||||
private:
|
||||
|
@ -50,5 +52,5 @@ private:
|
|||
|
||||
public:
|
||||
void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view);
|
||||
void RenderScene(int viewsector);
|
||||
void RenderScene(const int* viewsectors, unsigned sectcount);
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "hw_clipper.h"
|
||||
#include "v_draw.h"
|
||||
#include "gamecvars.h"
|
||||
#include "gamestruct.h"
|
||||
|
||||
EXTERN_CVAR(Float, r_visibility)
|
||||
CVAR(Bool, gl_bandedswlight, false, CVAR_ARCHIVE)
|
||||
|
@ -306,9 +307,18 @@ void HWDrawInfo::CreateScene()
|
|||
screen->mVertexData->Map();
|
||||
screen->mLights->Map();
|
||||
|
||||
spritesortcnt = 0;
|
||||
|
||||
vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) };
|
||||
mDrawer.Init(this, mClipper, view);
|
||||
mDrawer.RenderScene(vp.SectNum);
|
||||
if (vp.SectNums)
|
||||
mDrawer.RenderScene(vp.SectNums, vp.SectCount);
|
||||
else
|
||||
mDrawer.RenderScene(&vp.SectCount, 1);
|
||||
|
||||
SetupSprite.Clock();
|
||||
gi->processSprites(view.x, view.y, vp.Pos.Z * -256, bamang(vp.RotAngle), vp.TicFrac * 65536);
|
||||
SetupSprite.Unclock();
|
||||
|
||||
screen->mLights->Unmap();
|
||||
screen->mVertexData->Unmap();
|
||||
|
|
|
@ -40,7 +40,8 @@ struct FRenderViewpoint
|
|||
FRotator HWAngles;
|
||||
FAngle FieldOfView;
|
||||
angle_t RotAngle;
|
||||
int SectNum;
|
||||
int* SectNums;
|
||||
int SectCount;
|
||||
double TicFrac;
|
||||
};
|
||||
//==========================================================================
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "flatvertices.h"
|
||||
#include "hw_clock.h"
|
||||
#include "texturemanager.h"
|
||||
#include "gamestruct.h"
|
||||
|
||||
EXTERN_CVAR(Int, r_mirror_recursions)
|
||||
EXTERN_CVAR(Bool, gl_portals)
|
||||
|
@ -398,6 +399,7 @@ void HWPortal::RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestenci
|
|||
void HWScenePortalBase::ClearClipper(HWDrawInfo *di, Clipper *clipper)
|
||||
{
|
||||
auto outer_di = di->outer;
|
||||
#if 0 // todo: fixme or remove - Unlike for Doom this won't be of great benefit with Build's rendering approach.
|
||||
// This requires maximum precision, so convert everything to double.
|
||||
DAngle angleOffset = deltaangle(DAngle(outer_di->Viewpoint.HWAngles.Yaw.Degrees), DAngle(di->Viewpoint.HWAngles.Yaw.Degrees));
|
||||
|
||||
|
@ -418,6 +420,7 @@ void HWScenePortalBase::ClearClipper(HWDrawInfo *di, Clipper *clipper)
|
|||
clipper->SafeRemoveClipRange(startang, endang);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// and finally clip it to the visible area
|
||||
angle_t a1 = di->FrustumAngle();
|
||||
|
@ -554,7 +557,9 @@ bool HWMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clippe
|
|||
int newy = int((y << 1) + Scale(dy, i, j) - view.y);
|
||||
int newan = ((gethiq16angle(dx, dy) << 1) - bamang(vp.RotAngle).asq16()) & 0x7FFFFFF;
|
||||
vp.RotAngle = q16ang(newan).asbam();
|
||||
vp.SectNum = line->sector;
|
||||
vp.SectNums = nullptr;
|
||||
vp.SectCount = line->sector;
|
||||
|
||||
|
||||
vp.Pos.X = newx / 16.f;
|
||||
vp.Pos.Y = newy / -16.f;
|
||||
|
@ -636,7 +641,8 @@ bool HWLineToLinePortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *cl
|
|||
int origx = vp.Pos.X * 16;
|
||||
int origy = vp.Pos.Y * -16;
|
||||
|
||||
vp.SectNum = line->sector;
|
||||
vp.SectNums = nullptr;
|
||||
vp.SectCount = line->sector;
|
||||
vp.Pos.X = npos.X;
|
||||
vp.Pos.Y = npos.Y;
|
||||
|
||||
|
@ -689,7 +695,8 @@ bool HWLineToSpritePortal::Setup(HWDrawInfo* di, FRenderState& rstate, Clipper*
|
|||
int origx = vp.Pos.X * 16;
|
||||
int origy = vp.Pos.Y * -16;
|
||||
|
||||
vp.SectNum = camera->sectnum;
|
||||
vp.SectNums = nullptr;
|
||||
vp.SectCount = camera->sectnum;
|
||||
vp.Pos.X = npos.X;
|
||||
vp.Pos.Y = npos.Y;
|
||||
|
||||
|
@ -798,16 +805,23 @@ bool HWSkyboxPortal::AllowSSAO() { return false; } // [MK] sector skyboxes don't
|
|||
//-----------------------------------------------------------------------------
|
||||
bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper)
|
||||
{
|
||||
auto state = mState;
|
||||
// TODO: Handle recursion more intelligently
|
||||
auto& state = mState;
|
||||
if (state->renderdepth > r_mirror_recursions)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto portal = origin;
|
||||
auto &vp = di->Viewpoint;
|
||||
|
||||
vp.Pos += DVector3(portal->dx / 16., portal->dy / -16., portal->dz / -256.);
|
||||
//vp.ActorPos += origin->mDisplacement;
|
||||
//vp.ViewActor = nullptr;
|
||||
vp.SectNums = portal->targets.Data();
|
||||
vp.SectCount = portal->targets.Size();
|
||||
type = origin->type;
|
||||
state->insectorportal = true;
|
||||
|
||||
// avoid recursions!
|
||||
screen->instack[origin->type == PORTAL_SECTOR_CEILING ? 1 : 0]++;
|
||||
screen->instack[type == PORTAL_SECTOR_CEILING ? 1 : 0]++;
|
||||
|
||||
di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));
|
||||
//SetupCoverage(di);
|
||||
|
@ -819,7 +833,8 @@ bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
|
|||
|
||||
void HWSectorStackPortal::Shutdown(HWDrawInfo *di, FRenderState &rstate)
|
||||
{
|
||||
screen->instack[origin->type == PORTAL_SECTOR_CEILING ? 1 : 0]--;
|
||||
screen->instack[type == PORTAL_SECTOR_CEILING ? 1 : 0]--;
|
||||
mState->insectorportal = false;
|
||||
}
|
||||
|
||||
const char *HWSectorStackPortal::GetName() { return "Sectorstack"; }
|
||||
|
@ -829,7 +844,7 @@ const char *HWSectorStackPortal::GetName() { return "Sectorstack"; }
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// Plane Mirror Portal
|
||||
// Plane Mirror Portal (currently not needed, Witchaven 2 is the only Build game using such a feature)
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -182,6 +182,7 @@ struct FPortalSceneState
|
|||
|
||||
int PlaneMirrorMode = 0;
|
||||
bool inskybox = 0;
|
||||
bool insectorportal = false;
|
||||
|
||||
UniqueList<HWSkyInfo> UniqueSkies;
|
||||
UniqueList<HWHorizonInfo> UniqueHorizons;
|
||||
|
@ -350,6 +351,7 @@ public:
|
|||
struct HWSectorStackPortal : public HWScenePortalBase
|
||||
{
|
||||
TArray<sectortype *> sectors;
|
||||
int type = -1;
|
||||
protected:
|
||||
bool Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper) override;
|
||||
void Shutdown(HWDrawInfo *di, FRenderState &rstate) override;
|
||||
|
|
|
@ -81,13 +81,13 @@ void HWWall::SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowr
|
|||
{
|
||||
int ptype;
|
||||
|
||||
if (sector->portalflags == PORTAL_SECTOR_CEILING || sector->portalflags == PORTAL_SECTOR_FLOOR)
|
||||
if ((sector->portalflags == PORTAL_SECTOR_CEILING && plane == plane_ceiling) || (sector->portalflags == PORTAL_SECTOR_FLOOR && plane == plane_floor))
|
||||
{
|
||||
if (screen->instack[1 - plane] || allPortals.Size() == 0) return;
|
||||
if (screen->instack[1 - plane] || sector->portalnum >= (int)allPortals.Size()) return;
|
||||
portal = &allPortals[sector->portalnum];
|
||||
PutPortal(di, PORTALTYPE_SECTORSTACK, plane);
|
||||
}
|
||||
else if (sector->portalflags == PORTAL_SECTOR_CEILING_REFLECT || sector->portalflags == PORTAL_SECTOR_FLOOR_REFLECT)
|
||||
else if ((sector->portalflags == PORTAL_SECTOR_CEILING_REFLECT && plane == plane_ceiling) || (sector->portalflags == PORTAL_SECTOR_FLOOR_REFLECT && plane == plane_floor))
|
||||
{
|
||||
ptype = PORTALTYPE_PLANEMIRROR;
|
||||
if (plane == plane_ceiling && (sector->ceilingstat & CSTAT_SECTOR_SLOPE)) return;
|
||||
|
@ -115,7 +115,7 @@ void HWWall::SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowr
|
|||
|
||||
void HWWall::SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v2, float fch1, float fch2, float ffh1, float ffh2)
|
||||
{
|
||||
if (fs->ceilingstat & CSTAT_SECTOR_SKY)
|
||||
if ((fs->ceilingstat & CSTAT_SECTOR_SKY) || fs->portalflags == PORTAL_SECTOR_CEILING || fs->portalflags == PORTAL_SECTOR_CEILING_REFLECT)
|
||||
{
|
||||
ztop[0] = ztop[1] = 32768.0f;
|
||||
zbottom[0] = fch1;
|
||||
|
@ -123,7 +123,7 @@ void HWWall::SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v
|
|||
SkyPlane(di, fs, plane_ceiling, true);
|
||||
}
|
||||
|
||||
if (fs->floorstat & CSTAT_SECTOR_SKY)
|
||||
if ((fs->floorstat & CSTAT_SECTOR_SKY) || fs->portalflags == PORTAL_SECTOR_FLOOR || fs->portalflags == PORTAL_SECTOR_FLOOR_REFLECT)
|
||||
{
|
||||
ztop[0] = ffh1;
|
||||
ztop[1] = ffh2;
|
||||
|
|
|
@ -496,6 +496,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, spritetype &c, spritet
|
|||
("hitag", c.hitag, def->hitag)
|
||||
("extra", c.extra, def->extra)
|
||||
("detail", c.detail, def->detail)
|
||||
("time", c.time, def->time)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
|
|
|
@ -917,10 +917,10 @@ bool AddINIFile(const char* pzFile, bool bForce = false)
|
|||
if (findfrompath(pzFile, &pzFN)) return false; // failed to resolve the filename
|
||||
if (!FileExists(pzFN))
|
||||
{
|
||||
Xfree(pzFN);
|
||||
M_Free(pzFN);
|
||||
return false;
|
||||
} // failed to stat the file
|
||||
Xfree(pzFN);
|
||||
M_Free(pzFN);
|
||||
IniFile* pTempIni = new IniFile(pzFile);
|
||||
if (!pTempIni->FindSection("Episode1"))
|
||||
{
|
||||
|
|
|
@ -632,7 +632,7 @@ void artSetupMapArt(const char* filename)
|
|||
}
|
||||
|
||||
|
||||
for (bssize_t i = 0; i < MAXARTFILES_TOTAL - MAXARTFILES_BASE; i++)
|
||||
for (int i = 0; i < MAXARTFILES_TOTAL - MAXARTFILES_BASE; i++)
|
||||
{
|
||||
FStringf fullname("%s_%02d.art", filename, i);
|
||||
TileFiles.LoadArtFile(fullname, filename);
|
||||
|
|
|
@ -126,7 +126,7 @@ static tspritetype *viewAddEffect(int nTSprite, VIEW_EFFECT nViewEffect)
|
|||
{
|
||||
assert(nViewEffect >= 0 && nViewEffect < kViewEffectMax);
|
||||
auto pTSprite = &tsprite[nTSprite];
|
||||
if (gDetail < effectDetail[nViewEffect] || nTSprite >= maxspritesonscreen) return NULL;
|
||||
if (gDetail < effectDetail[nViewEffect] || nTSprite >= MAXSPRITESONSCREEN) return NULL;
|
||||
switch (nViewEffect)
|
||||
{
|
||||
case VIEW_EFFECT_18:
|
||||
|
@ -220,7 +220,7 @@ static tspritetype *viewAddEffect(int nTSprite, VIEW_EFFECT nViewEffect)
|
|||
{
|
||||
nAng = (nAng+1024)&2047;
|
||||
}
|
||||
for (int i = 0; i < 5 && spritesortcnt < maxspritesonscreen; i++)
|
||||
for (int i = 0; i < 5 && spritesortcnt < MAXSPRITESONSCREEN; i++)
|
||||
{
|
||||
int nSector = pTSprite->sectnum;
|
||||
auto pNSprite = viewInsertTSprite<tspritetype>(nSector, 32767, NULL);
|
||||
|
@ -433,7 +433,7 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t
|
|||
{
|
||||
// shift before interpolating to increase precision.
|
||||
int myclock = (PlayClock<<3) + MulScale(4<<3, smoothratio, 16);
|
||||
assert(spritesortcnt <= maxspritesonscreen);
|
||||
assert(spritesortcnt <= MAXSPRITESONSCREEN);
|
||||
gCameraAng = cA;
|
||||
int nViewSprites = spritesortcnt;
|
||||
for (int nTSprite = spritesortcnt-1; nTSprite >= 0; nTSprite--)
|
||||
|
@ -633,7 +633,7 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t
|
|||
pTSprite->xrepeat = pTSprite->yrepeat = 0;
|
||||
}
|
||||
}
|
||||
if (spritesortcnt >= maxspritesonscreen) continue;
|
||||
if (spritesortcnt >= MAXSPRITESONSCREEN) continue;
|
||||
if (pTXSprite && pTXSprite->burnTime > 0)
|
||||
{
|
||||
pTSprite->shade = ClipRange(pTSprite->shade-16-QRandom(8), -128, 127);
|
||||
|
|
|
@ -112,7 +112,6 @@ void StartLevel(MapRecord* level)
|
|||
}
|
||||
}
|
||||
memset(xsprite, 0, sizeof(xsprite));
|
||||
memset(sprite, 0, kMaxSprites * sizeof(spritetype));
|
||||
//drawLoadingScreen();
|
||||
dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsectnum, nullptr);
|
||||
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
||||
|
|
|
@ -201,6 +201,7 @@ int InsertSprite(int nSector, int nStat)
|
|||
|
||||
Numsprites++;
|
||||
|
||||
sprite[nSprite].time = leveltimer++;
|
||||
return nSprite;
|
||||
}
|
||||
|
||||
|
@ -512,6 +513,10 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
|
|||
gModernMap = false;
|
||||
#endif
|
||||
|
||||
memset(sector, 0, sizeof(*sector) * MAXSECTORS);
|
||||
memset(wall, 0, sizeof(*wall) * MAXWALLS);
|
||||
memset(sprite, 0, sizeof(*sector) * MAXSPRITES);
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
Polymost::Polymost_prepare_loadboard();
|
||||
#endif
|
||||
|
|
|
@ -157,7 +157,6 @@ void hudDraw(PLAYER *gView, int nSectnum, double bobx, double boby, double zDelt
|
|||
{
|
||||
DoLensEffect();
|
||||
viewingRange = viewingrange;
|
||||
yxAspect = yxaspect;
|
||||
r otatesprite(IntToFixed(280), IntToFixed(35), 53248, 512, 4077, v10, v14, 512 + 6, gViewX0, gViewY0, gViewX1, gViewY1);
|
||||
r otatesprite(IntToFixed(280), IntToFixed(35), 53248, 0, 1683, v10, 0, 512 + 35, gViewX0, gViewY0, gViewX1, gViewY1);
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ void InitMirrors(void)
|
|||
mirror[mirrorcnt].link = i;
|
||||
sector[j].ceilingpicnum = 4080+mirrorcnt;
|
||||
sector[j].portalflags = PORTAL_SECTOR_CEILING;
|
||||
sector[i].portalnum = portalAdd(PORTAL_SECTOR_CEILING, j, mirror[mirrorcnt].dx, mirror[mirrorcnt].dy, mirror[mirrorcnt].dz);
|
||||
sector[j].portalnum = portalAdd(PORTAL_SECTOR_CEILING, i, mirror[mirrorcnt].dx, mirror[mirrorcnt].dy, mirror[mirrorcnt].dz);
|
||||
mirrorcnt++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -772,10 +772,10 @@ void viewDrawScreen(bool sceneonly)
|
|||
|
||||
if (testnewrenderer)
|
||||
{
|
||||
fixed_t deliriumPitchI = interpolate(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate);
|
||||
fixedhoriz deliriumPitchI = q16horiz(interpolate(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;
|
||||
render_drawrooms(gView->pSprite, { cX, cY, cZ }, nSectnum, cA.asq16(), cH.asq16() + deliriumPitchI, rotscrnang.asbuildf());
|
||||
render_drawrooms(gView->pSprite, { cX, cY, cZ }, nSectnum, cA, cH + deliriumPitchI, rotscrnang);
|
||||
gView->pSprite->cstat = bakCstat;
|
||||
}
|
||||
else
|
||||
|
@ -868,8 +868,6 @@ bool GameInterface::DrawAutomapPlayer(int x, int y, int z, int a, double const s
|
|||
// [MR]: Confirm that this is correct as math doesn't match the variable names.
|
||||
int nCos = z * -bsin(a);
|
||||
int nSin = z * -bcos(a);
|
||||
int nCos2 = MulScale(nCos, yxaspect, 16);
|
||||
int nSin2 = MulScale(nSin, yxaspect, 16);
|
||||
int nPSprite = gView->pSprite->index;
|
||||
|
||||
for (int i = connecthead; i >= 0; i = connectpoint2[i])
|
||||
|
@ -886,7 +884,7 @@ bool GameInterface::DrawAutomapPlayer(int x, int y, int z, int a, double const s
|
|||
GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist << 2) + 16, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR);
|
||||
int nTop, nBottom;
|
||||
GetSpriteExtents(pSprite, &nTop, &nBottom);
|
||||
int nScale = MulScale((pSprite->yrepeat + ((floorZ - nBottom) >> 8)) * z, yxaspect, 16);
|
||||
int nScale = (pSprite->yrepeat + ((floorZ - nBottom) >> 8)) * z;
|
||||
nScale = ClipRange(nScale, 8000, 65536 << 1);
|
||||
// Players on automap
|
||||
double x = xdim / 2. + x1 / double(1 << 12);
|
||||
|
|
|
@ -41,6 +41,7 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
|
|||
#include "mapinfo.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "gamestate.h"
|
||||
#include "gamefuncs.h"
|
||||
|
||||
BEGIN_DUKE_NS
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
|
|||
#include "texturemanager.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "gamestate.h"
|
||||
#include "gamefuncs.h"
|
||||
|
||||
BEGIN_DUKE_NS
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ struct GameInterface : public ::GameInterface
|
|||
int chaseCamX(binangle ang) { return -ang.bcos(-4); }
|
||||
int chaseCamY(binangle ang) { return -ang.bsin(-4); }
|
||||
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() >> 9; }
|
||||
void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -399,15 +399,13 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
int i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
|
||||
int dax, day, cosang, sinang, xspan, yspan, sprx, spry;
|
||||
int xrepeat, yrepeat, tilenum, daang;
|
||||
int xvect, yvect, xvect2, yvect2;
|
||||
int xvect, yvect;
|
||||
int p;
|
||||
PalEntry col;
|
||||
spritetype* spr;
|
||||
|
||||
xvect = -bsin(cang) * czoom;
|
||||
yvect = -bcos(cang) * czoom;
|
||||
xvect2 = MulScale(xvect, yxaspect, 16);
|
||||
yvect2 = MulScale(yvect, yxaspect, 16);
|
||||
|
||||
//Draw sprites
|
||||
auto pactor = ps[screenpeek].GetActor();
|
||||
|
@ -435,15 +433,15 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
ox = sprx - cposx;
|
||||
oy = spry - cposy;
|
||||
x1 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||
y1 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
||||
y1 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||
|
||||
ox = bcos(spr->ang, -7);
|
||||
oy = bsin(spr->ang, -7);
|
||||
x2 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||
y2 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||
|
||||
x3 = MulScale(x2, yxaspect, 16);
|
||||
y3 = MulScale(y2, yxaspect, 16);
|
||||
x3 = x2;
|
||||
y3 = y2;
|
||||
|
||||
drawlinergb(x1 - x2 + (xdim << 11), y1 - y3 + (ydim << 11),
|
||||
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
|
||||
|
@ -475,12 +473,12 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
ox = x1 - cposx;
|
||||
oy = y1 - cposy;
|
||||
x1 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||
y1 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
||||
y1 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||
|
||||
ox = x2 - cposx;
|
||||
oy = y2 - cposy;
|
||||
x2 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||
y2 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
||||
y2 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||
|
||||
drawlinergb(x1 + (xdim << 11), y1 + (ydim << 11),
|
||||
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
||||
|
@ -521,22 +519,22 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
ox = x1 - cposx;
|
||||
oy = y1 - cposy;
|
||||
x1 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||
y1 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
||||
y1 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||
|
||||
ox = x2 - cposx;
|
||||
oy = y2 - cposy;
|
||||
x2 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||
y2 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
||||
y2 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||
|
||||
ox = x3 - cposx;
|
||||
oy = y3 - cposy;
|
||||
x3 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||
y3 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
||||
y3 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||
|
||||
ox = x4 - cposx;
|
||||
oy = y4 - cposy;
|
||||
x4 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||
y4 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
||||
y4 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||
|
||||
drawlinergb(x1 + (xdim << 11), y1 + (ydim << 11),
|
||||
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
||||
|
@ -571,7 +569,7 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
i = TILE_APLAYERTOP;
|
||||
|
||||
j = abs(pp.truefz - pp.posz) >> 8;
|
||||
j = MulScale(czoom * (pspr->yrepeat + j), yxaspect, 16);
|
||||
j = czoom * (pspr->yrepeat + j);
|
||||
|
||||
if (j < 22000) j = 22000;
|
||||
else if (j > (65536 << 1)) j = (65536 << 1);
|
||||
|
|
|
@ -924,7 +924,7 @@ static void SpawnPortals()
|
|||
if (findwallbetweensectors(i, t) >= 0)
|
||||
{
|
||||
sector[i].portalflags = PORTAL_SECTOR_FLOOR;
|
||||
sector[i].portalnum = uint8_t(&pt - allPortals.Data());
|
||||
sector[i].portalnum = uint8_t(1 ^ (&pt - allPortals.Data()));
|
||||
pt.targets.Push(i);
|
||||
goto nexti;
|
||||
}
|
||||
|
@ -943,7 +943,7 @@ static void SpawnPortals()
|
|||
if (findwallbetweensectors(i, t) >= 0)
|
||||
{
|
||||
sector[i].portalflags = PORTAL_SECTOR_CEILING;
|
||||
sector[i].portalnum = uint8_t(&pt - allPortals.Data());
|
||||
sector[i].portalnum = uint8_t(1 ^ (&pt - allPortals.Data()));
|
||||
pt.targets.Push(i);
|
||||
goto nexti;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ void renderView(spritetype* playersprite, int sectnum, int x, int y, int z, bina
|
|||
}
|
||||
else
|
||||
{
|
||||
render_drawrooms(playersprite, { x, y, z }, sectnum, a.asq16(), h.asq16(), rotscrnang.asbuildf());
|
||||
render_drawrooms(playersprite, { x, y, z }, sectnum, a, h, rotscrnang);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ void animatecamsprite(double smoothratio)
|
|||
}
|
||||
else
|
||||
{
|
||||
render_drawrooms(camera, camera->pos, camera->sectnum, ang.asq16(), IntToFixed(camera->shade), 0);
|
||||
render_drawrooms(camera, camera->pos, camera->sectnum, ang, buildhoriz(camera->shade), buildlook(0));
|
||||
}
|
||||
display_mirror = 0;
|
||||
renderDrawMasks();
|
||||
|
@ -414,6 +414,10 @@ bool GameInterface::GenerateSavePic()
|
|||
return true;
|
||||
}
|
||||
|
||||
void GameInterface::processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
|
||||
{
|
||||
fi.animatesprites(viewx, viewy, viewz, int(smoothRatio));
|
||||
}
|
||||
|
||||
|
||||
END_DUKE_NS
|
||||
|
|
|
@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "v_draw.h"
|
||||
#include "m_random.h"
|
||||
#include "gstrings.h"
|
||||
#include "gamefuncs.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
|
@ -255,6 +255,7 @@ struct GameInterface : ::GameInterface
|
|||
int chaseCamX(binangle ang) { return -ang.bcos() / 12; }
|
||||
int chaseCamY(binangle ang) { return -ang.bsin() / 12; }
|
||||
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() / 384; }
|
||||
void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
|
||||
|
||||
::GameStats getStats() override;
|
||||
};
|
||||
|
|
|
@ -77,8 +77,6 @@ bool GameInterface::DrawAutomapPlayer(int x, int y, int z, int a, double const s
|
|||
// [MR]: Confirm that this is correct as math doesn't match the variable names.
|
||||
int nCos = z * -bsin(a);
|
||||
int nSin = z * -bcos(a);
|
||||
int nCos2 = MulScale(nCos, yxaspect, 16);
|
||||
int nSin2 = MulScale(nSin, yxaspect, 16);
|
||||
|
||||
for (int i = connecthead; i >= 0; i = connectpoint2[i])
|
||||
{
|
||||
|
@ -94,7 +92,7 @@ bool GameInterface::DrawAutomapPlayer(int x, int y, int z, int a, double const s
|
|||
getzrange_old(pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist << 2) + 16, CLIPMASK0);
|
||||
int nTop, nBottom;
|
||||
GetSpriteExtents(pSprite, &nTop, &nBottom);
|
||||
int nScale = MulScale((pSprite->yrepeat + ((floorZ - nBottom) >> 8)) * z, yxaspect, 16);
|
||||
int nScale = (pSprite->yrepeat + ((floorZ - nBottom) >> 8)) * z;
|
||||
nScale = clamp(nScale, 8000, 65536 << 1);
|
||||
// Players on automap
|
||||
double x = xdim / 2. + x1 / double(1 << 12);
|
||||
|
|
|
@ -66,7 +66,7 @@ short enemy;
|
|||
short nEnemyPal = 0;
|
||||
|
||||
// NOTE - not to be confused with Ken's analyzesprites()
|
||||
static void analyzesprites(double const smoothratio)
|
||||
static void analyzesprites(int x, int y, int z, double const smoothratio)
|
||||
{
|
||||
tspritetype *pTSprite;
|
||||
|
||||
|
@ -90,11 +90,6 @@ static void analyzesprites(double const smoothratio)
|
|||
|
||||
besttarget = -1;
|
||||
|
||||
int x = pPlayerSprite->x;
|
||||
int y = pPlayerSprite->y;
|
||||
|
||||
int z = pPlayerSprite->z - (GetSpriteHeight(nPlayerSprite) / 2);
|
||||
|
||||
short nSector = pPlayerSprite->sectnum;
|
||||
|
||||
int nAngle = (2048 - pPlayerSprite->ang) & kAngleMask;
|
||||
|
@ -362,12 +357,12 @@ void DrawView(double smoothRatio, bool sceneonly)
|
|||
{
|
||||
renderSetRollAngle(rotscrnang.asbuildf());
|
||||
renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa.asq16(), nCamerapan.asq16(), nSector);
|
||||
analyzesprites(smoothRatio);
|
||||
analyzesprites(nCamerax, nCameray, viewz, smoothRatio);
|
||||
renderDrawMasks();
|
||||
}
|
||||
else
|
||||
{
|
||||
render_drawrooms(nullptr, { nCamerax, nCameray, viewz }, nSector, nCameraa.asq16(), nCamerapan.asq16(), rotscrnang.asbuildf());
|
||||
render_drawrooms(nullptr, { nCamerax, nCameray, viewz }, nSector, nCameraa, nCamerapan, rotscrnang);
|
||||
}
|
||||
|
||||
if (HavePLURemap())
|
||||
|
@ -467,6 +462,12 @@ bool GameInterface::GenerateSavePic()
|
|||
return true;
|
||||
}
|
||||
|
||||
void GameInterface::processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
|
||||
{
|
||||
analyzesprites(viewx, viewy, viewz, smoothRatio);
|
||||
}
|
||||
|
||||
|
||||
void NoClip()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,310 +1,7 @@
|
|||
BEGIN_SW_NS
|
||||
|
||||
short GlobStackSect[2];
|
||||
|
||||
void
|
||||
GetUpperLowerSector(short match, int x, int y, short* upper, short* lower)
|
||||
{
|
||||
int i;
|
||||
short sectorlist[16];
|
||||
int sln = 0;
|
||||
int SpriteNum;
|
||||
SPRITEp sp;
|
||||
|
||||
// keep a list of the last stacked sectors the view was in and
|
||||
// check those fisrt
|
||||
sln = 0;
|
||||
for (i = 0; i < (int)SIZ(GlobStackSect); i++)
|
||||
{
|
||||
// will not hurt if GlobStackSect is invalid - inside checks for this
|
||||
if (inside(x, y, GlobStackSect[i]) == 1)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
SectIterator it(GlobStackSect[i]);
|
||||
while ((SpriteNum = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[SpriteNum];
|
||||
|
||||
if (sp->statnum == STAT_FAF &&
|
||||
(sp->hitag >= VIEW_LEVEL1 && sp->hitag <= VIEW_LEVEL6)
|
||||
&& sp->lotag == match)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
sectorlist[sln] = GlobStackSect[i];
|
||||
sln++;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find it yet so test ALL sectors
|
||||
if (sln < 2)
|
||||
{
|
||||
sln = 0;
|
||||
for (i = numsectors - 1; i >= 0; i--)
|
||||
{
|
||||
if (inside(x, y, (short)i) == 1)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
SectIterator it(i);
|
||||
while ((SpriteNum = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[SpriteNum];
|
||||
|
||||
if (sp->statnum == STAT_FAF &&
|
||||
(sp->hitag >= VIEW_LEVEL1 && sp->hitag <= VIEW_LEVEL6)
|
||||
&& sp->lotag == match)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
if (sln < (int)SIZ(GlobStackSect))
|
||||
GlobStackSect[sln] = i;
|
||||
if (sln < (int)SIZ(sectorlist))
|
||||
sectorlist[sln] = i;
|
||||
sln++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// might not find ANYTHING if not tagged right
|
||||
if (sln == 0)
|
||||
{
|
||||
*upper = -1;
|
||||
*lower = -1;
|
||||
return;
|
||||
}
|
||||
// Map rooms have NOT been dragged on top of each other
|
||||
else if (sln == 1)
|
||||
{
|
||||
*lower = sectorlist[0];
|
||||
*upper = sectorlist[0];
|
||||
return;
|
||||
}
|
||||
// Map rooms HAVE been dragged on top of each other
|
||||
// inside will somtimes find that you are in two different sectors if the x,y
|
||||
// is exactly on a sector line.
|
||||
else if (sln > 2)
|
||||
{
|
||||
//DSPRINTF(ds, "TOO MANY SECTORS FOUND: x=%d, y=%d, match=%d, num sectors %d, %d, %d, %d, %d, %d", x, y, match, sln, sectorlist[0], sectorlist[1], sectorlist[2], sectorlist[3], sectorlist[4]);
|
||||
MONO_PRINT(ds);
|
||||
// try again moving the x,y pos around until you only get two sectors
|
||||
GetUpperLowerSector(match, x - 1, y, upper, lower);
|
||||
}
|
||||
|
||||
if (sln == 2)
|
||||
{
|
||||
if (sector[sectorlist[0]].floorz < sector[sectorlist[1]].floorz)
|
||||
{
|
||||
// swap
|
||||
// make sectorlist[0] the LOW sector
|
||||
short hold;
|
||||
|
||||
hold = sectorlist[0];
|
||||
sectorlist[0] = sectorlist[1];
|
||||
sectorlist[1] = hold;
|
||||
}
|
||||
|
||||
*lower = sectorlist[0];
|
||||
*upper = sectorlist[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FindCeilingView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum)
|
||||
{
|
||||
int xoff = 0;
|
||||
int yoff = 0;
|
||||
int i;
|
||||
SPRITEp sp = NULL;
|
||||
int pix_diff;
|
||||
int newz;
|
||||
|
||||
save.zcount = 0;
|
||||
|
||||
// Search Stat List For closest ceiling view sprite
|
||||
// Get the match, xoff, yoff from this point
|
||||
StatIterator it(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->hitag == VIEW_THRU_CEILING && sp->lotag == match)
|
||||
{
|
||||
xoff = *x - sp->x;
|
||||
yoff = *y - sp->y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
it.Reset(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->lotag == match)
|
||||
{
|
||||
// determine x,y position
|
||||
if (sp->hitag == VIEW_THRU_FLOOR)
|
||||
{
|
||||
short upper, lower;
|
||||
|
||||
*x = sp->x + xoff;
|
||||
*y = sp->y + yoff;
|
||||
|
||||
// get new sector
|
||||
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
||||
*sectnum = upper;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*sectnum < 0)
|
||||
return false;
|
||||
|
||||
ASSERT(sp);
|
||||
ASSERT(sp->hitag == VIEW_THRU_FLOOR);
|
||||
|
||||
pix_diff = labs(z - sector[sp->sectnum].floorz) >> 8;
|
||||
newz = sector[sp->sectnum].floorz + ((pix_diff / 128) + 1) * Z(128);
|
||||
|
||||
it.Reset(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->lotag == match)
|
||||
{
|
||||
// move lower levels ceilings up for the correct view
|
||||
if (sp->hitag == VIEW_LEVEL2)
|
||||
{
|
||||
// save it off
|
||||
save.sectnum[save.zcount] = sp->sectnum;
|
||||
save.zval[save.zcount] = sector[sp->sectnum].floorz;
|
||||
save.pic[save.zcount] = sector[sp->sectnum].floorpicnum;
|
||||
save.slope[save.zcount] = sector[sp->sectnum].floorheinum;
|
||||
|
||||
sector[sp->sectnum].floorz = newz;
|
||||
// don't change FAF_MIRROR_PIC - ConnectArea
|
||||
if (sector[sp->sectnum].floorpicnum != FAF_MIRROR_PIC)
|
||||
sector[sp->sectnum].floorpicnum = FAF_MIRROR_PIC + 1;
|
||||
sector[sp->sectnum].floorheinum = 0;
|
||||
|
||||
save.zcount++;
|
||||
PRODUCTION_ASSERT(save.zcount < ZMAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FindFloorView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum)
|
||||
{
|
||||
int xoff = 0;
|
||||
int yoff = 0;
|
||||
int i;
|
||||
SPRITEp sp = NULL;
|
||||
int newz;
|
||||
int pix_diff;
|
||||
|
||||
save.zcount = 0;
|
||||
|
||||
// Search Stat List For closest ceiling view sprite
|
||||
// Get the match, xoff, yoff from this point
|
||||
StatIterator it(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->hitag == VIEW_THRU_FLOOR && sp->lotag == match)
|
||||
{
|
||||
xoff = *x - sp->x;
|
||||
yoff = *y - sp->y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
it.Reset(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->lotag == match)
|
||||
{
|
||||
// determine x,y position
|
||||
if (sp->hitag == VIEW_THRU_CEILING)
|
||||
{
|
||||
short upper, lower;
|
||||
|
||||
*x = sp->x + xoff;
|
||||
*y = sp->y + yoff;
|
||||
|
||||
// get new sector
|
||||
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
||||
*sectnum = lower;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*sectnum < 0)
|
||||
return false;
|
||||
|
||||
ASSERT(sp);
|
||||
ASSERT(sp->hitag == VIEW_THRU_CEILING);
|
||||
|
||||
// move ceiling multiple of 128 so that the wall tile will line up
|
||||
pix_diff = labs(z - sector[sp->sectnum].ceilingz) >> 8;
|
||||
newz = sector[sp->sectnum].ceilingz - ((pix_diff / 128) + 1) * Z(128);
|
||||
|
||||
it.Reset(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->lotag == match)
|
||||
{
|
||||
// move upper levels floors down for the correct view
|
||||
if (sp->hitag == VIEW_LEVEL1)
|
||||
{
|
||||
// save it off
|
||||
save.sectnum[save.zcount] = sp->sectnum;
|
||||
save.zval[save.zcount] = sector[sp->sectnum].ceilingz;
|
||||
save.pic[save.zcount] = sector[sp->sectnum].ceilingpicnum;
|
||||
save.slope[save.zcount] = sector[sp->sectnum].ceilingheinum;
|
||||
|
||||
sector[sp->sectnum].ceilingz = newz;
|
||||
|
||||
// don't change FAF_MIRROR_PIC - ConnectArea
|
||||
if (sector[sp->sectnum].ceilingpicnum != FAF_MIRROR_PIC)
|
||||
sector[sp->sectnum].ceilingpicnum = FAF_MIRROR_PIC + 1;
|
||||
sector[sp->sectnum].ceilingheinum = 0;
|
||||
|
||||
save.zcount++;
|
||||
PRODUCTION_ASSERT(save.zcount < ZMAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FindCeilingView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum);
|
||||
bool FindFloorView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum);
|
||||
|
||||
|
||||
short
|
||||
|
@ -480,7 +177,7 @@ void polymost_drawscreen(PLAYERp pp, int tx, int ty, int tz, binangle tang, fixe
|
|||
if (!FAF_DebugView)
|
||||
FAF_DrawRooms(tx, ty, tz, tang.asq16(), thoriz.asq16(), tsectnum);
|
||||
|
||||
analyzesprites(tx, ty, tz, false);
|
||||
analyzesprites(tx, ty, tz, tang.asbuild());
|
||||
post_analyzesprites();
|
||||
renderDrawMasks();
|
||||
|
||||
|
@ -626,7 +323,7 @@ void JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, fixed_t tpq16ang, fixed
|
|||
|
||||
renderDrawRoomsQ16(tposx, tposy, tz, (tang), tpq16horiz, mirror[cnt].mirrorsector + MAXSECTORS);
|
||||
|
||||
analyzesprites(tposx, tposy, tz, true);
|
||||
analyzesprites(tposx, tposy, tz, tang >> 16);
|
||||
renderDrawMasks();
|
||||
|
||||
renderCompleteMirror(); // Reverse screen x-wise in this
|
||||
|
|
|
@ -71,7 +71,7 @@ extern short f_c;
|
|||
|
||||
extern ParentalStruct aVoxelArray[MAXTILES];
|
||||
|
||||
int ConnectCopySprite(uspritetype const * tsp);
|
||||
int ConnectCopySprite(spritetype const * tsp);
|
||||
void PreDrawStackedWater(void);
|
||||
|
||||
void SW_InitMultiPsky(void)
|
||||
|
@ -265,7 +265,7 @@ DoShadowFindGroundPoint(tspriteptr_t sp)
|
|||
}
|
||||
|
||||
void
|
||||
DoShadows(tspriteptr_t tsp, int viewz, bool mirror)
|
||||
DoShadows(tspriteptr_t tsp, int viewz, int camang)
|
||||
{
|
||||
tspriteptr_t New = &tsprite[spritesortcnt];
|
||||
USERp tu = User[tsp->owner];
|
||||
|
@ -553,7 +553,7 @@ void DoStarView(tspriteptr_t tsp, USERp tu, int viewz)
|
|||
}
|
||||
|
||||
void
|
||||
analyzesprites(int viewx, int viewy, int viewz, bool mirror)
|
||||
analyzesprites(int viewx, int viewy, int viewz, int camang)
|
||||
{
|
||||
int tSpriteNum;
|
||||
short SpriteNum;
|
||||
|
@ -645,7 +645,7 @@ analyzesprites(int viewx, int viewy, int viewz, bool mirror)
|
|||
|
||||
if (r_shadows && TEST(tu->Flags, SPR_SHADOW))
|
||||
{
|
||||
DoShadows(tsp, viewz, mirror);
|
||||
DoShadows(tsp, viewz, camang);
|
||||
}
|
||||
|
||||
//#define UK_VERSION 1
|
||||
|
@ -794,8 +794,7 @@ analyzesprites(int viewx, int viewy, int viewz, bool mirror)
|
|||
|
||||
if (OverlapDraw && FAF_ConnectArea(tsp->sectnum) && tsp->owner >= 0)
|
||||
{
|
||||
static_assert(sizeof(uspritetype) == sizeof(tspritetype)); // see TSPRITE_SIZE
|
||||
ConnectCopySprite((uspriteptr_t)tsp);
|
||||
ConnectCopySprite(tsp);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -902,7 +901,6 @@ post_analyzesprites(void)
|
|||
{
|
||||
if (tu->ID == FIREBALL_FLAMES && tu->Attach >= 0)
|
||||
{
|
||||
//uspritetype * const atsp = &sprite[tu->Attach];
|
||||
tspriteptr_t const atsp = get_tsprite(tu->Attach);
|
||||
|
||||
if (!atsp)
|
||||
|
@ -1096,34 +1094,6 @@ void PrintSpriteInfo(PLAYERp pp)
|
|||
}
|
||||
|
||||
|
||||
void SpriteSortList2D(int tx, int ty)
|
||||
{
|
||||
SPRITEp sp;
|
||||
int i;
|
||||
int dist,a,b,c;
|
||||
|
||||
spritesortcnt = 0;
|
||||
for (i = 0; i < MAXSPRITES; i++)
|
||||
{
|
||||
if (sprite[i].statnum < MAXSTATUS)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (!TEST(sp->cstat, CSTAT_SPRITE_INVISIBLE) &&
|
||||
(sp->xrepeat > 0) && (sp->yrepeat > 0) &&
|
||||
(spritesortcnt < MAXSPRITESONSCREEN))
|
||||
{
|
||||
DISTANCE(tx,ty,sp->x,sp->y,dist,a,b,c);
|
||||
|
||||
if (dist < 22000)
|
||||
{
|
||||
renderAddTSpriteFromSprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCrosshair(PLAYERp pp)
|
||||
{
|
||||
extern bool CameraTestMode;
|
||||
|
@ -1281,7 +1251,7 @@ PostDraw(void)
|
|||
}
|
||||
}
|
||||
|
||||
int CopySprite(uspritetype const * tsp, short newsector)
|
||||
int CopySprite(spritetype const * tsp, short newsector)
|
||||
{
|
||||
short New;
|
||||
SPRITEp sp;
|
||||
|
@ -1310,7 +1280,7 @@ int CopySprite(uspritetype const * tsp, short newsector)
|
|||
return New;
|
||||
}
|
||||
|
||||
int ConnectCopySprite(uspritetype const * tsp)
|
||||
int ConnectCopySprite(spritetype const * tsp)
|
||||
{
|
||||
short newsector;
|
||||
int testz;
|
||||
|
@ -1375,7 +1345,7 @@ void PreDrawStackedWater(void)
|
|||
sp = &sprite[i];
|
||||
u = User[i];
|
||||
|
||||
New = ConnectCopySprite((uspritetype const *)sp);
|
||||
New = ConnectCopySprite((spritetype const *)sp);
|
||||
if (New >= 0)
|
||||
{
|
||||
// spawn a user
|
||||
|
@ -1596,7 +1566,7 @@ drawscreen(PLAYERp pp, double smoothratio)
|
|||
else
|
||||
{
|
||||
UpdateWallPortalState();
|
||||
render_drawrooms(pp->SpriteP, { tx, ty, tz }, tsectnum, tang.asq16(), thoriz.asq16(), trotscrnang.asbuildf());
|
||||
render_drawrooms(pp->SpriteP, { tx, ty, tz }, tsectnum, tang, thoriz, trotscrnang);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1706,7 +1676,7 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
int i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
|
||||
int dax, day, cosang, sinang, xspan, yspan, sprx, spry;
|
||||
int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
|
||||
int xvect, yvect, xvect2, yvect2;
|
||||
int xvect, yvect;
|
||||
walltype* wal, * wal2;
|
||||
spritetype* spr;
|
||||
short p;
|
||||
|
@ -1716,8 +1686,6 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
|
||||
xvect = -bsin(cang) * czoom;
|
||||
yvect = -bcos(cang) * czoom;
|
||||
xvect2 = MulScale(xvect, yxaspect, 16);
|
||||
yvect2 = MulScale(yvect, yxaspect, 16);
|
||||
|
||||
|
||||
// Draw sprites
|
||||
|
@ -1784,7 +1752,7 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
|
||||
double xd = ((x1 << 4) + (xdim << 15)) / 65536.;
|
||||
double yd = ((y1 << 4) + (ydim << 15)) / 65536.;
|
||||
double sc = MulScale(czoom * (spr->yrepeat), yxaspect, 16) / 32768.;
|
||||
double sc = czoom * (spr->yrepeat) / 32768.;
|
||||
if (spnum >= 0)
|
||||
{
|
||||
DrawTexture(twod, tileGetTexture(1196 + pspr_ndx[myconnectindex], true), xd, yd, DTA_ScaleX, sc, DTA_ScaleY, sc, DTA_Rotate, daang * (-360. / 2048),
|
||||
|
@ -1815,12 +1783,12 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
ox = x1 - cposx;
|
||||
oy = y1 - cposy;
|
||||
x1 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
||||
y1 = MulScale(oy, xvect2, 16) + MulScale(ox, yvect2, 16);
|
||||
y1 = MulScale(oy, xvect, 16) + MulScale(ox, yvect, 16);
|
||||
|
||||
ox = x2 - cposx;
|
||||
oy = y2 - cposy;
|
||||
x2 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
||||
y2 = MulScale(oy, xvect2, 16) + MulScale(ox, yvect2, 16);
|
||||
y2 = MulScale(oy, xvect, 16) + MulScale(ox, yvect, 16);
|
||||
|
||||
drawlinergb(x1 + (xdim << 11), y1 + (ydim << 11),
|
||||
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
||||
|
@ -1863,22 +1831,22 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
ox = x1 - cposx;
|
||||
oy = y1 - cposy;
|
||||
x1 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
||||
y1 = MulScale(oy, xvect2, 16) + MulScale(ox, yvect2, 16);
|
||||
y1 = MulScale(oy, xvect, 16) + MulScale(ox, yvect, 16);
|
||||
|
||||
ox = x2 - cposx;
|
||||
oy = y2 - cposy;
|
||||
x2 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
||||
y2 = MulScale(oy, xvect2, 16) + MulScale(ox, yvect2, 16);
|
||||
y2 = MulScale(oy, xvect, 16) + MulScale(ox, yvect, 16);
|
||||
|
||||
ox = x3 - cposx;
|
||||
oy = y3 - cposy;
|
||||
x3 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
||||
y3 = MulScale(oy, xvect2, 16) + MulScale(ox, yvect2, 16);
|
||||
y3 = MulScale(oy, xvect, 16) + MulScale(ox, yvect, 16);
|
||||
|
||||
ox = x4 - cposx;
|
||||
oy = y4 - cposy;
|
||||
x4 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
||||
y4 = MulScale(oy, xvect2, 16) + MulScale(ox, yvect2, 16);
|
||||
y4 = MulScale(oy, xvect, 16) + MulScale(ox, yvect, 16);
|
||||
|
||||
drawlinergb(x1 + (xdim << 11), y1 + (ydim << 11),
|
||||
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
||||
|
@ -1901,6 +1869,12 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
|||
return true;
|
||||
}
|
||||
|
||||
void GameInterface::processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
|
||||
{
|
||||
analyzesprites(viewx, viewy, viewz, viewang.asbuild());
|
||||
post_analyzesprites();
|
||||
}
|
||||
|
||||
|
||||
|
||||
END_SW_NS
|
||||
|
|
|
@ -407,8 +407,8 @@ void InitLevel(MapRecord *maprec)
|
|||
PlaceActorsOnTracks();
|
||||
PostSetupSectorObject();
|
||||
SetupMirrorTiles();
|
||||
SetupSectorPortals();
|
||||
initlava();
|
||||
CollectPortals();
|
||||
|
||||
// reset NewGame
|
||||
NewGame = false;
|
||||
|
|
|
@ -1967,23 +1967,16 @@ int DoPickTarget(SPRITEp sp, uint32_t max_delta_ang, int skip_targets);
|
|||
void change_sprite_stat(short, short);
|
||||
void SetOwner(short, short);
|
||||
void SetAttach(short, short);
|
||||
void analyzesprites(int,int,int,bool);
|
||||
void analyzesprites(int,int,int,int);
|
||||
void ChangeState(short SpriteNum, STATEp statep);
|
||||
void CollectPortals();
|
||||
|
||||
void UpdateSectorFAF_Connect(short SpriteNum, int newz);
|
||||
#if 0
|
||||
bool FAF_ConnectCeiling(short sectnum);
|
||||
bool FAF_ConnectFloor(short sectnum);
|
||||
#else
|
||||
#define FAF_PLACE_MIRROR_PIC 341
|
||||
#define FAF_MIRROR_PIC 2356
|
||||
#define FAF_ConnectCeiling(sectnum) (sector[(sectnum)].ceilingpicnum == FAF_MIRROR_PIC)
|
||||
#define FAF_ConnectFloor(sectnum) (sector[(sectnum)].floorpicnum == FAF_MIRROR_PIC)
|
||||
#define FAF_ConnectArea(sectnum) (FAF_ConnectCeiling(sectnum) || FAF_ConnectFloor(sectnum))
|
||||
#endif
|
||||
//void updatesectorz(int, int, int, short *);
|
||||
void FAF_ConnectPlayerCeiling(PLAYERp pp);
|
||||
void FAF_ConnectPlayerFloor(PLAYERp pp);
|
||||
|
||||
bool PlayerCeilingHit(PLAYERp pp, int zlimit);
|
||||
bool PlayerFloorHit(PLAYERp pp, int zlimit);
|
||||
|
||||
|
@ -2135,7 +2128,6 @@ void DrawOverlapRoom(int tx,int ty,int tz,fixed_t tq16ang,fixed_t tq16horiz,shor
|
|||
void SetupMirrorTiles(void); // rooms.c
|
||||
bool FAF_Sector(short sectnum); // rooms.c
|
||||
int GetZadjustment(short sectnum,short hitag); // rooms.c
|
||||
void SetupSectorPortals();
|
||||
|
||||
void InitSetup(void); // setup.c
|
||||
|
||||
|
@ -2256,6 +2248,7 @@ struct GameInterface : ::GameInterface
|
|||
int chaseCamX(binangle ang) { return -ang.bcos(-3); }
|
||||
int chaseCamY(binangle ang) { return -ang.bsin(-3); }
|
||||
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() >> 8; }
|
||||
void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
|
||||
|
||||
|
||||
GameStats getStats() override;
|
||||
|
|
|
@ -464,7 +464,7 @@ void JS_InitMirrors(void)
|
|||
// Draw a 3d screen to a specific tile
|
||||
/////////////////////////////////////////////////////
|
||||
void drawroomstotile(int daposx, int daposy, int daposz,
|
||||
fixed_t daq16ang, fixed_t daq16horiz, short dacursectnum, short tilenume)
|
||||
binangle ang, fixedhoriz horiz, short dacursectnum, short tilenume)
|
||||
{
|
||||
TileFiles.MakeCanvas(tilenume, tileWidth(tilenume), tileHeight(tilenume));
|
||||
|
||||
|
@ -475,13 +475,13 @@ void drawroomstotile(int daposx, int daposy, int daposz,
|
|||
{
|
||||
if (!testnewrenderer)
|
||||
{
|
||||
renderDrawRoomsQ16(daposx, daposy, daposz, daq16ang, daq16horiz, dacursectnum);
|
||||
analyzesprites(daposx, daposy, daposz, false);
|
||||
renderDrawRoomsQ16(daposx, daposy, daposz, ang.asq16(), horiz.asq16(), dacursectnum);
|
||||
analyzesprites(daposx, daposy, daposz, ang.asbuild());
|
||||
renderDrawMasks();
|
||||
}
|
||||
else
|
||||
{
|
||||
render_drawrooms(nullptr, { daposx, daposy, daposz }, dacursectnum, daq16ang, daq16horiz, 0);
|
||||
render_drawrooms(nullptr, { daposx, daposy, daposz }, dacursectnum, ang, horiz, buildlook(0));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -721,11 +721,11 @@ void JS_DrawCameras(PLAYERp pp, int tx, int ty, int tz)
|
|||
|
||||
if (TEST_BOOL11(sp) && numplayers > 1)
|
||||
{
|
||||
drawroomstotile(cp->posx, cp->posy, cp->posz, cp->angle.ang.asq16(), cp->horizon.horiz.asq16(), cp->cursectnum, mirror[cnt].campic);
|
||||
drawroomstotile(cp->posx, cp->posy, cp->posz, cp->angle.ang, cp->horizon.horiz, cp->cursectnum, mirror[cnt].campic);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawroomstotile(sp->x, sp->y, sp->z, IntToFixed(SP_TAG5(sp)), IntToFixed(camhoriz), sp->sectnum, mirror[cnt].campic);
|
||||
drawroomstotile(sp->x, sp->y, sp->z, buildang(SP_TAG5(sp)), buildhoriz(camhoriz), sp->sectnum, mirror[cnt].campic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
|
|||
#include "names2.h"
|
||||
#include "panel.h"
|
||||
#include "misc.h"
|
||||
#include "hw_drawinfo.h"
|
||||
|
||||
BEGIN_SW_NS
|
||||
|
||||
|
@ -678,50 +679,521 @@ SetupMirrorTiles(void)
|
|||
}
|
||||
}
|
||||
|
||||
short GlobStackSect[2];
|
||||
|
||||
void SetupSectorPortals()
|
||||
void
|
||||
GetUpperLowerSector(short match, int x, int y, short *upper, short *lower)
|
||||
{
|
||||
TArray<int> foundf, foundc;
|
||||
// Search Stat List For closest ceiling view sprite
|
||||
// Get the match, xoff, yoff from this point
|
||||
StatIterator it(STAT_FAF);
|
||||
int i;
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
short sectorlist[16];
|
||||
int sln = 0;
|
||||
int SpriteNum;
|
||||
SPRITEp sp;
|
||||
#if 0
|
||||
// keep a list of the last stacked sectors the view was in and
|
||||
// check those fisrt
|
||||
sln = 0;
|
||||
for (i = 0; i < (int)SIZ(GlobStackSect); i++)
|
||||
{
|
||||
auto sp = &sprite[i];
|
||||
|
||||
if (sp->hitag == VIEW_THRU_CEILING) foundc.Push(i);
|
||||
if (sp->hitag == VIEW_THRU_FLOOR) foundf.Push(i);
|
||||
}
|
||||
|
||||
portalClear();
|
||||
while (foundf.Size())
|
||||
{
|
||||
auto spf = &sprite[foundf[0]];
|
||||
auto cindex = foundc.FindEx([=](int i) { return spf->lotag == sprite[i].lotag; });
|
||||
if (cindex != foundc.Size())
|
||||
// will not hurt if GlobStackSect is invalid - inside checks for this
|
||||
if (inside(x, y, GlobStackSect[i]) == 1)
|
||||
{
|
||||
auto spc = &sprite[foundf[cindex]];
|
||||
sector[spf->sectnum].portalflags = PORTAL_SECTOR_FLOOR;
|
||||
sector[spf->sectnum].portalnum = portalAdd(PORTAL_SECTOR_FLOOR, spc->sectnum, spc->x - spf->x, spc->y - spf->y, 0);
|
||||
bool found = false;
|
||||
|
||||
sector[spc->sectnum].portalflags = PORTAL_SECTOR_CEILING;
|
||||
sector[spc->sectnum].portalnum = portalAdd(PORTAL_SECTOR_CEILING, spf->sectnum, spf->x - spc->x, spf->y - spc->y, 0);
|
||||
SectIterator it(GlobStackSect[i]);
|
||||
while ((SpriteNum = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[SpriteNum];
|
||||
|
||||
//Printf("Portal with tag %d\n", sprite[foundf[0]].lotag);
|
||||
foundf.Delete(0);
|
||||
foundc.Delete(cindex);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Printf("Floor portal %d without partner\n", sprite[foundf[0]].lotag);
|
||||
foundf.Delete(0);
|
||||
if (sp->statnum == STAT_FAF &&
|
||||
(sp->hitag >= VIEW_LEVEL1 && sp->hitag <= VIEW_LEVEL6)
|
||||
&& sp->lotag == match)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
sectorlist[sln] = GlobStackSect[i];
|
||||
sln++;
|
||||
}
|
||||
}
|
||||
for (auto c : foundc)
|
||||
#endif
|
||||
|
||||
// didn't find it yet so test ALL sectors
|
||||
if (sln < 2)
|
||||
{
|
||||
//Printf("Ceiling portal %d without partner\n", sprite[c].lotag);
|
||||
sln = 0;
|
||||
for (i = 0; i < numsectors; i++)// - 1; i >= 0; i--)
|
||||
{
|
||||
if (inside(x, y, (short) i) == 1)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
SectIterator it(i);
|
||||
while ((SpriteNum = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[SpriteNum];
|
||||
|
||||
if (sp->statnum == STAT_FAF &&
|
||||
(sp->hitag >= VIEW_LEVEL1 && sp->hitag <= VIEW_LEVEL6)
|
||||
&& sp->lotag == match)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
if (sln < (int)SIZ(GlobStackSect))
|
||||
GlobStackSect[sln] = i;
|
||||
if (sln < (int)SIZ(sectorlist))
|
||||
sectorlist[sln] = i;
|
||||
sln++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// might not find ANYTHING if not tagged right
|
||||
if (sln == 0)
|
||||
{
|
||||
*upper = -1;
|
||||
*lower = -1;
|
||||
return;
|
||||
}
|
||||
// Map rooms have NOT been dragged on top of each other
|
||||
else if (sln == 1)
|
||||
{
|
||||
*lower = sectorlist[0];
|
||||
*upper = sectorlist[0];
|
||||
return;
|
||||
}
|
||||
// Map rooms HAVE been dragged on top of each other
|
||||
// inside will somtimes find that you are in two different sectors if the x,y
|
||||
// is exactly on a sector line.
|
||||
else if (sln > 2)
|
||||
{
|
||||
//DSPRINTF(ds, "TOO MANY SECTORS FOUND: x=%d, y=%d, match=%d, num sectors %d, %d, %d, %d, %d, %d", x, y, match, sln, sectorlist[0], sectorlist[1], sectorlist[2], sectorlist[3], sectorlist[4]);
|
||||
MONO_PRINT(ds);
|
||||
// try again moving the x,y pos around until you only get two sectors
|
||||
GetUpperLowerSector(match, x - 1, y, upper, lower);
|
||||
}
|
||||
|
||||
if (sln == 2)
|
||||
{
|
||||
if (sector[sectorlist[0]].floorz < sector[sectorlist[1]].floorz)
|
||||
{
|
||||
// swap
|
||||
// make sectorlist[0] the LOW sector
|
||||
short hold;
|
||||
|
||||
hold = sectorlist[0];
|
||||
sectorlist[0] = sectorlist[1];
|
||||
sectorlist[1] = hold;
|
||||
}
|
||||
|
||||
*lower = sectorlist[0];
|
||||
*upper = sectorlist[1];
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
FindCeilingView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum)
|
||||
{
|
||||
int xoff = 0;
|
||||
int yoff = 0;
|
||||
int i;
|
||||
SPRITEp sp = NULL;
|
||||
int pix_diff;
|
||||
int newz;
|
||||
|
||||
save.zcount = 0;
|
||||
|
||||
// Search Stat List For closest ceiling view sprite
|
||||
// Get the match, xoff, yoff from this point
|
||||
StatIterator it(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->hitag == VIEW_THRU_CEILING && sp->lotag == match)
|
||||
{
|
||||
xoff = *x - sp->x;
|
||||
yoff = *y - sp->y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
it.Reset(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->lotag == match)
|
||||
{
|
||||
// determine x,y position
|
||||
if (sp->hitag == VIEW_THRU_FLOOR)
|
||||
{
|
||||
short upper, lower;
|
||||
|
||||
*x = sp->x + xoff;
|
||||
*y = sp->y + yoff;
|
||||
|
||||
// get new sector
|
||||
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
||||
*sectnum = upper;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*sectnum < 0)
|
||||
return false;
|
||||
|
||||
ASSERT(sp);
|
||||
ASSERT(sp->hitag == VIEW_THRU_FLOOR);
|
||||
|
||||
pix_diff = labs(z - sector[sp->sectnum].floorz) >> 8;
|
||||
newz = sector[sp->sectnum].floorz + ((pix_diff / 128) + 1) * Z(128);
|
||||
|
||||
if (!testnewrenderer)
|
||||
{
|
||||
it.Reset(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->lotag == match)
|
||||
{
|
||||
// move lower levels ceilings up for the correct view
|
||||
if (sp->hitag == VIEW_LEVEL2)
|
||||
{
|
||||
// save it off
|
||||
save.sectnum[save.zcount] = sp->sectnum;
|
||||
save.zval[save.zcount] = sector[sp->sectnum].floorz;
|
||||
save.pic[save.zcount] = sector[sp->sectnum].floorpicnum;
|
||||
save.slope[save.zcount] = sector[sp->sectnum].floorheinum;
|
||||
|
||||
sector[sp->sectnum].floorz = newz;
|
||||
// don't change FAF_MIRROR_PIC - ConnectArea
|
||||
if (sector[sp->sectnum].floorpicnum != FAF_MIRROR_PIC)
|
||||
sector[sp->sectnum].floorpicnum = FAF_MIRROR_PIC + 1;
|
||||
sector[sp->sectnum].floorheinum = 0;
|
||||
|
||||
save.zcount++;
|
||||
PRODUCTION_ASSERT(save.zcount < ZMAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FindFloorView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum)
|
||||
{
|
||||
int xoff = 0;
|
||||
int yoff = 0;
|
||||
int i;
|
||||
SPRITEp sp = NULL;
|
||||
int newz;
|
||||
int pix_diff;
|
||||
|
||||
save.zcount = 0;
|
||||
|
||||
// Search Stat List For closest ceiling view sprite
|
||||
// Get the match, xoff, yoff from this point
|
||||
StatIterator it(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->hitag == VIEW_THRU_FLOOR && sp->lotag == match)
|
||||
{
|
||||
xoff = *x - sp->x;
|
||||
yoff = *y - sp->y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
it.Reset(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->lotag == match)
|
||||
{
|
||||
// determine x,y position
|
||||
if (sp->hitag == VIEW_THRU_CEILING)
|
||||
{
|
||||
short upper, lower;
|
||||
|
||||
*x = sp->x + xoff;
|
||||
*y = sp->y + yoff;
|
||||
|
||||
// get new sector
|
||||
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
||||
*sectnum = lower;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*sectnum < 0)
|
||||
return false;
|
||||
|
||||
ASSERT(sp);
|
||||
ASSERT(sp->hitag == VIEW_THRU_CEILING);
|
||||
|
||||
// move ceiling multiple of 128 so that the wall tile will line up
|
||||
pix_diff = labs(z - sector[sp->sectnum].ceilingz) >> 8;
|
||||
newz = sector[sp->sectnum].ceilingz - ((pix_diff / 128) + 1) * Z(128);
|
||||
|
||||
if (!testnewrenderer)
|
||||
{
|
||||
it.Reset(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->lotag == match)
|
||||
{
|
||||
// move upper levels floors down for the correct view
|
||||
if (sp->hitag == VIEW_LEVEL1)
|
||||
{
|
||||
// save it off
|
||||
save.sectnum[save.zcount] = sp->sectnum;
|
||||
save.zval[save.zcount] = sector[sp->sectnum].ceilingz;
|
||||
save.pic[save.zcount] = sector[sp->sectnum].ceilingpicnum;
|
||||
save.slope[save.zcount] = sector[sp->sectnum].ceilingheinum;
|
||||
|
||||
sector[sp->sectnum].ceilingz = newz;
|
||||
|
||||
// don't change FAF_MIRROR_PIC - ConnectArea
|
||||
if (sector[sp->sectnum].ceilingpicnum != FAF_MIRROR_PIC)
|
||||
sector[sp->sectnum].ceilingpicnum = FAF_MIRROR_PIC + 1;
|
||||
sector[sp->sectnum].ceilingheinum = 0;
|
||||
|
||||
save.zcount++;
|
||||
PRODUCTION_ASSERT(save.zcount < ZMAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
short
|
||||
FindViewSectorInScene(short cursectnum, short level)
|
||||
{
|
||||
int i;
|
||||
SPRITEp sp;
|
||||
short match;
|
||||
|
||||
StatIterator it(STAT_FAF);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
{
|
||||
sp = &sprite[i];
|
||||
|
||||
if (sp->hitag == level)
|
||||
{
|
||||
if (cursectnum == sp->sectnum)
|
||||
{
|
||||
// ignore case if sprite is pointing up
|
||||
if (sp->ang == 1536)
|
||||
continue;
|
||||
|
||||
// only gets to here is sprite is pointing down
|
||||
|
||||
// found a potential match
|
||||
match = sp->lotag;
|
||||
|
||||
return match;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct PortalGroup
|
||||
{
|
||||
TArray<int> sectors;
|
||||
int othersector = -1;
|
||||
vec3_t offset = { 0,0,0 };
|
||||
};
|
||||
|
||||
// This is very messy because some portals are linked outside the actual portal sectors, so we have to use the complicated original linking logic to find the connection. :?
|
||||
void CollectPortals()
|
||||
{
|
||||
int t = testnewrenderer;
|
||||
testnewrenderer = true;
|
||||
TArray<PortalGroup> floorportals;
|
||||
TArray<PortalGroup> ceilingportals;
|
||||
FixedBitArray<MAXSECTORS> floordone, ceilingdone;
|
||||
|
||||
floordone.Zero();
|
||||
ceilingdone.Zero();
|
||||
|
||||
for (int i = 0; i < numsectors; i++)
|
||||
{
|
||||
if (sector[i].floorpicnum == FAF_MIRROR_PIC && !floordone[i])
|
||||
{
|
||||
auto& fp = floorportals[floorportals.Reserve(1)];
|
||||
fp.sectors.Push(i);
|
||||
floordone.Set(i);
|
||||
for (unsigned ii = 0; ii < fp.sectors.Size(); ii++)
|
||||
{
|
||||
auto sec = §or[fp.sectors[ii]];
|
||||
for (int w = 0; w < sec->wallnum; w++)
|
||||
{
|
||||
auto ns = wall[sec->wallptr + w].nextsector;
|
||||
if (ns < 0 || floordone[ns] || sector[ns].floorpicnum != FAF_MIRROR_PIC) continue;
|
||||
fp.sectors.Push(ns);
|
||||
floordone.Set(ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sector[i].ceilingpicnum == FAF_MIRROR_PIC && !ceilingdone[i])
|
||||
{
|
||||
auto& fp = ceilingportals[ceilingportals.Reserve(1)];
|
||||
fp.sectors.Push(i);
|
||||
ceilingdone.Set(i);
|
||||
for (unsigned ii = 0; ii < fp.sectors.Size(); ii++)
|
||||
{
|
||||
auto sec = §or[fp.sectors[ii]];
|
||||
for (int w = 0; w < sec->wallnum; w++)
|
||||
{
|
||||
auto ns = wall[sec->wallptr + w].nextsector;
|
||||
if (ns < 0 || ceilingdone[ns] || sector[ns].ceilingpicnum != FAF_MIRROR_PIC) continue;
|
||||
fp.sectors.Push(ns);
|
||||
ceilingdone.Set(ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// now try to find connections.
|
||||
for (auto& fp : ceilingportals)
|
||||
{
|
||||
// pick one sprite out of the sectors, repeat until we get a valid connection
|
||||
for (auto sec : fp.sectors)
|
||||
{
|
||||
SectIterator it(sec);
|
||||
int spr;
|
||||
while ((spr = it.NextIndex()) >= 0)
|
||||
{
|
||||
int tx = sprite[spr].x;
|
||||
int ty = sprite[spr].y;
|
||||
int tz = sprite[spr].z;
|
||||
int16_t tsectnum = sec;
|
||||
|
||||
int match = FindViewSectorInScene(tsectnum, VIEW_LEVEL1);
|
||||
if (match != -1)
|
||||
{
|
||||
FindCeilingView(match, &tx, &ty, tz, &tsectnum);
|
||||
if (tsectnum >= 0 && sector[tsectnum].floorpicnum == FAF_MIRROR_PIC)
|
||||
{
|
||||
// got something!
|
||||
fp.othersector = tsectnum;
|
||||
fp.offset = { tx, ty, tz };
|
||||
fp.offset -= sprite[spr].pos;
|
||||
goto nextfg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextfg:;
|
||||
}
|
||||
|
||||
for (auto& fp : floorportals)
|
||||
{
|
||||
for (auto sec : fp.sectors)
|
||||
{
|
||||
SectIterator it(sec);
|
||||
int spr;
|
||||
while ((spr = it.NextIndex()) >= 0)
|
||||
{
|
||||
int tx = sprite[spr].x;
|
||||
int ty = sprite[spr].y;
|
||||
int tz = sprite[spr].z;
|
||||
int16_t tsectnum = sec;
|
||||
|
||||
int match = FindViewSectorInScene(tsectnum, VIEW_LEVEL2);
|
||||
if (match != -1)
|
||||
{
|
||||
FindFloorView(match, &tx, &ty, tz, &tsectnum);
|
||||
if (tsectnum >= 0 && sector[tsectnum].ceilingpicnum == FAF_MIRROR_PIC)
|
||||
{
|
||||
// got something!
|
||||
fp.othersector = tsectnum;
|
||||
fp.offset = { tx, ty, tz };
|
||||
fp.offset -= sprite[spr].pos;
|
||||
goto nextcg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextcg:;
|
||||
}
|
||||
for (auto& pt : floorportals)
|
||||
{
|
||||
if (pt.othersector > -1)
|
||||
{
|
||||
auto findother = [&](int other) -> PortalGroup*
|
||||
{
|
||||
for (auto& pt2 : ceilingportals)
|
||||
{
|
||||
if (pt2.sectors.Find(other) != pt2.sectors.Size()) return &pt2;
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
auto pt2 = findother(pt.othersector);
|
||||
if (pt2)
|
||||
{
|
||||
int pnum = portalAdd(PORTAL_SECTOR_FLOOR, -1, pt.offset.x, pt.offset.y, 0);
|
||||
allPortals[pnum].targets = pt2->sectors; // do not move! We still need the original.
|
||||
for (auto sec : pt.sectors)
|
||||
{
|
||||
sector[sec].portalflags = PORTAL_SECTOR_FLOOR;
|
||||
sector[sec].portalnum = pnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& pt : ceilingportals)
|
||||
{
|
||||
if (pt.othersector > -1)
|
||||
{
|
||||
auto findother = [&](int other) -> PortalGroup*
|
||||
{
|
||||
for (auto& pt2 : floorportals)
|
||||
{
|
||||
if (pt2.sectors.Find(other) != pt2.sectors.Size()) return &pt2;
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
auto pt2 = findother(pt.othersector);
|
||||
if (pt2)
|
||||
{
|
||||
int pnum = portalAdd(PORTAL_SECTOR_FLOOR, -1, pt.offset.x, pt.offset.y, 0);
|
||||
allPortals[pnum].targets = std::move(pt2->sectors);
|
||||
for (auto sec : pt.sectors)
|
||||
{
|
||||
sector[sec].portalflags = PORTAL_SECTOR_CEILING;
|
||||
sector[sec].portalnum = pnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
testnewrenderer = false;
|
||||
}
|
||||
|
||||
|
||||
END_SW_NS
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef struct
|
|||
} saveable_module;
|
||||
|
||||
template <typename T>
|
||||
constexpr enable_if_t<!std::is_pointer<T>::value, size_t> SAVE_SIZEOF(T const & obj) noexcept
|
||||
constexpr std::enable_if_t<!std::is_pointer<T>::value, size_t> SAVE_SIZEOF(T const & obj) noexcept
|
||||
{
|
||||
return sizeof(obj);
|
||||
}
|
||||
|
|
|
@ -639,7 +639,7 @@ TrackSetup(void)
|
|||
if (t->NumPoints == 0)
|
||||
{
|
||||
int i;
|
||||
auto const sp = (uspritetype const *)&sprite[StatIterator::First(STAT_TRACK+ndx)];
|
||||
auto const sp = (spritetype const *)&sprite[StatIterator::First(STAT_TRACK+ndx)];
|
||||
Printf("WARNING: Did not find first point of Track Number %d, x %d, y %d\n", ndx, sp->x, sp->y);
|
||||
StatIterator it(STAT_TRACK + ndx);
|
||||
while ((i = it.NextIndex()) >= 0)
|
||||
|
|
|
@ -10,10 +10,11 @@ EXTERN_CVAR(Bool, testnewrenderer)
|
|||
|
||||
BEGIN_WH_NS
|
||||
|
||||
int curpnum;
|
||||
|
||||
void drawscreen(int num, double dasmoothratio, bool sceneonly)
|
||||
{
|
||||
|
||||
curpnum = num;
|
||||
PLAYER& plr = player[num];
|
||||
|
||||
int cposx = plr.x;
|
||||
|
@ -90,7 +91,6 @@ void drawscreen(int num, double dasmoothratio, bool sceneonly)
|
|||
cposz = floorz - lz;
|
||||
|
||||
// do screen rotation.
|
||||
renderSetRollAngle(crotscrnang.asbam() / (double)(BAMUNIT));
|
||||
|
||||
if (!testnewrenderer)
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ void drawscreen(int num, double dasmoothratio, bool sceneonly)
|
|||
}
|
||||
else
|
||||
{
|
||||
render_drawrooms(nullptr, { cposx, cposy, cposz }, plr.sector, cang.asq16(), choriz.asq16(), crotscrnang.asbuildf());
|
||||
render_drawrooms(nullptr, { cposx, cposy, cposz }, plr.sector, cang, choriz, crotscrnang);
|
||||
}
|
||||
|
||||
if (!sceneonly)
|
||||
|
@ -118,6 +118,12 @@ void drawscreen(int num, double dasmoothratio, bool sceneonly)
|
|||
}
|
||||
}
|
||||
|
||||
void GameInterface::processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
|
||||
{
|
||||
PLAYER& plr = player[curpnum];
|
||||
analyzesprites(plr, (int)smoothRatio);
|
||||
}
|
||||
|
||||
void GameInterface::Render()
|
||||
{
|
||||
double const smoothRatio = playrunning() ? I_GetTimeFrac() * MaxSmoothRatio : MaxSmoothRatio;
|
||||
|
|
|
@ -535,6 +535,7 @@ struct GameInterface : public ::GameInterface
|
|||
int chaseCamX(binangle ang) { return -ang.bcos() / 12; }
|
||||
int chaseCamY(binangle ang) { return -ang.bsin() / 12; }
|
||||
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() / 384; }
|
||||
void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "hw_cvars.h"
|
||||
#include "gamestruct.h"
|
||||
#include "gl_models.h"
|
||||
#include "gamefuncs.h"
|
||||
|
||||
CVARD(Bool, hw_hightile, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable hightile texture rendering")
|
||||
bool hw_int_useindexedcolortextures;
|
||||
|
|
Loading…
Reference in a new issue