mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-31 20:40:39 +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,
|
MAXVOXMIPS = 5,
|
||||||
|
|
||||||
MAXXDIM = 7680,
|
|
||||||
MAXYDIM = 3200,
|
|
||||||
MINXDIM = 640,
|
|
||||||
MINYDIM = 480,
|
|
||||||
|
|
||||||
MAXWALLSB = ((MAXWALLS >> 2) + (MAXWALLS >> 3)),
|
MAXWALLSB = ((MAXWALLS >> 2) + (MAXWALLS >> 3)),
|
||||||
|
|
||||||
MAXVOXELS = 1024,
|
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"
|
#include "buildtypes.h"
|
||||||
|
|
||||||
using usectortype = sectortype;
|
using uspriteptr_t = spritetype const *;
|
||||||
using uwalltype = walltype;
|
using uwallptr_t = walltype const *;
|
||||||
using uspritetype = spritetype;
|
using usectorptr_t = sectortype const *;
|
||||||
|
|
||||||
using uspriteptr_t = uspritetype const *;
|
|
||||||
using uwallptr_t = uwalltype const *;
|
|
||||||
using usectorptr_t = usectortype const *;
|
|
||||||
using tspriteptr_t = tspritetype *;
|
using tspriteptr_t = tspritetype *;
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,17 +133,11 @@ typedef struct {
|
||||||
#define SPREXT_TSPRACCESS 16
|
#define SPREXT_TSPRACCESS 16
|
||||||
#define SPREXT_TEMPINVISIBLE 32
|
#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
|
// using the clipdist field
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TSPR_FLAGS_MDHACK = 1u<<0u,
|
TSPR_FLAGS_MDHACK = 1u<<0u,
|
||||||
TSPR_FLAGS_DRAW_LAST = 1u<<1u,
|
TSPR_FLAGS_DRAW_LAST = 1u<<1u,
|
||||||
TSPR_FLAGS_NO_SHADOW = 1u<<2u,
|
|
||||||
TSPR_FLAGS_INVISIBLE_WITH_SHADOW = 1u<<3u,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN int32_t guniqhudid;
|
EXTERN int32_t guniqhudid;
|
||||||
|
@ -177,57 +153,44 @@ struct usermaphack_t
|
||||||
EXTERN spriteext_t *spriteext;
|
EXTERN spriteext_t *spriteext;
|
||||||
EXTERN spritesmooth_t *spritesmooth;
|
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 sectortype *sector;
|
||||||
EXTERN walltype *wall;
|
EXTERN walltype *wall;
|
||||||
EXTERN spritetype *sprite;
|
EXTERN spritetype *sprite;
|
||||||
EXTERN tspriteptr_t tsprite;
|
EXTERN tspriteptr_t tsprite;
|
||||||
|
EXTERN int leveltimer;
|
||||||
|
|
||||||
extern sectortype sectorbackup[MAXSECTORS];
|
extern sectortype sectorbackup[MAXSECTORS];
|
||||||
extern walltype wallbackup[MAXWALLS];
|
extern walltype wallbackup[MAXWALLS];
|
||||||
|
|
||||||
extern bool inpreparemirror;
|
extern bool inpreparemirror;
|
||||||
|
|
||||||
|
inline tspriteptr_t renderAddNewTSprite()
|
||||||
static inline tspriteptr_t renderMakeTSpriteFromSprite(tspriteptr_t const tspr, uint16_t const spritenum)
|
|
||||||
{
|
{
|
||||||
auto const spr = &sprite[spritenum];
|
auto tspr = &tsprite[spritesortcnt++];
|
||||||
|
*tspr = {};
|
||||||
*tspr = *spr;
|
|
||||||
|
|
||||||
tspr->clipdist = 0;
|
|
||||||
tspr->owner = spritenum;
|
|
||||||
|
|
||||||
return 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 xdim, ydim;
|
||||||
EXTERN int32_t yxaspect, viewingrange;
|
EXTERN int32_t yxaspect, viewingrange;
|
||||||
|
@ -238,19 +201,8 @@ EXTERN int32_t display_mirror;
|
||||||
|
|
||||||
EXTERN int32_t randomseed;
|
EXTERN int32_t randomseed;
|
||||||
|
|
||||||
EXTERN int16_t numshades;
|
|
||||||
EXTERN uint8_t paletteloaded;
|
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 {
|
enum {
|
||||||
PALETTE_MAIN = 1<<0,
|
PALETTE_MAIN = 1<<0,
|
||||||
PALETTE_SHADE = 1<<1,
|
PALETTE_SHADE = 1<<1,
|
||||||
|
@ -385,22 +337,8 @@ SPRITE VARIABLES:
|
||||||
be in some sector, and must have some kind of status that you define.
|
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:
|
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
|
SINTABLE[2048] is a sin table with 2048 angles rather than the
|
||||||
normal 360 angles for higher precision. Also since SINTABLE is in
|
normal 360 angles for higher precision. Also since SINTABLE is in
|
||||||
all integers, the range is multiplied by 16383, so instead of the
|
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);
|
void plotpixel(int32_t x, int32_t y, char col);
|
||||||
FCanvasTexture *renderSetTarget(int16_t tilenume);
|
FCanvasTexture *renderSetTarget(int16_t tilenume);
|
||||||
void renderRestoreTarget();
|
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 setVideoMode();
|
||||||
void videoInit();
|
void videoInit();
|
||||||
void videoClearViewableArea(int32_t dacol);
|
void videoClearViewableArea(int32_t dacol);
|
||||||
void videoClearScreen(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;
|
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,
|
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)));
|
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)));
|
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);
|
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);
|
int32_t getsectordist(vec2_t const in, int const sectnum, vec2_t * const out = nullptr);
|
||||||
extern const int16_t *chsecptr_onextwall;
|
extern const int16_t *chsecptr_onextwall;
|
||||||
int32_t checksectorpointer(int16_t i, int16_t sectnum);
|
|
||||||
|
|
||||||
#if !KRANDDEBUG
|
#if !KRANDDEBUG
|
||||||
static FORCE_INLINE int32_t krand(void)
|
inline int32_t krand(void)
|
||||||
{
|
{
|
||||||
randomseed = (randomseed * 1664525ul) + 221297ul;
|
randomseed = (randomseed * 1664525ul) + 221297ul;
|
||||||
return ((uint32_t) randomseed)>>16;
|
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);
|
int32_t getangle(int32_t xvect, int32_t yvect);
|
||||||
fixed_t gethiq16angle(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;
|
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;
|
int32_t const dif = targetval - val;
|
||||||
return (dif>>1) ? val + (dif>>1) : targetval;
|
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_getceilzofslope(int const sectnum, vec2_t const vect);
|
||||||
int32_t yax_getflorzofslope(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);
|
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);
|
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);
|
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 };
|
vec2_t closest = { dax, day };
|
||||||
getsectordist(closest, sectnum, &closest);
|
getsectordist(closest, sectnum, &closest);
|
||||||
getzsofslopeptr((usectorptr_t)§or[sectnum], closest.x, closest.y, ceilz, florz);
|
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 };
|
vec2_t closest = { dax, day };
|
||||||
getsectordist(closest, sectnum, &closest);
|
getsectordist(closest, sectnum, &closest);
|
||||||
return getceilzofslopeptr((usectorptr_t)§or[sectnum], closest.x, closest.y);
|
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 };
|
vec2_t closest = { dax, day };
|
||||||
getsectordist(closest, sectnum, &closest);
|
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
|
// Is <wal> a red wall in a safe fashion, i.e. only if consistency invariant
|
||||||
// ".nextsector >= 0 iff .nextwall >= 0" holds.
|
// ".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);
|
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);
|
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 setspritez(int16_t spritenum, const vec3_t *) ATTRIBUTE((nonnull(2)));
|
||||||
|
|
||||||
int32_t spriteheightofsptr(uspriteptr_t spr, int32_t *height, int32_t alsotileyofs);
|
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);
|
return spriteheightofsptr((uspriteptr_t)&sprite[i], height, alsotileyofs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int videoCaptureScreen();
|
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 PrecacheHardwareTextures(int nTile);
|
||||||
void Polymost_Startup();
|
void Polymost_Startup();
|
||||||
|
|
||||||
|
@ -721,7 +628,7 @@ typedef struct
|
||||||
int16_t framenum; // calculate the number from the name when declaring
|
int16_t framenum; // calculate the number from the name when declaring
|
||||||
int16_t nexttile;
|
int16_t nexttile;
|
||||||
uint16_t smoothduration;
|
uint16_t smoothduration;
|
||||||
hudtyp *hudmem[2];
|
hudtyp hudmem[2];
|
||||||
int8_t skinnum;
|
int8_t skinnum;
|
||||||
char pal;
|
char pal;
|
||||||
} tile2model_t;
|
} tile2model_t;
|
||||||
|
@ -731,13 +638,13 @@ typedef struct
|
||||||
EXTERN int32_t mdinited;
|
EXTERN int32_t mdinited;
|
||||||
EXTERN tile2model_t tile2model[MAXTILES+EXTRATILES];
|
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;
|
return mdinited ? tile2model[Ptile2tile(tilenume,pal)].modelid : -1;
|
||||||
}
|
}
|
||||||
#endif // defined USE_OPENGL
|
#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);
|
UNREFERENCED_PARAMETER(pal);
|
||||||
return
|
return
|
||||||
|
@ -766,7 +673,7 @@ extern int skiptile;
|
||||||
|
|
||||||
static vec2_t const zerovec = { 0, 0 };
|
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) \
|
#define SET_AND_RETURN(Lval, Rval) \
|
||||||
do \
|
do \
|
||||||
|
@ -878,7 +785,7 @@ inline void tileUpdatePicnum(int* const tileptr, int const obj, int stat)
|
||||||
|
|
||||||
inline void setgotpic(int32_t tilenume)
|
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;
|
uint8_t dirty;
|
||||||
float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_;
|
float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_;
|
||||||
uint8_t portalflags;
|
uint8_t portalflags;
|
||||||
uint8_t portalnum;
|
int8_t portalnum;
|
||||||
|
|
||||||
int ceilingxpan() const { return int(ceilingxpan_); }
|
int ceilingxpan() const { return int(ceilingxpan_); }
|
||||||
int ceilingypan() const { return int(ceilingypan_); }
|
int ceilingypan() const { return int(ceilingypan_); }
|
||||||
|
@ -255,6 +255,7 @@ struct spritetype
|
||||||
};
|
};
|
||||||
int16_t extra;
|
int16_t extra;
|
||||||
int16_t detail;
|
int16_t detail;
|
||||||
|
int time;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// make sure we do not accidentally copy this
|
// make sure we do not accidentally copy this
|
||||||
|
|
|
@ -27,26 +27,6 @@
|
||||||
#endif
|
#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]]
|
# define fallthrough__ [[fallthrough]]
|
||||||
|
|
||||||
////////// Architecture detection //////////
|
////////// Architecture detection //////////
|
||||||
|
@ -91,17 +71,12 @@
|
||||||
|
|
||||||
#include "engineerrors.h"
|
#include "engineerrors.h"
|
||||||
|
|
||||||
////////// DEPRECATED: Standard library prefixing //////////
|
typedef intptr_t bssize_t;
|
||||||
|
|
||||||
typedef intptr_t ssize_t;
|
|
||||||
|
|
||||||
typedef ssize_t bssize_t;
|
|
||||||
|
|
||||||
#define BMAX_PATH 256
|
#define BMAX_PATH 256
|
||||||
|
|
||||||
////////// Metaprogramming structs //////////
|
////////// Metaprogramming structs //////////
|
||||||
|
|
||||||
using std::enable_if_t;
|
|
||||||
using native_t = intptr_t;
|
using native_t = intptr_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -121,44 +96,14 @@ typedef struct {
|
||||||
|
|
||||||
static_assert(sizeof(vec3f_t) == sizeof(float) * 3);
|
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 //////////
|
////////// Language tricks that depend on size_t //////////
|
||||||
|
|
||||||
#include "basics.h"
|
#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 //////////
|
////////// Bitfield manipulation //////////
|
||||||
|
|
||||||
// This once was a static array, requiring a memory acces where a shift would suffice.
|
inline void bitmap_set(uint8_t *const ptr, int const n) { ptr[n>>3] |= 1 << (n&7); }
|
||||||
// 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.
|
inline char bitmap_test(uint8_t const *const ptr, int const n) { return ptr[n>>3] & (1 << (n&7)); }
|
||||||
// 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)); }
|
|
||||||
|
|
||||||
////////// Utility functions //////////
|
////////// 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_
|
#endif // compat_h_
|
||||||
|
|
|
@ -212,10 +212,6 @@ void voxfree(voxmodel_t *m);
|
||||||
voxmodel_t *voxload(int lumpnum);
|
voxmodel_t *voxload(int lumpnum);
|
||||||
int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr);
|
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
|
#endif // defined USE_OPENGL
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -25,9 +25,9 @@ void polymost_completeMirror();
|
||||||
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype);
|
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype);
|
||||||
void polymost_deletesprite(int num);
|
void polymost_deletesprite(int num);
|
||||||
|
|
||||||
int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall);
|
int32_t polymost_maskWallHasTranslucency(walltype const * const wall);
|
||||||
int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr);
|
int32_t polymost_spriteHasTranslucency(spritetype const * const tspr);
|
||||||
int32_t polymost_spriteIsModelOrVoxel(tspritetype const * const tspr);
|
int32_t polymost_spriteIsModelOrVoxel(spritetype const * const tspr);
|
||||||
|
|
||||||
void polymost_glreset(void);
|
void polymost_glreset(void);
|
||||||
void polymost_scansector(int32_t sectnum);
|
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.
|
// these are defined in engine.cpp.
|
||||||
extern int16_t globalpicnum;
|
extern int16_t globalpicnum;
|
||||||
extern float fcosglobalang, fsinglobalang;
|
extern float fcosglobalang, fsinglobalang;
|
||||||
|
|
|
@ -27,41 +27,9 @@ static uint8_t clipignore[(MAXCLIPNUM+7)>>3];
|
||||||
|
|
||||||
int32_t quickloadboard=0;
|
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 };
|
vec2_t hitscangoal = { (1<<29)-1, (1<<29)-1 };
|
||||||
int32_t hitallsprites = 0;
|
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 //////////
|
////////// CLIPMOVE //////////
|
||||||
|
|
||||||
int32_t clipmoveboxtracenum = 3;
|
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;
|
clipit[clipnum].x2 = dax2; clipit[clipnum].y2 = day2;
|
||||||
clipobjectval[clipnum] = daoval;
|
clipobjectval[clipnum] = daoval;
|
||||||
|
|
||||||
uint32_t const mask = pow2char[clipnum&7];
|
uint32_t const mask = (1 << (clipnum&7));
|
||||||
uint8_t &value = clipignore[clipnum>>3];
|
uint8_t &value = clipignore[clipnum>>3];
|
||||||
value = (value & ~mask) | (-nofix & mask);
|
value = (value & ~mask) | (-nofix & mask);
|
||||||
|
|
||||||
clipnum++;
|
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 y2, int32_t *daxptr, int32_t *dayptr)
|
||||||
{
|
{
|
||||||
int32_t daz;
|
int32_t daz;
|
||||||
|
@ -530,7 +498,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
|
||||||
|
|
||||||
if (clipyou)
|
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
|
//Add 2 boxes at endpoints
|
||||||
int32_t bsz = walldist; if (diff.x < 0) bsz = -bsz;
|
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 (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;
|
hitscan_hitsectcf = (how+1)>>1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const int32_t curidx=(int32_t)tmp[0];
|
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];
|
const int32_t thislastsec = tmp[2];
|
||||||
|
|
||||||
if (!thislastsec)
|
if (!thislastsec)
|
||||||
{
|
{
|
||||||
if (inside(x1,y1,sec-(usectortype *)sector) == 1)
|
if (inside(x1,y1,sec-sector) == 1)
|
||||||
hit_set(hit, curspr->sectnum, -1, curspr-(uspritetype *)sprite, x1, y1, z1);
|
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 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] =
|
static const char *skyfaces[6] =
|
||||||
{
|
{
|
||||||
|
@ -1282,7 +1280,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (framei >= 0 && framei<1024)
|
if (framei >= 0 && framei<1024)
|
||||||
usedframebitmap[framei>>3] |= pow2char[framei&7];
|
usedframebitmap[framei>>3] |= (1 << (framei&7));
|
||||||
}
|
}
|
||||||
model_ok &= happy;
|
model_ok &= happy;
|
||||||
}
|
}
|
||||||
|
@ -1637,7 +1635,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
}
|
}
|
||||||
|
|
||||||
case T_ROTATE:
|
case T_ROTATE:
|
||||||
voxrotate[lastvoxid>>3] |= pow2char[lastvoxid&7];
|
voxrotate[lastvoxid>>3] |= (1 << (lastvoxid&7));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3196,9 +3194,6 @@ int32_t loaddefinitionsfile(const char *fn, bool loadadds)
|
||||||
if (script)
|
if (script)
|
||||||
scriptfile_close(script);
|
scriptfile_close(script);
|
||||||
|
|
||||||
DO_FREE_AND_NULL(faketilebuffer);
|
|
||||||
faketilebuffersiz = 0;
|
|
||||||
|
|
||||||
if (!script) return -1;
|
if (!script) return -1;
|
||||||
|
|
||||||
Printf(PRINT_NONOTIFY, "\n");
|
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
|
||||||
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||||||
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
||||||
// See the included license file "BUILDLIC.TXT" for license info.
|
// See the included license file "BUILDLIC.TXT" for license info.
|
||||||
//
|
//
|
||||||
|
@ -40,8 +41,6 @@
|
||||||
#include "gl_renderer.h"
|
#include "gl_renderer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float rollang;
|
|
||||||
|
|
||||||
int32_t r_rortexture = 0;
|
int32_t r_rortexture = 0;
|
||||||
int32_t r_rortexturerange = 0;
|
int32_t r_rortexturerange = 0;
|
||||||
int32_t r_rorphase = 0;
|
int32_t r_rorphase = 0;
|
||||||
|
@ -58,7 +57,7 @@ int16_t pskybits_override = -1;
|
||||||
static TArray<TArray<uint8_t>> voxelmemory;
|
static TArray<TArray<uint8_t>> voxelmemory;
|
||||||
|
|
||||||
int16_t tiletovox[MAXTILES];
|
int16_t tiletovox[MAXTILES];
|
||||||
char *voxfilenames[MAXVOXELS];
|
int voxlumps[MAXVOXELS];
|
||||||
char g_haveVoxels;
|
char g_haveVoxels;
|
||||||
//#define kloadvoxel loadvoxel
|
//#define kloadvoxel loadvoxel
|
||||||
|
|
||||||
|
@ -82,7 +81,7 @@ int32_t showfirstwall=0;
|
||||||
int32_t showheightindicators=1;
|
int32_t showheightindicators=1;
|
||||||
int32_t circlewall=-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)
|
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)) };
|
*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;
|
int32_t xdimen = -1, xdimenscale, xdimscale;
|
||||||
float fxdimen = -1.f;
|
float fxdimen = -1.f;
|
||||||
int32_t ydimen;
|
int32_t ydimen;
|
||||||
|
@ -168,35 +161,17 @@ int16_t globalpicnum;
|
||||||
|
|
||||||
static int32_t globaly1, globalx2;
|
static int32_t globaly1, globalx2;
|
||||||
|
|
||||||
int16_t sectorborder[256];
|
|
||||||
int16_t pointhighlight=-1, linehighlight=-1, highlightcnt=0;
|
int16_t pointhighlight=-1, linehighlight=-1, highlightcnt=0;
|
||||||
|
|
||||||
static_assert(MAXWALLSB < INT16_MAX);
|
|
||||||
int16_t numscans, numbunches;
|
|
||||||
static int16_t numhits;
|
static int16_t numhits;
|
||||||
|
|
||||||
bool inpreparemirror = 0;
|
bool inpreparemirror = 0;
|
||||||
static int32_t mirrorsx1, mirrorsy1, mirrorsx2, mirrorsy2;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Internal Engine Functions
|
// 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)
|
// animateoffs (internal)
|
||||||
|
@ -232,21 +207,6 @@ int32_t animateoffs(int const tilenum, int fakevar)
|
||||||
return offs;
|
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 int32_t engineLoadTables(void)
|
||||||
{
|
{
|
||||||
static char tablesloaded = 0;
|
static char tablesloaded = 0;
|
||||||
|
@ -281,16 +241,10 @@ static int32_t engineLoadTables(void)
|
||||||
|
|
||||||
////////// SPRITE LIST MANIPULATION FUNCTIONS //////////
|
////////// SPRITE LIST MANIPULATION FUNCTIONS //////////
|
||||||
|
|
||||||
#ifdef NETCODE_DISABLE
|
|
||||||
# define LISTFN_STATIC static
|
|
||||||
#else
|
|
||||||
# define LISTFN_STATIC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///// sector lists of sprites /////
|
///// sector lists of sprites /////
|
||||||
|
|
||||||
// insert sprite at the head of sector list, change .sectnum
|
// 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];
|
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
|
// 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 sectnum = sprite[deleteme].sectnum;
|
||||||
int32_t const prev = prevspritesect[deleteme];
|
int32_t const prev = prevspritesect[deleteme];
|
||||||
|
@ -321,7 +275,7 @@ LISTFN_STATIC void do_deletespritesect(int16_t deleteme)
|
||||||
///// now, status lists /////
|
///// now, status lists /////
|
||||||
|
|
||||||
// insert sprite at head of status list, change .statnum
|
// 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];
|
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)
|
// insertspritestat (internal)
|
||||||
LISTFN_STATIC int32_t insertspritestat(int16_t statnum)
|
static int32_t insertspritestat(int16_t statnum)
|
||||||
{
|
{
|
||||||
if ((statnum >= MAXSTATUS) || (headspritestat[MAXSTATUS] == -1))
|
if ((statnum >= MAXSTATUS) || (headspritestat[MAXSTATUS] == -1))
|
||||||
return -1; //list full
|
return -1; //list full
|
||||||
|
@ -356,7 +310,7 @@ LISTFN_STATIC int32_t insertspritestat(int16_t statnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove sprite 'deleteme' from its status list
|
// 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 sectnum = sprite[deleteme].statnum;
|
||||||
int32_t const prev = prevspritestat[deleteme];
|
int32_t const prev = prevspritestat[deleteme];
|
||||||
|
@ -390,6 +344,7 @@ int32_t insertsprite(int16_t sectnum, int16_t statnum)
|
||||||
Numsprites++;
|
Numsprites++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprite[newspritenum].time = leveltimer++;
|
||||||
return newspritenum;
|
return newspritenum;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -735,40 +690,20 @@ int32_t engineInit(void)
|
||||||
g_visibility = 512;
|
g_visibility = 512;
|
||||||
parallaxvisibility = 512;
|
parallaxvisibility = 512;
|
||||||
|
|
||||||
maxspritesonscreen = MAXSPRITESONSCREEN;
|
|
||||||
|
|
||||||
GPalette.Init(MAXPALOOKUPS + 1); // one slot for each translation, plus a separate one for the base palettes.
|
GPalette.Init(MAXPALOOKUPS + 1); // one slot for each translation, plus a separate one for the base palettes.
|
||||||
gi->loadPalette();
|
gi->loadPalette();
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
|
||||||
if (!mdinited) mdinit();
|
if (!mdinited) mdinit();
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// uninitengine
|
|
||||||
//
|
|
||||||
|
|
||||||
void engineUnInit(void)
|
|
||||||
{
|
|
||||||
Polymost::polymost_glreset();
|
|
||||||
freeallmodels();
|
|
||||||
# ifdef POLYMER
|
|
||||||
polymer_uninit();
|
|
||||||
# endif
|
|
||||||
|
|
||||||
TileFiles.CloseAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// initspritelists
|
// initspritelists
|
||||||
//
|
//
|
||||||
void (*initspritelists_replace)(void) = NULL;
|
void (*initspritelists_replace)(void) = NULL;
|
||||||
void initspritelists(void)
|
void initspritelists(void)
|
||||||
{
|
{
|
||||||
|
leveltimer = 0;
|
||||||
if (initspritelists_replace)
|
if (initspritelists_replace)
|
||||||
{
|
{
|
||||||
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
|
// qloadkvx
|
||||||
|
@ -1307,16 +785,13 @@ int32_t qloadkvx(int32_t voxindex, const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
|
||||||
if (voxmodels[voxindex])
|
if (voxmodels[voxindex])
|
||||||
{
|
{
|
||||||
voxfree(voxmodels[voxindex]);
|
voxfree(voxmodels[voxindex]);
|
||||||
voxmodels[voxindex] = NULL;
|
voxmodels[voxindex] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Xfree(voxfilenames[voxindex]);
|
voxlumps[voxindex] = fileSystem.FindFile(filename);
|
||||||
voxfilenames[voxindex] = Xstrdup(filename);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_haveVoxels = 1;
|
g_haveVoxels = 1;
|
||||||
|
|
||||||
|
@ -1325,21 +800,18 @@ int32_t qloadkvx(int32_t voxindex, const char *filename)
|
||||||
|
|
||||||
void vox_undefine(int32_t const tile)
|
void vox_undefine(int32_t const tile)
|
||||||
{
|
{
|
||||||
ssize_t voxindex = tiletovox[tile];
|
int voxindex = tiletovox[tile];
|
||||||
if (voxindex < 0)
|
if (voxindex < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
|
||||||
if (voxmodels[voxindex])
|
if (voxmodels[voxindex])
|
||||||
{
|
{
|
||||||
voxfree(voxmodels[voxindex]);
|
voxfree(voxmodels[voxindex]);
|
||||||
voxmodels[voxindex] = NULL;
|
voxmodels[voxindex] = NULL;
|
||||||
}
|
}
|
||||||
DO_FREE_AND_NULL(voxfilenames[voxindex]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
voxscale[voxindex] = 65536;
|
voxscale[voxindex] = 65536;
|
||||||
voxrotate[voxindex>>3] &= ~pow2char[voxindex&7];
|
voxrotate[voxindex>>3] &= ~(1 << (voxindex&7));
|
||||||
tiletovox[tile] = -1;
|
tiletovox[tile] = -1;
|
||||||
|
|
||||||
// TODO: nextvoxid
|
// 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)
|
if (x1 == x2 && y1 == y2)
|
||||||
return (sect1 == sect2);
|
return (sect1 == sect2);
|
||||||
|
|
||||||
sectbitmap[sect1>>3] |= pow2char[sect1&7];
|
sectbitmap[sect1>>3] |= (1 << (sect1&7));
|
||||||
clipsectorlist[0] = sect1; danum = 1;
|
clipsectorlist[0] = sect1; danum = 1;
|
||||||
|
|
||||||
for (dacnt=0; dacnt<danum; dacnt++)
|
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])
|
if (z <= cfz[0] || z >= cfz[1])
|
||||||
return 0;
|
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;
|
clipsectorlist[danum++] = nexts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectbitmap[sect2>>3] & pow2char[sect2&7])
|
if (sectbitmap[sect2>>3] & (1<<(sect2&7)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
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;
|
sector[wall[w].sector].dirty = 255;
|
||||||
wall[w].x = dax;
|
wall[w].x = dax;
|
||||||
wall[w].y = day;
|
wall[w].y = day;
|
||||||
walbitmap[w>>3] |= pow2char[w&7];
|
walbitmap[w>>3] |= (1<<(w&7));
|
||||||
|
|
||||||
if (!clockwise) //search points CCW
|
if (!clockwise) //search points CCW
|
||||||
{
|
{
|
||||||
|
@ -1906,7 +1378,7 @@ void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((walbitmap[w>>3] & pow2char[w&7]))
|
if ((walbitmap[w>>3] & (1<<(w&7))))
|
||||||
{
|
{
|
||||||
if (clockwise)
|
if (clockwise)
|
||||||
break;
|
break;
|
||||||
|
@ -2032,36 +1504,11 @@ int findwallbetweensectors(int sect1, int sect2)
|
||||||
// updatesector[z]
|
// updatesector[z]
|
||||||
//
|
//
|
||||||
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum)
|
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;
|
int16_t sect = *sectnum;
|
||||||
updatesectorneighbor(x, y, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST);
|
updatesectorneighbor(x, y, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST);
|
||||||
if (sect != -1)
|
if (sect != -1)
|
||||||
SET_AND_RETURN(*sectnum, sect);
|
SET_AND_RETURN(*sectnum, sect);
|
||||||
}
|
|
||||||
|
|
||||||
// we need to support passing in a sectnum of -1, unfortunately
|
// 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
|
// as starting sector and the 'initial' z check is skipped
|
||||||
// (not initial anymore because it follows the sector updating due to TROR)
|
// (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)
|
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum)
|
||||||
{
|
{
|
||||||
if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
|
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))
|
if (inside_p(x, y, *sectnum))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uwalltype const * wal = (uwalltype *)&wall[sector[*sectnum].wallptr];
|
walltype const * wal = &wall[sector[*sectnum].wallptr];
|
||||||
int wallsleft = sector[*sectnum].wallnum;
|
int wallsleft = sector[*sectnum].wallnum;
|
||||||
do
|
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;
|
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
|
// setview
|
||||||
//
|
//
|
||||||
|
@ -2256,32 +1686,11 @@ void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
|
||||||
ydimen = (y2-y1)+1;
|
ydimen = (y2-y1)+1;
|
||||||
|
|
||||||
fxdimen = (float) xdimen;
|
fxdimen = (float) xdimen;
|
||||||
#ifdef USE_OPENGL
|
|
||||||
fydimen = (float) ydimen;
|
fydimen = (float) ydimen;
|
||||||
#endif
|
|
||||||
videoSetCorrectedAspect();
|
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"
|
#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)
|
int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
|
||||||
{
|
{
|
||||||
if (!(sec->ceilingstat&2))
|
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
|
#ifndef ENGINE_PRIV_H
|
||||||
#define ENGINE_PRIV_H
|
#define ENGINE_PRIV_H
|
||||||
|
|
||||||
extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB];
|
extern int32_t globalpal, globalfloorpal;
|
||||||
extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
|
||||||
extern int16_t maskwall[MAXWALLSB], maskwallcnt;
|
|
||||||
extern tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
|
|
||||||
extern int32_t xdimen, xdimenscale, xdimscale, ydimen;
|
extern int32_t xdimen, xdimenscale, xdimscale, ydimen;
|
||||||
extern float fxdimen;
|
extern float fxdimen;
|
||||||
extern int32_t globalposx, globalposy, globalposz;
|
extern int32_t globalposx, globalposy, globalposz;
|
||||||
|
@ -31,20 +28,11 @@ extern int16_t globalpicnum;
|
||||||
|
|
||||||
extern int32_t globalorientation;
|
extern int32_t globalorientation;
|
||||||
|
|
||||||
extern int16_t sectorborder[256];
|
|
||||||
extern int32_t hitallsprites;
|
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);
|
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
|
// NOTE: tspr->owner >= MAXSPRITES (could be model) has to be handled by
|
||||||
// caller.
|
// caller.
|
||||||
|
|
|
@ -98,27 +98,23 @@ void freeallmodels()
|
||||||
if (models)
|
if (models)
|
||||||
{
|
{
|
||||||
for (i=0; i<nextmodelid; i++) mdfree(models[i]);
|
for (i=0; i<nextmodelid; i++) mdfree(models[i]);
|
||||||
DO_FREE_AND_NULL(models);
|
M_Free(models);
|
||||||
|
models = nullptr;
|
||||||
nummodelsalloced = 0;
|
nummodelsalloced = 0;
|
||||||
nextmodelid = 0;
|
nextmodelid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(tile2model,-1,sizeof(tile2model));
|
memset(tile2model,-1,sizeof(tile2model));
|
||||||
for (i=0; i<MAXTILES; i++)
|
|
||||||
memset(tile2model[i].hudmem, 0, sizeof(tile2model[i].hudmem));
|
|
||||||
|
|
||||||
curextra=MAXTILES;
|
curextra=MAXTILES;
|
||||||
|
|
||||||
if (vertlist)
|
if (vertlist)
|
||||||
{
|
{
|
||||||
DO_FREE_AND_NULL(vertlist);
|
M_Free(vertlist);
|
||||||
|
vertlist = nullptr;
|
||||||
allocmodelverts = maxmodelverts = 0;
|
allocmodelverts = maxmodelverts = 0;
|
||||||
allocmodeltris = maxmodeltris = 0;
|
allocmodeltris = maxmodeltris = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef POLYMER
|
|
||||||
DO_FREE_AND_NULL(tribuf);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mdinit()
|
void mdinit()
|
||||||
|
@ -135,7 +131,7 @@ int32_t md_loadmodel(const char *fn)
|
||||||
|
|
||||||
if (nextmodelid >= nummodelsalloced)
|
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;
|
models = ml; nummodelsalloced += MODELALLOCGROUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +243,7 @@ int32_t md_defineanimation(int32_t modelid, const char *framestart, const char *
|
||||||
ma.fpssc = fpssc;
|
ma.fpssc = fpssc;
|
||||||
ma.flags = flags;
|
ma.flags = flags;
|
||||||
|
|
||||||
map = (mdanim_t *)Xmalloc(sizeof(mdanim_t));
|
map = (mdanim_t *)M_Malloc(sizeof(mdanim_t));
|
||||||
|
|
||||||
memcpy(map, &ma, sizeof(ma));
|
memcpy(map, &ma, sizeof(ma));
|
||||||
|
|
||||||
|
@ -257,110 +253,6 @@ int32_t md_defineanimation(int32_t modelid, const char *framestart, const char *
|
||||||
return 0;
|
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)
|
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;
|
mdskinmap_t *sk, *skl;
|
||||||
|
@ -382,7 +274,7 @@ int32_t md_defineskin(int32_t modelid, const char *skinfn, int32_t palnum, int32
|
||||||
break;
|
break;
|
||||||
if (!sk)
|
if (!sk)
|
||||||
{
|
{
|
||||||
sk = (mdskinmap_t *)Xcalloc(1,sizeof(mdskinmap_t));
|
sk = (mdskinmap_t *)M_Calloc(1,sizeof(mdskinmap_t));
|
||||||
|
|
||||||
if (!skl) m->skinmap = sk;
|
if (!skl) m->skinmap = sk;
|
||||||
else skl->next = 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)modelid >= (uint32_t)nextmodelid) return -1;
|
||||||
if ((uint32_t)tilex >= (uint32_t)MAXTILES) return -2;
|
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->add = add;
|
||||||
hud->angadd = ((int16_t)angadd)|2048;
|
hud->angadd = ((int16_t)angadd)|2048;
|
||||||
|
@ -430,8 +320,6 @@ int32_t md_undefinetile(int32_t tile)
|
||||||
|
|
||||||
tile2model[tile].modelid = -1;
|
tile2model[tile].modelid = -1;
|
||||||
tile2model[tile].nexttile = -1;
|
tile2model[tile].nexttile = -1;
|
||||||
DO_FREE_AND_NULL(tile2model[tile].hudmem[0]);
|
|
||||||
DO_FREE_AND_NULL(tile2model[tile].hudmem[1]);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,8 +335,6 @@ int32_t md_undefinemodel(int32_t modelid)
|
||||||
if (tile2model[i].modelid == modelid)
|
if (tile2model[i].modelid == modelid)
|
||||||
{
|
{
|
||||||
tile2model[i].modelid = -1;
|
tile2model[i].modelid = -1;
|
||||||
DO_FREE_AND_NULL(tile2model[i].hudmem[0]);
|
|
||||||
DO_FREE_AND_NULL(tile2model[i].hudmem[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (models)
|
if (models)
|
||||||
|
@ -670,7 +556,7 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
||||||
|
|
||||||
int32_t ournumskins, ournumglcmds;
|
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;
|
m->mdnum = 2; m->scale = .01f;
|
||||||
|
|
||||||
fil.Read((char *)&head,sizeof(md2head_t));
|
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);
|
head.ofseof = LittleLong(head.ofseof);
|
||||||
#endif
|
#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;
|
ournumskins = head.numskins ? head.numskins : 1;
|
||||||
ournumglcmds = head.numglcmds ? head.numglcmds : 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->numglcmds = head.numglcmds;
|
||||||
m->framebytes = head.framebytes;
|
m->framebytes = head.framebytes;
|
||||||
|
|
||||||
m->frames = (char *)Xmalloc(m->numframes*m->framebytes);
|
m->frames = (char *)M_Malloc(m->numframes*m->framebytes);
|
||||||
m->glcmds = (int32_t *)Xmalloc(ournumglcmds*sizeof(int32_t));
|
m->glcmds = (int32_t *)M_Malloc(ournumglcmds*sizeof(int32_t));
|
||||||
m->tris = (md2tri_t *)Xmalloc(head.numtris*sizeof(md2tri_t));
|
m->tris = (md2tri_t *)M_Malloc(head.numtris*sizeof(md2tri_t));
|
||||||
m->uv = (md2uv_t *)Xmalloc(head.numuv*sizeof(md2uv_t));
|
m->uv = (md2uv_t *)M_Malloc(head.numuv*sizeof(md2uv_t));
|
||||||
|
|
||||||
fil.Seek(head.ofsframes,FileReader::SeekSet);
|
fil.Seek(head.ofsframes,FileReader::SeekSet);
|
||||||
if (fil.Read((char *)m->frames,m->numframes*m->framebytes) != m->numframes*m->framebytes)
|
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)
|
if (m->numglcmds > 0)
|
||||||
{
|
{
|
||||||
fil.Seek(head.ofsglcmds,FileReader::SeekSet);
|
fil.Seek(head.ofsglcmds,FileReader::SeekSet);
|
||||||
if (fil.Read((char *)m->glcmds,m->numglcmds*sizeof(int32_t)) != (int32_t)(m->numglcmds*sizeof(int32_t)))
|
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);
|
fil.Seek(head.ofstris,FileReader::SeekSet);
|
||||||
if (fil.Read((char *)m->tris,head.numtris*sizeof(md2tri_t)) != (int32_t)(head.numtris*sizeof(md2tri_t)))
|
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);
|
fil.Seek(head.ofsuv,FileReader::SeekSet);
|
||||||
if (fil.Read((char *)m->uv,head.numuv*sizeof(md2uv_t)) != (int32_t)(head.numuv*sizeof(md2uv_t)))
|
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
|
#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 ((st[i] == '/') || (st[i] == '\\')) { i++; break; }
|
||||||
if (i<0) i=0;
|
if (i<0) i=0;
|
||||||
st[i] = 0;
|
st[i] = 0;
|
||||||
m->basepath = (char *)Xmalloc(i+1);
|
m->basepath = (char *)M_Malloc(i+1);
|
||||||
strcpy(m->basepath, st);
|
strcpy(m->basepath, st);
|
||||||
|
|
||||||
m->skinfn = (char *)Xmalloc(ournumskins*64);
|
m->skinfn = (char *)M_Malloc(ournumskins*64);
|
||||||
if (m->numskins > 0)
|
if (m->numskins > 0)
|
||||||
{
|
{
|
||||||
fil.Seek(head.ofsskins,FileReader::SeekSet);
|
fil.Seek(head.ofsskins,FileReader::SeekSet);
|
||||||
if (fil.Read(m->skinfn,64*m->numskins) != 64*m->numskins)
|
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);
|
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
|
// the MD2 is now loaded internally - let's begin the MD3 conversion process
|
||||||
//Printf("Beginning md3 conversion.\n");
|
//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->mdnum = 3; m3->texture = nullptr; m3->scale = m->scale;
|
||||||
m3->head.id = IDP3_MAGIC; m3->head.vers = 15;
|
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->numskins = m3->head.numskins;
|
||||||
m3->numframes = m3->head.numframes;
|
m3->numframes = m3->head.numframes;
|
||||||
|
|
||||||
m3->head.frames = (md3frame_t *)Xcalloc(m3->head.numframes, sizeof(md3frame_t));
|
m3->head.frames = (md3frame_t *)M_Calloc(m3->head.numframes, sizeof(md3frame_t));
|
||||||
m3->muladdframes = (vec3f_t *)Xcalloc(m->numframes * 2, sizeof(vec3f_t));
|
m3->muladdframes = (vec3f_t *)M_Calloc(m->numframes * 2, sizeof(vec3f_t));
|
||||||
|
|
||||||
f = (md2frame_t *)(m->frames);
|
f = (md2frame_t *)(m->frames);
|
||||||
|
|
||||||
|
@ -811,7 +697,7 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
||||||
|
|
||||||
m3->head.tags = NULL;
|
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;
|
s = m3->head.surfs;
|
||||||
|
|
||||||
// model converting
|
// model converting
|
||||||
|
@ -828,9 +714,9 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
||||||
|
|
||||||
s->shaders = NULL;
|
s->shaders = NULL;
|
||||||
|
|
||||||
s->tris = (md3tri_t *)Xcalloc(head.numtris, sizeof(md3tri_t));
|
s->tris = (md3tri_t *)M_Calloc(head.numtris, sizeof(md3tri_t));
|
||||||
s->uv = (md3uv_t *)Xcalloc(s->numverts, sizeof(md3uv_t));
|
s->uv = (md3uv_t *)M_Calloc(s->numverts, sizeof(md3uv_t));
|
||||||
s->xyzn = (md3xyzn_t *)Xcalloc(s->numverts * m->numframes, sizeof(md3xyzn_t));
|
s->xyzn = (md3xyzn_t *)M_Calloc(s->numverts * m->numframes, sizeof(md3xyzn_t));
|
||||||
|
|
||||||
//memoryusage += (s->numverts * m->numframes * sizeof(md3xyzn_t));
|
//memoryusage += (s->numverts * m->numframes * sizeof(md3xyzn_t));
|
||||||
//Printf("Current model geometry memory usage : %i.\n", memoryusage);
|
//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;
|
mdskinmap_t *sk;
|
||||||
|
|
||||||
sk = (mdskinmap_t *)Xcalloc(1,sizeof(mdskinmap_t));
|
sk = (mdskinmap_t *)M_Calloc(1,sizeof(mdskinmap_t));
|
||||||
sk->palette = 0;
|
sk->palette = 0;
|
||||||
sk->skinnum = 0;
|
sk->skinnum = 0;
|
||||||
sk->surfnum = 0;
|
sk->surfnum = 0;
|
||||||
|
@ -892,12 +778,12 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
|
||||||
m3->skinmap = sk;
|
m3->skinmap = sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
m3->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * s->numtris);
|
m3->indexes = (uint16_t *)M_Malloc(sizeof(uint16_t) * s->numtris);
|
||||||
m3->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * s->numtris * 3);
|
m3->vindexes = (uint16_t *)M_Malloc(sizeof(uint16_t) * s->numtris * 3);
|
||||||
m3->maxdepths = (float *)Xmalloc(sizeof(float) * s->numtris);
|
m3->maxdepths = (float *)M_Malloc(sizeof(float) * s->numtris);
|
||||||
|
|
||||||
// die MD2 ! DIE !
|
// 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);
|
return ((md2model_t *)m3);
|
||||||
}
|
}
|
||||||
|
@ -949,7 +835,7 @@ static md3model_t *md3load(FileReader & fil)
|
||||||
md3model_t *m;
|
md3model_t *m;
|
||||||
md3surf_t *s;
|
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->mdnum = 3; m->texture = nullptr; m->scale = .01f;
|
||||||
|
|
||||||
m->muladdframes = NULL;
|
m->muladdframes = NULL;
|
||||||
|
@ -965,7 +851,7 @@ static md3model_t *md3load(FileReader & fil)
|
||||||
m->head.eof = LittleLong(m->head.eof);
|
m->head.eof = LittleLong(m->head.eof);
|
||||||
#endif
|
#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->numskins = m->head.numskins; //<- dead code?
|
||||||
m->numframes = m->head.numframes;
|
m->numframes = m->head.numframes;
|
||||||
|
@ -973,19 +859,19 @@ static md3model_t *md3load(FileReader & fil)
|
||||||
ofsurf = m->head.ofssurfs;
|
ofsurf = m->head.ofssurfs;
|
||||||
|
|
||||||
fil.Seek(m->head.ofsframes,FileReader::SeekSet); i = m->head.numframes*sizeof(md3frame_t);
|
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);
|
fil.Read(m->head.frames,i);
|
||||||
|
|
||||||
if (m->head.numtags == 0) m->head.tags = NULL;
|
if (m->head.numtags == 0) m->head.tags = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fil.Seek(m->head.ofstags,FileReader::SeekSet); i = m->head.numtags*sizeof(md3tag_t);
|
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.Read(m->head.tags,i);
|
||||||
}
|
}
|
||||||
|
|
||||||
fil.Seek(m->head.ofssurfs,FileReader::SeekSet);
|
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.
|
// NOTE: We assume that NULL is represented by all-zeros.
|
||||||
// surfs[0].geometry is for POLYMER_MD_PROCESS_CHECK (else: crashes).
|
// surfs[0].geometry is for POLYMER_MD_PROCESS_CHECK (else: crashes).
|
||||||
// surfs[i].geometry is for FREE_SURFS_GEOMETRY.
|
// 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));
|
//memoryusage += (s->numverts * s->numframes * sizeof(md3xyzn_t));
|
||||||
//Printf("Current model geometry memory usage : %i.\n", memoryusage);
|
//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->shaders = (md3shader_t *)(((intptr_t)s->tris)+leng[0]);
|
||||||
s->uv = (md3uv_t *)(((intptr_t)s->shaders)+leng[1]);
|
s->uv = (md3uv_t *)(((intptr_t)s->shaders)+leng[1]);
|
||||||
|
@ -1081,9 +967,9 @@ static md3model_t *md3load(FileReader & fil)
|
||||||
ofsurf += s->ofsend;
|
ofsurf += s->ofsend;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf);
|
m->indexes = (uint16_t *)M_Malloc(sizeof(uint16_t) * maxtrispersurf);
|
||||||
m->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf * 3);
|
m->vindexes = (uint16_t *)M_Malloc(sizeof(uint16_t) * maxtrispersurf * 3);
|
||||||
m->maxdepths = (float *)Xmalloc(sizeof(float) * maxtrispersurf);
|
m->maxdepths = (float *)M_Malloc(sizeof(float) * maxtrispersurf);
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@ -1556,12 +1442,12 @@ static void md3free(md3model_t *m)
|
||||||
for (anim=m->animations; anim; anim=nanim)
|
for (anim=m->animations; anim; anim=nanim)
|
||||||
{
|
{
|
||||||
nanim = anim->next;
|
nanim = anim->next;
|
||||||
Xfree(anim);
|
M_Free(anim);
|
||||||
}
|
}
|
||||||
for (sk=m->skinmap; sk; sk=nsk)
|
for (sk=m->skinmap; sk; sk=nsk)
|
||||||
{
|
{
|
||||||
nsk = sk->next;
|
nsk = sk->next;
|
||||||
Xfree(sk);
|
M_Free(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->head.surfs)
|
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--)
|
for (bssize_t surfi=m->head.numsurfs-1; surfi>=0; surfi--)
|
||||||
{
|
{
|
||||||
md3surf_t *s = &m->head.surfs[surfi];
|
md3surf_t *s = &m->head.surfs[surfi];
|
||||||
Xfree(s->tris);
|
M_Free(s->tris);
|
||||||
Xfree(s->geometry); // FREE_SURFS_GEOMETRY
|
M_Free(s->geometry); // FREE_SURFS_GEOMETRY
|
||||||
}
|
}
|
||||||
Xfree(m->head.surfs);
|
M_Free(m->head.surfs);
|
||||||
}
|
}
|
||||||
Xfree(m->head.tags);
|
M_Free(m->head.tags);
|
||||||
Xfree(m->head.frames);
|
M_Free(m->head.frames);
|
||||||
|
|
||||||
Xfree(m->muladdframes);
|
M_Free(m->muladdframes);
|
||||||
|
|
||||||
Xfree(m->indexes);
|
M_Free(m->indexes);
|
||||||
Xfree(m->vindexes);
|
M_Free(m->vindexes);
|
||||||
Xfree(m->maxdepths);
|
M_Free(m->maxdepths);
|
||||||
|
|
||||||
Xfree(m);
|
M_Free(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------- MD3 LIBRARY ENDS ----------------------------------------
|
//---------------------------------------- MD3 LIBRARY ENDS ----------------------------------------
|
||||||
|
@ -1639,7 +1525,7 @@ int32_t polymost_mddraw(tspriteptr_t tspr)
|
||||||
{
|
{
|
||||||
if (maxmodelverts > allocmodelverts)
|
if (maxmodelverts > allocmodelverts)
|
||||||
{
|
{
|
||||||
vertlist = (vec3f_t *) Xrealloc(vertlist, sizeof(vec3f_t)*maxmodelverts);
|
vertlist = (vec3f_t *) M_Realloc(vertlist, sizeof(vec3f_t)*maxmodelverts);
|
||||||
allocmodelverts = maxmodelverts;
|
allocmodelverts = maxmodelverts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,19 @@ Ken Silverman's official web site: http://www.advsys.net/ken
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "hw_renderstate.h"
|
#include "hw_renderstate.h"
|
||||||
#include "printf.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;
|
int skiptile = -1;
|
||||||
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap);
|
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.
|
// For testing - will be removed later.
|
||||||
CVAR(Int, skytile, 0, 0)
|
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
|
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)
|
static inline float polymost_invsqrt_approximation(float x)
|
||||||
{
|
{
|
||||||
// this is the comment
|
// this is the comment
|
||||||
|
@ -121,7 +168,7 @@ static float sectorVisibility(int sectnum)
|
||||||
return v? ((uint8_t)(v + 16)) / 16.f : 1.f;
|
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;
|
auto& tile = *tileptr;
|
||||||
|
|
||||||
|
@ -216,7 +263,7 @@ static int32_t pow2xsplit = 0, skyzbufferhack = 0, flatskyrender = 0;
|
||||||
static float drawpoly_alpha = 0.f;
|
static float drawpoly_alpha = 0.f;
|
||||||
static uint8_t drawpoly_blend = 0;
|
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)
|
if (wall->cstat & CSTAT_WALL_TRANSLUCENT)
|
||||||
return true;
|
return true;
|
||||||
|
@ -224,7 +271,7 @@ int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall)
|
||||||
return checkTranslucentReplacement(tileGetTexture(wall->picnum)->GetID(), wall->pal);
|
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) ||
|
if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || (tspr->clipdist & TSPR_FLAGS_DRAW_LAST) ||
|
||||||
((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha))
|
((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha))
|
||||||
|
@ -1771,7 +1818,7 @@ static void polymost_drawalls(int32_t const bunch)
|
||||||
domostpolymethod = DAMETH_NOMASK;
|
domostpolymethod = DAMETH_NOMASK;
|
||||||
|
|
||||||
if (nextsectnum >= 0)
|
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);
|
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 bunchfrst = numbunches;
|
||||||
int const onumscans = numscans;
|
int const onumscans = numscans;
|
||||||
|
@ -1895,7 +1942,7 @@ void polymost_scansector(int32_t sectnum)
|
||||||
int const nextsectnum = wal->nextsector; //Scan close sectors
|
int const nextsectnum = wal->nextsector; //Scan close sectors
|
||||||
|
|
||||||
if (nextsectnum >= 0 && !(wal->cstat&32) && sectorbordercnt < countof(sectorborder))
|
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;
|
double const d = fp1.X* fp2.Y - fp2.X * fp1.Y;
|
||||||
DVector2 const p1 = fp2 - fp1;
|
DVector2 const p1 = fp2 - fp1;
|
||||||
|
@ -1905,7 +1952,7 @@ void polymost_scansector(int32_t sectnum)
|
||||||
if (d*d < (p1.LengthSquared()) * 256.f)
|
if (d*d < (p1.LengthSquared()) * 256.f)
|
||||||
{
|
{
|
||||||
sectorborder[sectorbordercnt++] = nextsectnum;
|
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)
|
static inline int32_t polymost_findwall(tspritetype const * const tspr, vec2_t const * const tsiz, int32_t * rd)
|
||||||
{
|
{
|
||||||
int32_t dist = 4, closest = -1;
|
int32_t dist = 4, closest = -1;
|
||||||
auto const sect = (usectortype * )§or[tspr->sectnum];
|
auto const sect = §or[tspr->sectnum];
|
||||||
vec2_t n;
|
vec2_t n;
|
||||||
|
|
||||||
for (bssize_t i=sect->wallptr; i<sect->wallptr + sect->wallnum; i++)
|
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);
|
static_assert((int)RS_YFLIP == (int)HUDFLAG_FLIPPED);
|
||||||
|
|
||||||
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
||||||
|
@ -3234,8 +3283,483 @@ void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
||||||
if (tex) GLInterface.SetTexture(tex, palid, CLAMP_NONE);
|
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)
|
void PrecacheHardwareTextures(int nTile)
|
||||||
{
|
{
|
||||||
// PRECACHE
|
// PRECACHE
|
||||||
|
@ -3243,3 +3767,45 @@ void PrecacheHardwareTextures(int nTile)
|
||||||
Polymost::polymost_precache(nTile, 0, 1);
|
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)
|
void voxfree(voxmodel_t *m)
|
||||||
{
|
{
|
||||||
if (!m)
|
if (m) delete m;
|
||||||
return;
|
|
||||||
|
|
||||||
Xfree(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
voxmodel_t *voxload(int lumpnum)
|
voxmodel_t *voxload(int lumpnum)
|
||||||
|
@ -33,8 +30,8 @@ voxmodel_t *voxload(int lumpnum)
|
||||||
FVoxel* voxel = R_LoadKVX(lumpnum);
|
FVoxel* voxel = R_LoadKVX(lumpnum);
|
||||||
if (voxel != nullptr)
|
if (voxel != nullptr)
|
||||||
{
|
{
|
||||||
voxmodel_t* vm = (voxmodel_t*)Xmalloc(sizeof(voxmodel_t));
|
voxmodel_t* vm = new voxmodel_t;
|
||||||
memset(vm, 0, sizeof(voxmodel_t));
|
*vm = {};
|
||||||
auto pivot = voxel->Mips[0].Pivot;
|
auto pivot = voxel->Mips[0].Pivot;
|
||||||
vm->mdnum = 1; //VOXel model id
|
vm->mdnum = 1; //VOXel model id
|
||||||
vm->scale = vm->bscale = 1.f;
|
vm->scale = vm->bscale = 1.f;
|
||||||
|
@ -53,7 +50,6 @@ voxmodel_t *voxload(int lumpnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Draw voxel model as perfect cubes
|
//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)
|
int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr)
|
||||||
{
|
{
|
||||||
float f, g, k0, zoff;
|
float f, g, k0, zoff;
|
||||||
|
@ -193,7 +189,7 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char* voxfilenames[MAXVOXELS];
|
extern int voxlumps[MAXVOXELS];
|
||||||
void (*PolymostProcessVoxels_Callback)(void) = NULL;
|
void (*PolymostProcessVoxels_Callback)(void) = NULL;
|
||||||
void PolymostProcessVoxels(void)
|
void PolymostProcessVoxels(void)
|
||||||
{
|
{
|
||||||
|
@ -207,17 +203,16 @@ void PolymostProcessVoxels(void)
|
||||||
|
|
||||||
Printf(PRINT_NONOTIFY, "Generating voxel models for Polymost. This may take a while...\n");
|
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);
|
voxmodels[i]->scale = voxscale[i] * (1.f / 65536.f);
|
||||||
}
|
else
|
||||||
DO_FREE_AND_NULL(voxfilenames[i]);
|
Printf("Unable to load voxel from %s\n", fileSystem.GetFileFullPath(lumpnum));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#define MAXWIDTH 12000
|
#define MAXWIDTH 12000
|
||||||
#define MAXHEIGHT 5000
|
#define MAXHEIGHT 5000
|
||||||
|
@ -101,3 +102,6 @@ enum EStateUseFlags
|
||||||
SUF_WEAPON = 4,
|
SUF_WEAPON = 4,
|
||||||
SUF_ITEM = 8,
|
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 "automap.h"
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
#include "gamefuncs.h"
|
||||||
|
|
||||||
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR(Bool, autoloadbrightmaps, 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
|
// 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 height = windowxy2.y - windowxy1.y + 1, width = windowxy2.x - windowxy1.x + 1;
|
||||||
|
int bottomspace = screen->GetHeight() - windowxy2.y;
|
||||||
|
|
||||||
IntRect mSceneViewport;
|
IntRect mSceneViewport;
|
||||||
mSceneViewport.left = windowxy1.x;
|
mSceneViewport.left = windowxy1.x;
|
||||||
mSceneViewport.top = windowxy1.y;
|
mSceneViewport.top = (bottomspace - windowxy1.y/2);
|
||||||
mSceneViewport.width = width;
|
mSceneViewport.width = width;
|
||||||
mSceneViewport.height = height;
|
mSceneViewport.height = height;
|
||||||
return mSceneViewport;
|
return mSceneViewport;
|
||||||
|
@ -579,7 +581,7 @@ int GameMain()
|
||||||
TileFiles.CloseAll(); // delete the texture data before shutting down graphics.
|
TileFiles.CloseAll(); // delete the texture data before shutting down graphics.
|
||||||
GLInterface.Deinit();
|
GLInterface.Deinit();
|
||||||
I_ShutdownGraphics();
|
I_ShutdownGraphics();
|
||||||
engineUnInit();
|
freeallmodels();
|
||||||
if (gi)
|
if (gi)
|
||||||
{
|
{
|
||||||
delete 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,
|
// 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.
|
// 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;
|
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"
|
#include "inputstate.h"
|
||||||
|
|
||||||
class FSerializer;
|
class FSerializer;
|
||||||
|
struct FRenderViewpoint;
|
||||||
|
|
||||||
struct GameStats
|
struct GameStats
|
||||||
{
|
{
|
||||||
|
@ -101,7 +102,7 @@ struct GameInterface
|
||||||
virtual int chaseCamX(binangle ang) { return 0; }
|
virtual int chaseCamX(binangle ang) { return 0; }
|
||||||
virtual int chaseCamY(binangle ang) { return 0; }
|
virtual int chaseCamY(binangle ang) { return 0; }
|
||||||
virtual int chaseCamZ(fixedhoriz horiz) { 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()
|
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)
|
void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, int16_t* cursectnum)
|
||||||
{
|
{
|
||||||
inputState.ClearAllInput();
|
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);
|
FileReader fr = fileSystem.OpenFileReader(filename);
|
||||||
if (!fr.isOpen()) I_Error("Unable to open map %s", filename);
|
if (!fr.isOpen()) I_Error("Unable to open map %s", filename);
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "../../glbackend/glbackend.h"
|
#include "../../glbackend/glbackend.h"
|
||||||
|
|
||||||
LookupTableInfo lookups;
|
LookupTableInfo lookups;
|
||||||
|
int numshades;
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -136,7 +137,6 @@ void paletteLoadFromDisk(void)
|
||||||
|
|
||||||
void LookupTableInfo::postLoadTables(void)
|
void LookupTableInfo::postLoadTables(void)
|
||||||
{
|
{
|
||||||
globalpal = 0;
|
|
||||||
GPalette.GenerateGlobalBrightmapFromColormap(getTable(0), numshades);
|
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.
|
// 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);
|
void videoTintBlood(int32_t r, int32_t g, int32_t b);
|
||||||
|
|
||||||
extern int32_t globalpal, globalfloorpal;
|
extern int numshades;
|
||||||
extern void paletteLoadFromDisk(void);
|
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{};
|
FRenderViewpoint r_viewpoint{};
|
||||||
r_viewpoint.CameraSprite = cam;
|
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.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.Yaw = -90.f + angle.asdeg();
|
||||||
r_viewpoint.HWAngles.Pitch = -HorizToPitch(q16horizon);
|
r_viewpoint.HWAngles.Pitch = -horizon.aspitch();
|
||||||
r_viewpoint.HWAngles.Roll = -rollang;
|
r_viewpoint.HWAngles.Roll = -rollang.asdeg();
|
||||||
r_viewpoint.FieldOfView = (float)r_fov;
|
r_viewpoint.FieldOfView = (float)r_fov;
|
||||||
r_viewpoint.RotAngle = q16ang(q16angle).asbam();
|
r_viewpoint.RotAngle = angle.asbam();
|
||||||
return r_viewpoint;
|
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();
|
checkRotatedWalls();
|
||||||
|
|
||||||
|
@ -278,7 +279,7 @@ void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sect
|
||||||
RenderState->SetVertexBuffer(screen->mVertexData);
|
RenderState->SetVertexBuffer(screen->mVertexData);
|
||||||
screen->mVertexData->Reset();
|
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;
|
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
||||||
|
|
||||||
checkBenchActive();
|
checkBenchActive();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
class FSerializer;
|
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
|
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)];
|
auto& pt = allPortals[allPortals.Reserve(1)];
|
||||||
pt.type = type;
|
pt.type = type;
|
||||||
pt.targets.Push(target);
|
if (target >= 0) pt.targets.Push(target);
|
||||||
pt.dx = dx;
|
pt.dx = dx;
|
||||||
pt.dy = dy;
|
pt.dy = dy;
|
||||||
pt.dz = dz;
|
pt.dz = dz;
|
||||||
|
@ -50,7 +50,7 @@ inline void mergePortals()
|
||||||
{
|
{
|
||||||
auto& pt2 = allPortals[j];
|
auto& pt2 = allPortals[j];
|
||||||
if (pt1.type != pt2.type || pt1.dx != pt2.dx || pt1.dy != pt2.dy || pt1.dz != pt2.dz) continue;
|
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++)
|
for (unsigned t = 0; t < pt2.targets.Size(); t++)
|
||||||
{
|
{
|
||||||
|
@ -63,6 +63,7 @@ inline void mergePortals()
|
||||||
{
|
{
|
||||||
//Printf("Merged %d and %d\n", i, j);
|
//Printf("Merged %d and %d\n", i, j);
|
||||||
if (sector[n].portalnum == j) sector[n].portalnum = i;
|
if (sector[n].portalnum == j) sector[n].portalnum = i;
|
||||||
|
}
|
||||||
didsomething = true;
|
didsomething = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -73,4 +74,3 @@ inline void mergePortals()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "hw_drawstructs.h"
|
#include "hw_drawstructs.h"
|
||||||
#include "automap.h"
|
#include "automap.h"
|
||||||
#include "gamefuncs.h"
|
#include "gamefuncs.h"
|
||||||
|
#include "hw_portal.h"
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -52,8 +53,13 @@ void BunchDrawer::Init(HWDrawInfo *_di, Clipper* c, vec2_t& view)
|
||||||
clipper = c;
|
clipper = c;
|
||||||
viewx = view.x * (1/ 16.f);
|
viewx = view.x * (1/ 16.f);
|
||||||
viewy = view.y * -(1/ 16.f);
|
viewy = view.y * -(1/ 16.f);
|
||||||
|
iview = view;
|
||||||
StartScene();
|
StartScene();
|
||||||
clipper->SetViewpoint(view);
|
clipper->SetViewpoint(view);
|
||||||
|
|
||||||
|
gcosang = bamang(di->Viewpoint.RotAngle).fcos();
|
||||||
|
gsinang = bamang(di->Viewpoint.RotAngle).fsin();
|
||||||
|
|
||||||
for (int i = 0; i < numwalls; i++)
|
for (int i = 0; i < numwalls; i++)
|
||||||
{
|
{
|
||||||
// Precalculate the clip angles to avoid doing this repeatedly during level traversal.
|
// 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)
|
bool BunchDrawer::CheckClip(walltype* wal)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
|
||||||
if (wal - wall == 843 || wal - wall == 847)
|
|
||||||
{
|
|
||||||
int a = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto pt2 = &wall[wal->point2];
|
auto pt2 = &wall[wal->point2];
|
||||||
sectortype* backsector = §or[wal->nextsector];
|
sectortype* backsector = §or[wal->nextsector];
|
||||||
sectortype* frontsector = §or[wall[wal->nextwall].nextsector];
|
sectortype* frontsector = §or[wall[wal->nextwall].nextsector];
|
||||||
|
@ -427,16 +424,41 @@ void BunchDrawer::ProcessSector(int sectnum)
|
||||||
if (gotsector[sectnum]) return;
|
if (gotsector[sectnum]) return;
|
||||||
gotsector.Set(sectnum);
|
gotsector.Set(sectnum);
|
||||||
|
|
||||||
Bsp.Clock();
|
|
||||||
|
|
||||||
auto sect = §or[sectnum];
|
auto sect = §or[sectnum];
|
||||||
bool inbunch;
|
bool inbunch;
|
||||||
binangle startangle;
|
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();
|
SetupFlat.Clock();
|
||||||
HWFlat flat;
|
HWFlat flat;
|
||||||
flat.ProcessSector(di, §or[sectnum]);
|
flat.ProcessSector(di, §or[sectnum]);
|
||||||
SetupFlat.Unclock();
|
SetupFlat.Unclock();
|
||||||
|
Bsp.Clock();
|
||||||
|
|
||||||
//Todo: process subsectors
|
//Todo: process subsectors
|
||||||
inbunch = false;
|
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)
|
while (Bunches.Size() > 0)
|
||||||
{
|
{
|
||||||
int closest = FindClosestBunch();
|
int closest = FindClosestBunch();
|
||||||
|
|
|
@ -24,6 +24,8 @@ class BunchDrawer
|
||||||
TArray<FBunch> Bunches;
|
TArray<FBunch> Bunches;
|
||||||
TArray<int> CompareData;
|
TArray<int> CompareData;
|
||||||
double viewx, viewy;
|
double viewx, viewy;
|
||||||
|
vec2_t iview;
|
||||||
|
float gcosang, gsinang;
|
||||||
FixedBitArray<MAXSECTORS> gotsector;
|
FixedBitArray<MAXSECTORS> gotsector;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -50,5 +52,5 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view);
|
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 "hw_clipper.h"
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
#include "gamecvars.h"
|
#include "gamecvars.h"
|
||||||
|
#include "gamestruct.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Float, r_visibility)
|
EXTERN_CVAR(Float, r_visibility)
|
||||||
CVAR(Bool, gl_bandedswlight, false, CVAR_ARCHIVE)
|
CVAR(Bool, gl_bandedswlight, false, CVAR_ARCHIVE)
|
||||||
|
@ -306,9 +307,18 @@ void HWDrawInfo::CreateScene()
|
||||||
screen->mVertexData->Map();
|
screen->mVertexData->Map();
|
||||||
screen->mLights->Map();
|
screen->mLights->Map();
|
||||||
|
|
||||||
|
spritesortcnt = 0;
|
||||||
|
|
||||||
vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) };
|
vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) };
|
||||||
mDrawer.Init(this, mClipper, view);
|
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->mLights->Unmap();
|
||||||
screen->mVertexData->Unmap();
|
screen->mVertexData->Unmap();
|
||||||
|
|
|
@ -40,7 +40,8 @@ struct FRenderViewpoint
|
||||||
FRotator HWAngles;
|
FRotator HWAngles;
|
||||||
FAngle FieldOfView;
|
FAngle FieldOfView;
|
||||||
angle_t RotAngle;
|
angle_t RotAngle;
|
||||||
int SectNum;
|
int* SectNums;
|
||||||
|
int SectCount;
|
||||||
double TicFrac;
|
double TicFrac;
|
||||||
};
|
};
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "flatvertices.h"
|
#include "flatvertices.h"
|
||||||
#include "hw_clock.h"
|
#include "hw_clock.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
|
#include "gamestruct.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Int, r_mirror_recursions)
|
EXTERN_CVAR(Int, r_mirror_recursions)
|
||||||
EXTERN_CVAR(Bool, gl_portals)
|
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)
|
void HWScenePortalBase::ClearClipper(HWDrawInfo *di, Clipper *clipper)
|
||||||
{
|
{
|
||||||
auto outer_di = di->outer;
|
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.
|
// 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));
|
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);
|
clipper->SafeRemoveClipRange(startang, endang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// and finally clip it to the visible area
|
// and finally clip it to the visible area
|
||||||
angle_t a1 = di->FrustumAngle();
|
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 newy = int((y << 1) + Scale(dy, i, j) - view.y);
|
||||||
int newan = ((gethiq16angle(dx, dy) << 1) - bamang(vp.RotAngle).asq16()) & 0x7FFFFFF;
|
int newan = ((gethiq16angle(dx, dy) << 1) - bamang(vp.RotAngle).asq16()) & 0x7FFFFFF;
|
||||||
vp.RotAngle = q16ang(newan).asbam();
|
vp.RotAngle = q16ang(newan).asbam();
|
||||||
vp.SectNum = line->sector;
|
vp.SectNums = nullptr;
|
||||||
|
vp.SectCount = line->sector;
|
||||||
|
|
||||||
|
|
||||||
vp.Pos.X = newx / 16.f;
|
vp.Pos.X = newx / 16.f;
|
||||||
vp.Pos.Y = newy / -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 origx = vp.Pos.X * 16;
|
||||||
int origy = vp.Pos.Y * -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.X = npos.X;
|
||||||
vp.Pos.Y = npos.Y;
|
vp.Pos.Y = npos.Y;
|
||||||
|
|
||||||
|
@ -689,7 +695,8 @@ bool HWLineToSpritePortal::Setup(HWDrawInfo* di, FRenderState& rstate, Clipper*
|
||||||
int origx = vp.Pos.X * 16;
|
int origx = vp.Pos.X * 16;
|
||||||
int origy = vp.Pos.Y * -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.X = npos.X;
|
||||||
vp.Pos.Y = npos.Y;
|
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)
|
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 portal = origin;
|
||||||
auto &vp = di->Viewpoint;
|
auto &vp = di->Viewpoint;
|
||||||
|
|
||||||
vp.Pos += DVector3(portal->dx / 16., portal->dy / -16., portal->dz / -256.);
|
vp.Pos += DVector3(portal->dx / 16., portal->dy / -16., portal->dz / -256.);
|
||||||
//vp.ActorPos += origin->mDisplacement;
|
vp.SectNums = portal->targets.Data();
|
||||||
//vp.ViewActor = nullptr;
|
vp.SectCount = portal->targets.Size();
|
||||||
|
type = origin->type;
|
||||||
|
state->insectorportal = true;
|
||||||
|
|
||||||
// avoid recursions!
|
// 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));
|
di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));
|
||||||
//SetupCoverage(di);
|
//SetupCoverage(di);
|
||||||
|
@ -819,7 +833,8 @@ bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
|
||||||
|
|
||||||
void HWSectorStackPortal::Shutdown(HWDrawInfo *di, FRenderState &rstate)
|
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"; }
|
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;
|
int PlaneMirrorMode = 0;
|
||||||
bool inskybox = 0;
|
bool inskybox = 0;
|
||||||
|
bool insectorportal = false;
|
||||||
|
|
||||||
UniqueList<HWSkyInfo> UniqueSkies;
|
UniqueList<HWSkyInfo> UniqueSkies;
|
||||||
UniqueList<HWHorizonInfo> UniqueHorizons;
|
UniqueList<HWHorizonInfo> UniqueHorizons;
|
||||||
|
@ -350,6 +351,7 @@ public:
|
||||||
struct HWSectorStackPortal : public HWScenePortalBase
|
struct HWSectorStackPortal : public HWScenePortalBase
|
||||||
{
|
{
|
||||||
TArray<sectortype *> sectors;
|
TArray<sectortype *> sectors;
|
||||||
|
int type = -1;
|
||||||
protected:
|
protected:
|
||||||
bool Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper) override;
|
bool Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper) override;
|
||||||
void Shutdown(HWDrawInfo *di, FRenderState &rstate) 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;
|
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];
|
portal = &allPortals[sector->portalnum];
|
||||||
PutPortal(di, PORTALTYPE_SECTORSTACK, plane);
|
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;
|
ptype = PORTALTYPE_PLANEMIRROR;
|
||||||
if (plane == plane_ceiling && (sector->ceilingstat & CSTAT_SECTOR_SLOPE)) return;
|
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)
|
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;
|
ztop[0] = ztop[1] = 32768.0f;
|
||||||
zbottom[0] = fch1;
|
zbottom[0] = fch1;
|
||||||
|
@ -123,7 +123,7 @@ void HWWall::SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v
|
||||||
SkyPlane(di, fs, plane_ceiling, true);
|
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[0] = ffh1;
|
||||||
ztop[1] = ffh2;
|
ztop[1] = ffh2;
|
||||||
|
|
|
@ -496,6 +496,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, spritetype &c, spritet
|
||||||
("hitag", c.hitag, def->hitag)
|
("hitag", c.hitag, def->hitag)
|
||||||
("extra", c.extra, def->extra)
|
("extra", c.extra, def->extra)
|
||||||
("detail", c.detail, def->detail)
|
("detail", c.detail, def->detail)
|
||||||
|
("time", c.time, def->time)
|
||||||
.EndObject();
|
.EndObject();
|
||||||
}
|
}
|
||||||
return arc;
|
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 (findfrompath(pzFile, &pzFN)) return false; // failed to resolve the filename
|
||||||
if (!FileExists(pzFN))
|
if (!FileExists(pzFN))
|
||||||
{
|
{
|
||||||
Xfree(pzFN);
|
M_Free(pzFN);
|
||||||
return false;
|
return false;
|
||||||
} // failed to stat the file
|
} // failed to stat the file
|
||||||
Xfree(pzFN);
|
M_Free(pzFN);
|
||||||
IniFile* pTempIni = new IniFile(pzFile);
|
IniFile* pTempIni = new IniFile(pzFile);
|
||||||
if (!pTempIni->FindSection("Episode1"))
|
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);
|
FStringf fullname("%s_%02d.art", filename, i);
|
||||||
TileFiles.LoadArtFile(fullname, filename);
|
TileFiles.LoadArtFile(fullname, filename);
|
||||||
|
|
|
@ -126,7 +126,7 @@ static tspritetype *viewAddEffect(int nTSprite, VIEW_EFFECT nViewEffect)
|
||||||
{
|
{
|
||||||
assert(nViewEffect >= 0 && nViewEffect < kViewEffectMax);
|
assert(nViewEffect >= 0 && nViewEffect < kViewEffectMax);
|
||||||
auto pTSprite = &tsprite[nTSprite];
|
auto pTSprite = &tsprite[nTSprite];
|
||||||
if (gDetail < effectDetail[nViewEffect] || nTSprite >= maxspritesonscreen) return NULL;
|
if (gDetail < effectDetail[nViewEffect] || nTSprite >= MAXSPRITESONSCREEN) return NULL;
|
||||||
switch (nViewEffect)
|
switch (nViewEffect)
|
||||||
{
|
{
|
||||||
case VIEW_EFFECT_18:
|
case VIEW_EFFECT_18:
|
||||||
|
@ -220,7 +220,7 @@ static tspritetype *viewAddEffect(int nTSprite, VIEW_EFFECT nViewEffect)
|
||||||
{
|
{
|
||||||
nAng = (nAng+1024)&2047;
|
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;
|
int nSector = pTSprite->sectnum;
|
||||||
auto pNSprite = viewInsertTSprite<tspritetype>(nSector, 32767, NULL);
|
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.
|
// shift before interpolating to increase precision.
|
||||||
int myclock = (PlayClock<<3) + MulScale(4<<3, smoothratio, 16);
|
int myclock = (PlayClock<<3) + MulScale(4<<3, smoothratio, 16);
|
||||||
assert(spritesortcnt <= maxspritesonscreen);
|
assert(spritesortcnt <= MAXSPRITESONSCREEN);
|
||||||
gCameraAng = cA;
|
gCameraAng = cA;
|
||||||
int nViewSprites = spritesortcnt;
|
int nViewSprites = spritesortcnt;
|
||||||
for (int nTSprite = spritesortcnt-1; nTSprite >= 0; nTSprite--)
|
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;
|
pTSprite->xrepeat = pTSprite->yrepeat = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (spritesortcnt >= maxspritesonscreen) continue;
|
if (spritesortcnt >= MAXSPRITESONSCREEN) continue;
|
||||||
if (pTXSprite && pTXSprite->burnTime > 0)
|
if (pTXSprite && pTXSprite->burnTime > 0)
|
||||||
{
|
{
|
||||||
pTSprite->shade = ClipRange(pTSprite->shade-16-QRandom(8), -128, 127);
|
pTSprite->shade = ClipRange(pTSprite->shade-16-QRandom(8), -128, 127);
|
||||||
|
|
|
@ -112,7 +112,6 @@ void StartLevel(MapRecord* level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memset(xsprite, 0, sizeof(xsprite));
|
memset(xsprite, 0, sizeof(xsprite));
|
||||||
memset(sprite, 0, kMaxSprites * sizeof(spritetype));
|
|
||||||
//drawLoadingScreen();
|
//drawLoadingScreen();
|
||||||
dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsectnum, nullptr);
|
dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsectnum, nullptr);
|
||||||
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
||||||
|
|
|
@ -201,6 +201,7 @@ int InsertSprite(int nSector, int nStat)
|
||||||
|
|
||||||
Numsprites++;
|
Numsprites++;
|
||||||
|
|
||||||
|
sprite[nSprite].time = leveltimer++;
|
||||||
return nSprite;
|
return nSprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,6 +513,10 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
|
||||||
gModernMap = false;
|
gModernMap = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
memset(sector, 0, sizeof(*sector) * MAXSECTORS);
|
||||||
|
memset(wall, 0, sizeof(*wall) * MAXWALLS);
|
||||||
|
memset(sprite, 0, sizeof(*sector) * MAXSPRITES);
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
Polymost::Polymost_prepare_loadboard();
|
Polymost::Polymost_prepare_loadboard();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -157,7 +157,6 @@ void hudDraw(PLAYER *gView, int nSectnum, double bobx, double boby, double zDelt
|
||||||
{
|
{
|
||||||
DoLensEffect();
|
DoLensEffect();
|
||||||
viewingRange = viewingrange;
|
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, 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);
|
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;
|
mirror[mirrorcnt].link = i;
|
||||||
sector[j].ceilingpicnum = 4080+mirrorcnt;
|
sector[j].ceilingpicnum = 4080+mirrorcnt;
|
||||||
sector[j].portalflags = PORTAL_SECTOR_CEILING;
|
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++;
|
mirrorcnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -772,10 +772,10 @@ void viewDrawScreen(bool sceneonly)
|
||||||
|
|
||||||
if (testnewrenderer)
|
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;
|
int bakCstat = gView->pSprite->cstat;
|
||||||
gView->pSprite->cstat |= (gViewPos == 0) ? CSTAT_SPRITE_INVISIBLE : CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANSLUCENT_INVERT;
|
gView->pSprite->cstat |= (gViewPos == 0) ? CSTAT_SPRITE_INVISIBLE : CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_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;
|
gView->pSprite->cstat = bakCstat;
|
||||||
}
|
}
|
||||||
else
|
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.
|
// [MR]: Confirm that this is correct as math doesn't match the variable names.
|
||||||
int nCos = z * -bsin(a);
|
int nCos = z * -bsin(a);
|
||||||
int nSin = z * -bcos(a);
|
int nSin = z * -bcos(a);
|
||||||
int nCos2 = MulScale(nCos, yxaspect, 16);
|
|
||||||
int nSin2 = MulScale(nSin, yxaspect, 16);
|
|
||||||
int nPSprite = gView->pSprite->index;
|
int nPSprite = gView->pSprite->index;
|
||||||
|
|
||||||
for (int i = connecthead; i >= 0; i = connectpoint2[i])
|
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);
|
GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist << 2) + 16, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR);
|
||||||
int nTop, nBottom;
|
int nTop, nBottom;
|
||||||
GetSpriteExtents(pSprite, &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);
|
nScale = ClipRange(nScale, 8000, 65536 << 1);
|
||||||
// Players on automap
|
// Players on automap
|
||||||
double x = xdim / 2. + x1 / double(1 << 12);
|
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 "mapinfo.h"
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "gamestate.h"
|
#include "gamestate.h"
|
||||||
|
#include "gamefuncs.h"
|
||||||
|
|
||||||
BEGIN_DUKE_NS
|
BEGIN_DUKE_NS
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "gamestate.h"
|
#include "gamestate.h"
|
||||||
|
#include "gamefuncs.h"
|
||||||
|
|
||||||
BEGIN_DUKE_NS
|
BEGIN_DUKE_NS
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ struct GameInterface : public ::GameInterface
|
||||||
int chaseCamX(binangle ang) { return -ang.bcos(-4); }
|
int chaseCamX(binangle ang) { return -ang.bcos(-4); }
|
||||||
int chaseCamY(binangle ang) { return -ang.bsin(-4); }
|
int chaseCamY(binangle ang) { return -ang.bsin(-4); }
|
||||||
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() >> 9; }
|
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 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 dax, day, cosang, sinang, xspan, yspan, sprx, spry;
|
||||||
int xrepeat, yrepeat, tilenum, daang;
|
int xrepeat, yrepeat, tilenum, daang;
|
||||||
int xvect, yvect, xvect2, yvect2;
|
int xvect, yvect;
|
||||||
int p;
|
int p;
|
||||||
PalEntry col;
|
PalEntry col;
|
||||||
spritetype* spr;
|
spritetype* spr;
|
||||||
|
|
||||||
xvect = -bsin(cang) * czoom;
|
xvect = -bsin(cang) * czoom;
|
||||||
yvect = -bcos(cang) * czoom;
|
yvect = -bcos(cang) * czoom;
|
||||||
xvect2 = MulScale(xvect, yxaspect, 16);
|
|
||||||
yvect2 = MulScale(yvect, yxaspect, 16);
|
|
||||||
|
|
||||||
//Draw sprites
|
//Draw sprites
|
||||||
auto pactor = ps[screenpeek].GetActor();
|
auto pactor = ps[screenpeek].GetActor();
|
||||||
|
@ -435,15 +433,15 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
||||||
ox = sprx - cposx;
|
ox = sprx - cposx;
|
||||||
oy = spry - cposy;
|
oy = spry - cposy;
|
||||||
x1 = DMulScale(ox, xvect, -oy, yvect, 16);
|
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);
|
ox = bcos(spr->ang, -7);
|
||||||
oy = bsin(spr->ang, -7);
|
oy = bsin(spr->ang, -7);
|
||||||
x2 = DMulScale(ox, xvect, -oy, yvect, 16);
|
x2 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||||
y2 = DMulScale(oy, xvect, ox, yvect, 16);
|
y2 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||||
|
|
||||||
x3 = MulScale(x2, yxaspect, 16);
|
x3 = x2;
|
||||||
y3 = MulScale(y2, yxaspect, 16);
|
y3 = y2;
|
||||||
|
|
||||||
drawlinergb(x1 - x2 + (xdim << 11), y1 - y3 + (ydim << 11),
|
drawlinergb(x1 - x2 + (xdim << 11), y1 - y3 + (ydim << 11),
|
||||||
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
|
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;
|
ox = x1 - cposx;
|
||||||
oy = y1 - cposy;
|
oy = y1 - cposy;
|
||||||
x1 = DMulScale(ox, xvect, -oy, yvect, 16);
|
x1 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||||
y1 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
y1 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||||
|
|
||||||
ox = x2 - cposx;
|
ox = x2 - cposx;
|
||||||
oy = y2 - cposy;
|
oy = y2 - cposy;
|
||||||
x2 = DMulScale(ox, xvect, -oy, yvect, 16);
|
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),
|
drawlinergb(x1 + (xdim << 11), y1 + (ydim << 11),
|
||||||
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
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;
|
ox = x1 - cposx;
|
||||||
oy = y1 - cposy;
|
oy = y1 - cposy;
|
||||||
x1 = DMulScale(ox, xvect, -oy, yvect, 16);
|
x1 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||||
y1 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
y1 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||||
|
|
||||||
ox = x2 - cposx;
|
ox = x2 - cposx;
|
||||||
oy = y2 - cposy;
|
oy = y2 - cposy;
|
||||||
x2 = DMulScale(ox, xvect, -oy, yvect, 16);
|
x2 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||||
y2 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
y2 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||||
|
|
||||||
ox = x3 - cposx;
|
ox = x3 - cposx;
|
||||||
oy = y3 - cposy;
|
oy = y3 - cposy;
|
||||||
x3 = DMulScale(ox, xvect, -oy, yvect, 16);
|
x3 = DMulScale(ox, xvect, -oy, yvect, 16);
|
||||||
y3 = DMulScale(oy, xvect2, ox, yvect2, 16);
|
y3 = DMulScale(oy, xvect, ox, yvect, 16);
|
||||||
|
|
||||||
ox = x4 - cposx;
|
ox = x4 - cposx;
|
||||||
oy = y4 - cposy;
|
oy = y4 - cposy;
|
||||||
x4 = DMulScale(ox, xvect, -oy, yvect, 16);
|
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),
|
drawlinergb(x1 + (xdim << 11), y1 + (ydim << 11),
|
||||||
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
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;
|
i = TILE_APLAYERTOP;
|
||||||
|
|
||||||
j = abs(pp.truefz - pp.posz) >> 8;
|
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;
|
if (j < 22000) j = 22000;
|
||||||
else if (j > (65536 << 1)) j = (65536 << 1);
|
else if (j > (65536 << 1)) j = (65536 << 1);
|
||||||
|
|
|
@ -924,7 +924,7 @@ static void SpawnPortals()
|
||||||
if (findwallbetweensectors(i, t) >= 0)
|
if (findwallbetweensectors(i, t) >= 0)
|
||||||
{
|
{
|
||||||
sector[i].portalflags = PORTAL_SECTOR_FLOOR;
|
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);
|
pt.targets.Push(i);
|
||||||
goto nexti;
|
goto nexti;
|
||||||
}
|
}
|
||||||
|
@ -943,7 +943,7 @@ static void SpawnPortals()
|
||||||
if (findwallbetweensectors(i, t) >= 0)
|
if (findwallbetweensectors(i, t) >= 0)
|
||||||
{
|
{
|
||||||
sector[i].portalflags = PORTAL_SECTOR_CEILING;
|
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);
|
pt.targets.Push(i);
|
||||||
goto nexti;
|
goto nexti;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ void renderView(spritetype* playersprite, int sectnum, int x, int y, int z, bina
|
||||||
}
|
}
|
||||||
else
|
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
|
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;
|
display_mirror = 0;
|
||||||
renderDrawMasks();
|
renderDrawMasks();
|
||||||
|
@ -414,6 +414,10 @@ bool GameInterface::GenerateSavePic()
|
||||||
return true;
|
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
|
END_DUKE_NS
|
||||||
|
|
|
@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
|
#include "gamefuncs.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
|
@ -255,6 +255,7 @@ struct GameInterface : ::GameInterface
|
||||||
int chaseCamX(binangle ang) { return -ang.bcos() / 12; }
|
int chaseCamX(binangle ang) { return -ang.bcos() / 12; }
|
||||||
int chaseCamY(binangle ang) { return -ang.bsin() / 12; }
|
int chaseCamY(binangle ang) { return -ang.bsin() / 12; }
|
||||||
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() / 384; }
|
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() / 384; }
|
||||||
|
void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
|
||||||
|
|
||||||
::GameStats getStats() 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.
|
// [MR]: Confirm that this is correct as math doesn't match the variable names.
|
||||||
int nCos = z * -bsin(a);
|
int nCos = z * -bsin(a);
|
||||||
int nSin = z * -bcos(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])
|
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);
|
getzrange_old(pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist << 2) + 16, CLIPMASK0);
|
||||||
int nTop, nBottom;
|
int nTop, nBottom;
|
||||||
GetSpriteExtents(pSprite, &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);
|
nScale = clamp(nScale, 8000, 65536 << 1);
|
||||||
// Players on automap
|
// Players on automap
|
||||||
double x = xdim / 2. + x1 / double(1 << 12);
|
double x = xdim / 2. + x1 / double(1 << 12);
|
||||||
|
|
|
@ -66,7 +66,7 @@ short enemy;
|
||||||
short nEnemyPal = 0;
|
short nEnemyPal = 0;
|
||||||
|
|
||||||
// NOTE - not to be confused with Ken's analyzesprites()
|
// 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;
|
tspritetype *pTSprite;
|
||||||
|
|
||||||
|
@ -90,11 +90,6 @@ static void analyzesprites(double const smoothratio)
|
||||||
|
|
||||||
besttarget = -1;
|
besttarget = -1;
|
||||||
|
|
||||||
int x = pPlayerSprite->x;
|
|
||||||
int y = pPlayerSprite->y;
|
|
||||||
|
|
||||||
int z = pPlayerSprite->z - (GetSpriteHeight(nPlayerSprite) / 2);
|
|
||||||
|
|
||||||
short nSector = pPlayerSprite->sectnum;
|
short nSector = pPlayerSprite->sectnum;
|
||||||
|
|
||||||
int nAngle = (2048 - pPlayerSprite->ang) & kAngleMask;
|
int nAngle = (2048 - pPlayerSprite->ang) & kAngleMask;
|
||||||
|
@ -362,12 +357,12 @@ void DrawView(double smoothRatio, bool sceneonly)
|
||||||
{
|
{
|
||||||
renderSetRollAngle(rotscrnang.asbuildf());
|
renderSetRollAngle(rotscrnang.asbuildf());
|
||||||
renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa.asq16(), nCamerapan.asq16(), nSector);
|
renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa.asq16(), nCamerapan.asq16(), nSector);
|
||||||
analyzesprites(smoothRatio);
|
analyzesprites(nCamerax, nCameray, viewz, smoothRatio);
|
||||||
renderDrawMasks();
|
renderDrawMasks();
|
||||||
}
|
}
|
||||||
else
|
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())
|
if (HavePLURemap())
|
||||||
|
@ -467,6 +462,12 @@ bool GameInterface::GenerateSavePic()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameInterface::processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
|
||||||
|
{
|
||||||
|
analyzesprites(viewx, viewy, viewz, smoothRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void NoClip()
|
void NoClip()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,310 +1,7 @@
|
||||||
BEGIN_SW_NS
|
BEGIN_SW_NS
|
||||||
|
|
||||||
short GlobStackSect[2];
|
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);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
short
|
short
|
||||||
|
@ -480,7 +177,7 @@ void polymost_drawscreen(PLAYERp pp, int tx, int ty, int tz, binangle tang, fixe
|
||||||
if (!FAF_DebugView)
|
if (!FAF_DebugView)
|
||||||
FAF_DrawRooms(tx, ty, tz, tang.asq16(), thoriz.asq16(), tsectnum);
|
FAF_DrawRooms(tx, ty, tz, tang.asq16(), thoriz.asq16(), tsectnum);
|
||||||
|
|
||||||
analyzesprites(tx, ty, tz, false);
|
analyzesprites(tx, ty, tz, tang.asbuild());
|
||||||
post_analyzesprites();
|
post_analyzesprites();
|
||||||
renderDrawMasks();
|
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);
|
renderDrawRoomsQ16(tposx, tposy, tz, (tang), tpq16horiz, mirror[cnt].mirrorsector + MAXSECTORS);
|
||||||
|
|
||||||
analyzesprites(tposx, tposy, tz, true);
|
analyzesprites(tposx, tposy, tz, tang >> 16);
|
||||||
renderDrawMasks();
|
renderDrawMasks();
|
||||||
|
|
||||||
renderCompleteMirror(); // Reverse screen x-wise in this
|
renderCompleteMirror(); // Reverse screen x-wise in this
|
||||||
|
|
|
@ -71,7 +71,7 @@ extern short f_c;
|
||||||
|
|
||||||
extern ParentalStruct aVoxelArray[MAXTILES];
|
extern ParentalStruct aVoxelArray[MAXTILES];
|
||||||
|
|
||||||
int ConnectCopySprite(uspritetype const * tsp);
|
int ConnectCopySprite(spritetype const * tsp);
|
||||||
void PreDrawStackedWater(void);
|
void PreDrawStackedWater(void);
|
||||||
|
|
||||||
void SW_InitMultiPsky(void)
|
void SW_InitMultiPsky(void)
|
||||||
|
@ -265,7 +265,7 @@ DoShadowFindGroundPoint(tspriteptr_t sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DoShadows(tspriteptr_t tsp, int viewz, bool mirror)
|
DoShadows(tspriteptr_t tsp, int viewz, int camang)
|
||||||
{
|
{
|
||||||
tspriteptr_t New = &tsprite[spritesortcnt];
|
tspriteptr_t New = &tsprite[spritesortcnt];
|
||||||
USERp tu = User[tsp->owner];
|
USERp tu = User[tsp->owner];
|
||||||
|
@ -553,7 +553,7 @@ void DoStarView(tspriteptr_t tsp, USERp tu, int viewz)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
analyzesprites(int viewx, int viewy, int viewz, bool mirror)
|
analyzesprites(int viewx, int viewy, int viewz, int camang)
|
||||||
{
|
{
|
||||||
int tSpriteNum;
|
int tSpriteNum;
|
||||||
short SpriteNum;
|
short SpriteNum;
|
||||||
|
@ -645,7 +645,7 @@ analyzesprites(int viewx, int viewy, int viewz, bool mirror)
|
||||||
|
|
||||||
if (r_shadows && TEST(tu->Flags, SPR_SHADOW))
|
if (r_shadows && TEST(tu->Flags, SPR_SHADOW))
|
||||||
{
|
{
|
||||||
DoShadows(tsp, viewz, mirror);
|
DoShadows(tsp, viewz, camang);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define UK_VERSION 1
|
//#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)
|
if (OverlapDraw && FAF_ConnectArea(tsp->sectnum) && tsp->owner >= 0)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(uspritetype) == sizeof(tspritetype)); // see TSPRITE_SIZE
|
ConnectCopySprite(tsp);
|
||||||
ConnectCopySprite((uspriteptr_t)tsp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -902,7 +901,6 @@ post_analyzesprites(void)
|
||||||
{
|
{
|
||||||
if (tu->ID == FIREBALL_FLAMES && tu->Attach >= 0)
|
if (tu->ID == FIREBALL_FLAMES && tu->Attach >= 0)
|
||||||
{
|
{
|
||||||
//uspritetype * const atsp = &sprite[tu->Attach];
|
|
||||||
tspriteptr_t const atsp = get_tsprite(tu->Attach);
|
tspriteptr_t const atsp = get_tsprite(tu->Attach);
|
||||||
|
|
||||||
if (!atsp)
|
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)
|
void DrawCrosshair(PLAYERp pp)
|
||||||
{
|
{
|
||||||
extern bool CameraTestMode;
|
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;
|
short New;
|
||||||
SPRITEp sp;
|
SPRITEp sp;
|
||||||
|
@ -1310,7 +1280,7 @@ int CopySprite(uspritetype const * tsp, short newsector)
|
||||||
return New;
|
return New;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConnectCopySprite(uspritetype const * tsp)
|
int ConnectCopySprite(spritetype const * tsp)
|
||||||
{
|
{
|
||||||
short newsector;
|
short newsector;
|
||||||
int testz;
|
int testz;
|
||||||
|
@ -1375,7 +1345,7 @@ void PreDrawStackedWater(void)
|
||||||
sp = &sprite[i];
|
sp = &sprite[i];
|
||||||
u = User[i];
|
u = User[i];
|
||||||
|
|
||||||
New = ConnectCopySprite((uspritetype const *)sp);
|
New = ConnectCopySprite((spritetype const *)sp);
|
||||||
if (New >= 0)
|
if (New >= 0)
|
||||||
{
|
{
|
||||||
// spawn a user
|
// spawn a user
|
||||||
|
@ -1596,7 +1566,7 @@ drawscreen(PLAYERp pp, double smoothratio)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UpdateWallPortalState();
|
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 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 dax, day, cosang, sinang, xspan, yspan, sprx, spry;
|
||||||
int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
|
int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
|
||||||
int xvect, yvect, xvect2, yvect2;
|
int xvect, yvect;
|
||||||
walltype* wal, * wal2;
|
walltype* wal, * wal2;
|
||||||
spritetype* spr;
|
spritetype* spr;
|
||||||
short p;
|
short p;
|
||||||
|
@ -1716,8 +1686,6 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
||||||
|
|
||||||
xvect = -bsin(cang) * czoom;
|
xvect = -bsin(cang) * czoom;
|
||||||
yvect = -bcos(cang) * czoom;
|
yvect = -bcos(cang) * czoom;
|
||||||
xvect2 = MulScale(xvect, yxaspect, 16);
|
|
||||||
yvect2 = MulScale(yvect, yxaspect, 16);
|
|
||||||
|
|
||||||
|
|
||||||
// Draw sprites
|
// 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 xd = ((x1 << 4) + (xdim << 15)) / 65536.;
|
||||||
double yd = ((y1 << 4) + (ydim << 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)
|
if (spnum >= 0)
|
||||||
{
|
{
|
||||||
DrawTexture(twod, tileGetTexture(1196 + pspr_ndx[myconnectindex], true), xd, yd, DTA_ScaleX, sc, DTA_ScaleY, sc, DTA_Rotate, daang * (-360. / 2048),
|
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;
|
ox = x1 - cposx;
|
||||||
oy = y1 - cposy;
|
oy = y1 - cposy;
|
||||||
x1 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
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;
|
ox = x2 - cposx;
|
||||||
oy = y2 - cposy;
|
oy = y2 - cposy;
|
||||||
x2 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
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),
|
drawlinergb(x1 + (xdim << 11), y1 + (ydim << 11),
|
||||||
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
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;
|
ox = x1 - cposx;
|
||||||
oy = y1 - cposy;
|
oy = y1 - cposy;
|
||||||
x1 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
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;
|
ox = x2 - cposx;
|
||||||
oy = y2 - cposy;
|
oy = y2 - cposy;
|
||||||
x2 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
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;
|
ox = x3 - cposx;
|
||||||
oy = y3 - cposy;
|
oy = y3 - cposy;
|
||||||
x3 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
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;
|
ox = x4 - cposx;
|
||||||
oy = y4 - cposy;
|
oy = y4 - cposy;
|
||||||
x4 = MulScale(ox, xvect, 16) - MulScale(oy, yvect, 16);
|
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),
|
drawlinergb(x1 + (xdim << 11), y1 + (ydim << 11),
|
||||||
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
x2 + (xdim << 11), y2 + (ydim << 11), col);
|
||||||
|
@ -1901,6 +1869,12 @@ bool GameInterface::DrawAutomapPlayer(int cposx, int cposy, int czoom, int cang,
|
||||||
return true;
|
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
|
END_SW_NS
|
||||||
|
|
|
@ -407,8 +407,8 @@ void InitLevel(MapRecord *maprec)
|
||||||
PlaceActorsOnTracks();
|
PlaceActorsOnTracks();
|
||||||
PostSetupSectorObject();
|
PostSetupSectorObject();
|
||||||
SetupMirrorTiles();
|
SetupMirrorTiles();
|
||||||
SetupSectorPortals();
|
|
||||||
initlava();
|
initlava();
|
||||||
|
CollectPortals();
|
||||||
|
|
||||||
// reset NewGame
|
// reset NewGame
|
||||||
NewGame = false;
|
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 change_sprite_stat(short, short);
|
||||||
void SetOwner(short, short);
|
void SetOwner(short, short);
|
||||||
void SetAttach(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 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_PLACE_MIRROR_PIC 341
|
||||||
#define FAF_MIRROR_PIC 2356
|
#define FAF_MIRROR_PIC 2356
|
||||||
#define FAF_ConnectCeiling(sectnum) (sector[(sectnum)].ceilingpicnum == FAF_MIRROR_PIC)
|
#define FAF_ConnectCeiling(sectnum) (sector[(sectnum)].ceilingpicnum == FAF_MIRROR_PIC)
|
||||||
#define FAF_ConnectFloor(sectnum) (sector[(sectnum)].floorpicnum == FAF_MIRROR_PIC)
|
#define FAF_ConnectFloor(sectnum) (sector[(sectnum)].floorpicnum == FAF_MIRROR_PIC)
|
||||||
#define FAF_ConnectArea(sectnum) (FAF_ConnectCeiling(sectnum) || FAF_ConnectFloor(sectnum))
|
#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 PlayerCeilingHit(PLAYERp pp, int zlimit);
|
||||||
bool PlayerFloorHit(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
|
void SetupMirrorTiles(void); // rooms.c
|
||||||
bool FAF_Sector(short sectnum); // rooms.c
|
bool FAF_Sector(short sectnum); // rooms.c
|
||||||
int GetZadjustment(short sectnum,short hitag); // rooms.c
|
int GetZadjustment(short sectnum,short hitag); // rooms.c
|
||||||
void SetupSectorPortals();
|
|
||||||
|
|
||||||
void InitSetup(void); // setup.c
|
void InitSetup(void); // setup.c
|
||||||
|
|
||||||
|
@ -2256,6 +2248,7 @@ struct GameInterface : ::GameInterface
|
||||||
int chaseCamX(binangle ang) { return -ang.bcos(-3); }
|
int chaseCamX(binangle ang) { return -ang.bcos(-3); }
|
||||||
int chaseCamY(binangle ang) { return -ang.bsin(-3); }
|
int chaseCamY(binangle ang) { return -ang.bsin(-3); }
|
||||||
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() >> 8; }
|
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() >> 8; }
|
||||||
|
void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
|
||||||
|
|
||||||
|
|
||||||
GameStats getStats() override;
|
GameStats getStats() override;
|
||||||
|
|
|
@ -464,7 +464,7 @@ void JS_InitMirrors(void)
|
||||||
// Draw a 3d screen to a specific tile
|
// Draw a 3d screen to a specific tile
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
void drawroomstotile(int daposx, int daposy, int daposz,
|
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));
|
TileFiles.MakeCanvas(tilenume, tileWidth(tilenume), tileHeight(tilenume));
|
||||||
|
|
||||||
|
@ -475,13 +475,13 @@ void drawroomstotile(int daposx, int daposy, int daposz,
|
||||||
{
|
{
|
||||||
if (!testnewrenderer)
|
if (!testnewrenderer)
|
||||||
{
|
{
|
||||||
renderDrawRoomsQ16(daposx, daposy, daposz, daq16ang, daq16horiz, dacursectnum);
|
renderDrawRoomsQ16(daposx, daposy, daposz, ang.asq16(), horiz.asq16(), dacursectnum);
|
||||||
analyzesprites(daposx, daposy, daposz, false);
|
analyzesprites(daposx, daposy, daposz, ang.asbuild());
|
||||||
renderDrawMasks();
|
renderDrawMasks();
|
||||||
}
|
}
|
||||||
else
|
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)
|
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
|
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 "names2.h"
|
||||||
#include "panel.h"
|
#include "panel.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "hw_drawinfo.h"
|
||||||
|
|
||||||
BEGIN_SW_NS
|
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;
|
int i;
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
// 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// didn't find it yet so test ALL sectors
|
||||||
|
if (sln < 2)
|
||||||
|
{
|
||||||
|
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
|
// Search Stat List For closest ceiling view sprite
|
||||||
// Get the match, xoff, yoff from this point
|
// Get the match, xoff, yoff from this point
|
||||||
StatIterator it(STAT_FAF);
|
StatIterator it(STAT_FAF);
|
||||||
int i;
|
|
||||||
while ((i = it.NextIndex()) >= 0)
|
while ((i = it.NextIndex()) >= 0)
|
||||||
{
|
{
|
||||||
auto sp = &sprite[i];
|
sp = &sprite[i];
|
||||||
|
|
||||||
if (sp->hitag == VIEW_THRU_CEILING) foundc.Push(i);
|
if (sp->hitag == VIEW_THRU_CEILING && sp->lotag == match)
|
||||||
if (sp->hitag == VIEW_THRU_FLOOR) foundf.Push(i);
|
{
|
||||||
|
xoff = *x - sp->x;
|
||||||
|
yoff = *y - sp->y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
portalClear();
|
it.Reset(STAT_FAF);
|
||||||
while (foundf.Size())
|
while ((i = it.NextIndex()) >= 0)
|
||||||
{
|
{
|
||||||
auto spf = &sprite[foundf[0]];
|
sp = &sprite[i];
|
||||||
auto cindex = foundc.FindEx([=](int i) { return spf->lotag == sprite[i].lotag; });
|
|
||||||
if (cindex != foundc.Size())
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
sector[spc->sectnum].portalflags = PORTAL_SECTOR_CEILING;
|
if (sp->lotag == match)
|
||||||
sector[spc->sectnum].portalnum = portalAdd(PORTAL_SECTOR_CEILING, spf->sectnum, spf->x - spc->x, spf->y - spc->y, 0);
|
{
|
||||||
|
// determine x,y position
|
||||||
|
if (sp->hitag == VIEW_THRU_FLOOR)
|
||||||
|
{
|
||||||
|
short upper, lower;
|
||||||
|
|
||||||
//Printf("Portal with tag %d\n", sprite[foundf[0]].lotag);
|
*x = sp->x + xoff;
|
||||||
foundf.Delete(0);
|
*y = sp->y + yoff;
|
||||||
foundc.Delete(cindex);
|
|
||||||
|
// get new sector
|
||||||
|
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
||||||
|
*sectnum = upper;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
//Printf("Floor portal %d without partner\n", sprite[foundf[0]].lotag);
|
it.Reset(STAT_FAF);
|
||||||
foundf.Delete(0);
|
while ((i = it.NextIndex()) >= 0)
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto c : foundc)
|
|
||||||
{
|
{
|
||||||
//Printf("Ceiling portal %d without partner\n", sprite[c].lotag);
|
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
|
END_SW_NS
|
||||||
|
|
|
@ -44,7 +44,7 @@ typedef struct
|
||||||
} saveable_module;
|
} saveable_module;
|
||||||
|
|
||||||
template <typename T>
|
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);
|
return sizeof(obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -639,7 +639,7 @@ TrackSetup(void)
|
||||||
if (t->NumPoints == 0)
|
if (t->NumPoints == 0)
|
||||||
{
|
{
|
||||||
int i;
|
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);
|
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);
|
StatIterator it(STAT_TRACK + ndx);
|
||||||
while ((i = it.NextIndex()) >= 0)
|
while ((i = it.NextIndex()) >= 0)
|
||||||
|
|
|
@ -10,10 +10,11 @@ EXTERN_CVAR(Bool, testnewrenderer)
|
||||||
|
|
||||||
BEGIN_WH_NS
|
BEGIN_WH_NS
|
||||||
|
|
||||||
|
int curpnum;
|
||||||
|
|
||||||
void drawscreen(int num, double dasmoothratio, bool sceneonly)
|
void drawscreen(int num, double dasmoothratio, bool sceneonly)
|
||||||
{
|
{
|
||||||
|
curpnum = num;
|
||||||
PLAYER& plr = player[num];
|
PLAYER& plr = player[num];
|
||||||
|
|
||||||
int cposx = plr.x;
|
int cposx = plr.x;
|
||||||
|
@ -90,7 +91,6 @@ void drawscreen(int num, double dasmoothratio, bool sceneonly)
|
||||||
cposz = floorz - lz;
|
cposz = floorz - lz;
|
||||||
|
|
||||||
// do screen rotation.
|
// do screen rotation.
|
||||||
renderSetRollAngle(crotscrnang.asbam() / (double)(BAMUNIT));
|
|
||||||
|
|
||||||
if (!testnewrenderer)
|
if (!testnewrenderer)
|
||||||
{
|
{
|
||||||
|
@ -101,7 +101,7 @@ void drawscreen(int num, double dasmoothratio, bool sceneonly)
|
||||||
}
|
}
|
||||||
else
|
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)
|
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()
|
void GameInterface::Render()
|
||||||
{
|
{
|
||||||
double const smoothRatio = playrunning() ? I_GetTimeFrac() * MaxSmoothRatio : MaxSmoothRatio;
|
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 chaseCamX(binangle ang) { return -ang.bcos() / 12; }
|
||||||
int chaseCamY(binangle ang) { return -ang.bsin() / 12; }
|
int chaseCamY(binangle ang) { return -ang.bsin() / 12; }
|
||||||
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() / 384; }
|
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 "hw_cvars.h"
|
||||||
#include "gamestruct.h"
|
#include "gamestruct.h"
|
||||||
#include "gl_models.h"
|
#include "gl_models.h"
|
||||||
|
#include "gamefuncs.h"
|
||||||
|
|
||||||
CVARD(Bool, hw_hightile, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable hightile texture rendering")
|
CVARD(Bool, hw_hightile, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable hightile texture rendering")
|
||||||
bool hw_int_useindexedcolortextures;
|
bool hw_int_useindexedcolortextures;
|
||||||
|
|
Loading…
Reference in a new issue