From 291726cc5564098f3aabd19e4ce774709c817722 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 3 Aug 2022 15:50:27 +0200 Subject: [PATCH] - removed the Polymost renderer. --- source/CMakeLists.txt | 9 - source/build/include/build.h | 10 - source/build/include/polymost.h | 75 - source/build/src/engine.cpp | 26 - source/build/src/engine_priv.h | 15 - source/build/src/mdsprite.cpp | 366 -- source/build/src/polymost.cpp | 3979 ----------------- source/core/gamecontrol.cpp | 3 +- source/core/mainloop.cpp | 3 - source/core/palette.cpp | 13 +- source/core/palette.h | 6 +- source/core/rendering/hw_entrypoint.cpp | 15 +- .../core/rendering/scene/hw_drawlistadd.cpp | 1 - source/core/rendering/scene/hw_walls.cpp | 1 - source/core/screenshot.cpp | 2 - source/core/zcc_compile_raze.cpp | 4 +- source/games/blood/all.cpp | 2 - source/games/blood/src/_polymost.cpp | 358 -- source/games/blood/src/animatesprite.cpp | 1 - source/games/blood/src/blood.h | 6 - source/games/blood/src/db.cpp | 3 - source/games/blood/src/mirrors.cpp | 8 - source/games/blood/src/view.cpp | 23 +- source/games/duke/src/_polymost.cpp | 274 -- source/games/duke/src/duke3d.h | 1 - source/games/duke/src/game.cpp | 2 +- source/games/duke/src/render.cpp | 59 +- source/games/duke/src/sectors.cpp | 14 +- source/games/exhumed/src/view.cpp | 25 +- source/games/sw/all.cpp | 2 - source/games/sw/src/_polymost.cpp | 379 -- source/games/sw/src/draw.cpp | 22 +- source/games/sw/src/jsector.cpp | 13 +- source/games/sw/src/rooms.cpp | 11 - source/glbackend/gl_texture.cpp | 88 - source/glbackend/glbackend.cpp | 435 -- source/glbackend/glbackend.h | 313 -- source/glbackend/pm_renderstate.h | 99 - 38 files changed, 45 insertions(+), 6621 deletions(-) delete mode 100644 source/build/include/polymost.h delete mode 100644 source/build/src/polymost.cpp delete mode 100644 source/games/blood/src/_polymost.cpp delete mode 100644 source/games/duke/src/_polymost.cpp delete mode 100644 source/games/sw/src/_polymost.cpp delete mode 100644 source/glbackend/gl_texture.cpp delete mode 100644 source/glbackend/glbackend.cpp delete mode 100644 source/glbackend/glbackend.h delete mode 100644 source/glbackend/pm_renderstate.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 5203b9249..b7f8ab856 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -601,7 +601,6 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) # there's generally a new cpp for every header so this file will get changed file( GLOB HEADER_FILES build/include/*.h - glbackend/*.h core/*.h core/2d/*.h core/utility/*.h @@ -681,9 +680,6 @@ set( NOT_COMPILED_SOURCE_FILES zcc-parse.h common/platform/win32/zutil.natvis common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.natvis - games/blood/src/_polymost.cpp - games/duke/src/_polymost.cpp - games/sw/src/_polymost.cpp # Blood games/blood/src/actor.cpp @@ -998,16 +994,12 @@ set (PCH_SOURCES common/thirdparty/richpresence.cpp - glbackend/glbackend.cpp - glbackend/gl_texture.cpp - thirdparty/src/md4.cpp # Todo: Split out the license-safe code from this. build/src/clip.cpp build/src/engine.cpp build/src/mdsprite.cpp - build/src/polymost.cpp core/actorinfo.cpp core/zcc_compile_raze.cpp @@ -1550,7 +1542,6 @@ source_group("Core\\DObject" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/co source_group("Core\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/menu/.+") source_group("Core\\Rendering" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/rendering/.+") source_group("Core\\Rendering\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/rendering/scene/.+") -source_group("Rendering" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/glbackend/.+") source_group("Platform" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/.+") source_group("Platform\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/win32/.+") source_group("Platform\\POSIX" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/.+") diff --git a/source/build/include/build.h b/source/build/include/build.h index 92c17e5cd..b479ebdf5 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -142,9 +142,7 @@ EXTERN int32_t enginecompatibility_mode; void engineInit(void); -void videoSetCorrectedAspect(); void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2); -void renderSetAspect(int32_t daxrange, int32_t daaspect); FCanvasTexture *renderSetTarget(int16_t tilenume); void renderRestoreTarget(); @@ -264,8 +262,6 @@ EXTERN_CVAR(Bool, r_voxels) extern int32_t mdtims, omdtims; -extern int32_t r_rortexture; -extern int32_t r_rortexturerange; extern int32_t r_rorphase; // flags bitset: 1 = don't compress @@ -318,12 +314,6 @@ int32_t md_definehud (int32_t modelid, int32_t tilex, FVector3 add, int32_t md_undefinetile(int32_t tile); int32_t md_undefinemodel(int32_t modelid); -#ifdef USE_OPENGL -# include "polymost.h" -#endif - -extern int skiptile; - static vec2_t const zerovec = { 0, 0 }; #define SET_AND_RETURN(Lval, Rval) \ diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h deleted file mode 100644 index c1fd02afc..000000000 --- a/source/build/include/polymost.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef polymost_h_ -# define polymost_h_ - - -#include "mdsprite.h" - -extern tspritetype pm_tsprite[MAXSPRITESONSCREEN]; -extern int pm_spritesortcnt; -extern int pm_smoothratio; - - -namespace Polymost -{ -extern float gtang; -extern double gxyaspect; -extern float grhalfxdown10x; -extern float gcosang, gsinang, gcosang2, gsinang2; - -//void phex(char v, char *s); -void polymost_drawsprite(int32_t snum); -void polymost_drawmaskwall(int32_t damaskwallcnt); -void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, int32_t uniqid); -void polymost_initosdfuncs(void); - -void polymost_glreset(void); -void polymost_scansector(int32_t sectnum); - -extern float curpolygonoffset; - -} - -void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall, - int32_t* tposx, int32_t* tposy, fixed_t* tang); -void renderCompleteMirror(void); - -int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int dacursectnum, bool fromoutside); -int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, sectortype* dacursect, bool fromoutside); - -void renderDrawMasks(void); - -// PLAG: line utility functions -typedef struct s_equation -{ - float a, b, c; -} _equation; - -void renderSetRollAngle(float rolla); - - -// these are defined in engine.cpp. -extern int16_t globalpicnum; -extern float fcosglobalang, fsinglobalang; -extern float fydimen, fviewingrange; -extern int32_t viewingrangerecip; - -// Flags of the argument of various functions -enum { - DAMETH_NOMASK = 0, - DAMETH_MASK = 1, - DAMETH_TRANS1 = 2, - DAMETH_TRANS2 = 3, - - DAMETH_MASKPROPS = 3, - - DAMETH_CLAMPED = 4, - DAMETH_MODEL = 8, - DAMETH_SKY = 16, - - DAMETH_WALL = 32, // signals a texture for a wall (for r_npotwallmode) - - // used internally by polymost_domost - DAMETH_BACKFACECULL = -1, -}; - -#endif diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index bf7a90f33..b3bdb6b58 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -35,9 +35,7 @@ #ifdef USE_OPENGL # include "mdsprite.h" -# include "polymost.h" #include "v_video.h" -#include "../../glbackend/glbackend.h" #include "gl_renderer.h" #endif @@ -78,22 +76,6 @@ static void getclosestpointonwall_internal(vec2_t const p, int32_t const dawall, *closest = { (int32_t)(w.X + ((d.X * i) >> 30)), (int32_t)(w.Y + ((d.Y * i) >> 30)) }; } -int32_t xdimen = -1, xdimenscale, xdimscale; -float fxdimen = -1.f; -int32_t ydimen; - -int32_t globalposx, globalposy, globalposz; -fixed_t qglobalhoriz; -float fglobalposx, fglobalposy, fglobalposz; -int16_t globalang, globalcursectnum; -fixed_t qglobalang; -int32_t globalpal, globalfloorpal, cosglobalang, singlobalang; -int32_t cosviewingrangeglobalang, sinviewingrangeglobalang; - -int32_t viewingrangerecip; - -int32_t globalshade, globalorientation; -int16_t globalpicnum; static int32_t globaly1, globalx2; @@ -667,13 +649,6 @@ void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2) windowxy1.Y = y1; windowxy2.X = x2; windowxy2.Y = y2; - - xdimen = (x2-x1)+1; - ydimen = (y2-y1)+1; - - fxdimen = (float) xdimen; - fydimen = (float) ydimen; - videoSetCorrectedAspect(); } @@ -711,7 +686,6 @@ FCanvasTexture* renderSetTarget(int16_t tilenume) xdim = ysiz; ydim = xsiz; videoSetViewableArea(0,0,ysiz-1,xsiz-1); - renderSetAspect(65536,65536); return canvas; } diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index c182ee270..2c6953a28 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -13,21 +13,6 @@ #ifndef ENGINE_PRIV_H #define ENGINE_PRIV_H -extern int32_t globalpal, globalfloorpal; -extern int32_t xdimen, xdimenscale, xdimscale, ydimen; -extern float fxdimen; -extern int32_t globalposx, globalposy, globalposz; -extern fixed_t qglobalhoriz, qglobalang; -extern float fglobalposx, fglobalposy, fglobalposz; -extern int16_t globalang, globalcursectnum; -extern int32_t globalpal, cosglobalang, singlobalang; -extern int32_t cosviewingrangeglobalang, sinviewingrangeglobalang; -extern int32_t xyaspect; -extern int32_t globalshade; -extern int16_t globalpicnum; - -extern int32_t globalorientation; - extern int32_t hitallsprites; int32_t animateoffs(int tilenum, int fakevar); diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index 669909178..e44515a9a 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -4,7 +4,6 @@ #include "build.h" #include "engine_priv.h" -#include "polymost.h" #include "mdsprite.h" #include "coreactor.h" @@ -17,7 +16,6 @@ #include "hw_renderstate.h" #include "printf.h" #include "hw_voxels.h" -#include "../../glbackend/glbackend.h" #ifdef _MSC_VER // just make it shut up. Most of this file will go down the drain anyway soon. @@ -29,9 +27,6 @@ static int32_t curextra=MAXTILES; #define MIN_CACHETIME_PRINT 10 -using namespace Polymost; -int32_t polymost_voxdraw(voxmodel_t* m, tspritetype* const tspr, bool rotate); - static int32_t addtileP(int32_t ,int32_t tile,int32_t pallet) { // tile >= 0 && tile < MAXTILES @@ -1073,351 +1068,6 @@ static void md3postload_common(md3model_t *m) } -void md3_vox_calcmat_common(tspritetype* tspr, const FVector3 *a0, float f, float mat[16]) -{ - float k0, k1, k2, k3, k4, k5, k6, k7; - - auto ownerActor = tspr->ownerActor; - k0 = ((float)(tspr->pos.X+ownerActor->sprext.position_offset.X-globalposx))*f*(1.f/1024.f); - k1 = ((float)(tspr->pos.Y+ownerActor->sprext.position_offset.Y-globalposy))*f*(1.f/1024.f); - k4 = -bsinf(tspr->ang+ownerActor->sprext.angoff, -14); - k5 = bcosf(tspr->ang+ownerActor->sprext.angoff, -14); - k2 = k0*(1-k4)+k1*k5; - k3 = k1*(1-k4)-k0*k5; - k6 = - gsinang; - k7 = gcosang; - mat[0] = k4*k6 + k5*k7; mat[4] = 0; mat[ 8] = k4*k7 - k5*k6; mat[12] = k2*k6 + k3*k7; - - mat[1] = 0; mat[5] = 1; mat[ 9] = 0; mat[13] = 0; - - k6 = gcosang2; - k7 = gsinang2; - mat[2] = k4*k6 + k5*k7; - mat[6] =0; - mat[10] = k4*k7 - k5*k6; - mat[14] = k2*k6 + k3*k7; - - mat[12] = (mat[12] + a0->Y*mat[0]) + (a0->Z*mat[4] + a0->X*mat[ 8]); - mat[13] = (mat[13] + a0->Y*mat[1]) + (a0->Z*mat[5] + a0->X*mat[ 9]); - mat[14] = (mat[14] + a0->Y*mat[2]) + (a0->Z*mat[6] + a0->X*mat[10]); -} - -static void md3draw_handle_triangles(const md3surf_t *s, uint16_t *indexhandle, - int32_t , const md3model_t *M) -{ - int32_t i; - - - auto data = screen->mVertexData->AllocVertices(s->numtris * 3); - auto vt = data.first; - for (i=s->numtris-1; i>=0; i--) - { - uint16_t tri = M ? M->indexes[i] : i; - int32_t j; - - for (j=0; j<3; j++, vt++) - { - int32_t k = s->tris[tri].i[j]; - - vt->SetTexCoord(s->uv[k].u, s->uv[k].v); - - vt->SetVertex(vertlist[k].X, vertlist[k].Y, vertlist[k].Z); - } - } - GLInterface.Draw(DT_Triangles, data.second, s->numtris *3); -} - -static int32_t polymost_md3draw(md3model_t *m, tspritetype* tspr) -{ - FVector3 m0, m1, a0; - md3xyzn_t *v0, *v1; - int32_t i, surfi; - float f, g, k0, k1, k2=0, k3=0, mat[16]; // inits: compiler-happy - float pc[4]; - // int32_t texunits = GL_TEXTURE0; - - auto ownerActor = tspr->ownerActor; - const uint8_t lpal = ownerActor->spr.pal; - const int32_t sizyrep = tileHeight(tspr->picnum) * tspr->yrepeat; - - updateanimation((md2model_t *)m, tspr, lpal); - - //create current&next frame's vertex list from whole list - - f = m->interpol; g = 1.f - f; - - if (m->interpol < 0.f || m->interpol > 1.f || - (unsigned)m->cframe >= (unsigned)m->numframes || - (unsigned)m->nframe >= (unsigned)m->numframes) - { -#ifdef DEBUGGINGAIDS - Printf("%s: mdframe oob: c:%d n:%d total:%d interpol:%.02f\n", - m->head.nam, m->cframe, m->nframe, m->numframes, m->interpol); -#endif - - m->interpol = clamp(m->interpol, 0.f, 1.f); - m->cframe = clamp(m->cframe, 0, m->numframes-1); - m->nframe = clamp(m->nframe, 0, m->numframes-1); - } - - m0.Z = m0.Y = m0.X = g *= m->scale * (1.f/64.f); - m1.Z = m1.Y = m1.X = f *= m->scale * (1.f/64.f); - - a0.X = a0.Y = 0; - a0.Z = m->zadd * m->scale; - - // Parkar: Moved up to be able to use k0 for the y-flipping code - k0 = (float)tspr->pos.Z+ownerActor->sprext.position_offset.Z; - f = ((globalorientation & 8) && (ownerActor->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_FACING) ? -4.f : 4.f; - k0 -= (tspr->yoffset*tspr->yrepeat)*f; - if ((globalorientation&128) && !((globalorientation & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR)) - k0 += (float)(sizyrep<<1); - - // Parkar: Changed to use the same method as centeroriented sprites - if (globalorientation&8) //y-flipping - { - m0.Z = -m0.Z; m1.Z = -m1.Z; a0.Z = -a0.Z; - k0 -= (float)(sizyrep<<2); - } - if (globalorientation&4) { m0.Y = -m0.Y; m1.Y = -m1.Y; a0.Y = -a0.Y; } //x-flipping - - // yoffset differs from zadd in that it does not follow cstat & CSTAT_SPRITE_YFLIP y-flipping - a0.Z += m->yoffset*m->scale; - - f = ((float)tspr->xrepeat) * (1.f/64.f) * m->bscale; - m0.X *= f; m0.Y *= -f; - m1.X *= f; m1.Y *= -f; - a0.X *= f; a0.Y *= -f; - f = ((float)tspr->yrepeat) * (1.f/64.f) * m->bscale; - m0.Z *= f; m1.Z *= f; a0.Z *= f; - - // floor aligned - k1 = (float)tspr->pos.Y+ ownerActor->sprext.position_offset.Y; - if ((globalorientation & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR) - { - m0.Z = -m0.Z; m1.Z = -m1.Z; a0.Z = -a0.Z; - m0.Y = -m0.Y; m1.Y = -m1.Y; a0.Y = -a0.Y; - f = a0.X; a0.X = a0.Z; a0.Z = f; - k1 += (float)(sizyrep>>3); - } - - // Note: These SCREEN_FACTORS will be neutralized in axes offset - // calculations below again, but are needed for the base offsets. - f = (65536.f*512.f)/(fxdimen*fviewingrange); - g = 32.f/(fxdimen*gxyaspect); - m0.Y *= f; m1.Y *= f; a0.Y = (((float)(tspr->pos.X+ ownerActor->sprext.position_offset.X-globalposx))* (1.f/1024.f) + a0.Y)*f; - m0.X *=-f; m1.X *=-f; a0.X = ((k1 -fglobalposy) * -(1.f/1024.f) + a0.X)*-f; - m0.Z *= g; m1.Z *= g; a0.Z = ((k0 -fglobalposz) * -(1.f/16384.f) + a0.Z)*g; - - md3_vox_calcmat_common(tspr, &a0, f, mat); - - // floor aligned - if ((globalorientation & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR) - { - f = mat[4]; mat[4] = mat[8]*16.f; mat[8] = -f*(1.f/16.f); - f = mat[5]; mat[5] = mat[9]*16.f; mat[9] = -f*(1.f/16.f); - f = mat[6]; mat[6] = mat[10]*16.f; mat[10] = -f*(1.f/16.f); - } - - //Mirrors - if (grhalfxdown10x < 0) { mat[0] = -mat[0]; mat[4] = -mat[4]; mat[8] = -mat[8]; mat[12] = -mat[12]; } - - //------------ - // TSPR_FLAGS_MDHACK is an ugly hack in game.c:G_DoSpriteAnimations() telling md2sprite - // to use Z-buffer hacks to hide overdraw problems with the flat-tsprite-on-floor shadows, - // also disabling detail, glow, normal, and specular maps. - - if (tspr->clipdist & TSPR_FLAGS_MDHACK) - { - // What once was here had been neutered in EDuke32 already. - GLInterface.SetDepthFunc(DF_LEqual); - } - - int winding = ((grhalfxdown10x >= 0) ^((globalorientation&8) != 0) ^((globalorientation&4) != 0))? Winding_CW : Winding_CCW; - GLInterface.SetCull(Cull_Back, winding); - - // tinting - pc[0] = pc[1] = pc[2] = ((float)numshades - min(max((globalshade * hw_shadescale) + m->shadeoff, 0.f), (float)numshades)) / (float)numshades; - - pc[3] = (tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) ? glblend[tspr->blend].def[!!(tspr->cstat & CSTAT_SPRITE_TRANS_FLIP)].alpha : 1.0f; - pc[3] *= 1.0f - ownerActor->sprext.alpha; - - SetRenderStyleFromBlend(!!(tspr->cstat & CSTAT_SPRITE_TRANSLUCENT), tspr->blend, !!(tspr->cstat & CSTAT_SPRITE_TRANS_FLIP)); - - if (m->usesalpha) //Sprites with alpha in texture - { - // PLAG : default cutoff removed - GLInterface.EnableBlend(true); - GLInterface.EnableAlphaTest(true); - GLInterface.SetAlphaThreshold(TileFiles.tiledata[globalpicnum].texture->alphaThreshold); - } - else - { - if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || ownerActor->sprext.alpha > 0.f || pc[3] < 1.0f) - GLInterface.EnableBlend(true); //else GLInterface.EnableBlend(false); - } - GLInterface.SetColor(pc[0],pc[1],pc[2],pc[3]); - //if (MFLAGS_NOCONV(m)) - // GLInterface.SetColor(0.0f, 0.0f, 1.0f, 1.0f); - //------------ - - // PLAG: Cleaner model rotation code - if (ownerActor->sprext.pitch || ownerActor->sprext.roll) - { - float factor = 1.f/((fxdimen * fviewingrange) * (256.f/(65536.f*128.f)) * (m0.X+m1.X)); - memset(&a0, 0, sizeof(a0)); - - if (ownerActor->sprext.pivot_offset.X) - a0.X = (float) ownerActor->sprext.pivot_offset.X * factor; - - if (ownerActor->sprext.pivot_offset.Y) // Compare with SCREEN_FACTORS above - a0.Y = (float) ownerActor->sprext.pivot_offset.Y * factor; - - if ((ownerActor->sprext.pivot_offset.Z) && !(tspr->clipdist & TSPR_FLAGS_MDHACK)) // Compare with SCREEN_FACTORS above - a0.Z = (float)ownerActor->sprext.pivot_offset.Z / (gxyaspect * fxdimen * (65536.f/128.f) * (m0.Z+m1.Z)); - - k0 = bcosf(ownerActor->sprext.pitch, -14); - k1 = bsinf(ownerActor->sprext.pitch, -14); - k2 = bcosf(ownerActor->sprext.roll, -14); - k3 = bsinf(ownerActor->sprext.roll, -14); - } - - VSMatrix imat = 0; - imat.scale(1024, 1024, 1024); - GLInterface.SetMatrix(Matrix_Model, &imat); - - for (surfi=0; surfihead.numsurfs; surfi++) - { - //PLAG : sorting stuff - uint16_t *indexhandle; - FVector3 fp; - - const md3surf_t *const s = &m->head.surfs[surfi]; - - v0 = &s->xyzn[m->cframe*s->numverts]; - v1 = &s->xyzn[m->nframe*s->numverts]; - - if (ownerActor->sprext.pitch || ownerActor->sprext.roll) - { - FVector3 fp1, fp2; - - for (i=s->numverts-1; i>=0; i--) - { - fp.Z = v0[i].x + a0.X; - fp.X = v0[i].y + a0.Y; - fp.Y = v0[i].z + a0.Z; - - fp1.X = fp.X*k2 + fp.Y*k3; - fp1.Y = fp.X*k0*(-k3) + fp.Y*k0*k2 + fp.Z*(-k1); - fp1.Z = fp.X*k1*(-k3) + fp.Y*k1*k2 + fp.Z*k0; - - fp.Z = v1[i].x + a0.X; - fp.X = v1[i].y + a0.Y; - fp.Y = v1[i].z + a0.Z; - - fp2.X = fp.X*k2 + fp.Y*k3; - fp2.Y = fp.X*k0*(-k3) + fp.Y*k0*k2 + fp.Z*(-k1); - fp2.Z = fp.X*k1*(-k3) + fp.Y*k1*k2 + fp.Z*k0; - fp.Z = (fp1.Z - a0.X)*m0.X + (fp2.Z - a0.X)*m1.X; - fp.X = (fp1.X - a0.Y)*m0.Y + (fp2.X - a0.Y)*m1.Y; - fp.Y = (fp1.Y - a0.Z)*m0.Z + (fp2.Y - a0.Z)*m1.Z; - - vertlist[i] = fp; - } - } - else - { - for (i=s->numverts-1; i>=0; i--) - { - fp.Z = v0[i].x*m0.X + v1[i].x*m1.X; - fp.Y = v0[i].z*m0.Z + v1[i].z*m1.Z; - fp.X = v0[i].y*m0.Y + v1[i].y*m1.Y; - - vertlist[i] = fp; - } - } - - //Let OpenGL (and perhaps hardware :) handle the matrix rotation - mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; - for (int mm = 0; mm < 15; mm++) mat[mm] *= 1024.f; - GLInterface.SetMatrix(Matrix_Model, mat); - // PLAG: End - - bool exact = false; - auto tex = mdloadskin((md2model_t *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,globalpal,surfi, &exact); - if (!tex) - continue; - - int palid = TRANSLATION(Translation_Remap + curbasepal, globalpal); - GLInterface.SetFade(tspr->sectp->floorpal); - GLInterface.SetTexture(tex, palid, CLAMP_XY); - - if (tspr->clipdist & TSPR_FLAGS_MDHACK) - { - //POGOTODO: if we add support for palette indexing on model skins, the texture for the palswap could be setup here - - indexhandle = m->vindexes; - - //PLAG: delayed polygon-level sorted rendering - - if (m->usesalpha) - { - for (i=0; i<=s->numtris-1; ++i) - { - FVector3 const vlt[3] = { vertlist[s->tris[i].i[0]], vertlist[s->tris[i].i[1]], vertlist[s->tris[i].i[2]] }; - - // Matrix multiplication - ugly but clear - FVector3 const fpmat[3] = { { (vlt[0].X * mat[0]) + (vlt[0].Y * mat[4]) + (vlt[0].Z * mat[8]) + mat[12], - (vlt[0].X * mat[1]) + (vlt[0].Y * mat[5]) + (vlt[0].Z * mat[9]) + mat[13], - (vlt[0].X * mat[2]) + (vlt[0].Y * mat[6]) + (vlt[0].Z * mat[10]) + mat[14] }, - - { (vlt[1].X * mat[0]) + (vlt[1].Y * mat[4]) + (vlt[1].Z * mat[8]) + mat[12], - (vlt[1].X * mat[1]) + (vlt[1].Y * mat[5]) + (vlt[1].Z * mat[9]) + mat[13], - (vlt[1].X * mat[2]) + (vlt[1].Y * mat[6]) + (vlt[1].Z * mat[10]) + mat[14] }, - - { (vlt[2].X * mat[0]) + (vlt[2].Y * mat[4]) + (vlt[2].Z * mat[8]) + mat[12], - (vlt[2].X * mat[1]) + (vlt[2].Y * mat[5]) + (vlt[2].Z * mat[9]) + mat[13], - (vlt[2].X * mat[2]) + (vlt[2].Y * mat[6]) + (vlt[2].Z * mat[10]) + mat[14] } }; - - f = (fpmat[0].X * fpmat[0].X) + (fpmat[0].Y * fpmat[0].Y) + (fpmat[0].Z * fpmat[0].Z); - g = (fpmat[1].X * fpmat[1].X) + (fpmat[1].Y * fpmat[1].Y) + (fpmat[1].Z * fpmat[1].Z); - - if (f > g) - f = g; - - g = (fpmat[2].X * fpmat[2].X) + (fpmat[2].Y * fpmat[2].Y) + (fpmat[2].Z * fpmat[2].Z); - - if (f > g) - f = g; - - m->maxdepths[i] = f; - m->indexes[i] = i; - } - - // dichotomic recursive sorting - about 100x less iterations than bubblesort - quicksort(m->indexes, m->maxdepths, 0, s->numtris - 1); - } - - md3draw_handle_triangles(s, indexhandle, 1, m->usesalpha ? m : NULL); - } - else - { - indexhandle = m->vindexes; - - md3draw_handle_triangles(s, indexhandle, 1, NULL); - } - } - //------------ - - if (m->usesalpha) GLInterface.EnableAlphaTest(false); - - GLInterface.SetCull(Cull_None); - - GLInterface.SetIdentityMatrix(Matrix_Model); - - globalnoeffect=0; - return 1; -} static void md3free(md3model_t *m) { @@ -1508,22 +1158,6 @@ static mdmodel_t *mdload(const char *filnam) } -int32_t polymost_mddraw(tspritetype* tspr) -{ - if (maxmodelverts > allocmodelverts) - { - vertlist = (FVector3 *) M_Realloc(vertlist, sizeof(FVector3)*maxmodelverts); - allocmodelverts = maxmodelverts; - } - - mdmodel_t *const vm = models[tile2model[Ptile2tile(tspr->picnum, tspr->ownerActor->spr.pal)].modelid]; - if (vm->mdnum == 1) - return polymost_voxdraw((voxmodel_t *)vm,tspr, false); // can't access rotating info anymore - else if (vm->mdnum == 3) - return polymost_md3draw((md3model_t *)vm,tspr); - return 0; -} - void voxfree(voxmodel_t* m) { if (m) delete m; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp deleted file mode 100644 index 9342e1b1b..000000000 --- a/source/build/src/polymost.cpp +++ /dev/null @@ -1,3979 +0,0 @@ -/************************************************************************************************** -"POLYMOST" code originally written by Ken Silverman -Ken Silverman's official web site: http://www.advsys.net/ken - -**************************************************************************************************/ - - -#include "build.h" -#include "automap.h" -#include "engine_priv.h" -#include "mdsprite.h" -#include "polymost.h" -#include "files.h" -#include "buildtiles.h" -#include "bitmap.h" -#include "../../glbackend/glbackend.h" -#include "c_cvars.h" -#include "gamecvars.h" -#include "v_video.h" -#include "flatvertices.h" -#include "palettecontainer.h" -#include "texturemanager.h" -#include "hw_renderstate.h" -#include "printf.h" -#include "gamefuncs.h" -#include "hw_drawinfo.h" -#include "gamestruct.h" -#include "gamestruct.h" -#include "hw_voxels.h" -#include "coreactor.h" -#include "psky.h" - -#ifdef _MSC_VER -// just make it shut up. Most of this file will go down the drain anyway soon. -#pragma warning(disable:4244) -#endif - -typedef struct { - union { double x; double d; }; - union { double y; double u; }; - union { double z; double v; }; -} vec3d_t; - -static_assert(sizeof(vec3d_t) == sizeof(double) * 3); -int32_t xyaspect = -1; -bool inpreparemirror = 0; -int32_t r_rortexture = 0; -int32_t r_rortexturerange = 0; -int32_t r_rorphase = 0; - -inline int32_t bad_tspr(tspritetype* tspr) -{ - return (tspr->ownerActor == nullptr || (unsigned)tspr->picnum >= MAXTILES); -} - -inline void set_globalpos(int32_t const x, int32_t const y, int32_t const z) -{ - globalposx = x, fglobalposx = (float)x; - globalposy = y, fglobalposy = (float)y; - globalposz = z, fglobalposz = (float)z; -} - - -inline int widthBits(int num) -{ - return sizeToBits(tileWidth(num)); -} - -inline int heightBits(int num) -{ - return sizeToBits(tileHeight(num)); -} - - - -void calcSlope(const sectortype* sec, float xpos, float ypos, float* pceilz, float* pflorz); - -int skiptile = -1; -FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap = 0); -int32_t polymost_voxdraw(voxmodel_t* m, tspritetype* const tspr, bool rotate); - -int checkTranslucentReplacement(FTextureID picnum, int pal); - -CVARD(Bool, hw_animsmoothing, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable model animation smoothing") -CVARD(Bool, hw_models, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable model rendering") -CVARD(Bool, hw_parallaxskypanning, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable parallaxed floor/ceiling panning when drawing a parallaxing sky") -CVARD(Float, hw_shadescale, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "multiplier for shading") -int pm_smoothratio; - - -//{ "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) -CVAR(Bool, vid_renderer, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -static vec3_t spritesxyz[MAXSPRITESONSCREEN + 1]; -static int16_t thewall[MAXWALLSB]; -static int16_t bunchp2[MAXWALLSB], thesector[MAXWALLSB]; -static int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB]; -static int16_t numscans, numbunches; -static int16_t maskwall[MAXWALLSB], maskwallcnt; -static int16_t sectorborder[256]; -static tspritetype* tspriteptr[MAXSPRITESONSCREEN + 1]; -tspritetype pm_tsprite[MAXSPRITESONSCREEN]; -int pm_spritesortcnt; - - - -namespace Polymost -{ - - -typedef struct { float x, cy[2], fy[2]; int32_t tag; int16_t n, p, ctag, ftag; } vsptyp; -#define VSPMAX 2048 //<- careful! -static vsptyp vsp[VSPMAX]; -static int32_t gtag, viewportNodeCount; -static float xbl, xbr, xbt, xbb; -static int32_t domost_rejectcount; - -static float dxb1[MAXWALLSB], dxb2[MAXWALLSB]; - -//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 - -#define SOFTROTMAT 0 - -static int32_t r_pogoDebug = 0; - -static float gviewxrange; -static float ghoriz, ghoriz2; -static float ghorizcorrect; -double gxyaspect; -float gyxscale, ghalfx, grhalfxdown10, grhalfxdown10x, ghalfy; -float gcosang, gsinang, gcosang2, gsinang2; -float gtang = 0.f; - -static float gchang = 0, gshang = 0, gctang = 0, gstang = 0; -static float gvrcorrection = 1.f; - -static vec3d_t xtex, ytex, otex, xtex2, ytex2, otex2; - -static float fsearchx, fsearchy, fsearchz; -static int psectnum, pwallnum, pbottomwall, pisbottomwall, psearchstat; - -static int32_t drawpoly_srepeat = 0, drawpoly_trepeat = 0; -#define MAX_DRAWPOLY_VERTS 8 - -static int32_t lastglpolygonmode = 0; //FUK - -static int32_t r_yshearing = 0; - -// used for fogcalc -static float fogresult, fogresult2; - -static char ptempbuf[MAXWALLSB<<1]; - -// polymost ART sky control -static int32_t r_parallaxskyclamping = 1; - -#define MIN_CACHETIME_PRINT 10 - - - -#define Bfabsf fabsf - -static int32_t drawingskybox = 0; - -FGameTexture* globalskytex = nullptr; - -void polymost_outputGLDebugMessage(uint8_t severity, const char* format, ...) -{ -} - -static void set_globalang(fixed_t const ang) -{ - globalang = FixedToInt(ang) & 2047; - qglobalang = ang & 0x7FFFFFF; - - float const f_ang = FixedToFloat(ang); - float const fcosang = bcosf(f_ang); - float const fsinang = bsinf(f_ang); - -#ifdef USE_OPENGL - fcosglobalang = fcosang; - fsinglobalang = fsinang; -#endif - - cosglobalang = (int)fcosang; - singlobalang = (int)fsinang; - - cosviewingrangeglobalang = MulScale(cosglobalang, viewingrange, 16); - sinviewingrangeglobalang = MulScale(singlobalang, viewingrange, 16); -} - -static inline float polymost_invsqrt_approximation(float x) -{ - // this is the comment - return 1.f / sqrtf(x); -} - -static float sectorVisibility(const sectortype* sect) -{ - // Beware of wraparound madness... - int v = sect->visibility; - return v? ((uint8_t)(v + 16)) / 16.f : 1.f; -} - -static void tileUpdatePicnum(short* const tileptr, int const obj) -{ - auto& tile = *tileptr; - - if (picanm[tile].sf & PICANM_ANIMTYPE_MASK) - tile += animateoffs(tile, obj); - - if (((obj & 16384) == 16384) && (globalorientation & CSTAT_WALL_ROTATE_90) && RotTile(tile).newtile != -1) - tile = RotTile(tile).newtile; -} - -//-------------------------------------------------------------------------------------------------- - -//Use this for both initialization and uninitialization of OpenGL. - -//in-place multiply m0=m0*m1 -static float* multiplyMatrix4f(float m0[4*4], const float m1[4*4]) -{ - float mR[4*4]; - -#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] - - multMatrix4RowCol(0, 0); - multMatrix4RowCol(0, 1); - multMatrix4RowCol(0, 2); - multMatrix4RowCol(0, 3); - - multMatrix4RowCol(1, 0); - multMatrix4RowCol(1, 1); - multMatrix4RowCol(1, 2); - multMatrix4RowCol(1, 3); - - multMatrix4RowCol(2, 0); - multMatrix4RowCol(2, 1); - multMatrix4RowCol(2, 2); - multMatrix4RowCol(2, 3); - - multMatrix4RowCol(3, 0); - multMatrix4RowCol(3, 1); - multMatrix4RowCol(3, 2); - multMatrix4RowCol(3, 3); - - memcpy(m0, mR, sizeof(float)*4*4); - - return m0; - -#undef multMatrix4RowCol -} - - -void polymost_glreset() -{ - //Reset if this is -1 (meaning 1st texture call ever), or > 0 (textures in memory) - gcosang = gcosang2 = 16384.f/262144.f; - gsinang = gsinang2 = 0.f; -} - -FileReader GetBaseResource(const char* fn); - -static void resizeglcheck(void) -{ - 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]{}; - - float const nearclip = 4.0f / (gxyaspect * gyxscale); - float const farclip = 65536.f; - - 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); - renderSetProjectionMatrix(&m[0][0]); -} - -//(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 - -// drawpoly's hack globals -static int32_t pow2xsplit = 0, skyzbufferhack = 0, flatskyrender = 0; -static float drawpoly_alpha = 0.f; -static uint8_t drawpoly_blend = 0; - -int32_t polymost_maskWallHasTranslucency(walltype const * const wall) -{ - if (wall->cstat & CSTAT_WALL_TRANSLUCENT) - return true; - - return checkTranslucentReplacement(tileGetTexture(wall->picnum)->GetID(), wall->pal); -} - -int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr) -{ - if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || (tspr->clipdist & TSPR_FLAGS_DRAW_LAST) || - (tspr->ownerActor && tspr->ownerActor->sprext.alpha)) - return true; - - return checkTranslucentReplacement(tileGetTexture(tspr->picnum)->GetID(), tspr->pal); -} - -static void polymost_updaterotmat(void) -{ - //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); - renderSetViewMatrix(matrix); - float fxdimen = FixedToFloat(xdimenscale); - renderSetVisibility((g_visibility + g_relvisibility) * fxdimen * (1.f / (65536.f)) / r_ambientlight); -} - -const vec2_16_t tileSize(int index) -{ - vec2_16_t v = { (int16_t)tileWidth(index), (int16_t)tileHeight(index) }; - return v; -} - -static void polymost_flatskyrender(FVector2 const* const dpxy, int32_t const n, int32_t method, const vec2_16_t& tilesize); - -// Hack for Duke's camera until I can find out why this behaves erratically. - -static void polymost_drawpoly(FVector2 const * const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesize) -{ - if (method == DAMETH_BACKFACECULL || globalpicnum == skiptile || - (uint32_t)globalpicnum >= MAXTILES) - return; - - const int32_t method_ = method; - - if (n == 3) - { - 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 - } - else if (n > 3) - { - float f = 0; //f is area of polygon / 2 - - for (intptr_t i=n-2, j=n-1,k=0; k= 3) && (px[j-1] == px[0]) && (py[j-1] == py[0])) j--; - - if (j < 3) - return; - - int const npoints = j; - - float usub = 0; - float vsub = 0; - - // This only takes effect for textures with their default set to SamplerClampXY. - int sampleroverride = CLAMP_NONE; - if (method & DAMETH_CLAMPED) - { - if (!drawpoly_srepeat) sampleroverride |= CLAMP_Y; - if (!drawpoly_trepeat) sampleroverride |= CLAMP_X; - } - - - int palid = TRANSLATION(Translation_Remap + curbasepal, globalpal); - GLInterface.SetFade(globalfloorpal); - bool success = GLInterface.SetTexture(globalskytex? globalskytex : tileGetTexture(globalpicnum), !hw_int_useindexedcolortextures && globalskytex ? 0 : palid, sampleroverride); - if (!success) - { - tsiz.X = tsiz.Y = 1; - GLInterface.SetColorMask(false); //Hack to update Z-buffer for invalid mirror textures - } - - GLInterface.SetShade(globalshade, numshades); - - if ((method & DAMETH_WALL) != 0) - { - int32_t size = tilesize.Y; - int32_t size2; - for (size2 = 1; size2 < size; size2 += size2) {} - if (size == size2) - GLInterface.SetNpotEmulation(0.f, 0.f); - else - { - float xOffset = 1.f / tilesize.X; - GLInterface.SetNpotEmulation((1.f*size2) / size, xOffset); - } - } - else - { - GLInterface.SetNpotEmulation(0.f, 0.f); - } - - vec2_t tsiz2 = tsiz; - - - if (method & DAMETH_MASKPROPS) - { - SetRenderStyleFromBlend((method & DAMETH_MASKPROPS) > DAMETH_MASK, drawpoly_blend, (method & DAMETH_MASKPROPS) == DAMETH_TRANS2); - } - - if (!(method & (DAMETH_CLAMPED | DAMETH_MASKPROPS))) - GLInterface.SetTextureMode(TM_OPAQUE); - - float pc[4]; - - // 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); - pc[3] = GetAlphaFromBlend(method & DAMETH_MASKPROPS, drawpoly_blend) * (1.f - drawpoly_alpha); - - if (skyzbufferhack_pass) - pc[3] = 0.01f; - - GLInterface.SetColor(pc[0], pc[1], pc[2], pc[3]); - - FVector2 const scale = { 1.f / tsiz2.X, 1.f / tsiz2.Y }; - auto data = screen->mVertexData->AllocVertices(npoints); - auto vt = data.first; - for (intptr_t i = 0; i < npoints; ++i, vt++) - { - float const r = 1.f / dd[i]; - - if (tileGetTexture(globalpicnum)->GetTexture()->isHardwareCanvas()) - { - //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); - } - - //update verts - vt->SetVertex( - (px[i] - ghalfx) * r * grhalfxdown10x * 1024.f, - (ghalfy - py[i]) * r * grhalfxdown10 * 1024.f, - r); - - } - GLInterface.Draw(DT_TriangleFan, data.second, npoints); - - GLInterface.SetNpotEmulation(0.f, 0.f); - GLInterface.SetTextureMode(TM_NORMAL); - - if (skyzbufferhack && skyzbufferhack_pass == 0) - { - vec3d_t const bxtex = xtex, bytex = ytex, botex = otex; - xtex = xtex2, ytex = ytex2, otex = otex2; - GLInterface.SetColorMask(false); - GLInterface.Draw(DT_TriangleFan, data.second, npoints); - GLInterface.SetColorMask(true); - xtex = bxtex, ytex = bytex, otex = botex; - } - - if (!success) - GLInterface.SetColorMask(true); -} - - -static inline void vsp_finalize_init(int32_t const vcnt) -{ - for (intptr_t i=0; i= 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); - dp2[n2] = { (dpxy[j].X - dpxy[i].X) * r + dpxy[i].X, - (dpxy[j].Y - dpxy[i].Y) * r + dpxy[i].Y }; - 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 (intptr_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); - dpxy[n] = { (dp2[j].X - dp2[i].X) * r + dp2[i].X, - (dp2[j].Y - dp2[i].Y) * r + dp2[i].Y }; - 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) -{ - int const dir = (x0 < x1); - - 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); - - y0top -= DOMOST_OFFSET; - y1top -= DOMOST_OFFSET; - y0bot += DOMOST_OFFSET; - y1bot += DOMOST_OFFSET; - - if (dir) //clip dmost (floor) - { - y0 -= DOMOST_OFFSET; - y1 -= DOMOST_OFFSET; - } - else //clip umost (ceiling) - { - if (x0 == x1) return; - std::swap(x0, x1); - std::swap(y0, y1); - std::swap(y0top, y1top); - std::swap(y0bot, y1bot); - y0 += DOMOST_OFFSET; - y1 += DOMOST_OFFSET; //necessary? - } - - // Test if span is outside screen bounds - if (x1 < xbl || x0 > xbr) - { - domost_rejectcount++; - return; - } - - FVector2 dm0 = { x0 - DOMOST_OFFSET, y0 }; - FVector2 dm1 = { x1 + DOMOST_OFFSET, y1 }; - - float const slop = (dm1.Y - dm0.Y) / (dm1.X - dm0.X); - - 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; - } - - drawpoly_alpha = 0.f; - drawpoly_blend = 0; - - FVector2 n0, n1; - float spx[4]; - int32_t spt[4]; - int firstnode = vsp[0].n; - - for (intptr_t newi, i=vsp[0].n; i; i=newi) - { - newi = vsp[i].n; n0.X = vsp[i].x; n1.X = vsp[newi].x; - - if (dm0.X >= n1.X) - { - firstnode = i; - continue; - } - - if (n0.X >= dm1.X) - break; - - if (vsp[i].ctag <= 0) continue; - - 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; - - //Test if left edge requires split (dm0.x,dm0.y) (nx0,cy(0)), - if ((dm0.X > n0.X) && (dm0.X < n1.X)) - { - float const t = (dm0.X-n0.X)*cv[dir] - (dm0.Y-cy[dir])*dx; - if (((!dir) && (t < 0.f)) || ((dir) && (t > 0.f))) - { spx[scnt] = dm0.X; spt[scnt] = -1; scnt++; } - } - - //Test for intersection on umost (0) and dmost (1) - - float const d[2] = { ((dm0.Y - dm1.Y) * dx) - ((dm0.X - dm1.X) * cv[0]), - ((dm0.Y - dm1.Y) * dx) - ((dm0.X - dm1.X) * cv[1]) }; - - float const nn[2] = { ((dm0.Y - cy[0]) * dx) - ((dm0.X - n0.X) * cv[0]), - ((dm0.Y - cy[1]) * dx) - ((dm0.X - n0.X) * cv[1]) }; - - float const fnx[2] = { dm0.X + ((nn[0] / d[0]) * (dm1.X - dm0.X)), - dm0.X + ((nn[1] / d[1]) * (dm1.X - dm0.X)) }; - - if ((fabsf(d[0]) > fabsf(nn[0])) && (d[0] * nn[0] >= 0.f) && (fnx[0] > n0.X) && (fnx[0] < n1.X)) - spx[scnt] = fnx[0], spt[scnt++] = 0; - - if ((fabsf(d[1]) > fabsf(nn[1])) && (d[1] * nn[1] >= 0.f) && (fnx[1] > n0.X) && (fnx[1] < n1.X)) - spx[scnt] = fnx[1], spt[scnt++] = 1; - - //Nice hack to avoid full sort later :) - if ((scnt >= 2) && (spx[scnt-1] < spx[scnt-2])) - { - std::swap(spx[scnt-1], spx[scnt-2]); - std::swap(spt[scnt-1], spt[scnt-2]); - } - - //Test if right edge requires split - if ((dm1.X > n0.X) && (dm1.X < n1.X)) - { - float const t = (dm1.X-n0.X)*cv[dir] - (dm1.Y-cy[dir])*dx; - if (((!dir) && (t < 0.f)) || ((dir) && (t > 0.f))) - { spx[scnt] = dm1.X; spt[scnt] = -1; scnt++; } - } - - vsp[i].tag = vsp[newi].tag = -1; - - float const rdx = 1.f/dx; - - for (intptr_t z=0, vcnt=0; z<=scnt; z++,i=vcnt) - { - float t; - - if (z == scnt) - goto skip; - - t = (spx[z]-n0.X)*rdx; - vcnt = vsinsaft(i); - 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]; - -skip: ; - int32_t const ni = vsp[i].n; if (!ni) continue; //this 'if' fixes many bugs! - 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; - - // 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 ? - - int k = 4; - - 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; - - if (!dir) - { - switch (k) - { - case 4: - case 5: - case 7: - { - FVector2 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); - polymost_drawpoly(dpxy, n, domostpolymethod, tileSize(globalpicnum)); - - vsp[i].cy[0] = n0.Y; - vsp[i].cy[1] = n1.Y; - vsp[i].ctag = gtag; - } - break; - case 1: - case 2: - { - FVector2 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); - polymost_drawpoly(dpxy, n, domostpolymethod, tileSize(globalpicnum)); - - vsp[i].cy[0] = n0.Y; - vsp[i].ctag = gtag; - } - break; - case 3: - case 6: - { - FVector2 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); - polymost_drawpoly(dpxy, n, domostpolymethod, tileSize(globalpicnum)); - - vsp[i].cy[1] = n1.Y; - vsp[i].ctag = gtag; - } - break; - case 8: - { - FVector2 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); - polymost_drawpoly(dpxy, n, domostpolymethod, tileSize(globalpicnum)); - - vsp[i].ctag = vsp[i].ftag = -1; - } - default: break; - } - } - else - { - switch (k) - { - case 4: - case 3: - case 1: - { - FVector2 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); - polymost_drawpoly(dpxy, n, domostpolymethod, tileSize(globalpicnum)); - - vsp[i].fy[0] = n0.Y; - vsp[i].fy[1] = n1.Y; - vsp[i].ftag = gtag; - } - break; - case 7: - case 6: - { - FVector2 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); - polymost_drawpoly(dpxy, n, domostpolymethod, tileSize(globalpicnum)); - - vsp[i].fy[0] = n0.Y; - vsp[i].ftag = gtag; - } - break; - case 5: - case 2: - { - FVector2 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); - polymost_drawpoly(dpxy, n, domostpolymethod, tileSize(globalpicnum)); - - vsp[i].fy[1] = n1.Y; - vsp[i].ftag = gtag; - } - break; - case 0: - { - FVector2 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); - polymost_drawpoly(dpxy, n, domostpolymethod, tileSize(globalpicnum)); - - vsp[i].ctag = vsp[i].ftag = -1; - } - default: - break; - } - } - } - } - - gtag++; - - //Combine neighboring vertical strips with matching collinear top&bottom edges - //This prevents x-splits from propagating through the entire scan -#ifdef COMBINE_STRIPS - int i = firstnode; - - do - { - if (vsp[i].x >= dm1.X) - break; - - if ((vsp[i].cy[0]+DOMOST_OFFSET*2 >= vsp[i].fy[0]) && (vsp[i].cy[1]+DOMOST_OFFSET*2 >= vsp[i].fy[1])) - vsp[i].ctag = vsp[i].ftag = -1; - - int const ni = vsp[i].n; - - //POGO: specially treat the viewport nodes so that we will never end up in a situation where we accidentally access the sentinel node - if (ni >= viewportNodeCount) - { - if ((vsp[i].ctag == vsp[ni].ctag) && (vsp[i].ftag == vsp[ni].ftag)) - { - vsmerge(i, ni); - 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; - vsmerge(i, ni); - continue; - } - } - i = ni; - } - while (i); -#endif -} - -// 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; -static int32_t global_cf_shade, global_cf_pal, global_cf_fogpal; -static float (*global_getzofslope_func)(const sectortype*, float, float); - -static void polymost_internal_nonparallaxed(FVector2 n0, FVector2 n1, float ryp0, float ryp1, float x0, float x1, - float y0, float y1, int32_t sectnum, bool have_floor) -{ - auto const sec = §or[sectnum]; - - // 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) - - float ft[4] = { fglobalposx, fglobalposy, fcosglobalang, fsinglobalang }; - - 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); - - if (globalorientation & 64) - { - //relative alignment - vec2_t const xy = sec->firstWall()->delta(); - - float r; - - int length = ksqrt(uhypsq(xy.X, xy.Y)); - if (globalorientation & 2) - { - r = 1.f / length; - } - else - { - int i; if (length == 0) i = 1024; else i = 1048576 / length; // consider integer truncation - r = i * (1.f/1048576.f); - } - - FVector2 const fxy = { xy.X*r, xy.Y*r }; - - ft[0] = ((float)(globalposx - sec->firstWall()->wall_int_pos().X)) * fxy.X + ((float)(globalposy - sec->firstWall()->wall_int_pos().Y)) * fxy.Y; - ft[1] = ((float)(globalposy - sec->firstWall()->wall_int_pos().Y)) * fxy.X - ((float)(globalposx - sec->firstWall()->wall_int_pos().X)) * fxy.Y; - ft[2] = fcosglobalang * fxy.X + fsinglobalang * fxy.Y; - ft[3] = fsinglobalang * fxy.X - fcosglobalang * fxy.Y; - - 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); - - 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; - - //Texture flipping - if (globalorientation&4) - { - std::swap(xtex.u, xtex.v); - std::swap(ytex.u, ytex.v); - std::swap(otex.u, otex.v); - } - - 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; } - - //Texture panning - FVector2 fxy = { global_cf_xpanning * ((float)(1 << widthBits(globalpicnum))) * (1.0f / 256.f), - global_cf_ypanning * ((float)(1 << heightBits(globalpicnum))) * (1.0f / 256.f) }; - - if ((globalorientation&(2+64)) == (2+64)) //Hack for panning for slopes w/ relative alignment - { - 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; - } - ytex.u += ytex.d*fxy.X; otex.u += otex.d*fxy.X; - ytex.v += ytex.d*fxy.Y; otex.v += otex.d*fxy.Y; - - if (globalorientation&2) //slopes - { - //Pick some point guaranteed to be not collinear to the 1st two points - FVector2 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; - - FVector2 const oxy = { n0.X + dxy.X, n0.Y + dxy.Y }; - - float const ox2 = (oxy.Y - fglobalposy) * gcosang - (oxy.X - fglobalposx) * gsinang; - float oy2 = 1.f / ((oxy.X - fglobalposx) * gcosang2 + (oxy.Y - fglobalposy) * gsinang2); - - double const px[3] = { x0, x1, (double)ghalfx * ox2 * oy2 + ghalfx }; - - oy2 *= gyxscale; - - double py[3] = { ryp0 + (double)ghoriz, ryp1 + (double)ghoriz, oy2 + (double)ghoriz }; - - 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) - }, - { (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) - }, - { (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) - } - }; - - py[0] = y0; - py[1] = y1; - py[2] = double(global_getzofslope_func(sec, oxy.X, oxy.Y) - globalposz) * oy2 + ghoriz; - - FVector3 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]) } }; - - float const r = 1.f / (oxyz[0].X * px[0] + oxyz[0].Y * px[1] + oxyz[0].Z * px[2]); - - 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; - - 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; - - 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; - - if (globalorientation&64) //Hack for relative alignment on slopes - { - float dist = global_cf_heinum * (1.0f / 4096.f); - dist = sqrtf(dist*dist+1); - if (!(globalorientation&4)) { xtex.v *= dist; ytex.v *= dist; otex.v *= dist; } - else { xtex.u *= dist; ytex.u *= dist; otex.u *= dist; } - } - } - - domostpolymethod = (globalorientation>>7) & DAMETH_MASKPROPS; - - pow2xsplit = 0; - drawpoly_alpha = 0.f; - drawpoly_blend = 0; - - if (have_floor) - { - if (globalposz > getflorzofslopeptr(sec, globalposx, globalposy)) - domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling - - if (domostpolymethod & DAMETH_MASKPROPS) - GLInterface.EnableBlend(true); - - polymost_domost(x0, y0, x1, y1); //flor - } - else - { - if (globalposz < getceilzofslopeptr(sec, globalposx, globalposy)) - domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling - - if (domostpolymethod & DAMETH_MASKPROPS) - GLInterface.EnableBlend(true); - - polymost_domost(x1, y1, x0, y0); //ceil - } - - if (domostpolymethod & DAMETH_MASKPROPS) - GLInterface.EnableBlend(false); - - domostpolymethod = DAMETH_NOMASK; -} - -static void calc_ypanning(int32_t refposz, float ryp0, float ryp1, - float x0, float x1, float ypan, uint8_t yrepeat, - int32_t dopancor, const vec2_16_t &tilesize) -{ - float const t0 = ((float)(refposz-globalposz))*ryp0 + ghoriz; - float const t1 = ((float)(refposz-globalposz))*ryp1 + ghoriz; - float t = (float(xtex.d*x0 + otex.d) * (float)yrepeat) / ((x1-x0) * ryp0 * 2048.f); - int i = 1<< heightBits(globalpicnum); - if (i < tilesize.Y) i <<= 1; - - - 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; -} - -static inline int32_t testvisiblemost(float const x0, float const x1) -{ - for (intptr_t i=vsp[0].n, newi; i; i=newi) - { - newi = vsp[i].n; - if ((x0 < vsp[newi].x) && (vsp[i].x < x1) && (vsp[i].ctag >= 0)) - return 1; - } - return 0; -} - -static inline int polymost_getclosestpointonwall(vec2_t const * const pos, int32_t dawall, vec2_t * const n) -{ - vec2_t const w = { wall[dawall].wall_int_pos().X, wall[dawall].wall_int_pos().Y }; - vec2_t const d = { POINT2(dawall).wall_int_pos().X - w.X, POINT2(dawall).wall_int_pos().Y - w.Y }; - int64_t i = d.X * ((int64_t)pos->X - w.X) + d.Y * ((int64_t)pos->Y - w.Y); - - if (d.X == 0 && d.Y == 0) - { - // In Blood's E1M1 this gets triggered for wall 522. - return 1; - } - - if (i < 0) - return 1; - - int64_t const j = (int64_t)d.X * d.X + (int64_t)d.Y * d.Y; - - if (i > j) - return 1; - - i = ((i << 15) / j) << 15; - - n->X = w.X + ((d.X * i) >> 30); - n->Y = w.Y + ((d.Y * i) >> 30); - - return 0; -} - -static float fgetceilzofslope(const sectortype* sec, float dax, float day) -{ - float z; - calcSlope(sec, dax, day, &z, nullptr); - return z; -} - -static float fgetflorzofslope(const sectortype* sec, float dax, float day) -{ - float z; - calcSlope(sec, dax, day, nullptr, &z); - return z; -} - -static void fgetzsofslope(const sectortype* sec, float dax, float day, float* ceilz, float *florz) -{ - calcSlope(sec, dax, day, ceilz, florz); -} - -static void polymost_flatskyrender(FVector2 const* const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesize) -{ - flatskyrender = 0; - FVector2 xys[8]; - - auto f = GLInterface.useMapFog; - GLInterface.useMapFog = false; - // Transform polygon to sky coordinates - for (int i = 0; i < n; i++) - { - FVector3 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; - } - - float const fglobalang = FixedToFloat(qglobalang); - auto sky = getSky(globalpicnum); - int32_t dapskybits = clamp(sky.lognumtiles, 0, 4), dapyoffs = sky.pmoffset, daptileyscale = sky.scale * 65536; - int16_t const * dapskyoff = sky.offsets; - - int remap = TRANSLATION(Translation_Remap + curbasepal, globalpal); - globalskytex = skytile? nullptr : GetSkyTexture(globalpicnum, dapskybits, dapskyoff, remap); - int realskybits = dapskybits; - if (globalskytex) - { - dapskybits = 0; - } - - dapyoffs = isExhumed()? 64*1024 : isSWALL()? 16*1024 : isDuke() && globalpicnum == 89 ? 17 * 1024 : 32 * 1024; - ghoriz = (qglobalhoriz*(1.f/65536.f)-float(ydimen>>1))*dapyoffs*(1.f/65536.f)+float(ydimen>>1)+ghorizcorrect; - - float const dd = fxdimen*.0000001f; //Adjust sky depth based on screen size! - float vv[2]; - float t = (float)((1<<(widthBits(globalpicnum)))<>1)+dapyoffs)) - vv[1]*ghoriz; - int ti = (1<<(heightBits(globalpicnum))); if (ti != tilesize.Y) ti += ti; - FVector3 o; - - 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]; - otex.v = hw_parallaxskypanning ? vv[0] + dd*(float)global_cf_ypanning*(float)ti*(1.f/256.f) : vv[0]; - - float x0 = xys[0].X, x1 = xys[0].X; - - for (intptr_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; - } - - int const npot = (1<<(widthBits(globalpicnum))) != tileWidth(globalpicnum); - float const xPanning = (hw_parallaxskypanning ? global_cf_xpanning / (1 << (realskybits-dapskybits)) : 0); - - 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; - - do - { - globalpicnum = dapskyoff[y&((1< 0) - globalpicnum = skytile; - 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; - 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 - FVector2 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) - } - }; - FVector2 fxyt[3]; - vec3d_t duvt[3]; - - for (int i = 0; i < 3; i++) - { - FVector2 const o1 = { fxy[i].X-ghalfx, fxy[i].Y-ghalfy }; - FVector3 const o2 = { o1.X, o1.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; - } - - FVector3 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; - - FVector2 cxy[8]; - FVector2 cxy2[8]; - int n2 = 0, n3 = 0; - - // Clip to o.x - for (intptr_t i=0; i= 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 (intptr_t i=0; i= 0); - globalskytex = nullptr; - globalpicnum = picnumbak; - - flatskyrender = 1; - GLInterface.useMapFog = f; -} - -static void polymost_drawalls(int32_t const bunch) -{ - drawpoly_alpha = 0.f; - drawpoly_blend = 0; - - int32_t const sectnum = thesector[bunchfirst[bunch]]; - auto const sec = §or[sectnum]; - float const fglobalang = FixedToFloat(qglobalang); - - polymost_outputGLDebugMessage(3, "polymost_drawalls(bunch:%d)", bunch); - - //DRAW WALLS SECTION! - for (intptr_t z=bunchfirst[bunch]; z>=0; z=bunchp2[z]) - { - int32_t const wallnum = thewall[z]; - - auto const wal = &wall[wallnum]; - auto const wal2 = wal->point2Wall(); - int32_t const nextsectnum = wal->nextsector; - auto const nextsec = nextsectnum>=0 ? §or[nextsectnum] : NULL; - - //Offset&Rotate 3D coordinates to screen 3D space - FVector2 walpos = { (float)(wal->wall_int_pos().X-globalposx), (float)(wal->wall_int_pos().Y-globalposy) }; - - FVector2 p0 = { walpos.Y * gcosang - walpos.X * gsinang, walpos.X * gcosang2 + walpos.Y * gsinang2 }; - FVector2 const op0 = p0; - - walpos = { (float)(wal2->wall_int_pos().X - globalposx), - (float)(wal2->wall_int_pos().Y - globalposy) }; - - FVector2 p1 = { walpos.Y * gcosang - walpos.X * gsinang, walpos.X * gcosang2 + walpos.Y * gsinang2 }; - - //Clip to close parallel-screen plane - - FVector2 n0, n1; - float t0, t1; - - if (p0.Y < SCISDIST) - { - if (p1.Y < SCISDIST) continue; - t0 = (SCISDIST-p0.Y)/(p1.Y-p0.Y); - p0 = { (p1.X-p0.X)*t0+p0.X, SCISDIST }; - n0 = { (wal2->wall_int_pos().X-wal->wall_int_pos().X)*t0+wal->wall_int_pos().X, - (wal2->wall_int_pos().Y-wal->wall_int_pos().Y)*t0+wal->wall_int_pos().Y }; - } - else - { - t0 = 0.f; - n0 = { (float)wal->wall_int_pos().X, (float)wal->wall_int_pos().Y }; - } - - if (p1.Y < SCISDIST) - { - t1 = (SCISDIST-op0.Y)/(p1.Y-op0.Y); - p1 = { (p1.X-op0.X)*t1+op0.X, SCISDIST }; - n1 = { (wal2->wall_int_pos().X-wal->wall_int_pos().X)*t1+wal->wall_int_pos().X, - (wal2->wall_int_pos().Y-wal->wall_int_pos().Y)*t1+wal->wall_int_pos().Y }; - } - else - { - t1 = 1.f; - n1 = { (float)wal2->wall_int_pos().X, (float)wal2->wall_int_pos().Y }; - } - - float ryp0 = 1.f/p0.Y, ryp1 = 1.f/p1.Y; - - //Generate screen coordinates for front side of wall - float const x0 = ghalfx*p0.X*ryp0 + ghalfx, x1 = ghalfx*p1.X*ryp1 + ghalfx; - - if (x1 <= x0) continue; - - ryp0 *= gyxscale; ryp1 *= gyxscale; - - float cz, fz; - - fgetzsofslope(sec,n0.X,n0.Y,&cz,&fz); - float const cy0 = (cz-globalposz)*ryp0 + ghoriz, fy0 = (fz-globalposz)*ryp0 + ghoriz; - - fgetzsofslope(sec,n1.X,n1.Y,&cz,&fz); - float const cy1 = (cz-globalposz)*ryp1 + ghoriz, fy1 = (fz-globalposz)*ryp1 + ghoriz; - - 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; - - // Floor - - globalpicnum = sec->floorpicnum; - globalshade = sec->floorshade; - globalfloorpal = globalpal = sec->floorpal; - globalorientation = sec->floorstat; - - GLInterface.SetVisibility(sectorVisibility(sec)); - - tileUpdatePicnum(&globalpicnum, sectnum); - - global_cf_fogpal = sec->fogpal; - global_cf_shade = sec->floorshade, global_cf_pal = sec->floorpal; global_cf_z = sec->floorz; // REFACT - global_cf_xpanning = sec->floorxpan_; - global_cf_ypanning = sec->floorypan_; - global_cf_heinum = sec->floorheinum; - global_getzofslope_func = &fgetflorzofslope; - - 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)) - { - int32_t fslopez = getflorzofslopeptr(sec, globalposx, globalposy); - if (globalposz <= fslopez) - polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, fy0, fy1, sectnum, true); - } - else if ((nextsectnum < 0) || (!(sector[nextsectnum].floorstat & CSTAT_SECTOR_SKY))) - { - skyzbufferhack = 1; - - //if (!hw_hightile || !hicfindskybox(globalpicnum, globalpal)) - { - float const ghorizbak = ghoriz; - pow2xsplit = 0; - flatskyrender = 1; - GLInterface.SetVisibility(0.f); - polymost_domost(x0,fy0,x1,fy1); - flatskyrender = 0; - ghoriz = ghorizbak; - } - - } - - // Ceiling - - globalpicnum = sec->ceilingpicnum; - globalshade = sec->ceilingshade; - globalfloorpal = globalpal = sec->ceilingpal; - globalorientation = sec->ceilingstat; - GLInterface.SetVisibility(sectorVisibility(sec)); - - tileUpdatePicnum(&globalpicnum, sectnum); - - - global_cf_fogpal = sec->fogpal; - global_cf_shade = sec->ceilingshade, global_cf_pal = sec->ceilingpal; global_cf_z = sec->ceilingz; // REFACT - global_cf_xpanning = sec->ceilingxpan_; - global_cf_ypanning = sec->ceilingypan_, - global_cf_heinum = sec->ceilingheinum; - global_getzofslope_func = &fgetceilzofslope; - - 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)) - { - int32_t cslopez = getceilzofslopeptr(sec, globalposx, globalposy); - if (globalposz >= cslopez) - polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, cy0, cy1, sectnum, false); - } - else if ((nextsectnum < 0) || (!(sector[nextsectnum].ceilingstat & CSTAT_SECTOR_SKY))) - { - skyzbufferhack = 1; - - //if (!hw_hightile || !hicfindskybox(globalpicnum, globalpal)) - { - float const ghorizbak = ghoriz; - pow2xsplit = 0; - flatskyrender = 1; - GLInterface.SetVisibility(0.f); - polymost_domost(x1, cy1, x0, cy0); - flatskyrender = 0; - ghoriz = ghorizbak; - } - - skyzbufferhack = 0; - } - - // Wall - - 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); - otex.u = t0*ryp0*gxyaspect*wal->xrepeat*8.0 - xtex.u*x0; - otex.u += (float)wal->xpan_*otex.d; - xtex.u += (float)wal->xpan_*xtex.d; - ytex.u = 0; - - float const ogux = xtex.u, oguy = ytex.u, oguo = otex.u; - - assert(domostpolymethod == DAMETH_NOMASK); - domostpolymethod = DAMETH_WALL; - - if (nextsectnum >= 0) - { - fgetzsofslope(§or[nextsectnum],n0.X,n0.Y,&cz,&fz); - float const ocy0 = (cz-globalposz)*ryp0 + ghoriz; - float const ofy0 = (fz-globalposz)*ryp0 + ghoriz; - fgetzsofslope(§or[nextsectnum],n1.X,n1.Y,&cz,&fz); - float const ocy1 = (cz-globalposz)*ryp1 + ghoriz; - float const ofy1 = (fz-globalposz)*ryp1 + ghoriz; - - if ((wal->cstat & (CSTAT_WALL_MASKED | CSTAT_WALL_1WAY)) == CSTAT_WALL_MASKED) maskwall[maskwallcnt++] = z; - - if (((cy0 < ocy0) || (cy1 < ocy1)) && (!((sec->ceilingstat§or[nextsectnum].ceilingstat) & CSTAT_SECTOR_SKY))) - { - globalpicnum = wal->picnum; globalshade = wal->shade; globalfloorpal = globalpal = (int32_t)((uint8_t)wal->pal); - GLInterface.SetVisibility(sectorVisibility(sec)); - globalorientation = wal->cstat; - tileUpdatePicnum(&globalpicnum, wallnum+16384); - - int i = (!(wal->cstat & CSTAT_WALL_ALIGN_BOTTOM)) ? sector[nextsectnum].ceilingz : sec->ceilingz; - - // over - calc_ypanning(i, ryp0, ryp1, x0, x1, wal->ypan_, wal->yrepeat, wal->cstat & CSTAT_WALL_ALIGN_BOTTOM, tileSize(globalpicnum)); - - if (wal->cstat & CSTAT_WALL_XFLIP) //xflip - { - float const t = (float)(wal->xrepeat*8 + wal->xpan_*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 & CSTAT_WALL_YFLIP) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; } //yflip - - pow2xsplit = 1; - polymost_domost(x1,ocy1,x0,ocy0,cy1,ocy1,cy0,ocy0); - if (wal->cstat & CSTAT_WALL_XFLIP) { xtex.u = ogux; ytex.u = oguy; otex.u = oguo; } - } - if (((ofy0 < fy0) || (ofy1 < fy1)) && (!((sec->floorstat§or[nextsectnum].floorstat) & CSTAT_SECTOR_SKY))) - { - const walltype* nwal; - - if (!(wal->cstat & CSTAT_WALL_BOTTOM_SWAP)) nwal = wal; - else - { - nwal = &wall[wal->nextwall]; - otex.u += (float)(nwal->xpan_ - wal->xpan_) * otex.d; - xtex.u += (float)(nwal->xpan_ - wal->xpan_) * xtex.d; - ytex.u += (float)(nwal->xpan_ - wal->xpan_) * ytex.d; - } - globalpicnum = nwal->picnum; globalshade = nwal->shade; globalfloorpal = globalpal = (int32_t)((uint8_t)nwal->pal); - GLInterface.SetVisibility(sectorVisibility(sec)); - globalorientation = nwal->cstat; - tileUpdatePicnum(&globalpicnum, wallnum+16384); - - int i = (!(nwal->cstat&CSTAT_WALL_ALIGN_BOTTOM)) ? sector[nextsectnum].floorz : sec->ceilingz; - - // under - calc_ypanning(i, ryp0, ryp1, x0, x1, nwal->ypan_, wal->yrepeat, !(nwal->cstat & CSTAT_WALL_ALIGN_BOTTOM), tileSize(globalpicnum)); - - if (wal->cstat & CSTAT_WALL_XFLIP) //xflip - { - float const t = (float)(wal->xrepeat*8 + nwal->xpan_*2); - xtex.u = xtex.d*t - xtex.u; - ytex.u = ytex.d*t - ytex.u; - otex.u = otex.d*t - otex.u; - } - if (nwal->cstat & CSTAT_WALL_YFLIP) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; } //yflip - - pow2xsplit = 1; - polymost_domost(x0,ofy0,x1,ofy1,ofy0,fy0,ofy1,fy1); - if (wal->cstat&(CSTAT_WALL_BOTTOM_SWAP | CSTAT_WALL_XFLIP)) { otex.u = oguo; xtex.u = ogux; ytex.u = oguy; } - } - } - - if ((nextsectnum < 0) || (wal->cstat & CSTAT_WALL_1WAY)) //White/1-way wall - { - do - { - const int maskingOneWay = (nextsectnum >= 0 && (wal->cstat & CSTAT_WALL_1WAY)); - - if (maskingOneWay) - { - vec2_t n, pos = { globalposx, globalposy }; - if (!polymost_getclosestpointonwall(&pos, wallnum, &n) && abs(pos.X - n.X) + abs(pos.Y - n.Y) <= 128) - break; - } - - globalpicnum = (nextsectnum < 0) ? wal->picnum : wal->overpicnum; - - globalshade = wal->shade; - globalfloorpal = globalpal = wal->pal; - GLInterface.SetVisibility(sectorVisibility(sec)); - globalorientation = wal->cstat; - tileUpdatePicnum(&globalpicnum, wallnum+16384); - - int i; - int const nwcs4 = !(wal->cstat & CSTAT_WALL_ALIGN_BOTTOM); - - if (nextsectnum >= 0) { i = nwcs4 ? nextsec->ceilingz : sec->ceilingz; } - else { i = nwcs4 ? sec->ceilingz : sec->floorz; } - - // white / 1-way - calc_ypanning(i, ryp0, ryp1, x0, x1, wal->ypan_, wal->yrepeat, nwcs4 && !maskingOneWay, tileSize(globalpicnum)); - - if (wal->cstat & CSTAT_WALL_XFLIP) //xflip - { - float const t = (float) (wal->xrepeat*8 + wal->xpan_*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 & CSTAT_WALL_YFLIP) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; } //yflip - - pow2xsplit = 1; - - polymost_domost(x0, cy0, x1, cy1, cy0, fy0, cy1, fy1); - } while (0); - } - - domostpolymethod = DAMETH_NOMASK; - - if (nextsectnum >= 0) - if (!gotsector[nextsectnum] && testvisiblemost(x0,x1)) - polymost_scansector(nextsectnum); - } -} - -// -// wallfront (internal) -// -int32_t wallfront(int32_t l1, int32_t l2) -{ - vec2_t const l1vect = wall[thewall[l1]].wall_int_pos(); - vec2_t const l1p2vect = wall[thewall[l1]].point2Wall()->wall_int_pos(); - vec2_t const l2vect = wall[thewall[l2]].wall_int_pos(); - vec2_t const l2p2vect = wall[thewall[l2]].point2Wall()->wall_int_pos(); - vec2_t d = { l1p2vect.X - l1vect.X, l1p2vect.Y - l1vect.Y }; - int32_t t1 = DMulScale(l2vect.X - l1vect.X, d.Y, -d.X, l2vect.Y - l1vect.Y, 2); //p1(l2) vs. l1 - int32_t t2 = DMulScale(l2p2vect.X - l1vect.X, d.Y, -d.X, l2p2vect.Y - l1vect.Y, 2); //p2(l2) vs. l1 - - if (t1 == 0) { if (t2 == 0) return -1; t1 = t2; } - if (t2 == 0) t2 = t1; - - if ((t1 ^ t2) >= 0) //pos vs. l1 - return (DMulScale(globalposx - l1vect.X, d.Y, -d.X, globalposy - l1vect.Y, 2) ^ t1) >= 0; - - d.X = l2p2vect.X - l2vect.X; - d.Y = l2p2vect.Y - l2vect.Y; - - t1 = DMulScale(l1vect.X - l2vect.X, d.Y, -d.X, l1vect.Y - l2vect.Y, 2); //p1(l1) vs. l2 - t2 = DMulScale(l1p2vect.X - l2vect.X, d.Y, -d.X, l1p2vect.Y - l2vect.Y, 2); //p2(l1) vs. l2 - - if (t1 == 0) { if (t2 == 0) return -1; t1 = t2; } - if (t2 == 0) t2 = t1; - - if ((t1 ^ t2) >= 0) //pos vs. l2 - return (DMulScale(globalposx - l2vect.X, d.Y, -d.X, globalposy - l2vect.Y, 2) ^ t1) < 0; - - return -2; -} - - -static int32_t polymost_bunchfront(const int32_t b1, const int32_t b2) -{ - int b1f = bunchfirst[b1]; - const double x2b2 = dxb2[bunchlast[b2]]; - const double x1b1 = dxb1[b1f]; - - if (x1b1 >= x2b2) - return -1; - - int b2f = bunchfirst[b2]; - const double x1b2 = dxb1[b2f]; - - if (x1b2 >= dxb2[bunchlast[b1]]) - return -1; - - if (x1b1 > x1b2) - { - while (dxb2[b2f] <= x1b1) b2f=bunchp2[b2f]; - return wallfront(b1f, b2f); - } - - while (dxb2[b1f] <= x1b2) b1f=bunchp2[b1f]; - return wallfront(b1f, b2f); -} - -void polymost_scansector(int32_t sectnum) -{ - if (sectnum < 0) return; - - if (automapping) - show2dsector.Set(sectnum); - - sectorborder[0] = sectnum; - int sectorbordercnt = 1; - do - { - sectnum = sectorborder[--sectorbordercnt]; - - TSectIterator it(sectnum); - while (auto act = it.Next()) - { - if ((act->spr.cstat & CSTAT_SPRITE_INVISIBLE) || act->spr.xrepeat == 0 || act->spr.yrepeat == 0) - continue; - - vec2_t const s = { act->spr.pos.X-globalposx, act->spr.pos.Y-globalposy }; - - if ((act->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) || - (hw_models && tile2model[act->spr.picnum].modelid>=0) || - ((s.X * gcosang) + (s.Y * gsinang) > 0)) - { - if ((act->spr.cstat&(CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_ALIGNMENT_MASK))!=(CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_ALIGNMENT_WALL) || - (r_voxels && tiletovox[act->spr.picnum] >= 0 && voxmodels[tiletovox[act->spr.picnum]]) || - (r_voxels && gi->Voxelize(act->spr.picnum) > -1) || - DMulScale(bcos(act->spr.ang), -s.X, bsin(act->spr.ang), -s.Y, 6) > 0) - if (!renderAddTsprite(pm_tsprite, pm_spritesortcnt, act)) - break; - } - } - - gotsector.Set(sectnum); - - int const bunchfrst = numbunches; - int const onumscans = numscans; - int const startwall = sector[sectnum].wallptr; - int const endwall = sector[sectnum].wallnum + startwall; - - int scanfirst = numscans; - - DVector2 p2 = { 0, 0 }; - - const walltype* wal; - - int z; - for (z=startwall,wal=&wall[z]; zpoint2Wall(); - - DVector2 const fp1 = { double(wal->wall_int_pos().X - globalposx), double(wal->wall_int_pos().Y - globalposy) }; - DVector2 const fp2 = { double(wal2->wall_int_pos().X - globalposx), double(wal2->wall_int_pos().Y - globalposy) }; - - int const nextsectnum = wal->nextsector; //Scan close sectors - - if (nextsectnum >= 0 && !(wal->cstat & CSTAT_WALL_1WAY) && sectorbordercnt < (int)countof(sectorborder)) - if (gotsector[nextsectnum] == 0) - { - double const d = fp1.X* fp2.Y - fp2.X * fp1.Y; - DVector2 const p1 = fp2 - fp1; - - // 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.LengthSquared()) * 256.f) - { - sectorborder[sectorbordercnt++] = nextsectnum; - gotsector.Set(nextsectnum); - } - } - - DVector2 p1; - - if ((z == startwall) || (wall[z-1].point2 != z)) - { - p1 = { (((fp1.Y * fcosglobalang) - (fp1.X * fsinglobalang)) * (1.0/64.0)), - (((fp1.X * cosviewingrangeglobalang) + (fp1.Y * sinviewingrangeglobalang)) * (1.0/64.0)) }; - } - else { p1 = p2; } - - p2 = { (((fp2.Y * fcosglobalang) - (fp2.X * fsinglobalang)) * (1.0/64.0)), - (((fp2.X * cosviewingrangeglobalang) + (fp2.Y * sinviewingrangeglobalang)) * (1.0/64.0)) }; - - if (numscans >= MAXWALLSB-1) - { - Printf("!!numscans\n"); - return; - } - - //if wall is facing you... - if ((p1.Y >= SCISDIST || p2.Y >= SCISDIST) && (p1.X*p2.Y < p2.X*p1.Y)) - { - 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; - - 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; - - if (dxb1[numscans] < dxb2[numscans]) - { - thesector[numscans] = sectnum; - thewall[numscans] = z; - bunchp2[numscans] = numscans + 1; - numscans++; - } - } - - if ((wall[z].point2 < z) && (scanfirst < numscans)) - { - bunchp2[numscans-1] = scanfirst; - scanfirst = numscans; - } - } - - for (intptr_t scan=onumscans; scan dxb1[bunchp2[scan]])) - { - bunchfirst[numbunches++] = bunchp2[scan]; - bunchp2[scan] = -1; - } - } - - for (intptr_t bunch=bunchfrst; bunch=0; zz=bunchp2[zz]) { } - bunchlast[bunch] = zz; - } - } - while (sectorbordercnt > 0); -} - -/*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]) -*/ - -static void polymost_initmosts(const float * px, const float * py, int const n) -{ - if (n < 3) return; - - int32_t imin = (px[1] < px[0]); - - for (intptr_t i=n-1; i>=2; i--) - if (px[i] < px[imin]) imin = i; - - int32_t vcnt = 1; //0 is dummy solid node - - vsp[vcnt].x = px[imin]; - vsp[vcnt].cy[0] = vsp[vcnt].fy[0] = py[imin]; - vcnt++; - - int i = imin+1, j = imin-1; - if (i >= n) i = 0; - if (j < 0) j = n-1; - - do - { - if (px[i] < px[j]) - { - if (px[i] <= vsp[vcnt-1].x) vcnt--; - vsp[vcnt].x = px[i]; - vsp[vcnt].cy[0] = py[i]; - int k = j+1; if (k >= n) k = 0; - //(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]) - { - if (px[j] <= vsp[vcnt-1].x) vcnt--; - vsp[vcnt].x = px[j]; - vsp[vcnt].fy[0] = py[j]; - int k = i-1; if (k < 0) k = n-1; - //(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 - { - if (px[i] <= vsp[vcnt-1].x) vcnt--; - 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++; - } - - domost_rejectcount = 0; - - vsp_finalize_init(vcnt); - - xbl = px[0]; - xbr = px[0]; - xbt = py[0]; - xbb = py[0]; - - for (intptr_t ii = n - 1; ii >= 1; ii--) - { - if (xbl > px[ii]) xbl = px[ii]; - if (xbr < px[ii]) xbr = px[ii]; - if (xbt > py[ii]) xbt = py[ii]; - if (xbb < py[ii]) xbb = py[ii]; - } - - gtag = vcnt; - viewportNodeCount = vcnt; -} - -void polymost_drawrooms() -{ - polymost_outputGLDebugMessage(3, "polymost_drawrooms()"); - - GLInterface.ClearDepth(); - GLInterface.EnableBlend(false); - GLInterface.EnableAlphaTest(false); - GLInterface.EnableDepthTest(true); - GLInterface.SetDepthFunc(DF_LEqual); - GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); - renderSetViewpoint(0, 0, 0); - - gvrcorrection = viewingrange*(1.f/65536.f); - //if (glprojectionhacks == 2) - { - // 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 / pi::pi()); - 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; - } - - //Polymost supports true look up/down :) Here, we convert horizon to angle. - //gchang&gshang are cos&sin of this angle (respectively) - 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); - ghoriz = FixedToFloat(qglobalhoriz); - ghorizcorrect = FixedToFloat(DivScale(xdimenscale, viewingrange, 16)); - - //global cos/sin height angle - if (r_yshearing) - { - gshang = 0.f; - gchang = 1.f; - ghoriz2 = (float)(ydimen >> 1) - (ghoriz + ghorizcorrect); - } - else - { - float r = (float)(ydimen >> 1) - (ghoriz + ghorizcorrect); - gshang = r / sqrtf(r * r + ghalfx * ghalfx / (gvrcorrection * gvrcorrection)); - gchang = sqrtf(1.f - gshang * gshang); - ghoriz2 = 0.f; - } - - ghoriz = (float)(ydimen>>1); - - resizeglcheck(); - float const ratio = 1.f; - - //global cos/sin tilt angle - gctang = cosf(gtang); - gstang = sinf(gtang); - - if (Bfabsf(gstang) < .001f) // This avoids nasty precision bugs in domost() - { - gstang = 0.f; - gctang = (gctang > 0.f) ? 1.f : -1.f; - } - - if (inpreparemirror) - gstang = -gstang; - - //Generate viewport trapezoid (for handling screen up/down) - FVector3 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 } }; - - for (auto & v : p) - { - //Tilt rotation (backwards) - FVector2 const o = { (v.X-ghalfx)*ratio, (v.Y-ghoriz)*ratio }; - FVector3 const o2 = { o.X*gctang + o.Y*gstang, o.Y*gctang - o.X*gstang + ghoriz2, ghalfx / gvrcorrection }; - - //Up/down rotation (backwards) - v = { o2.X, o2.Y * gchang + o2.Z * gshang, o2.Z * gchang - o2.Y * gshang }; - } - - if (inpreparemirror) - gstang = -gstang; - polymost_updaterotmat(); - - //Clip to SCISDIST plane - int n = 0; - - FVector3 p2[6]; - - for (intptr_t i=0; i<4; i++) - { - int const j = i < 3 ? i + 1 : 0; - - if (p[i].Z >= SCISDIST) - p2[n++] = p[i]; - - if ((p[i].Z >= SCISDIST) != (p[j].Z >= SCISDIST)) - { - float const r = (SCISDIST - p[i].Z) / (p[j].Z - p[i].Z); - p2[n++] = { (p[j].X - p[i].X) * r + p[i].X, (p[j].Y - p[i].Y) * r + p[i].Y, SCISDIST }; - } - } - - if (n < 3) - { - GLInterface.SetDepthFunc(DF_LEqual); - return; - } - - float sx[6], sy[6]; - - for (intptr_t i = 0; i < n; i++) - { - float const r = (ghalfx / gvrcorrection) / p2[i].Z; - sx[i] = p2[i].X * r + ghalfx; - sy[i] = p2[i].Y * r + ghoriz; - } - - polymost_initmosts(sx, sy, n); - - numscans = numbunches = 0; - - // MASKWALL_BAD_ACCESS - // Fixes access of stale maskwall[maskwallcnt] (a "scan" index, in BUILD lingo): - maskwallcnt = 0; - - // NOTE: globalcursectnum has been already adjusted in ADJUST_GLOBALCURSECTNUM. - if (!validSectorIndex(globalcursectnum)) return; // if we can't render - don't render. Asserting here is useless. - polymost_scansector(globalcursectnum); - - grhalfxdown10x = grhalfxdown10; - - renderBeginScene(); - - if (inpreparemirror) - { - // see engine.c: INPREPAREMIRROR_NO_BUNCHES - if (numbunches > 0) - { - grhalfxdown10x = -grhalfxdown10; - polymost_drawalls(0); - numbunches--; - bunchfirst[0] = bunchfirst[numbunches]; - bunchlast[0] = bunchlast[numbunches]; - } else - { - inpreparemirror = 0; - } - } - - - while (numbunches > 0) - { - memset(ptempbuf,0,numbunches+3); ptempbuf[0] = 1; - - int32_t closest = 0; //Almost works, but not quite :( - - for (intptr_t i=1; i=0; z=bunchp2[z]) - show2dwall.Set(thewall[z]); - } - - numbunches--; - bunchfirst[closest] = bunchfirst[numbunches]; - bunchlast[closest] = bunchlast[numbunches]; - } - renderFinishScene(); - - GLInterface.SetDepthFunc(DF_LEqual); -} - -static void polymost_drawmaskwallinternal(int32_t wallIndex) -{ - auto const wal = &wall[wallIndex]; - auto const wal2 = wal->point2Wall(); - if (wal->nextwall == -1) return; - int32_t const sectnum = wal->nextWall()->nextsector; - auto const sec = §or[sectnum]; - - auto const nsec = wal->nextSector(); - - polymost_outputGLDebugMessage(3, "polymost_drawmaskwallinternal(wallIndex:%d)", wallIndex); - - globalpicnum = wal->overpicnum; - if ((uint32_t)globalpicnum >= MAXTILES) - globalpicnum = 0; - - globalorientation = (int32_t)wal->cstat; - tileUpdatePicnum(&globalpicnum, (int16_t)wallIndex+16384); - - GLInterface.SetVisibility(sectorVisibility(sec)); - - globalshade = (int32_t)wal->shade; - globalfloorpal = globalpal = (int32_t)((uint8_t)wal->pal); - - FVector2 s0 = { (float)(wal->wall_int_pos().X-globalposx), (float)(wal->wall_int_pos().Y-globalposy) }; - FVector2 p0 = { s0.Y*gcosang - s0.X*gsinang, s0.X*gcosang2 + s0.Y*gsinang2 }; - - FVector2 s1 = { (float)(wal2->wall_int_pos().X-globalposx), (float)(wal2->wall_int_pos().Y-globalposy) }; - FVector2 p1 = { s1.Y*gcosang - s1.X*gsinang, s1.X*gcosang2 + s1.Y*gsinang2 }; - - if ((p0.Y < SCISDIST) && (p1.Y < SCISDIST)) return; - - //Clip to close parallel-screen plane - FVector2 const op0 = p0; - - float t0 = 0.f; - - if (p0.Y < SCISDIST) - { - t0 = (SCISDIST - p0.Y) / (p1.Y - p0.Y); - p0 = { (p1.X - p0.X) * t0 + p0.X, SCISDIST }; - } - - float t1 = 1.f; - - if (p1.Y < SCISDIST) - { - t1 = (SCISDIST - op0.Y) / (p1.Y - op0.Y); - p1 = { (p1.X - op0.X) * t1 + op0.X, SCISDIST }; - } - - int32_t m0 = (int32_t)((wal2->wall_int_pos().X - wal->wall_int_pos().X) * t0 + wal->wall_int_pos().X); - int32_t m1 = (int32_t)((wal2->wall_int_pos().Y - wal->wall_int_pos().Y) * t0 + wal->wall_int_pos().Y); - int32_t cz[4], fz[4]; - getzsofslopeptr(sec, m0, m1, &cz[0], &fz[0]); - getzsofslopeptr(wal->nextSector(), m0, m1, &cz[1], &fz[1]); - m0 = (int32_t)((wal2->wall_int_pos().X - wal->wall_int_pos().X) * t1 + wal->wall_int_pos().X); - m1 = (int32_t)((wal2->wall_int_pos().Y - wal->wall_int_pos().Y) * t1 + wal->wall_int_pos().Y); - getzsofslopeptr(sec, m0, m1, &cz[2], &fz[2]); - getzsofslopeptr(wal->nextSector(), m0, m1, &cz[3], &fz[3]); - - float ryp0 = 1.f/p0.Y; - float ryp1 = 1.f/p1.Y; - - //Generate screen coordinates for front side of wall - float const x0 = ghalfx*p0.X*ryp0 + ghalfx; - float const x1 = ghalfx*p1.X*ryp1 + ghalfx; - if (x1 <= x0) return; - - ryp0 *= gyxscale; ryp1 *= gyxscale; - - xtex.d = (ryp0-ryp1)*gxyaspect / (x0-x1); - ytex.d = 0; - otex.d = ryp0*gxyaspect - xtex.d*x0; - - //gux*x0 + guo = t0*wal->xrepeat*8*yp0 - //gux*x1 + guo = t1*wal->xrepeat*8*yp1 - 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->xpan_*otex.d; - xtex.u += (float)wal->xpan_*xtex.d; - ytex.u = 0; - - // mask - calc_ypanning((!(wal->cstat & CSTAT_WALL_ALIGN_BOTTOM)) ? max(nsec->ceilingz, sec->ceilingz) : min(nsec->floorz, sec->floorz), ryp0, ryp1, - x0, x1, wal->ypan_, wal->yrepeat, 0, tileSize(globalpicnum)); - - if (wal->cstat & CSTAT_WALL_XFLIP) //xflip - { - float const t = (float)(wal->xrepeat*8 + wal->xpan_*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 & CSTAT_WALL_YFLIP) { xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; } //yflip - - int method = DAMETH_MASK | DAMETH_WALL; - - if (wal->cstat & CSTAT_WALL_TRANSLUCENT) - method = DAMETH_WALL | (((wal->cstat & CSTAT_WALL_TRANS_FLIP)) ? DAMETH_TRANS2 : DAMETH_TRANS1); - - uint8_t const blend = 0;// wal->blend; nothing sets this and this feature is not worth reimplementing (render style needs to be done less hacky.) - SetRenderStyleFromBlend(!!(wal->cstat & CSTAT_WALL_TRANSLUCENT), blend, !!(wal->cstat & CSTAT_WALL_TRANS_FLIP)); - - drawpoly_alpha = 0.f; - drawpoly_blend = blend; - - 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 }; - - //Clip 2 quadrilaterals - // /csy3 - // / | - // csy0------/----csy2 - // | /xxxxxxx| - // | /xxxxxxxxx| - // csy1/xxxxxxxxxxx| - // |xxxxxxxxxxx/fsy3 - // |xxxxxxxxx/ | - // |xxxxxxx/ | - // fsy0----/------fsy2 - // | / - // fsy1/ - - FVector2 dpxy[16] = { { x0, csy[1] }, { x1, csy[3] }, { x1, fsy[3] }, { x0, fsy[1] } }; - - //Clip to (x0,csy[0])-(x1,csy[2]) - - FVector2 dp2[8]; - - int n2 = 0; - t1 = -((dpxy[0].X - x0) * (csy[2] - csy[0]) - (dpxy[0].Y - csy[0]) * (x1 - x0)); - - for (intptr_t i=0; i<4; i++) - { - int j = i + 1; - - if (j >= 4) - 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]; - - if ((t0 >= 0) != (t1 >= 0) && (t0 <= 0) != (t1 <= 0)) - { - float const r = t0 / (t0 - t1); - dp2[n2++] = { (dpxy[j].X - dpxy[i].X) * r + dpxy[i].X, (dpxy[j].Y - dpxy[i].Y) * r + dpxy[i].Y }; - } - } - - if (n2 < 3) - return; - - //Clip to (x1,fsy[2])-(x0,fsy[0]) - t1 = -((dp2[0].X - x1) * (fsy[0] - fsy[2]) - (dp2[0].Y - fsy[2]) * (x0 - x1)); - int n = 0; - - for (intptr_t i = 0, j = 1; i < n2; j = ++i + 1) - { - 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]; - - if ((t0 >= 0) != (t1 >= 0) && (t0 <= 0) != (t1 <= 0)) - { - float const r = t0 / (t0 - t1); - dpxy[n++] = { (dp2[j].X - dp2[i].X) * r + dp2[i].X, (dp2[j].Y - dp2[i].Y) * r + dp2[i].Y }; - } - } - - if (n < 3) - return; - - pow2xsplit = 0; - - polymost_drawpoly(dpxy, n, method, tileSize(globalpicnum)); -} - -void polymost_drawmaskwall(int32_t damaskwallcnt) -{ - int const z = maskwall[damaskwallcnt]; - polymost_drawmaskwallinternal(thewall[z]); -} - -void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t mirrorWall) -{ - polymost_outputGLDebugMessage(3, "polymost_prepareMirror(%u)", mirrorWall); - - //POGO: prepare necessary globals for drawing, as we intend to call this outside of drawrooms - gvrcorrection = viewingrange*(1.f/65536.f); - //if (glprojectionhacks == 2) - { - // calculates the extent 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 / pi::pi()); - 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; - } - - set_globalpos(dax, day, daz); - set_globalang(daang); - qglobalhoriz = MulScale(dahoriz, DivScale(xdimenscale, viewingrange, 16), 16)+IntToFixed(ydimen>>1); - 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); - ghoriz = FixedToFloat(qglobalhoriz); - ghorizcorrect = FixedToFloat(DivScale(xdimenscale, viewingrange, 16)); - resizeglcheck(); - if (r_yshearing) - { - gshang = 0.f; - gchang = 1.f; - ghoriz2 = (float)(ydimen >> 1) - (ghoriz+ghorizcorrect); - } - else - { - float r = (float)(ydimen >> 1) - (ghoriz+ghorizcorrect); - gshang = r / sqrtf(r * r + ghalfx * ghalfx / (gvrcorrection * gvrcorrection)); - gchang = sqrtf(1.f - gshang * gshang); - 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; - } - polymost_updaterotmat(); - grhalfxdown10x = grhalfxdown10; - - renderBeginScene(); - //POGO: write the mirror region to the stencil buffer to allow showing mirrors & skyboxes at the same time - GLInterface.EnableStencilWrite(1); - GLInterface.EnableAlphaTest(false); - GLInterface.EnableDepthTest(false); - polymost_drawmaskwallinternal(mirrorWall); - GLInterface.EnableAlphaTest(true); - GLInterface.EnableDepthTest(true); - renderFinishScene(); - - //POGO: render only to the mirror region - GLInterface.EnableStencilTest(1); -} - -void polymost_completeMirror() -{ - polymost_outputGLDebugMessage(3, "polymost_completeMirror()"); - GLInterface.DisableStencil(); -} - - -static inline int32_t polymost_findwall(tspritetype const * const tspr, vec2_t const * const tsiz, int32_t * rd) -{ - int32_t dist = 4; - auto const sect = tspr->sectp; - vec2_t n; - walltype* closest = nullptr; - - for(auto& wal : wallsofsector(sect)) - { - if ((!wal.twoSided() || ((wal.nextSector()->ceilingz > (tspr->pos.Z - ((tsiz->Y * tspr->yrepeat) << 2))) || - wal.nextSector()->floorz < tspr->pos.Z)) && !polymost_getclosestpointonwall((const vec2_t *) tspr, wallnum(&wal), &n)) - { - int const dst = abs(tspr->pos.X - n.X) + abs(tspr->pos.Y - n.Y); - - if (dst <= dist) - { - dist = dst; - closest = &wal; - } - } - } - - *rd = dist; - - return closest? wallnum(closest) : -1; -} - -static int32_t polymost_lintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - 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; - - if (!bot) - return 0; - - int32_t const x31 = x3 - x1, y31 = y3 - y1; - int32_t const topt = x31 * y34 - y31 * x34; - - int rv = 1; - - if (bot > 0) - { - if ((unsigned)topt >= (unsigned)bot) - rv = 0; - - int32_t topu = x21 * y31 - y21 * x31; - - if ((unsigned)topu >= (unsigned)bot) - rv = 0; - } - else - { - if ((unsigned)topt <= (unsigned)bot) - rv = 0; - - int32_t topu = x21 * y31 - y21 * x31; - - if ((unsigned)topu <= (unsigned)bot) - rv = 0; - } - - return rv; -} - -static inline float tspriteGetZOfSlopeFloat(tspritetype* const tspr, float dax, float day) -{ - int16_t const heinum = tspriteGetSlope(tspr); - if (heinum == 0) - return float(tspr->pos.Z); - - float const f = bsin(tspr->ang + 1024) * (day - tspr->pos.Y) - bsin(tspr->ang + 512) * (dax - tspr->pos.X); - return float(tspr->pos.Z) + heinum * f * (1.f / 4194304.f); -} - - -#define TSPR_OFFSET_FACTOR .0002f -#define TSPR_OFFSET(tspr) (TSPR_OFFSET_FACTOR + ((tspr->ownerActor ? tspr->ownerActor->GetIndex() & 63 : 0) * TSPR_OFFSET_FACTOR)) - -void polymost_drawsprite(int32_t snum) -{ - auto const tspr = tspriteptr[snum]; - - if (bad_tspr(tspr)) - return; - - const sectortype* sec; - - auto actor = tspr->ownerActor; - - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLAB) - tileUpdatePicnum(&tspr->picnum, (actor->GetIndex() & 16383) + 32768); - - globalpicnum = tspr->picnum; - globalshade = tspr->shade; - globalpal = tspr->pal; - globalfloorpal = tspr->sectp->floorpal; - globalorientation = tspr->cstat; - - GLInterface.SetVisibility(sectorVisibility(tspr->sectp)); - - vec2_t off = { 0, 0 }; - - if ((globalorientation & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLAB) // only non-voxel sprites should do this - { - int const flag = hw_hightile && TileFiles.tiledata[globalpicnum].hiofs.xsize > 0; - off = { (flag ? TileFiles.tiledata[globalpicnum].hiofs.xoffs : tileLeftOffset(globalpicnum)), - (flag ? TileFiles.tiledata[globalpicnum].hiofs.yoffs : tileTopOffset(globalpicnum)) }; - - if (!(tspr->clipdist & TSPR_SLOPESPRITE)) - { - off.X += tspr->xoffset; - off.Y += tspr->yoffset; - } - - } - - int32_t method = DAMETH_MASK | DAMETH_CLAMPED; - - if (tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) - method = DAMETH_CLAMPED | ((tspr->cstat & CSTAT_SPRITE_TRANS_FLIP) ? DAMETH_TRANS2 : DAMETH_TRANS1); - - SetRenderStyleFromBlend(!!(tspr->cstat & CSTAT_SPRITE_TRANSLUCENT), tspr->blend, !!(tspr->cstat & CSTAT_SPRITE_TRANS_FLIP)); - - drawpoly_alpha = actor->sprext.alpha; - drawpoly_blend = tspr->blend; - - sec = tspr->sectp; - - while (!(actor->sprext.renderflags & SPREXT_NOTMD)) - { - if (hw_models && tile2model[Ptile2tile(tspr->picnum, tspr->pal)].modelid >= 0 && - tile2model[Ptile2tile(tspr->picnum, tspr->pal)].framenum >= 0) - { - if (polymost_mddraw(tspr)) return; - break; // else, render as flat sprite - } - - if (r_voxels) - { - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLAB && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) - { - int num = tiletovox[tspr->picnum]; - if (polymost_voxdraw(voxmodels[num], tspr, voxrotate[num])) return; - break; // else, render as flat sprite - } - - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_SLAB && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum]) - { - int num = tspr->picnum; - polymost_voxdraw(voxmodels[tspr->picnum], tspr, voxrotate[num]); - return; - } - } - - - break; - } - - vec3_t pos = tspr->pos; - - if (actor->sprext.renderflags & SPREXT_AWAY1) - { - pos.X += bcos(tspr->ang, -13); - pos.Y += bsin(tspr->ang, -13); - } - else if (actor->sprext.renderflags & SPREXT_AWAY2) - { - pos.X -= bcos(tspr->ang, -13); - pos.Y -= bsin(tspr->ang, -13); - } - - vec2_t tsiz; - - if (hw_hightile && TileFiles.tiledata[globalpicnum].hiofs.xsize) - tsiz = { TileFiles.tiledata[globalpicnum].hiofs.xsize, TileFiles.tiledata[globalpicnum].hiofs.ysize }; - else - tsiz = { tileWidth(globalpicnum), tileHeight(globalpicnum) }; - - if (tsiz.X <= 0 || tsiz.Y <= 0) - return; - - FVector2 const ftsiz = { (float) tsiz.X, (float) tsiz.Y }; - - switch ((globalorientation >> 4) & 3) - { - case 0: // Face sprite - { - // Project 3D to 2D - if (globalorientation & 4) - off.X = -off.X; - // NOTE: yoff not negated not for y flipping, unlike wall and floor - // aligned sprites. - - int const ang = (getangle(tspr->pos.X - globalposx, tspr->pos.Y - globalposy) + 1024) & 2047; - - float foffs = TSPR_OFFSET(tspr); - - FVector2 const offs = { float(bcosf(ang, -6) * foffs), float(bsinf(ang, -6) * foffs) }; - - FVector2 s0 = { (float)(tspr->pos.X - globalposx) + offs.X, - (float)(tspr->pos.Y - globalposy) + offs.Y}; - - FVector2 p0 = { s0.Y * gcosang - s0.X * gsinang, s0.X * gcosang2 + s0.Y * gsinang2 }; - - if (p0.Y <= SCISDIST) - goto _drawsprite_return; - - float const ryp0 = 1.f / p0.Y; - s0 = { ghalfx * p0.X * ryp0 + ghalfx, ((float)(pos.Z - globalposz)) * gyxscale * ryp0 + ghoriz }; - - float const f = ryp0 * fxdimen * (1.0f / 160.f); - - FVector2 ff = { ((float)tspr->xrepeat) * f, - ((float)tspr->yrepeat) * f * ((float)yxaspect * (1.0f / 65536.f)) }; - - if (tsiz.X & 1) - s0.X += ff.X * 0.5f; - if (globalorientation & 128 && tsiz.Y & 1) - s0.Y += ff.Y * 0.5f; - - s0.X -= ff.X * (float) off.X; - s0.Y -= ff.Y * (float) off.Y; - - ff.X *= ftsiz.X; - ff.Y *= ftsiz.Y; - - FVector2 pxy[4]; - - pxy[0].X = pxy[3].X = s0.X - ff.X * 0.5f; - pxy[1].X = pxy[2].X = s0.X + ff.X * 0.5f; - if (!(globalorientation & 128)) - { - pxy[0].Y = pxy[1].Y = s0.Y - ff.Y; - pxy[2].Y = pxy[3].Y = s0.Y; - } - else - { - pxy[0].Y = pxy[1].Y = s0.Y - ff.Y * 0.5f; - pxy[2].Y = pxy[3].Y = s0.Y + ff.Y * 0.5f; - } - - xtex.d = ytex.d = ytex.u = xtex.v = 0; - otex.d = ryp0 * gviewxrange; - - if (!(globalorientation & 4)) - { - xtex.u = ftsiz.X * otex.d / (pxy[1].X - pxy[0].X + .002f); - otex.u = -xtex.u * (pxy[0].X - .001f); - } - else - { - xtex.u = ftsiz.X * otex.d / (pxy[0].X - pxy[1].X - .002f); - otex.u = -xtex.u * (pxy[1].X + .001f); - } - - if (!(globalorientation & 8)) - { - ytex.v = ftsiz.Y * otex.d / (pxy[3].Y - pxy[0].Y + .002f); - otex.v = -ytex.v * (pxy[0].Y - .001f); - } - else - { - ytex.v = ftsiz.Y * otex.d / (pxy[0].Y - pxy[3].Y - .002f); - otex.v = -ytex.v * (pxy[3].Y + .001f); - } - - // Clip sprites to ceilings/floors when no parallaxing and not sloped - if (!(tspr->sectp->ceilingstat & (CSTAT_SECTOR_SKY|CSTAT_SECTOR_SLOPE))) - { - s0.Y = ((float) (tspr->sectp->ceilingz - globalposz)) * gyxscale * ryp0 + ghoriz; - if (pxy[0].Y < s0.Y) - pxy[0].Y = pxy[1].Y = s0.Y; - } - - if (!(tspr->sectp->floorstat & (CSTAT_SECTOR_SKY | CSTAT_SECTOR_SLOPE))) - { - s0.Y = ((float) (tspr->sectp->floorz - globalposz)) * gyxscale * ryp0 + ghoriz; - if (pxy[2].Y > s0.Y) - pxy[2].Y = pxy[3].Y = s0.Y; - } - - vec2_16_t tempsiz = { (int16_t)tsiz.X, (int16_t)tsiz.Y }; - pow2xsplit = 0; - if (globalshade > 63) globalshade = 63; // debug - polymost_drawpoly(pxy, 4, method, tempsiz); - - drawpoly_srepeat = 0; - drawpoly_trepeat = 0; - } - break; - - case 1: // Wall sprite - { - // Project 3D to 2D - if (globalorientation & 4) - off.X = -off.X; - - if (globalorientation & 8) - off.Y = -off.Y; - - FVector2 const extent = { float(tspr->xrepeat * bsinf(tspr->ang, -16)), - float(tspr->xrepeat * -bcosf(tspr->ang, -16)) }; - - float f = (float)(tsiz.X >> 1) + (float)off.X; - - FVector2 const vf = { extent.X * f, extent.Y * f }; - - FVector2 vec0 = { (float)(pos.X - globalposx) - vf.X, - (float)(pos.Y - globalposy) - vf.Y }; - - int32_t walldist = 1; - int w = polymost_findwall(tspr, &tsiz, &walldist); - - // detect if the sprite is either on the wall line or the wall line and sprite intersect - if (w != -1) - { - vec2_t v = { /*Blrintf(vf.x)*/(int)vf.X, /*Blrintf(vf.y)*/(int)vf.Y }; - - if (walldist <= 2 || ((pos.X - v.X) + (pos.X + v.X)) == (wall[w].wall_int_pos().X + POINT2(w).wall_int_pos().X) || - ((pos.Y - v.Y) + (pos.Y + v.Y)) == (wall[w].wall_int_pos().Y + POINT2(w).wall_int_pos().Y) || - polymost_lintersect(pos.X - v.X, pos.Y - v.Y, pos.X + v.X, pos.Y + v.Y, wall[w].wall_int_pos().X, wall[w].wall_int_pos().Y, - POINT2(w).wall_int_pos().X, POINT2(w).wall_int_pos().Y)) - { - int32_t const ang = getangle(wall[w].wall_int_pos().X - POINT2(w).wall_int_pos().X, wall[w].wall_int_pos().Y - POINT2(w).wall_int_pos().Y); - float const foffs = TSPR_OFFSET(tspr); - DVector2 const offs = { -bsinf(ang, -6) * foffs, bcosf(ang, -6) * foffs }; - - vec0.X -= offs.X; - vec0.Y -= offs.Y; - } - } - - FVector2 p0 = { vec0.Y * gcosang - vec0.X * gsinang, - vec0.X * gcosang2 + vec0.Y * gsinang2 }; - - FVector2 const pp = { extent.X * ftsiz.X + vec0.X, - extent.Y * ftsiz.X + vec0.Y }; - - FVector2 p1 = { pp.Y * gcosang - pp.X * gsinang, - pp.X * gcosang2 + pp.Y * gsinang2 }; - - if ((p0.Y <= SCISDIST) && (p1.Y <= SCISDIST)) - goto _drawsprite_return; - - // Clip to close parallel-screen plane - FVector2 const op0 = p0; - - float t0 = 0.f, t1 = 1.f; - - if (p0.Y < SCISDIST) - { - t0 = (SCISDIST - p0.Y) / (p1.Y - p0.Y); - p0 = { (p1.X - p0.X) * t0 + p0.X, SCISDIST }; - } - - if (p1.Y < SCISDIST) - { - t1 = (SCISDIST - op0.Y) / (p1.Y - op0.Y); - p1 = { (p1.X - op0.X) * t1 + op0.X, SCISDIST }; - } - - f = 1.f / p0.Y; - const float ryp0 = f * gyxscale; - float sx0 = ghalfx * p0.X * f + ghalfx; - - f = 1.f / p1.Y; - const float ryp1 = f * gyxscale; - float sx1 = ghalfx * p1.X * f + ghalfx; - - pos.Z -= ((off.Y * tspr->yrepeat) << 2); - - if (globalorientation & 128) - { - pos.Z += ((tsiz.Y * tspr->yrepeat) << 1); - - if (tsiz.Y & 1) - pos.Z += (tspr->yrepeat << 1); // Odd yspans - } - - xtex.d = (ryp0 - ryp1) * gxyaspect / (sx0 - sx1); - ytex.d = 0; - otex.d = ryp0 * gxyaspect - xtex.d * sx0; - - if (globalorientation & 4) - { - t0 = 1.f - t0; - t1 = 1.f - t1; - } - - xtex.u = (t0 * ryp0 - t1 * ryp1) * gxyaspect * ftsiz.X / (sx0 - sx1); - ytex.u = 0; - otex.u = t0 * ryp0 * gxyaspect * ftsiz.X - xtex.u * sx0; - - f = ((float) tspr->yrepeat) * ftsiz.Y * 4; - - 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; - - // gvx*sx0 + gvy*sc0 + gvo = 0 - // gvx*sx1 + gvy*sc1 + gvo = 0 - // gvx*sx0 + gvy*sf0 + gvo = tsizy*(gdx*sx0 + gdo) - f = ftsiz.Y * (xtex.d * sx0 + otex.d) / ((sx0 - sx1) * (sc0 - sf0)); - - 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; - } - - // Clip sprites to ceilings/floors when no parallaxing - if (!(tspr->sectp->ceilingstat & CSTAT_SECTOR_SKY)) - { - if (tspr->sectp->ceilingz > pos.Z - (float)((tspr->yrepeat * tsiz.Y) << 2)) - { - sc0 = (float)(tspr->sectp->ceilingz - globalposz) * ryp0 + ghoriz; - sc1 = (float)(tspr->sectp->ceilingz - globalposz) * ryp1 + ghoriz; - } - } - if (!(tspr->sectp->floorstat & CSTAT_SECTOR_SKY)) - { - if (tspr->sectp->floorz < pos.Z) - { - sf0 = (float)(tspr->sectp->floorz - globalposz) * ryp0 + ghoriz; - sf1 = (float)(tspr->sectp->floorz - globalposz) * ryp1 + ghoriz; - } - } - - if (sx0 > sx1) - { - if (globalorientation & 64) - goto _drawsprite_return; // 1-sided sprite - - std::swap(sx0, sx1); - std::swap(sc0, sc1); - std::swap(sf0, sf1); - } - - FVector2 const pxy[4] = { { sx0, sc0 }, { sx1, sc1 }, { sx1, sf1 }, { sx0, sf0 } }; - - vec2_16_t tempsiz = { (int16_t)tsiz.X, (int16_t)tsiz.Y }; - pow2xsplit = 0; - polymost_drawpoly(pxy, 4, method, tempsiz); - - drawpoly_srepeat = 0; - drawpoly_trepeat = 0; - } - break; - - case 2: // Floor sprite - GLInterface.SetVisibility(sectorVisibility(tspr->sectp) * (4.f/5.f)); // No idea why this uses a different visibility setting... - - if ((globalorientation & 64) != 0 - && (globalposz > tspriteGetZOfSlope(tspr, globalposx, globalposy)) == (!(globalorientation & 8))) - goto _drawsprite_return; - else - { - int16_t const heinum = tspriteGetSlope(tspr); - float const fheinum = heinum * (1.f / 4096.f); - float ratio = 1.f / sqrtf(fheinum * fheinum + 1.f); - - if ((globalorientation & 4) > 0) - off.X = -off.X; - if ((globalorientation & 8) > 0) - off.Y = -off.Y; - - FVector2 const p0 = { (float)(((tsiz.X + 1) >> 1) - off.X) * tspr->xrepeat, - (float)(((tsiz.Y + 1) >> 1) - off.Y) * tspr->yrepeat * ratio }, - p1 = { (float)((tsiz.X >> 1) + off.X) * tspr->xrepeat, - (float)((tsiz.Y >> 1) + off.Y) * tspr->yrepeat * ratio }; - - float const c = bcosf(tspr->ang, -16); - float const s = bsinf(tspr->ang, -16); - - FVector3 pxy[6]; - - // Project 3D to 2D - for (intptr_t j = 0; j < 4; j++) - { - FVector2 s0 = { (float)(tspr->pos.X - globalposx), (float)(tspr->pos.Y - globalposy) }; - - 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; - } - - pxy[j] = { s0.Y * gcosang - s0.X * gsinang, s0.X * gcosang2 + s0.Y * gsinang2, - float(tspriteGetZOfSlopeFloat(tspr, s0.X + globalposx, s0.Y + globalposy)) }; - } - - if (tspriteGetZOfSlope(tspr, globalposx, globalposy) < globalposz) // if floor sprite is above you, reverse order of points - { - std::swap(pxy[0], pxy[1]); - std::swap(pxy[2], pxy[3]); - } - - // Clip to SCISDIST plane - int32_t npoints = 0; - FVector3 p2[6]; - - for (intptr_t i = 0, j = 1; i < 4; j = ((++i + 1) & 3)) - { - 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); - FVector3 const t = { (pxy[j].X - pxy[i].X) * f + pxy[i].X, - (pxy[j].Y - pxy[i].Y) * f + pxy[i].Y, - (pxy[j].Z - pxy[i].Z)* f + pxy[i].Z }; - p2[npoints++] = t; - } - } - - if (npoints < 3) - goto _drawsprite_return; - - // Project rotated 3D points to screen - - int fadjust = 0; - - if (heinum == 0) - { - // unfortunately, offsetting by only 1 isn't enough on most Android devices - if (pos.Z == sec->ceilingz || pos.Z == sec->ceilingz + 1) - pos.Z = sec->ceilingz + 2, fadjust = (tspr->ownerActor->GetIndex() & 31); - - if (pos.Z == sec->floorz || pos.Z == sec->floorz - 1) - pos.Z = sec->floorz - 2, fadjust = -((tspr->ownerActor->GetIndex() & 31)); - } - - FVector2 pxy2[6]; - double pfy[6]; - - for (intptr_t j = 0; j < npoints; j++) - { - float const ryp0 = 1.f / p2[j].Y; - float const fs = (float)(p2[j].Z - globalposz + fadjust) * gyxscale; - pxy2[j] = { ghalfx * p2[j].X * ryp0 + ghalfx, fs * ryp0 + ghoriz }; - pfy[j] = double(gyxscale * ryp0) + ghoriz; - } - - // gd? Copied from floor rendering code - - xtex.d = 0; - ytex.d = gxyaspect; - if (heinum == 0) - ytex.d /= (double)(pos.Z - globalposz + fadjust); - otex.d = -ghoriz * ytex.d; - - // copied&modified from relative alignment - FVector2 const vv = { (float)tspr->pos.X + s * p1.X + c * p1.Y, (float)tspr->pos.Y + s * p1.Y - c * p1.X }; - FVector2 ff = { -(p0.X + p1.X) * s, (p0.X + p1.X) * c }; - - float f = 1.f / sqrtf(ff.X * ff.X + ff.Y * ff.Y); - - ff.X *= f; - ff.Y *= f; - - float const ft[4] = { ((float)(globalposy - vv.Y)) * ff.Y + ((float)(globalposx - vv.X)) * ff.X, - ((float)(globalposx - vv.X)) * ff.Y - ((float)(globalposy - vv.Y)) * ff.X, - fsinglobalang * ff.Y + fcosglobalang * ff.X, - fsinglobalang * ff.X - fcosglobalang * ff.Y }; - - f = fviewingrange * -(1.f / (65536.f * 262144.f)); - xtex.u = (float)ft[3] * f; - xtex.v = (float)ft[2] * f; - 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) - { - xtex.u = ftsiz.X * xtex.d - xtex.u; - ytex.u = ftsiz.X * ytex.d - ytex.u; - otex.u = ftsiz.X * otex.d - otex.u; - } - - if (heinum != 0) - { - vec3d_t const duv[3] = { - { (pxy2[0].X * xtex.d + pfy[0] * ytex.d + otex.d), - (pxy2[0].X * xtex.u + pfy[0] * ytex.u + otex.u), - (pxy2[0].X * xtex.v + pfy[0] * ytex.v + otex.v) - }, - { (pxy2[1].X * xtex.d + pfy[1] * ytex.d + otex.d), - (pxy2[1].X * xtex.u + pfy[1] * ytex.u + otex.u), - (pxy2[1].X * xtex.v + pfy[1] * ytex.v + otex.v) - }, - { (pxy2[2].X * xtex.d + pfy[2] * ytex.d + otex.d), - (pxy2[2].X * xtex.u + pfy[2] * ytex.u + otex.u), - (pxy2[2].X * xtex.v + pfy[2] * ytex.v + otex.v) - } - }; - - FVector3 oxyz[2] = { { (float)(pxy2[1].Y - pxy2[2].Y), (float)(pxy2[2].Y - pxy2[0].Y), (float)(pxy2[0].Y - pxy2[1].Y) }, - { (float)(pxy2[2].X - pxy2[1].X), (float)(pxy2[0].X - pxy2[2].X), (float)(pxy2[1].X - pxy2[0].X) } }; - - float const r = 1.f / (oxyz[0].X * pxy2[0].X + oxyz[0].Y * pxy2[1].X + oxyz[0].Z * pxy2[2].X); - - 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; - - 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; - - otex.d = duv[0].d - pxy2[0].X * xtex.d - pxy2[0].Y * ytex.d; - otex.u = duv[0].u - pxy2[0].X * xtex.u - pxy2[0].Y * ytex.u; - otex.v = duv[0].v - pxy2[0].X * xtex.v - pxy2[0].Y * ytex.v; - - float const rr = sqrtf(fheinum * fheinum + 1.f); - xtex.v *= rr; ytex.v *= rr; otex.v *= rr; - } - - vec2_16_t tempsiz = { (int16_t)tsiz.X, (int16_t)tsiz.Y }; - pow2xsplit = 0; - - polymost_drawpoly(pxy2, npoints, method, tempsiz); - - drawpoly_srepeat = 0; - drawpoly_trepeat = 0; - } - - break; - - case 3: // Voxel sprite - break; - } - - actor->spr.cstat2 |= CSTAT2_SPRITE_MAPPED; - -_drawsprite_return: - ; -} - -////////////////////////////////// - -static_assert((int)RS_YFLIP == (int)HUDFLAG_FLIPPED); - - -} - -// -// preparemirror -// -void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t dawall, - int32_t* tposx, int32_t* tposy, fixed_t* tang) -{ - const int32_t x = wall[dawall].wall_int_pos().X, dx = wall[dawall].point2Wall()->wall_int_pos().X - x; - const int32_t y = wall[dawall].wall_int_pos().Y, dy = wall[dawall].point2Wall()->wall_int_pos().Y - y; - - const int32_t j = dx * dx + dy * dy; - if (j == 0) - return; - - int i = ((dax - x) * dx + (day - y) * dy) << 1; - - *tposx = (x << 1) + Scale(dx, i, j) - dax; - *tposy = (y << 1) + Scale(dy, i, j) - day; - *tang = ((bvectangbam(dx, dy).asq16() << 1) - daang) & 0x7FFFFFF; - - inpreparemirror = 1; - - Polymost::polymost_prepareMirror(dax, day, daz, daang, dahoriz, dawall); -} - - -// -// completemirror -// -void renderCompleteMirror(void) -{ - Polymost::polymost_completeMirror(); - inpreparemirror = 0; -} - -// -// drawrooms -// -EXTERN_CVAR(Int, gl_fogmode) - -int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, sectortype* dacursect, bool fromoutside) -{ - if (dacursect) return renderDrawRoomsQ16(daposx, daposy, daposz, daang, dahoriz, sectnum(dacursect), fromoutside); - return 0; -} - -int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, - fixed_t daang, fixed_t dahoriz, int dacursectnum, bool fromoutside) -{ - memset(pm_tsprite, 0, sizeof(pm_tsprite)); - pm_spritesortcnt = 0; - checkRotatedWalls(); - - // Update starting sector number (common to classic and Polymost). - // ADJUST_GLOBALCURSECTNUM. - if (!fromoutside) - { - int i = dacursectnum; - updatesector(daposx, daposy, &dacursectnum); - if (dacursectnum < 0) dacursectnum = i; - - // PK 20110123: I'm not sure what the line above is supposed to do, but 'i' - // *can* be negative, so let's just quit here in that case... - if (dacursectnum < 0) - return 0; - } - - set_globalpos(daposx, daposy, daposz); - Polymost::set_globalang(daang); - - gotsector.Zero(); - qglobalhoriz = MulScale(dahoriz, DivScale(xdimenscale, viewingrange, 16), 16) + IntToFixed(ydimen >> 1); - globalcursectnum = dacursectnum; - Polymost::polymost_drawrooms(); - return inpreparemirror; -} - -// UTILITY TYPES AND FUNCTIONS FOR DRAWMASKS OCCLUSION TREE -// typedef struct s_maskleaf -// { -// int32_t index; -// _point2d p1, p2; -// _equation maskeq, p1eq, p2eq; -// struct s_maskleaf* branch[MAXWALLSB]; -// int32_t drawing; -// } _maskleaf; -// -// _maskleaf maskleaves[MAXWALLSB]; - -// returns equation of a line given two points -static inline _equation equation(float const x1, float const y1, float const x2, float const y2) -{ - const float f = x2 - x1; - - // vertical - if (f == 0.f) - return { 1, 0, -x1 }; - else - { - float const ff = (y2 - y1) / f; - return { ff, -1, (y1 - (ff * x1)) }; - } -} - -static inline int32_t sameside(const _equation* eq, const FVector2* p1, const FVector2* p2) -{ - const float sign1 = (eq->a * p1->X) + (eq->b * p1->Y) + eq->c; - const float sign2 = (eq->a * p2->X) + (eq->b * p2->Y) + eq->c; - return (sign1 * sign2) > 0.f; -} - - -static inline int comparetsprites(int const k, int const l) -{ - if ((tspriteptr[k]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != (tspriteptr[l]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK)) - return (tspriteptr[k]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) - (tspriteptr[l]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK); - - if ((tspriteptr[k]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_WALL && tspriteptr[k]->ang != tspriteptr[l]->ang) - return tspriteptr[k]->ang - tspriteptr[l]->ang; - - if (tspriteptr[k]->statnum != tspriteptr[l]->statnum) - return tspriteptr[k]->statnum - tspriteptr[l]->statnum; - - if (!tspriteptr[k]->ownerActor || !tspriteptr[l]->ownerActor) return 0; // why are these getting dragged into here? - - if (tspriteptr[k]->pos.X == tspriteptr[l]->pos.X && - tspriteptr[k]->pos.Y == tspriteptr[l]->pos.Y && - tspriteptr[k]->pos.Z == tspriteptr[l]->pos.Z && - (tspriteptr[k]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == (tspriteptr[l]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) && - tspriteptr[k]->ownerActor != tspriteptr[l]->ownerActor) - return tspriteptr[k]->ownerActor->GetIndex() - tspriteptr[l]->ownerActor->GetIndex(); - - if (abs(spritesxyz[k].Z - globalposz) != abs(spritesxyz[l].Z - globalposz)) - return abs(spritesxyz[k].Z - globalposz) - abs(spritesxyz[l].Z - globalposz); - - return 0; -} - -static void sortsprites(int const start, int const end) -{ - int32_t i, gap, y, ys; - - if (start >= end) - return; - - gap = 1; while (gap < end - start) gap = (gap << 1) + 1; - for (gap >>= 1; gap > 0; gap >>= 1) //Sort sprite list - for (i = start; i < end - gap; i++) - for (intptr_t l = i; l >= start; l -= gap) - { - if (spritesxyz[l].Y <= spritesxyz[l + gap].Y) break; - std::swap(tspriteptr[l], tspriteptr[l + gap]); - std::swap(spritesxyz[l].X, spritesxyz[l + gap].X); - std::swap(spritesxyz[l].Y, spritesxyz[l + gap].Y); - } - - ys = spritesxyz[start].Y; i = start; - for (intptr_t j = start + 1; j <= end; j++) - { - if (j < end) - { - y = spritesxyz[j].Y; - if (y == ys) - continue; - - ys = y; - } - - if (j > i + 1) - { - for (intptr_t k = i; k < j; k++) - { - auto const s = tspriteptr[k]; - - spritesxyz[k].Z = s->pos.Z; - if ((s->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_FLOOR) - { - int32_t yoff = tileTopOffset(s->picnum) + s->yoffset; - int32_t yspan = (tileHeight(s->picnum) * s->yrepeat << 2); - - spritesxyz[k].Z -= (yoff * s->yrepeat) << 2; - - if (!(s->cstat & CSTAT_SPRITE_YCENTER)) - spritesxyz[k].Z -= (yspan >> 1); - if (abs(spritesxyz[k].Z - globalposz) < (yspan >> 1)) - spritesxyz[k].Z = globalposz; - } - } - - for (intptr_t k = i + 1; k < j; k++) - for (intptr_t l = i; l < k; l++) - if (comparetsprites(k, l) < 0) - { - std::swap(tspriteptr[k], tspriteptr[l]); - vec3_t tv3 = spritesxyz[k]; - spritesxyz[k] = spritesxyz[l]; - spritesxyz[l] = tv3; - } - } - i = j; - } -} - -static bool spriteIsModelOrVoxel(const tspritetype* tspr) -{ - if (!tspr->ownerActor || tspr->ownerActor->sprext.renderflags & SPREXT_NOTMD) - return false; - - if (hw_models) - { - auto& mdinfo = tile2model[Ptile2tile(tspr->picnum, tspr->pal)]; - if (mdinfo.modelid >= 0 && mdinfo.framenum >= 0) return true; - } - - auto slabalign = (tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_SLAB; - if (r_voxels && !slabalign && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) return true; - return (slabalign && voxmodels[tspr->picnum]); -} - - -// -// drawmasks -// -void renderDrawMasks(void) -{ -# define debugmask_add(dispidx, idx) do {} while (0) - int32_t i = pm_spritesortcnt - 1; - int32_t numSprites = pm_spritesortcnt; - - pm_spritesortcnt = 0; - int32_t back = i; - for (; i >= 0; --i) - { - if (Polymost::polymost_spriteHasTranslucency(&pm_tsprite[i])) - { - tspriteptr[pm_spritesortcnt] = &pm_tsprite[i]; - ++pm_spritesortcnt; - } - else - { - tspriteptr[back] = &pm_tsprite[i]; - --back; - } - } - - for (i = numSprites - 1; i >= 0; --i) - { - const int32_t xs = tspriteptr[i]->pos.X - globalposx, ys = tspriteptr[i]->pos.Y - globalposy; - const int32_t yp = DMulScale(xs, cosviewingrangeglobalang, ys, sinviewingrangeglobalang, 6); - const int32_t modelp = spriteIsModelOrVoxel(tspriteptr[i]); - - if (yp > (4 << 8)) - { - const int32_t xp = DMulScale(ys, cosglobalang, -xs, singlobalang, 6); - - if (MulScale(labs(xp + yp), xdimen, 24) >= yp) - goto killsprite; - - spritesxyz[i].X = Scale(xp + yp, xdimen << 7, yp); - } - else if ((tspriteptr[i]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == 0) - { - killsprite: - if (!modelp) - { - //Delete face sprite if on wrong side! - if (i >= pm_spritesortcnt) - { - --numSprites; - if (i != numSprites) - { - tspriteptr[i] = tspriteptr[numSprites]; - spritesxyz[i].X = spritesxyz[numSprites].X; - spritesxyz[i].Y = spritesxyz[numSprites].Y; - } - } - else - { - --numSprites; - --pm_spritesortcnt; - if (i != numSprites) - { - tspriteptr[i] = tspriteptr[pm_spritesortcnt]; - spritesxyz[i].X = spritesxyz[pm_spritesortcnt].X; - spritesxyz[i].Y = spritesxyz[pm_spritesortcnt].Y; - tspriteptr[pm_spritesortcnt] = tspriteptr[numSprites]; - spritesxyz[pm_spritesortcnt].X = spritesxyz[numSprites].X; - spritesxyz[pm_spritesortcnt].Y = spritesxyz[numSprites].Y; - } - } - continue; - } - } - spritesxyz[i].Y = yp; - } - - sortsprites(0, pm_spritesortcnt); - sortsprites(pm_spritesortcnt, numSprites); - renderBeginScene(); - - GLInterface.EnableBlend(false); - GLInterface.EnableAlphaTest(true); - GLInterface.SetDepthBias(-2, -256); - - if (pm_spritesortcnt < numSprites) - { - for (intptr_t spr = pm_spritesortcnt; spr < numSprites;) - { - int32_t py = spritesxyz[spr].Y; - int32_t pcstat = tspriteptr[spr]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK; - int32_t pangle = tspriteptr[spr]->ang; - int j = spr + 1; - if (!spriteIsModelOrVoxel(tspriteptr[spr])) - { - while (j < numSprites && py == spritesxyz[j].Y && pcstat == (tspriteptr[j]->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) && (pcstat != 16 || pangle == tspriteptr[j]->ang) - && !spriteIsModelOrVoxel(tspriteptr[j])) - { - j++; - } - } - if (j - spr == 1) - { - debugmask_add(spr | 32768, tspriteptr[spr]->owner); - Polymost::polymost_drawsprite(spr); - tspriteptr[spr] = NULL; - } - else - { - GLInterface.SetDepthMask(false); - - for (intptr_t k = j - 1; k >= spr; k--) - { - debugmask_add(k | 32768, tspriteptr[k]->owner); - Polymost::polymost_drawsprite(k); - } - - GLInterface.SetDepthMask(true); - - GLInterface.SetColorMask(false); - - for (intptr_t k = j - 1; k >= spr; k--) - { - Polymost::polymost_drawsprite(k); - tspriteptr[k] = NULL; - } - - GLInterface.SetColorMask(true); - - } - spr = j; - } - } - - int32_t numMaskWalls = maskwallcnt; - maskwallcnt = 0; - for (i = 0; i < numMaskWalls; i++) - { - if (Polymost::polymost_maskWallHasTranslucency(&wall[thewall[maskwall[i]]])) - { - maskwall[maskwallcnt] = maskwall[i]; - maskwallcnt++; - } - else - Polymost::polymost_drawmaskwall(i); - } - - GLInterface.EnableBlend(true); - GLInterface.EnableAlphaTest(true); - GLInterface.SetDepthMask(false); - - FVector2 pos; - - pos.X = fglobalposx; - pos.Y = fglobalposy; - - // CAUTION: maskwallcnt and spritesortcnt may be zero! - // Writing e.g. "while (maskwallcnt--)" is wrong! - while (maskwallcnt) - { - // PLAG: sorting stuff - const int32_t w = thewall[maskwall[maskwallcnt - 1]]; - - maskwallcnt--; - - FVector2 dot = { (float)wall[w].wall_int_pos().X, (float)wall[w].wall_int_pos().Y }; - FVector2 dot2 = { (float)wall[w].point2Wall()->wall_int_pos().X, (float)wall[w].point2Wall()->wall_int_pos().Y }; - FVector2 middle = { (dot.X + dot2.X) * .5f, (dot.Y + dot2.Y) * .5f }; - - _equation maskeq = equation(dot.X, dot.Y, dot2.X, dot2.Y); - _equation p1eq = equation(pos.X, pos.Y, dot.X, dot.Y); - _equation p2eq = equation(pos.X, pos.Y, dot2.X, dot2.Y); - - i = pm_spritesortcnt; - while (i) - { - i--; - if (tspriteptr[i] != NULL) - { - FVector2 spr; - auto const tspr = tspriteptr[i]; - - spr.X = (float)tspr->pos.X; - spr.Y = (float)tspr->pos.Y; - - if (!sameside(&maskeq, &spr, &pos)) - { - // Sprite and camera are on different sides of the - // masked wall. - - // Check if the sprite is inside the 'cone' given by - // the rays from the camera to the two wall-points. - const int32_t inleft = sameside(&p1eq, &middle, &spr); - const int32_t inright = sameside(&p2eq, &middle, &spr); - - int32_t ok = (inleft && inright); - - if (!ok) - { - // If not, check if any of the border points are... - vec2_t pp[4]; - int32_t numpts, jj; - - const _equation pineq = inleft ? p1eq : p2eq; - - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR) - { - numpts = 4; - GetFlatSpritePosition(tspr, tspr->pos.vec2, pp, nullptr); - } - else - { - const int32_t oang = tspr->ang; - numpts = 2; - - // Consider face sprites as wall sprites with camera ang. - // XXX: factor 4/5 needed? - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_WALL) - tspriteptr[i]->ang = globalang; - - GetWallSpritePosition(tspr, tspr->pos.vec2, pp); - - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_WALL) - tspriteptr[i]->ang = oang; - } - - for (jj = 0; jj < numpts; jj++) - { - spr.X = (float)pp[jj].X; - spr.Y = (float)pp[jj].Y; - - if (!sameside(&maskeq, &spr, &pos)) // behind the maskwall, - if ((sameside(&p1eq, &middle, &spr) && // inside the 'cone', - sameside(&p2eq, &middle, &spr)) - || !sameside(&pineq, &middle, &spr)) // or on the other outside. - { - ok = 1; - break; - } - } - } - - if (ok) - { - debugmask_add(i | 32768, tspr->owner); - Polymost::polymost_drawsprite(i); - - tspriteptr[i] = NULL; - } - } - } - } - - debugmask_add(maskwall[maskwallcnt], thewall[maskwall[maskwallcnt]]); - Polymost::polymost_drawmaskwall(maskwallcnt); - } - - while (pm_spritesortcnt) - { - --pm_spritesortcnt; - if (tspriteptr[pm_spritesortcnt] != NULL) - { - debugmask_add(i | 32768, tspriteptr[i]->owner); - Polymost::polymost_drawsprite(pm_spritesortcnt); - tspriteptr[pm_spritesortcnt] = NULL; - } - } - renderFinishScene(); - GLInterface.SetDepthMask(true); - GLInterface.SetDepthBias(0, 0); -} - - -// -// setrollangle -// -void renderSetRollAngle(float rolla) -{ - Polymost::gtang = rolla * BAngRadian; -} - -void videoSetCorrectedAspect() -{ - // In DOS the game world is displayed with an aspect of 1.28 instead 1.333, - // meaning we have to stretch it by a factor of 1.25 instead of 1.2 - // to get perfect squares - int32_t yx = (65536 * 5) / 4; - int32_t vr, y, x; - - x = xdim; - y = ydim; - - vr = DivScale(x * 3, y * 4, 16); - - renderSetAspect(vr, yx); -} - - -// -// setaspect -// -void renderSetAspect(int32_t daxrange, int32_t daaspect) -{ - if (daxrange == 65536) daxrange--; // This doesn't work correctly with 65536. All other values are fine. No idea where this is evaluated wrong. - viewingrange = daxrange; - viewingrangerecip = DivScale(1, daxrange, 32); - fviewingrange = (float)daxrange; - - yxaspect = daaspect; - xyaspect = DivScale(1, yxaspect, 32); - xdimenscale = Scale(xdimen, yxaspect, 320); - xdimscale = Scale(320, xyaspect, xdimen); -} - -//Draw voxel model as perfect cubes -int32_t polymost_voxdraw(voxmodel_t* m, tspritetype* const tspr, bool rotate) -{ - float f, g, k0, zoff; - - if ((intptr_t)m == (intptr_t)(-1)) // hackhackhack - return 0; - - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR) - return 0; - - if ((tspr->clipdist & TSPR_MDLROTATE) || rotate) - { - int myclock = (PlayClock << 3) + MulScale(4 << 3, pm_smoothratio, 16); - tspr->ang = (tspr->ang + myclock) & 2047; // will be applied in md3_vox_calcmat_common. - } - - - FVector3 m0 = { m->scale, m->scale, m->scale }; - FVector3 a0 = { 0, 0, m->zadd * m->scale }; - - k0 = m->bscale / 64.f; - f = (float)tspr->xrepeat * (256.f / 320.f) * k0; - if ((tspr->ownerActor->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_WALL) - { - f *= 1.25f; - a0.Y -= tspr->xoffset * bcosf(tspr->ownerActor->sprext.angoff, -20); - a0.X += tspr->xoffset * bsinf(tspr->ownerActor->sprext.angoff, -20); - } - - if (globalorientation & 8) { m0.Z = -m0.Z; a0.Z = -a0.Z; } //y-flipping - if (globalorientation & 4) { m0.X = -m0.X; a0.X = -a0.X; a0.Y = -a0.Y; } //x-flipping - - m0.X *= f; a0.X *= f; f = -f; - m0.Y *= f; a0.Y *= f; - f = (float)tspr->yrepeat * k0; - m0.Z *= f; a0.Z *= f; - - k0 = (float)(tspr->pos.Z + tspr->ownerActor->sprext.position_offset.Z); - f = ((globalorientation & 8) && (tspr->ownerActor->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != 0) ? -4.f : 4.f; - k0 -= (tspr->yoffset * tspr->yrepeat) * f * m->bscale; - zoff = m->siz.Z * .5f; - if (!(tspr->cstat & CSTAT_SPRITE_YCENTER)) - zoff += m->piv.Z; - else if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != 48) - { - zoff += m->piv.Z; - zoff -= m->siz.Z * .5f; - } - if (globalorientation & 8) zoff = m->siz.Z - zoff; - - f = (65536.f * 512.f) / ((float)xdimen * viewingrange); - g = 32.f / ((float)xdimen * Polymost::gxyaspect); - - int const shadowHack = !!(tspr->clipdist & TSPR_FLAGS_MDHACK); - - m0.Y *= f; a0.Y = (((float)(tspr->pos.X + tspr->ownerActor->sprext.position_offset.X - globalposx)) * (1.f / 1024.f) + a0.Y) * f; - m0.X *= -f; a0.X = (((float)(tspr->pos.Y + tspr->ownerActor->sprext.position_offset.Y - globalposy)) * -(1.f / 1024.f) + a0.X) * -f; - m0.Z *= g; a0.Z = (((float)(k0 - globalposz - shadowHack)) * -(1.f / 16384.f) + a0.Z) * g; - - float mat[16]; - md3_vox_calcmat_common(tspr, &a0, f, mat); - - //Mirrors - if (Polymost::grhalfxdown10x < 0) - { - mat[0] = -mat[0]; - mat[4] = -mat[4]; - mat[8] = -mat[8]; - mat[12] = -mat[12]; - } - - if (shadowHack) - { - GLInterface.SetDepthFunc(DF_LEqual); - } - - - int winding = ((Polymost::grhalfxdown10x >= 0) ^ ((globalorientation & 8) != 0) ^ ((globalorientation & 4) != 0)) ? Winding_CW : Winding_CCW; - GLInterface.SetCull(Cull_Back, winding); - - float pc[4]; - - pc[0] = pc[1] = pc[2] = 1.f; - - - if (!shadowHack) - { - pc[3] = (tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) ? glblend[tspr->blend].def[!!(tspr->cstat & CSTAT_SPRITE_TRANS_FLIP)].alpha : 1.0f; - pc[3] *= 1.0f - tspr->ownerActor->sprext.alpha; - - SetRenderStyleFromBlend(!!(tspr->cstat & CSTAT_SPRITE_TRANSLUCENT), tspr->blend, !!(tspr->cstat & CSTAT_SPRITE_TRANS_FLIP)); - - if (!(tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || tspr->ownerActor->sprext.alpha > 0.f || pc[3] < 1.0f) - GLInterface.EnableBlend(true); // else GLInterface.EnableBlend(false); - } - else pc[3] = 1.f; - GLInterface.SetShade(max(0, globalshade), numshades); - //------------ - - //transform to Build coords - float omat[16]; - memcpy(omat, mat, sizeof(omat)); - - f = 1.f / 64.f; - g = m0.X * f; mat[0] *= g; mat[1] *= g; mat[2] *= g; - g = m0.Y * f; mat[4] = omat[8] * g; mat[5] = omat[9] * g; mat[6] = omat[10] * g; - g = -m0.Z * f; mat[8] = omat[4] * g; mat[9] = omat[5] * g; mat[10] = omat[6] * g; - // - mat[12] -= (m->piv.X * mat[0] + m->piv.Y * mat[4] + zoff * mat[8]); - mat[13] -= (m->piv.X * mat[1] + m->piv.Y * mat[5] + zoff * mat[9]); - mat[14] -= (m->piv.X * mat[2] + m->piv.Y * mat[6] + zoff * mat[10]); - // - //Let OpenGL (and perhaps hardware :) handle the matrix rotation - mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; - - for (int i = 0; i < 15; i++) mat[i] *= 1024.f; - - // Adjust to backend coordinate system being used by the vertex buffer. - for (int i = 4; i < 8; i++) - { - float val = mat[i]; - mat[i] = -mat[i + 4]; - mat[i + 4] = -val; - } - - GLInterface.SetMatrix(Matrix_Model, mat); - - GLInterface.SetPalswap(globalpal); - GLInterface.SetFade(tspr->sectp->floorpal); - - auto tex = TexMan.GetGameTexture(m->model->GetPaletteTexture()); - GLInterface.SetTexture(tex, TRANSLATION(Translation_Remap + curbasepal, globalpal), CLAMP_NOFILTER_XY, true); - GLInterface.SetModel(m->model, 0, 0, 0); - - // 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); - - bool trans = (tspr->cstat & CSTAT_SPRITE_TRANSLUCENT); - float alpha; - FRenderStyle RenderStyle; - if (trans) - { - RenderStyle = GetRenderStyle(0, !!(tspr->cstat & CSTAT_SPRITE_TRANS_FLIP)); - alpha = GetAlphaFromBlend((tspr->cstat & CSTAT_SPRITE_TRANS_FLIP) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0); - } - else - { - RenderStyle = LegacyRenderStyles[STYLE_Translucent]; - alpha = 1.f; - } - alpha *= 1.f - tspr->ownerActor->sprext.alpha; - GLInterface.SetRenderStyle(RenderStyle); - GLInterface.SetColor(pc[0], pc[1], pc[2], alpha); - - GLInterface.Draw(DT_Triangles, 0, 0); - GLInterface.SetModel(nullptr, 0, 0, 0); - GLInterface.SetCull(Cull_None); - - if (shadowHack) - { - GLInterface.SetDepthFunc(DF_Less); - } - GLInterface.SetIdentityMatrix(Matrix_Model); - return 1; -} - - diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 5a6207dde..8558b7ec5 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -55,7 +55,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "v_text.h" #include "resourcefile.h" #include "c_dispatch.h" -#include "glbackend/glbackend.h" #include "engineerrors.h" #include "gamestate.h" #include "gstrings.h" @@ -82,6 +81,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "wipe.h" #include "findfile.h" #include "version.h" +#include "hw_material.h" void LoadHexFont(const char* filename); @@ -1130,7 +1130,6 @@ int RunGame() setVideoMode(); LoadVoxelModels(); - GLInterface.Init(screen->GetWidth()); screen->BeginFrame(); screen->SetTextureFilterMode(); setViewport(hud_size); diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 70bc47ed9..086f47078 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -77,7 +77,6 @@ #include "c_console.h" #include "uiinput.h" #include "v_video.h" -#include "glbackend/glbackend.h" #include "palette.h" #include "build.h" #include "g_input.h" @@ -397,7 +396,6 @@ void DrawOverlays() // Display // //========================================================================== -EXTERN_CVAR(Bool, vid_renderer); void Display() { @@ -442,7 +440,6 @@ void Display() screen->SetSceneRenderTarget(gl_ssao != 0); updateModelInterpolation(); gi->Render(); - if (vid_renderer == 0) videoShowFrame(); DrawFullscreenBlends(); drawMapTitle(); break; diff --git a/source/core/palette.cpp b/source/core/palette.cpp index 676c164a4..5729c4714 100644 --- a/source/core/palette.cpp +++ b/source/core/palette.cpp @@ -45,7 +45,6 @@ #include "v_font.h" #include "printf.h" #include "v_draw.h" -#include "../../glbackend/glbackend.h" LookupTableInfo lookups; int numshades; @@ -419,6 +418,7 @@ void LookupTableInfo::setPaletteTint(int palnum, int r, int g, int b, int sr, in #include "v_2ddrawer.h" uint8_t curbasepal; +int32_t r_scenebrightness; PalEntry palfadergb; static int32_t tint_blood_r = 0, tint_blood_g = 0, tint_blood_b = 0; glblend_t glblend[MAXBLENDTABS]; @@ -462,17 +462,6 @@ FRenderStyle GetRenderStyle(int blend, int def) return rs; } -void SetRenderStyleFromBlend(uint8_t enable, uint8_t blend, uint8_t def) -{ - if (!enable) - { - GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); - return; - } - auto rs = GetRenderStyle(blend, def); - GLInterface.SetRenderStyle(rs); -} - float GetAlphaFromBlend(uint32_t method, uint32_t blend) { return method == DAMETH_TRANS1 || method == DAMETH_TRANS2 ? glblend[blend].def[method - DAMETH_TRANS1].alpha : 1.f; diff --git a/source/core/palette.h b/source/core/palette.h index b7e173841..cd36c99e4 100644 --- a/source/core/palette.h +++ b/source/core/palette.h @@ -188,8 +188,12 @@ struct glblend_t extern glblend_t const nullglblend, defaultglblend; extern glblend_t glblend[MAXBLENDTABS]; +enum { + DAMETH_TRANS1 = 2, + DAMETH_TRANS2 = 3, +}; + FRenderStyle GetRenderStyle(int blend, int def); -extern void SetRenderStyleFromBlend(uint8_t enable, uint8_t blend, uint8_t def); float GetAlphaFromBlend(uint32_t maskprops, uint32_t blend); void DrawFullscreenBlends(); diff --git a/source/core/rendering/hw_entrypoint.cpp b/source/core/rendering/hw_entrypoint.cpp index 9985dde1a..86949a14c 100644 --- a/source/core/rendering/hw_entrypoint.cpp +++ b/source/core/rendering/hw_entrypoint.cpp @@ -59,6 +59,15 @@ float GlobalFogDensity = 350.f; TArray allPortals; void Draw2D(F2DDrawer* drawer, FRenderState& state); +CVARD(Bool, hw_hightile, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable hightile texture rendering") +bool hw_int_useindexedcolortextures; +CUSTOM_CVARD(Bool, hw_useindexedcolortextures, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable indexed color texture rendering") +{ + if (screen) screen->SetTextureFilterMode(); +} +CVARD(Bool, hw_models, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable model rendering") + + #if 0 void CollectLights(FLevelLocals* Level) @@ -230,15 +239,9 @@ bool writingsavepic; FileWriter* savefile; int savewidth, saveheight; void PM_WriteSavePic(FileWriter* file, int width, int height); -EXTERN_CVAR(Bool, vid_renderer); void WriteSavePic(FileWriter* file, int width, int height) { - if (!vid_renderer) - { - PM_WriteSavePic(file, width, height); - return; - } int oldx = xdim; int oldy = ydim; auto oldwindowxy1 = windowxy1; diff --git a/source/core/rendering/scene/hw_drawlistadd.cpp b/source/core/rendering/scene/hw_drawlistadd.cpp index c050920b4..b7e2315b6 100644 --- a/source/core/rendering/scene/hw_drawlistadd.cpp +++ b/source/core/rendering/scene/hw_drawlistadd.cpp @@ -27,7 +27,6 @@ #include "hw_drawinfo.h" #include "hw_material.h" #include "build.h" -#include "polymost.h" #include "gamefuncs.h" EXTERN_CVAR(Bool, gl_seamless) diff --git a/source/core/rendering/scene/hw_walls.cpp b/source/core/rendering/scene/hw_walls.cpp index a4144a36d..fc636cc80 100644 --- a/source/core/rendering/scene/hw_walls.cpp +++ b/source/core/rendering/scene/hw_walls.cpp @@ -38,7 +38,6 @@ #include "v_video.h" #include "flatvertices.h" -#include "glbackend/glbackend.h" DCoreActor* wall_to_sprite_actors[8]; // gets updated each frame. Todo: Encapsulate this better without having to permanently store actors in the wall object. diff --git a/source/core/screenshot.cpp b/source/core/screenshot.cpp index f49b0f0c8..e8dc8d164 100644 --- a/source/core/screenshot.cpp +++ b/source/core/screenshot.cpp @@ -41,8 +41,6 @@ #include "c_dispatch.h" #include "v_video.h" -#include "../../glbackend/glbackend.h" - EXTERN_CVAR(Float, png_gamma) // // screencapture diff --git a/source/core/zcc_compile_raze.cpp b/source/core/zcc_compile_raze.cpp index f31170d23..9926cf312 100644 --- a/source/core/zcc_compile_raze.cpp +++ b/source/core/zcc_compile_raze.cpp @@ -241,7 +241,7 @@ void ZCCRazeCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *pr const char * p = prop->params; auto exp = property->Values; - FCompileContext ctx(OutNamespace, bag.Info->VMType, false); + FCompileContext ctx(OutNamespace, bag.Info->VMType, false, mVersion); while (true) { FPropParam conv; @@ -422,7 +422,7 @@ void ZCCRazeCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt * } auto exp = property->Values; - FCompileContext ctx(OutNamespace, bag.Info->VMType, false); + FCompileContext ctx(OutNamespace, bag.Info->VMType, false, mVersion); for (auto f : prop->Variables) { void *addr; diff --git a/source/games/blood/all.cpp b/source/games/blood/all.cpp index 46e731887..2c86a79a2 100644 --- a/source/games/blood/all.cpp +++ b/source/games/blood/all.cpp @@ -66,8 +66,6 @@ #include "src/warp.cpp" #include "src/weapon.cpp" -#include "src/_polymost.cpp" - // This includes the VM so it is last #include "src/d_menu.cpp" diff --git a/source/games/blood/src/_polymost.cpp b/source/games/blood/src/_polymost.cpp deleted file mode 100644 index a8952c129..000000000 --- a/source/games/blood/src/_polymost.cpp +++ /dev/null @@ -1,358 +0,0 @@ -#include "polymost.h" - -BEGIN_BLD_NS - - -// leftover bits needed to keep Polymost running through the transition. -// This is mainly the game side part of the portal renderer. - -void collectTSpritesForPortal(int x, int y, int i, int interpolation) -{ - int nSector = mirror[i].link; - int nSector2 = mirror[i].wallnum; - BloodSectIterator it(nSector); - while (auto actor = it.Next()) - { - if (actor == gView->actor) - continue; - int top, bottom; - GetActorExtents(actor, &top, &bottom); - int zCeil, zFloor; - getzsofslopeptr(§or[nSector], actor->spr.pos.X, actor->spr.pos.Y, &zCeil, &zFloor); - if (actor->spr.statnum == kStatDude && (top < zCeil || bottom > zFloor)) - { - int j = i; - if (mirror[i].type == 2) - j++; - else - j--; - int dx = mirror[j].dx; - int dy = mirror[j].dy; - int dz = mirror[j].dz; - if (pm_spritesortcnt < MAXSPRITESONSCREEN) - { - tspritetype* pTSprite = &pm_tsprite[pm_spritesortcnt++]; - *pTSprite = {}; - pTSprite->type = actor->spr.type; - pTSprite->sectp = §or[nSector2]; - pTSprite->pos.X = actor->spr.pos.X + dx; - pTSprite->pos.Y = actor->spr.pos.Y + dy; - pTSprite->pos.Z = actor->spr.pos.Z + dz; - pTSprite->ang = actor->spr.ang; - pTSprite->picnum = actor->spr.picnum; - pTSprite->shade = actor->spr.shade; - pTSprite->pal = actor->spr.pal; - pTSprite->xrepeat = actor->spr.xrepeat; - pTSprite->yrepeat = actor->spr.yrepeat; - pTSprite->xoffset = actor->spr.xoffset; - pTSprite->yoffset = actor->spr.yoffset; - pTSprite->cstat = actor->spr.cstat; - pTSprite->statnum = kStatDecoration; - pTSprite->ownerActor = actor; - pTSprite->flags = actor->spr.hitag | 0x200; - pTSprite->pos.X = dx + interpolatedvalue(actor->opos.X, actor->spr.pos.X, interpolation); - pTSprite->pos.Y = dy + interpolatedvalue(actor->opos.Y, actor->spr.pos.Y, interpolation); - pTSprite->pos.Z = dz + interpolatedvalue(actor->opos.Z, actor->spr.pos.Z, interpolation); - pTSprite->ang = actor->interpolatedang(interpolation); - - int nAnim = 0; - switch (picanm[pTSprite->picnum].extra & 7) - { - case 1: - { - int dX = x - pTSprite->pos.X; - int dY = y - pTSprite->pos.Y; - RotateVector(&dX, &dY, 128 - pTSprite->ang); - nAnim = GetOctant(dX, dY); - if (nAnim <= 4) - { - pTSprite->cstat &= ~CSTAT_SPRITE_XFLIP; - } - else - { - nAnim = 8 - nAnim; - pTSprite->cstat |= CSTAT_SPRITE_XFLIP; - } - break; - } - case 2: - { - int dX = x - pTSprite->pos.X; - int dY = y - pTSprite->pos.Y; - RotateVector(&dX, &dY, 128 - pTSprite->ang); - nAnim = GetOctant(dX, dY); - break; - } - } - while (nAnim > 0) - { - pTSprite->picnum += picanm[pTSprite->picnum].num + 1; - nAnim--; - } - - pm_spritesortcnt++; - } - } - } - -} - -void processSpritesOnOtherSideOfPortal(int x, int y, int interpolation) -{ - if (pm_spritesortcnt == 0) return; - int nViewSprites = pm_spritesortcnt-1; - for (int nTSprite = nViewSprites; nTSprite >= 0; nTSprite--) - { - tspritetype *pTSprite = &pm_tsprite[nTSprite]; - pTSprite->xrepeat = pTSprite->yrepeat = 0; - } - for (int i = mirrorcnt-1; i >= 0; i--) - { - int nTile = 4080+i; - if (testgotpic(nTile)) - { - if (mirror[i].type == 1 || mirror[i].type == 2) - { - collectTSpritesForPortal(x, y, i, interpolation); - } - } - } -} - - -void render3DViewPolymost(int nSectnum, int cX, int cY, int cZ, binangle cA, fixedhoriz cH) -{ - videoSetCorrectedAspect(); - - int v1 = xs_CRoundToInt(double(viewingrange) * tan(r_fov * (pi::pi() / 360.))); - - renderSetAspect(v1, yxaspect); - -RORHACK: - bool ror_status[16]; - for (int i = 0; i < 16; i++) - ror_status[i] = testgotpic(4080 + i); - fixed_t deliriumPitchI = interpolatedvalue(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate); - DrawMirrors(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, int(gInterpolate), gViewIndex); - auto bakCstat = gView->actor->spr.cstat; - if (gViewPos == 0) - { - gView->actor->spr.cstat |= CSTAT_SPRITE_INVISIBLE; - } - else - { - gView->actor->spr.cstat |= CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANS_FLIP; - } - - renderDrawRoomsQ16(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, nSectnum, false); - viewProcessSprites(pm_tsprite, pm_spritesortcnt, cX, cY, cZ, cA.asbuild(), int(gInterpolate)); - bool do_ror_hack = false; - for (int i = 0; i < 16; i++) - if (ror_status[i] != testgotpic(4080 + i)) - do_ror_hack = true; - if (do_ror_hack) - { - gView->actor->spr.cstat = bakCstat; - pm_spritesortcnt = 0; - goto RORHACK; - } - setPortalFlags(1); - int nSpriteSortCnt = pm_spritesortcnt; - renderDrawMasks(); - pm_spritesortcnt = nSpriteSortCnt; - setPortalFlags(0); - processSpritesOnOtherSideOfPortal(cX, cY, int(gInterpolate)); - renderDrawMasks(); - gView->actor->spr.cstat = bakCstat; - -} - -// hack the portal planes with the sky flag for rendering. Only Polymost needs this hack. -void setPortalFlags(int mode) -{ - for (int i = mirrorcnt - 1; i >= 0; i--) - { - int nTile = 4080 + i; - if (testgotpic(nTile)) - { - switch (mirror[i].type) - { - case 1: - if (mode) - sector[mirror[i].wallnum].ceilingstat |= CSTAT_SECTOR_SKY; - else - sector[mirror[i].wallnum].ceilingstat &= ~CSTAT_SECTOR_SKY; - break; - case 2: - if (mode) - sector[mirror[i].wallnum].floorstat |= CSTAT_SECTOR_SKY; - else - sector[mirror[i].wallnum].floorstat &= ~CSTAT_SECTOR_SKY; - break; - } - } - } -} - -// Note: debug range checks on wall [] need to be disabled because this deliberately writes beyond the regular part. - -void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer) -{ - auto wallarr = wall.Data(); // this disables the range checks for the wall TArray, - for (int i = mirrorcnt - 1; i >= 0; i--) - { - int nTile = 4080 + i; - if (testgotpic(nTile, true)) - { - switch (mirror[i].type) - { - case 0: - { - // gross hack alert. Blood adds some dummy walls and sectors that must not be among the counted, but here they have to be valid. - wall.Reserve(4); - sector.Reserve(1); - int nWall = mirror[i].link; - walltype* pWall = &wall[nWall]; - int nSector = pWall->sector; - int nNextWall = pWall->nextwall; - int nNextSector = pWall->nextsector; - pWall->nextwall = mirrorwall[0]; - pWall->nextsector = mirrorsector; - wallarr[mirrorwall[0]].nextwall = nWall; - wallarr[mirrorwall[0]].nextsector = nSector; - wallarr[mirrorwall[0]].pos.X = pWall->point2Wall()->pos.X; - wallarr[mirrorwall[0]].pos.Y = pWall->point2Wall()->pos.Y; - wallarr[mirrorwall[1]].pos.X = pWall->pos.X; - wallarr[mirrorwall[1]].pos.Y = pWall->pos.Y; - wallarr[mirrorwall[2]].pos.X = wallarr[mirrorwall[1]].pos.X + (wallarr[mirrorwall[1]].pos.X - wallarr[mirrorwall[0]].pos.X) * 16; - wallarr[mirrorwall[2]].pos.Y = wallarr[mirrorwall[1]].pos.Y + (wallarr[mirrorwall[1]].pos.Y - wallarr[mirrorwall[0]].pos.Y) * 16; - wallarr[mirrorwall[3]].pos.X = wallarr[mirrorwall[0]].pos.X + (wallarr[mirrorwall[0]].pos.X - wallarr[mirrorwall[1]].pos.X) * 16; - wallarr[mirrorwall[3]].pos.Y = wallarr[mirrorwall[0]].pos.Y + (wallarr[mirrorwall[0]].pos.Y - wallarr[mirrorwall[1]].pos.Y) * 16; - sector.Data()[mirrorsector].setfloorz(sector[nSector].floorz, true); - sector.Data()[mirrorsector].setceilingz(sector[nSector].ceilingz, true); - int cx, cy, ca; - if (pWall->type == kWallStack) - { - cx = x - (wall[pWall->hitag].wall_int_pos().X - pWall->point2Wall()->wall_int_pos().X); - cy = y - (wall[pWall->hitag].wall_int_pos().Y - pWall->point2Wall()->wall_int_pos().Y); - ca = a; - } - else - { - renderPrepareMirror(x, y, z, a, horiz, nWall, &cx, &cy, &ca); - } - renderDrawRoomsQ16(cx, cy, z, ca, horiz, mirrorsector, true); - viewProcessSprites(pm_tsprite, pm_spritesortcnt, cx, cy, z, FixedToInt(ca), smooth); - renderDrawMasks(); - if (pWall->type != kWallStack) - renderCompleteMirror(); - pWall->nextwall = nNextWall; - pWall->nextsector = nNextSector; - wall.Clamp(wall.Size() - 4); - sector.Clamp(sector.Size() - 1); - - return; - } - case 1: - { - r_rorphase = 1; - int nSector = mirror[i].link; - ESpriteFlags bakCstat = 0; - if (viewPlayer >= 0) - { - bakCstat = gPlayer[viewPlayer].actor->spr.cstat; - if (gViewPos == 0) - { - gPlayer[viewPlayer].actor->spr.cstat |= CSTAT_SPRITE_INVISIBLE; - } - else - { - gPlayer[viewPlayer].actor->spr.cstat |= CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANS_FLIP; - } - } - renderDrawRoomsQ16(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, a, horiz, nSector, true); - viewProcessSprites(pm_tsprite, pm_spritesortcnt, x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, FixedToInt(a), smooth); - auto fstat = sector[nSector].floorstat; - sector[nSector].floorstat |= CSTAT_SECTOR_SKY; - renderDrawMasks(); - sector[nSector].floorstat = fstat; - for (int ii = 0; ii < 16; ii++) - gotpic.Clear(4080 + ii); - if (viewPlayer >= 0) - { - gPlayer[viewPlayer].actor->spr.cstat = bakCstat; - } - r_rorphase = 0; - return; - } - case 2: - { - r_rorphase = 1; - int nSector = mirror[i].link; - ESpriteFlags bakCstat = 0; - if (viewPlayer >= 0) - { - bakCstat = gPlayer[viewPlayer].actor->spr.cstat; - if (gViewPos == 0) - { - gPlayer[viewPlayer].actor->spr.cstat |= CSTAT_SPRITE_INVISIBLE; - } - else - { - gPlayer[viewPlayer].actor->spr.cstat |= CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANS_FLIP; - } - } - renderDrawRoomsQ16(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, a, horiz, nSector, true); - viewProcessSprites(pm_tsprite, pm_spritesortcnt, x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, FixedToInt(a), smooth); - auto cstat = sector[nSector].ceilingstat; - sector[nSector].ceilingstat |= CSTAT_SECTOR_SKY; - renderDrawMasks(); - sector[nSector].ceilingstat = cstat; - for (int ii = 0; ii < 16; ii++) - gotpic.Clear(4080 + ii); - if (viewPlayer >= 0) - { - gPlayer[viewPlayer].actor->spr.cstat = bakCstat; - } - r_rorphase = 0; - return; - } - } - } - } -} - - -void InitPolymostMirrorHack() -{ - mirrorsector = sector.Size(); - for (int i = 0; i < 4; i++) - { - mirrorwall[i] = wall.Size() + i; - auto pWall = &(wall.Data()[mirrorwall[i]]); - pWall->picnum = 504; - pWall->overpicnum = 504; - pWall->cstat = 0; - pWall->nextsector = -1; - pWall->nextwall = -1; - pWall->point2 = wall.Size() + i + 1; - } - wall.Data()[mirrorwall[3]].point2 = mirrorwall[0]; - sector.Data()[mirrorsector].ceilingpicnum = 504; - sector.Data()[mirrorsector].floorpicnum = 504; - sector.Data()[mirrorsector].wallptr = mirrorwall[0]; - sector.Data()[mirrorsector].wallnum = 4; -} - -void PolymostAllocFakeSector() -{ - // these additional entries are needed by Blood's mirror code. We must get them upon map load to avoid a later occuring reallocation. Ugh... - // We do not want to actually increase the array size for this, though because it may screw with the savegame code. - // Before rendering this will temporarily be bumped up. - // Note that this depends on the resize operation not deleting and altering the new entries! - sector.Reserve(1); - wall.Reserve(4); - wall.Clamp(wall.Size() - 4); - sector.Clamp(sector.Size() - 1); -} -END_BLD_NS diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index 885b39dc9..1e1a88766 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -38,7 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "v_font.h" #include "hw_voxels.h" #include "gamefuncs.h" -#include "glbackend/glbackend.h" BEGIN_BLD_NS diff --git a/source/games/blood/src/blood.h b/source/games/blood/src/blood.h index ffb5e7f9e..e845542e0 100644 --- a/source/games/blood/src/blood.h +++ b/source/games/blood/src/blood.h @@ -96,12 +96,6 @@ struct MIRROR extern MIRROR mirror[16]; extern int mirrorcnt, mirrorsector, mirrorwall[4]; -//polymost needs to do some voodoo for mirrors. -void InitPolymostMirrorHack(); -void PolymostAllocFakeSector(); - - - inline bool DemoRecordStatus(void) { return false; diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 7075edc12..fbed7748e 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -218,9 +218,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, int* } gMapRev = mapHeader.revision; allocateMapArrays(mapHeader.numwalls, mapHeader.numsectors, mapHeader.numsprites); -#if 1 // bad, bad hack, just for making Polymost happy... - PolymostAllocFakeSector(); -#endif *cursectnum = mapHeader.sect; if (encrypted) diff --git a/source/games/blood/src/mirrors.cpp b/source/games/blood/src/mirrors.cpp index a0d368a52..a4c3ec555 100644 --- a/source/games/blood/src/mirrors.cpp +++ b/source/games/blood/src/mirrors.cpp @@ -43,9 +43,6 @@ MIRROR mirror[16]; // only needed by Polymost. void InitMirrors(void) { - r_rortexture = 4080; - r_rortexturerange = 16; - mirrorcnt = 0; tileDelete(504); portalClear(); @@ -154,7 +151,6 @@ void InitMirrors(void) } mirrorsector = sector.Size(); mergePortals(); - InitPolymostMirrorHack(); } //--------------------------------------------------------------------------- @@ -198,14 +194,10 @@ void SerializeMirrors(FSerializer& arc) tileDelete(504); - r_rortexture = 4080; - r_rortexturerange = 16; - for (int i = 0; i < 16; i++) { tileDelete(4080 + i); } - InitPolymostMirrorHack(); } } diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp index 3464a043f..56e81c0be 100644 --- a/source/games/blood/src/view.cpp +++ b/source/games/blood/src/view.cpp @@ -45,7 +45,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "razefont.h" -EXTERN_CVAR(Bool, vid_renderer) BEGIN_BLD_NS VIEW gPrevView[kMaxPlayers]; @@ -655,7 +654,6 @@ void viewDrawScreen(bool sceneonly) gInterpolate = !cl_interpolate || cl_capfps ? MaxSmoothRatio : I_GetTimeFrac() * MaxSmoothRatio; } else gInterpolate = MaxSmoothRatio; - pm_smoothratio = (int)gInterpolate; if (cl_interpolate) { @@ -766,21 +764,12 @@ void viewDrawScreen(bool sceneonly) } } - if (vid_renderer) - { - if (!sceneonly) hudDraw(gView, pSector, shakeX, shakeY, zDelta, basepal, gInterpolate); - fixedhoriz deliriumPitchI = q16horiz(interpolatedvalue(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate)); - auto bakCstat = gView->actor->spr.cstat; - gView->actor->spr.cstat |= (gViewPos == 0) ? CSTAT_SPRITE_INVISIBLE : CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANS_FLIP; - render_drawrooms(gView->actor, { cX, cY, cZ }, sectnum(pSector), cA, cH + deliriumPitchI, rotscrnang, gInterpolate); - gView->actor->spr.cstat = bakCstat; - } - else - { - renderSetRollAngle((float)rotscrnang.asbuildf()); - render3DViewPolymost(sectnum(pSector), cX, cY, cZ, cA, cH); - if (!sceneonly) hudDraw(gView, pSector, shakeX, shakeY, zDelta, basepal, gInterpolate); - } + if (!sceneonly) hudDraw(gView, pSector, shakeX, shakeY, zDelta, basepal, gInterpolate); + fixedhoriz deliriumPitchI = q16horiz(interpolatedvalue(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate)); + auto bakCstat = gView->actor->spr.cstat; + gView->actor->spr.cstat |= (gViewPos == 0) ? CSTAT_SPRITE_INVISIBLE : CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANS_FLIP; + render_drawrooms(gView->actor, { cX, cY, cZ }, sectnum(pSector), cA, cH + deliriumPitchI, rotscrnang, gInterpolate); + gView->actor->spr.cstat = bakCstat; bDeliriumOld = bDelirium && gDeliriumBlur; int nClipDist = gView->actor->spr.clipdist << 2; diff --git a/source/games/duke/src/_polymost.cpp b/source/games/duke/src/_polymost.cpp deleted file mode 100644 index 10edfdd6e..000000000 --- a/source/games/duke/src/_polymost.cpp +++ /dev/null @@ -1,274 +0,0 @@ -BEGIN_DUKE_NS - -void SE40_Draw(int tag, spritetype *spr, int x, int y, int z, binangle a, fixedhoriz h, int smoothratio) -{ - int i, k = 0; - int ok = 0, fofmode = 0; - int offx, offy; - spritetype* floor1, *floor2 = nullptr; - - if (spr->ang != 512) return; - - i = FOF; //Effect TILE - tileDelete(FOF); - if (!testgotpic(FOF, true)) return; - - floor1 = spr; - - if (spr->lotag == tag + 2) fofmode = tag + 0; - if (spr->lotag == tag + 3) fofmode = tag + 1; - if (spr->lotag == tag + 4) fofmode = tag + 0; - if (spr->lotag == tag + 5) fofmode = tag + 1; - - ok++; - - DukeStatIterator it(STAT_RAROR); - while (auto act = it.Next()) - { - if ( - act->spr.picnum == SECTOREFFECTOR && - act->spr.lotag == fofmode && - act->spr.hitag == floor1->hitag - ) - { - floor1 = spr; - fofmode = act->spr.lotag; - ok++; - break; - } - } - // if(ok==1) { Message("no floor1",RED); return; } - - if (fofmode == tag + 0) k = tag + 1; else k = tag + 0; - - it.Reset(STAT_RAROR); - while (auto act = it.Next()) - { - if ( - act->spr.picnum == SECTOREFFECTOR && - act->spr.lotag == k && - act->spr.hitag == floor1->hitag - ) - { - floor2 = spr; - ok++; - break; - } - } - - // if(ok==2) { Message("no floor2",RED); return; } - - it.Reset(STAT_RAROR); - while (auto act = it.Next()) - { - if (act->spr.picnum == SECTOREFFECTOR && - act->spr.lotag == k + 2 && - act->spr.hitag == floor1->hitag - ) - { - auto sect = act->sector(); - // repurpose otherwise unused fields in sectortype as temporary storage. - if (k == tag + 0) - { - sect->Flag = sect->floorz; - sect->addfloorz((((z - sect->floorz) / 32768) + 1) * 32768, true); - sect->Damage = sect->floorpicnum; - sect->floorpicnum = 13; - } - if (k == tag + 1) - { - sect->Flag = sect->ceilingz; - sect->addceilingz((((z - sect->ceilingz) / 32768) - 1) * 32768, true); - sect->Damage = sect->ceilingpicnum; - sect->ceilingpicnum = 13; - } - } - } - - offx = x - floor1->pos.X; - offy = y - floor1->pos.Y; - - renderDrawRoomsQ16(floor2->pos.X + offx, floor2->pos.Y + offy, z, a.asq16(), h.asq16(), floor2->sectp, false); - fi.animatesprites(pm_tsprite, pm_spritesortcnt, offx + floor2->pos.X, offy + floor2->pos.Y, a.asbuild(), smoothratio); - renderDrawMasks(); - - it.Reset(STAT_RAROR); - while (auto act = it.Next()) - { - if (act->spr.picnum == 1 && - act->spr.lotag == k + 2 && - act->spr.hitag == floor1->hitag - ) - { - auto sect = act->sector(); - if (k == tag + 0) - { - sect->setfloorz(sect->Flag, true); - sect->floorpicnum = sect->Damage; - } - if (k == tag + 1) - { - sect->setceilingz(sect->Flag, true); - sect->ceilingpicnum = sect->Damage; - } - }// end if - }// end for - -} // end SE40 - - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void se40code(int x, int y, int z, binangle a, fixedhoriz h, int smoothratio) -{ - int tag; - if (!isRR()) tag = 40; - else if (isRRRA()) tag = 150; - else return; - - DukeStatIterator it(STAT_RAROR); - while (auto act = it.Next()) - { - switch (act->spr.lotag - tag + 40) - { - //case 40: - //case 41: - // SE40_Draw(i,x,y,a,smoothratio); - // break; - case 42: - case 43: - case 44: - case 45: - if (ps[screenpeek].cursector == act->sector()) - SE40_Draw(tag, &act->spr, x, y, z, a, h, smoothratio); - break; - } - } -} - - -//--------------------------------------------------------------------------- -// -// split out so it can also be applied to camera views -// -//--------------------------------------------------------------------------- - -void renderMirror(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int smoothratio) -{ - if (mirrorcnt > 0 && testgotpic(TILE_MIRROR, true)) - { - int dst = 0x7fffffff, i = 0; - for (int k = 0; k < mirrorcnt; k++) - { - int j = abs(mirrorwall[k]->wall_int_pos().X - cposx) + abs(mirrorwall[k]->wall_int_pos().Y - cposy); - if (j < dst) dst = j, i = k; - } - - if (mirrorwall[i] && mirrorwall[i]->overpicnum == TILE_MIRROR) - { - int tposx, tposy; - fixed_t tang; - - renderPrepareMirror(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), wallnum(mirrorwall[i]), &tposx, &tposy, &tang); - - int j = g_visibility; - g_visibility = (j >> 1) + (j >> 2); - - renderDrawRoomsQ16(tposx, tposy, cposz, tang, choriz.asq16(), sectnum(mirrorsector[i]), true); - - display_mirror = 1; - fi.animatesprites(pm_tsprite, pm_spritesortcnt, tposx, tposy, tang, smoothratio); - display_mirror = 0; - - renderDrawMasks(); - renderCompleteMirror(); //Reverse screen x-wise in this function - g_visibility = j; - } - } -} - -//--------------------------------------------------------------------------- -// -// used by RR to inject some external geometry into a scene. -// -//--------------------------------------------------------------------------- - -static void geometryEffect(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int sect, int smoothratio) -{ - auto sectp = §or[sect]; - int gs, geoid = 0; - sectortype* tgsect, *geosect; - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect, false); - fi.animatesprites(pm_tsprite, pm_spritesortcnt, cposx, cposy, cang.asbuild(), smoothratio); - renderDrawMasks(); - for (gs = 0; gs < geocnt; gs++) - { - tgsect = geosector[gs]; - - DukeSectIterator it(tgsect); - while (auto act = it.Next()) - { - ChangeActorSect(act, geosectorwarp[gs]); - SetActor(act, { act->spr.pos.X -= int(geox[gs] * worldtoint), act->spr.pos.Y -= int(geoy[gs] * worldtoint), act->spr.pos.Z }); - } - if (geosector[gs] == sectp) - { - geosect = geosectorwarp[gs]; - geoid = gs; - } - } - cposx -= int(geox[geoid] * worldtoint); - cposy -= int(geoy[geoid] * worldtoint); - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect, false); - cposx += int(geox[geoid] * worldtoint); - cposy += int(geoy[geoid] * worldtoint); - for (gs = 0; gs < geocnt; gs++) - { - tgsect = geosectorwarp[gs]; - DukeSectIterator it(tgsect); - while (auto act = it.Next()) - { - ChangeActorSect(act, geosector[gs]); - SetActor(act, { act->spr.pos.X += int(geox[gs] * worldtoint), act->spr.pos.Y += int(geoy[gs] * worldtoint), act->spr.pos.Z }); - } - } - fi.animatesprites(pm_tsprite, pm_spritesortcnt, cposx, cposy, cang.asbuild(), smoothratio); - renderDrawMasks(); - for (gs = 0; gs < geocnt; gs++) - { - tgsect = geosector[gs]; - DukeSectIterator it(tgsect); - while (auto act = it.Next()) - { - ChangeActorSect(act, geosectorwarp2[gs]); - SetActor(act, { act->spr.pos.X -= int(geox2[gs] * worldtoint), act->spr.pos.Y -= int(geoy2[gs] * worldtoint), act->spr.pos.Z }); - } - if (geosector[gs] == sectp) - { - geosect = geosectorwarp2[gs]; - geoid = gs; - } - } - cposx -= int(geox2[geoid] * worldtoint); - cposy -= int(geoy2[geoid] * worldtoint); - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect, false); - cposx += int(geox2[geoid] * worldtoint); - cposy += int(geoy2[geoid] * worldtoint); - for (gs = 0; gs < geocnt; gs++) - { - tgsect = geosectorwarp2[gs]; - DukeSectIterator it(tgsect); - while (auto act = it.Next()) - { - ChangeActorSect(act, geosector[gs]); - SetActor(act, { act->spr.pos.X += int(geox2[gs] * worldtoint), act->spr.pos.Y += int(geoy2[gs] * worldtoint), act->spr.pos.Z }); - } - } - fi.animatesprites(pm_tsprite, pm_spritesortcnt, cposx, cposy, cang.asbuild(), smoothratio); - renderDrawMasks(); -} -END_DUKE_NS diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 8bbcd6017..1e91f1bd7 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -2,7 +2,6 @@ #include "build.h" -#include "polymost.h" #include "gamecvars.h" #include "razemenu.h" #include "gamecontrol.h" diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index 14a15145e..e10aafa39 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -283,7 +283,7 @@ static void setupbackdrop() static void initTiles() { tileDelete(TILE_MIRROR); - skiptile = TILE_W_FORCEFIELD + 1; + //skiptile = TILE_W_FORCEFIELD + 1; if (isRR()) tileDelete(0); diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp index 6851fd43e..4defd1c36 100644 --- a/source/games/duke/src/render.cpp +++ b/source/games/duke/src/render.cpp @@ -34,16 +34,11 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) #include "dukeactor.h" #include "interpolate.h" #include "render.h" -#include "glbackend/glbackend.h" - -#include "_polymost.cpp" // temporary hack to pass along RRRA's global fog. Needs to be done better later. extern PalEntry GlobalMapFog; extern float GlobalFogDensity; -EXTERN_CVAR(Bool, vid_renderer) - BEGIN_DUKE_NS //--------------------------------------------------------------------------- @@ -66,23 +61,8 @@ BEGIN_DUKE_NS void renderView(DDukeActor* playersprite, sectortype* sect, int x, int y, int z, binangle a, fixedhoriz h, binangle rotscrnang, double smoothratio, bool sceneonly) { - if (!vid_renderer) - { - // do screen rotation. - renderSetRollAngle((float)rotscrnang.asbuildf()); - - se40code(x, y, z, a, h, smoothratio); - renderMirror(x, y, z, a, h, smoothratio); - renderDrawRoomsQ16(x, y, z, a.asq16(), h.asq16(), sect, false); - fi.animatesprites(pm_tsprite, pm_spritesortcnt, x, y, a.asbuild(), smoothratio); - if (!sceneonly) drawweapon(smoothratio); - renderDrawMasks(); - } - else - { - if (!sceneonly) drawweapon(smoothratio); - render_drawrooms(playersprite, { x, y, z }, sectnum(sect), a, h, rotscrnang, smoothratio); - } + if (!sceneonly) drawweapon(smoothratio); + render_drawrooms(playersprite, { x, y, z }, sectnum(sect), a, h, rotscrnang, smoothratio); } //--------------------------------------------------------------------------- @@ -114,20 +94,10 @@ void GameInterface::UpdateCameras(double smoothratio) auto camera = camsprite->GetOwner(); auto ang = buildang(camera->interpolatedang(smoothratio)); display_mirror = 1; // should really be 'display external view'. - if (!vid_renderer) - { - // Note: no ROR or camera here - Polymost has no means to detect these things before rendering the scene itself. - renderDrawRoomsQ16(camera->spr.pos.X, camera->spr.pos.Y, camera->spr.pos.Z, ang.asq16(), IntToFixed(camera->spr.shade), camera->sector(), false); // why 'shade'...? - fi.animatesprites(pm_tsprite, pm_spritesortcnt, camera->spr.pos.X, camera->spr.pos.Y, ang.asbuild(), (int)smoothratio); - renderDrawMasks(); - } - else - { - auto cstat = camera->spr.cstat; - camera->spr.cstat = CSTAT_SPRITE_INVISIBLE; - render_camtex(camera, camera->spr.pos, camera->sector(), ang, buildhoriz(camera->spr.shade), buildang(0), tex, rect, smoothratio); - camera->spr.cstat = cstat; - } + auto cstat = camera->spr.cstat; + camera->spr.cstat = CSTAT_SPRITE_INVISIBLE; + render_camtex(camera, camera->spr.pos, camera->sector(), ang, buildhoriz(camera->spr.shade), buildang(0), tex, rect, smoothratio); + camera->spr.cstat = cstat; display_mirror = 0; }); renderRestoreTarget(); @@ -260,7 +230,6 @@ void displayrooms(int snum, double smoothratio, bool sceneonly) struct player_struct* p; p = &ps[snum]; - pm_smoothratio = (int)smoothratio; if (automapMode == am_full || !p->insector()) return; @@ -274,17 +243,13 @@ void displayrooms(int snum, double smoothratio, bool sceneonly) g_visibility = ud.const_visibility; g_relvisibility = p->visibility - ud.const_visibility; - videoSetCorrectedAspect(); - auto sect = p->cursector; GlobalMapFog = fogactive ? 0x999999 : 0; GlobalFogDensity = fogactive ? 350.f : 0.f; - GLInterface.SetMapFog(fogactive != 0); DoInterpolations(smoothratio / 65536.); setgamepalette(BASEPAL); - if (!vid_renderer) gi->UpdateCameras(smoothratio); // Only Polymost does this here. The new renderer calls this internally. if (ud.cameraactor) { @@ -307,7 +272,7 @@ void displayrooms(int snum, double smoothratio, bool sceneonly) // Fixme: This should get the aspect ratio from the backend, not the current viewport size. int i = DivScale(1, isRR() ? 64 : p->GetActor()->spr.yrepeat + 28, 22); int viewingaspect = !isRRRA() || !p->DrugMode ? xs_CRoundToInt(double(i) * tan(r_fov * (pi::pi() / 360.))) : getdrugmode(p, i); - renderSetAspect(MulScale(viewingaspect, viewingrange, 16), yxaspect); + // todo: transform this mess into something sane to feed to the renderer. // The camera texture must be rendered with the base palette, so this is the only place where the current global palette can be set. // The setting here will be carried over to the rendering of the weapon sprites, but other 2D content will always default to the main palette. @@ -415,15 +380,7 @@ void displayrooms(int snum, double smoothratio, bool sceneonly) auto cstat = viewer->spr.cstat; if (camview) viewer->spr.cstat = CSTAT_SPRITE_INVISIBLE; - if (isRR() && sect->lotag == 848 && !vid_renderer) - { - renderSetRollAngle((float)rotscrnang.asbuildf()); - geometryEffect(cposx, cposy, cposz, cang, choriz, sectnum(sect), (int)smoothratio); - } - else - { - renderView(viewer, sect, cposx, cposy, cposz, cang, choriz, rotscrnang, smoothratio, sceneonly); - } + renderView(viewer, sect, cposx, cposy, cposz, cang, choriz, rotscrnang, smoothratio, sceneonly); viewer->spr.cstat = cstat; } //GLInterface.SetMapFog(false); diff --git a/source/games/duke/src/sectors.cpp b/source/games/duke/src/sectors.cpp index 65b16f9fc..aa3ef2adc 100644 --- a/source/games/duke/src/sectors.cpp +++ b/source/games/duke/src/sectors.cpp @@ -1303,17 +1303,9 @@ void moveclouds(double smoothratio) cloudy += (float)ps[screenpeek].angle.ang.fsin() * 0.5f; for (int i = 0; i < numclouds; i++) { - if (!vid_renderer) - { - clouds[i]->setceilingxpan(cloudx); - clouds[i]->setceilingypan(cloudy); - } - else - { - // no clamping here! - clouds[i]->ceilingxpan_ = cloudx; - clouds[i]->ceilingypan_ = cloudy; - } + // no clamping here! + clouds[i]->ceilingxpan_ = cloudx; + clouds[i]->ceilingypan_ = cloudy; clouds[i]->exflags |= SECTOREX_CLOUDSCROLL; } } diff --git a/source/games/exhumed/src/view.cpp b/source/games/exhumed/src/view.cpp index 56667044c..0d94bbcad 100644 --- a/source/games/exhumed/src/view.cpp +++ b/source/games/exhumed/src/view.cpp @@ -32,8 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "render.h" #include -EXTERN_CVAR(Bool, vid_renderer) - BEGIN_PS_NS bool bSubTitles = true; @@ -207,7 +205,6 @@ void DrawView(double smoothRatio, bool sceneonly) zbob = bsin(2 * bobangle, -3); DoInterpolations(smoothRatio / 65536.); - pm_smoothratio = (int)smoothRatio; auto pPlayerActor = PlayerList[nLocalPlayer].pActor; auto nPlayerOldCstat = pPlayerActor->spr.cstat; @@ -354,25 +351,9 @@ void DrawView(double smoothRatio, bool sceneonly) } } - if (!vid_renderer) - { - // this little block of code is Exhumed's entire interface to Polymost. - int const vr = xs_CRoundToInt(65536. * tan(r_fov * (pi::pi() / 360.))); - videoSetCorrectedAspect(); - renderSetAspect(MulScale(vr, viewingrange, 16), yxaspect); - renderSetRollAngle((float)rotscrnang.asbuildf()); - renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa.asq16(), nCamerapan.asq16(), sectnum(pSector), false); - analyzesprites(pm_tsprite, pm_spritesortcnt, nCamerax, nCameray, viewz, smoothRatio); - renderDrawMasks(); - if (!nFreeze && !sceneonly) - DrawWeapons(smoothRatio); - } - else - { - if (!nFreeze && !sceneonly) - DrawWeapons(smoothRatio); - render_drawrooms(nullptr, { nCamerax, nCameray, viewz }, sectnum(pSector), nCameraa, nCamerapan, rotscrnang, smoothRatio); - } + if (!nFreeze && !sceneonly) + DrawWeapons(smoothRatio); + render_drawrooms(nullptr, { nCamerax, nCameray, viewz }, sectnum(pSector), nCameraa, nCamerapan, rotscrnang, smoothRatio); if (HavePLURemap()) { diff --git a/source/games/sw/all.cpp b/source/games/sw/all.cpp index 0e7dd2257..6ff08afb9 100644 --- a/source/games/sw/all.cpp +++ b/source/games/sw/all.cpp @@ -59,5 +59,3 @@ #include "src/zilla.cpp" #include "src/zombie.cpp" #include "src/d_menu.cpp" - -#include "src/_polymost.cpp" diff --git a/source/games/sw/src/_polymost.cpp b/source/games/sw/src/_polymost.cpp deleted file mode 100644 index 59e72cc5e..000000000 --- a/source/games/sw/src/_polymost.cpp +++ /dev/null @@ -1,379 +0,0 @@ -BEGIN_SW_NS - -bool FindCeilingView(int match, int* x, int* y, int z, sectortype** sect); -bool FindFloorView(int match, int* x, int* y, int z, sectortype** sect); - - -int ViewSectorInScene(sectortype* cursect, int level) -{ - SWStatIterator it(STAT_FAF); - while (auto actor = it.Next()) - { - if (actor->spr.hitag == level) - { - if (cursect == actor->sector()) - { - // ignore case if sprite is pointing up - if (actor->spr.ang == 1536) - continue; - - // only gets to here is sprite is pointing down - - // found a potential match - int match = actor->spr.lotag; - - if (!testgotpic(FAF_MIRROR_PIC, true)) - return -1; - return match; - } - } - } - - return -1; -} - - - -void DrawOverlapRoom(int tx, int ty, int tz, fixed_t tq16ang, fixed_t tq16horiz, sectortype* tsect) -{ - save.zcount = 0; - - int match = ViewSectorInScene(tsect, VIEW_LEVEL1); - if (match != -1) - { - FindCeilingView(match, &tx, &ty, tz, &tsect); - - if (tsect == nullptr) - return; - - renderDrawRoomsQ16(tx, ty, tz, tq16ang, tq16horiz, sectnum(tsect), false); - - // reset Z's - for (int i = 0; i < save.zcount; i++) - { - save.sect[i]->setfloorz(save.zval[i], true); - save.sect[i]->floorpicnum = save.pic[i]; - save.sect[i]->setfloorslope(save.slope[i]); - } - - analyzesprites(pm_tsprite, pm_spritesortcnt, tx, ty, tz, false); - post_analyzesprites(pm_tsprite, pm_spritesortcnt); - renderDrawMasks(); - - } - else - { - match = ViewSectorInScene(tsect, VIEW_LEVEL2); - if (match != -1) - { - FindFloorView(match, &tx, &ty, tz, &tsect); - - if (tsect == nullptr) - return; - - renderDrawRoomsQ16(tx, ty, tz, tq16ang, tq16horiz, sectnum(tsect), false); - - // reset Z's - for (int i = 0; i < save.zcount; i++) - { - save.sect[i]->setceilingz(save.zval[i], true); - save.sect[i]->ceilingpicnum = save.pic[i]; - save.sect[i]->setceilingslope(save.slope[i]); - } - - analyzesprites(pm_tsprite, pm_spritesortcnt, tx, ty, tz, false); - post_analyzesprites(pm_tsprite, pm_spritesortcnt); - renderDrawMasks(); - - } - } -} - -void FAF_DrawRooms(int x, int y, int z, fixed_t q16ang, fixed_t q16horiz, int sectnum) -{ - SWStatIterator it(STAT_CEILING_FLOOR_PIC_OVERRIDE); - while (auto actor = it.Next()) - { - if (SP_TAG3(actor) == 0) - { - // back up ceilingpicnum and ceilingstat - SP_TAG5(actor) = actor->sector()->ceilingpicnum; - actor->sector()->ceilingpicnum = SP_TAG2(actor); - SP_TAG4(actor) = actor->sector()->ceilingstat; - actor->sector()->ceilingstat |= (ESectorFlags::FromInt(SP_TAG6(actor))); - actor->sector()->ceilingstat &= ~(CSTAT_SECTOR_SKY); - } - else if (SP_TAG3(actor) == 1) - { - SP_TAG5(actor) = actor->sector()->floorpicnum; - actor->sector()->floorpicnum = SP_TAG2(actor); - SP_TAG4(actor) = actor->sector()->floorstat; - actor->sector()->floorstat |= (ESectorFlags::FromInt(SP_TAG6(actor))); - actor->sector()->floorstat &= ~(CSTAT_SECTOR_SKY); - } - } - - renderDrawRoomsQ16(x,y,z,q16ang,q16horiz,sectnum, false); - - it.Reset(STAT_CEILING_FLOOR_PIC_OVERRIDE); - while (auto actor = it.Next()) - { - // manually set gotpic - if (gotsector[actor->sectno()]) - { - gotpic.Set(FAF_MIRROR_PIC); - } - - if (SP_TAG3(actor) == 0) - { - // restore ceilingpicnum and ceilingstat - actor->sector()->ceilingpicnum = SP_TAG5(actor); - actor->sector()->ceilingstat = ESectorFlags::FromInt(SP_TAG4(actor)); - actor->sector()->ceilingstat &= ~(CSTAT_SECTOR_SKY); - } - else if (SP_TAG3(actor) == 1) - { - actor->sector()->floorpicnum = SP_TAG5(actor); - actor->sector()->floorstat = ESectorFlags::FromInt(SP_TAG4(actor)); - actor->sector()->floorstat &= ~(CSTAT_SECTOR_SKY); - } - } -} - -void polymost_drawscreen(PLAYER* pp, int tx, int ty, int tz, binangle tang, fixedhoriz thoriz, sectortype* tsect) -{ - videoSetCorrectedAspect(); - renderSetAspect(xs_CRoundToInt(double(viewingrange) * tan(r_fov * (pi::pi() / 360.))), yxaspect); - OverlapDraw = true; - DrawOverlapRoom(tx, ty, tz, tang.asq16(), thoriz.asq16(), tsect); - OverlapDraw = false; - - if (automapMode != am_full) - { - // TEST this! Changed to camerapp - //JS_DrawMirrors(camerapp, tx, ty, tz, tang.asq16(), thoriz.asq16()); - JS_DrawMirrors(pp, tx, ty, tz, tang.asq16(), thoriz.asq16()); - } - - // TODO: This call is redundant if the tiled overhead map is shown, but the - // HUD elements should be properly outputted with hardware rendering first. - if (!FAF_DebugView) - FAF_DrawRooms(tx, ty, tz, tang.asq16(), thoriz.asq16(), sectnum(tsect)); - - analyzesprites(pm_tsprite, pm_spritesortcnt, tx, ty, tz, tang.asbuild()); - post_analyzesprites(pm_tsprite, pm_spritesortcnt); - renderDrawMasks(); - -} - -void JS_DrawMirrors(PLAYER* pp, int tx, int ty, int tz, fixed_t tpq16ang, fixed_t tpq16horiz) -{ - int j, cnt; - int dist; - int tposx, tposy; // Camera - int *longptr; - fixed_t tang; - -// int tx, ty, tz, tpang; // Interpolate so mirror doesn't - // drift! - bool bIsWallMirror = false; - - { - for (cnt = mirrorcnt - 1; cnt >= 0; cnt--) - //if (testgotpic(cnt + MIRRORLABEL) || testgotpic(cnt + CAMSPRITE)) - if (testgotpic(cnt + MIRRORLABEL) || ((unsigned)mirror[cnt].campic < MAXTILES && testgotpic(mirror[cnt].campic))) - { - bIsWallMirror = false; - if (testgotpic(cnt + MIRRORLABEL, true)) - { - bIsWallMirror = true; - } - else if ((unsigned)mirror[cnt].campic < MAXTILES && testgotpic(mirror[cnt].campic)) - { - gotpic.Clear(mirror[cnt].campic); - } - - mirrorinview = true; - -// tx = interpolatedvalue(pp->oposx, pp->posx, smoothratio); -// ty = interpolatedvalue(pp->oposy, pp->posy, smoothratio); -// tz = interpolatedvalue(pp->oposz, pp->posz, smoothratio); -// tpq16ang = pp->angle.ang.asq16(); - - - dist = 0x7fffffff; - - if (bIsWallMirror) - { - j = abs(mirror[cnt].mirrorWall->wall_int_pos().X - tx); - j += abs(mirror[cnt].mirrorWall->wall_int_pos().Y - ty); - if (j < dist) - dist = j; - } - else if (mirror[cnt].camspriteActor) - { - auto pos = mirror[cnt].camspriteActor->spr.pos; - - j = abs(pos.X - tx); - j += abs(pos.Y - ty); - if (j < dist) - dist = j; - } - - if (mirror[cnt].ismagic) - { - int camhoriz; - int w; - int dx, dy, dz, tdx, tdy, tdz, midx, midy; - - auto actor = mirror[cnt].cameraActor; - ASSERT(actor != nullptr); - - // Calculate the angle of the mirror wall - auto wal = mirror[cnt].mirrorWall; - - // Get wall midpoint for offset in mirror view - midx = (wal->wall_int_pos().X + wal->point2Wall()->wall_int_pos().X) / 2; - midy = (wal->wall_int_pos().Y + wal->point2Wall()->wall_int_pos().Y) / 2; - - // Finish finding offsets - tdx = abs(midx - tx); - tdy = abs(midy - ty); - - if (midx >= tx) - dx = actor->spr.pos.X - tdx; - else - dx = actor->spr.pos.X + tdx; - - if (midy >= ty) - dy = actor->spr.pos.Y - tdy; - else - dy = actor->spr.pos.Y + tdy; - - tdz = abs(tz - actor->spr.pos.Z); - if (tz >= actor->spr.pos.Z) - dz = actor->spr.pos.Z + tdz; - else - dz = actor->spr.pos.Z - tdz; - - - // Is it a TV cam or a teleporter that shows destination? - // true = It's a TV cam - mirror[cnt].mstate = m_normal; - if (TEST_BOOL1(actor)) - mirror[cnt].mstate = m_viewon; - - // Show teleport destination - // NOTE: Adding true lets you draw a room, even if - // you are outside of it! - if (mirror[cnt].mstate != m_viewon) - { - tileDelete(MIRROR); - // Set TV camera sprite size to 0 to show mirror - // behind in this case! - - if (mirror[cnt].campic != -1) - tileDelete(mirror[cnt].campic); - renderDrawRoomsQ16(dx, dy, dz, tpq16ang, tpq16horiz, actor->sector(), true); - analyzesprites(pm_tsprite, pm_spritesortcnt, dx, dy, dz, false); - renderDrawMasks(); - } - } - else if (mirror[cnt].mirrorWall) - { - // It's just a mirror - // Prepare drawrooms for drawing mirror and calculate - // reflected - // position into tposx, tposy, and tang (tposz == cposz) - // Must call preparemirror before drawrooms and - // completemirror after drawrooms - display_mirror = true; - renderPrepareMirror(tx, ty, tz, tpq16ang, tpq16horiz, - wallnum(mirror[cnt].mirrorWall), /*mirror[cnt].mirrorsector,*/ &tposx, &tposy, &tang); - - renderDrawRoomsQ16(tposx, tposy, tz, (tang), tpq16horiz, sectnum(mirror[cnt].mirrorSector), true); - - analyzesprites(pm_tsprite, pm_spritesortcnt, tposx, tposy, tz, tang >> 16); - renderDrawMasks(); - - renderCompleteMirror(); // Reverse screen x-wise in this - display_mirror = false; - } - - // Clean up anything that the camera view might have done - tileDelete(MIRROR); - mirror[cnt].mirrorWall->overpicnum = MIRRORLABEL + cnt; - } - else - mirrorinview = false; - } -} - - -void SW_FloorPortalHack(DSWActor* actor, int z, int match) -{ - // move ceiling multiple of 128 so that the wall tile will line up - int pix_diff = labs(z - actor->sector()->ceilingz) >> 8; - int newz = actor->sector()->ceilingz - ((pix_diff / 128) + 1) * Z(128); - - SWStatIterator it(STAT_FAF); - while ((actor = it.Next())) - { - if (actor->spr.lotag == match) - { - // move upper levels floors down for the correct view - if (actor->spr.hitag == VIEW_LEVEL1) - { - // save it off - save.sect[save.zcount] = actor->sector(); - save.zval[save.zcount] = actor->sector()->ceilingz; - save.pic[save.zcount] = actor->sector()->ceilingpicnum; - save.slope[save.zcount] = actor->sector()->ceilingheinum; - - actor->sector()->setceilingz(newz, true); - - // don't change FAF_MIRROR_PIC - ConnectArea - if (actor->sector()->ceilingpicnum != FAF_MIRROR_PIC) - actor->sector()->ceilingpicnum = FAF_MIRROR_PIC + 1; - actor->sector()->setceilingslope(0); - - save.zcount++; - PRODUCTION_ASSERT(save.zcount < ZMAX); - } - } - } -} - -void SW_CeilingPortalHack(DSWActor* actor, int z, int match) -{ - int pix_diff = labs(z - actor->sector()->floorz) >> 8; - int newz = actor->sector()->floorz + ((pix_diff / 128) + 1) * Z(128); - - SWStatIterator it(STAT_FAF); - while ((actor = it.Next())) - { - if (actor->spr.lotag == match) - { - // move lower levels ceilings up for the correct view - if (actor->spr.hitag == VIEW_LEVEL2) - { - // save it off - save.sect[save.zcount] = actor->sector(); - save.zval[save.zcount] = actor->sector()->floorz; - save.pic[save.zcount] = actor->sector()->floorpicnum; - save.slope[save.zcount] = actor->sector()->floorheinum; - - actor->sector()->setfloorz(newz, true); - // don't change FAF_MIRROR_PIC - ConnectArea - if (actor->sector()->floorpicnum != FAF_MIRROR_PIC) - actor->sector()->floorpicnum = FAF_MIRROR_PIC + 1; - actor->sector()->setfloorslope(0); - - save.zcount++; - PRODUCTION_ASSERT(save.zcount < ZMAX); - } - } - } - -} -END_SW_NS diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index 9910e7118..ee3e7be69 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -56,7 +56,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "v_draw.h" #include "render.h" #include "razefont.h" -EXTERN_CVAR(Bool, vid_renderer) extern DCoreActor* wall_to_sprite_actors[8]; @@ -1382,7 +1381,6 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly) PreUpdatePanel(smoothratio); int sr = (int)smoothratio; - pm_smoothratio = sr; if (!sceneonly) { @@ -1493,23 +1491,13 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly) if (automapMode != am_full) { // Cameras must be done before the main loop. - if (!vid_renderer) JS_DrawCameras(pp, tx, ty, tz, smoothratio); - else JS_CameraParms(pp, tx, ty, tz); + JS_CameraParms(pp, tx, ty, tz); } - if (!vid_renderer) - { - renderSetRollAngle((float)trotscrnang.asbuildf()); - polymost_drawscreen(pp, tx, ty, tz, tang, thoriz, tsect); - if (!sceneonly) UpdatePanel(smoothratio); - } - else - { - if (!sceneonly) UpdatePanel(smoothratio); - UpdateWallPortalState(); - render_drawrooms(pp->actor, { tx, ty, tz }, sectnum(tsect), tang, thoriz, trotscrnang, smoothratio); - RestorePortalState(); - } + if (!sceneonly) UpdatePanel(smoothratio); + UpdateWallPortalState(); + render_drawrooms(pp->actor, { tx, ty, tz }, sectnum(tsect), tang, thoriz, trotscrnang, smoothratio); + RestorePortalState(); if (sceneonly) { diff --git a/source/games/sw/src/jsector.cpp b/source/games/sw/src/jsector.cpp index 395fe4744..69c548785 100644 --- a/source/games/sw/src/jsector.cpp +++ b/source/games/sw/src/jsector.cpp @@ -46,8 +46,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "v_video.h" #include "render.h" -EXTERN_CVAR(Bool, vid_renderer) - BEGIN_SW_NS @@ -412,16 +410,7 @@ void drawroomstotile(int daposx, int daposy, int daposz, screen->RenderTextureView(canvas, [=](IntRect& rect) { - if (!vid_renderer) - { - renderDrawRoomsQ16(daposx, daposy, daposz, ang.asq16(), horiz.asq16(), dacursect, false); - analyzesprites(pm_tsprite, pm_spritesortcnt, daposx, daposy, daposz, ang.asbuild()); - renderDrawMasks(); - } - else - { - render_camtex(nullptr, { daposx, daposy, daposz }, dacursect, ang, horiz, buildang(0), tileGetTexture(tilenume), rect, smoothratio); - } + render_camtex(nullptr, { daposx, daposy, daposz }, dacursect, ang, horiz, buildang(0), tileGetTexture(tilenume), rect, smoothratio); }); renderRestoreTarget(); diff --git a/source/games/sw/src/rooms.cpp b/source/games/sw/src/rooms.cpp index 72fddce15..73690824e 100644 --- a/source/games/sw/src/rooms.cpp +++ b/source/games/sw/src/rooms.cpp @@ -709,10 +709,6 @@ bool FindCeilingView(int match, int* x, int* y, int z, sectortype** sect) } - if (!vid_renderer) - { - SW_CeilingPortalHack(actor, z, match); - } return true; } @@ -770,10 +766,6 @@ bool FindFloorView(int match, int* x, int* y, int z, sectortype** sect) return false; } - if (!vid_renderer) - { - SW_FloorPortalHack(actor, z, match); - } return true; } @@ -815,8 +807,6 @@ struct PortalGroup // This is very messy because some portals are linked outside the actual portal sectors, so we have to use the complicated original linking logic to find the connection. :? void CollectPortals() { - int t = vid_renderer; - vid_renderer = true; TArray floorportals; TArray ceilingportals; BitArray floordone(sector.Size()), ceilingdone(sector.Size()); @@ -981,7 +971,6 @@ void CollectPortals() } } } - vid_renderer = t; } diff --git a/source/glbackend/gl_texture.cpp b/source/glbackend/gl_texture.cpp deleted file mode 100644 index 0743e09f9..000000000 --- a/source/glbackend/gl_texture.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* -** gl_texture.cpp -** high level GL texture interface -** -**--------------------------------------------------------------------------- -** Copyright 2019 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** -*/ - -#include "palette.h" -#include "build.h" -#include "polymost.h" -#include "textures.h" -#include "bitmap.h" -#include "v_font.h" -#include "palettecontainer.h" -#include "../../glbackend/glbackend.h" -#include "texturemanager.h" -#include "v_video.h" -#include "printf.h" - -//=========================================================================== -// -// Retrieve the texture to be used. -// -//=========================================================================== - -// Test CVARs. -#ifdef _DEBUG -CVAR(Int, fixpalette, -1, 0) -CVAR(Int, fixpalswap, -1, 0) -#endif - -bool GLInstance::SetTexture(FGameTexture* tex, int paletteid, int sampler, bool notindexed) -{ - if (!tex->isValid()) - { - return false; - } -#ifdef _DEBUG - int basepal = GetTranslationType(paletteid) - Translation_Remap; - int translation = GetTranslationIndex(paletteid); - int usepalette = fixpalette >= 0 ? fixpalette : basepal; - int usepalswap = fixpalswap >= 0 ? fixpalswap : translation; - paletteid = TRANSLATION(Translation_Remap + usepalette, usepalswap); -#endif - - SetPalswap(GetTranslationIndex(paletteid)); - - auto &mat = renderState.mMaterial; - assert(tex->isValid()); - mat.mTexture = tex; - mat.uFlags = UF_Texture; - mat.mScaleFlags = 0; - mat.mClampMode = sampler; - mat.mTranslation = paletteid; - mat.mOverrideShader = -1; - mat.mChanged = true; - GLInterface.SetAlphaThreshold(tex->alphaThreshold); - return true; -} - diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp deleted file mode 100644 index 436522e37..000000000 --- a/source/glbackend/glbackend.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/* -** glbackend.cpp -** -** OpenGL API abstraction -** -**--------------------------------------------------------------------------- -** Copyright 2019 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ -#include -#include -#include "glbackend.h" -#include "textures.h" -#include "palette.h" -#include "gamecontrol.h" -#include "v_2ddrawer.h" -#include "v_video.h" -#include "flatvertices.h" -#include "build.h" -#include "v_draw.h" -#include "v_font.h" -#include "hw_viewpointuniforms.h" -#include "hw_viewpointbuffer.h" -#include "hw_renderstate.h" -#include "hw_cvars.h" -#include "gamestruct.h" -#include "hw_models.h" -#include "gamefuncs.h" -#include "gamehud.h" - -CVARD(Bool, hw_hightile, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable hightile texture rendering") -bool hw_int_useindexedcolortextures; -CUSTOM_CVARD(Bool, hw_useindexedcolortextures, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable indexed color texture rendering") -{ - if (screen) screen->SetTextureFilterMode(); -} - -EXTERN_CVAR(Bool, gl_texture) - -static int BufferLock = 0; - -TArray matrixArray; - -GLInstance GLInterface; - -GLInstance::GLInstance() -{ - VSMatrix mat(0); - matrixArray.Push(mat); -} - -void GLInstance::Init(int ydim) -{ - new(&renderState) PolymostRenderState; // reset to defaults. -} - -void GLInstance::Draw(EDrawType type, size_t start, size_t count) -{ - assert (BufferLock > 0); - applyMapFog(); - renderState.vindex = (int)start; - renderState.vcount = (int)count; - renderState.primtype = type; - rendercommands.Push(renderState); - clearMapFog(); - renderState.StateFlags &= ~(STF_CLEARCOLOR | STF_CLEARDEPTH | STF_VIEWPORTSET | STF_SCISSORSET); -} - -void GLInstance::DoDraw() -{ - GLState lastState; - - if (rendercommands.Size() > 0) - { - if (!useMapFog) hw_int_useindexedcolortextures = hw_useindexedcolortextures; - - lastState.Flags = ~rendercommands[0].StateFlags; // Force ALL flags to be considered 'changed'. - lastState.DepthFunc = INT_MIN; // Something totally invalid. - screen->RenderState()->EnableMultisampling(true); - auto& state = *screen->RenderState(); - - for (auto& rs : rendercommands) - { - if (rs.Apply(state, lastState)) - { - if (!rs.model) - { - state.Draw(rs.primtype, rs.vindex, rs.vcount); - } - else - { - FHWModelRenderer mr(*screen->RenderState(), -1); - state.SetDepthFunc(DF_LEqual); - state.EnableTexture(true); - rs.model->BuildVertexBuffer(&mr); - mr.SetupFrame(rs.model, rs.mframes[0], rs.mframes[1], 0); - rs.model->RenderFrame(&mr, rs.mMaterial.mTexture, rs.mframes[0], rs.mframes[1], 0.f, rs.mMaterial.mTranslation, nullptr); - state.SetDepthFunc(DF_Less); - state.SetVertexBuffer(screen->mVertexData); - } - } - } - state.SetNpotEmulation(0, 0); // make sure we do not leave this in an undefined state. - renderState.Apply(*screen->RenderState(), lastState); // apply any pending change before returning. - rendercommands.Clear(); - hw_int_useindexedcolortextures = false; - } - matrixArray.Resize(1); -} - - -int GLInstance::SetMatrix(int num, const VSMatrix *mat) -{ - int r = renderState.matrixIndex[num]; - renderState.matrixIndex[num] = matrixArray.Size(); - matrixArray.Push(*mat); - return r; -} - -void GLInstance::SetIdentityMatrix(int num) -{ - renderState.matrixIndex[num] = -1; -} - -void GLInstance::SetPalswap(int index) -{ - renderState.ShadeDiv = lookups.tables[index].ShadeFactor; -} - -void GLInstance::SetFade(int index) -{ - renderState.FogColor = lookups.getFade(index); -} - -extern int globalpal; -void GLInstance::SetShade(int32_t shade, int numshades) -{ - // Ugh... This particular palette does not fade to black. Should be handled better. - // It's really too bad that everything runs through here without being able to identify it anymore. - renderState.drawblack = (!(g_gameType & GAMEFLAG_PSEXHUMED) || globalpal != 4) ? shade > numshades : false; - renderState.Shade = min(shade, numshades - 1); -} - -bool PolymostRenderState::Apply(FRenderState& state, GLState& oldState) -{ - // Fog must be done before the texture so that the texture selector can override it. - bool foggy = (GLInterface.useMapFog || (FogColor & 0xffffff)); - // Disable brightmaps if non-black fog is used. - if (!(Flags & RF_FogDisabled) && ShadeDiv >= 1 / 1000.f && foggy) - { - state.EnableFog(1); - float density = GLInterface.useMapFog ? 350.f : 350.f - Scale(numshades - Shade, 150, numshades); - state.SetFog((GLInterface.useMapFog) ? PalEntry(0x999999) : FogColor, density); - state.SetSoftLightLevel(255); - state.SetLightParms(128.f, 1 / 1000.f); - } - else - { - state.EnableFog(0); - state.SetFog(0, 0); - state.SetSoftLightLevel(ShadeDiv >= 1 / 1000.f ? 255 - Scale(Shade, 255, numshades) : 255); - state.SetLightParms(VisFactor, ShadeDiv / (numshades - 2)); - } - - if (Flags & RF_ColorOnly) - { - state.EnableTexture(false); - } - else - { - if (!mMaterial.mTexture) return false; // Oh no! Something passed an invalid tile! - state.EnableTexture(gl_texture); - state.SetMaterial(mMaterial.mTexture, mMaterial.uFlags, mMaterial.mScaleFlags, mMaterial.mClampMode, mMaterial.mTranslation, mMaterial.mOverrideShader); - } - - if (!drawblack) state.SetColor(Color[0], Color[1], Color[2], Color[3]); - else state.SetColor(0, 0, 0, Color[3]); - if (StateFlags != oldState.Flags) - { - state.EnableDepthTest(StateFlags & STF_DEPTHTEST); - - if ((StateFlags ^ oldState.Flags) & (STF_STENCILTEST | STF_STENCILWRITE)) - { - if (StateFlags & STF_STENCILWRITE) - { - state.EnableStencil(true); - state.SetEffect(EFF_STENCIL); - state.SetStencil(0, SOP_Increment, SF_ColorMaskOff); - } - else if (StateFlags & STF_STENCILTEST) - { - state.EnableStencil(true); - state.SetEffect(EFF_NONE); - state.SetStencil(1, SOP_Keep, SF_DepthMaskOff); - } - else - { - state.EnableStencil(false); - state.SetEffect(EFF_NONE); - } - } - if ((StateFlags ^ oldState.Flags) & (STF_CULLCW | STF_CULLCCW)) - { - int cull = Cull_None; - if (StateFlags & STF_CULLCCW) cull = Cull_CCW; - else if (StateFlags & STF_CULLCW) cull = Cull_CW; - state.SetCulling(cull); - } - state.SetColorMask(StateFlags & STF_COLORMASK); - state.SetDepthMask(StateFlags & STF_DEPTHMASK); - if (StateFlags & (STF_CLEARCOLOR | STF_CLEARDEPTH)) - { - int clear = 0; - if (StateFlags & STF_CLEARCOLOR) clear |= CT_Color; - if (StateFlags & STF_CLEARDEPTH) clear |= CT_Depth; - state.Clear(clear); - } - if (StateFlags & STF_VIEWPORTSET) - { - state.SetViewport(vp_x, vp_y, vp_w, vp_h); - } - if (StateFlags & STF_SCISSORSET) - { - state.SetScissor(sc_x, sc_y, sc_w, sc_h); - } - state.SetDepthBias(mBias.mFactor, mBias.mUnits); - - StateFlags &= ~(STF_CLEARCOLOR | STF_CLEARDEPTH | STF_VIEWPORTSET | STF_SCISSORSET); - oldState.Flags = StateFlags; - } - state.SetRenderStyle(Style); - if (DepthFunc != oldState.DepthFunc) - { - state.SetDepthFunc(DepthFunc); - oldState.DepthFunc = DepthFunc; - } - - state.SetTextureMode(TextureMode); - - state.SetNpotEmulation(NPOTEmulation.Y, NPOTEmulation.X); - state.AlphaFunc(Alpha_Greater, AlphaTest ? AlphaThreshold : -1.f); - - if (matrixIndex[Matrix_Model] != -1) - { - state.EnableModelMatrix(true); - state.mModelMatrix = matrixArray[matrixIndex[Matrix_Model]]; - } - else state.EnableModelMatrix(false); - - memset(matrixIndex, -1, sizeof(matrixIndex)); - return true; -} - -static void PM_DoWriteSavePic(FileWriter* file, ESSType ssformat, uint8_t* scr, int width, int height, bool upsidedown) -{ - int pixelsize = 3; - int pitch = width * pixelsize; - if (upsidedown) - { - scr += ((height - 1) * width * pixelsize); - pitch *= -1; - } - - M_CreatePNG(file, scr, nullptr, ssformat, width, height, pitch, vid_gamma); -} - -//=========================================================================== -// -// Render the view to a savegame picture -// -//=========================================================================== - -void PM_WriteSavePic(FileWriter* file, int width, int height) -{ - IntRect bounds; - bounds.left = 0; - bounds.top = 0; - bounds.width = width; - bounds.height = height; - auto& RenderState = *screen->RenderState(); - - // we must be sure the GPU finished reading from the buffer before we fill it with new data. - screen->WaitForCommands(false); - screen->mVertexData->Reset(); - - // Switch to render buffers dimensioned for the savepic - screen->SetSaveBuffers(true); - - screen->ImageTransitionScene(true); - - RenderState.SetVertexBuffer(screen->mVertexData); - screen->mVertexData->Reset(); - //screen->mLights->Clear(); - screen->mViewpoints->Clear(); - - int oldx = xdim; - int oldy = ydim; - auto oldwindowxy1 = windowxy1; - auto oldwindowxy2 = windowxy2; - - xdim = width; - ydim = height; - videoSetViewableArea(0, 0, width - 1, height - 1); - renderSetAspect(65536, 65536); - screen->SetSceneRenderTarget(false); - RenderState.SetPassType(NORMAL_PASS); - RenderState.EnableDrawBuffers(1, true); - - screen->SetViewportRects(&bounds); - twodpsp.Clear(); - /*bool didit =*/ gi->GenerateSavePic(); - - float Brightness = 8.f / (r_scenebrightness + 8.f); - screen->PostProcessScene(false, 0, Brightness, []() { - Draw2D(&twodpsp, *screen->RenderState()); // draws the weapon sprites - }); - - xdim = oldx; - ydim = oldy; - videoSetViewableArea(oldwindowxy1.X, oldwindowxy1.Y, oldwindowxy2.X, oldwindowxy2.Y); - - // The 2D drawers can contain some garbage from the dirty render setup. Get rid of that first. - twod->Clear(); - twodpsp.Clear(); - - int numpixels = width * height; - uint8_t* scr = (uint8_t*)M_Malloc(numpixels * 3); - screen->CopyScreenToBuffer(width, height, scr); - - PM_DoWriteSavePic(file, SS_RGB, scr, width, height, screen->FlipSavePic()); - M_Free(scr); - - // Switch back the screen render buffers - screen->SetViewportRects(nullptr); - screen->SetSaveBuffers(false); -} - - -static HWViewpointUniforms vp; - -void renderSetProjectionMatrix(const float* p) -{ - if (p) - { - vp.mProjectionMatrix.loadMatrix(p); - GLInterface.mProjectionM5 = p[5]; - } - else vp.mProjectionMatrix.loadIdentity(); -} - -void renderSetViewMatrix(const float* p) -{ - if (p) vp.mViewMatrix.loadMatrix(p); - else vp.mViewMatrix.loadIdentity(); -} - -void renderSetVisibility(float vis) -{ - vp.mGlobVis = vis; -} - -void renderSetViewpoint(float x, float y, float z) -{ - vp.mCameraPos = {x, z, y, 0}; -} - -void renderBeginScene() -{ - assert(BufferLock == 0); - - vp.mPalLightLevels = numshades | (static_cast(gl_fogmode) << 8) | ((int)5 << 16); - screen->mViewpoints->SetViewpoint(*screen->RenderState(), &vp); - - if (BufferLock++ == 0) - { - screen->mVertexData->Map(); - } -} - -void renderFinishScene() -{ - assert(BufferLock == 1); - if (--BufferLock == 0) - { - screen->mVertexData->Unmap(); - GLInterface.DoDraw(); - } -} - - -int32_t r_scenebrightness = 0; - - - -void videoShowFrame() -{ - int oldssao = gl_ssao; - - // These two features do not really work with Polymost because the rendered scene does not provide it - gl_ssao = 0; - float Brightness = 8.f / (r_scenebrightness + 8.f); - - screen->PostProcessScene(false, 0, Brightness, []() { - Draw2D(&twodpsp, *screen->RenderState()); // draws the weapon sprites - }); - screen->mVertexData->Reset(); - screen->mViewpoints->Clear(); - - gl_ssao = oldssao; -} diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h deleted file mode 100644 index dcfdfa1ee..000000000 --- a/source/glbackend/glbackend.h +++ /dev/null @@ -1,313 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include "c_cvars.h" -#include "gl_samplers.h" -#include "gl_hwtexture.h" -#include "matrix.h" -#include "palentry.h" -#include "renderstyle.h" -#include "hw_material.h" -#include "hw_renderstate.h" -#include "pm_renderstate.h" - - -class FShader; -class FGameTexture; -class GLInstance; -class F2DDrawer; -struct palette_t; -extern int xdim, ydim; - -struct glinfo_t { - float maxanisotropy; -}; - -enum ECullSide -{ - Cull_Front, - Cull_Back -}; - -enum EWinding -{ - Winding_CCW, - Winding_CW -}; - -struct ImDrawData; -struct palette_t; - -enum -{ - MAX_TEXTURES = 4, /*15*/ // slot 15 is used internally and not available. - The renderer uses only 5, though. -}; - -struct GLState -{ - int Flags; - int DepthFunc; -}; - -class GLInstance -{ - friend IHardwareTexture* setpalettelayer(int layer, int translation); - -public: - TArray rendercommands; - FGameTexture* currentTexture = nullptr; - int MatrixChange = 0; - - PolymostRenderState renderState; - - -public: - float mProjectionM5 = 1.0f; // needed by ssao - glinfo_t glinfo; - - void Init(int y); - - static int GetTexDimension(int value) - { - //if (value > gl.max_texturesize) return gl.max_texturesize; - return value; - } - - GLInstance(); - void Draw(EDrawType type, size_t start, size_t count); - void DoDraw(); - - float GetProjectionM5() { return mProjectionM5; } - int SetMatrix(int num, const VSMatrix *mat ); - int SetMatrix(int num, const float *mat) - { - return SetMatrix(num, reinterpret_cast(mat)); - } - void SetIdentityMatrix(int num); - void RestoreMatrix(int num, int index) - { - renderState.matrixIndex[num] = index; - } - - void SetTextureMode(int m) - { - renderState.TextureMode = m; - } - - void SetDepthBias(float a, float b) - { - renderState.mBias.mFactor = a; - renderState.mBias.mUnits = b; - renderState.mBias.mChanged = true; - } - - void ClearDepthBias() - { - renderState.mBias.mFactor = 0; - renderState.mBias.mUnits = 0; - renderState.mBias.mChanged = true; - } - - void SetPalswap(int index); - void SetFade(int palette); - - void SetShade(int32_t shade, int numshades); - - void SetVisibility(float visibility) - { - renderState.VisFactor = visibility; - } - - void EnableBlend(bool on) - { - if (on) renderState.StateFlags |= STF_BLEND; - else renderState.StateFlags &= ~STF_BLEND; - } - - void EnableDepthTest(bool on) - { - if (on) renderState.StateFlags |= STF_DEPTHTEST; - else renderState.StateFlags &= ~STF_DEPTHTEST; - } - - void EnableStencilWrite(int value) - { - renderState.StateFlags |= STF_STENCILWRITE; - renderState.StateFlags &= ~STF_STENCILTEST; - } - - void EnableStencilTest(int value) - { - renderState.StateFlags &= ~STF_STENCILWRITE; - renderState.StateFlags |= STF_STENCILTEST; - } - - void DisableStencil() - { - renderState.StateFlags &= ~(STF_STENCILWRITE | STF_STENCILTEST); - } - - void SetCull(int type, int winding = Winding_CW) - { - renderState.StateFlags &= ~(STF_CULLCCW | STF_CULLCW); - if (type != Cull_None) - { - if (winding == Winding_CW) renderState.StateFlags |= STF_CULLCW; - else renderState.StateFlags |= STF_CULLCCW; - } - } - - void SetColorMask(bool on) - { - if (on) renderState.StateFlags |= STF_COLORMASK; - else renderState.StateFlags &= ~STF_COLORMASK; - } - - void SetDepthMask(bool on) - { - if (on) renderState.StateFlags |= STF_DEPTHMASK; - else renderState.StateFlags &= ~STF_DEPTHMASK; - } - - void ClearScreen(PalEntry pe, bool depth) - { - renderState.ClearColor = pe; - renderState.StateFlags |= STF_CLEARCOLOR; - if (depth) renderState.StateFlags |= STF_CLEARDEPTH; - } - - void SetViewport(int x, int y, int w, int h) - { - renderState.vp_x = (short)x; - renderState.vp_y = (short)y; - renderState.vp_w = (short)w; - renderState.vp_h = (short)h; - renderState.StateFlags |= STF_VIEWPORTSET; - } - - void SetScissor(int x1, int y1, int x2, int y2) - { - renderState.sc_x = (short)x1; - renderState.sc_y = (short)y1; - renderState.sc_w = (short)x2; - renderState.sc_h = (short)y2; - renderState.StateFlags |= STF_SCISSORSET; - } - - void DisableScissor() - { - renderState.sc_x = SHRT_MIN; - renderState.StateFlags |= STF_SCISSORSET; - } - - void SetDepthFunc(int func) - { - renderState.DepthFunc = func; - } - - - void ClearScreen(PalEntry pe) - { - //twod->Clear(); - SetViewport(0, 0, xdim, ydim); - ClearScreen(pe, true); - } - - void ClearDepth() - { - renderState.StateFlags |= STF_CLEARDEPTH; - } - - void SetRenderStyle(FRenderStyle style) - { - renderState.Style = style; - } - - void SetColor(float r, float g, float b, float a = 1.f) - { - renderState.Color[0] = r; - renderState.Color[1] = g; - renderState.Color[2] = b; - renderState.Color[3] = a; - } - void SetColorub(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) - { - SetColor(r * (1 / 255.f), g * (1 / 255.f), b * (1 / 255.f), a * (1 / 255.f)); - } - - void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader) - { - assert(tex); - renderState.mMaterial.mTexture = tex; - renderState.mMaterial.uFlags = upscalemask; - renderState.mMaterial.mScaleFlags = scaleflags; - renderState.mMaterial.mClampMode = clampmode; - renderState.mMaterial.mTranslation = translation; - renderState.mMaterial.mOverrideShader = overrideshader; - renderState.mMaterial.mChanged = true; - } - - void UseColorOnly(bool yes) - { - if (yes) renderState.Flags |= RF_ColorOnly; - else renderState.Flags &= ~RF_ColorOnly; - } - - void SetNpotEmulation(float factor, float xOffset) - { - renderState.NPOTEmulation.Y = factor; - renderState.NPOTEmulation.X = xOffset; - } - - // Hack... - bool useMapFog = false; - - void SetMapFog(bool yes) - { - useMapFog = yes; - } - - void applyMapFog() - { - if (useMapFog) renderState.Flags |= RF_MapFog; - else renderState.Flags &= ~RF_MapFog; - } - - void clearMapFog() - { - renderState.Flags &= ~RF_MapFog; - } - - void EnableAlphaTest(bool on) - { - renderState.AlphaTest = on; - } - - void SetAlphaThreshold(float al) - { - renderState.AlphaThreshold = al; - } - - bool SetTexture(FGameTexture* tex, int palette, int sampleroverride, bool notindexed = false); - - void SetModel(FModel* model, int frame1, int frame2, float factor) - { - renderState.model = model; - renderState.mframes[0] = frame1; - renderState.mframes[1] = frame2; - renderState.mfactor = factor; - } -}; - -extern GLInstance GLInterface; - -void renderSetProjectionMatrix(const float* p); -void renderSetViewMatrix(const float* p); -void renderSetVisibility(float v); -void renderSetViewpoint(float x, float y, float z); -void renderBeginScene(); -void renderFinishScene(); -void videoShowFrame(); diff --git a/source/glbackend/pm_renderstate.h b/source/glbackend/pm_renderstate.h deleted file mode 100644 index 1c20f2383..000000000 --- a/source/glbackend/pm_renderstate.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include -#include "palentry.h" -#include "gl_buffers.h" -#include "renderstyle.h" -struct GLState; -class FMaterial; -class FModel; - -enum EMatrixType -{ - Matrix_Model, - // These are the only ones being used. - NUMMATRICES -}; - -enum PRSFlags -{ - RF_ColorOnly = 1, - RF_FogDisabled = 128, - RF_MapFog = 256, // RRRA E2L1. - - RF_TINT_Grayscale = 0x10000, - RF_TINT_Invert = 0x20000, - RF_TINT_Colorize = 0x40000, - RF_TINT_BLEND_Screen = 0x80000, - RF_TINT_BLEND_Overlay = 0x100000, - RF_TINT_BLEND_Hardlight = 0x200000, - RF_TINT_BLENDMASK = RF_TINT_BLEND_Screen | RF_TINT_BLEND_Overlay | RF_TINT_BLEND_Hardlight, - RF_TINT_MASK = 0x3f0000, - - STF_BLEND = 1, - STF_COLORMASK = 2, - STF_DEPTHMASK = 4, - STF_DEPTHTEST = 8, - STF_STENCILWRITE = 32, - STF_STENCILTEST = 64, - STF_CULLCW = 128, - STF_CULLCCW = 256, - STF_CLEARCOLOR = 1024, - STF_CLEARDEPTH = 2048, - STF_VIEWPORTSET = 4096, - STF_SCISSORSET = 8192, -}; - -struct PolymostTextureState -{ - FGameTexture* mTexture = nullptr; - EUpscaleFlags uFlags; - int mScaleFlags; - int mClampMode; - int mTranslation; - int mOverrideShader; - bool mChanged; - - void Reset() - { - mTexture = nullptr; - uFlags = UF_None; - mScaleFlags = 0; - mTranslation = 0; - mClampMode = CLAMP_NONE; - mOverrideShader = -1; - mChanged = false; - } -}; - -struct PolymostRenderState -{ - int vindex, vcount, primtype; - int Shade; - int drawblack = false; - float ShadeDiv = 62.f; - float VisFactor = 128.f; - int Flags = 0; - int TextureMode = TM_NORMAL; - FVector2 NPOTEmulation = { 0.f, 0.f }; - float AlphaThreshold = 0.5f; - bool AlphaTest = true; - float Color[4] = { 1,1,1,1 }; - short matrixIndex[NUMMATRICES] = { -1 }; - FDepthBiasState mBias{ }; - PolymostTextureState mMaterial; - FModel* model = nullptr; - int mframes[2] = { 0,0 }; - float mfactor = 0; - - int StateFlags = STF_COLORMASK|STF_DEPTHMASK; - FRenderStyle Style{}; - int DepthFunc = 1; - PalEntry ClearColor = 0; - short vp_x, vp_y, vp_w, vp_h; - short sc_x = SHRT_MIN, sc_y, sc_w, sc_h; - - PalEntry FogColor; - - bool Apply(FRenderState & state, GLState& oldState); -};