2006-04-13 20:47:06 +00:00
|
|
|
/**************************************************************************************************
|
2015-02-11 05:23:04 +00:00
|
|
|
"POLYMOST" code originally written by Ken Silverman
|
2006-04-13 20:47:06 +00:00
|
|
|
Ken Silverman's official web site: http://www.advsys.net/ken
|
2018-02-16 06:38:34 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
**************************************************************************************************/
|
|
|
|
|
2008-12-02 10:44:39 +00:00
|
|
|
|
|
|
|
#include "build.h"
|
2020-09-06 10:44:58 +00:00
|
|
|
#include "automap.h"
|
2008-12-02 10:44:39 +00:00
|
|
|
#include "engine_priv.h"
|
2019-03-19 17:09:16 +00:00
|
|
|
#include "mdsprite.h"
|
|
|
|
#include "polymost.h"
|
2019-10-04 21:29:00 +00:00
|
|
|
#include "files.h"
|
2020-05-24 05:58:56 +00:00
|
|
|
#include "buildtiles.h"
|
2019-10-05 19:59:03 +00:00
|
|
|
#include "bitmap.h"
|
2019-09-16 17:35:04 +00:00
|
|
|
#include "../../glbackend/glbackend.h"
|
2019-10-23 19:11:37 +00:00
|
|
|
#include "c_cvars.h"
|
|
|
|
#include "gamecvars.h"
|
2020-01-18 21:41:08 +00:00
|
|
|
#include "v_video.h"
|
|
|
|
#include "flatvertices.h"
|
2020-04-12 05:50:24 +00:00
|
|
|
#include "palettecontainer.h"
|
2020-05-24 21:26:47 +00:00
|
|
|
#include "texturemanager.h"
|
2020-05-31 08:24:04 +00:00
|
|
|
#include "hw_renderstate.h"
|
2020-08-28 07:06:49 +00:00
|
|
|
#include "printf.h"
|
2019-10-23 19:11:37 +00:00
|
|
|
|
|
|
|
CVAR(Bool, hw_detailmapping, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|
|
|
CVAR(Bool, hw_glowmapping, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|
|
|
CVARD(Bool, hw_animsmoothing, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable model animation smoothing")
|
2020-02-04 19:40:10 +00:00
|
|
|
CVARD(Bool, hw_hightile, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable hightile texture rendering")
|
2020-04-13 11:21:46 +00:00
|
|
|
CVARD(Bool, hw_models, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable model rendering")
|
2019-10-23 19:11:37 +00:00
|
|
|
CVARD(Bool, hw_parallaxskypanning, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable parallaxed floor/ceiling panning when drawing a parallaxing sky")
|
|
|
|
CVARD(Bool, hw_shadeinterpolate, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable shade interpolation")
|
|
|
|
CVARD(Float, hw_shadescale, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "multiplier for shading")
|
2020-02-04 19:40:10 +00:00
|
|
|
bool hw_int_useindexedcolortextures;
|
|
|
|
CUSTOM_CVARD(Bool, hw_useindexedcolortextures, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable indexed color texture rendering")
|
|
|
|
{
|
|
|
|
hw_int_useindexedcolortextures = self;
|
|
|
|
}
|
2019-10-23 19:11:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
//{ "r_yshearing", "enable/disable y-shearing", (void*)&r_yshearing, CVAR_BOOL, 0, 1 }, disabled because not fully functional
|
|
|
|
|
|
|
|
// For testing - will be removed later.
|
|
|
|
CVAR(Int, skytile, 0, 0)
|
2019-10-10 21:29:13 +00:00
|
|
|
|
2011-09-04 19:44:07 +00:00
|
|
|
typedef struct { float x, cy[2], fy[2]; int32_t tag; int16_t n, p, ctag, ftag; } vsptyp;
|
2017-11-30 23:54:18 +00:00
|
|
|
#define VSPMAX 2048 //<- careful!
|
2006-04-13 20:47:06 +00:00
|
|
|
static vsptyp vsp[VSPMAX];
|
2019-06-25 18:35:19 +00:00
|
|
|
static int32_t gtag, viewportNodeCount;
|
2019-03-19 17:07:53 +00:00
|
|
|
static float xbl, xbr, xbt, xbb;
|
2020-01-28 21:21:53 +00:00
|
|
|
static int32_t domost_rejectcount;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-09-30 04:06:05 +00:00
|
|
|
static float dxb1[MAXWALLSB], dxb2[MAXWALLSB];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-07-05 21:17:54 +00:00
|
|
|
//POGOTODO: the SCISDIST could be set to 0 now to allow close objects to render properly,
|
|
|
|
// but there's a nasty rendering bug that needs to be dug into when setting SCISDIST lower than 1
|
|
|
|
#define SCISDIST 1.f //close plane clipping distance
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-03-19 17:08:39 +00:00
|
|
|
#define SOFTROTMAT 0
|
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static int32_t r_pogoDebug = 0;
|
2011-07-24 15:15:57 +00:00
|
|
|
|
2014-09-30 04:06:05 +00:00
|
|
|
static float gviewxrange;
|
2019-09-19 20:02:45 +00:00
|
|
|
static float ghoriz, ghoriz2;
|
|
|
|
static float ghorizcorrect;
|
2019-03-19 17:08:05 +00:00
|
|
|
double gxyaspect;
|
2019-09-19 20:02:45 +00:00
|
|
|
float gyxscale, ghalfx, grhalfxdown10, grhalfxdown10x, ghalfy;
|
2014-09-30 04:06:05 +00:00
|
|
|
float gcosang, gsinang, gcosang2, gsinang2;
|
|
|
|
float gtang = 0.f;
|
2020-01-19 12:57:24 +00:00
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static float gchang = 0, gshang = 0, gctang = 0, gstang = 0;
|
|
|
|
static float gvrcorrection = 1.f;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-03-19 17:08:43 +00:00
|
|
|
static vec3d_t xtex, ytex, otex, xtex2, ytex2, otex2;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static float fsearchx, fsearchy, fsearchz;
|
|
|
|
static int psectnum, pwallnum, pbottomwall, pisbottomwall, psearchstat;
|
2010-09-06 23:08:35 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
static int32_t drawpoly_srepeat = 0, drawpoly_trepeat = 0;
|
2018-02-16 06:37:58 +00:00
|
|
|
#define MAX_DRAWPOLY_VERTS 8
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2015-02-11 05:23:04 +00:00
|
|
|
static int32_t lastglpolygonmode = 0; //FUK
|
2019-09-17 18:18:18 +00:00
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static int32_t r_yshearing = 0;
|
2019-09-19 20:02:45 +00:00
|
|
|
|
2009-04-16 06:41:24 +00:00
|
|
|
// used for fogcalc
|
2015-03-24 00:40:48 +00:00
|
|
|
static float fogresult, fogresult2;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static char ptempbuf[MAXWALLSB<<1];
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2008-09-12 02:07:44 +00:00
|
|
|
// polymost ART sky control
|
2020-01-28 21:21:53 +00:00
|
|
|
static int32_t r_parallaxskyclamping = 1;
|
2008-09-12 02:07:44 +00:00
|
|
|
|
2011-09-28 20:30:24 +00:00
|
|
|
#define MIN_CACHETIME_PRINT 10
|
2011-01-30 11:02:28 +00:00
|
|
|
|
2019-09-13 19:43:05 +00:00
|
|
|
|
|
|
|
|
2014-10-25 03:34:25 +00:00
|
|
|
#define Bfabsf fabsf
|
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static int32_t drawingskybox = 0;
|
|
|
|
static int32_t hicprecaching = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static hitdata_t polymost_hitdata;
|
2015-07-08 03:34:27 +00:00
|
|
|
|
2019-05-25 14:59:09 +00:00
|
|
|
void polymost_outputGLDebugMessage(uint8_t severity, const char* format, ...)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-05 17:06:31 +00:00
|
|
|
float sectorVisibility(int sectnum)
|
|
|
|
{
|
|
|
|
// Beware of wraparound madness...
|
|
|
|
int v = sector[sectnum].visibility;
|
|
|
|
return v? ((uint8_t)(v + 16)) / 16.f : 1.f;
|
|
|
|
}
|
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2013-05-15 02:17:17 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//Use this for both initialization and uninitialization of OpenGL.
|
2010-05-25 10:56:00 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
//in-place multiply m0=m0*m1
|
2020-01-28 21:21:53 +00:00
|
|
|
static float* multiplyMatrix4f(float m0[4*4], const float m1[4*4])
|
2018-02-16 06:38:34 +00:00
|
|
|
{
|
|
|
|
float mR[4*4];
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
#define multMatrix4RowCol(r, c) mR[r*4+c] = m0[r*4]*m1[c] + m0[r*4+1]*m1[c+4] + m0[r*4+2]*m1[c+8] + m0[r*4+3]*m1[c+12]
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
multMatrix4RowCol(0, 0);
|
|
|
|
multMatrix4RowCol(0, 1);
|
|
|
|
multMatrix4RowCol(0, 2);
|
|
|
|
multMatrix4RowCol(0, 3);
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
multMatrix4RowCol(1, 0);
|
|
|
|
multMatrix4RowCol(1, 1);
|
|
|
|
multMatrix4RowCol(1, 2);
|
|
|
|
multMatrix4RowCol(1, 3);
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
multMatrix4RowCol(2, 0);
|
|
|
|
multMatrix4RowCol(2, 1);
|
|
|
|
multMatrix4RowCol(2, 2);
|
|
|
|
multMatrix4RowCol(2, 3);
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
multMatrix4RowCol(3, 0);
|
|
|
|
multMatrix4RowCol(3, 1);
|
|
|
|
multMatrix4RowCol(3, 2);
|
|
|
|
multMatrix4RowCol(3, 3);
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2020-09-08 16:48:18 +00:00
|
|
|
memcpy(m0, mR, sizeof(float)*4*4);
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
return m0;
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
#undef multMatrix4RowCol
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
void polymost_glreset()
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
//Reset if this is -1 (meaning 1st texture call ever), or > 0 (textures in memory)
|
2020-05-28 21:48:50 +00:00
|
|
|
gcosang = gcosang2 = 16384.f/262144.f;
|
|
|
|
gsinang = gsinang2 = 0.f;
|
2007-01-06 01:29:45 +00:00
|
|
|
}
|
2006-12-31 06:32:04 +00:00
|
|
|
|
2019-10-04 21:29:00 +00:00
|
|
|
FileReader GetBaseResource(const char* fn);
|
|
|
|
|
2012-10-01 17:52:25 +00:00
|
|
|
static void resizeglcheck(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2020-02-09 14:51:16 +00:00
|
|
|
const int32_t ourxdimen = (windowxy2.x-windowxy1.x+1);
|
|
|
|
float ratio = 1;
|
|
|
|
const int32_t fovcorrect = (int32_t)(ourxdimen*ratio - ourxdimen);
|
|
|
|
|
|
|
|
ratio = 1.f/ratio;
|
|
|
|
|
|
|
|
GLInterface.SetViewport(windowxy1.x-(fovcorrect/2), ydim-(windowxy2.y+1),
|
|
|
|
ourxdimen+fovcorrect, windowxy2.y-windowxy1.y+1);
|
|
|
|
|
|
|
|
float m[4][4]{};
|
|
|
|
|
2020-06-01 07:55:28 +00:00
|
|
|
float const nearclip = 4.0f / (gxyaspect * gyxscale);
|
|
|
|
float const farclip = 65536.f;
|
2020-02-09 14:51:16 +00:00
|
|
|
|
|
|
|
m[0][0] = 1.f;
|
|
|
|
m[1][1] = fxdimen / (fydimen * ratio);
|
|
|
|
m[2][0] = 2.f * ghoriz2 * gstang / fxdimen;
|
|
|
|
m[2][1] = 2.f * (ghoriz2 * gctang + ghorizcorrect) / fydimen;
|
|
|
|
m[2][2] = (farclip + nearclip) / (farclip - nearclip);
|
|
|
|
m[2][3] = 1.f;
|
|
|
|
m[3][2] = -(2.f * farclip * nearclip) / (farclip - nearclip);
|
2020-06-04 16:46:44 +00:00
|
|
|
renderSetProjectionMatrix(&m[0][0]);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//(dpx,dpy) specifies an n-sided polygon. The polygon must be a convex clockwise loop.
|
|
|
|
// n must be <= 8 (assume clipping can double number of vertices)
|
|
|
|
//method: 0:solid, 1:masked(255 is transparent), 2:transluscent #1, 3:transluscent #2
|
|
|
|
// +4 means it's a sprite, so wraparound isn't needed
|
2013-03-04 01:23:29 +00:00
|
|
|
|
|
|
|
// drawpoly's hack globals
|
2019-09-03 04:09:25 +00:00
|
|
|
static int32_t pow2xsplit = 0, skyclamphack = 0, skyzbufferhack = 0, flatskyrender = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
static float drawpoly_alpha = 0.f;
|
2016-10-09 07:55:23 +00:00
|
|
|
static uint8_t drawpoly_blend = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-04-19 21:45:22 +00:00
|
|
|
int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall)
|
|
|
|
{
|
|
|
|
if (wall->cstat & CSTAT_WALL_TRANSLUCENT)
|
|
|
|
return true;
|
|
|
|
|
2020-05-24 13:02:20 +00:00
|
|
|
auto tex = tileGetTexture(wall->picnum);
|
2020-05-24 06:47:45 +00:00
|
|
|
auto si = TileFiles.FindReplacement(wall->picnum, wall->pal);
|
2019-10-23 19:11:37 +00:00
|
|
|
if (si && hw_hightile) tex = si->faces[0];
|
2020-05-24 06:47:45 +00:00
|
|
|
if (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
|
2019-10-10 21:29:13 +00:00
|
|
|
return tex && tex->GetTranslucency();
|
2019-04-19 21:45:22 +00:00
|
|
|
}
|
|
|
|
|
2019-12-26 06:27:48 +00:00
|
|
|
int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr)
|
2019-04-19 21:45:22 +00:00
|
|
|
{
|
2019-12-26 06:28:08 +00:00
|
|
|
if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || (tspr->clipdist & TSPR_FLAGS_DRAW_LAST) ||
|
2019-05-27 05:45:45 +00:00
|
|
|
((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha))
|
2019-04-19 21:45:22 +00:00
|
|
|
return true;
|
|
|
|
|
2020-05-24 13:02:20 +00:00
|
|
|
auto tex = tileGetTexture(tspr->picnum);
|
2020-05-24 06:47:45 +00:00
|
|
|
auto si = TileFiles.FindReplacement(tspr->picnum, tspr->shade, 0);
|
2019-10-23 19:11:37 +00:00
|
|
|
if (si && hw_hightile) tex = si->faces[0];
|
2020-05-23 22:38:10 +00:00
|
|
|
if (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
|
|
|
|
return tex && tex->GetTranslucency();
|
2019-04-19 21:45:22 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
int32_t polymost_spriteIsModelOrVoxel(tspritetype const * const tspr)
|
|
|
|
{
|
2020-03-12 22:07:38 +00:00
|
|
|
if ((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].flags&SPREXT_NOTMD)
|
2020-02-02 20:06:21 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
if (hw_models && tile2model[Ptile2tile(tspr->picnum, tspr->pal)].modelid >= 0 &&
|
|
|
|
tile2model[Ptile2tile(tspr->picnum, tspr->pal)].framenum >= 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (r_voxels && (tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLAB && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]])
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB && voxmodels[tspr->picnum])
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2018-02-16 06:38:34 +00:00
|
|
|
|
2019-03-19 17:08:39 +00:00
|
|
|
static void polymost_updaterotmat(void)
|
|
|
|
{
|
2020-01-19 12:57:24 +00:00
|
|
|
//Up/down rotation
|
|
|
|
float matrix[16] = {
|
|
|
|
1.f, 0.f, 0.f, 0.f,
|
|
|
|
0.f, gchang, -gshang*gvrcorrection, 0.f,
|
|
|
|
0.f, gshang/gvrcorrection, gchang, 0.f,
|
|
|
|
0.f, 0.f, 0.f, 1.f,
|
|
|
|
};
|
|
|
|
// Tilt rotation
|
|
|
|
float tiltmatrix[16] = {
|
|
|
|
gctang, -gstang, 0.f, 0.f,
|
|
|
|
gstang, gctang, 0.f, 0.f,
|
|
|
|
0.f, 0.f, 1.f, 0.f,
|
|
|
|
0.f, 0.f, 0.f, 1.f,
|
|
|
|
};
|
|
|
|
multiplyMatrix4f(matrix, tiltmatrix);
|
2020-06-04 16:46:44 +00:00
|
|
|
renderSetViewMatrix(matrix);
|
2020-07-03 07:38:42 +00:00
|
|
|
renderSetVisibility(mulscale16(g_visibility, mulscale16(xdimenscale, viewingrangerecip)) * fviewingrange * (1.f / (65536.f * 65536.f)) / r_ambientlight);
|
2019-03-19 17:08:39 +00:00
|
|
|
}
|
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, int32_t method, const vec2_16_t& tilesiz);
|
2019-09-03 04:09:25 +00:00
|
|
|
|
2020-05-28 22:44:13 +00:00
|
|
|
// Hack for Duke's camera until I can find out why this behaves erratically.
|
|
|
|
int skiptile = -1;
|
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesize)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2020-05-28 22:44:13 +00:00
|
|
|
if (method == DAMETH_BACKFACECULL || globalpicnum == skiptile ||
|
2016-06-21 00:34:18 +00:00
|
|
|
(uint32_t)globalpicnum >= MAXTILES)
|
|
|
|
return;
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
const int32_t method_ = method;
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (n == 3)
|
|
|
|
{
|
2014-10-25 03:33:26 +00:00
|
|
|
if ((dpxy[0].x-dpxy[1].x) * (dpxy[2].y-dpxy[1].y) >=
|
|
|
|
(dpxy[2].x-dpxy[1].x) * (dpxy[0].y-dpxy[1].y)) return; //for triangle
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2019-06-25 18:35:19 +00:00
|
|
|
else if (n > 3)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
float f = 0; //f is area of polygon / 2
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=n-2, j=n-1,k=0; k<n; i=j,j=k,k++)
|
2014-10-25 03:33:26 +00:00
|
|
|
f += (dpxy[i].x-dpxy[k].x)*dpxy[j].y;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (f <= 0) return;
|
|
|
|
}
|
|
|
|
|
2019-09-03 04:09:25 +00:00
|
|
|
static int32_t skyzbufferhack_pass = 0;
|
2020-04-11 22:21:35 +00:00
|
|
|
|
2019-09-03 04:09:25 +00:00
|
|
|
if (flatskyrender && skyzbufferhack_pass == 0)
|
|
|
|
{
|
2019-10-19 17:29:59 +00:00
|
|
|
polymost_flatskyrender(dpxy, n, method|DAMETH_SKY, tilesize);
|
2019-09-03 04:09:25 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-05-27 20:19:02 +00:00
|
|
|
if (!lookups.checkTable(globalpal))
|
2020-09-20 18:39:11 +00:00
|
|
|
globalfloorpal = globalpal = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//Load texture (globalpicnum)
|
|
|
|
setgotpic(globalpicnum);
|
2019-10-11 19:04:31 +00:00
|
|
|
vec2_t tsiz = { tilesize.x, tilesize.y };
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2020-08-30 21:34:40 +00:00
|
|
|
assert(n <= MAX_DRAWPOLY_VERTS);
|
2015-07-08 03:34:20 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int j = 0;
|
|
|
|
float px[8], py[8], dd[8], uu[8], vv[8];
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=0; i<n; ++i)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-03-19 17:08:39 +00:00
|
|
|
px[j] = dpxy[i].x;
|
|
|
|
py[j] = dpxy[i].y;
|
|
|
|
|
|
|
|
dd[j] = (dpxy[i].x * xtex.d + dpxy[i].y * ytex.d + otex.d);
|
2019-08-04 02:52:06 +00:00
|
|
|
if (dd[j] <= 0.f) // invalid polygon
|
|
|
|
return;
|
2019-03-19 17:08:39 +00:00
|
|
|
uu[j] = (dpxy[i].x * xtex.u + dpxy[i].y * ytex.u + otex.u);
|
|
|
|
vv[j] = (dpxy[i].x * xtex.v + dpxy[i].y * ytex.v + otex.v);
|
|
|
|
j++;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
while ((j >= 3) && (px[j-1] == px[0]) && (py[j-1] == py[0])) j--;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (j < 3)
|
|
|
|
return;
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int const npoints = j;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2020-01-26 12:45:33 +00:00
|
|
|
float usub = 0;
|
|
|
|
float vsub = 0;
|
2020-06-07 08:14:32 +00:00
|
|
|
#if 0
|
2020-01-26 12:45:33 +00:00
|
|
|
if (skyclamphack)
|
|
|
|
{
|
|
|
|
drawpoly_srepeat = false;
|
|
|
|
drawpoly_trepeat = false;
|
|
|
|
method = DAMETH_CLAMPED;
|
|
|
|
|
|
|
|
vec2f_t const scale = { 1.f / tsiz.x, 1.f / tsiz.y };
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
usub = FLT_MAX;
|
|
|
|
vsub = FLT_MAX;
|
|
|
|
for (int i = 0; i < npoints; i++)
|
|
|
|
{
|
|
|
|
float const r = 1.f / dd[i];
|
|
|
|
float u = floor(uu[i] * r * scale.x);
|
|
|
|
float v = floor(vv[i] * r * scale.y);
|
|
|
|
if (u < usub) usub = u;
|
|
|
|
if (v < vsub) vsub = v;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (int i = 0; i < npoints; i++)
|
|
|
|
{
|
|
|
|
float const r = 1.f / dd[i];
|
|
|
|
float u = uu[i] * r * scale.x - usub;
|
|
|
|
float v = vv[i] * r * scale.y - vsub;
|
|
|
|
if (u < -FLT_EPSILON || u > 1 + FLT_EPSILON) drawpoly_srepeat = true;
|
|
|
|
if (v < -FLT_EPSILON || v > 1 + FLT_EPSILON) drawpoly_trepeat = true;
|
|
|
|
}
|
|
|
|
}
|
2020-06-07 08:14:32 +00:00
|
|
|
#endif
|
2006-07-22 22:52:24 +00:00
|
|
|
|
2019-05-25 14:59:09 +00:00
|
|
|
polymost_outputGLDebugMessage(3, "polymost_drawpoly(dpxy:%p, n:%d, method_:%X), method: %X", dpxy, n, method_, method);
|
|
|
|
|
2019-10-17 19:44:34 +00:00
|
|
|
// This only takes effect for textures with their default set to SamplerClampXY.
|
2020-05-29 22:30:56 +00:00
|
|
|
int sampleroverride = CLAMP_NONE;
|
|
|
|
if (method & DAMETH_CLAMPED)
|
|
|
|
{
|
|
|
|
if (drawpoly_srepeat) sampleroverride |= CLAMP_Y;
|
|
|
|
if (drawpoly_trepeat) sampleroverride |= CLAMP_X;
|
|
|
|
}
|
|
|
|
|
2011-06-26 13:00:31 +00:00
|
|
|
|
2020-05-29 14:46:36 +00:00
|
|
|
int palid = TRANSLATION(Translation_Remap + curbasepal, globalpal);
|
2020-09-20 18:39:11 +00:00
|
|
|
GLInterface.SetFade(globalfloorpal);
|
2020-06-02 14:55:02 +00:00
|
|
|
bool success = GLInterface.SetTexture(globalpicnum, tileGetTexture(globalpicnum), palid, sampleroverride);
|
2019-10-17 19:44:34 +00:00
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
tsiz.x = tsiz.y = 1;
|
2019-10-04 17:17:55 +00:00
|
|
|
GLInterface.SetColorMask(false); //Hack to update Z-buffer for invalid mirror textures
|
2019-10-17 19:44:34 +00:00
|
|
|
}
|
2019-09-18 18:44:21 +00:00
|
|
|
|
2019-10-17 19:44:34 +00:00
|
|
|
GLInterface.SetShade(globalshade, numshades);
|
2018-03-21 20:41:26 +00:00
|
|
|
|
2019-10-10 17:25:03 +00:00
|
|
|
if ((method & DAMETH_WALL) != 0)
|
2019-03-19 17:08:43 +00:00
|
|
|
{
|
2019-10-11 19:04:31 +00:00
|
|
|
int32_t size = tilesize.y;
|
2019-03-19 17:08:43 +00:00
|
|
|
int32_t size2;
|
|
|
|
for (size2 = 1; size2 < size; size2 += size2) {}
|
|
|
|
if (size == size2)
|
2020-06-07 07:30:55 +00:00
|
|
|
GLInterface.SetNpotEmulation(0.f, 0.f);
|
2019-03-19 17:08:43 +00:00
|
|
|
else
|
|
|
|
{
|
2019-10-11 19:04:31 +00:00
|
|
|
float xOffset = 1.f / tilesize.x;
|
2020-06-07 07:30:55 +00:00
|
|
|
GLInterface.SetNpotEmulation((1.f*size2) / size, xOffset);
|
2019-03-19 17:08:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-07 07:30:55 +00:00
|
|
|
GLInterface.SetNpotEmulation(0.f, 0.f);
|
2019-03-19 17:08:43 +00:00
|
|
|
}
|
2007-02-15 01:35:34 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vec2_t tsiz2 = tsiz;
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-10-10 19:05:10 +00:00
|
|
|
if (method & DAMETH_MASKPROPS)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2020-05-23 12:40:54 +00:00
|
|
|
SetRenderStyleFromBlend((method & DAMETH_MASKPROPS) > DAMETH_MASK, drawpoly_blend, (method & DAMETH_MASKPROPS) == DAMETH_TRANS2);
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2020-07-28 19:28:10 +00:00
|
|
|
if (!(method & (DAMETH_CLAMPED | DAMETH_MASKPROPS)))
|
2020-06-11 21:55:23 +00:00
|
|
|
GLInterface.SetTextureMode(TM_OPAQUE);
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
float pc[4];
|
2014-03-23 23:14:50 +00:00
|
|
|
|
2020-01-11 21:18:06 +00:00
|
|
|
// The shade rgb from the tint is ignored here.
|
|
|
|
pc[0] = (float)globalr * (1.f / 255.f);
|
|
|
|
pc[1] = (float)globalg * (1.f / 255.f);
|
|
|
|
pc[2] = (float)globalb * (1.f / 255.f);
|
2020-05-23 12:40:54 +00:00
|
|
|
pc[3] = GetAlphaFromBlend(method & DAMETH_MASKPROPS, drawpoly_blend) * (1.f - drawpoly_alpha);
|
2018-02-26 14:46:36 +00:00
|
|
|
|
2019-03-19 17:08:51 +00:00
|
|
|
if (skyzbufferhack_pass)
|
|
|
|
pc[3] = 0.01f;
|
|
|
|
|
2019-10-04 16:25:18 +00:00
|
|
|
GLInterface.SetColor(pc[0], pc[1], pc[2], pc[3]);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2020-01-11 21:18:06 +00:00
|
|
|
vec2f_t const scale = { 1.f / tsiz2.x, 1.f / tsiz2.y };
|
2020-01-18 21:41:08 +00:00
|
|
|
auto data = screen->mVertexData->AllocVertices(npoints);
|
|
|
|
auto vt = data.first;
|
2020-03-29 12:01:46 +00:00
|
|
|
for (bssize_t i = 0; i < npoints; ++i, vt++)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2019-10-10 21:38:06 +00:00
|
|
|
float const r = 1.f / dd[i];
|
2015-03-24 03:33:57 +00:00
|
|
|
|
2020-05-25 21:59:07 +00:00
|
|
|
if (tileGetTexture(globalpicnum)->GetTexture()->isHardwareCanvas())
|
2020-03-29 12:01:46 +00:00
|
|
|
{
|
|
|
|
//update texcoords, canvas textures are upside down!
|
|
|
|
vt->SetTexCoord(
|
|
|
|
uu[i] * r * scale.x - usub,
|
|
|
|
1.f - (vv[i] * r * scale.y - vsub));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//update texcoords
|
|
|
|
vt->SetTexCoord(
|
|
|
|
uu[i] * r * scale.x - usub,
|
|
|
|
vv[i] * r * scale.y - vsub);
|
|
|
|
}
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2019-10-10 21:38:06 +00:00
|
|
|
//update verts
|
|
|
|
vt->SetVertex(
|
2020-06-01 07:55:28 +00:00
|
|
|
(px[i] - ghalfx) * r * grhalfxdown10x * 1024.f,
|
|
|
|
(ghalfy - py[i]) * r * grhalfxdown10 * 1024.f,
|
|
|
|
r);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
}
|
2020-05-31 08:24:04 +00:00
|
|
|
GLInterface.Draw(DT_TriangleFan, data.second, npoints);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-01-18 15:13:39 +00:00
|
|
|
GLInterface.SetTinting(-1, 0xffffff, 0xffffff);
|
2020-06-07 07:30:55 +00:00
|
|
|
GLInterface.SetNpotEmulation(0.f, 0.f);
|
2020-06-11 21:55:23 +00:00
|
|
|
GLInterface.SetTextureMode(TM_NORMAL);
|
2016-01-08 01:33:20 +00:00
|
|
|
|
2019-10-10 19:05:10 +00:00
|
|
|
if (skyzbufferhack && skyzbufferhack_pass == 0)
|
2019-03-19 17:08:51 +00:00
|
|
|
{
|
|
|
|
vec3d_t const bxtex = xtex, bytex = ytex, botex = otex;
|
|
|
|
xtex = xtex2, ytex = ytex2, otex = otex2;
|
2019-10-04 17:17:55 +00:00
|
|
|
GLInterface.SetColorMask(false);
|
2020-05-31 08:24:04 +00:00
|
|
|
GLInterface.Draw(DT_TriangleFan, data.second, npoints);
|
2020-01-26 12:45:33 +00:00
|
|
|
GLInterface.SetColorMask(true);
|
2019-10-04 17:17:55 +00:00
|
|
|
xtex = bxtex, ytex = bytex, otex = botex;
|
2019-03-19 17:08:51 +00:00
|
|
|
}
|
2019-05-25 14:59:14 +00:00
|
|
|
|
2019-12-01 20:43:54 +00:00
|
|
|
if (!success)
|
2019-10-04 17:17:55 +00:00
|
|
|
GLInterface.SetColorMask(true);
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
static inline void vsp_finalize_init(int32_t const vcnt)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=0; i<vcnt; ++i)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
|
|
|
vsp[i].cy[1] = vsp[i+1].cy[0]; vsp[i].ctag = i;
|
|
|
|
vsp[i].fy[1] = vsp[i+1].fy[0]; vsp[i].ftag = i;
|
|
|
|
vsp[i].n = i+1; vsp[i].p = i-1;
|
|
|
|
// vsp[i].tag = -1;
|
|
|
|
}
|
|
|
|
vsp[vcnt-1].n = 0; vsp[0].p = vcnt-1;
|
|
|
|
|
|
|
|
//VSPMAX-1 is dummy empty node
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=vcnt; i<VSPMAX; i++) { vsp[i].n = i+1; vsp[i].p = i-1; }
|
2015-03-24 00:40:33 +00:00
|
|
|
vsp[VSPMAX-1].n = vcnt; vsp[vcnt].p = VSPMAX-1;
|
|
|
|
}
|
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
#define COMBINE_STRIPS
|
|
|
|
|
|
|
|
#ifdef COMBINE_STRIPS
|
2020-03-12 00:57:52 +00:00
|
|
|
static inline void vsdel(int const i)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
//Delete i
|
2015-07-08 03:34:20 +00:00
|
|
|
int const pi = vsp[i].p;
|
|
|
|
int const ni = vsp[i].n;
|
|
|
|
|
|
|
|
vsp[ni].p = pi;
|
|
|
|
vsp[pi].n = ni;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Add i to empty list
|
|
|
|
vsp[i].n = vsp[VSPMAX-1].n;
|
|
|
|
vsp[i].p = VSPMAX-1;
|
|
|
|
vsp[vsp[VSPMAX-1].n].p = i;
|
|
|
|
vsp[VSPMAX-1].n = i;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2020-03-12 00:57:52 +00:00
|
|
|
|
|
|
|
static inline void vsmerge(int const i, int const ni)
|
|
|
|
{
|
|
|
|
vsp[i].cy[1] = vsp[ni].cy[1];
|
|
|
|
vsp[i].fy[1] = vsp[ni].fy[1];
|
|
|
|
vsdel(ni);
|
|
|
|
}
|
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-03-12 00:57:52 +00:00
|
|
|
static inline int32_t vsinsaft(int const i)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
//i = next element from empty list
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t const r = vsp[VSPMAX-1].n;
|
2006-04-24 19:04:22 +00:00
|
|
|
vsp[vsp[r].n].p = VSPMAX-1;
|
|
|
|
vsp[VSPMAX-1].n = vsp[r].n;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
vsp[r] = vsp[i]; //copy i to r
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//insert r after i
|
|
|
|
vsp[r].p = i; vsp[r].n = vsp[i].n;
|
|
|
|
vsp[vsp[i].n].p = r; vsp[i].n = r;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
return r;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2019-03-19 17:07:53 +00:00
|
|
|
|
2015-12-04 11:52:54 +00:00
|
|
|
static int32_t domostpolymethod = DAMETH_NOMASK;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
#define DOMOST_OFFSET .01f
|
|
|
|
|
2019-03-04 23:49:11 +00:00
|
|
|
static void polymost_clipmost(vec2f_t *dpxy, int &n, float x0, float x1, float y0top, float y0bot, float y1top, float y1bot)
|
|
|
|
{
|
|
|
|
if (y0bot < y0top || y1bot < y1top)
|
|
|
|
return;
|
|
|
|
|
|
|
|
//Clip to (x0,y0top)-(x1,y1top)
|
|
|
|
|
|
|
|
vec2f_t dp2[8];
|
|
|
|
|
|
|
|
float t0, t1;
|
|
|
|
int n2 = 0;
|
|
|
|
t1 = -((dpxy[0].x - x0) * (y1top - y0top) - (dpxy[0].y - y0top) * (x1 - x0));
|
|
|
|
|
|
|
|
for (bssize_t i=0; i<n; i++)
|
|
|
|
{
|
|
|
|
int j = i + 1;
|
|
|
|
|
|
|
|
if (j >= n)
|
|
|
|
j = 0;
|
|
|
|
|
|
|
|
t0 = t1;
|
|
|
|
t1 = -((dpxy[j].x - x0) * (y1top - y0top) - (dpxy[j].y - y0top) * (x1 - x0));
|
|
|
|
|
|
|
|
if (t0 >= 0)
|
|
|
|
dp2[n2++] = dpxy[i];
|
|
|
|
|
|
|
|
if ((t0 >= 0) != (t1 >= 0) && (t0 <= 0) != (t1 <= 0))
|
|
|
|
{
|
|
|
|
float const r = t0 / (t0 - t1);
|
2019-03-19 17:10:08 +00:00
|
|
|
dp2[n2] = { (dpxy[j].x - dpxy[i].x) * r + dpxy[i].x,
|
|
|
|
(dpxy[j].y - dpxy[i].y) * r + dpxy[i].y };
|
2019-03-04 23:49:11 +00:00
|
|
|
n2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n2 < 3)
|
|
|
|
{
|
|
|
|
n = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Clip to (x1,y1bot)-(x0,y0bot)
|
|
|
|
t1 = -((dp2[0].x - x1) * (y0bot - y1bot) - (dp2[0].y - y1bot) * (x0 - x1));
|
|
|
|
n = 0;
|
|
|
|
|
|
|
|
for (bssize_t i = 0, j = 1; i < n2; j = ++i + 1)
|
|
|
|
{
|
|
|
|
if (j >= n2)
|
|
|
|
j = 0;
|
|
|
|
|
|
|
|
t0 = t1;
|
|
|
|
t1 = -((dp2[j].x - x1) * (y0bot - y1bot) - (dp2[j].y - y1bot) * (x0 - x1));
|
|
|
|
|
|
|
|
if (t0 >= 0)
|
|
|
|
dpxy[n++] = dp2[i];
|
|
|
|
|
|
|
|
if ((t0 >= 0) != (t1 >= 0) && (t0 <= 0) != (t1 <= 0))
|
|
|
|
{
|
|
|
|
float const r = t0 / (t0 - t1);
|
2019-03-19 17:10:08 +00:00
|
|
|
dpxy[n] = { (dp2[j].x - dp2[i].x) * r + dp2[i].x,
|
|
|
|
(dp2[j].y - dp2[i].y) * r + dp2[i].y };
|
2019-03-04 23:49:11 +00:00
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n < 3)
|
|
|
|
{
|
|
|
|
n = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void polymost_domost(float x0, float y0, float x1, float y1, float y0top = 0.f, float y0bot = -1.f, float y1top = 0.f, float y1bot = -1.f)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-06-21 00:34:18 +00:00
|
|
|
int const dir = (x0 < x1);
|
2013-03-04 09:10:54 +00:00
|
|
|
|
2019-05-25 14:59:09 +00:00
|
|
|
polymost_outputGLDebugMessage(3, "polymost_domost(x0:%f, y0:%f, x1:%f, y1:%f, y0top:%f, y0bot:%f, y1top:%f, y1bot:%f)",
|
|
|
|
x0, y0, x1, y1, y0top, y0bot, y1top, y1bot);
|
|
|
|
|
2019-03-04 23:49:11 +00:00
|
|
|
y0top -= DOMOST_OFFSET;
|
|
|
|
y1top -= DOMOST_OFFSET;
|
|
|
|
y0bot += DOMOST_OFFSET;
|
|
|
|
y1bot += DOMOST_OFFSET;
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (dir) //clip dmost (floor)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
y0 -= DOMOST_OFFSET;
|
|
|
|
y1 -= DOMOST_OFFSET;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
else //clip umost (ceiling)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
|
|
|
if (x0 == x1) return;
|
2020-09-10 14:36:31 +00:00
|
|
|
std::swap(x0, x1);
|
|
|
|
std::swap(y0, y1);
|
|
|
|
std::swap(y0top, y1top);
|
|
|
|
std::swap(y0bot, y1bot);
|
2015-03-24 00:40:48 +00:00
|
|
|
y0 += DOMOST_OFFSET;
|
|
|
|
y1 += DOMOST_OFFSET; //necessary?
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2019-03-02 23:22:12 +00:00
|
|
|
// Test if span is outside screen bounds
|
2019-03-19 17:08:39 +00:00
|
|
|
if (x1 < xbl || x0 > xbr)
|
2019-03-02 23:22:12 +00:00
|
|
|
{
|
|
|
|
domost_rejectcount++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-08-01 06:50:29 +00:00
|
|
|
vec2f_t dm0 = { x0 - DOMOST_OFFSET, y0 };
|
|
|
|
vec2f_t dm1 = { x1 + DOMOST_OFFSET, y1 };
|
2015-03-24 00:40:48 +00:00
|
|
|
|
|
|
|
float const slop = (dm1.y - dm0.y) / (dm1.x - dm0.x);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-03-04 23:49:03 +00:00
|
|
|
if (dm0.x < xbl)
|
|
|
|
{
|
|
|
|
dm0.y += slop*(xbl-dm0.x);
|
|
|
|
dm0.x = xbl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dm1.x > xbr)
|
|
|
|
{
|
|
|
|
dm1.y += slop*(xbr-dm1.x);
|
|
|
|
dm1.x = xbr;
|
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
drawpoly_alpha = 0.f;
|
2016-10-09 07:55:23 +00:00
|
|
|
drawpoly_blend = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec2f_t n0, n1;
|
2015-07-08 03:34:20 +00:00
|
|
|
float spx[4];
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t spt[4];
|
2019-08-01 06:50:21 +00:00
|
|
|
int firstnode = vsp[0].n;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t newi, i=vsp[0].n; i; i=newi)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2014-10-25 03:34:25 +00:00
|
|
|
newi = vsp[i].n; n0.x = vsp[i].x; n1.x = vsp[newi].x;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-08-01 06:50:21 +00:00
|
|
|
if (dm0.x >= n1.x)
|
|
|
|
{
|
|
|
|
firstnode = i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n0.x >= dm1.x)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (vsp[i].ctag <= 0) continue;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
float const dx = n1.x-n0.x;
|
|
|
|
float const cy[2] = { vsp[i].cy[0], vsp[i].fy[0] },
|
|
|
|
cv[2] = { vsp[i].cy[1]-cy[0], vsp[i].fy[1]-cy[1] };
|
|
|
|
|
|
|
|
int scnt = 0;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
//Test if left edge requires split (dm0.x,dm0.y) (nx0,cy(0)),<dx,cv(0)>
|
|
|
|
if ((dm0.x > n0.x) && (dm0.x < n1.x))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const t = (dm0.x-n0.x)*cv[dir] - (dm0.y-cy[dir])*dx;
|
2014-09-30 04:14:21 +00:00
|
|
|
if (((!dir) && (t < 0.f)) || ((dir) && (t > 0.f)))
|
2015-07-08 03:34:20 +00:00
|
|
|
{ spx[scnt] = dm0.x; spt[scnt] = -1; scnt++; }
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2014-10-25 03:34:25 +00:00
|
|
|
//Test for intersection on umost (0) and dmost (1)
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2016-06-05 04:46:28 +00:00
|
|
|
float const d[2] = { ((dm0.y - dm1.y) * dx) - ((dm0.x - dm1.x) * cv[0]),
|
2015-03-24 00:40:48 +00:00
|
|
|
((dm0.y - dm1.y) * dx) - ((dm0.x - dm1.x) * cv[1]) };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
float const n[2] = { ((dm0.y - cy[0]) * dx) - ((dm0.x - n0.x) * cv[0]),
|
|
|
|
((dm0.y - cy[1]) * dx) - ((dm0.x - n0.x) * cv[1]) };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
float const fnx[2] = { dm0.x + ((n[0] / d[0]) * (dm1.x - dm0.x)),
|
|
|
|
dm0.x + ((n[1] / d[1]) * (dm1.x - dm0.x)) };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-09-10 14:36:31 +00:00
|
|
|
if ((fabsf(d[0]) > fabsf(n[0])) && (d[0] * n[0] >= 0.f) && (fnx[0] > n0.x) && (fnx[0] < n1.x))
|
2015-03-24 00:40:33 +00:00
|
|
|
spx[scnt] = fnx[0], spt[scnt++] = 0;
|
|
|
|
|
2020-09-10 14:36:31 +00:00
|
|
|
if ((fabsf(d[1]) > fabsf(n[1])) && (d[1] * n[1] >= 0.f) && (fnx[1] > n0.x) && (fnx[1] < n1.x))
|
2015-03-24 00:40:33 +00:00
|
|
|
spx[scnt] = fnx[1], spt[scnt++] = 1;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Nice hack to avoid full sort later :)
|
|
|
|
if ((scnt >= 2) && (spx[scnt-1] < spx[scnt-2]))
|
|
|
|
{
|
2020-09-10 14:36:31 +00:00
|
|
|
std::swap(spx[scnt-1], spx[scnt-2]);
|
|
|
|
std::swap(spt[scnt-1], spt[scnt-2]);
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Test if right edge requires split
|
2015-03-24 00:40:48 +00:00
|
|
|
if ((dm1.x > n0.x) && (dm1.x < n1.x))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2016-06-21 00:34:18 +00:00
|
|
|
float const t = (dm1.x-n0.x)*cv[dir] - (dm1.y-cy[dir])*dx;
|
|
|
|
if (((!dir) && (t < 0.f)) || ((dir) && (t > 0.f)))
|
2015-07-08 03:34:20 +00:00
|
|
|
{ spx[scnt] = dm1.x; spt[scnt] = -1; scnt++; }
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vsp[i].tag = vsp[newi].tag = -1;
|
2014-10-25 03:33:26 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
float const rdx = 1.f/dx;
|
2014-10-25 03:33:26 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t z=0, vcnt=0; z<=scnt; z++,i=vcnt)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-01-11 04:55:07 +00:00
|
|
|
float t;
|
2014-10-25 03:33:26 +00:00
|
|
|
|
2014-10-25 03:34:25 +00:00
|
|
|
if (z == scnt)
|
|
|
|
goto skip;
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
t = (spx[z]-n0.x)*rdx;
|
2015-07-08 03:34:20 +00:00
|
|
|
vcnt = vsinsaft(i);
|
2014-10-25 03:34:25 +00:00
|
|
|
vsp[i].cy[1] = t*cv[0] + cy[0];
|
|
|
|
vsp[i].fy[1] = t*cv[1] + cy[1];
|
|
|
|
vsp[vcnt].x = spx[z];
|
|
|
|
vsp[vcnt].cy[0] = vsp[i].cy[1];
|
|
|
|
vsp[vcnt].fy[0] = vsp[i].fy[1];
|
|
|
|
vsp[vcnt].tag = spt[z];
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-01-18 20:21:17 +00:00
|
|
|
skip: ;
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t const ni = vsp[i].n; if (!ni) continue; //this 'if' fixes many bugs!
|
2015-03-24 00:40:48 +00:00
|
|
|
float const dx0 = vsp[i].x; if (dm0.x > dx0) continue;
|
|
|
|
float const dx1 = vsp[ni].x; if (dm1.x < dx1) continue;
|
|
|
|
n0.y = (dx0-dm0.x)*slop + dm0.y;
|
|
|
|
n1.y = (dx1-dm0.x)*slop + dm0.y;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
// dx0 dx1
|
|
|
|
// ~ ~
|
|
|
|
//----------------------------
|
|
|
|
// t0+=0 t1+=0
|
|
|
|
// vsp[i].cy[0] vsp[i].cy[1]
|
|
|
|
//============================
|
|
|
|
// t0+=1 t1+=3
|
|
|
|
//============================
|
|
|
|
// vsp[i].fy[0] vsp[i].fy[1]
|
|
|
|
// t0+=2 t1+=6
|
|
|
|
//
|
|
|
|
// ny0 ? ny1 ?
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int k = 4;
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
if ((vsp[i].tag == 0) || (n0.y <= vsp[i].cy[0]+DOMOST_OFFSET)) k--;
|
|
|
|
if ((vsp[i].tag == 1) || (n0.y >= vsp[i].fy[0]-DOMOST_OFFSET)) k++;
|
|
|
|
if ((vsp[ni].tag == 0) || (n1.y <= vsp[i].cy[1]+DOMOST_OFFSET)) k -= 3;
|
|
|
|
if ((vsp[ni].tag == 1) || (n1.y >= vsp[i].fy[1]-DOMOST_OFFSET)) k += 3;
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (!dir)
|
|
|
|
{
|
2006-11-13 23:12:47 +00:00
|
|
|
switch (k)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
case 4:
|
|
|
|
case 5:
|
|
|
|
case 7:
|
|
|
|
{
|
2019-06-25 18:50:42 +00:00
|
|
|
vec2f_t dpxy[8] = {
|
|
|
|
{ dx0, vsp[i].cy[0] }, { dx1, vsp[i].cy[1] }, { dx1, n1.y }, { dx0, n0.y }
|
|
|
|
};
|
|
|
|
|
|
|
|
int n = 4;
|
|
|
|
polymost_clipmost(dpxy, n, x0, x1, y0top, y0bot, y1top, y1bot);
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
|
2019-03-04 23:49:11 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vsp[i].cy[0] = n0.y;
|
|
|
|
vsp[i].cy[1] = n1.y;
|
|
|
|
vsp[i].ctag = gtag;
|
|
|
|
}
|
2014-09-30 04:14:21 +00:00
|
|
|
break;
|
2015-03-24 00:40:33 +00:00
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
{
|
2019-06-25 18:50:42 +00:00
|
|
|
vec2f_t dpxy[8] = { { dx0, vsp[i].cy[0] }, { dx1, vsp[i].cy[1] }, { dx0, n0.y } };
|
|
|
|
|
|
|
|
int n = 3;
|
|
|
|
polymost_clipmost(dpxy, n, x0, x1, y0top, y0bot, y1top, y1bot);
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vsp[i].cy[0] = n0.y;
|
|
|
|
vsp[i].ctag = gtag;
|
|
|
|
}
|
2014-09-30 04:14:21 +00:00
|
|
|
break;
|
2015-03-24 00:40:33 +00:00
|
|
|
case 3:
|
|
|
|
case 6:
|
|
|
|
{
|
2019-06-25 18:50:42 +00:00
|
|
|
vec2f_t dpxy[8] = { { dx0, vsp[i].cy[0] }, { dx1, vsp[i].cy[1] }, { dx1, n1.y } };
|
|
|
|
|
|
|
|
int n = 3;
|
|
|
|
polymost_clipmost(dpxy, n, x0, x1, y0top, y0bot, y1top, y1bot);
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vsp[i].cy[1] = n1.y;
|
|
|
|
vsp[i].ctag = gtag;
|
|
|
|
}
|
2014-09-30 04:14:21 +00:00
|
|
|
break;
|
2015-03-24 00:40:33 +00:00
|
|
|
case 8:
|
|
|
|
{
|
2019-06-25 18:50:42 +00:00
|
|
|
vec2f_t dpxy[8] = {
|
|
|
|
{ dx0, vsp[i].cy[0] }, { dx1, vsp[i].cy[1] }, { dx1, vsp[i].fy[1] }, { dx0, vsp[i].fy[0] }
|
|
|
|
};
|
|
|
|
|
|
|
|
int n = 4;
|
|
|
|
polymost_clipmost(dpxy, n, x0, x1, y0top, y0bot, y1top, y1bot);
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
|
2019-03-04 23:49:11 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vsp[i].ctag = vsp[i].ftag = -1;
|
|
|
|
}
|
|
|
|
default: break;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-13 23:12:47 +00:00
|
|
|
switch (k)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2014-10-25 03:34:25 +00:00
|
|
|
case 4:
|
|
|
|
case 3:
|
|
|
|
case 1:
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2019-06-25 18:50:42 +00:00
|
|
|
vec2f_t dpxy[8] = {
|
|
|
|
{ dx0, n0.y }, { dx1, n1.y }, { dx1, vsp[i].fy[1] }, { dx0, vsp[i].fy[0] }
|
|
|
|
};
|
|
|
|
|
|
|
|
int n = 4;
|
|
|
|
polymost_clipmost(dpxy, n, x0, x1, y0top, y0bot, y1top, y1bot);
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
|
2019-03-04 23:49:11 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vsp[i].fy[0] = n0.y;
|
|
|
|
vsp[i].fy[1] = n1.y;
|
|
|
|
vsp[i].ftag = gtag;
|
|
|
|
}
|
2014-10-25 03:34:25 +00:00
|
|
|
break;
|
2006-11-13 23:12:47 +00:00
|
|
|
case 7:
|
|
|
|
case 6:
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2019-06-25 18:50:42 +00:00
|
|
|
vec2f_t dpxy[8] = { { dx0, n0.y }, { dx1, vsp[i].fy[1] }, { dx0, vsp[i].fy[0] } };
|
|
|
|
|
|
|
|
int n = 3;
|
|
|
|
polymost_clipmost(dpxy, n, x0, x1, y0top, y0bot, y1top, y1bot);
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vsp[i].fy[0] = n0.y;
|
|
|
|
vsp[i].ftag = gtag;
|
|
|
|
}
|
2014-09-30 04:14:21 +00:00
|
|
|
break;
|
2006-11-13 23:12:47 +00:00
|
|
|
case 5:
|
|
|
|
case 2:
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2019-06-25 18:50:42 +00:00
|
|
|
vec2f_t dpxy[8] = { { dx0, vsp[i].fy[0] }, { dx1, n1.y }, { dx1, vsp[i].fy[1] } };
|
|
|
|
|
|
|
|
int n = 3;
|
|
|
|
polymost_clipmost(dpxy, n, x0, x1, y0top, y0bot, y1top, y1bot);
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vsp[i].fy[1] = n1.y;
|
|
|
|
vsp[i].ftag = gtag;
|
|
|
|
}
|
2014-09-30 04:14:21 +00:00
|
|
|
break;
|
2006-04-24 19:04:22 +00:00
|
|
|
case 0:
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2019-06-25 18:50:42 +00:00
|
|
|
vec2f_t dpxy[8] = { { dx0, vsp[i].cy[0] }, { dx1, vsp[i].cy[1] }, { dx1, vsp[i].fy[1] }, { dx0, vsp[i].fy[0] } };
|
|
|
|
|
|
|
|
int n = 4;
|
|
|
|
polymost_clipmost(dpxy, n, x0, x1, y0top, y0bot, y1top, y1bot);
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
|
2019-03-04 23:49:11 +00:00
|
|
|
|
2014-09-30 04:14:21 +00:00
|
|
|
vsp[i].ctag = vsp[i].ftag = -1;
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
2006-11-13 23:12:47 +00:00
|
|
|
default:
|
2014-09-30 04:14:21 +00:00
|
|
|
break;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gtag++;
|
|
|
|
|
|
|
|
//Combine neighboring vertical strips with matching collinear top&bottom edges
|
|
|
|
//This prevents x-splits from propagating through the entire scan
|
2015-07-08 03:34:20 +00:00
|
|
|
#ifdef COMBINE_STRIPS
|
2019-08-01 06:50:21 +00:00
|
|
|
int i = firstnode;
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2019-03-04 23:48:55 +00:00
|
|
|
do
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-08-01 06:50:21 +00:00
|
|
|
if (vsp[i].x >= dm1.x)
|
|
|
|
break;
|
|
|
|
|
2019-07-26 21:54:48 +00:00
|
|
|
if ((vsp[i].cy[0]+DOMOST_OFFSET*2 >= vsp[i].fy[0]) && (vsp[i].cy[1]+DOMOST_OFFSET*2 >= vsp[i].fy[1]))
|
2011-09-04 19:44:07 +00:00
|
|
|
vsp[i].ctag = vsp[i].ftag = -1;
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int const ni = vsp[i].n;
|
|
|
|
|
2019-06-25 18:35:19 +00:00
|
|
|
//POGO: specially treat the viewport nodes so that we will never end up in a situation where we accidentally access the sentinel node
|
2019-08-01 06:50:29 +00:00
|
|
|
if (ni >= viewportNodeCount)
|
2011-09-04 19:44:07 +00:00
|
|
|
{
|
2019-08-01 06:50:29 +00:00
|
|
|
if ((vsp[i].ctag == vsp[ni].ctag) && (vsp[i].ftag == vsp[ni].ftag))
|
|
|
|
{
|
2020-03-12 00:57:52 +00:00
|
|
|
vsmerge(i, ni);
|
2019-08-01 06:50:29 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (vsp[ni].x - vsp[i].x < DOMOST_OFFSET)
|
|
|
|
{
|
|
|
|
vsp[i].x = vsp[ni].x;
|
|
|
|
vsp[i].cy[0] = vsp[ni].cy[0];
|
|
|
|
vsp[i].fy[0] = vsp[ni].fy[0];
|
|
|
|
vsp[i].ctag = vsp[ni].ctag;
|
|
|
|
vsp[i].ftag = vsp[ni].ftag;
|
2020-03-12 00:57:52 +00:00
|
|
|
vsmerge(i, ni);
|
2019-08-01 06:50:29 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-09-04 19:44:07 +00:00
|
|
|
}
|
2019-08-01 06:50:29 +00:00
|
|
|
i = ni;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2019-03-04 23:48:55 +00:00
|
|
|
while (i);
|
2015-07-08 03:34:20 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2015-07-08 03:34:27 +00:00
|
|
|
|
2011-03-19 18:07:12 +00:00
|
|
|
// variables that are set to ceiling- or floor-members, depending
|
|
|
|
// on which one is processed right now
|
|
|
|
static int32_t global_cf_z;
|
|
|
|
static float global_cf_xpanning, global_cf_ypanning, global_cf_heinum;
|
2014-04-05 11:28:08 +00:00
|
|
|
static int32_t global_cf_shade, global_cf_pal, global_cf_fogpal;
|
2019-07-26 21:54:37 +00:00
|
|
|
static float (*global_getzofslope_func)(usectorptr_t, float, float);
|
2011-03-19 18:07:12 +00:00
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
static void polymost_internal_nonparallaxed(vec2f_t n0, vec2f_t n1, float ryp0, float ryp1, float x0, float x1,
|
|
|
|
float y0, float y1, int32_t sectnum)
|
2011-03-19 18:07:12 +00:00
|
|
|
{
|
2015-07-08 03:34:20 +00:00
|
|
|
int const have_floor = sectnum & MAXSECTORS;
|
|
|
|
sectnum &= ~MAXSECTORS;
|
2020-02-15 20:36:29 +00:00
|
|
|
auto const sec = (usectorptr_t)§or[sectnum];
|
2011-03-19 18:07:12 +00:00
|
|
|
|
|
|
|
// comments from floor code:
|
|
|
|
//(singlobalang/-16384*(sx-ghalfx) + 0*(sy-ghoriz) + (cosviewingrangeglobalang/16384)*ghalfx)*d + globalposx = u*16
|
|
|
|
//(cosglobalang/ 16384*(sx-ghalfx) + 0*(sy-ghoriz) + (sinviewingrangeglobalang/16384)*ghalfx)*d + globalposy = v*16
|
|
|
|
//( 0*(sx-ghalfx) + 1*(sy-ghoriz) + ( 0)*ghalfx)*d + globalposz/16 = (sec->floorz/16)
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
float ft[4] = { fglobalposx, fglobalposy, fcosglobalang, fsinglobalang };
|
|
|
|
|
2019-06-25 18:35:19 +00:00
|
|
|
polymost_outputGLDebugMessage(3, "polymost_internal_nonparallaxed(n0:{x:%f, y:%f}, n1:{x:%f, y:%f}, ryp0:%f, ryp1:%f, x0:%f, x1:%f, y0:%f, y1:%f, sectnum:%d)",
|
|
|
|
n0.x, n0.y, n1.x, n1.y, ryp0, ryp1, x0, x1, y0, y1, sectnum);
|
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
if (globalorientation & 64)
|
2011-03-19 18:07:12 +00:00
|
|
|
{
|
|
|
|
//relative alignment
|
2019-03-19 17:08:35 +00:00
|
|
|
vec2_t const xy = { wall[wall[sec->wallptr].point2].x - wall[sec->wallptr].x,
|
2019-03-19 17:08:39 +00:00
|
|
|
wall[wall[sec->wallptr].point2].y - wall[sec->wallptr].y };
|
2019-03-19 17:08:35 +00:00
|
|
|
float r;
|
2019-03-19 17:08:39 +00:00
|
|
|
|
2019-03-19 17:08:35 +00:00
|
|
|
if (globalorientation & 2)
|
|
|
|
{
|
|
|
|
int i = krecipasm(nsqrtasm(uhypsq(xy.x,xy.y)));
|
|
|
|
r = i * (1.f/1073741824.f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-14 18:21:16 +00:00
|
|
|
int i = nsqrtasm(uhypsq(xy.x,xy.y)); if (i == 0) i = 1024; else i = 1048576 / i;
|
2019-03-19 17:08:35 +00:00
|
|
|
r = i * (1.f/1048576.f);
|
|
|
|
}
|
2015-07-08 03:34:20 +00:00
|
|
|
|
2019-03-19 17:08:35 +00:00
|
|
|
vec2f_t const fxy = { xy.x*r, xy.y*r };
|
2015-07-08 03:34:20 +00:00
|
|
|
|
|
|
|
ft[0] = ((float)(globalposx - wall[sec->wallptr].x)) * fxy.x + ((float)(globalposy - wall[sec->wallptr].y)) * fxy.y;
|
|
|
|
ft[1] = ((float)(globalposy - wall[sec->wallptr].y)) * fxy.x - ((float)(globalposx - wall[sec->wallptr].x)) * fxy.y;
|
2015-03-24 00:40:33 +00:00
|
|
|
ft[2] = fcosglobalang * fxy.x + fsinglobalang * fxy.y;
|
2015-07-08 03:34:20 +00:00
|
|
|
ft[3] = fsinglobalang * fxy.x - fcosglobalang * fxy.y;
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
globalorientation ^= (!(globalorientation & 4)) ? 32 : 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
xtex.d = 0;
|
|
|
|
ytex.d = gxyaspect;
|
|
|
|
|
|
|
|
if (!(globalorientation&2) && global_cf_z-globalposz) // PK 2012: don't allow div by zero
|
|
|
|
ytex.d /= (double)(global_cf_z-globalposz);
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
otex.d = -ghoriz * ytex.d;
|
|
|
|
|
|
|
|
if (globalorientation & 8)
|
|
|
|
{
|
|
|
|
ft[0] *= (1.f / 8.f);
|
|
|
|
ft[1] *= -(1.f / 8.f);
|
|
|
|
ft[2] *= (1.f / 2097152.f);
|
|
|
|
ft[3] *= (1.f / 2097152.f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ft[0] *= (1.f / 16.f);
|
|
|
|
ft[1] *= -(1.f / 16.f);
|
|
|
|
ft[2] *= (1.f / 4194304.f);
|
|
|
|
ft[3] *= (1.f / 4194304.f);
|
|
|
|
}
|
|
|
|
|
|
|
|
xtex.u = ft[3] * -(1.f / 65536.f) * (double)viewingrange;
|
|
|
|
xtex.v = ft[2] * -(1.f / 65536.f) * (double)viewingrange;
|
|
|
|
ytex.u = ft[0] * ytex.d;
|
|
|
|
ytex.v = ft[1] * ytex.d;
|
|
|
|
otex.u = ft[0] * otex.d;
|
|
|
|
otex.v = ft[1] * otex.d;
|
|
|
|
otex.u += (ft[2] - xtex.u) * ghalfx;
|
|
|
|
otex.v -= (ft[3] + xtex.v) * ghalfx;
|
2011-03-19 18:07:12 +00:00
|
|
|
|
|
|
|
//Texture flipping
|
|
|
|
if (globalorientation&4)
|
|
|
|
{
|
2020-09-10 14:36:31 +00:00
|
|
|
std::swap(xtex.u, xtex.v);
|
|
|
|
std::swap(ytex.u, ytex.v);
|
|
|
|
std::swap(otex.u, otex.v);
|
2011-03-19 18:07:12 +00:00
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (globalorientation&16) { xtex.u = -xtex.u; ytex.u = -ytex.u; otex.u = -otex.u; }
|
|
|
|
if (globalorientation&32) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; }
|
2011-03-19 18:07:12 +00:00
|
|
|
|
|
|
|
//Texture panning
|
2020-05-23 22:27:24 +00:00
|
|
|
vec2f_t fxy = { global_cf_xpanning * ((float)(1 << widthBits(globalpicnum))) * (1.0f / 256.f),
|
|
|
|
global_cf_ypanning * ((float)(1 << heightBits(globalpicnum))) * (1.0f / 256.f) };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2011-03-19 18:07:12 +00:00
|
|
|
if ((globalorientation&(2+64)) == (2+64)) //Hack for panning for slopes w/ relative alignment
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
float r = global_cf_heinum * (1.0f / 4096.f);
|
|
|
|
r = polymost_invsqrt_approximation(r * r + 1);
|
|
|
|
|
|
|
|
if (!(globalorientation & 4))
|
|
|
|
fxy.y *= r;
|
|
|
|
else
|
|
|
|
fxy.x *= r;
|
2011-03-19 18:07:12 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.u += ytex.d*fxy.x; otex.u += otex.d*fxy.x;
|
|
|
|
ytex.v += ytex.d*fxy.y; otex.v += otex.d*fxy.y;
|
2011-03-19 18:07:12 +00:00
|
|
|
|
|
|
|
if (globalorientation&2) //slopes
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
//Pick some point guaranteed to be not collinear to the 1st two points
|
2019-03-19 17:07:57 +00:00
|
|
|
vec2f_t dxy = { n1.y - n0.y, n0.x - n1.x };
|
|
|
|
|
|
|
|
float const dxyr = polymost_invsqrt_approximation(dxy.x * dxy.x + dxy.y * dxy.y);
|
|
|
|
|
|
|
|
dxy.x *= dxyr * 4096.f;
|
|
|
|
dxy.y *= dxyr * 4096.f;
|
|
|
|
|
|
|
|
vec2f_t const oxy = { n0.x + dxy.x, n0.y + dxy.y };
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
float const ox2 = (oxy.y - fglobalposy) * gcosang - (oxy.x - fglobalposx) * gsinang;
|
|
|
|
float oy2 = 1.f / ((oxy.x - fglobalposx) * gcosang2 + (oxy.y - fglobalposy) * gsinang2);
|
2011-03-19 18:07:12 +00:00
|
|
|
|
2019-03-19 17:08:05 +00:00
|
|
|
double const px[3] = { x0, x1, (double)ghalfx * ox2 * oy2 + ghalfx };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
oy2 *= gyxscale;
|
|
|
|
|
|
|
|
double py[3] = { ryp0 + (double)ghoriz, ryp1 + (double)ghoriz, oy2 + (double)ghoriz };
|
|
|
|
|
2017-06-09 06:40:17 +00:00
|
|
|
vec3d_t const duv[3] = {
|
|
|
|
{ (px[0] * xtex.d + py[0] * ytex.d + otex.d),
|
|
|
|
(px[0] * xtex.u + py[0] * ytex.u + otex.u),
|
|
|
|
(px[0] * xtex.v + py[0] * ytex.v + otex.v)
|
2015-04-18 21:59:19 +00:00
|
|
|
},
|
2017-06-09 06:40:17 +00:00
|
|
|
{ (px[1] * xtex.d + py[1] * ytex.d + otex.d),
|
|
|
|
(px[1] * xtex.u + py[1] * ytex.u + otex.u),
|
|
|
|
(px[1] * xtex.v + py[1] * ytex.v + otex.v)
|
2015-04-18 21:59:19 +00:00
|
|
|
},
|
2017-06-09 06:40:17 +00:00
|
|
|
{ (px[2] * xtex.d + py[2] * ytex.d + otex.d),
|
|
|
|
(px[2] * xtex.u + py[2] * ytex.u + otex.u),
|
|
|
|
(px[2] * xtex.v + py[2] * ytex.v + otex.v)
|
2015-04-18 21:59:19 +00:00
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
};
|
2011-03-19 18:07:12 +00:00
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
py[0] = y0;
|
|
|
|
py[1] = y1;
|
2019-07-26 21:54:37 +00:00
|
|
|
py[2] = double(global_getzofslope_func((usectorptr_t)§or[sectnum], oxy.x, oxy.y) - globalposz) * oy2 + ghoriz;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec3f_t oxyz[2] = { { (float)(py[1] - py[2]), (float)(py[2] - py[0]), (float)(py[0] - py[1]) },
|
|
|
|
{ (float)(px[2] - px[1]), (float)(px[0] - px[2]), (float)(px[1] - px[0]) } };
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
float const r = 1.f / (oxyz[0].x * px[0] + oxyz[0].y * px[1] + oxyz[0].z * px[2]);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
xtex.d = (oxyz[0].x * duv[0].d + oxyz[0].y * duv[1].d + oxyz[0].z * duv[2].d) * r;
|
|
|
|
xtex.u = (oxyz[0].x * duv[0].u + oxyz[0].y * duv[1].u + oxyz[0].z * duv[2].u) * r;
|
|
|
|
xtex.v = (oxyz[0].x * duv[0].v + oxyz[0].y * duv[1].v + oxyz[0].z * duv[2].v) * r;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
ytex.d = (oxyz[1].x * duv[0].d + oxyz[1].y * duv[1].d + oxyz[1].z * duv[2].d) * r;
|
|
|
|
ytex.u = (oxyz[1].x * duv[0].u + oxyz[1].y * duv[1].u + oxyz[1].z * duv[2].u) * r;
|
|
|
|
ytex.v = (oxyz[1].x * duv[0].v + oxyz[1].y * duv[1].v + oxyz[1].z * duv[2].v) * r;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
otex.d = duv[0].d - px[0] * xtex.d - py[0] * ytex.d;
|
|
|
|
otex.u = duv[0].u - px[0] * xtex.u - py[0] * ytex.u;
|
|
|
|
otex.v = duv[0].v - px[0] * xtex.v - py[0] * ytex.v;
|
2011-03-19 18:07:12 +00:00
|
|
|
|
|
|
|
if (globalorientation&64) //Hack for relative alignment on slopes
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float r = global_cf_heinum * (1.0f / 4096.f);
|
2020-09-08 16:48:18 +00:00
|
|
|
r = sqrtf(r*r+1);
|
2015-03-24 00:40:33 +00:00
|
|
|
if (!(globalorientation&4)) { xtex.v *= r; ytex.v *= r; otex.v *= r; }
|
|
|
|
else { xtex.u *= r; ytex.u *= r; otex.u *= r; }
|
2011-03-19 18:07:12 +00:00
|
|
|
}
|
|
|
|
}
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2015-12-04 11:52:54 +00:00
|
|
|
domostpolymethod = (globalorientation>>7) & DAMETH_MASKPROPS;
|
2014-09-30 04:06:05 +00:00
|
|
|
|
|
|
|
pow2xsplit = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
drawpoly_alpha = 0.f;
|
2016-10-09 07:55:23 +00:00
|
|
|
drawpoly_blend = 0;
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2011-03-19 18:07:12 +00:00
|
|
|
if (have_floor)
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
if (globalposz > getflorzofslope(sectnum, globalposx, globalposy))
|
2015-12-04 11:52:54 +00:00
|
|
|
domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2019-05-03 15:02:44 +00:00
|
|
|
if (domostpolymethod & DAMETH_MASKPROPS)
|
2019-10-04 16:12:03 +00:00
|
|
|
GLInterface.EnableBlend(true);
|
2019-05-03 15:02:44 +00:00
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
polymost_domost(x0, y0, x1, y1); //flor
|
2011-03-19 18:07:12 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
if (globalposz < getceilzofslope(sectnum, globalposx, globalposy))
|
2015-12-04 11:52:54 +00:00
|
|
|
domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling
|
2012-12-14 19:28:09 +00:00
|
|
|
|
2019-05-03 15:02:44 +00:00
|
|
|
if (domostpolymethod & DAMETH_MASKPROPS)
|
2019-10-04 16:12:03 +00:00
|
|
|
GLInterface.EnableBlend(true);
|
2019-05-03 15:02:44 +00:00
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
polymost_domost(x1, y1, x0, y0); //ceil
|
2014-09-30 04:06:05 +00:00
|
|
|
}
|
2012-12-14 19:28:09 +00:00
|
|
|
|
2019-05-03 15:02:44 +00:00
|
|
|
if (domostpolymethod & DAMETH_MASKPROPS)
|
2019-10-04 16:12:03 +00:00
|
|
|
GLInterface.EnableBlend(false);
|
2019-05-03 15:02:44 +00:00
|
|
|
|
2015-12-04 11:52:54 +00:00
|
|
|
domostpolymethod = DAMETH_NOMASK;
|
2011-03-19 18:07:12 +00:00
|
|
|
}
|
|
|
|
|
2014-09-30 04:06:05 +00:00
|
|
|
static void calc_ypanning(int32_t refposz, float ryp0, float ryp1,
|
|
|
|
float x0, float x1, uint8_t ypan, uint8_t yrepeat,
|
2019-10-11 19:04:31 +00:00
|
|
|
int32_t dopancor, const vec2_16_t &tilesize)
|
2012-07-08 21:47:14 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
float const t0 = ((float)(refposz-globalposz))*ryp0 + ghoriz;
|
|
|
|
float const t1 = ((float)(refposz-globalposz))*ryp1 + ghoriz;
|
2019-03-19 17:08:05 +00:00
|
|
|
float t = (float(xtex.d*x0 + otex.d) * (float)yrepeat) / ((x1-x0) * ryp0 * 2048.f);
|
2020-05-23 22:27:24 +00:00
|
|
|
int i = 1<< heightBits(globalpicnum);
|
2019-10-11 19:04:31 +00:00
|
|
|
if (i < tilesize.y) i <<= 1;
|
2012-07-08 21:47:14 +00:00
|
|
|
|
|
|
|
|
2019-03-19 17:08:05 +00:00
|
|
|
float const fy = (float)(ypan * i) * (1.f / 256.f);
|
|
|
|
|
|
|
|
xtex.v = double(t0 - t1) * t;
|
|
|
|
ytex.v = double(x1 - x0) * t;
|
|
|
|
otex.v = -xtex.v * x0 - ytex.v * t0 + fy * otex.d;
|
|
|
|
xtex.v += fy * xtex.d;
|
|
|
|
ytex.v += fy * ytex.d;
|
2012-07-08 21:47:14 +00:00
|
|
|
}
|
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
static inline int32_t testvisiblemost(float const x0, float const x1)
|
2014-09-30 04:14:21 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=vsp[0].n, newi; i; i=newi)
|
2014-09-30 04:14:21 +00:00
|
|
|
{
|
|
|
|
newi = vsp[i].n;
|
2015-07-08 03:34:20 +00:00
|
|
|
if ((x0 < vsp[newi].x) && (vsp[i].x < x1) && (vsp[i].ctag >= 0))
|
|
|
|
return 1;
|
2014-09-30 04:14:21 +00:00
|
|
|
}
|
2015-07-08 03:34:20 +00:00
|
|
|
return 0;
|
2014-09-30 04:14:21 +00:00
|
|
|
}
|
2012-07-08 21:47:14 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
static inline int polymost_getclosestpointonwall(vec2_t const * const pos, int32_t dawall, vec2_t * const n)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
vec2_t const w = { wall[dawall].x, wall[dawall].y };
|
|
|
|
vec2_t const d = { POINT2(dawall).x - w.x, POINT2(dawall).y - w.y };
|
2019-03-19 17:08:05 +00:00
|
|
|
int64_t i = d.x * ((int64_t)pos->x - w.x) + d.y * ((int64_t)pos->y - w.y);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-07-14 18:39:48 +00:00
|
|
|
if (d.x == 0 && d.y == 0)
|
|
|
|
{
|
|
|
|
// In Blood's E1M1 this gets triggered for wall 522.
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (i < 0)
|
|
|
|
return 1;
|
|
|
|
|
2019-03-19 17:08:05 +00:00
|
|
|
int64_t const j = (int64_t)d.x * d.x + (int64_t)d.y * d.y;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (i > j)
|
|
|
|
return 1;
|
|
|
|
|
2020-07-14 18:21:16 +00:00
|
|
|
i = ((i << 15) / j) << 15;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
n->x = w.x + ((d.x * i) >> 30);
|
|
|
|
n->y = w.y + ((d.y * i) >> 30);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2011-05-22 21:52:22 +00:00
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static float fgetceilzofslope(usectorptr_t sec, float dax, float day)
|
2019-07-26 21:54:37 +00:00
|
|
|
{
|
|
|
|
if (!(sec->ceilingstat&2))
|
|
|
|
return float(sec->ceilingz);
|
|
|
|
|
|
|
|
auto const wal = (uwallptr_t)&wall[sec->wallptr];
|
|
|
|
auto const wal2 = (uwallptr_t)&wall[wal->point2];
|
|
|
|
|
|
|
|
vec2_t const w = *(vec2_t const *)wal;
|
|
|
|
vec2_t const d = { wal2->x - w.x, wal2->y - w.y };
|
|
|
|
|
|
|
|
int const i = nsqrtasm(uhypsq(d.x,d.y))<<5;
|
|
|
|
if (i == 0) return sec->ceilingz;
|
|
|
|
|
|
|
|
float const j = (d.x*(day-w.y)-d.y*(dax-w.x))*(1.f/8.f);
|
|
|
|
return float(sec->ceilingz) + (sec->ceilingheinum*j)/i;
|
|
|
|
}
|
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static float fgetflorzofslope(usectorptr_t sec, float dax, float day)
|
2019-07-26 21:54:37 +00:00
|
|
|
{
|
|
|
|
if (!(sec->floorstat&2))
|
|
|
|
return float(sec->floorz);
|
|
|
|
|
|
|
|
auto const wal = (uwallptr_t)&wall[sec->wallptr];
|
|
|
|
auto const wal2 = (uwallptr_t)&wall[wal->point2];
|
|
|
|
|
|
|
|
vec2_t const w = *(vec2_t const *)wal;
|
|
|
|
vec2_t const d = { wal2->x - w.x, wal2->y - w.y };
|
|
|
|
|
|
|
|
int const i = nsqrtasm(uhypsq(d.x,d.y))<<5;
|
|
|
|
if (i == 0) return sec->floorz;
|
|
|
|
|
|
|
|
float const j = (d.x*(day-w.y)-d.y*(dax-w.x))*(1.f/8.f);
|
|
|
|
return float(sec->floorz) + (sec->floorheinum*j)/i;
|
|
|
|
}
|
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static void fgetzsofslope(usectorptr_t sec, float dax, float day, float* ceilz, float *florz)
|
2019-07-26 21:54:37 +00:00
|
|
|
{
|
|
|
|
*ceilz = float(sec->ceilingz); *florz = float(sec->floorz);
|
|
|
|
|
|
|
|
if (((sec->ceilingstat|sec->floorstat)&2) != 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto const wal = (uwallptr_t)&wall[sec->wallptr];
|
|
|
|
auto const wal2 = (uwallptr_t)&wall[wal->point2];
|
|
|
|
|
|
|
|
vec2_t const d = { wal2->x - wal->x, wal2->y - wal->y };
|
|
|
|
|
|
|
|
int const i = nsqrtasm(uhypsq(d.x,d.y))<<5;
|
|
|
|
if (i == 0) return;
|
|
|
|
|
|
|
|
float const j = (d.x*(day-wal->y)-d.y*(dax-wal->x))*(1.f/8.f);
|
|
|
|
if (sec->ceilingstat&2)
|
|
|
|
*ceilz += (sec->ceilingheinum*j)/i;
|
|
|
|
if (sec->floorstat&2)
|
|
|
|
*florz += (sec->floorheinum*j)/i;
|
|
|
|
}
|
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesiz)
|
2019-09-03 04:09:25 +00:00
|
|
|
{
|
|
|
|
flatskyrender = 0;
|
|
|
|
vec2f_t xys[8];
|
|
|
|
|
2020-04-11 22:21:35 +00:00
|
|
|
auto f = GLInterface.useMapFog;
|
|
|
|
GLInterface.useMapFog = false;
|
2019-09-03 04:09:25 +00:00
|
|
|
// Transform polygon to sky coordinates
|
|
|
|
for (int i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
vec3f_t const o = { dpxy[i].x-ghalfx, dpxy[i].y-ghalfy, ghalfx / gvrcorrection };
|
|
|
|
|
|
|
|
//Up/down rotation
|
|
|
|
vec3d_t v = { o.x, o.y * gchang - o.z * gshang, o.z * gchang + o.y * gshang };
|
|
|
|
float const r = (ghalfx / gvrcorrection) / v.z;
|
|
|
|
xys[i].x = v.x * r + ghalfx;
|
|
|
|
xys[i].y = v.y * r + ghalfy;
|
|
|
|
}
|
|
|
|
|
2020-09-01 13:00:35 +00:00
|
|
|
float const fglobalang = FixedToFloat(qglobalang);
|
2019-09-03 04:09:25 +00:00
|
|
|
int32_t dapyscale, dapskybits, dapyoffs, daptileyscale;
|
2020-07-14 22:06:19 +00:00
|
|
|
int16_t const * dapskyoff = getpsky(globalpicnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale);
|
2019-09-03 04:09:25 +00:00
|
|
|
|
2019-09-07 13:36:37 +00:00
|
|
|
ghoriz = (qglobalhoriz*(1.f/65536.f)-float(ydimen>>1))*dapyscale*(1.f/65536.f)+float(ydimen>>1)+ghorizcorrect;
|
2019-09-03 04:09:25 +00:00
|
|
|
|
|
|
|
float const dd = fxdimen*.0000001f; //Adjust sky depth based on screen size!
|
|
|
|
float vv[2];
|
2020-05-23 22:27:24 +00:00
|
|
|
float t = (float)((1<<(widthBits(globalpicnum)))<<dapskybits);
|
2019-09-03 04:09:25 +00:00
|
|
|
vv[1] = dd*((float)xdimscale*fviewingrange) * (1.f/(daptileyscale*65536.f));
|
2019-10-11 19:04:31 +00:00
|
|
|
vv[0] = dd*((float)((tilesiz.y>>1)+dapyoffs)) - vv[1]*ghoriz;
|
2020-05-23 22:27:24 +00:00
|
|
|
int ti = (1<<(heightBits(globalpicnum))); if (ti != tilesiz.y) ti += ti;
|
2019-09-03 04:09:25 +00:00
|
|
|
vec3f_t o;
|
|
|
|
|
|
|
|
skyclamphack = 0;
|
|
|
|
|
|
|
|
xtex.d = xtex.v = 0;
|
|
|
|
ytex.d = ytex.u = 0;
|
|
|
|
otex.d = dd;
|
|
|
|
xtex.u = otex.d * (t * double(((uint64_t)xdimscale * yxaspect) * viewingrange)) *
|
|
|
|
(1.0 / (16384.0 * 65536.0 * 65536.0 * 5.0 * 1024.0));
|
|
|
|
ytex.v = vv[1];
|
2019-10-23 19:11:37 +00:00
|
|
|
otex.v = hw_parallaxskypanning ? vv[0] + dd*(float)global_cf_ypanning*(float)ti*(1.f/256.f) : vv[0];
|
2019-09-03 04:09:25 +00:00
|
|
|
|
|
|
|
float x0 = xys[0].x, x1 = xys[0].x;
|
|
|
|
|
|
|
|
for (bssize_t i=n-1; i>=1; i--)
|
|
|
|
{
|
|
|
|
if (xys[i].x < x0) x0 = xys[i].x;
|
|
|
|
if (xys[i].x > x1) x1 = xys[i].x;
|
|
|
|
}
|
|
|
|
|
2020-05-23 22:27:24 +00:00
|
|
|
int const npot = (1<<(widthBits(globalpicnum))) != tileWidth(globalpicnum);
|
2019-10-23 19:11:37 +00:00
|
|
|
int const xpanning = (hw_parallaxskypanning?global_cf_xpanning:0);
|
2019-09-08 01:00:57 +00:00
|
|
|
|
2019-09-03 04:09:25 +00:00
|
|
|
int picnumbak = globalpicnum;
|
|
|
|
ti = globalpicnum;
|
|
|
|
o.y = fviewingrange/(ghalfx*256.f); o.z = 1.f/o.y;
|
|
|
|
|
|
|
|
int y = ((int32_t)(((x0-ghalfx)*o.y)+fglobalang)>>(11-dapskybits));
|
|
|
|
float fx = x0;
|
|
|
|
|
2020-01-26 12:45:33 +00:00
|
|
|
skyclamphack = true; // Hack to make Blood's skies show properly.
|
2019-09-03 04:09:25 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
globalpicnum = dapskyoff[y&((1<<dapskybits)-1)]+ti;
|
2019-10-19 08:21:07 +00:00
|
|
|
if (skytile > 0)
|
|
|
|
globalpicnum = skytile;
|
2019-09-08 01:00:57 +00:00
|
|
|
if (npot)
|
|
|
|
{
|
|
|
|
fx = ((float)((y<<(11-dapskybits))-fglobalang))*o.z+ghalfx;
|
|
|
|
int tang = (y<<(11-dapskybits))&2047;
|
|
|
|
otex.u = otex.d*(t*((float)(tang)) * (1.f/2048.f) + xpanning) - xtex.u*fx;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
otex.u = otex.d*(t*((float)(fglobalang-(y<<(11-dapskybits)))) * (1.f/2048.f) + xpanning) - xtex.u*ghalfx;
|
2019-09-03 04:09:25 +00:00
|
|
|
y++;
|
|
|
|
o.x = fx; fx = ((float)((y<<(11-dapskybits))-fglobalang))*o.z+ghalfx;
|
|
|
|
|
|
|
|
if (fx > x1) { fx = x1; ti = -1; }
|
|
|
|
|
|
|
|
vec3d_t otexbak = otex, xtexbak = xtex, ytexbak = ytex;
|
|
|
|
|
|
|
|
// Transform texture mapping factors
|
|
|
|
vec2f_t fxy[3] = { { ghalfx * (1.f - 0.25f), ghalfy * (1.f - 0.25f) },
|
|
|
|
{ ghalfx, ghalfy * (1.f + 0.25f) },
|
|
|
|
{ ghalfx * (1.f + 0.25f), ghalfy * (1.f - 0.25f) } };
|
|
|
|
|
|
|
|
vec3d_t duv[3] = {
|
|
|
|
{ (fxy[0].x * xtex.d + fxy[0].y * ytex.d + otex.d),
|
|
|
|
(fxy[0].x * xtex.u + fxy[0].y * ytex.u + otex.u),
|
|
|
|
(fxy[0].x * xtex.v + fxy[0].y * ytex.v + otex.v)
|
|
|
|
},
|
|
|
|
{ (fxy[1].x * xtex.d + fxy[1].y * ytex.d + otex.d),
|
|
|
|
(fxy[1].x * xtex.u + fxy[1].y * ytex.u + otex.u),
|
|
|
|
(fxy[1].x * xtex.v + fxy[1].y * ytex.v + otex.v)
|
|
|
|
},
|
|
|
|
{ (fxy[2].x * xtex.d + fxy[2].y * ytex.d + otex.d),
|
|
|
|
(fxy[2].x * xtex.u + fxy[2].y * ytex.u + otex.u),
|
|
|
|
(fxy[2].x * xtex.v + fxy[2].y * ytex.v + otex.v)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
vec2f_t fxyt[3];
|
|
|
|
vec3d_t duvt[3];
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
vec2f_t const o = { fxy[i].x-ghalfx, fxy[i].y-ghalfy };
|
|
|
|
vec3f_t const o2 = { o.x, o.y, ghalfx / gvrcorrection };
|
|
|
|
|
|
|
|
//Up/down rotation (backwards)
|
|
|
|
vec3d_t v = { o2.x, o2.y * gchang + o2.z * gshang, o2.z * gchang - o2.y * gshang };
|
|
|
|
float const r = (ghalfx / gvrcorrection) / v.z;
|
|
|
|
fxyt[i].x = v.x * r + ghalfx;
|
|
|
|
fxyt[i].y = v.y * r + ghalfy;
|
|
|
|
duvt[i].d = duv[i].d*r;
|
|
|
|
duvt[i].u = duv[i].u*r;
|
|
|
|
duvt[i].v = duv[i].v*r;
|
|
|
|
}
|
|
|
|
|
|
|
|
vec3f_t oxyz[2] = { { (float)(fxyt[1].y - fxyt[2].y), (float)(fxyt[2].y - fxyt[0].y), (float)(fxyt[0].y - fxyt[1].y) },
|
|
|
|
{ (float)(fxyt[2].x - fxyt[1].x), (float)(fxyt[0].x - fxyt[2].x), (float)(fxyt[1].x - fxyt[0].x) } };
|
|
|
|
|
|
|
|
float const rr = 1.f / (oxyz[0].x * fxyt[0].x + oxyz[0].y * fxyt[1].x + oxyz[0].z * fxyt[2].x);
|
|
|
|
|
|
|
|
xtex.d = (oxyz[0].x * duvt[0].d + oxyz[0].y * duvt[1].d + oxyz[0].z * duvt[2].d) * rr;
|
|
|
|
xtex.u = (oxyz[0].x * duvt[0].u + oxyz[0].y * duvt[1].u + oxyz[0].z * duvt[2].u) * rr;
|
|
|
|
xtex.v = (oxyz[0].x * duvt[0].v + oxyz[0].y * duvt[1].v + oxyz[0].z * duvt[2].v) * rr;
|
|
|
|
|
|
|
|
ytex.d = (oxyz[1].x * duvt[0].d + oxyz[1].y * duvt[1].d + oxyz[1].z * duvt[2].d) * rr;
|
|
|
|
ytex.u = (oxyz[1].x * duvt[0].u + oxyz[1].y * duvt[1].u + oxyz[1].z * duvt[2].u) * rr;
|
|
|
|
ytex.v = (oxyz[1].x * duvt[0].v + oxyz[1].y * duvt[1].v + oxyz[1].z * duvt[2].v) * rr;
|
|
|
|
|
|
|
|
otex.d = duvt[0].d - fxyt[0].x * xtex.d - fxyt[0].y * ytex.d;
|
|
|
|
otex.u = duvt[0].u - fxyt[0].x * xtex.u - fxyt[0].y * ytex.u;
|
|
|
|
otex.v = duvt[0].v - fxyt[0].x * xtex.v - fxyt[0].y * ytex.v;
|
|
|
|
|
|
|
|
vec2f_t cxy[8];
|
|
|
|
vec2f_t cxy2[8];
|
|
|
|
int n2 = 0, n3 = 0;
|
|
|
|
|
|
|
|
// Clip to o.x
|
|
|
|
for (bssize_t i=0; i<n; i++)
|
|
|
|
{
|
|
|
|
int const j = i < n-1 ? i + 1 : 0;
|
|
|
|
|
|
|
|
if (xys[i].x >= o.x)
|
|
|
|
cxy[n2++] = xys[i];
|
|
|
|
|
|
|
|
if ((xys[i].x >= o.x) != (xys[j].x >= o.x))
|
|
|
|
{
|
|
|
|
float const r = (o.x - xys[i].x) / (xys[j].x - xys[i].x);
|
|
|
|
cxy[n2++] = { o.x, (xys[j].y - xys[i].y) * r + xys[i].y };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clip to fx
|
|
|
|
for (bssize_t i=0; i<n2; i++)
|
|
|
|
{
|
|
|
|
int const j = i < n2-1 ? i + 1 : 0;
|
|
|
|
|
|
|
|
if (cxy[i].x <= fx)
|
|
|
|
cxy2[n3++] = cxy[i];
|
|
|
|
|
|
|
|
if ((cxy[i].x <= fx) != (cxy[j].x <= fx))
|
|
|
|
{
|
|
|
|
float const r = (fx - cxy[i].x) / (cxy[j].x - cxy[i].x);
|
|
|
|
cxy2[n3++] = { fx, (cxy[j].y - cxy[i].y) * r + cxy[i].y };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Transform back to polymost coordinates
|
|
|
|
for (int i = 0; i < n3; i++)
|
|
|
|
{
|
|
|
|
vec3f_t const o = { cxy2[i].x-ghalfx, cxy2[i].y-ghalfy, ghalfx / gvrcorrection };
|
|
|
|
|
|
|
|
//Up/down rotation
|
|
|
|
vec3d_t v = { o.x, o.y * gchang + o.z * gshang, o.z * gchang - o.y * gshang };
|
|
|
|
float const r = (ghalfx / gvrcorrection) / v.z;
|
|
|
|
cxy[i].x = v.x * r + ghalfx;
|
|
|
|
cxy[i].y = v.y * r + ghalfy;
|
|
|
|
}
|
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(cxy, n3, method|DAMETH_WALL, tilesiz);
|
2019-09-03 04:09:25 +00:00
|
|
|
|
|
|
|
otex = otexbak, xtex = xtexbak, ytex = ytexbak;
|
|
|
|
}
|
|
|
|
while (ti >= 0);
|
2020-01-26 12:45:33 +00:00
|
|
|
skyclamphack = false;
|
2019-09-03 04:09:25 +00:00
|
|
|
|
|
|
|
globalpicnum = picnumbak;
|
|
|
|
|
|
|
|
flatskyrender = 1;
|
2020-04-11 22:21:35 +00:00
|
|
|
GLInterface.useMapFog = f;
|
2019-09-03 04:09:25 +00:00
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
static void polymost_drawalls(int32_t const bunch)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
|
|
|
drawpoly_alpha = 0.f;
|
2016-10-09 07:55:23 +00:00
|
|
|
drawpoly_blend = 0;
|
2013-03-04 09:10:54 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t const sectnum = thesector[bunchfirst[bunch]];
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const sec = (usectorptr_t)§or[sectnum];
|
2020-09-01 13:00:35 +00:00
|
|
|
float const fglobalang = FixedToFloat(qglobalang);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-05-25 14:59:09 +00:00
|
|
|
polymost_outputGLDebugMessage(3, "polymost_drawalls(bunch:%d)", bunch);
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//DRAW WALLS SECTION!
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t z=bunchfirst[bunch]; z>=0; z=bunchp2[z])
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t const wallnum = thewall[z];
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const wal = (uwallptr_t)&wall[wallnum];
|
|
|
|
auto const wal2 = (uwallptr_t)&wall[wal->point2];
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t const nextsectnum = wal->nextsector;
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const nextsec = nextsectnum>=0 ? (usectorptr_t)§or[nextsectnum] : NULL;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//Offset&Rotate 3D coordinates to screen 3D space
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2f_t walpos = { (float)(wal->x-globalposx), (float)(wal->y-globalposy) };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2f_t p0 = { walpos.y * gcosang - walpos.x * gsinang, walpos.x * gcosang2 + walpos.y * gsinang2 };
|
2015-03-24 00:40:33 +00:00
|
|
|
vec2f_t const op0 = p0;
|
|
|
|
|
2019-03-19 17:10:08 +00:00
|
|
|
walpos = { (float)(wal2->x - globalposx),
|
|
|
|
(float)(wal2->y - globalposy) };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2f_t p1 = { walpos.y * gcosang - walpos.x * gsinang, walpos.x * gcosang2 + walpos.y * gsinang2 };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Clip to close parallel-screen plane
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec2f_t n0, n1;
|
|
|
|
float t0, t1;
|
|
|
|
|
|
|
|
if (p0.y < SCISDIST)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
if (p1.y < SCISDIST) continue;
|
2019-03-19 17:10:08 +00:00
|
|
|
t0 = (SCISDIST-p0.y)/(p1.y-p0.y);
|
|
|
|
p0 = { (p1.x-p0.x)*t0+p0.x, SCISDIST };
|
|
|
|
n0 = { (wal2->x-wal->x)*t0+wal->x,
|
|
|
|
(wal2->y-wal->y)*t0+wal->y };
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
t0 = 0.f;
|
|
|
|
n0 = { (float)wal->x, (float)wal->y };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2019-03-19 17:10:08 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (p1.y < SCISDIST)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-03-19 17:10:08 +00:00
|
|
|
t1 = (SCISDIST-op0.y)/(p1.y-op0.y);
|
|
|
|
p1 = { (p1.x-op0.x)*t1+op0.x, SCISDIST };
|
|
|
|
n1 = { (wal2->x-wal->x)*t1+wal->x,
|
|
|
|
(wal2->y-wal->y)*t1+wal->y };
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
t1 = 1.f;
|
|
|
|
n1 = { (float)wal2->x, (float)wal2->y };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
float ryp0 = 1.f/p0.y, ryp1 = 1.f/p1.y;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Generate screen coordinates for front side of wall
|
2015-03-24 00:40:33 +00:00
|
|
|
float const x0 = ghalfx*p0.x*ryp0 + ghalfx, x1 = ghalfx*p1.x*ryp1 + ghalfx;
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (x1 <= x0) continue;
|
|
|
|
|
|
|
|
ryp0 *= gyxscale; ryp1 *= gyxscale;
|
|
|
|
|
2019-07-26 21:54:37 +00:00
|
|
|
float cz, fz;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-07-26 21:54:37 +00:00
|
|
|
fgetzsofslope((usectorptr_t)§or[sectnum],n0.x,n0.y,&cz,&fz);
|
|
|
|
float const cy0 = (cz-globalposz)*ryp0 + ghoriz, fy0 = (fz-globalposz)*ryp0 + ghoriz;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-07-26 21:54:37 +00:00
|
|
|
fgetzsofslope((usectorptr_t)§or[sectnum],n1.x,n1.y,&cz,&fz);
|
|
|
|
float const cy1 = (cz-globalposz)*ryp1 + ghoriz, fy1 = (fz-globalposz)*ryp1 + ghoriz;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-03-19 17:08:43 +00:00
|
|
|
xtex2.d = (ryp0 - ryp1)*gxyaspect / (x0 - x1);
|
|
|
|
ytex2.d = 0;
|
|
|
|
otex2.d = ryp0 * gxyaspect - xtex2.d*x0;
|
|
|
|
|
|
|
|
xtex2.u = ytex2.u = otex2.u = 0;
|
|
|
|
xtex2.v = ytex2.v = otex2.v = 0;
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2019-03-19 17:08:43 +00:00
|
|
|
// Floor
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
globalpicnum = sec->floorpicnum;
|
|
|
|
globalshade = sec->floorshade;
|
2020-09-20 18:39:11 +00:00
|
|
|
globalfloorpal = globalpal = sec->floorpal;
|
2006-04-24 19:04:22 +00:00
|
|
|
globalorientation = sec->floorstat;
|
2020-06-05 17:06:31 +00:00
|
|
|
|
|
|
|
GLInterface.SetVisibility(sectorVisibility(sectnum));
|
2013-05-15 02:19:14 +00:00
|
|
|
|
2019-06-25 11:30:22 +00:00
|
|
|
tileUpdatePicnum(&globalpicnum, sectnum);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-09-19 20:02:45 +00:00
|
|
|
int32_t dapyscale, dapskybits, dapyoffs, daptileyscale;
|
2020-07-14 22:06:19 +00:00
|
|
|
int16_t const * dapskyoff = getpsky(globalpicnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale);
|
2011-05-22 21:52:22 +00:00
|
|
|
|
2014-04-05 11:28:10 +00:00
|
|
|
global_cf_fogpal = sec->fogpal;
|
2011-03-19 18:07:12 +00:00
|
|
|
global_cf_shade = sec->floorshade, global_cf_pal = sec->floorpal; global_cf_z = sec->floorz; // REFACT
|
|
|
|
global_cf_xpanning = sec->floorxpanning; global_cf_ypanning = sec->floorypanning, global_cf_heinum = sec->floorheinum;
|
2019-07-26 21:54:37 +00:00
|
|
|
global_getzofslope_func = &fgetflorzofslope;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-09-19 20:02:45 +00:00
|
|
|
if (globalpicnum >= r_rortexture && globalpicnum < r_rortexture + r_rortexturerange && r_rorphase == 0)
|
|
|
|
{
|
|
|
|
xtex.d = (ryp0-ryp1)*gxyaspect / (x0-x1);
|
|
|
|
ytex.d = 0;
|
|
|
|
otex.d = ryp0*gxyaspect - xtex.d*x0;
|
|
|
|
|
|
|
|
xtex.u = ytex.u = otex.u = 0;
|
|
|
|
xtex.v = ytex.v = otex.v = 0;
|
|
|
|
polymost_domost(x0, fy0, x1, fy1);
|
|
|
|
}
|
|
|
|
else if (!(globalorientation&1))
|
2011-05-22 21:52:22 +00:00
|
|
|
{
|
2019-03-19 17:07:53 +00:00
|
|
|
int32_t fz = getflorzofslope(sectnum, globalposx, globalposy);
|
|
|
|
if (globalposz <= fz)
|
2015-07-08 03:34:20 +00:00
|
|
|
polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, fy0, fy1, sectnum | MAXSECTORS);
|
2011-05-22 21:52:22 +00:00
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
else if ((nextsectnum < 0) || (!(sector[nextsectnum].floorstat&1)))
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
//Use clamping for tiled sky textures
|
2017-11-29 07:29:51 +00:00
|
|
|
//(don't wrap around edges if the sky use multiple panels)
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=(1<<dapskybits)-1; i>0; i--)
|
2015-03-24 00:40:33 +00:00
|
|
|
if (dapskyoff[i] != dapskyoff[i-1])
|
|
|
|
{ skyclamphack = r_parallaxskyclamping; break; }
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-03-19 17:08:51 +00:00
|
|
|
skyzbufferhack = 1;
|
|
|
|
|
2019-10-23 19:11:37 +00:00
|
|
|
//if (!hw_hightile || !hicfindskybox(globalpicnum, globalpal))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-09-19 20:02:45 +00:00
|
|
|
float const ghorizbak = ghoriz;
|
2019-10-10 22:15:20 +00:00
|
|
|
pow2xsplit = 0;
|
|
|
|
skyclamphack = 0;
|
|
|
|
flatskyrender = 1;
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(0.f);
|
2019-10-10 22:15:20 +00:00
|
|
|
polymost_domost(x0,fy0,x1,fy1);
|
|
|
|
flatskyrender = 0;
|
2019-09-19 20:02:45 +00:00
|
|
|
ghoriz = ghorizbak;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2019-10-17 18:29:58 +00:00
|
|
|
#if 0
|
2006-04-24 19:04:22 +00:00
|
|
|
else //NOTE: code copied from ceiling code... lots of duplicated stuff :/
|
2007-12-12 17:42:14 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
//Skybox code for parallax floor!
|
2015-03-24 00:40:48 +00:00
|
|
|
float sky_t0, sky_t1; // _nx0, _ny0, _nx1, _ny1;
|
|
|
|
float sky_ryp0, sky_ryp1, sky_x0, sky_x1, sky_cy0, sky_fy0, sky_cy1, sky_fy1, sky_ox0, sky_ox1;
|
|
|
|
static vec2f_t const skywal[4] = { { -512, -512 }, { 512, -512 }, { 512, 512 }, { -512, 512 } };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
pow2xsplit = 0;
|
|
|
|
skyclamphack = 1;
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=0; i<4; i++)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
walpos = skywal[i&3];
|
|
|
|
vec2f_t skyp0 = { walpos.y * gcosang - walpos.x * gsinang,
|
|
|
|
walpos.x * gcosang2 + walpos.y * gsinang2 };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
walpos = skywal[(i + 1) & 3];
|
|
|
|
vec2f_t skyp1 = { walpos.y * gcosang - walpos.x * gsinang,
|
|
|
|
walpos.x * gcosang2 + walpos.y * gsinang2 };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec2f_t const oskyp0 = skyp0;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Clip to close parallel-screen plane
|
2015-03-24 00:40:33 +00:00
|
|
|
if (skyp0.y < SCISDIST)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
if (skyp1.y < SCISDIST) continue;
|
2019-03-19 17:10:08 +00:00
|
|
|
sky_t0 = (SCISDIST - skyp0.y) / (skyp1.y - skyp0.y);
|
|
|
|
skyp0 = { (skyp1.x - skyp0.x) * sky_t0 + skyp0.x, SCISDIST };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
else { sky_t0 = 0.f; }
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (skyp1.y < SCISDIST)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-03-19 17:10:08 +00:00
|
|
|
sky_t1 = (SCISDIST - oskyp0.y) / (skyp1.y - oskyp0.y);
|
|
|
|
skyp1 = { (skyp1.x - oskyp0.x) * sky_t1 + oskyp0.x, SCISDIST };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-11-01 19:56:33 +00:00
|
|
|
else { sky_t1 = 1.f; }
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_ryp0 = 1.f/skyp0.y; sky_ryp1 = 1.f/skyp1.y;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Generate screen coordinates for front side of wall
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_x0 = ghalfx*skyp0.x*sky_ryp0 + ghalfx;
|
|
|
|
sky_x1 = ghalfx*skyp1.x*sky_ryp1 + ghalfx;
|
|
|
|
if ((sky_x1 <= sky_x0) || (sky_x0 >= x1) || (x0 >= sky_x1)) continue;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_ryp0 *= gyxscale; sky_ryp1 *= gyxscale;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_cy0 = -8192.f*sky_ryp0 + ghoriz;
|
|
|
|
sky_fy0 = 8192.f*sky_ryp0 + ghoriz;
|
|
|
|
sky_cy1 = -8192.f*sky_ryp1 + ghoriz;
|
|
|
|
sky_fy1 = 8192.f*sky_ryp1 + ghoriz;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_ox0 = sky_x0; sky_ox1 = sky_x1;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-11-01 19:56:33 +00:00
|
|
|
//Make sure: x0<=_x0<_x1<=x1
|
2015-07-08 03:34:20 +00:00
|
|
|
float nfy[2] = { fy0, fy1 };
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
if (sky_x0 < x0)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const t = (x0-sky_x0)/(sky_x1-sky_x0);
|
|
|
|
sky_cy0 += (sky_cy1-sky_cy0)*t;
|
|
|
|
sky_fy0 += (sky_fy1-sky_fy0)*t;
|
|
|
|
sky_x0 = x0;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-07-08 03:34:20 +00:00
|
|
|
else if (sky_x0 > x0) nfy[0] += (sky_x0-x0)*(fy1-fy0)/(x1-x0);
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
if (sky_x1 > x1)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const t = (x1-sky_x1)/(sky_x1-sky_x0);
|
|
|
|
sky_cy1 += (sky_cy1-sky_cy0)*t;
|
|
|
|
sky_fy1 += (sky_fy1-sky_fy0)*t;
|
|
|
|
sky_x1 = x1;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-07-08 03:34:20 +00:00
|
|
|
else if (sky_x1 < x1) nfy[1] += (sky_x1-x1)*(fy1-fy0)/(x1-x0);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
// (skybox floor)
|
|
|
|
//(_x0,_fy0)-(_x1,_fy1)
|
|
|
|
// (skybox wall)
|
|
|
|
//(_x0,_cy0)-(_x1,_cy1)
|
|
|
|
// (skybox ceiling)
|
|
|
|
//(_x0,nfy0)-(_x1,nfy1)
|
|
|
|
|
2015-11-01 19:56:33 +00:00
|
|
|
//floor of skybox
|
|
|
|
drawingskybox = 6; //floor/6th texture/index 5 of skybox
|
2015-03-24 00:40:33 +00:00
|
|
|
float const ft[4] = { 512 / 16, 512 / -16, fcosglobalang * (1.f / 2147483648.f),
|
2015-11-01 19:56:33 +00:00
|
|
|
fsinglobalang * (1.f / 2147483648.f) };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
xtex.d = 0;
|
2019-03-19 17:08:05 +00:00
|
|
|
ytex.d = gxyaspect*(1.0/4194304.0);
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.d = -ghoriz*ytex.d;
|
2015-11-01 19:56:33 +00:00
|
|
|
xtex.u = ft[3]*fviewingrange*(-1.0/65536.0);
|
|
|
|
xtex.v = ft[2]*fviewingrange*(-1.0/65536.0);
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.u = ft[0]*ytex.d; ytex.v = ft[1]*ytex.d;
|
|
|
|
otex.u = ft[0]*otex.d; otex.v = ft[1]*otex.d;
|
|
|
|
otex.u += (ft[2]-xtex.u)*ghalfx;
|
|
|
|
otex.v -= (ft[3]+xtex.v)*ghalfx;
|
|
|
|
xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; //y-flip skybox floor
|
|
|
|
|
2015-11-01 19:56:33 +00:00
|
|
|
if ((sky_fy0 > nfy[0]) && (sky_fy1 > nfy[1]))
|
|
|
|
polymost_domost(sky_x0,sky_fy0,sky_x1,sky_fy1);
|
2015-07-08 03:34:20 +00:00
|
|
|
else if ((sky_fy0 > nfy[0]) != (sky_fy1 > nfy[1]))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-11-01 19:56:33 +00:00
|
|
|
//(ox,oy) is intersection of: (_x0,_fy0)-(_x1,_fy1)
|
2006-04-24 19:04:22 +00:00
|
|
|
// (_x0,nfy0)-(_x1,nfy1)
|
2015-07-08 03:34:20 +00:00
|
|
|
float const t = (sky_fy0-nfy[0])/(nfy[1]-nfy[0]-sky_fy1+sky_fy0);
|
2015-11-01 19:56:33 +00:00
|
|
|
vec2f_t const o = { sky_x0 + (sky_x1-sky_x0)*t, sky_fy0 + (sky_fy1-sky_fy0)*t };
|
2015-07-08 03:34:20 +00:00
|
|
|
if (nfy[0] > sky_fy0)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2015-11-01 19:56:33 +00:00
|
|
|
polymost_domost(sky_x0,nfy[0],o.x,o.y);
|
|
|
|
polymost_domost(o.x,o.y,sky_x1,sky_fy1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
polymost_domost(sky_x0,sky_fy0,o.x,o.y);
|
|
|
|
polymost_domost(o.x,o.y,sky_x1,nfy[1]);
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
2015-11-01 19:56:33 +00:00
|
|
|
else
|
|
|
|
polymost_domost(sky_x0,nfy[0],sky_x1,nfy[1]);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//wall of skybox
|
|
|
|
drawingskybox = i+1; //i+1th texture/index i of skybox
|
2019-03-19 17:08:05 +00:00
|
|
|
xtex.d = (sky_ryp0-sky_ryp1)*gxyaspect*(1.0/512.0) / (sky_ox0-sky_ox1);
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.d = 0;
|
2019-03-19 17:08:05 +00:00
|
|
|
otex.d = sky_ryp0*gxyaspect*(1.0/512.0) - xtex.d*sky_ox0;
|
|
|
|
xtex.u = (sky_t0*sky_ryp0 - sky_t1*sky_ryp1)*gxyaspect*(64.0/512.0) / (sky_ox0-sky_ox1);
|
|
|
|
otex.u = sky_t0*sky_ryp0*gxyaspect*(64.0/512.0) - xtex.u*sky_ox0;
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.u = 0;
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_t0 = -8192.f*sky_ryp0 + ghoriz;
|
|
|
|
sky_t1 = -8192.f*sky_ryp1 + ghoriz;
|
|
|
|
float const t = ((xtex.d*sky_ox0 + otex.d)*8.f) / ((sky_ox1-sky_ox0) * sky_ryp0 * 2048.f);
|
|
|
|
xtex.v = (sky_t0-sky_t1)*t;
|
|
|
|
ytex.v = (sky_ox1-sky_ox0)*t;
|
|
|
|
otex.v = -xtex.v*sky_ox0 - ytex.v*sky_t0;
|
2015-11-01 19:56:33 +00:00
|
|
|
|
|
|
|
if ((sky_cy0 > nfy[0]) && (sky_cy1 > nfy[1]))
|
|
|
|
polymost_domost(sky_x0,sky_cy0,sky_x1,sky_cy1);
|
2015-07-08 03:34:20 +00:00
|
|
|
else if ((sky_cy0 > nfy[0]) != (sky_cy1 > nfy[1]))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
|
|
|
//(ox,oy) is intersection of: (_x0,_fy0)-(_x1,_fy1)
|
|
|
|
// (_x0,nfy0)-(_x1,nfy1)
|
2015-07-08 03:34:20 +00:00
|
|
|
float const t = (sky_cy0-nfy[0])/(nfy[1]-nfy[0]-sky_cy1+sky_cy0);
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2f_t const o = { sky_x0 + (sky_x1 - sky_x0) * t, sky_cy0 + (sky_cy1 - sky_cy0) * t };
|
2015-11-01 19:56:33 +00:00
|
|
|
if (nfy[0] > sky_cy0)
|
|
|
|
{
|
|
|
|
polymost_domost(sky_x0,nfy[0],o.x,o.y);
|
|
|
|
polymost_domost(o.x,o.y,sky_x1,sky_cy1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
polymost_domost(sky_x0,sky_cy0,o.x,o.y);
|
|
|
|
polymost_domost(o.x,o.y,sky_x1,nfy[1]);
|
|
|
|
}
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
2015-11-01 19:56:33 +00:00
|
|
|
else
|
|
|
|
polymost_domost(sky_x0,nfy[0],sky_x1,nfy[1]);
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2015-11-01 19:56:33 +00:00
|
|
|
//Ceiling of skybox
|
|
|
|
drawingskybox = 5; //ceiling/5th texture/index 4 of skybox
|
2015-03-24 00:40:33 +00:00
|
|
|
float const ft[4] = { 512 / 16, -512 / -16, fcosglobalang * (1.f / 2147483648.f),
|
|
|
|
fsinglobalang * (1.f / 2147483648.f) };
|
|
|
|
|
|
|
|
xtex.d = 0;
|
2019-03-19 17:08:05 +00:00
|
|
|
ytex.d = gxyaspect*(-1.0/4194304.0);
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.d = -ghoriz*ytex.d;
|
2015-11-01 19:56:33 +00:00
|
|
|
xtex.u = ft[3]*fviewingrange*(-1.0/65536.0);
|
|
|
|
xtex.v = ft[2]*fviewingrange*(-1.0/65536.0);
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.u = ft[0]*ytex.d; ytex.v = ft[1]*ytex.d;
|
|
|
|
otex.u = ft[0]*otex.d; otex.v = ft[1]*otex.d;
|
|
|
|
otex.u += (ft[2]-xtex.u)*ghalfx;
|
|
|
|
otex.v -= (ft[3]+xtex.v)*ghalfx;
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
polymost_domost(x0,fy0,x1,fy1);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
skyclamphack = 0;
|
|
|
|
drawingskybox = 0;
|
|
|
|
}
|
2019-10-17 18:29:58 +00:00
|
|
|
#endif
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
skyclamphack = 0;
|
2019-03-19 17:08:51 +00:00
|
|
|
skyzbufferhack = 0;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2015-11-01 19:56:33 +00:00
|
|
|
// Ceiling
|
|
|
|
|
|
|
|
globalpicnum = sec->ceilingpicnum;
|
|
|
|
globalshade = sec->ceilingshade;
|
2020-09-20 18:39:11 +00:00
|
|
|
globalfloorpal = globalpal = sec->ceilingpal;
|
2006-04-24 19:04:22 +00:00
|
|
|
globalorientation = sec->ceilingstat;
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(sectorVisibility(sectnum));
|
2013-05-15 02:19:14 +00:00
|
|
|
|
2019-06-25 11:30:22 +00:00
|
|
|
tileUpdatePicnum(&globalpicnum, sectnum);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2019-09-19 20:02:45 +00:00
|
|
|
dapskyoff = getpsky(globalpicnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale);
|
2011-05-22 21:52:22 +00:00
|
|
|
|
2014-04-05 11:28:10 +00:00
|
|
|
global_cf_fogpal = sec->fogpal;
|
2011-03-19 18:07:12 +00:00
|
|
|
global_cf_shade = sec->ceilingshade, global_cf_pal = sec->ceilingpal; global_cf_z = sec->ceilingz; // REFACT
|
|
|
|
global_cf_xpanning = sec->ceilingxpanning; global_cf_ypanning = sec->ceilingypanning, global_cf_heinum = sec->ceilingheinum;
|
2019-07-26 21:54:37 +00:00
|
|
|
global_getzofslope_func = &fgetceilzofslope;
|
2019-09-19 20:02:45 +00:00
|
|
|
|
|
|
|
if (globalpicnum >= r_rortexture && globalpicnum < r_rortexture + r_rortexturerange && r_rorphase == 0)
|
|
|
|
{
|
|
|
|
xtex.d = (ryp0-ryp1)*gxyaspect / (x0-x1);
|
|
|
|
ytex.d = 0;
|
|
|
|
otex.d = ryp0*gxyaspect - xtex.d*x0;
|
|
|
|
|
|
|
|
xtex.u = ytex.u = otex.u = 0;
|
|
|
|
xtex.v = ytex.v = otex.v = 0;
|
|
|
|
polymost_domost(x1, cy1, x0, cy0);
|
|
|
|
}
|
|
|
|
else if (!(globalorientation&1))
|
2011-05-22 21:52:22 +00:00
|
|
|
{
|
2019-03-19 17:07:53 +00:00
|
|
|
int32_t cz = getceilzofslope(sectnum, globalposx, globalposy);
|
|
|
|
if (globalposz >= cz)
|
2015-07-08 03:34:20 +00:00
|
|
|
polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, cy0, cy1, sectnum);
|
2011-05-22 21:52:22 +00:00
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
else if ((nextsectnum < 0) || (!(sector[nextsectnum].ceilingstat&1)))
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
//Use clamping for tiled sky textures
|
2017-11-29 07:29:51 +00:00
|
|
|
//(don't wrap around edges if the sky use multiple panels)
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=(1<<dapskybits)-1; i>0; i--)
|
2015-03-24 00:40:33 +00:00
|
|
|
if (dapskyoff[i] != dapskyoff[i-1])
|
|
|
|
{ skyclamphack = r_parallaxskyclamping; break; }
|
2012-12-14 19:28:09 +00:00
|
|
|
|
2019-03-19 17:08:51 +00:00
|
|
|
skyzbufferhack = 1;
|
|
|
|
|
2019-10-23 19:11:37 +00:00
|
|
|
//if (!hw_hightile || !hicfindskybox(globalpicnum, globalpal))
|
2019-10-10 22:15:20 +00:00
|
|
|
{
|
|
|
|
float const ghorizbak = ghoriz;
|
|
|
|
pow2xsplit = 0;
|
|
|
|
skyclamphack = 0;
|
|
|
|
flatskyrender = 1;
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(0.f);
|
2019-10-10 22:15:20 +00:00
|
|
|
polymost_domost(x1, cy1, x0, cy0);
|
|
|
|
flatskyrender = 0;
|
2019-09-19 20:02:45 +00:00
|
|
|
ghoriz = ghorizbak;
|
2019-10-10 22:15:20 +00:00
|
|
|
}
|
2019-10-17 18:29:58 +00:00
|
|
|
#if 0
|
2006-04-24 19:04:22 +00:00
|
|
|
else
|
2007-12-12 17:42:14 +00:00
|
|
|
{
|
|
|
|
//Skybox code for parallax ceiling!
|
2015-03-24 00:40:48 +00:00
|
|
|
float sky_t0, sky_t1; // _nx0, _ny0, _nx1, _ny1;
|
|
|
|
float sky_ryp0, sky_ryp1, sky_x0, sky_x1, sky_cy0, sky_fy0, sky_cy1, sky_fy1, sky_ox0, sky_ox1;
|
|
|
|
static vec2f_t const skywal[4] = { { -512, -512 }, { 512, -512 }, { 512, 512 }, { -512, 512 } };
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
pow2xsplit = 0;
|
|
|
|
skyclamphack = 1;
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=0; i<4; i++)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
walpos = skywal[i&3];
|
2015-07-08 03:34:20 +00:00
|
|
|
vec2f_t skyp0 = { walpos.y * gcosang - walpos.x * gsinang,
|
|
|
|
walpos.x * gcosang2 + walpos.y * gsinang2 };
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
walpos = skywal[(i + 1) & 3];
|
|
|
|
vec2f_t skyp1 = { walpos.y * gcosang - walpos.x * gsinang,
|
|
|
|
walpos.x * gcosang2 + walpos.y * gsinang2 };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vec2f_t const oskyp0 = skyp0;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Clip to close parallel-screen plane
|
2015-03-24 00:40:33 +00:00
|
|
|
if (skyp0.y < SCISDIST)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
if (skyp1.y < SCISDIST) continue;
|
2019-03-19 17:10:08 +00:00
|
|
|
sky_t0 = (SCISDIST - skyp0.y) / (skyp1.y - skyp0.y);
|
|
|
|
skyp0 = { (skyp1.x - skyp0.x) * sky_t0 + skyp0.x, SCISDIST };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
else { sky_t0 = 0.f; }
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (skyp1.y < SCISDIST)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-03-19 17:10:08 +00:00
|
|
|
sky_t1 = (SCISDIST - oskyp0.y) / (skyp1.y - oskyp0.y);
|
|
|
|
skyp1 = { (skyp1.x - oskyp0.x) * sky_t1 + oskyp0.x, SCISDIST };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
else { sky_t1 = 1.f; }
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_ryp0 = 1.f/skyp0.y; sky_ryp1 = 1.f/skyp1.y;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Generate screen coordinates for front side of wall
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_x0 = ghalfx*skyp0.x*sky_ryp0 + ghalfx;
|
|
|
|
sky_x1 = ghalfx*skyp1.x*sky_ryp1 + ghalfx;
|
|
|
|
if ((sky_x1 <= sky_x0) || (sky_x0 >= x1) || (x0 >= sky_x1)) continue;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_ryp0 *= gyxscale; sky_ryp1 *= gyxscale;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_cy0 = -8192.f*sky_ryp0 + ghoriz;
|
|
|
|
sky_fy0 = 8192.f*sky_ryp0 + ghoriz;
|
|
|
|
sky_cy1 = -8192.f*sky_ryp1 + ghoriz;
|
|
|
|
sky_fy1 = 8192.f*sky_ryp1 + ghoriz;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_ox0 = sky_x0; sky_ox1 = sky_x1;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-11-01 19:56:33 +00:00
|
|
|
//Make sure: x0<=_x0<_x1<=x1
|
2015-03-24 00:40:33 +00:00
|
|
|
float ncy[2] = { cy0, cy1 };
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
if (sky_x0 < x0)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const t = (x0-sky_x0)/(sky_x1-sky_x0);
|
|
|
|
sky_cy0 += (sky_cy1-sky_cy0)*t;
|
|
|
|
sky_fy0 += (sky_fy1-sky_fy0)*t;
|
|
|
|
sky_x0 = x0;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
else if (sky_x0 > x0) ncy[0] += (sky_x0-x0)*(cy1-cy0)/(x1-x0);
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
if (sky_x1 > x1)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const t = (x1-sky_x1)/(sky_x1-sky_x0);
|
|
|
|
sky_cy1 += (sky_cy1-sky_cy0)*t;
|
|
|
|
sky_fy1 += (sky_fy1-sky_fy0)*t;
|
|
|
|
sky_x1 = x1;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
else if (sky_x1 < x1) ncy[1] += (sky_x1-x1)*(cy1-cy0)/(x1-x0);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
// (skybox ceiling)
|
|
|
|
//(_x0,_cy0)-(_x1,_cy1)
|
|
|
|
// (skybox wall)
|
|
|
|
//(_x0,_fy0)-(_x1,_fy1)
|
|
|
|
// (skybox floor)
|
|
|
|
//(_x0,ncy0)-(_x1,ncy1)
|
|
|
|
|
|
|
|
//ceiling of skybox
|
|
|
|
drawingskybox = 5; //ceiling/5th texture/index 4 of skybox
|
2015-03-24 00:40:33 +00:00
|
|
|
float const ft[4] = { 512 / 16, -512 / -16, fcosglobalang * (1.f / 2147483648.f),
|
|
|
|
fsinglobalang * (1.f / 2147483648.f) };
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
xtex.d = 0;
|
2019-03-19 17:08:05 +00:00
|
|
|
ytex.d = gxyaspect*(-1.0/4194304.0);
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.d = -ghoriz*ytex.d;
|
2015-11-01 19:56:33 +00:00
|
|
|
xtex.u = ft[3]*fviewingrange*(-1.0/65536.0);
|
|
|
|
xtex.v = ft[2]*fviewingrange*(-1.0/65536.0);
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.u = ft[0]*ytex.d; ytex.v = ft[1]*ytex.d;
|
|
|
|
otex.u = ft[0]*otex.d; otex.v = ft[1]*otex.d;
|
|
|
|
otex.u += (ft[2]-xtex.u)*ghalfx;
|
|
|
|
otex.v -= (ft[3]+xtex.v)*ghalfx;
|
2015-11-01 19:56:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
if ((sky_cy0 < ncy[0]) && (sky_cy1 < ncy[1]))
|
|
|
|
polymost_domost(sky_x1,sky_cy1,sky_x0,sky_cy0);
|
2015-03-24 00:40:48 +00:00
|
|
|
else if ((sky_cy0 < ncy[0]) != (sky_cy1 < ncy[1]))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
|
|
|
//(ox,oy) is intersection of: (_x0,_cy0)-(_x1,_cy1)
|
|
|
|
// (_x0,ncy0)-(_x1,ncy1)
|
2015-03-24 00:40:48 +00:00
|
|
|
float const t = (sky_cy0-ncy[0])/(ncy[1]-ncy[0]-sky_cy1+sky_cy0);
|
|
|
|
vec2f_t const o = { sky_x0 + (sky_x1-sky_x0)*t, sky_cy0 + (sky_cy1-sky_cy0)*t };
|
2015-11-01 19:56:33 +00:00
|
|
|
if (ncy[0] < sky_cy0)
|
|
|
|
{
|
|
|
|
polymost_domost(o.x,o.y,sky_x0,ncy[0]);
|
|
|
|
polymost_domost(sky_x1,sky_cy1,o.x,o.y);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
polymost_domost(o.x,o.y,sky_x0,sky_cy0);
|
|
|
|
polymost_domost(sky_x1,ncy[1],o.x,o.y);
|
|
|
|
}
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
2015-11-01 19:56:33 +00:00
|
|
|
else
|
|
|
|
polymost_domost(sky_x1,ncy[1],sky_x0,ncy[0]);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//wall of skybox
|
|
|
|
drawingskybox = i+1; //i+1th texture/index i of skybox
|
2019-03-19 17:08:05 +00:00
|
|
|
xtex.d = (sky_ryp0-sky_ryp1)*gxyaspect*(1.0/512.0) / (sky_ox0-sky_ox1);
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.d = 0;
|
2019-03-19 17:08:05 +00:00
|
|
|
otex.d = sky_ryp0*gxyaspect*(1.0/512.0) - xtex.d*sky_ox0;
|
|
|
|
xtex.u = (sky_t0*sky_ryp0 - sky_t1*sky_ryp1)*gxyaspect*(64.0/512.0) / (sky_ox0-sky_ox1);
|
|
|
|
otex.u = sky_t0*sky_ryp0*gxyaspect*(64.0/512.0) - xtex.u*sky_ox0;
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.u = 0;
|
2015-03-24 00:40:48 +00:00
|
|
|
sky_t0 = -8192.f*sky_ryp0 + ghoriz;
|
|
|
|
sky_t1 = -8192.f*sky_ryp1 + ghoriz;
|
|
|
|
float const t = ((xtex.d*sky_ox0 + otex.d)*8.f) / ((sky_ox1-sky_ox0) * sky_ryp0 * 2048.f);
|
|
|
|
xtex.v = (sky_t0-sky_t1)*t;
|
|
|
|
ytex.v = (sky_ox1-sky_ox0)*t;
|
|
|
|
otex.v = -xtex.v*sky_ox0 - ytex.v*sky_t0;
|
2015-11-01 19:56:33 +00:00
|
|
|
|
|
|
|
if ((sky_fy0 < ncy[0]) && (sky_fy1 < ncy[1]))
|
|
|
|
polymost_domost(sky_x1,sky_fy1,sky_x0,sky_fy0);
|
2015-03-24 00:40:48 +00:00
|
|
|
else if ((sky_fy0 < ncy[0]) != (sky_fy1 < ncy[1]))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
|
|
|
//(ox,oy) is intersection of: (_x0,_fy0)-(_x1,_fy1)
|
|
|
|
// (_x0,ncy0)-(_x1,ncy1)
|
2015-03-24 00:40:48 +00:00
|
|
|
float const t = (sky_fy0-ncy[0])/(ncy[1]-ncy[0]-sky_fy1+sky_fy0);
|
|
|
|
vec2f_t const o = { sky_x0 + (sky_x1 - sky_x0) * t, sky_fy0 + (sky_fy1 - sky_fy0) * t };
|
2015-11-01 19:56:33 +00:00
|
|
|
if (ncy[0] < sky_fy0)
|
|
|
|
{
|
|
|
|
polymost_domost(o.x,o.y,sky_x0,ncy[0]);
|
|
|
|
polymost_domost(sky_x1,sky_fy1,o.x,o.y);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
polymost_domost(o.x,o.y,sky_x0,sky_fy0);
|
|
|
|
polymost_domost(sky_x1,ncy[1],o.x,o.y);
|
|
|
|
}
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
2015-11-01 19:56:33 +00:00
|
|
|
else
|
|
|
|
polymost_domost(sky_x1,ncy[1],sky_x0,ncy[0]);
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Floor of skybox
|
|
|
|
drawingskybox = 6; //floor/6th texture/index 5 of skybox
|
2015-03-24 00:40:33 +00:00
|
|
|
float const ft[4] = { 512 / 16, 512 / -16, fcosglobalang * (1.f / 2147483648.f),
|
|
|
|
fsinglobalang * (1.f / 2147483648.f) };
|
2015-11-01 19:56:33 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
xtex.d = 0;
|
2019-03-19 17:08:05 +00:00
|
|
|
ytex.d = gxyaspect*(1.0/4194304.0);
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.d = -ghoriz*ytex.d;
|
|
|
|
xtex.u = ft[3]*fviewingrange*(-1.0/65536.0);
|
|
|
|
xtex.v = ft[2]*fviewingrange*(-1.0/65536.0);
|
|
|
|
ytex.u = ft[0]*ytex.d; ytex.v = ft[1]*ytex.d;
|
|
|
|
otex.u = ft[0]*otex.d; otex.v = ft[1]*otex.d;
|
|
|
|
otex.u += (ft[2]-xtex.u)*ghalfx;
|
|
|
|
otex.v -= (ft[3]+xtex.v)*ghalfx;
|
|
|
|
xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; //y-flip skybox floor
|
2015-07-08 03:34:20 +00:00
|
|
|
polymost_domost(x1,cy1,x0,cy0);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
skyclamphack = 0;
|
|
|
|
drawingskybox = 0;
|
|
|
|
}
|
2019-10-17 18:29:58 +00:00
|
|
|
#endif
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
skyclamphack = 0;
|
2019-03-19 17:08:51 +00:00
|
|
|
skyzbufferhack = 0;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2015-11-01 19:56:33 +00:00
|
|
|
// Wall
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
xtex.d = (ryp0-ryp1)*gxyaspect / (x0-x1);
|
|
|
|
ytex.d = 0;
|
|
|
|
otex.d = ryp0*gxyaspect - xtex.d*x0;
|
|
|
|
|
|
|
|
xtex.u = (t0*ryp0 - t1*ryp1)*gxyaspect*(float)wal->xrepeat*8.f / (x0-x1);
|
2019-03-19 17:08:05 +00:00
|
|
|
otex.u = t0*ryp0*gxyaspect*wal->xrepeat*8.0 - xtex.u*x0;
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.u += (float)wal->xpanning*otex.d;
|
|
|
|
xtex.u += (float)wal->xpanning*xtex.d;
|
|
|
|
ytex.u = 0;
|
|
|
|
|
|
|
|
float const ogux = xtex.u, oguy = ytex.u, oguo = otex.u;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2020-08-30 21:34:40 +00:00
|
|
|
assert(domostpolymethod == DAMETH_NOMASK);
|
2014-06-01 11:55:19 +00:00
|
|
|
domostpolymethod = DAMETH_WALL;
|
2019-03-19 17:08:05 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (nextsectnum >= 0)
|
|
|
|
{
|
2019-07-26 21:54:37 +00:00
|
|
|
fgetzsofslope((usectorptr_t)§or[nextsectnum],n0.x,n0.y,&cz,&fz);
|
|
|
|
float const ocy0 = (cz-globalposz)*ryp0 + ghoriz;
|
|
|
|
float const ofy0 = (fz-globalposz)*ryp0 + ghoriz;
|
|
|
|
fgetzsofslope((usectorptr_t)§or[nextsectnum],n1.x,n1.y,&cz,&fz);
|
|
|
|
float const ocy1 = (cz-globalposz)*ryp1 + ghoriz;
|
|
|
|
float const ofy1 = (fz-globalposz)*ryp1 + ghoriz;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
if ((wal->cstat&48) == 16) maskwall[maskwallcnt++] = z;
|
|
|
|
|
|
|
|
if (((cy0 < ocy0) || (cy1 < ocy1)) && (!((sec->ceilingstat§or[nextsectnum].ceilingstat)&1)))
|
|
|
|
{
|
2020-09-20 18:39:11 +00:00
|
|
|
globalpicnum = wal->picnum; globalshade = wal->shade; globalfloorpal = globalpal = (int32_t)((uint8_t)wal->pal);
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(sectorVisibility(sectnum));
|
2018-11-18 18:13:48 +00:00
|
|
|
globalorientation = wal->cstat;
|
2019-06-25 11:30:22 +00:00
|
|
|
tileUpdatePicnum(&globalpicnum, wallnum+16384);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int i = (!(wal->cstat&4)) ? sector[nextsectnum].ceilingz : sec->ceilingz;
|
2008-03-27 21:32:23 +00:00
|
|
|
|
2012-07-09 19:00:14 +00:00
|
|
|
// over
|
2019-10-11 19:04:31 +00:00
|
|
|
calc_ypanning(i, ryp0, ryp1, x0, x1, wal->ypanning, wal->yrepeat, wal->cstat&4, tilesiz[globalpicnum]);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
if (wal->cstat&8) //xflip
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
float const t = (float)(wal->xrepeat*8 + wal->xpanning*2);
|
|
|
|
xtex.u = xtex.d*t - xtex.u;
|
|
|
|
ytex.u = ytex.d*t - ytex.u;
|
|
|
|
otex.u = otex.d*t - otex.u;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
if (wal->cstat&256) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; } //yflip
|
2012-12-14 19:28:09 +00:00
|
|
|
|
2019-04-07 20:56:35 +00:00
|
|
|
pow2xsplit = 1;
|
|
|
|
polymost_domost(x1,ocy1,x0,ocy0,cy1,ocy1,cy0,ocy0);
|
2015-03-24 00:40:33 +00:00
|
|
|
if (wal->cstat&8) { xtex.u = ogux; ytex.u = oguy; otex.u = oguo; }
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
if (((ofy0 < fy0) || (ofy1 < fy1)) && (!((sec->floorstat§or[nextsectnum].floorstat)&1)))
|
|
|
|
{
|
2019-09-21 11:02:17 +00:00
|
|
|
uwallptr_t nwal;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (!(wal->cstat&2)) nwal = wal;
|
|
|
|
else
|
|
|
|
{
|
2019-09-21 11:02:17 +00:00
|
|
|
nwal = (uwallptr_t)&wall[wal->nextwall];
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.u += (float)(nwal->xpanning - wal->xpanning) * otex.d;
|
|
|
|
xtex.u += (float)(nwal->xpanning - wal->xpanning) * xtex.d;
|
|
|
|
ytex.u += (float)(nwal->xpanning - wal->xpanning) * ytex.d;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2020-09-20 18:39:11 +00:00
|
|
|
globalpicnum = nwal->picnum; globalshade = nwal->shade; globalfloorpal = globalpal = (int32_t)((uint8_t)nwal->pal);
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(sectorVisibility(sectnum));
|
2019-02-02 23:24:32 +00:00
|
|
|
globalorientation = nwal->cstat;
|
2019-06-25 11:30:22 +00:00
|
|
|
tileUpdatePicnum(&globalpicnum, wallnum+16384);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int i = (!(nwal->cstat&4)) ? sector[nextsectnum].floorz : sec->ceilingz;
|
2008-03-27 21:32:23 +00:00
|
|
|
|
2012-07-09 19:00:14 +00:00
|
|
|
// under
|
2019-10-11 19:04:31 +00:00
|
|
|
calc_ypanning(i, ryp0, ryp1, x0, x1, nwal->ypanning, wal->yrepeat, !(nwal->cstat&4), tilesiz[globalpicnum]);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
if (wal->cstat&8) //xflip
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
float const t = (float)(wal->xrepeat*8 + nwal->xpanning*2);
|
|
|
|
xtex.u = xtex.d*t - xtex.u;
|
|
|
|
ytex.u = ytex.d*t - ytex.u;
|
|
|
|
otex.u = otex.d*t - otex.u;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
if (nwal->cstat&256) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; } //yflip
|
2012-12-14 19:28:09 +00:00
|
|
|
|
2019-04-07 20:56:35 +00:00
|
|
|
pow2xsplit = 1;
|
|
|
|
polymost_domost(x0,ofy0,x1,ofy1,ofy0,fy0,ofy1,fy1);
|
2015-03-24 00:40:33 +00:00
|
|
|
if (wal->cstat&(2+8)) { otex.u = oguo; xtex.u = ogux; ytex.u = oguy; }
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((nextsectnum < 0) || (wal->cstat&32)) //White/1-way wall
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
const int maskingOneWay = (nextsectnum >= 0 && (wal->cstat&32));
|
|
|
|
|
|
|
|
if (maskingOneWay)
|
|
|
|
{
|
|
|
|
vec2_t n, pos = { globalposx, globalposy };
|
|
|
|
if (!polymost_getclosestpointonwall(&pos, wallnum, &n) && klabs(pos.x - n.x) + klabs(pos.y - n.y) <= 128)
|
|
|
|
break;
|
|
|
|
}
|
2014-05-28 22:40:14 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
globalpicnum = (nextsectnum < 0) ? wal->picnum : wal->overpicnum;
|
2013-05-15 02:19:14 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
globalshade = wal->shade;
|
2020-09-20 18:39:11 +00:00
|
|
|
globalfloorpal = globalpal = wal->pal;
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(sectorVisibility(sectnum));
|
2018-11-18 18:13:48 +00:00
|
|
|
globalorientation = wal->cstat;
|
2019-06-25 11:30:22 +00:00
|
|
|
tileUpdatePicnum(&globalpicnum, wallnum+16384);
|
2008-03-27 21:32:23 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int i;
|
|
|
|
int const nwcs4 = !(wal->cstat & 4);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (nextsectnum >= 0) { i = nwcs4 ? nextsec->ceilingz : sec->ceilingz; }
|
|
|
|
else { i = nwcs4 ? sec->ceilingz : sec->floorz; }
|
|
|
|
|
|
|
|
// white / 1-way
|
2019-10-11 19:04:31 +00:00
|
|
|
calc_ypanning(i, ryp0, ryp1, x0, x1, wal->ypanning, wal->yrepeat, nwcs4 && !maskingOneWay, tilesiz[globalpicnum]);
|
2012-12-14 19:28:09 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (wal->cstat&8) //xflip
|
|
|
|
{
|
|
|
|
float const t = (float) (wal->xrepeat*8 + wal->xpanning*2);
|
|
|
|
xtex.u = xtex.d*t - xtex.u;
|
|
|
|
ytex.u = ytex.d*t - ytex.u;
|
|
|
|
otex.u = otex.d*t - otex.u;
|
|
|
|
}
|
|
|
|
if (wal->cstat&256) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; } //yflip
|
2012-12-14 19:28:09 +00:00
|
|
|
|
2019-03-30 19:35:34 +00:00
|
|
|
pow2xsplit = 1;
|
|
|
|
|
|
|
|
polymost_domost(x0, cy0, x1, cy1, cy0, fy0, cy1, fy1);
|
2015-03-24 00:40:33 +00:00
|
|
|
} while (0);
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2015-12-04 11:52:54 +00:00
|
|
|
domostpolymethod = DAMETH_NOMASK;
|
2014-06-01 11:55:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (nextsectnum >= 0)
|
2015-07-08 03:34:20 +00:00
|
|
|
if ((!(gotsector[nextsectnum>>3]&pow2char[nextsectnum&7])) && testvisiblemost(x0,x1))
|
2006-04-24 19:04:22 +00:00
|
|
|
polymost_scansector(nextsectnum);
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2014-09-30 04:06:05 +00:00
|
|
|
static int32_t polymost_bunchfront(const int32_t b1, const int32_t b2)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
int b1f = bunchfirst[b1];
|
2019-09-18 22:19:02 +00:00
|
|
|
const double x2b2 = dxb2[bunchlast[b2]];
|
|
|
|
const double x1b1 = dxb1[b1f];
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
if (nexttowardf(x1b1, x2b2) >= x2b2)
|
2014-10-25 03:34:25 +00:00
|
|
|
return -1;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
int b2f = bunchfirst[b2];
|
2019-09-18 22:19:02 +00:00
|
|
|
const double x1b2 = dxb1[b2f];
|
2014-10-25 03:34:25 +00:00
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
if (nexttowardf(x1b2, dxb2[bunchlast[b1]]) >= dxb2[bunchlast[b1]])
|
2015-03-24 00:40:33 +00:00
|
|
|
return -1;
|
2014-10-25 03:34:25 +00:00
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
if (nexttowardf(x1b1, x1b2) > x1b2)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2019-03-02 23:21:52 +00:00
|
|
|
while (nexttowardf(dxb2[b2f], x1b1) <= x1b1) b2f=bunchp2[b2f];
|
2015-03-24 00:40:48 +00:00
|
|
|
return wallfront(b1f, b2f);
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
while (nexttowardf(dxb2[b1f], x1b2) <= x1b2) b1f=bunchp2[b1f];
|
2015-03-24 00:40:48 +00:00
|
|
|
return wallfront(b1f, b2f);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2011-05-22 21:52:22 +00:00
|
|
|
void polymost_scansector(int32_t sectnum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
if (sectnum < 0) return;
|
|
|
|
|
2019-08-01 06:50:56 +00:00
|
|
|
if (automapping)
|
2020-03-07 09:04:29 +00:00
|
|
|
show2dsector.Set(sectnum);
|
2019-09-19 20:02:45 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
sectorborder[0] = sectnum;
|
|
|
|
int sectorbordercnt = 1;
|
2006-04-24 19:04:22 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
sectnum = sectorborder[--sectorbordercnt];
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t z=headspritesect[sectnum]; z>=0; z=nextspritesect[z])
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const spr = (uspriteptr_t)&sprite[z];
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2016-10-25 05:43:42 +00:00
|
|
|
if ((spr->cstat & 0x8000 && !showinvisibility) || spr->xrepeat == 0 || spr->yrepeat == 0)
|
|
|
|
continue;
|
2016-05-13 22:15:28 +00:00
|
|
|
|
2016-10-25 05:43:42 +00:00
|
|
|
vec2_t const s = { spr->x-globalposx, spr->y-globalposy };
|
|
|
|
|
2019-08-01 00:08:05 +00:00
|
|
|
if ((spr->cstat&48) ||
|
2019-10-23 19:11:37 +00:00
|
|
|
(hw_models && tile2model[spr->picnum].modelid>=0) ||
|
2019-08-01 00:08:05 +00:00
|
|
|
((s.x * gcosang) + (s.y * gsinang) > 0))
|
2016-10-25 05:43:42 +00:00
|
|
|
{
|
2019-08-01 00:08:05 +00:00
|
|
|
if ((spr->cstat&(64+48))!=(64+16) ||
|
2019-10-23 19:11:37 +00:00
|
|
|
(r_voxels && tiletovox[spr->picnum] >= 0 && voxmodels[tiletovox[spr->picnum]]) ||
|
2019-08-01 00:08:05 +00:00
|
|
|
dmulscale6(sintable[(spr->ang+512)&2047],-s.x, sintable[spr->ang&2047],-s.y) > 0)
|
2018-04-12 21:04:00 +00:00
|
|
|
if (renderAddTsprite(z, sectnum))
|
2016-10-25 05:43:42 +00:00
|
|
|
break;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gotsector[sectnum>>3] |= pow2char[sectnum&7];
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
int const bunchfrst = numbunches;
|
2017-12-20 08:35:49 +00:00
|
|
|
int const onumscans = numscans;
|
2015-03-24 00:40:48 +00:00
|
|
|
int const startwall = sector[sectnum].wallptr;
|
2017-12-20 08:35:49 +00:00
|
|
|
int const endwall = sector[sectnum].wallnum + startwall;
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
int scanfirst = numscans;
|
2017-12-20 08:35:49 +00:00
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
vec2d_t p2 = { 0, 0 };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-09-21 11:02:17 +00:00
|
|
|
uwallptr_t wal;
|
2015-03-24 00:40:48 +00:00
|
|
|
int z;
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2019-09-21 11:02:17 +00:00
|
|
|
for (z=startwall,wal=(uwallptr_t)&wall[z]; z<endwall; z++,wal++)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const wal2 = (uwallptr_t)&wall[wal->point2];
|
2017-12-20 08:35:49 +00:00
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
vec2d_t const fp1 = { double(wal->x - globalposx), double(wal->y - globalposy) };
|
|
|
|
vec2d_t const fp2 = { double(wal2->x - globalposx), double(wal2->y - globalposy) };
|
2015-03-24 00:40:48 +00:00
|
|
|
|
|
|
|
int const nextsectnum = wal->nextsector; //Scan close sectors
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2020-08-30 21:34:40 +00:00
|
|
|
if (nextsectnum >= 0 && !(wal->cstat&32) && sectorbordercnt < countof(sectorborder))
|
2015-01-04 18:45:03 +00:00
|
|
|
if ((gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-03-02 23:21:52 +00:00
|
|
|
double const d = fp1.x*fp2.y - fp2.x*fp1.y;
|
|
|
|
vec2d_t const p1 = { fp2.x-fp1.x, fp2.y-fp1.y };
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
// this said (SCISDIST*SCISDIST*260.f), but SCISDIST is 1 and the significance of 260 isn't obvious to me
|
|
|
|
// is 260 fudged to solve a problem, and does the problem still apply to our version of the renderer?
|
|
|
|
if (d*d < (p1.x*p1.x + p1.y*p1.y) * 256.f)
|
2015-01-04 18:45:03 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
sectorborder[sectorbordercnt++] = nextsectnum;
|
2015-01-04 18:45:03 +00:00
|
|
|
gotsector[nextsectnum>>3] |= pow2char[nextsectnum&7];
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
vec2d_t p1;
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if ((z == startwall) || (wall[z-1].point2 != z))
|
|
|
|
{
|
2019-03-02 23:21:52 +00:00
|
|
|
p1 = { (((fp1.y * fcosglobalang) - (fp1.x * fsinglobalang)) * (1.0/64.0)),
|
|
|
|
(((fp1.x * cosviewingrangeglobalang) + (fp1.y * sinviewingrangeglobalang)) * (1.0/64.0)) };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2014-09-30 04:14:21 +00:00
|
|
|
else { p1 = p2; }
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
p2 = { (((fp2.y * fcosglobalang) - (fp2.x * fsinglobalang)) * (1.0/64.0)),
|
|
|
|
(((fp2.x * cosviewingrangeglobalang) + (fp2.y * sinviewingrangeglobalang)) * (1.0/64.0)) };
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2019-03-21 09:28:01 +00:00
|
|
|
if (numscans >= MAXWALLSB-1)
|
|
|
|
{
|
2020-04-11 21:45:45 +00:00
|
|
|
Printf("!!numscans\n");
|
2019-03-21 09:28:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-05-13 22:15:28 +00:00
|
|
|
//if wall is facing you...
|
2019-03-02 23:21:52 +00:00
|
|
|
if ((p1.y >= SCISDIST || p2.y >= SCISDIST) && (nexttoward(p1.x*p2.y, p2.x*p1.y) < p2.x*p1.y))
|
2016-05-13 22:15:28 +00:00
|
|
|
{
|
2019-03-02 23:21:52 +00:00
|
|
|
dxb1[numscans] = (p1.y >= SCISDIST) ? float(p1.x*ghalfx/p1.y + ghalfx) : -1e32f;
|
|
|
|
dxb2[numscans] = (p2.y >= SCISDIST) ? float(p2.x*ghalfx/p2.y + ghalfx) : 1e32f;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-07-26 21:54:41 +00:00
|
|
|
if (dxb1[numscans] < xbl)
|
|
|
|
dxb1[numscans] = xbl;
|
|
|
|
else if (dxb1[numscans] > xbr)
|
|
|
|
dxb1[numscans] = xbr;
|
|
|
|
if (dxb2[numscans] < xbl)
|
|
|
|
dxb2[numscans] = xbl;
|
|
|
|
else if (dxb2[numscans] > xbr)
|
|
|
|
dxb2[numscans] = xbr;
|
|
|
|
|
2019-03-02 23:21:52 +00:00
|
|
|
if (nexttowardf(dxb1[numscans], dxb2[numscans]) < dxb2[numscans])
|
2016-05-13 22:15:28 +00:00
|
|
|
{
|
|
|
|
thesector[numscans] = sectnum;
|
|
|
|
thewall[numscans] = z;
|
|
|
|
bunchp2[numscans] = numscans + 1;
|
|
|
|
numscans++;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2016-05-13 22:15:28 +00:00
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
if ((wall[z].point2 < z) && (scanfirst < numscans))
|
2016-05-13 22:15:28 +00:00
|
|
|
{
|
|
|
|
bunchp2[numscans-1] = scanfirst;
|
|
|
|
scanfirst = numscans;
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2017-12-20 08:35:49 +00:00
|
|
|
for (bssize_t z=onumscans; z<numscans; z++)
|
2016-05-13 22:15:28 +00:00
|
|
|
{
|
2019-03-02 23:21:52 +00:00
|
|
|
if ((wall[thewall[z]].point2 != thewall[bunchp2[z]]) || (dxb2[z] > nexttowardf(dxb1[bunchp2[z]], dxb2[z])))
|
2011-05-22 21:52:22 +00:00
|
|
|
{
|
2016-05-13 22:15:28 +00:00
|
|
|
bunchfirst[numbunches++] = bunchp2[z];
|
|
|
|
bunchp2[z] = -1;
|
2011-05-22 21:52:22 +00:00
|
|
|
}
|
2016-05-13 22:15:28 +00:00
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t z=bunchfrst; z<numbunches; z++)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
int zz;
|
2016-01-12 10:31:12 +00:00
|
|
|
for (zz=bunchfirst[z]; bunchp2[zz]>=0; zz=bunchp2[zz]) { }
|
2006-04-24 19:04:22 +00:00
|
|
|
bunchlast[z] = zz;
|
|
|
|
}
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
|
|
|
while (sectorbordercnt > 0);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2014-09-30 04:14:21 +00:00
|
|
|
/*Init viewport boundary (must be 4 point convex loop):
|
|
|
|
// (px[0],py[0]).----.(px[1],py[1])
|
|
|
|
// / \
|
|
|
|
// / \
|
|
|
|
// (px[3],py[3]).--------------.(px[2],py[2])
|
|
|
|
*/
|
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
static void polymost_initmosts(const float * px, const float * py, int const n)
|
2014-09-30 04:14:21 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
if (n < 3) return;
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t imin = (px[1] < px[0]);
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=n-1; i>=2; i--)
|
2016-05-13 22:15:28 +00:00
|
|
|
if (px[i] < px[imin]) imin = i;
|
2014-09-30 04:14:21 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t vcnt = 1; //0 is dummy solid node
|
2014-09-30 04:14:21 +00:00
|
|
|
|
|
|
|
vsp[vcnt].x = px[imin];
|
|
|
|
vsp[vcnt].cy[0] = vsp[vcnt].fy[0] = py[imin];
|
|
|
|
vcnt++;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2016-06-05 04:46:28 +00:00
|
|
|
int i = imin+1, j = imin-1;
|
2015-03-24 00:40:33 +00:00
|
|
|
if (i >= n) i = 0;
|
|
|
|
if (j < 0) j = n-1;
|
|
|
|
|
2014-09-30 04:14:21 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
if (px[i] < px[j])
|
|
|
|
{
|
2018-10-25 23:29:38 +00:00
|
|
|
if (px[i] <= vsp[vcnt-1].x) vcnt--;
|
2014-09-30 04:14:21 +00:00
|
|
|
vsp[vcnt].x = px[i];
|
|
|
|
vsp[vcnt].cy[0] = py[i];
|
2015-03-24 00:40:33 +00:00
|
|
|
int k = j+1; if (k >= n) k = 0;
|
2014-09-30 04:14:21 +00:00
|
|
|
//(px[k],py[k])
|
|
|
|
//(px[i],?)
|
|
|
|
//(px[j],py[j])
|
|
|
|
vsp[vcnt].fy[0] = (px[i]-px[k])*(py[j]-py[k])/(px[j]-px[k]) + py[k];
|
|
|
|
vcnt++;
|
|
|
|
i++; if (i >= n) i = 0;
|
|
|
|
}
|
|
|
|
else if (px[j] < px[i])
|
|
|
|
{
|
2018-10-25 23:29:38 +00:00
|
|
|
if (px[j] <= vsp[vcnt-1].x) vcnt--;
|
2014-09-30 04:14:21 +00:00
|
|
|
vsp[vcnt].x = px[j];
|
|
|
|
vsp[vcnt].fy[0] = py[j];
|
2015-03-24 00:40:33 +00:00
|
|
|
int k = i-1; if (k < 0) k = n-1;
|
2014-09-30 04:14:21 +00:00
|
|
|
//(px[k],py[k])
|
|
|
|
//(px[j],?)
|
|
|
|
//(px[i],py[i])
|
|
|
|
vsp[vcnt].cy[0] = (px[j]-px[k])*(py[i]-py[k])/(px[i]-px[k]) + py[k];
|
|
|
|
vcnt++;
|
|
|
|
j--; if (j < 0) j = n-1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-25 23:29:38 +00:00
|
|
|
if (px[i] <= vsp[vcnt-1].x) vcnt--;
|
2014-09-30 04:14:21 +00:00
|
|
|
vsp[vcnt].x = px[i];
|
|
|
|
vsp[vcnt].cy[0] = py[i];
|
|
|
|
vsp[vcnt].fy[0] = py[j];
|
|
|
|
vcnt++;
|
|
|
|
i++; if (i >= n) i = 0; if (i == j) break;
|
|
|
|
j--; if (j < 0) j = n-1;
|
|
|
|
}
|
|
|
|
} while (i != j);
|
|
|
|
|
|
|
|
if (px[i] > vsp[vcnt-1].x)
|
|
|
|
{
|
|
|
|
vsp[vcnt].x = px[i];
|
|
|
|
vsp[vcnt].cy[0] = vsp[vcnt].fy[0] = py[i];
|
|
|
|
vcnt++;
|
|
|
|
}
|
|
|
|
|
2019-03-02 23:22:12 +00:00
|
|
|
domost_rejectcount = 0;
|
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
vsp_finalize_init(vcnt);
|
2019-03-19 17:07:53 +00:00
|
|
|
|
|
|
|
xbl = px[0];
|
|
|
|
xbr = px[0];
|
|
|
|
xbt = py[0];
|
|
|
|
xbb = py[0];
|
|
|
|
|
|
|
|
for (bssize_t i=n-1; i>=1; i--)
|
|
|
|
{
|
|
|
|
if (xbl > px[i]) xbl = px[i];
|
|
|
|
if (xbr < px[i]) xbr = px[i];
|
|
|
|
if (xbt > py[i]) xbt = py[i];
|
|
|
|
if (xbb < py[i]) xbb = py[i];
|
|
|
|
}
|
|
|
|
|
2014-09-30 04:14:21 +00:00
|
|
|
gtag = vcnt;
|
2019-06-25 18:35:19 +00:00
|
|
|
viewportNodeCount = vcnt;
|
2014-09-30 04:14:21 +00:00
|
|
|
}
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
void polymost_drawrooms()
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() == REND_CLASSIC) return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-05-25 14:59:09 +00:00
|
|
|
polymost_outputGLDebugMessage(3, "polymost_drawrooms()");
|
|
|
|
|
2020-07-14 14:06:14 +00:00
|
|
|
GLInterface.ClearDepth();
|
2019-10-04 16:12:03 +00:00
|
|
|
GLInterface.EnableBlend(false);
|
|
|
|
GLInterface.EnableAlphaTest(false);
|
|
|
|
GLInterface.EnableDepthTest(true);
|
2020-06-11 16:40:53 +00:00
|
|
|
GLInterface.SetDepthFunc(DF_LEqual);
|
2020-08-30 15:36:21 +00:00
|
|
|
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-08-07 22:44:33 +00:00
|
|
|
gvrcorrection = viewingrange*(1.f/65536.f);
|
2020-01-19 12:57:24 +00:00
|
|
|
//if (glprojectionhacks == 2)
|
2019-08-07 22:44:33 +00:00
|
|
|
{
|
|
|
|
// calculates the extend of the zenith glitch
|
|
|
|
float verticalfovtan = (fviewingrange * (windowxy2.y-windowxy1.y) * 5.f) / ((float)yxaspect * (windowxy2.x-windowxy1.x) * 4.f);
|
|
|
|
float verticalfov = atanf(verticalfovtan) * (2.f / fPI);
|
|
|
|
static constexpr float const maxhorizangle = 0.6361136f; // horiz of 199 in degrees
|
|
|
|
float zenglitch = verticalfov + maxhorizangle - 0.95f; // less than 1 because the zenith glitch extends a bit
|
|
|
|
if (zenglitch > 0.f)
|
|
|
|
gvrcorrection /= (zenglitch * 2.5f) + 1.f;
|
|
|
|
}
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//Polymost supports true look up/down :) Here, we convert horizon to angle.
|
|
|
|
//gchang&gshang are cos&sin of this angle (respectively)
|
2014-09-30 04:06:05 +00:00
|
|
|
gyxscale = ((float)xdimenscale)*(1.0f/131072.f);
|
2019-03-19 17:08:05 +00:00
|
|
|
gxyaspect = ((double)xyaspect*fviewingrange)*(5.0/(65536.0*262144.0));
|
2014-10-25 03:27:35 +00:00
|
|
|
gviewxrange = fviewingrange * fxdimen * (1.f/(32768.f*1024.f));
|
2014-09-30 04:14:21 +00:00
|
|
|
gcosang = fcosglobalang*(1.0f/262144.f);
|
|
|
|
gsinang = fsinglobalang*(1.0f/262144.f);
|
2014-10-25 03:27:35 +00:00
|
|
|
gcosang2 = gcosang * (fviewingrange * (1.0f/65536.f));
|
|
|
|
gsinang2 = gsinang * (fviewingrange * (1.0f/65536.f));
|
2015-03-24 00:40:33 +00:00
|
|
|
ghalfx = (float)(xdimen>>1);
|
2019-09-19 20:02:45 +00:00
|
|
|
ghalfy = (float)(ydimen>>1);
|
2014-09-30 04:06:05 +00:00
|
|
|
grhalfxdown10 = 1.f/(ghalfx*1024.f);
|
2020-09-01 13:00:35 +00:00
|
|
|
ghoriz = FixedToFloat(qglobalhoriz);
|
2020-09-21 08:41:56 +00:00
|
|
|
ghorizcorrect = FixedToFloat(divscale16(xdimenscale, viewingrange));
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-10-23 19:11:37 +00:00
|
|
|
GLInterface.SetShadeInterpolate(hw_shadeinterpolate);
|
2019-05-19 03:54:24 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//global cos/sin height angle
|
2019-09-19 20:02:45 +00:00
|
|
|
if (r_yshearing)
|
|
|
|
{
|
2019-05-19 03:54:52 +00:00
|
|
|
gshang = 0.f;
|
|
|
|
gchang = 1.f;
|
2019-09-21 11:02:17 +00:00
|
|
|
ghoriz2 = (float)(ydimen >> 1) - (ghoriz + ghorizcorrect);
|
2019-09-19 20:02:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-21 11:02:17 +00:00
|
|
|
float r = (float)(ydimen >> 1) - (ghoriz + ghorizcorrect);
|
2020-09-08 16:48:18 +00:00
|
|
|
gshang = r / sqrtf(r * r + ghalfx * ghalfx / (gvrcorrection * gvrcorrection));
|
|
|
|
gchang = sqrtf(1.f - gshang * gshang);
|
2019-05-19 03:54:52 +00:00
|
|
|
ghoriz2 = 0.f;
|
|
|
|
}
|
2019-09-21 11:02:17 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
ghoriz = (float)(ydimen>>1);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-09-19 20:02:45 +00:00
|
|
|
resizeglcheck();
|
2020-01-19 12:57:24 +00:00
|
|
|
float const ratio = 1.f;
|
2019-09-19 20:02:45 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//global cos/sin tilt angle
|
2015-03-24 00:40:33 +00:00
|
|
|
gctang = cosf(gtang);
|
|
|
|
gstang = sinf(gtang);
|
2015-07-08 03:34:20 +00:00
|
|
|
|
2020-01-19 15:06:31 +00:00
|
|
|
if (Bfabsf(gstang) < .001f) // This avoids nasty precision bugs in domost()
|
2015-07-08 03:34:20 +00:00
|
|
|
{
|
|
|
|
gstang = 0.f;
|
|
|
|
gctang = (gctang > 0.f) ? 1.f : -1.f;
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
if (inpreparemirror)
|
2006-04-24 19:04:22 +00:00
|
|
|
gstang = -gstang;
|
|
|
|
|
|
|
|
//Generate viewport trapezoid (for handling screen up/down)
|
2019-09-19 20:02:45 +00:00
|
|
|
vec3f_t p[4] = { { 0-1, 0-1+ghorizcorrect, 0 },
|
|
|
|
{ (float)(windowxy2.x + 1 - windowxy1.x + 2), 0-1+ghorizcorrect, 0 },
|
|
|
|
{ (float)(windowxy2.x + 1 - windowxy1.x + 2), (float)(windowxy2.y + 1 - windowxy1.y + 2)+ghorizcorrect, 0 },
|
|
|
|
{ 0-1, (float)(windowxy2.y + 1 - windowxy1.y + 2)+ghorizcorrect, 0 } };
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2019-03-19 17:10:08 +00:00
|
|
|
for (auto & v : p)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
//Tilt rotation (backwards)
|
2019-08-07 22:44:33 +00:00
|
|
|
vec2f_t const o = { (v.x-ghalfx)*ratio, (v.y-ghoriz)*ratio };
|
|
|
|
vec3f_t const o2 = { o.x*gctang + o.y*gstang, o.y*gctang - o.x*gstang + ghoriz2, ghalfx / gvrcorrection };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Up/down rotation (backwards)
|
2019-03-19 17:10:08 +00:00
|
|
|
v = { o2.x, o2.y * gchang + o2.z * gshang, o2.z * gchang - o2.y * gshang };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
if (inpreparemirror)
|
2019-04-07 20:56:38 +00:00
|
|
|
gstang = -gstang;
|
2020-01-19 15:06:31 +00:00
|
|
|
polymost_updaterotmat();
|
2019-04-07 20:56:38 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//Clip to SCISDIST plane
|
2015-03-24 00:40:48 +00:00
|
|
|
int n = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec3f_t p2[6];
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=0; i<4; i++)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-26 21:42:19 +00:00
|
|
|
int const j = i < 3 ? i + 1 : 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (p[i].z >= SCISDIST)
|
2015-03-24 00:40:48 +00:00
|
|
|
p2[n++] = p[i];
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if ((p[i].z >= SCISDIST) != (p[j].z >= SCISDIST))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
float const r = (SCISDIST - p[i].z) / (p[j].z - p[i].z);
|
2019-03-19 17:10:08 +00:00
|
|
|
p2[n++] = { (p[j].x - p[i].x) * r + p[i].x, (p[j].y - p[i].y) * r + p[i].y, SCISDIST };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-10-04 16:44:16 +00:00
|
|
|
if (n < 3)
|
|
|
|
{
|
2020-06-11 16:40:53 +00:00
|
|
|
GLInterface.SetDepthFunc(DF_LEqual);
|
2019-10-04 16:44:16 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-09-19 20:02:45 +00:00
|
|
|
float sx[6], sy[6];
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i = 0; i < n; i++)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2019-08-07 22:44:33 +00:00
|
|
|
float const r = (ghalfx / gvrcorrection) / p2[i].z;
|
2015-03-24 00:40:33 +00:00
|
|
|
sx[i] = p2[i].x * r + ghalfx;
|
|
|
|
sy[i] = p2[i].y * r + ghoriz;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-07-08 03:34:20 +00:00
|
|
|
polymost_initmosts(sx, sy, n);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
numscans = numbunches = 0;
|
|
|
|
|
2012-01-26 21:57:51 +00:00
|
|
|
// MASKWALL_BAD_ACCESS
|
|
|
|
// Fixes access of stale maskwall[maskwallcnt] (a "scan" index, in BUILD lingo):
|
|
|
|
maskwallcnt = 0;
|
|
|
|
|
2015-08-01 08:41:14 +00:00
|
|
|
// NOTE: globalcursectnum has been already adjusted in ADJUST_GLOBALCURSECTNUM.
|
2020-08-30 21:34:40 +00:00
|
|
|
assert((unsigned)globalcursectnum < MAXSECTORS);
|
2006-04-24 19:04:22 +00:00
|
|
|
polymost_scansector(globalcursectnum);
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
grhalfxdown10x = grhalfxdown10;
|
|
|
|
|
2020-06-04 16:46:44 +00:00
|
|
|
renderBeginScene();
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (inpreparemirror)
|
|
|
|
{
|
2012-03-08 19:15:03 +00:00
|
|
|
// see engine.c: INPREPAREMIRROR_NO_BUNCHES
|
|
|
|
if (numbunches > 0)
|
|
|
|
{
|
2019-06-25 18:35:05 +00:00
|
|
|
grhalfxdown10x = -grhalfxdown10;
|
2012-03-08 19:15:03 +00:00
|
|
|
polymost_drawalls(0);
|
|
|
|
numbunches--;
|
|
|
|
bunchfirst[0] = bunchfirst[numbunches];
|
|
|
|
bunchlast[0] = bunchlast[numbunches];
|
2019-06-25 18:35:05 +00:00
|
|
|
} else
|
|
|
|
{
|
|
|
|
inpreparemirror = 0;
|
2012-03-08 19:15:03 +00:00
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2020-06-04 16:46:44 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
while (numbunches > 0)
|
|
|
|
{
|
2020-09-08 16:48:18 +00:00
|
|
|
memset(ptempbuf,0,numbunches+3); ptempbuf[0] = 1;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t closest = 0; //Almost works, but not quite :(
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=1; i<numbunches; ++i)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
int const bnch = polymost_bunchfront(i,closest); if (bnch < 0) continue;
|
2009-01-09 09:29:17 +00:00
|
|
|
ptempbuf[i] = 1;
|
2015-03-24 00:40:33 +00:00
|
|
|
if (!bnch) { ptempbuf[closest] = 1; closest = i; }
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=0; i<numbunches; ++i) //Double-check
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2009-01-09 09:29:17 +00:00
|
|
|
if (ptempbuf[i]) continue;
|
2015-03-24 00:40:33 +00:00
|
|
|
int const bnch = polymost_bunchfront(i,closest); if (bnch < 0) continue;
|
2009-01-09 09:29:17 +00:00
|
|
|
ptempbuf[i] = 1;
|
2015-03-24 00:40:33 +00:00
|
|
|
if (!bnch) { ptempbuf[closest] = 1; closest = i; i = 0; }
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
polymost_drawalls(closest);
|
|
|
|
|
2019-09-19 20:02:45 +00:00
|
|
|
if (automapping)
|
|
|
|
{
|
2019-08-01 06:50:56 +00:00
|
|
|
for (int z=bunchfirst[closest]; z>=0; z=bunchp2[z])
|
2020-09-06 10:44:58 +00:00
|
|
|
show2dwall.Set(thewall[z]);
|
2019-09-19 20:02:45 +00:00
|
|
|
}
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
numbunches--;
|
|
|
|
bunchfirst[closest] = bunchfirst[numbunches];
|
|
|
|
bunchlast[closest] = bunchlast[numbunches];
|
|
|
|
}
|
2020-06-04 16:46:44 +00:00
|
|
|
renderFinishScene();
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-06-11 16:40:53 +00:00
|
|
|
GLInterface.SetDepthFunc(DF_LEqual);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2019-06-25 18:35:16 +00:00
|
|
|
static void polymost_drawmaskwallinternal(int32_t wallIndex)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2019-06-25 18:35:16 +00:00
|
|
|
auto const wal = (uwallptr_t)&wall[wallIndex];
|
|
|
|
auto const wal2 = (uwallptr_t)&wall[wal->point2];
|
|
|
|
int32_t const sectnum = wall[wal->nextwall].nextsector;
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const sec = (usectorptr_t)§or[sectnum];
|
2012-01-26 21:57:51 +00:00
|
|
|
|
|
|
|
// if (wal->nextsector < 0) return;
|
|
|
|
// Without MASKWALL_BAD_ACCESS fix:
|
|
|
|
// wal->nextsector is -1, WGR2 SVN Lochwood Hollow (Til' Death L1) (or trueror1.map)
|
|
|
|
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const nsec = (usectorptr_t)§or[wal->nextsector];
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-06-25 18:35:16 +00:00
|
|
|
polymost_outputGLDebugMessage(3, "polymost_drawmaskwallinternal(wallIndex:%d)", wallIndex);
|
2019-05-25 14:59:09 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
globalpicnum = wal->overpicnum;
|
|
|
|
if ((uint32_t)globalpicnum >= MAXTILES)
|
|
|
|
globalpicnum = 0;
|
2013-05-15 02:19:14 +00:00
|
|
|
|
2018-11-18 18:13:48 +00:00
|
|
|
globalorientation = (int32_t)wal->cstat;
|
2019-06-25 18:35:16 +00:00
|
|
|
tileUpdatePicnum(&globalpicnum, (int16_t)wallIndex+16384);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(sectorVisibility(sectnum));
|
2019-03-19 17:08:39 +00:00
|
|
|
|
2009-01-09 09:29:17 +00:00
|
|
|
globalshade = (int32_t)wal->shade;
|
2020-09-20 18:39:11 +00:00
|
|
|
globalfloorpal = globalpal = (int32_t)((uint8_t)wal->pal);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2f_t s0 = { (float)(wal->x-globalposx), (float)(wal->y-globalposy) };
|
|
|
|
vec2f_t p0 = { s0.y*gcosang - s0.x*gsinang, s0.x*gcosang2 + s0.y*gsinang2 };
|
|
|
|
|
|
|
|
vec2f_t s1 = { (float)(wal2->x-globalposx), (float)(wal2->y-globalposy) };
|
|
|
|
vec2f_t p1 = { s1.y*gcosang - s1.x*gsinang, s1.x*gcosang2 + s1.y*gsinang2 };
|
|
|
|
|
|
|
|
if ((p0.y < SCISDIST) && (p1.y < SCISDIST)) return;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Clip to close parallel-screen plane
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2f_t const op0 = p0;
|
|
|
|
|
|
|
|
float t0 = 0.f;
|
|
|
|
|
|
|
|
if (p0.y < SCISDIST)
|
|
|
|
{
|
|
|
|
t0 = (SCISDIST - p0.y) / (p1.y - p0.y);
|
2019-03-19 17:10:08 +00:00
|
|
|
p0 = { (p1.x - p0.x) * t0 + p0.x, SCISDIST };
|
2015-03-24 00:40:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
float t1 = 1.f;
|
|
|
|
|
|
|
|
if (p1.y < SCISDIST)
|
|
|
|
{
|
|
|
|
t1 = (SCISDIST - op0.y) / (p1.y - op0.y);
|
2019-03-19 17:10:08 +00:00
|
|
|
p1 = { (p1.x - op0.x) * t1 + op0.x, SCISDIST };
|
2015-03-24 00:40:48 +00:00
|
|
|
}
|
|
|
|
|
2017-10-31 00:35:23 +00:00
|
|
|
int32_t m0 = (int32_t)((wal2->x - wal->x) * t0 + wal->x);
|
|
|
|
int32_t m1 = (int32_t)((wal2->y - wal->y) * t0 + wal->y);
|
2015-03-24 00:40:48 +00:00
|
|
|
int32_t cz[4], fz[4];
|
|
|
|
getzsofslope(sectnum, m0, m1, &cz[0], &fz[0]);
|
|
|
|
getzsofslope(wal->nextsector, m0, m1, &cz[1], &fz[1]);
|
2017-10-31 00:35:23 +00:00
|
|
|
m0 = (int32_t)((wal2->x - wal->x) * t1 + wal->x);
|
|
|
|
m1 = (int32_t)((wal2->y - wal->y) * t1 + wal->y);
|
2015-03-24 00:40:48 +00:00
|
|
|
getzsofslope(sectnum, m0, m1, &cz[2], &fz[2]);
|
|
|
|
getzsofslope(wal->nextsector, m0, m1, &cz[3], &fz[3]);
|
|
|
|
|
|
|
|
float ryp0 = 1.f/p0.y;
|
|
|
|
float ryp1 = 1.f/p1.y;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Generate screen coordinates for front side of wall
|
2015-03-24 00:40:48 +00:00
|
|
|
float const x0 = ghalfx*p0.x*ryp0 + ghalfx;
|
|
|
|
float const x1 = ghalfx*p1.x*ryp1 + ghalfx;
|
2006-04-24 19:04:22 +00:00
|
|
|
if (x1 <= x0) return;
|
|
|
|
|
|
|
|
ryp0 *= gyxscale; ryp1 *= gyxscale;
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
xtex.d = (ryp0-ryp1)*gxyaspect / (x0-x1);
|
|
|
|
ytex.d = 0;
|
|
|
|
otex.d = ryp0*gxyaspect - xtex.d*x0;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//gux*x0 + guo = t0*wal->xrepeat*8*yp0
|
|
|
|
//gux*x1 + guo = t1*wal->xrepeat*8*yp1
|
2015-03-24 00:40:33 +00:00
|
|
|
xtex.u = (t0*ryp0 - t1*ryp1)*gxyaspect*(float)wal->xrepeat*8.f / (x0-x1);
|
|
|
|
otex.u = t0*ryp0*gxyaspect*(float)wal->xrepeat*8.f - xtex.u*x0;
|
|
|
|
otex.u += (float)wal->xpanning*otex.d;
|
|
|
|
xtex.u += (float)wal->xpanning*xtex.d;
|
|
|
|
ytex.u = 0;
|
2012-07-08 21:47:14 +00:00
|
|
|
|
2012-07-09 19:00:14 +00:00
|
|
|
// mask
|
2015-03-24 00:40:48 +00:00
|
|
|
calc_ypanning((!(wal->cstat & 4)) ? max(nsec->ceilingz, sec->ceilingz) : min(nsec->floorz, sec->floorz), ryp0, ryp1,
|
2019-10-11 19:04:31 +00:00
|
|
|
x0, x1, wal->ypanning, wal->yrepeat, 0, tilesiz[globalpicnum]);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
if (wal->cstat&8) //xflip
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const t = (float)(wal->xrepeat*8 + wal->xpanning*2);
|
2015-03-24 00:40:33 +00:00
|
|
|
xtex.u = xtex.d*t - xtex.u;
|
|
|
|
ytex.u = ytex.d*t - ytex.u;
|
|
|
|
otex.u = otex.d*t - otex.u;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
if (wal->cstat&256) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; } //yflip
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-12-04 11:52:54 +00:00
|
|
|
int method = DAMETH_MASK | DAMETH_WALL;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
if (wal->cstat & 128)
|
2016-12-04 22:53:56 +00:00
|
|
|
method = DAMETH_WALL | (((wal->cstat & 512)) ? DAMETH_TRANS2 : DAMETH_TRANS1);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2017-06-25 11:23:47 +00:00
|
|
|
#ifdef NEW_MAP_FORMAT
|
|
|
|
uint8_t const blend = wal->blend;
|
|
|
|
#else
|
2019-06-25 18:35:16 +00:00
|
|
|
uint8_t const blend = wallext[wallIndex].blend;
|
2017-06-25 11:23:47 +00:00
|
|
|
#endif
|
2020-05-23 12:40:54 +00:00
|
|
|
SetRenderStyleFromBlend(!!(wal->cstat & 128), blend, !!(wal->cstat & 512));
|
2017-06-25 11:23:47 +00:00
|
|
|
|
|
|
|
drawpoly_alpha = 0.f;
|
|
|
|
drawpoly_blend = blend;
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
float const csy[4] = { ((float)(cz[0] - globalposz)) * ryp0 + ghoriz,
|
|
|
|
((float)(cz[1] - globalposz)) * ryp0 + ghoriz,
|
|
|
|
((float)(cz[2] - globalposz)) * ryp1 + ghoriz,
|
|
|
|
((float)(cz[3] - globalposz)) * ryp1 + ghoriz };
|
|
|
|
|
|
|
|
float const fsy[4] = { ((float)(fz[0] - globalposz)) * ryp0 + ghoriz,
|
|
|
|
((float)(fz[1] - globalposz)) * ryp0 + ghoriz,
|
|
|
|
((float)(fz[2] - globalposz)) * ryp1 + ghoriz,
|
|
|
|
((float)(fz[3] - globalposz)) * ryp1 + ghoriz };
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//Clip 2 quadrilaterals
|
|
|
|
// /csy3
|
|
|
|
// / |
|
|
|
|
// csy0------/----csy2
|
|
|
|
// | /xxxxxxx|
|
|
|
|
// | /xxxxxxxxx|
|
|
|
|
// csy1/xxxxxxxxxxx|
|
|
|
|
// |xxxxxxxxxxx/fsy3
|
|
|
|
// |xxxxxxxxx/ |
|
|
|
|
// |xxxxxxx/ |
|
|
|
|
// fsy0----/------fsy2
|
|
|
|
// | /
|
|
|
|
// fsy1/
|
|
|
|
|
2019-09-18 22:19:02 +00:00
|
|
|
vec2f_t dpxy[16] = { { x0, csy[1] }, { x1, csy[3] }, { x1, fsy[3] }, { x0, fsy[1] } };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//Clip to (x0,csy[0])-(x1,csy[2])
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-03-19 17:08:43 +00:00
|
|
|
vec2f_t dp2[8];
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
int n2 = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
t1 = -((dpxy[0].x - x0) * (csy[2] - csy[0]) - (dpxy[0].y - csy[0]) * (x1 - x0));
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=0; i<4; i++)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
int j = i + 1;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
if (j >= 4)
|
2015-03-24 00:40:33 +00:00
|
|
|
j = 0;
|
|
|
|
|
|
|
|
t0 = t1;
|
|
|
|
t1 = -((dpxy[j].x - x0) * (csy[2] - csy[0]) - (dpxy[j].y - csy[0]) * (x1 - x0));
|
|
|
|
|
|
|
|
if (t0 >= 0)
|
|
|
|
dp2[n2++] = dpxy[i];
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2017-11-02 04:25:59 +00:00
|
|
|
if ((t0 >= 0) != (t1 >= 0) && (t0 <= 0) != (t1 <= 0))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const r = t0 / (t0 - t1);
|
2019-03-19 17:10:08 +00:00
|
|
|
dp2[n2++] = { (dpxy[j].x - dpxy[i].x) * r + dpxy[i].x, (dpxy[j].y - dpxy[i].y) * r + dpxy[i].y };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (n2 < 3)
|
|
|
|
return;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
|
|
|
//Clip to (x1,fsy[2])-(x0,fsy[0])
|
2015-03-24 00:40:33 +00:00
|
|
|
t1 = -((dp2[0].x - x1) * (fsy[0] - fsy[2]) - (dp2[0].y - fsy[2]) * (x0 - x1));
|
2015-10-20 07:15:15 +00:00
|
|
|
int n = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i = 0, j = 1; i < n2; j = ++i + 1)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
if (j >= n2)
|
|
|
|
j = 0;
|
|
|
|
|
|
|
|
t0 = t1;
|
|
|
|
t1 = -((dp2[j].x - x1) * (fsy[0] - fsy[2]) - (dp2[j].y - fsy[2]) * (x0 - x1));
|
|
|
|
|
|
|
|
if (t0 >= 0)
|
|
|
|
dpxy[n++] = dp2[i];
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2017-11-02 04:25:59 +00:00
|
|
|
if ((t0 >= 0) != (t1 >= 0) && (t0 <= 0) != (t1 <= 0))
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const r = t0 / (t0 - t1);
|
2019-03-19 17:10:08 +00:00
|
|
|
dpxy[n++] = { (dp2[j].x - dp2[i].x) * r + dp2[i].x, (dp2[j].y - dp2[i].y) * r + dp2[i].y };
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
|
|
|
|
if (n < 3)
|
|
|
|
return;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2013-03-04 01:23:29 +00:00
|
|
|
pow2xsplit = 0;
|
|
|
|
skyclamphack = 0;
|
2017-06-25 11:23:47 +00:00
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(dpxy, n, method, tilesiz[globalpicnum]);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2019-06-25 18:35:16 +00:00
|
|
|
void polymost_drawmaskwall(int32_t damaskwallcnt)
|
|
|
|
{
|
|
|
|
int const z = maskwall[damaskwallcnt];
|
|
|
|
polymost_drawmaskwallinternal(thewall[z]);
|
|
|
|
}
|
|
|
|
|
2020-09-01 13:00:35 +00:00
|
|
|
void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t mirrorWall)
|
2019-06-25 18:35:16 +00:00
|
|
|
{
|
|
|
|
polymost_outputGLDebugMessage(3, "polymost_prepareMirror(%u)", mirrorWall);
|
|
|
|
|
|
|
|
//POGO: prepare necessary globals for drawing, as we intend to call this outside of drawrooms
|
2019-08-07 22:44:33 +00:00
|
|
|
gvrcorrection = viewingrange*(1.f/65536.f);
|
2020-01-19 12:57:24 +00:00
|
|
|
//if (glprojectionhacks == 2)
|
2019-08-07 22:44:33 +00:00
|
|
|
{
|
|
|
|
// calculates the extend of the zenith glitch
|
|
|
|
float verticalfovtan = (fviewingrange * (windowxy2.y-windowxy1.y) * 5.f) / ((float)yxaspect * (windowxy2.x-windowxy1.x) * 4.f);
|
|
|
|
float verticalfov = atanf(verticalfovtan) * (2.f / fPI);
|
|
|
|
static constexpr float const maxhorizangle = 0.6361136f; // horiz of 199 in degrees
|
|
|
|
float zenglitch = verticalfov + maxhorizangle - 0.95f; // less than 1 because the zenith glitch extends a bit
|
|
|
|
if (zenglitch > 0.f)
|
|
|
|
gvrcorrection /= (zenglitch * 2.5f) + 1.f;
|
|
|
|
}
|
|
|
|
|
2019-06-25 18:35:16 +00:00
|
|
|
set_globalpos(dax, day, daz);
|
|
|
|
set_globalang(daang);
|
2020-09-01 13:00:35 +00:00
|
|
|
globalhoriz = mulscale16(FixedToInt(dahoriz)-100,divscale16(xdimenscale,viewingrange))+(ydimen>>1);
|
|
|
|
qglobalhoriz = mulscale16(dahoriz-IntToFixed(100), divscale16(xdimenscale, viewingrange))+IntToFixed(ydimen>>1);
|
2019-06-25 18:35:16 +00:00
|
|
|
gyxscale = ((float)xdimenscale)*(1.0f/131072.f);
|
|
|
|
gxyaspect = ((double)xyaspect*fviewingrange)*(5.0/(65536.0*262144.0));
|
|
|
|
gviewxrange = fviewingrange * fxdimen * (1.f/(32768.f*1024.f));
|
|
|
|
gcosang = fcosglobalang*(1.0f/262144.f);
|
|
|
|
gsinang = fsinglobalang*(1.0f/262144.f);
|
|
|
|
gcosang2 = gcosang * (fviewingrange * (1.0f/65536.f));
|
|
|
|
gsinang2 = gsinang * (fviewingrange * (1.0f/65536.f));
|
|
|
|
ghalfx = (float)(xdimen>>1);
|
|
|
|
ghalfy = (float)(ydimen>>1);
|
|
|
|
grhalfxdown10 = 1.f/(ghalfx*1024.f);
|
2020-09-01 13:00:35 +00:00
|
|
|
ghoriz = FixedToFloat(qglobalhoriz);
|
2020-09-21 08:41:56 +00:00
|
|
|
ghorizcorrect = FixedToFloat(divscale16(xdimenscale, viewingrange));
|
2019-06-25 18:35:16 +00:00
|
|
|
resizeglcheck();
|
|
|
|
if (r_yshearing)
|
|
|
|
{
|
|
|
|
gshang = 0.f;
|
|
|
|
gchang = 1.f;
|
2019-09-21 11:02:17 +00:00
|
|
|
ghoriz2 = (float)(ydimen >> 1) - (ghoriz+ghorizcorrect);
|
2019-06-25 18:35:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-21 11:02:17 +00:00
|
|
|
float r = (float)(ydimen >> 1) - (ghoriz+ghorizcorrect);
|
2020-09-08 16:48:18 +00:00
|
|
|
gshang = r / sqrtf(r * r + ghalfx * ghalfx / (gvrcorrection * gvrcorrection));
|
|
|
|
gchang = sqrtf(1.f - gshang * gshang);
|
2019-06-25 18:35:16 +00:00
|
|
|
ghoriz2 = 0.f;
|
|
|
|
}
|
|
|
|
ghoriz = (float)(ydimen>>1);
|
|
|
|
gctang = cosf(gtang);
|
|
|
|
gstang = sinf(gtang);
|
|
|
|
if (Bfabsf(gstang) < .001f)
|
|
|
|
{
|
|
|
|
gstang = 0.f;
|
|
|
|
gctang = (gctang > 0.f) ? 1.f : -1.f;
|
|
|
|
}
|
2020-01-19 15:06:31 +00:00
|
|
|
polymost_updaterotmat();
|
2019-06-25 18:35:16 +00:00
|
|
|
grhalfxdown10x = grhalfxdown10;
|
|
|
|
|
2020-06-04 16:46:44 +00:00
|
|
|
renderBeginScene();
|
2019-06-25 18:35:16 +00:00
|
|
|
//POGO: write the mirror region to the stencil buffer to allow showing mirrors & skyboxes at the same time
|
2019-10-04 16:12:03 +00:00
|
|
|
GLInterface.EnableStencilWrite(1);
|
|
|
|
GLInterface.EnableAlphaTest(false);
|
|
|
|
GLInterface.EnableDepthTest(false);
|
2019-06-25 18:35:16 +00:00
|
|
|
polymost_drawmaskwallinternal(mirrorWall);
|
2019-10-04 16:12:03 +00:00
|
|
|
GLInterface.EnableAlphaTest(true);
|
|
|
|
GLInterface.EnableDepthTest(true);
|
2020-06-04 16:46:44 +00:00
|
|
|
renderFinishScene();
|
2019-06-25 18:35:16 +00:00
|
|
|
|
|
|
|
//POGO: render only to the mirror region
|
2019-10-04 16:12:03 +00:00
|
|
|
GLInterface.EnableStencilTest(1);
|
2019-06-25 18:35:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void polymost_completeMirror()
|
|
|
|
{
|
|
|
|
polymost_outputGLDebugMessage(3, "polymost_completeMirror()");
|
2019-10-04 16:12:03 +00:00
|
|
|
GLInterface.DisableStencil();
|
2019-06-25 18:35:16 +00:00
|
|
|
}
|
|
|
|
|
2015-01-11 04:56:58 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int16_t wall;
|
|
|
|
int8_t wdist;
|
|
|
|
int8_t filler;
|
|
|
|
} wallspriteinfo_t;
|
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static wallspriteinfo_t wsprinfo[MAXSPRITES];
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2016-10-24 21:30:34 +00:00
|
|
|
void Polymost_prepare_loadboard(void)
|
|
|
|
{
|
2020-09-08 16:48:18 +00:00
|
|
|
memset(wsprinfo, 0, sizeof(wsprinfo));
|
2016-10-24 21:30:34 +00:00
|
|
|
}
|
|
|
|
|
2020-07-14 11:51:03 +00:00
|
|
|
void polymost_deletesprite(int num)
|
|
|
|
{
|
|
|
|
wsprinfo[num].wall = -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-12-26 06:27:48 +00:00
|
|
|
static inline int32_t polymost_findwall(tspritetype const * const tspr, vec2_t const * const tsiz, int32_t * rd)
|
2015-01-11 04:56:58 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t dist = 4, closest = -1;
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const sect = (usectortype * )§or[tspr->sectnum];
|
2015-01-11 04:56:58 +00:00
|
|
|
vec2_t n;
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=sect->wallptr; i<sect->wallptr + sect->wallnum; i++)
|
2015-01-11 04:56:58 +00:00
|
|
|
{
|
2016-05-13 22:15:28 +00:00
|
|
|
if ((wall[i].nextsector == -1 || ((sector[wall[i].nextsector].ceilingz > (tspr->z - ((tsiz->y * tspr->yrepeat) << 2))) ||
|
|
|
|
sector[wall[i].nextsector].floorz < tspr->z)) && !polymost_getclosestpointonwall((const vec2_t *) tspr, i, &n))
|
2015-01-11 04:56:58 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
int const dst = klabs(tspr->x - n.x) + klabs(tspr->y - n.y);
|
2015-01-11 04:56:58 +00:00
|
|
|
|
|
|
|
if (dst <= dist)
|
|
|
|
{
|
|
|
|
dist = dst;
|
|
|
|
closest = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*rd = dist;
|
2015-10-20 07:15:15 +00:00
|
|
|
|
2015-01-11 04:56:58 +00:00
|
|
|
return closest;
|
|
|
|
}
|
|
|
|
|
2020-01-28 21:21:53 +00:00
|
|
|
static int32_t polymost_lintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
|
2015-01-11 04:56:58 +00:00
|
|
|
int32_t x3, int32_t y3, int32_t x4, int32_t y4)
|
|
|
|
{
|
|
|
|
// p1 to p2 is a line segment
|
|
|
|
int32_t const x21 = x2 - x1, x34 = x3 - x4;
|
|
|
|
int32_t const y21 = y2 - y1, y34 = y3 - y4;
|
|
|
|
int32_t const bot = x21 * y34 - y21 * x34;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (!bot)
|
|
|
|
return 0;
|
|
|
|
|
2015-01-11 04:56:58 +00:00
|
|
|
int32_t const x31 = x3 - x1, y31 = y3 - y1;
|
|
|
|
int32_t const topt = x31 * y34 - y31 * x34;
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int rv = 1;
|
|
|
|
|
|
|
|
if (bot > 0)
|
2015-01-11 04:56:58 +00:00
|
|
|
{
|
|
|
|
if ((unsigned)topt >= (unsigned)bot)
|
2015-03-24 00:40:33 +00:00
|
|
|
rv = 0;
|
2015-01-11 04:56:58 +00:00
|
|
|
|
|
|
|
int32_t topu = x21 * y31 - y21 * x31;
|
|
|
|
|
|
|
|
if ((unsigned)topu >= (unsigned)bot)
|
2015-03-24 00:40:33 +00:00
|
|
|
rv = 0;
|
2015-01-11 04:56:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((unsigned)topt <= (unsigned)bot)
|
2015-03-24 00:40:33 +00:00
|
|
|
rv = 0;
|
2015-01-11 04:56:58 +00:00
|
|
|
|
|
|
|
int32_t topu = x21 * y31 - y21 * x31;
|
|
|
|
|
|
|
|
if ((unsigned)topu <= (unsigned)bot)
|
2015-03-24 00:40:33 +00:00
|
|
|
rv = 0;
|
2015-01-11 04:56:58 +00:00
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
return rv;
|
2015-01-11 04:56:58 +00:00
|
|
|
}
|
|
|
|
|
2020-05-22 14:27:45 +00:00
|
|
|
#define TSPR_OFFSET_FACTOR .0002f
|
|
|
|
#define TSPR_OFFSET(tspr) (TSPR_OFFSET_FACTOR + ((tspr->owner != -1 ? tspr->owner & 63 : 0) * TSPR_OFFSET_FACTOR))
|
|
|
|
|
|
|
|
#define TSPR_OFFSET_FACTOR2 .000008f
|
|
|
|
#define TSPR_OFFSET2(tspr) ((TSPR_OFFSET_FACTOR + ((tspr->owner != -1 ? tspr->owner & 63 : 1) * TSPR_OFFSET_FACTOR)) * (float)sepdist(globalposx - tspr->x, globalposy - tspr->y, globalposz - tspr->z) * 0.025f)
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2018-02-16 06:38:34 +00:00
|
|
|
|
2009-01-09 09:29:17 +00:00
|
|
|
void polymost_drawsprite(int32_t snum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2019-09-21 11:02:17 +00:00
|
|
|
auto const tspr = tspriteptr[snum];
|
2014-05-01 22:02:21 +00:00
|
|
|
|
2020-09-04 19:24:48 +00:00
|
|
|
if (bad_tspr(tspr))
|
2013-04-29 19:24:19 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-09-21 11:02:17 +00:00
|
|
|
usectorptr_t sec;
|
2013-03-19 06:23:38 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t spritenum = tspr->owner;
|
2013-03-19 06:23:38 +00:00
|
|
|
|
2019-05-25 14:59:09 +00:00
|
|
|
polymost_outputGLDebugMessage(3, "polymost_drawsprite(snum:%d)", snum);
|
|
|
|
|
2019-07-09 05:42:10 +00:00
|
|
|
if ((tspr->cstat&48) != 48)
|
|
|
|
tileUpdatePicnum(&tspr->picnum, spritenum + 32768);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
globalpicnum = tspr->picnum;
|
|
|
|
globalshade = tspr->shade;
|
|
|
|
globalpal = tspr->pal;
|
2020-09-20 18:39:11 +00:00
|
|
|
globalfloorpal = sector[tspr->sectnum].floorpal;
|
2006-04-24 19:04:22 +00:00
|
|
|
globalorientation = tspr->cstat;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(sectorVisibility(tspr->sectnum));
|
2019-03-19 17:08:39 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2_t off = { 0, 0 };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-07-14 18:39:48 +00:00
|
|
|
if ((globalorientation & 48) != 48) // only non-voxel sprites should do this
|
|
|
|
{
|
2020-09-23 14:54:52 +00:00
|
|
|
int const flag = hw_hightile && TileFiles.tiledata[globalpicnum].h_xsize;
|
|
|
|
off = { (int32_t)tspr->xoffset + (flag ? TileFiles.tiledata[globalpicnum].h_xoffs : tileLeftOffset(globalpicnum)),
|
|
|
|
(int32_t)tspr->yoffset + (flag ? TileFiles.tiledata[globalpicnum].h_yoffs : tileTopOffset(globalpicnum)) };
|
2020-07-14 18:39:48 +00:00
|
|
|
}
|
|
|
|
|
2015-12-04 11:52:54 +00:00
|
|
|
int32_t method = DAMETH_MASK | DAMETH_CLAMPED;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (tspr->cstat & 2)
|
2016-05-13 22:15:28 +00:00
|
|
|
method = DAMETH_CLAMPED | ((tspr->cstat & 512) ? DAMETH_TRANS2 : DAMETH_TRANS1);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-05-23 12:40:54 +00:00
|
|
|
SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
|
2016-10-09 07:55:23 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
drawpoly_alpha = spriteext[spritenum].alpha;
|
2016-10-09 07:55:23 +00:00
|
|
|
drawpoly_blend = tspr->blend;
|
2013-03-04 01:23:29 +00:00
|
|
|
|
2019-09-21 11:02:17 +00:00
|
|
|
sec = (usectorptr_t)§or[tspr->sectnum];
|
2015-03-24 00:40:48 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
while (!(spriteext[spritenum].flags & SPREXT_NOTMD))
|
2007-12-12 17:42:14 +00:00
|
|
|
{
|
2019-10-23 19:11:37 +00:00
|
|
|
if (hw_models && tile2model[Ptile2tile(tspr->picnum, tspr->pal)].modelid >= 0 &&
|
2015-03-24 00:40:33 +00:00
|
|
|
tile2model[Ptile2tile(tspr->picnum, tspr->pal)].framenum >= 0)
|
2007-12-12 17:42:14 +00:00
|
|
|
{
|
2016-05-13 22:15:28 +00:00
|
|
|
if (polymost_mddraw(tspr)) return;
|
2015-03-24 00:40:33 +00:00
|
|
|
break; // else, render as flat sprite
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2012-10-01 17:52:22 +00:00
|
|
|
|
2019-12-19 16:51:33 +00:00
|
|
|
if (r_voxels)
|
2007-12-12 17:42:14 +00:00
|
|
|
{
|
2019-12-19 16:51:33 +00:00
|
|
|
if ((tspr->cstat & 48) != 48 && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]])
|
|
|
|
{
|
|
|
|
if (polymost_voxdraw(voxmodels[tiletovox[tspr->picnum]], tspr)) return;
|
|
|
|
break; // else, render as flat sprite
|
|
|
|
}
|
2012-10-01 17:52:22 +00:00
|
|
|
|
2020-07-01 20:14:11 +00:00
|
|
|
if ((tspr->cstat & 48) == 48 && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum])
|
2019-12-19 16:51:33 +00:00
|
|
|
{
|
|
|
|
polymost_voxdraw(voxmodels[tspr->picnum], tspr);
|
|
|
|
return;
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
|
2019-12-19 16:51:33 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-10-01 17:52:22 +00:00
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
vec3_t pos = tspr->pos;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (spriteext[spritenum].flags & SPREXT_AWAY1)
|
2007-12-20 19:14:38 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
pos.x += (sintable[(tspr->ang + 512) & 2047] >> 13);
|
|
|
|
pos.y += (sintable[(tspr->ang) & 2047] >> 13);
|
2007-12-20 19:14:38 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
else if (spriteext[spritenum].flags & SPREXT_AWAY2)
|
2007-12-28 20:04:58 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
pos.x -= (sintable[(tspr->ang + 512) & 2047] >> 13);
|
|
|
|
pos.y -= (sintable[(tspr->ang) & 2047] >> 13);
|
2007-12-28 20:04:58 +00:00
|
|
|
}
|
2012-10-01 17:52:22 +00:00
|
|
|
|
2020-09-23 14:54:52 +00:00
|
|
|
vec2_t tsiz;
|
|
|
|
|
|
|
|
if (hw_hightile && TileFiles.tiledata[globalpicnum].h_xsize)
|
|
|
|
tsiz = { TileFiles.tiledata[globalpicnum].h_xsize, TileFiles.tiledata[globalpicnum].h_ysize };
|
|
|
|
else
|
|
|
|
tsiz = { tileWidth(globalpicnum), tileHeight(globalpicnum) };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (tsiz.x <= 0 || tsiz.y <= 0)
|
2012-06-13 23:13:36 +00:00
|
|
|
return;
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2f_t const ftsiz = { (float) tsiz.x, (float) tsiz.y };
|
2014-10-25 03:26:31 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
switch ((globalorientation >> 4) & 3)
|
|
|
|
{
|
|
|
|
case 0: // Face sprite
|
2014-10-25 03:26:31 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
// Project 3D to 2D
|
|
|
|
if (globalorientation & 4)
|
2015-03-24 00:40:48 +00:00
|
|
|
off.x = -off.x;
|
2015-03-24 00:40:33 +00:00
|
|
|
// NOTE: yoff not negated not for y flipping, unlike wall and floor
|
|
|
|
// aligned sprites.
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2015-10-20 07:15:28 +00:00
|
|
|
int const ang = (getangle(tspr->x - globalposx, tspr->y - globalposy) + 1024) & 2047;
|
|
|
|
|
2020-05-22 14:27:45 +00:00
|
|
|
float foffs = TSPR_OFFSET(tspr);
|
|
|
|
float foffs2 = TSPR_OFFSET(tspr);
|
|
|
|
if (fabs(foffs2) < fabs(foffs)) foffs = foffs2;
|
2015-10-20 07:15:28 +00:00
|
|
|
|
2020-05-22 14:27:45 +00:00
|
|
|
vec2f_t const offs = { (float)(sintable[(ang + 512) & 2047] >> 6)* foffs, (float) (sintable[(ang) & 2047] >> 6) * foffs };
|
2015-10-20 07:15:28 +00:00
|
|
|
|
|
|
|
vec2f_t s0 = { (float)(tspr->x - globalposx) + offs.x,
|
2018-02-16 06:38:21 +00:00
|
|
|
(float)(tspr->y - globalposy) + offs.y};
|
2015-10-20 07:15:28 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vec2f_t p0 = { s0.y * gcosang - s0.x * gsinang, s0.x * gcosang2 + s0.y * gsinang2 };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (p0.y <= SCISDIST)
|
2019-03-19 17:08:39 +00:00
|
|
|
goto _drawsprite_return;
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
float const ryp0 = 1.f / p0.y;
|
2020-02-02 19:00:37 +00:00
|
|
|
s0 = { ghalfx * p0.x * ryp0 + ghalfx, ((float)(pos.z - globalposz)) * gyxscale * ryp0 + ghoriz };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
float const f = ryp0 * fxdimen * (1.0f / 160.f);
|
|
|
|
|
|
|
|
vec2f_t ff = { ((float)tspr->xrepeat) * f,
|
|
|
|
((float)tspr->yrepeat) * f * ((float)yxaspect * (1.0f / 65536.f)) };
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (tsiz.x & 1)
|
2015-03-24 00:40:48 +00:00
|
|
|
s0.x += ff.x * 0.5f;
|
2017-06-23 09:17:12 +00:00
|
|
|
if (globalorientation & 128 && tsiz.y & 1)
|
|
|
|
s0.y += ff.y * 0.5f;
|
2015-03-24 00:40:48 +00:00
|
|
|
|
|
|
|
s0.x -= ff.x * (float) off.x;
|
|
|
|
s0.y -= ff.y * (float) off.y;
|
|
|
|
|
|
|
|
ff.x *= ftsiz.x;
|
|
|
|
ff.y *= ftsiz.y;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec2f_t pxy[4];
|
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
pxy[0].x = pxy[3].x = s0.x - ff.x * 0.5f;
|
|
|
|
pxy[1].x = pxy[2].x = s0.x + ff.x * 0.5f;
|
2015-03-24 00:40:33 +00:00
|
|
|
if (!(globalorientation & 128))
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
pxy[0].y = pxy[1].y = s0.y - ff.y;
|
2015-03-24 00:40:33 +00:00
|
|
|
pxy[2].y = pxy[3].y = s0.y;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
pxy[0].y = pxy[1].y = s0.y - ff.y * 0.5f;
|
|
|
|
pxy[2].y = pxy[3].y = s0.y + ff.y * 0.5f;
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
xtex.d = ytex.d = ytex.u = xtex.v = 0;
|
|
|
|
otex.d = ryp0 * gviewxrange;
|
|
|
|
|
|
|
|
if (!(globalorientation & 4))
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
xtex.u = ftsiz.x * otex.d / (pxy[1].x - pxy[0].x + .002f);
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.u = -xtex.u * (pxy[0].x - .001f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
xtex.u = ftsiz.x * otex.d / (pxy[0].x - pxy[1].x - .002f);
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.u = -xtex.u * (pxy[1].x + .001f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(globalorientation & 8))
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
ytex.v = ftsiz.y * otex.d / (pxy[3].y - pxy[0].y + .002f);
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.v = -ytex.v * (pxy[0].y - .001f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
ytex.v = ftsiz.y * otex.d / (pxy[0].y - pxy[3].y - .002f);
|
2015-03-24 00:40:33 +00:00
|
|
|
otex.v = -ytex.v * (pxy[3].y + .001f);
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// sprite panning
|
|
|
|
if (spriteext[spritenum].xpanning)
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
ytex.u -= ytex.d * ((float) (spriteext[spritenum].xpanning) * (1.0f / 255.f)) * ftsiz.x;
|
|
|
|
otex.u -= otex.d * ((float) (spriteext[spritenum].xpanning) * (1.0f / 255.f)) * ftsiz.x;
|
2015-03-24 00:40:33 +00:00
|
|
|
drawpoly_srepeat = 1;
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (spriteext[spritenum].ypanning)
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
ytex.v -= ytex.d * ((float) (spriteext[spritenum].ypanning) * (1.0f / 255.f)) * ftsiz.y;
|
|
|
|
otex.v -= otex.d * ((float) (spriteext[spritenum].ypanning) * (1.0f / 255.f)) * ftsiz.y;
|
2015-03-24 00:40:33 +00:00
|
|
|
drawpoly_trepeat = 1;
|
|
|
|
}
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// Clip sprites to ceilings/floors when no parallaxing and not sloped
|
|
|
|
if (!(sector[tspr->sectnum].ceilingstat & 3))
|
|
|
|
{
|
|
|
|
s0.y = ((float) (sector[tspr->sectnum].ceilingz - globalposz)) * gyxscale * ryp0 + ghoriz;
|
|
|
|
if (pxy[0].y < s0.y)
|
|
|
|
pxy[0].y = pxy[1].y = s0.y;
|
|
|
|
}
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (!(sector[tspr->sectnum].floorstat & 3))
|
|
|
|
{
|
|
|
|
s0.y = ((float) (sector[tspr->sectnum].floorz - globalposz)) * gyxscale * ryp0 + ghoriz;
|
|
|
|
if (pxy[2].y > s0.y)
|
|
|
|
pxy[2].y = pxy[3].y = s0.y;
|
|
|
|
}
|
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
|
2015-03-24 00:40:33 +00:00
|
|
|
pow2xsplit = 0;
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(pxy, 4, method, tempsiz);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
drawpoly_srepeat = 0;
|
|
|
|
drawpoly_trepeat = 0;
|
|
|
|
}
|
2015-03-24 00:40:48 +00:00
|
|
|
break;
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
case 1: // Wall sprite
|
2015-01-11 04:56:58 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
// Project 3D to 2D
|
|
|
|
if (globalorientation & 4)
|
2015-03-24 00:40:48 +00:00
|
|
|
off.x = -off.x;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (globalorientation & 8)
|
2015-03-24 00:40:48 +00:00
|
|
|
off.y = -off.y;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec2f_t const extent = { (float)tspr->xrepeat * (float)sintable[(tspr->ang) & 2047] * (1.0f / 65536.f),
|
|
|
|
(float)tspr->xrepeat * (float)sintable[(tspr->ang + 1536) & 2047] * (1.0f / 65536.f) };
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
float f = (float)(tsiz.x >> 1) + (float)off.x;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec2f_t const vf = { extent.x * f, extent.y * f };
|
2016-06-05 04:46:28 +00:00
|
|
|
|
|
|
|
vec2f_t vec0 = { (float)(pos.x - globalposx) - vf.x,
|
2015-03-24 00:40:33 +00:00
|
|
|
(float)(pos.y - globalposy) - vf.y };
|
2015-01-11 04:56:58 +00:00
|
|
|
|
|
|
|
int32_t const s = tspr->owner;
|
|
|
|
int32_t walldist = 1;
|
|
|
|
int32_t w = (s == -1) ? -1 : wsprinfo[s].wall;
|
|
|
|
|
|
|
|
// find the wall most likely to be what the sprite is supposed to be ornamented against
|
2020-07-14 11:51:03 +00:00
|
|
|
// this is really slow, so cache the result. Also assume that this association never changes once it is set up
|
|
|
|
if (s == -1 || !wsprinfo[s].wall)
|
2015-01-11 04:56:58 +00:00
|
|
|
{
|
2016-05-13 22:15:28 +00:00
|
|
|
w = polymost_findwall(tspr, &tsiz, &walldist);
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2016-06-21 00:32:47 +00:00
|
|
|
if (s != -1)
|
2015-01-11 04:56:58 +00:00
|
|
|
{
|
|
|
|
wallspriteinfo_t *ws = &wsprinfo[s];
|
|
|
|
ws->wall = w;
|
2016-06-21 00:32:47 +00:00
|
|
|
|
|
|
|
if (w != -1)
|
|
|
|
{
|
|
|
|
ws->wdist = walldist;
|
|
|
|
}
|
2015-01-11 04:56:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (s != -1)
|
|
|
|
walldist = wsprinfo[s].wdist;
|
|
|
|
|
|
|
|
// detect if the sprite is either on the wall line or the wall line and sprite intersect
|
|
|
|
if (w != -1)
|
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
vec2_t v = { /*Blrintf(vf.x)*/(int)vf.x, /*Blrintf(vf.y)*/(int)vf.y };
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2015-10-20 07:15:15 +00:00
|
|
|
if (walldist <= 2 || ((pos.x - v.x) + (pos.x + v.x)) == (wall[w].x + POINT2(w).x) ||
|
2015-03-24 00:40:33 +00:00
|
|
|
((pos.y - v.y) + (pos.y + v.y)) == (wall[w].y + POINT2(w).y) ||
|
|
|
|
polymost_lintersect(pos.x - v.x, pos.y - v.y, pos.x + v.x, pos.y + v.y, wall[w].x, wall[w].y,
|
|
|
|
POINT2(w).x, POINT2(w).y))
|
2015-01-11 04:56:58 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
int32_t const ang = getangle(wall[w].x - POINT2(w).x, wall[w].y - POINT2(w).y);
|
2015-10-21 19:53:57 +00:00
|
|
|
float const foffs = TSPR_OFFSET(tspr);
|
2015-10-20 07:15:15 +00:00
|
|
|
vec2f_t const offs = { (float)(sintable[(ang + 1024) & 2047] >> 6) * foffs,
|
|
|
|
(float)(sintable[(ang + 512) & 2047] >> 6) * foffs};
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vec0.x -= offs.x;
|
|
|
|
vec0.y -= offs.y;
|
2015-01-11 04:56:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vec2f_t p0 = { vec0.y * gcosang - vec0.x * gsinang,
|
|
|
|
vec0.x * gcosang2 + vec0.y * gsinang2 };
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
vec2f_t const pp = { extent.x * ftsiz.x + vec0.x,
|
|
|
|
extent.y * ftsiz.x + vec0.y };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
vec2f_t p1 = { pp.y * gcosang - pp.x * gsinang,
|
|
|
|
pp.x * gcosang2 + pp.y * gsinang2 };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if ((p0.y <= SCISDIST) && (p1.y <= SCISDIST))
|
2019-03-19 17:08:39 +00:00
|
|
|
goto _drawsprite_return;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// Clip to close parallel-screen plane
|
|
|
|
vec2f_t const op0 = p0;
|
2014-10-25 03:26:31 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
float t0 = 0.f, t1 = 1.f;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (p0.y < SCISDIST)
|
|
|
|
{
|
|
|
|
t0 = (SCISDIST - p0.y) / (p1.y - p0.y);
|
2019-03-19 17:10:08 +00:00
|
|
|
p0 = { (p1.x - p0.x) * t0 + p0.x, SCISDIST };
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (p1.y < SCISDIST)
|
|
|
|
{
|
|
|
|
t1 = (SCISDIST - op0.y) / (p1.y - op0.y);
|
2019-03-19 17:10:08 +00:00
|
|
|
p1 = { (p1.x - op0.x) * t1 + op0.x, SCISDIST };
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
f = 1.f / p0.y;
|
|
|
|
const float ryp0 = f * gyxscale;
|
|
|
|
float sx0 = ghalfx * p0.x * f + ghalfx;
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
f = 1.f / p1.y;
|
|
|
|
const float ryp1 = f * gyxscale;
|
|
|
|
float sx1 = ghalfx * p1.x * f + ghalfx;
|
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
pos.z -= ((off.y * tspr->yrepeat) << 2);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (globalorientation & 128)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2020-02-02 19:00:37 +00:00
|
|
|
pos.z += ((tsiz.y * tspr->yrepeat) << 1);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
if (tsiz.y & 1)
|
2020-02-02 19:00:37 +00:00
|
|
|
pos.z += (tspr->yrepeat << 1); // Odd yspans
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
xtex.d = (ryp0 - ryp1) * gxyaspect / (sx0 - sx1);
|
|
|
|
ytex.d = 0;
|
|
|
|
otex.d = ryp0 * gxyaspect - xtex.d * sx0;
|
|
|
|
|
|
|
|
if (globalorientation & 4)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
t0 = 1.f - t0;
|
|
|
|
t1 = 1.f - t1;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// sprite panning
|
|
|
|
if (spriteext[spritenum].xpanning)
|
|
|
|
{
|
|
|
|
float const xpan = ((float)(spriteext[spritenum].xpanning) * (1.0f / 255.f));
|
|
|
|
t0 -= xpan;
|
|
|
|
t1 -= xpan;
|
|
|
|
drawpoly_srepeat = 1;
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
xtex.u = (t0 * ryp0 - t1 * ryp1) * gxyaspect * ftsiz.x / (sx0 - sx1);
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.u = 0;
|
2015-03-24 00:40:48 +00:00
|
|
|
otex.u = t0 * ryp0 * gxyaspect * ftsiz.x - xtex.u * sx0;
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
f = ((float) tspr->yrepeat) * ftsiz.y * 4;
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
float sc0 = ((float) (pos.z - globalposz - f)) * ryp0 + ghoriz;
|
|
|
|
float sc1 = ((float) (pos.z - globalposz - f)) * ryp1 + ghoriz;
|
|
|
|
float sf0 = ((float) (pos.z - globalposz)) * ryp0 + ghoriz;
|
|
|
|
float sf1 = ((float) (pos.z - globalposz)) * ryp1 + ghoriz;
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// gvx*sx0 + gvy*sc0 + gvo = 0
|
|
|
|
// gvx*sx1 + gvy*sc1 + gvo = 0
|
|
|
|
// gvx*sx0 + gvy*sf0 + gvo = tsizy*(gdx*sx0 + gdo)
|
2015-03-24 00:40:48 +00:00
|
|
|
f = ftsiz.y * (xtex.d * sx0 + otex.d) / ((sx0 - sx1) * (sc0 - sf0));
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if (!(globalorientation & 8))
|
|
|
|
{
|
|
|
|
xtex.v = (sc0 - sc1) * f;
|
|
|
|
ytex.v = (sx1 - sx0) * f;
|
|
|
|
otex.v = -xtex.v * sx0 - ytex.v * sc0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xtex.v = (sf1 - sf0) * f;
|
|
|
|
ytex.v = (sx0 - sx1) * f;
|
|
|
|
otex.v = -xtex.v * sx0 - ytex.v * sf0;
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// sprite panning
|
|
|
|
if (spriteext[spritenum].ypanning)
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const ypan = ((float)(spriteext[spritenum].ypanning) * (1.0f / 255.f)) * ftsiz.y;
|
2015-03-24 00:40:33 +00:00
|
|
|
xtex.v -= xtex.d * ypan;
|
|
|
|
ytex.v -= ytex.d * ypan;
|
|
|
|
otex.v -= otex.d * ypan;
|
|
|
|
drawpoly_trepeat = 1;
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// Clip sprites to ceilings/floors when no parallaxing
|
|
|
|
if (!(sector[tspr->sectnum].ceilingstat & 1))
|
|
|
|
{
|
2020-02-02 19:00:37 +00:00
|
|
|
if (sector[tspr->sectnum].ceilingz > pos.z - (float)((tspr->yrepeat * tsiz.y) << 2))
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
|
|
|
sc0 = (float)(sector[tspr->sectnum].ceilingz - globalposz) * ryp0 + ghoriz;
|
|
|
|
sc1 = (float)(sector[tspr->sectnum].ceilingz - globalposz) * ryp1 + ghoriz;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!(sector[tspr->sectnum].floorstat & 1))
|
|
|
|
{
|
2020-02-02 19:00:37 +00:00
|
|
|
if (sector[tspr->sectnum].floorz < pos.z)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
|
|
|
sf0 = (float)(sector[tspr->sectnum].floorz - globalposz) * ryp0 + ghoriz;
|
|
|
|
sf1 = (float)(sector[tspr->sectnum].floorz - globalposz) * ryp1 + ghoriz;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sx0 > sx1)
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2015-03-24 00:40:33 +00:00
|
|
|
if (globalorientation & 64)
|
2019-03-19 17:08:39 +00:00
|
|
|
goto _drawsprite_return; // 1-sided sprite
|
2015-03-24 00:40:48 +00:00
|
|
|
|
2020-09-10 14:36:31 +00:00
|
|
|
std::swap(sx0, sx1);
|
|
|
|
std::swap(sc0, sc1);
|
|
|
|
std::swap(sf0, sf1);
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
vec2f_t const pxy[4] = { { sx0, sc0 }, { sx1, sc1 }, { sx1, sf1 }, { sx0, sf0 } };
|
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
|
|
|
|
pow2xsplit = 0;
|
|
|
|
polymost_drawpoly(pxy, 4, method, tempsiz);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
drawpoly_srepeat = 0;
|
|
|
|
drawpoly_trepeat = 0;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
break;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
case 2: // Floor sprite
|
2020-06-05 17:06:31 +00:00
|
|
|
GLInterface.SetVisibility(sectorVisibility(tspr->sectnum) * (4.f/5.f)); // No idea why this uses a different visibility setting...
|
2019-03-19 17:08:39 +00:00
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
if ((globalorientation & 64) != 0 && (globalposz > pos.z) == (!(globalorientation & 8)))
|
2019-03-19 17:08:39 +00:00
|
|
|
goto _drawsprite_return;
|
2015-03-24 00:40:33 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((globalorientation & 4) > 0)
|
2015-03-24 00:40:48 +00:00
|
|
|
off.x = -off.x;
|
2015-03-24 00:40:33 +00:00
|
|
|
if ((globalorientation & 8) > 0)
|
2015-03-24 00:40:48 +00:00
|
|
|
off.y = -off.y;
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2017-06-21 13:47:04 +00:00
|
|
|
vec2f_t const p0 = { (float)(((tsiz.x + 1) >> 1) - off.x) * tspr->xrepeat,
|
|
|
|
(float)(((tsiz.y + 1) >> 1) - off.y) * tspr->yrepeat },
|
2015-03-24 00:40:48 +00:00
|
|
|
p1 = { (float)((tsiz.x >> 1) + off.x) * tspr->xrepeat,
|
|
|
|
(float)((tsiz.y >> 1) + off.y) * tspr->yrepeat };
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
float const c = sintable[(tspr->ang + 512) & 2047] * (1.0f / 65536.f);
|
|
|
|
float const s = sintable[tspr->ang & 2047] * (1.0f / 65536.f);
|
2015-01-11 04:56:58 +00:00
|
|
|
|
2016-05-13 22:15:28 +00:00
|
|
|
vec2f_t pxy[6];
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// Project 3D to 2D
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t j = 0; j < 4; j++)
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
|
|
|
vec2f_t s0 = { (float)(tspr->x - globalposx), (float)(tspr->y - globalposy) };
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
if ((j + 0) & 2)
|
|
|
|
{
|
|
|
|
s0.y -= s * p0.y;
|
|
|
|
s0.x -= c * p0.y;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
s0.y += s * p1.y;
|
|
|
|
s0.x += c * p1.y;
|
|
|
|
}
|
|
|
|
if ((j + 1) & 2)
|
|
|
|
{
|
|
|
|
s0.x -= s * p0.x;
|
|
|
|
s0.y += c * p0.x;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
s0.x += s * p1.x;
|
|
|
|
s0.y -= c * p1.x;
|
|
|
|
}
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2019-03-19 17:10:08 +00:00
|
|
|
pxy[j] = { s0.y * gcosang - s0.x * gsinang, s0.x * gcosang2 + s0.y * gsinang2 };
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
2014-10-25 03:26:31 +00:00
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
if (pos.z < globalposz) // if floor sprite is above you, reverse order of points
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
2020-09-04 19:24:48 +00:00
|
|
|
static_assert(sizeof(uint64_t) == sizeof(vec2f_t));
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2020-09-10 14:36:31 +00:00
|
|
|
std::swap(pxy[0], pxy[1]);
|
|
|
|
std::swap(pxy[2], pxy[3]);
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
// Clip to SCISDIST plane
|
|
|
|
int32_t npoints = 0;
|
|
|
|
vec2f_t p2[6];
|
2008-01-03 21:54:58 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i = 0, j = 1; i < 4; j = ((++i + 1) & 3))
|
2015-03-24 00:40:33 +00:00
|
|
|
{
|
|
|
|
if (pxy[i].y >= SCISDIST)
|
|
|
|
p2[npoints++] = pxy[i];
|
|
|
|
|
|
|
|
if ((pxy[i].y >= SCISDIST) != (pxy[j].y >= SCISDIST))
|
|
|
|
{
|
|
|
|
float const f = (SCISDIST - pxy[i].y) / (pxy[j].y - pxy[i].y);
|
|
|
|
vec2f_t const t = { (pxy[j].x - pxy[i].x) * f + pxy[i].x,
|
|
|
|
(pxy[j].y - pxy[i].y) * f + pxy[i].y };
|
|
|
|
p2[npoints++] = t;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (npoints < 3)
|
2019-03-19 17:08:39 +00:00
|
|
|
goto _drawsprite_return;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
// Project rotated 3D points to screen
|
|
|
|
|
2015-10-23 23:00:10 +00:00
|
|
|
int fadjust = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-10-23 23:00:10 +00:00
|
|
|
// unfortunately, offsetting by only 1 isn't enough on most Android devices
|
2020-02-02 19:00:37 +00:00
|
|
|
if (pos.z == sec->ceilingz || pos.z == sec->ceilingz + 1)
|
|
|
|
pos.z = sec->ceilingz + 2, fadjust = (tspr->owner & 31);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
if (pos.z == sec->floorz || pos.z == sec->floorz - 1)
|
|
|
|
pos.z = sec->floorz - 2, fadjust = -((tspr->owner & 31));
|
2015-10-23 23:00:10 +00:00
|
|
|
|
2020-02-02 19:00:37 +00:00
|
|
|
float f = (float)(pos.z - globalposz + fadjust) * gyxscale;
|
2015-04-18 21:59:20 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t j = 0; j < npoints; j++)
|
2015-03-24 00:40:48 +00:00
|
|
|
{
|
2015-10-20 07:15:15 +00:00
|
|
|
float const ryp0 = 1.f / p2[j].y;
|
2019-03-19 17:10:08 +00:00
|
|
|
pxy[j] = { ghalfx * p2[j].x * ryp0 + ghalfx, f * ryp0 + ghoriz };
|
2015-03-24 00:40:48 +00:00
|
|
|
}
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
// gd? Copied from floor rendering code
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
xtex.d = 0;
|
2020-02-02 19:00:37 +00:00
|
|
|
ytex.d = gxyaspect / (double)(pos.z - globalposz + fadjust);
|
2015-03-24 00:40:48 +00:00
|
|
|
otex.d = -ghoriz * ytex.d;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
// copied&modified from relative alignment
|
|
|
|
vec2f_t const vv = { (float)tspr->x + s * p1.x + c * p1.y, (float)tspr->y + s * p1.y - c * p1.x };
|
|
|
|
vec2f_t ff = { -(p0.x + p1.x) * s, (p0.x + p1.x) * c };
|
|
|
|
|
2015-10-20 07:15:15 +00:00
|
|
|
f = polymost_invsqrt_approximation(ff.x * ff.x + ff.y * ff.y);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
ff.x *= f;
|
|
|
|
ff.y *= f;
|
|
|
|
|
|
|
|
float const ft[4] = { ((float)(globalposy - vv.y)) * ff.y + ((float)(globalposx - vv.x)) * ff.x,
|
2015-03-24 00:40:48 +00:00
|
|
|
((float)(globalposx - vv.x)) * ff.y - ((float)(globalposy - vv.y)) * ff.x,
|
2018-03-07 12:02:03 +00:00
|
|
|
fsinglobalang * ff.y + fcosglobalang * ff.x,
|
|
|
|
fsinglobalang * ff.x - fcosglobalang * ff.y };
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2015-03-24 00:40:48 +00:00
|
|
|
f = fviewingrange * -(1.f / (65536.f * 262144.f));
|
|
|
|
xtex.u = (float)ft[3] * f;
|
|
|
|
xtex.v = (float)ft[2] * f;
|
2015-03-24 00:40:33 +00:00
|
|
|
ytex.u = ft[0] * ytex.d;
|
|
|
|
ytex.v = ft[1] * ytex.d;
|
|
|
|
otex.u = ft[0] * otex.d;
|
|
|
|
otex.v = ft[1] * otex.d;
|
|
|
|
otex.u += (ft[2] * (1.0f / 262144.f) - xtex.u) * ghalfx;
|
|
|
|
otex.v -= (ft[3] * (1.0f / 262144.f) + xtex.v) * ghalfx;
|
|
|
|
|
|
|
|
f = 4.f / (float)tspr->xrepeat;
|
|
|
|
xtex.u *= f;
|
|
|
|
ytex.u *= f;
|
|
|
|
otex.u *= f;
|
|
|
|
|
|
|
|
f = -4.f / (float)tspr->yrepeat;
|
|
|
|
xtex.v *= f;
|
|
|
|
ytex.v *= f;
|
|
|
|
otex.v *= f;
|
|
|
|
|
|
|
|
if (globalorientation & 4)
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
xtex.u = ftsiz.x * xtex.d - xtex.u;
|
|
|
|
ytex.u = ftsiz.x * ytex.d - ytex.u;
|
|
|
|
otex.u = ftsiz.x * otex.d - otex.u;
|
2015-03-24 00:40:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// sprite panning
|
|
|
|
if (spriteext[spritenum].xpanning)
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const f = ((float)(spriteext[spritenum].xpanning) * (1.0f / 255.f)) * ftsiz.x;
|
|
|
|
ytex.u -= ytex.d * f;
|
|
|
|
otex.u -= otex.d * f;
|
2015-03-24 00:40:33 +00:00
|
|
|
drawpoly_srepeat = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (spriteext[spritenum].ypanning)
|
|
|
|
{
|
2015-03-24 00:40:48 +00:00
|
|
|
float const f = ((float)(spriteext[spritenum].ypanning) * (1.0f / 255.f)) * ftsiz.y;
|
|
|
|
ytex.v -= ytex.d * f;
|
|
|
|
otex.v -= otex.d * f;
|
2015-03-24 00:40:33 +00:00
|
|
|
drawpoly_trepeat = 1;
|
|
|
|
}
|
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
|
|
|
|
pow2xsplit = 0;
|
2015-03-24 00:40:33 +00:00
|
|
|
|
2019-10-11 19:04:31 +00:00
|
|
|
polymost_drawpoly(pxy, npoints, method, tempsiz);
|
2015-03-24 00:40:33 +00:00
|
|
|
|
|
|
|
drawpoly_srepeat = 0;
|
|
|
|
drawpoly_trepeat = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: // Voxel sprite
|
|
|
|
break;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
2019-08-01 06:50:56 +00:00
|
|
|
|
|
|
|
if (automapping == 1 && (unsigned)spritenum < MAXSPRITES)
|
2020-09-06 10:44:58 +00:00
|
|
|
show2dsprite.Set(spritenum);
|
2019-08-01 06:50:56 +00:00
|
|
|
|
2019-03-19 17:08:39 +00:00
|
|
|
_drawsprite_return:
|
2020-01-19 15:06:31 +00:00
|
|
|
;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2020-09-04 19:24:48 +00:00
|
|
|
static_assert((int)RS_YFLIP == (int)HUDFLAG_FLIPPED);
|
2013-11-22 19:26:52 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
void polymost_initosdfuncs(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-20 20:48:54 +00:00
|
|
|
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
// dapicnum and dapalnum are like you'd expect
|
|
|
|
// datype is 0 for a wall/floor/ceiling and 1 for a sprite
|
|
|
|
// basically this just means walls are repeating
|
|
|
|
// while sprites are clamped
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() < REND_POLYMOST) return;
|
2020-05-27 20:19:02 +00:00
|
|
|
if ((dapalnum < (MAXPALOOKUPS - RESERVEDPALS)) && (!lookups.checkTable(dapalnum))) return;//dapalnum = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2020-04-11 21:45:45 +00:00
|
|
|
//Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype);
|
2006-04-24 19:04:22 +00:00
|
|
|
hicprecaching = 1;
|
2020-05-29 14:46:36 +00:00
|
|
|
int palid = TRANSLATION(Translation_Remap + curbasepal, dapalnum);
|
2020-06-02 14:55:02 +00:00
|
|
|
GLInterface.SetTexture(dapicnum, tileGetTexture(dapicnum), palid, CLAMP_NONE);
|
2006-04-24 19:04:22 +00:00
|
|
|
hicprecaching = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2019-10-23 19:11:37 +00:00
|
|
|
if (datype == 0 || !hw_models) return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-10-25 23:31:05 +00:00
|
|
|
int const mid = md_tilehasmodel(dapicnum, dapalnum);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2015-12-23 04:05:51 +00:00
|
|
|
if (mid < 0 || models[mid]->mdnum < 2) return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-10-25 23:31:05 +00:00
|
|
|
int const surfaces = (models[mid]->mdnum == 3) ? ((md3model_t *)models[mid])->head.numsurfs : 0;
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2018-10-25 23:31:05 +00:00
|
|
|
for (int i = 0; i <= surfaces; i++)
|
2019-10-18 12:04:32 +00:00
|
|
|
{
|
2019-10-18 17:06:57 +00:00
|
|
|
auto tex = mdloadskin((md2model_t *)models[mid], 0, dapalnum, i, nullptr);
|
2020-05-29 14:46:36 +00:00
|
|
|
int palid = TRANSLATION(Translation_Remap + curbasepal, dapalnum);
|
2020-06-02 14:55:02 +00:00
|
|
|
if (tex) GLInterface.SetTexture(-1, tex, palid, CLAMP_NONE);
|
2019-10-18 12:04:32 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2019-10-14 22:54:14 +00:00
|
|
|
void PrecacheHardwareTextures(int nTile)
|
|
|
|
{
|
|
|
|
// PRECACHE
|
|
|
|
// This really *really* needs improvement on the game side - the entire precaching logic has no clue about the different needs of a hardware renderer.
|
|
|
|
polymost_precache(nTile, 0, 1);
|
|
|
|
}
|
2019-12-23 18:37:40 +00:00
|
|
|
|
|
|
|
extern char* voxfilenames[MAXVOXELS];
|
|
|
|
void (*PolymostProcessVoxels_Callback)(void) = NULL;
|
2020-07-14 15:35:19 +00:00
|
|
|
void PolymostProcessVoxels(void)
|
2019-12-23 18:37:40 +00:00
|
|
|
{
|
|
|
|
if (PolymostProcessVoxels_Callback)
|
|
|
|
PolymostProcessVoxels_Callback();
|
|
|
|
|
|
|
|
if (g_haveVoxels != 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
g_haveVoxels = 2;
|
|
|
|
|
2020-08-25 18:21:18 +00:00
|
|
|
Printf(PRINT_NONOTIFY, "Generating voxel models for Polymost. This may take a while...\n");
|
2019-12-23 18:37:40 +00:00
|
|
|
|
|
|
|
for (bssize_t i = 0; i < MAXVOXELS; i++)
|
|
|
|
{
|
|
|
|
if (voxfilenames[i])
|
|
|
|
{
|
|
|
|
voxmodels[i] = voxload(voxfilenames[i]);
|
|
|
|
voxmodels[i]->scale = voxscale[i] * (1.f / 65536.f);
|
|
|
|
DO_FREE_AND_NULL(voxfilenames[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|