mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 20:20:40 +00:00
- cleaned engine.cpp off all code exclusive to the Polymost renderer.
This commit is contained in:
parent
e47b4507e4
commit
022edd2dc2
7 changed files with 569 additions and 614 deletions
|
@ -223,7 +223,6 @@ static inline tspriteptr_t renderAddTSpriteFromSprite(uint16_t const spritenum)
|
|||
|
||||
|
||||
EXTERN int16_t maskwall[MAXWALLSB], maskwallcnt;
|
||||
EXTERN int16_t thewall[MAXWALLSB];
|
||||
EXTERN tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
|
||||
|
||||
EXTERN int32_t xdim, ydim;
|
||||
|
@ -441,18 +440,11 @@ void renderSetAspect(int32_t daxrange, int32_t daaspect);
|
|||
void plotpixel(int32_t x, int32_t y, char col);
|
||||
FCanvasTexture *renderSetTarget(int16_t tilenume);
|
||||
void renderRestoreTarget();
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall,
|
||||
int32_t *tposx, int32_t *tposy, fixed_t *tang);
|
||||
void renderCompleteMirror(void);
|
||||
|
||||
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int16_t dacursectnum);
|
||||
|
||||
void renderDrawMasks(void);
|
||||
void setVideoMode();
|
||||
void videoInit();
|
||||
void videoClearViewableArea(int32_t dacol);
|
||||
void videoClearScreen(int32_t dacol);
|
||||
void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang);
|
||||
|
||||
class F2DDrawer;
|
||||
|
||||
|
@ -653,16 +645,6 @@ static FORCE_INLINE int32_t spriteheightofs(int16_t i, int32_t *height, int32_t
|
|||
|
||||
int videoCaptureScreen();
|
||||
|
||||
// PLAG: line utility functions
|
||||
typedef struct s_equation
|
||||
{
|
||||
float a, b, c;
|
||||
} _equation;
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
void renderSetRollAngle(float rolla);
|
||||
#endif
|
||||
|
||||
void PrecacheHardwareTextures(int nTile);
|
||||
void Polymost_Startup();
|
||||
|
||||
|
|
|
@ -36,6 +36,23 @@ extern float curpolygonoffset;
|
|||
|
||||
}
|
||||
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall,
|
||||
int32_t* tposx, int32_t* tposy, fixed_t* tang);
|
||||
void renderCompleteMirror(void);
|
||||
|
||||
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int16_t dacursectnum);
|
||||
|
||||
void renderDrawMasks(void);
|
||||
|
||||
// PLAG: line utility functions
|
||||
typedef struct s_equation
|
||||
{
|
||||
float a, b, c;
|
||||
} _equation;
|
||||
|
||||
void renderSetRollAngle(float rolla);
|
||||
|
||||
|
||||
// these are defined in engine.cpp.
|
||||
extern int16_t globalpicnum;
|
||||
extern float fcosglobalang, fsinglobalang;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||||
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||||
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
||||
// See the included license file "BUILDLIC.TXT" for license info.
|
||||
//
|
||||
|
@ -40,8 +41,6 @@
|
|||
#include "gl_renderer.h"
|
||||
#endif
|
||||
|
||||
float rollang;
|
||||
|
||||
int32_t r_rortexture = 0;
|
||||
int32_t r_rortexturerange = 0;
|
||||
int32_t r_rorphase = 0;
|
||||
|
@ -82,7 +81,7 @@ int32_t showfirstwall=0;
|
|||
int32_t showheightindicators=1;
|
||||
int32_t circlewall=-1;
|
||||
|
||||
static fixed_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms)
|
||||
fixed_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms)
|
||||
|
||||
static FString printcoords(void)
|
||||
{
|
||||
|
@ -140,12 +139,6 @@ static void getclosestpointonwall_internal(vec2_t const p, int32_t const dawall,
|
|||
*closest = { (int32_t)(w.x + ((d.x * i) >> 30)), (int32_t)(w.y + ((d.y * i) >> 30)) };
|
||||
}
|
||||
|
||||
int16_t bunchp2[MAXWALLSB], thesector[MAXWALLSB];
|
||||
int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
||||
|
||||
|
||||
static vec3_t spritesxyz[MAXSPRITESONSCREEN+1];
|
||||
|
||||
int32_t xdimen = -1, xdimenscale, xdimscale;
|
||||
float fxdimen = -1.f;
|
||||
int32_t ydimen;
|
||||
|
@ -171,12 +164,9 @@ static int32_t globaly1, globalx2;
|
|||
int16_t sectorborder[256];
|
||||
int16_t pointhighlight=-1, linehighlight=-1, highlightcnt=0;
|
||||
|
||||
static_assert(MAXWALLSB < INT16_MAX);
|
||||
int16_t numscans, numbunches;
|
||||
static int16_t numhits;
|
||||
|
||||
char inpreparemirror = 0;
|
||||
static int32_t mirrorsx1, mirrorsy1, mirrorsx2, mirrorsy2;
|
||||
|
||||
|
||||
//
|
||||
|
@ -232,21 +222,6 @@ int32_t animateoffs(int const tilenum, int fakevar)
|
|||
return offs;
|
||||
}
|
||||
|
||||
static void renderDrawSprite(int32_t snum)
|
||||
{
|
||||
Polymost::polymost_drawsprite(snum);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// drawmaskwall (internal)
|
||||
//
|
||||
static void renderDrawMaskedWall(int16_t damaskwallcnt)
|
||||
{
|
||||
Polymost::polymost_drawmaskwall(damaskwallcnt); return;
|
||||
}
|
||||
|
||||
|
||||
static int32_t engineLoadTables(void)
|
||||
{
|
||||
static char tablesloaded = 0;
|
||||
|
@ -281,16 +256,10 @@ static int32_t engineLoadTables(void)
|
|||
|
||||
////////// SPRITE LIST MANIPULATION FUNCTIONS //////////
|
||||
|
||||
#ifdef NETCODE_DISABLE
|
||||
# define LISTFN_STATIC static
|
||||
#else
|
||||
# define LISTFN_STATIC
|
||||
#endif
|
||||
|
||||
///// sector lists of sprites /////
|
||||
|
||||
// insert sprite at the head of sector list, change .sectnum
|
||||
LISTFN_STATIC void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sectnum)
|
||||
static void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sectnum)
|
||||
{
|
||||
int16_t const ohead = headspritesect[sectnum];
|
||||
|
||||
|
@ -304,7 +273,7 @@ LISTFN_STATIC void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sect
|
|||
}
|
||||
|
||||
// remove sprite 'deleteme' from its sector list
|
||||
LISTFN_STATIC void do_deletespritesect(int16_t deleteme)
|
||||
static void do_deletespritesect(int16_t deleteme)
|
||||
{
|
||||
int32_t const sectnum = sprite[deleteme].sectnum;
|
||||
int32_t const prev = prevspritesect[deleteme];
|
||||
|
@ -321,7 +290,7 @@ LISTFN_STATIC void do_deletespritesect(int16_t deleteme)
|
|||
///// now, status lists /////
|
||||
|
||||
// insert sprite at head of status list, change .statnum
|
||||
LISTFN_STATIC void do_insertsprite_at_headofstat(int16_t spritenum, int16_t statnum)
|
||||
static void do_insertsprite_at_headofstat(int16_t spritenum, int16_t statnum)
|
||||
{
|
||||
int16_t const ohead = headspritestat[statnum];
|
||||
|
||||
|
@ -335,7 +304,7 @@ LISTFN_STATIC void do_insertsprite_at_headofstat(int16_t spritenum, int16_t stat
|
|||
}
|
||||
|
||||
// insertspritestat (internal)
|
||||
LISTFN_STATIC int32_t insertspritestat(int16_t statnum)
|
||||
static int32_t insertspritestat(int16_t statnum)
|
||||
{
|
||||
if ((statnum >= MAXSTATUS) || (headspritestat[MAXSTATUS] == -1))
|
||||
return -1; //list full
|
||||
|
@ -356,7 +325,7 @@ LISTFN_STATIC int32_t insertspritestat(int16_t statnum)
|
|||
}
|
||||
|
||||
// remove sprite 'deleteme' from its status list
|
||||
LISTFN_STATIC void do_deletespritestat(int16_t deleteme)
|
||||
static void do_deletespritestat(int16_t deleteme)
|
||||
{
|
||||
int32_t const sectnum = sprite[deleteme].statnum;
|
||||
int32_t const prev = prevspritestat[deleteme];
|
||||
|
@ -740,29 +709,10 @@ int32_t engineInit(void)
|
|||
GPalette.Init(MAXPALOOKUPS + 1); // one slot for each translation, plus a separate one for the base palettes.
|
||||
gi->loadPalette();
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
if (!mdinited) mdinit();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// uninitengine
|
||||
//
|
||||
|
||||
void engineUnInit(void)
|
||||
{
|
||||
Polymost::polymost_glreset();
|
||||
freeallmodels();
|
||||
# ifdef POLYMER
|
||||
polymer_uninit();
|
||||
# endif
|
||||
|
||||
TileFiles.CloseAll();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// initspritelists
|
||||
//
|
||||
|
@ -818,463 +768,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
|
||||
|
@ -2226,22 +1719,6 @@ void rotatepoint(vec2_t const pivot, vec2_t p, int16_t const daang, vec2_t * con
|
|||
p2->y = DMulScale(p.y, dacos, p.x, dasin, 14) + pivot.y;
|
||||
}
|
||||
|
||||
void videoSetCorrectedAspect()
|
||||
{
|
||||
// In DOS the game world is displayed with an aspect of 1.28 instead 1.333,
|
||||
// meaning we have to stretch it by a factor of 1.25 instead of 1.2
|
||||
// to get perfect squares
|
||||
int32_t yx = (65536 * 5) / 4;
|
||||
int32_t vr, y, x;
|
||||
|
||||
x = xdim;
|
||||
y = ydim;
|
||||
|
||||
vr = DivScale(x*3, y*4, 16);
|
||||
|
||||
renderSetAspect(vr, yx);
|
||||
}
|
||||
|
||||
//
|
||||
// setview
|
||||
//
|
||||
|
@ -2355,41 +1832,6 @@ void renderRestoreTarget()
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// preparemirror
|
||||
//
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall,
|
||||
int32_t *tposx, int32_t *tposy, fixed_t *tang)
|
||||
{
|
||||
const int32_t x = wall[dawall].x, dx = wall[wall[dawall].point2].x-x;
|
||||
const int32_t y = wall[dawall].y, dy = wall[wall[dawall].point2].y-y;
|
||||
|
||||
const int32_t j = dx*dx + dy*dy;
|
||||
if (j == 0)
|
||||
return;
|
||||
|
||||
int i = ((dax-x)*dx + (day-y)*dy)<<1;
|
||||
|
||||
*tposx = (x<<1) + Scale(dx,i,j) - dax;
|
||||
*tposy = (y<<1) + Scale(dy,i,j) - day;
|
||||
*tang = ((gethiq16angle(dx, dy) << 1) - daang) & 0x7FFFFFF;
|
||||
|
||||
inpreparemirror = 1;
|
||||
|
||||
Polymost::polymost_prepareMirror(dax, day, daz, daang, dahoriz, dawall);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// completemirror
|
||||
//
|
||||
void renderCompleteMirror(void)
|
||||
{
|
||||
Polymost::polymost_completeMirror();
|
||||
inpreparemirror = 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
|
||||
{
|
||||
if (!(sec->ceilingstat&2))
|
||||
|
@ -2493,15 +1935,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,8 +13,6 @@
|
|||
#ifndef ENGINE_PRIV_H
|
||||
#define ENGINE_PRIV_H
|
||||
|
||||
extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB];
|
||||
extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
||||
extern int16_t maskwall[MAXWALLSB], maskwallcnt;
|
||||
extern tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
|
||||
extern int32_t xdimen, xdimenscale, xdimscale, ydimen;
|
||||
|
@ -36,14 +34,6 @@ extern char inpreparemirror;
|
|||
extern int16_t sectorborder[256];
|
||||
extern int32_t hitallsprites;
|
||||
|
||||
extern int16_t bunchp2[MAXWALLSB];
|
||||
extern int16_t numscans, numbunches;
|
||||
|
||||
|
||||
// int32_t wallmost(int16_t *mostbuf, int32_t w, int32_t sectnum, char dastat);
|
||||
|
||||
void set_globalang(fixed_t const ang);
|
||||
|
||||
int32_t animateoffs(int tilenum, int fakevar);
|
||||
|
||||
static FORCE_INLINE int32_t bad_tspr(tspriteptr_t tspr)
|
||||
|
|
|
@ -22,6 +22,8 @@ Ken Silverman's official web site: http://www.advsys.net/ken
|
|||
#include "texturemanager.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "printf.h"
|
||||
#include "gamefuncs.h"
|
||||
#include "hw_drawinfo.h"
|
||||
|
||||
int skiptile = -1;
|
||||
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap);
|
||||
|
@ -38,6 +40,17 @@ CVARD(Float, hw_shadescale, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "multiplier
|
|||
|
||||
// For testing - will be removed later.
|
||||
CVAR(Int, skytile, 0, 0)
|
||||
CVAR(Bool, testnewrenderer, true, 0)
|
||||
|
||||
extern fixed_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms)
|
||||
static vec3_t spritesxyz[MAXSPRITESONSCREEN + 1];
|
||||
static int16_t thewall[MAXWALLSB];
|
||||
static int16_t bunchp2[MAXWALLSB], thesector[MAXWALLSB];
|
||||
static int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
||||
static float rollang;
|
||||
static int16_t numscans, numbunches;
|
||||
|
||||
|
||||
|
||||
namespace Polymost
|
||||
{
|
||||
|
@ -108,6 +121,27 @@ void polymost_outputGLDebugMessage(uint8_t severity, const char* format, ...)
|
|||
{
|
||||
}
|
||||
|
||||
static void set_globalang(fixed_t const ang)
|
||||
{
|
||||
globalang = FixedToInt(ang) & 2047;
|
||||
qglobalang = ang & 0x7FFFFFF;
|
||||
|
||||
float const f_ang = FixedToFloat(ang);
|
||||
float const fcosang = bcosf(f_ang);
|
||||
float const fsinang = bsinf(f_ang);
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
fcosglobalang = fcosang;
|
||||
fsinglobalang = fsinang;
|
||||
#endif
|
||||
|
||||
cosglobalang = (int)fcosang;
|
||||
singlobalang = (int)fsinang;
|
||||
|
||||
cosviewingrangeglobalang = MulScale(cosglobalang, viewingrange, 16);
|
||||
sinviewingrangeglobalang = MulScale(singlobalang, viewingrange, 16);
|
||||
}
|
||||
|
||||
static inline float polymost_invsqrt_approximation(float x)
|
||||
{
|
||||
// this is the comment
|
||||
|
@ -121,7 +155,7 @@ static float sectorVisibility(int sectnum)
|
|||
return v? ((uint8_t)(v + 16)) / 16.f : 1.f;
|
||||
}
|
||||
|
||||
template <typename T> static FORCE_INLINE void tileUpdatePicnum(T* const tileptr, int const obj)
|
||||
static void tileUpdatePicnum(short* const tileptr, int const obj)
|
||||
{
|
||||
auto& tile = *tileptr;
|
||||
|
||||
|
@ -3200,6 +3234,8 @@ _drawsprite_return:
|
|||
;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
static_assert((int)RS_YFLIP == (int)HUDFLAG_FLIPPED);
|
||||
|
||||
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
||||
|
@ -3209,9 +3245,9 @@ void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
|||
// basically this just means walls are repeating
|
||||
// while sprites are clamped
|
||||
|
||||
if ((dapalnum < (MAXPALOOKUPS - RESERVEDPALS)) && (!lookups.checkTable(dapalnum))) return;//dapalnum = 0;
|
||||
if ((dapalnum < (MAXPALOOKUPS - RESERVEDPALS)) && (!lookups.checkTable(dapalnum))) return;//dapalnum = 0;
|
||||
|
||||
//Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype);
|
||||
//Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype);
|
||||
hicprecaching = 1;
|
||||
int palid = TRANSLATION(Translation_Remap + curbasepal, dapalnum);
|
||||
auto tex = tileGetTexture(dapicnum);
|
||||
|
@ -3225,17 +3261,492 @@ void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
|||
|
||||
if (mid < 0 || models[mid]->mdnum < 2) return;
|
||||
|
||||
int const surfaces = (models[mid]->mdnum == 3) ? ((md3model_t *)models[mid])->head.numsurfs : 0;
|
||||
int const surfaces = (models[mid]->mdnum == 3) ? ((md3model_t*)models[mid])->head.numsurfs : 0;
|
||||
|
||||
for (int i = 0; i <= surfaces; i++)
|
||||
{
|
||||
auto tex = mdloadskin((md2model_t *)models[mid], 0, dapalnum, i, nullptr);
|
||||
{
|
||||
auto tex = mdloadskin((md2model_t*)models[mid], 0, dapalnum, i, nullptr);
|
||||
int palid = TRANSLATION(Translation_Remap + curbasepal, dapalnum);
|
||||
if (tex) GLInterface.SetTexture(tex, palid, CLAMP_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// preparemirror
|
||||
//
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall,
|
||||
int32_t* tposx, int32_t* tposy, fixed_t* tang)
|
||||
{
|
||||
const int32_t x = wall[dawall].x, dx = wall[wall[dawall].point2].x - x;
|
||||
const int32_t y = wall[dawall].y, dy = wall[wall[dawall].point2].y - y;
|
||||
|
||||
const int32_t j = dx * dx + dy * dy;
|
||||
if (j == 0)
|
||||
return;
|
||||
|
||||
int i = ((dax - x) * dx + (day - y) * dy) << 1;
|
||||
|
||||
*tposx = (x << 1) + Scale(dx, i, j) - dax;
|
||||
*tposy = (y << 1) + Scale(dy, i, j) - day;
|
||||
*tang = ((gethiq16angle(dx, dy) << 1) - daang) & 0x7FFFFFF;
|
||||
|
||||
inpreparemirror = 1;
|
||||
|
||||
Polymost::polymost_prepareMirror(dax, day, daz, daang, dahoriz, dawall);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// completemirror
|
||||
//
|
||||
void renderCompleteMirror(void)
|
||||
{
|
||||
Polymost::polymost_completeMirror();
|
||||
inpreparemirror = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// drawrooms
|
||||
//
|
||||
EXTERN_CVAR(Int, gl_fogmode)
|
||||
|
||||
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
|
||||
fixed_t daang, fixed_t dahoriz, int16_t dacursectnum)
|
||||
{
|
||||
checkRotatedWalls();
|
||||
|
||||
if (gl_fogmode == 1) gl_fogmode = 2; // only radial fog works with Build's screwed up coordinate system.
|
||||
|
||||
// Update starting sector number (common to classic and Polymost).
|
||||
// ADJUST_GLOBALCURSECTNUM.
|
||||
if (dacursectnum >= MAXSECTORS)
|
||||
dacursectnum -= MAXSECTORS;
|
||||
else
|
||||
{
|
||||
int i = dacursectnum;
|
||||
updatesector(daposx, daposy, &dacursectnum);
|
||||
if (dacursectnum < 0) dacursectnum = i;
|
||||
|
||||
// PK 20110123: I'm not sure what the line above is supposed to do, but 'i'
|
||||
// *can* be negative, so let's just quit here in that case...
|
||||
if (dacursectnum < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_globalpos(daposx, daposy, daposz);
|
||||
Polymost::set_globalang(daang);
|
||||
|
||||
global100horiz = dahoriz;
|
||||
|
||||
memset(gotsector, 0, sizeof(gotsector));
|
||||
qglobalhoriz = MulScale(dahoriz, DivScale(xdimenscale, viewingrange, 16), 16) + IntToFixed(ydimen >> 1);
|
||||
globalcursectnum = dacursectnum;
|
||||
Polymost::polymost_drawrooms();
|
||||
return inpreparemirror;
|
||||
}
|
||||
|
||||
// UTILITY TYPES AND FUNCTIONS FOR DRAWMASKS OCCLUSION TREE
|
||||
// typedef struct s_maskleaf
|
||||
// {
|
||||
// int32_t index;
|
||||
// _point2d p1, p2;
|
||||
// _equation maskeq, p1eq, p2eq;
|
||||
// struct s_maskleaf* branch[MAXWALLSB];
|
||||
// int32_t drawing;
|
||||
// } _maskleaf;
|
||||
//
|
||||
// _maskleaf maskleaves[MAXWALLSB];
|
||||
|
||||
// returns equation of a line given two points
|
||||
static inline _equation equation(float const x1, float const y1, float const x2, float const y2)
|
||||
{
|
||||
const float f = x2 - x1;
|
||||
|
||||
// vertical
|
||||
if (f == 0.f)
|
||||
return { 1, 0, -x1 };
|
||||
else
|
||||
{
|
||||
float const ff = (y2 - y1) / f;
|
||||
return { ff, -1, (y1 - (ff * x1)) };
|
||||
}
|
||||
}
|
||||
|
||||
static inline int32_t sameside(const _equation* eq, const vec2f_t* p1, const vec2f_t* p2)
|
||||
{
|
||||
const float sign1 = (eq->a * p1->x) + (eq->b * p1->y) + eq->c;
|
||||
const float sign2 = (eq->a * p2->x) + (eq->b * p2->y) + eq->c;
|
||||
return (sign1 * sign2) > 0.f;
|
||||
}
|
||||
|
||||
|
||||
static inline int comparetsprites(int const k, int const l)
|
||||
{
|
||||
if ((tspriteptr[k]->cstat & 48) != (tspriteptr[l]->cstat & 48))
|
||||
return (tspriteptr[k]->cstat & 48) - (tspriteptr[l]->cstat & 48);
|
||||
|
||||
if ((tspriteptr[k]->cstat & 48) == 16 && tspriteptr[k]->ang != tspriteptr[l]->ang)
|
||||
return tspriteptr[k]->ang - tspriteptr[l]->ang;
|
||||
|
||||
if (tspriteptr[k]->statnum != tspriteptr[l]->statnum)
|
||||
return tspriteptr[k]->statnum - tspriteptr[l]->statnum;
|
||||
|
||||
if (tspriteptr[k]->x == tspriteptr[l]->x &&
|
||||
tspriteptr[k]->y == tspriteptr[l]->y &&
|
||||
tspriteptr[k]->z == tspriteptr[l]->z &&
|
||||
(tspriteptr[k]->cstat & 48) == (tspriteptr[l]->cstat & 48) &&
|
||||
tspriteptr[k]->owner != tspriteptr[l]->owner)
|
||||
return tspriteptr[k]->owner - tspriteptr[l]->owner;
|
||||
|
||||
if (abs(spritesxyz[k].z - globalposz) != abs(spritesxyz[l].z - globalposz))
|
||||
return abs(spritesxyz[k].z - globalposz) - abs(spritesxyz[l].z - globalposz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sortsprites(int const start, int const end)
|
||||
{
|
||||
int32_t i, gap, y, ys;
|
||||
|
||||
if (start >= end)
|
||||
return;
|
||||
|
||||
gap = 1; while (gap < end - start) gap = (gap << 1) + 1;
|
||||
for (gap >>= 1; gap > 0; gap >>= 1) //Sort sprite list
|
||||
for (i = start; i < end - gap; i++)
|
||||
for (bssize_t l = i; l >= start; l -= gap)
|
||||
{
|
||||
if (spritesxyz[l].y <= spritesxyz[l + gap].y) break;
|
||||
std::swap(tspriteptr[l], tspriteptr[l + gap]);
|
||||
std::swap(spritesxyz[l].x, spritesxyz[l + gap].x);
|
||||
std::swap(spritesxyz[l].y, spritesxyz[l + gap].y);
|
||||
}
|
||||
|
||||
ys = spritesxyz[start].y; i = start;
|
||||
for (bssize_t j = start + 1; j <= end; j++)
|
||||
{
|
||||
if (j < end)
|
||||
{
|
||||
y = spritesxyz[j].y;
|
||||
if (y == ys)
|
||||
continue;
|
||||
|
||||
ys = y;
|
||||
}
|
||||
|
||||
if (j > i + 1)
|
||||
{
|
||||
for (bssize_t k = i; k < j; k++)
|
||||
{
|
||||
auto const s = tspriteptr[k];
|
||||
|
||||
spritesxyz[k].z = s->z;
|
||||
if ((s->cstat & 48) != 32)
|
||||
{
|
||||
int32_t yoff = tileTopOffset(s->picnum) + s->yoffset;
|
||||
int32_t yspan = (tileHeight(s->picnum) * s->yrepeat << 2);
|
||||
|
||||
spritesxyz[k].z -= (yoff * s->yrepeat) << 2;
|
||||
|
||||
if (!(s->cstat & 128))
|
||||
spritesxyz[k].z -= (yspan >> 1);
|
||||
if (abs(spritesxyz[k].z - globalposz) < (yspan >> 1))
|
||||
spritesxyz[k].z = globalposz;
|
||||
}
|
||||
}
|
||||
|
||||
for (bssize_t k = i + 1; k < j; k++)
|
||||
for (bssize_t l = i; l < k; l++)
|
||||
if (comparetsprites(k, l) < 0)
|
||||
{
|
||||
std::swap(tspriteptr[k], tspriteptr[l]);
|
||||
vec3_t tv3 = spritesxyz[k];
|
||||
spritesxyz[k] = spritesxyz[l];
|
||||
spritesxyz[l] = tv3;
|
||||
}
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// drawmasks
|
||||
//
|
||||
void renderDrawMasks(void)
|
||||
{
|
||||
# define debugmask_add(dispidx, idx) do {} while (0)
|
||||
int32_t i = spritesortcnt - 1;
|
||||
int32_t numSprites = spritesortcnt;
|
||||
|
||||
spritesortcnt = 0;
|
||||
int32_t back = i;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (Polymost::polymost_spriteHasTranslucency(&tsprite[i]))
|
||||
{
|
||||
tspriteptr[spritesortcnt] = &tsprite[i];
|
||||
++spritesortcnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
tspriteptr[back] = &tsprite[i];
|
||||
--back;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = numSprites - 1; i >= 0; --i)
|
||||
{
|
||||
const int32_t xs = tspriteptr[i]->x - globalposx, ys = tspriteptr[i]->y - globalposy;
|
||||
const int32_t yp = DMulScale(xs, cosviewingrangeglobalang, ys, sinviewingrangeglobalang, 6);
|
||||
const int32_t modelp = spriteIsModelOrVoxel(tspriteptr[i]);
|
||||
|
||||
if (yp > (4 << 8))
|
||||
{
|
||||
const int32_t xp = DMulScale(ys, cosglobalang, -xs, singlobalang, 6);
|
||||
|
||||
if (MulScale(labs(xp + yp), xdimen, 24) >= yp)
|
||||
goto killsprite;
|
||||
|
||||
spritesxyz[i].x = Scale(xp + yp, xdimen << 7, yp);
|
||||
}
|
||||
else if ((tspriteptr[i]->cstat & 48) == 0)
|
||||
{
|
||||
killsprite:
|
||||
if (!modelp)
|
||||
{
|
||||
//Delete face sprite if on wrong side!
|
||||
if (i >= spritesortcnt)
|
||||
{
|
||||
--numSprites;
|
||||
if (i != numSprites)
|
||||
{
|
||||
tspriteptr[i] = tspriteptr[numSprites];
|
||||
spritesxyz[i].x = spritesxyz[numSprites].x;
|
||||
spritesxyz[i].y = spritesxyz[numSprites].y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
--numSprites;
|
||||
--spritesortcnt;
|
||||
if (i != numSprites)
|
||||
{
|
||||
tspriteptr[i] = tspriteptr[spritesortcnt];
|
||||
spritesxyz[i].x = spritesxyz[spritesortcnt].x;
|
||||
spritesxyz[i].y = spritesxyz[spritesortcnt].y;
|
||||
tspriteptr[spritesortcnt] = tspriteptr[numSprites];
|
||||
spritesxyz[spritesortcnt].x = spritesxyz[numSprites].x;
|
||||
spritesxyz[spritesortcnt].y = spritesxyz[numSprites].y;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
spritesxyz[i].y = yp;
|
||||
}
|
||||
|
||||
sortsprites(0, spritesortcnt);
|
||||
sortsprites(spritesortcnt, numSprites);
|
||||
renderBeginScene();
|
||||
|
||||
GLInterface.EnableBlend(false);
|
||||
GLInterface.EnableAlphaTest(true);
|
||||
GLInterface.SetDepthBias(-2, -256);
|
||||
|
||||
if (spritesortcnt < numSprites)
|
||||
{
|
||||
i = spritesortcnt;
|
||||
for (bssize_t i = spritesortcnt; i < numSprites;)
|
||||
{
|
||||
int32_t py = spritesxyz[i].y;
|
||||
int32_t pcstat = tspriteptr[i]->cstat & 48;
|
||||
int32_t pangle = tspriteptr[i]->ang;
|
||||
int j = i + 1;
|
||||
if (!spriteIsModelOrVoxel(tspriteptr[i]))
|
||||
{
|
||||
while (j < numSprites && py == spritesxyz[j].y && pcstat == (tspriteptr[j]->cstat & 48) && (pcstat != 16 || pangle == tspriteptr[j]->ang)
|
||||
&& !spriteIsModelOrVoxel(tspriteptr[j]))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j - i == 1)
|
||||
{
|
||||
debugmask_add(i | 32768, tspriteptr[i]->owner);
|
||||
Polymost::polymost_drawsprite(i);
|
||||
tspriteptr[i] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
GLInterface.SetDepthMask(false);
|
||||
|
||||
for (bssize_t k = j - 1; k >= i; k--)
|
||||
{
|
||||
debugmask_add(k | 32768, tspriteptr[k]->owner);
|
||||
Polymost::polymost_drawsprite(k);
|
||||
}
|
||||
|
||||
GLInterface.SetDepthMask(true);
|
||||
|
||||
GLInterface.SetColorMask(false);
|
||||
|
||||
for (bssize_t k = j - 1; k >= i; k--)
|
||||
{
|
||||
Polymost::polymost_drawsprite(k);
|
||||
tspriteptr[k] = NULL;
|
||||
}
|
||||
|
||||
GLInterface.SetColorMask(true);
|
||||
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t numMaskWalls = maskwallcnt;
|
||||
maskwallcnt = 0;
|
||||
for (i = 0; i < numMaskWalls; i++)
|
||||
{
|
||||
if (Polymost::polymost_maskWallHasTranslucency((uwalltype*)&wall[thewall[maskwall[i]]]))
|
||||
{
|
||||
maskwall[maskwallcnt] = maskwall[i];
|
||||
maskwallcnt++;
|
||||
}
|
||||
else
|
||||
Polymost::polymost_drawmaskwall(i);
|
||||
}
|
||||
|
||||
GLInterface.EnableBlend(true);
|
||||
GLInterface.EnableAlphaTest(true);
|
||||
GLInterface.SetDepthMask(false);
|
||||
|
||||
vec2f_t pos;
|
||||
|
||||
pos.x = fglobalposx;
|
||||
pos.y = fglobalposy;
|
||||
|
||||
// CAUTION: maskwallcnt and spritesortcnt may be zero!
|
||||
// Writing e.g. "while (maskwallcnt--)" is wrong!
|
||||
while (maskwallcnt)
|
||||
{
|
||||
// PLAG: sorting stuff
|
||||
const int32_t w = thewall[maskwall[maskwallcnt - 1]];
|
||||
|
||||
maskwallcnt--;
|
||||
|
||||
vec2f_t dot = { (float)wall[w].x, (float)wall[w].y };
|
||||
vec2f_t dot2 = { (float)wall[wall[w].point2].x, (float)wall[wall[w].point2].y };
|
||||
vec2f_t middle = { (dot.x + dot2.x) * .5f, (dot.y + dot2.y) * .5f };
|
||||
|
||||
_equation maskeq = equation(dot.x, dot.y, dot2.x, dot2.y);
|
||||
_equation p1eq = equation(pos.x, pos.y, dot.x, dot.y);
|
||||
_equation p2eq = equation(pos.x, pos.y, dot2.x, dot2.y);
|
||||
|
||||
i = spritesortcnt;
|
||||
while (i)
|
||||
{
|
||||
i--;
|
||||
if (tspriteptr[i] != NULL)
|
||||
{
|
||||
vec2f_t spr;
|
||||
auto const tspr = tspriteptr[i];
|
||||
|
||||
spr.x = (float)tspr->x;
|
||||
spr.y = (float)tspr->y;
|
||||
|
||||
if (!sameside(&maskeq, &spr, &pos))
|
||||
{
|
||||
// Sprite and camera are on different sides of the
|
||||
// masked wall.
|
||||
|
||||
// Check if the sprite is inside the 'cone' given by
|
||||
// the rays from the camera to the two wall-points.
|
||||
const int32_t inleft = sameside(&p1eq, &middle, &spr);
|
||||
const int32_t inright = sameside(&p2eq, &middle, &spr);
|
||||
|
||||
int32_t ok = (inleft && inright);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
// If not, check if any of the border points are...
|
||||
vec2_t pp[4];
|
||||
int32_t numpts, jj;
|
||||
|
||||
const _equation pineq = inleft ? p1eq : p2eq;
|
||||
|
||||
if ((tspr->cstat & 48) == 32)
|
||||
{
|
||||
numpts = 4;
|
||||
GetFlatSpritePosition(tspr, tspr->pos.vec2, pp);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int32_t oang = tspr->ang;
|
||||
numpts = 2;
|
||||
|
||||
// Consider face sprites as wall sprites with camera ang.
|
||||
// XXX: factor 4/5 needed?
|
||||
if ((tspr->cstat & 48) != 16)
|
||||
tspriteptr[i]->ang = globalang;
|
||||
|
||||
GetWallSpritePosition(tspr, tspr->pos.vec2, pp);
|
||||
|
||||
if ((tspr->cstat & 48) != 16)
|
||||
tspriteptr[i]->ang = oang;
|
||||
}
|
||||
|
||||
for (jj = 0; jj < numpts; jj++)
|
||||
{
|
||||
spr.x = (float)pp[jj].x;
|
||||
spr.y = (float)pp[jj].y;
|
||||
|
||||
if (!sameside(&maskeq, &spr, &pos)) // behind the maskwall,
|
||||
if ((sameside(&p1eq, &middle, &spr) && // inside the 'cone',
|
||||
sameside(&p2eq, &middle, &spr))
|
||||
|| !sameside(&pineq, &middle, &spr)) // or on the other outside.
|
||||
{
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
debugmask_add(i | 32768, tspr->owner);
|
||||
Polymost::polymost_drawsprite(i);
|
||||
|
||||
tspriteptr[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debugmask_add(maskwall[maskwallcnt], thewall[maskwall[maskwallcnt]]);
|
||||
Polymost::polymost_drawmaskwall(maskwallcnt);
|
||||
}
|
||||
|
||||
while (spritesortcnt)
|
||||
{
|
||||
--spritesortcnt;
|
||||
if (tspriteptr[spritesortcnt] != NULL)
|
||||
{
|
||||
debugmask_add(i | 32768, tspriteptr[i]->owner);
|
||||
Polymost::polymost_drawsprite(spritesortcnt);
|
||||
tspriteptr[spritesortcnt] = NULL;
|
||||
}
|
||||
}
|
||||
renderFinishScene();
|
||||
GLInterface.SetDepthMask(true);
|
||||
GLInterface.SetDepthBias(0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PrecacheHardwareTextures(int nTile)
|
||||
{
|
||||
// PRECACHE
|
||||
|
@ -3243,3 +3754,28 @@ void PrecacheHardwareTextures(int nTile)
|
|||
Polymost::polymost_precache(nTile, 0, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// setrollangle
|
||||
//
|
||||
void renderSetRollAngle(float rolla)
|
||||
{
|
||||
Polymost::gtang = rolla * BAngRadian;
|
||||
rollang = rolla * (BAngRadian * 180 / pi::pif());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -570,7 +570,7 @@ int GameMain()
|
|||
TileFiles.CloseAll(); // delete the texture data before shutting down graphics.
|
||||
GLInterface.Deinit();
|
||||
I_ShutdownGraphics();
|
||||
engineUnInit();
|
||||
freeallmodels();
|
||||
if (gi)
|
||||
{
|
||||
delete gi;
|
||||
|
|
|
@ -262,7 +262,7 @@ void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// Check if some walls are set to be rotated textures.
|
||||
// Check if some walls are set to use rotated textures.
|
||||
// Ideally this should just have been done with texture rotation,
|
||||
// but the effects on the render code would be too severe due to the alignment mess.
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue