From d42ce0ee7e12cee68f4b105a1f4d4bbb251d3973 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 20 Mar 2021 23:01:16 +0100 Subject: [PATCH] - WIP --- source/CMakeLists.txt | 1 + source/build/include/buildtypes.h | 16 ++ source/build/src/engine.cpp | 61 ++-- source/build/src/polymost.cpp | 4 +- source/core/gamefuncs.cpp | 31 ++ source/core/gamefuncs.h | 1 + source/core/gamestruct.h | 1 + source/core/maploader.cpp | 1 + source/core/rendering/hw_entrypoint.cpp | 29 +- source/core/rendering/render.h | 9 +- source/core/rendering/scene/hw_drawinfo.h | 1 + source/core/savegamehelp.cpp | 2 + source/games/blood/all.cpp | 4 + source/games/blood/src/_polymost.cpp | 336 ++++++++++++++++++++++ source/games/blood/src/animatesprite.cpp | 5 + source/games/blood/src/blood.h | 22 +- source/games/blood/src/bloodactor.h | 8 - source/games/blood/src/mirrors.cpp | 281 +----------------- source/games/blood/src/misc.h | 4 +- source/games/blood/src/nnexts.cpp | 1 - source/games/blood/src/nnexts.h | 3 +- source/games/blood/src/view.cpp | 311 +++++++++----------- 22 files changed, 612 insertions(+), 520 deletions(-) create mode 100644 source/games/blood/src/_polymost.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index c431ea50c..5eb2b6fa0 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1284,6 +1284,7 @@ set (PCH_SOURCES games/exhumed/all.cpp games/blood/all.cpp games/sw/all.cpp + ) if( ${HAVE_VM_JIT} ) diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index c8d543821..649b22bbc 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -32,6 +32,20 @@ enum CSTAT_SECTOR_METHOD = 384 }; +enum +{ + PORTAL_SECTOR_FLOOR = 1, + PORTAL_SECTOR_CEILING = 2, + PORTAL_SECTOR_FLOOR_REFLECT = 4, + PORTAL_SECTOR_CEILING_REFLECT = 8, +}; + +enum +{ + PORTAL_WALL_VIEW = 1, + PORTAL_WALL_MIRROR = 2, +}; + //40 bytes struct sectortype { @@ -53,6 +67,7 @@ struct sectortype uint8_t dirty; float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_; + uint8_t portalflags; int ceilingxpan() const { return int(ceilingxpan_); } int ceilingypan() const { return int(ceilingypan_); } @@ -104,6 +119,7 @@ struct walltype int16_t extra; float xpan_, ypan_; angle_t clipangle; + uint8_t portalflags; int xpan() const { return int(xpan_); } int ypan() const { return int(ypan_); } diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 1d9275964..6da516082 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -849,71 +849,42 @@ CVAR(Bool, testnewinterface, true, 0) int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int16_t dacursectnum) { - for (int i = 0; i < numwalls; ++i) - { - if (wall[i].cstat & CSTAT_WALL_ROTATE_90) - { - auto& w = wall[i]; - auto& tile = RotTile(w.picnum + animateoffs(w.picnum, 16384)); - - if (tile.newtile == -1 && tile.owner == -1) - { - auto owner = w.picnum + animateoffs(w.picnum, 16384); - - tile.newtile = TileFiles.tileCreateRotated(owner); - assert(tile.newtile != -1); - - RotTile(tile.newtile).owner = w.picnum + animateoffs(w.picnum, 16384); - - } - } - } - - - int32_t i; + checkRotatedWalls(); if (gl_fogmode == 1) gl_fogmode = 2; // only radial fog works with Build's screwed up coordinate system. - set_globalpos(daposx, daposy, daposz); - set_globalang(daang); - - global100horiz = dahoriz; - - // xdimenscale is Scale(xdimen,yxaspect,320); - // normalization by viewingrange so that center-of-aim doesn't depend on it - qglobalhoriz = MulScale(dahoriz, DivScale(xdimenscale, viewingrange, 16), 16)+IntToFixed(ydimen>>1); - - globalcursectnum = dacursectnum; - - memset(gotsector, 0, sizeof(gotsector)); - - i = xdimen-1; - // Update starting sector number (common to classic and Polymost). // ADJUST_GLOBALCURSECTNUM. - if (globalcursectnum >= MAXSECTORS) - globalcursectnum -= MAXSECTORS; + if (dacursectnum >= MAXSECTORS) + dacursectnum -= MAXSECTORS; else { - i = globalcursectnum; - updatesector(globalposx,globalposy,&globalcursectnum); - if (globalcursectnum < 0) globalcursectnum = i; + 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 (globalcursectnum<0) + if (dacursectnum < 0) return 0; } if (!testnewrenderer) { + set_globalpos(daposx, daposy, daposz); + set_globalang(daang); + + global100horiz = dahoriz; + + memset(gotsector, 0, sizeof(gotsector)); + qglobalhoriz = MulScale(dahoriz, DivScale(xdimenscale, viewingrange, 16), 16) + IntToFixed(ydimen >> 1); + globalcursectnum = dacursectnum; Polymost::polymost_drawrooms(); } else { vec3_t pos = { daposx, daposy, daposz }; - //if (!testnewinterface) render_drawrooms_(pos, globalcursectnum, daang, dahoriz, rollang, r_fov, false, false); - /*else*/ render_drawrooms(pos, globalcursectnum, daang, dahoriz, rollang, false, false); + render_drawrooms(nullptr, pos, dacursectnum, daang, dahoriz, rollang, 0); } return inpreparemirror; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 9c1ee60cf..9d5170ea1 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -2075,7 +2075,7 @@ void polymost_drawrooms() { polymost_outputGLDebugMessage(3, "polymost_drawrooms()"); - GLInterface.ClearDepth(); + GLInterface.ClearDepth(); GLInterface.EnableBlend(false); GLInterface.EnableAlphaTest(false); GLInterface.EnableDepthTest(true); @@ -2477,7 +2477,7 @@ void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang gvrcorrection = viewingrange*(1.f/65536.f); //if (glprojectionhacks == 2) { - // calculates the extend of the zenith glitch + // 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 diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index 79c0a8b29..e8c0bd355 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -260,6 +260,37 @@ void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out) } +//========================================================================== +// +// Check if some walls are set to be rotated textures. +// Ideally this should just have been done with texture rotation, +// but the effects on the render code would be too severe due to the alignment mess. +// +//========================================================================== + +void checkRotatedWalls() +{ + for (int i = 0; i < numwalls; ++i) + { + if (wall[i].cstat & CSTAT_WALL_ROTATE_90) + { + auto& w = wall[i]; + auto& tile = RotTile(w.picnum + animateoffs(w.picnum, 16384)); + + if (tile.newtile == -1 && tile.owner == -1) + { + auto owner = w.picnum + animateoffs(w.picnum, 16384); + + tile.newtile = TileFiles.tileCreateRotated(owner); + assert(tile.newtile != -1); + + RotTile(tile.newtile).owner = w.picnum + animateoffs(w.picnum, 16384); + + } + } + } +} + //========================================================================== // // vector serializers diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index 47b47c251..e228a5e6a 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -12,6 +12,7 @@ void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, fl void setWallSectors(); void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out); void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out); +void checkRotatedWalls(); // y is negated so that the orientation is the same as in GZDoom, in order to use its utilities. // The render code should NOT use Build coordinates for anything! diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index 66359440e..5a073cd35 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -101,6 +101,7 @@ struct GameInterface virtual int chaseCamX(binangle ang) { return 0; } virtual int chaseCamY(binangle ang) { return 0; } virtual int chaseCamZ(fixedhoriz horiz) { return 0; } + virtual void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) {} virtual FString statFPS() { diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index 1ad84180e..cd36a0c7e 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -43,6 +43,7 @@ #include "gamecontrol.h" #include "gamefuncs.h" #include "sectorgeometry.h" +#include "render.h" static void ReadSectorV7(FileReader& fr, sectortype& sect) diff --git a/source/core/rendering/hw_entrypoint.cpp b/source/core/rendering/hw_entrypoint.cpp index 3de35aa53..24f0cb03d 100644 --- a/source/core/rendering/hw_entrypoint.cpp +++ b/source/core/rendering/hw_entrypoint.cpp @@ -31,16 +31,10 @@ //#include "a_dynlight.h" #include "v_video.h" #include "m_png.h" -//#include "doomstat.h" -//#include "r_data/r_interpolate.h" -//#include "r_utility.h" -//#include "d_player.h" #include "i_time.h" #include "hw_dynlightdata.h" #include "hw_clock.h" #include "flatvertices.h" -//#include "v_palette.h" -//#include "d_main.h" #include "hw_renderstate.h" #include "hw_lightbuffer.h" @@ -49,12 +43,12 @@ #include "hw_clipper.h" //#include "hwrenderer/scene/hw_portal.h" #include "hw_vrmodes.h" -//#include "g_levellocals.h" #include "hw_drawstructs.h" #include "hw_drawlist.h" #include "hw_drawinfo.h" #include "gamecvars.h" +#include "render.h" EXTERN_CVAR(Bool, cl_capfps) bool NoInterpolateView; @@ -178,9 +172,10 @@ void RenderViewpoint(FRenderViewpoint& mainvp, IntRect* bounds, float fov, float // //=========================================================================== -FRenderViewpoint SetupView(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang) +FRenderViewpoint SetupView(spritetype* cam, const vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang) { FRenderViewpoint r_viewpoint{}; + r_viewpoint.CameraSprite = cam; r_viewpoint.SectNum = sectnum; r_viewpoint.Pos = { position.x / 16.f, position.y / -16.f, position.z / -256.f }; r_viewpoint.HWAngles.Yaw = -90.f + q16ang(q16angle).asdeg(); @@ -269,13 +264,25 @@ static void CheckTimer(FRenderState &state, uint64_t ShaderStartTime) } -void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, bool mirror, bool planemirror) +void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, int flags) { + checkRotatedWalls(); + + if (gl_fogmode == 1) gl_fogmode = 2; // still needed? + + if (flags & RSF_UPDATESECTOR) + { + int16_t sect = sectnum; + updatesector(position.x, position.y, §); + if (sect >= 0) sectnum = sect; + if (sectnum < 0) return; + } + auto RenderState = screen->RenderState(); RenderState->SetVertexBuffer(screen->mVertexData); screen->mVertexData->Reset(); - FRenderViewpoint r_viewpoint = SetupView(position, sectnum, q16angle, q16horizon, rollang); + FRenderViewpoint r_viewpoint = SetupView(playersprite, position, sectnum, q16angle, q16horizon, rollang); iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0; checkBenchActive(); @@ -326,6 +333,6 @@ void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q screen->ImageTransitionScene(true); // Only relevant for Vulkan. - RenderViewpoint(r_viewpoint, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true); + RenderViewpoint(r_viewpoint, nullptr, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, flags & RSF_MIRROR, flags & RSF_PLANEMIRROR); All.Unclock(); } diff --git a/source/core/rendering/render.h b/source/core/rendering/render.h index 59c31eb8f..6026528f9 100644 --- a/source/core/rendering/render.h +++ b/source/core/rendering/render.h @@ -1,4 +1,11 @@ #pragma once #include "build.h" -void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, bool mirror, bool planemirror); +void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, int flags); + +enum ERenderSceneFlags +{ + RSF_MIRROR = 1, + RSF_PLANEMIRROR = 2, + RSF_UPDATESECTOR = 4, +}; diff --git a/source/core/rendering/scene/hw_drawinfo.h b/source/core/rendering/scene/hw_drawinfo.h index c86e908dd..3ddd9b4b2 100644 --- a/source/core/rendering/scene/hw_drawinfo.h +++ b/source/core/rendering/scene/hw_drawinfo.h @@ -35,6 +35,7 @@ class FRenderState; struct FRenderViewpoint { + spritetype* CameraSprite; DVector3 Pos; FRotator HWAngles; FAngle FieldOfView; diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index 3e9faf194..f92d1a2c1 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -554,6 +554,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectort ("lotag", c.lotag, def->lotag) ("hitag", c.hitag, def->hitag) ("extra", c.extra, def->extra) + ("portalflags", c.portalflags, def->portalflags) .EndObject(); } return arc; @@ -580,6 +581,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype ("lotag", c.lotag, def->lotag) ("hitag", c.hitag, def->hitag) ("extra", c.extra, def->extra) + ("portalflags", c.portalflags, def->portalflags) .EndObject(); } return arc; diff --git a/source/games/blood/all.cpp b/source/games/blood/all.cpp index 23658ca4d..0c1757af6 100644 --- a/source/games/blood/all.cpp +++ b/source/games/blood/all.cpp @@ -66,5 +66,9 @@ #include "src/view.cpp" #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 new file mode 100644 index 000000000..b4910e487 --- /dev/null +++ b/source/games/blood/src/_polymost.cpp @@ -0,0 +1,336 @@ + +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; + int nSprite; + SectIterator it(nSector); + while ((nSprite = it.NextIndex()) >= 0) + { + spritetype* pSprite = &sprite[nSprite]; + if (pSprite == gView->pSprite) + continue; + int top, bottom; + GetSpriteExtents(pSprite, &top, &bottom); + int zCeil, zFloor; + getzsofslope(nSector, pSprite->x, pSprite->y, &zCeil, &zFloor); + if (pSprite->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; + tspritetype* pTSprite = &tsprite[spritesortcnt++]; + *pTSprite = {}; + pTSprite->type = pSprite->type; + pTSprite->index = pSprite->index; + pTSprite->sectnum = nSector2; + pTSprite->x = pSprite->x + dx; + pTSprite->y = pSprite->y + dy; + pTSprite->z = pSprite->z + dz; + pTSprite->ang = pSprite->ang; + pTSprite->picnum = pSprite->picnum; + pTSprite->shade = pSprite->shade; + pTSprite->pal = pSprite->pal; + pTSprite->xrepeat = pSprite->xrepeat; + pTSprite->yrepeat = pSprite->yrepeat; + pTSprite->xoffset = pSprite->xoffset; + pTSprite->yoffset = pSprite->yoffset; + pTSprite->cstat = pSprite->cstat; + pTSprite->statnum = kStatDecoration; + pTSprite->owner = pSprite->index; + pTSprite->extra = pSprite->extra; + pTSprite->flags = pSprite->hitag | 0x200; + pTSprite->x = dx + interpolate(pSprite->ox, pSprite->x, interpolation); + pTSprite->y = dy + interpolate(pSprite->oy, pSprite->y, interpolation); + pTSprite->z = dz + interpolate(pSprite->oz, pSprite->z, interpolation); + pTSprite->ang = pSprite->interpolatedang(interpolation); + + int nAnim = 0; + switch (picanm[pTSprite->picnum].extra & 7) + { + case 1: + { + int dX = x - pTSprite->x; + int dY = y - pTSprite->y; + RotateVector(&dX, &dY, 128 - pTSprite->ang); + nAnim = GetOctant(dX, dY); + if (nAnim <= 4) + { + pTSprite->cstat &= ~4; + } + else + { + nAnim = 8 - nAnim; + pTSprite->cstat |= 4; + } + break; + } + case 2: + { + int dX = x - pTSprite->x; + int dY = y - pTSprite->y; + RotateVector(&dX, &dY, 128 - pTSprite->ang); + nAnim = GetOctant(dX, dY); + break; + } + } + while (nAnim > 0) + { + pTSprite->picnum += picanm[pTSprite->picnum].num + 1; + nAnim--; + } + + spritesortcnt++; + } + } + +} + +void processSpritesOnOtherSideOfPortal(int x, int y, int interpolation) +{ + if (spritesortcnt == 0) return; + int nViewSprites = spritesortcnt-1; + for (int nTSprite = nViewSprites; nTSprite >= 0; nTSprite--) + { + tspritetype *pTSprite = &tsprite[nTSprite]; + pTSprite->xrepeat = pTSprite->yrepeat = 0; + } + for (int i = mirrorcnt-1; i >= 0; i--) + { + int nTile = 4080+i; + if (TestBitString(gotpic, 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) +{ + int yxAspect = yxaspect; + int viewingRange = viewingrange; + videoSetCorrectedAspect(); + + int v1 = xs_CRoundToInt(double(viewingrange) * tan(r_fov * (pi::pi() / 360.))); + + renderSetAspect(v1, yxaspect); + + + int ceilingZ, floorZ; + getzsofslope(nSectnum, cX, cY, &ceilingZ, &floorZ); + if (cZ >= floorZ) + { + cZ = floorZ - (gUpperLink[nSectnum] >= 0 ? 0 : (8 << 8)); + } + if (cZ <= ceilingZ) + { + cZ = ceilingZ + (gLowerLink[nSectnum] >= 0 ? 0 : (8 << 8)); + } + cH = q16horiz(ClipRange(cH.asq16(), gi->playerHorizMin(), gi->playerHorizMax())); +RORHACK: + int ror_status[16]; + for (int i = 0; i < 16; i++) + ror_status[i] = TestBitString(gotpic, 4080 + i); + fixed_t deliriumPitchI = interpolate(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate); + DrawMirrors(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, gInterpolate, gViewIndex); + int bakCstat = gView->pSprite->cstat; + if (gViewPos == 0) + { + gView->pSprite->cstat |= 32768; + } + else + { + gView->pSprite->cstat |= 514; + } + + renderDrawRoomsQ16(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, nSectnum); + viewProcessSprites(cX, cY, cZ, cA.asbuild(), gInterpolate); + bool do_ror_hack = false; + for (int i = 0; i < 16; i++) + if (ror_status[i] != TestBitString(gotpic, 4080 + i)) + do_ror_hack = true; + if (do_ror_hack) + { + gView->pSprite->cstat = bakCstat; + spritesortcnt = 0; + goto RORHACK; + } + setPortalFlags(1); + int nSpriteSortCnt = spritesortcnt; + renderDrawMasks(); + spritesortcnt = nSpriteSortCnt; + setPortalFlags(0); + processSpritesOnOtherSideOfPortal(cX, cY, gInterpolate); + renderDrawMasks(); + gView->pSprite->cstat = bakCstat; + +} + +// hack the portal planes with the sky flag for rendering. Only Polymost needs this hack. +void setPortalFlags(char mode) +{ + for (int i = mirrorcnt - 1; i >= 0; i--) + { + int nTile = 4080 + i; + if (TestBitString(gotpic, nTile)) + { + switch (mirror[i].type) + { + case 1: + if (mode) + sector[mirror[i].wallnum].ceilingstat |= 1; + else + sector[mirror[i].wallnum].ceilingstat &= ~1; + break; + case 2: + if (mode) + sector[mirror[i].wallnum].floorstat |= 1; + else + sector[mirror[i].wallnum].floorstat &= ~1; + break; + } + } + } +} + + +void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer) +{ + for (int i = mirrorcnt - 1; i >= 0; i--) + { + int nTile = 4080 + i; + if (TestBitString(gotpic, nTile)) + { + ClearBitString(gotpic, nTile); + switch (mirror[i].type) + { + case 0: + { + int nWall = mirror[i].link; + int nSector = sectorofwall(nWall); + walltype* pWall = &wall[nWall]; + int nNextWall = pWall->nextwall; + int nNextSector = pWall->nextsector; + pWall->nextwall = mirrorwall[0]; + pWall->nextsector = mirrorsector; + wall[mirrorwall[0]].nextwall = nWall; + wall[mirrorwall[0]].nextsector = nSector; + wall[mirrorwall[0]].x = wall[pWall->point2].x; + wall[mirrorwall[0]].y = wall[pWall->point2].y; + wall[mirrorwall[1]].x = pWall->x; + wall[mirrorwall[1]].y = pWall->y; + wall[mirrorwall[2]].x = wall[mirrorwall[1]].x + (wall[mirrorwall[1]].x - wall[mirrorwall[0]].x) * 16; + wall[mirrorwall[2]].y = wall[mirrorwall[1]].y + (wall[mirrorwall[1]].y - wall[mirrorwall[0]].y) * 16; + wall[mirrorwall[3]].x = wall[mirrorwall[0]].x + (wall[mirrorwall[0]].x - wall[mirrorwall[1]].x) * 16; + wall[mirrorwall[3]].y = wall[mirrorwall[0]].y + (wall[mirrorwall[0]].y - wall[mirrorwall[1]].y) * 16; + sector[mirrorsector].floorz = sector[nSector].floorz; + sector[mirrorsector].ceilingz = sector[nSector].ceilingz; + int cx, cy, ca; + if (GetWallType(nWall) == kWallStack) + { + cx = x - (wall[pWall->hitag].x - wall[pWall->point2].x); + cy = y - (wall[pWall->hitag].y - wall[pWall->point2].y); + ca = a; + } + else + { + renderPrepareMirror(x, y, z, a, horiz, nWall, &cx, &cy, &ca); + } + int32_t didmirror = renderDrawRoomsQ16(cx, cy, z, ca, horiz, mirrorsector | MAXSECTORS); + viewProcessSprites(cx, cy, z, FixedToInt(ca), smooth); + renderDrawMasks(); + if (GetWallType(nWall) != kWallStack) + renderCompleteMirror(); + if (wall[nWall].pal != 0 || wall[nWall].shade != 0) + TranslateMirrorColors(wall[nWall].shade, wall[nWall].pal); + pWall->nextwall = nNextWall; + pWall->nextsector = nNextSector; + return; + } + case 1: + { + r_rorphase = 1; + int nSector = mirror[i].link; + int bakCstat; + if (viewPlayer >= 0) + { + bakCstat = gPlayer[viewPlayer].pSprite->cstat; + if (gViewPos == 0) + { + gPlayer[viewPlayer].pSprite->cstat |= 32768; + } + else + { + gPlayer[viewPlayer].pSprite->cstat |= 514; + } + } + renderDrawRoomsQ16(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, a, horiz, nSector | MAXSECTORS); + viewProcessSprites(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, FixedToInt(a), smooth); + short fstat = sector[nSector].floorstat; + sector[nSector].floorstat |= 1; + renderDrawMasks(); + sector[nSector].floorstat = fstat; + for (int i = 0; i < 16; i++) + ClearBitString(gotpic, 4080 + i); + if (viewPlayer >= 0) + { + gPlayer[viewPlayer].pSprite->cstat = bakCstat; + } + r_rorphase = 0; + return; + } + case 2: + { + r_rorphase = 1; + int nSector = mirror[i].link; + int bakCstat; + if (viewPlayer >= 0) + { + bakCstat = gPlayer[viewPlayer].pSprite->cstat; + if (gViewPos == 0) + { + gPlayer[viewPlayer].pSprite->cstat |= 32768; + } + else + { + gPlayer[viewPlayer].pSprite->cstat |= 514; + } + } + renderDrawRoomsQ16(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, a, horiz, nSector | MAXSECTORS); + viewProcessSprites(x + mirror[i].dx, y + mirror[i].dy, z + mirror[i].dz, FixedToInt(a), smooth); + short cstat = sector[nSector].ceilingstat; + sector[nSector].ceilingstat |= 1; + renderDrawMasks(); + sector[nSector].ceilingstat = cstat; + for (int i = 0; i < 16; i++) + ClearBitString(gotpic, 4080 + i); + if (viewPlayer >= 0) + { + gPlayer[viewPlayer].pSprite->cstat = bakCstat; + } + r_rorphase = 0; + return; + } + } + } + } +} + + + +END_BLD_NS diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index d6cee051e..536ae1d5d 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -887,4 +887,9 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t } +void GameInterface::processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) +{ + viewProcessSprites(viewx, viewy, viewz, viewang.asbuild(), int(smoothRatio)); +} + END_BLD_NS diff --git a/source/games/blood/src/blood.h b/source/games/blood/src/blood.h index 2154cbf29..b16a315f6 100644 --- a/source/games/blood/src/blood.h +++ b/source/games/blood/src/blood.h @@ -35,7 +35,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "ai.h" #include "aistate.h" #include "aiunicult.h" -#include "blood.h" #include "callback.h" #include "db.h" #include "endgame.h" @@ -83,6 +82,20 @@ void ProcessFrame(void); void ScanINIFiles(void); void EndLevel(); +struct MIRROR +{ + int type; + int link; + int dx; + int dy; + int dz; + int wallnum; +}; + +extern MIRROR mirror[16]; +extern int mirrorcnt, mirrorsector, mirrorwall[4]; + + inline bool DemoRecordStatus(void) { return false; @@ -131,9 +144,10 @@ struct GameInterface : ::GameInterface void ToggleThirdPerson() override; void SwitchCoopView() override; void ToggleShowWeapon() override; - int chaseCamX(binangle ang) { return MulScale(-Cos(ang.asbuild()), 1280, 30); } - int chaseCamY(binangle ang) { return MulScale(-Sin(ang.asbuild()), 1280, 30); } - int chaseCamZ(fixedhoriz horiz) { return FixedToInt(MulScale(horiz.asq16(), 1280, 3)) - (16 << 8); } + int chaseCamX(binangle ang) override { return MulScale(-Cos(ang.asbuild()), 1280, 30); } + int chaseCamY(binangle ang) override { return MulScale(-Sin(ang.asbuild()), 1280, 30); } + int chaseCamZ(fixedhoriz horiz) override { return FixedToInt(MulScale(horiz.asq16(), 1280, 3)) - (16 << 8); } + void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override; GameStats getStats() override; }; diff --git a/source/games/blood/src/bloodactor.h b/source/games/blood/src/bloodactor.h index 544bc9c1f..afab01824 100644 --- a/source/games/blood/src/bloodactor.h +++ b/source/games/blood/src/bloodactor.h @@ -1,13 +1,5 @@ #pragma once -#include "build.h" -#include "common_game.h" -#include "db.h" -#include "ai.h" -#include "nnexts.h" -#include "seq.h" -#include "aiunicult.h" - BEGIN_BLD_NS extern int cumulDamage[kMaxXSprites]; diff --git a/source/games/blood/src/mirrors.cpp b/source/games/blood/src/mirrors.cpp index 5bce8e6ca..8dfe0d9fa 100644 --- a/source/games/blood/src/mirrors.cpp +++ b/source/games/blood/src/mirrors.cpp @@ -23,23 +23,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "ns.h" // Must come before everything else! #include "build.h" -#include "compat.h" -#include "blood.h" +#include "automap.h" +#include "mmulti.h" +#include "savegamehelp.h" + +#include "blood.h" BEGIN_BLD_NS int mirrorcnt, mirrorsector, mirrorwall[4]; -typedef struct -{ - int type; - int link; - int dx; - int dy; - int dz; - int wallnum; -} MIRROR; - MIRROR mirror[16]; void InitMirrors(void) @@ -64,6 +57,7 @@ void InitMirrors(void) if (wall[i].extra > 0 && GetWallType(i) == kWallStack) { wall[i].overpicnum = nTile; + wall[i].portalflags = PORTAL_WALL_VIEW; mirror[mirrorcnt].wallnum = i; mirror[mirrorcnt].type = 0; wall[i].cstat |= 32; @@ -96,6 +90,7 @@ void InitMirrors(void) wall[i].picnum = nTile; mirror[mirrorcnt].type = 0; wall[i].cstat |= 32; + wall[i].portalflags = PORTAL_WALL_MIRROR; mirrorcnt++; continue; } @@ -121,6 +116,7 @@ void InitMirrors(void) mirror[mirrorcnt].wallnum = i; mirror[mirrorcnt].link = j; sector[i].floorpicnum = 4080+mirrorcnt; + sector[i].portalflags = PORTAL_SECTOR_FLOOR; mirrorcnt++; mirror[mirrorcnt].type = 1; mirror[mirrorcnt].dx = sprite[nLink].x-sprite[nLink2].x; @@ -129,10 +125,12 @@ void InitMirrors(void) mirror[mirrorcnt].wallnum = j; mirror[mirrorcnt].link = i; sector[j].ceilingpicnum = 4080+mirrorcnt; + sector[j].portalflags = PORTAL_SECTOR_CEILING; mirrorcnt++; } } mirrorsector = numsectors; +#if 1 // The new backend won't need this shit anymore. for (int i = 0; i < 4; i++) { mirrorwall[i] = numwalls+i; @@ -148,270 +146,13 @@ void InitMirrors(void) sector[mirrorsector].floorpicnum = 504; sector[mirrorsector].wallptr = mirrorwall[0]; sector[mirrorsector].wallnum = 4; +#endif } void TranslateMirrorColors(int nShade, int nPalette) { } -void sub_5571C(char mode) -{ - for (int i = mirrorcnt-1; i >= 0; i--) - { - int nTile = 4080+i; - if (TestBitString(gotpic, nTile)) - { - switch (mirror[i].type) - { - case 1: - if (mode) - sector[mirror[i].wallnum].ceilingstat |= 1; - else - sector[mirror[i].wallnum].ceilingstat &= ~1; - break; - case 2: - if (mode) - sector[mirror[i].wallnum].floorstat |= 1; - else - sector[mirror[i].wallnum].floorstat &= ~1; - break; - } - } - } -} - -void sub_557C4(int x, int y, int interpolation) -{ - if (spritesortcnt == 0) return; - int nViewSprites = spritesortcnt-1; - for (int nTSprite = nViewSprites; nTSprite >= 0; nTSprite--) - { - tspritetype *pTSprite = &tsprite[nTSprite]; - pTSprite->xrepeat = pTSprite->yrepeat = 0; - } - for (int i = mirrorcnt-1; i >= 0; i--) - { - int nTile = 4080+i; - if (TestBitString(gotpic, nTile)) - { - if (mirror[i].type == 1 || mirror[i].type == 2) - { - int nSector = mirror[i].link; - int nSector2 = mirror[i].wallnum; - int nSprite; - SectIterator it(nSector); - while ((nSprite = it.NextIndex()) >= 0) - { - spritetype *pSprite = &sprite[nSprite]; - if (pSprite == gView->pSprite) - continue; - int top, bottom; - GetSpriteExtents(pSprite, &top, &bottom); - int zCeil, zFloor; - getzsofslope(nSector, pSprite->x, pSprite->y, &zCeil, &zFloor); - if (pSprite->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; - tspritetype *pTSprite = &tsprite[spritesortcnt]; - memset(pTSprite, 0, sizeof(tspritetype)); - pTSprite->type = pSprite->type; - pTSprite->index = pSprite->index; - pTSprite->sectnum = nSector2; - pTSprite->x = pSprite->x+dx; - pTSprite->y = pSprite->y+dy; - pTSprite->z = pSprite->z+dz; - pTSprite->ang = pSprite->ang; - pTSprite->picnum = pSprite->picnum; - pTSprite->shade = pSprite->shade; - pTSprite->pal = pSprite->pal; - pTSprite->xrepeat = pSprite->xrepeat; - pTSprite->yrepeat = pSprite->yrepeat; - pTSprite->xoffset = pSprite->xoffset; - pTSprite->yoffset = pSprite->yoffset; - pTSprite->cstat = pSprite->cstat; - pTSprite->statnum = kStatDecoration; - pTSprite->owner = pSprite->index; - pTSprite->extra = pSprite->extra; - pTSprite->flags = pSprite->hitag|0x200; - pTSprite->x = dx+interpolate(pSprite->ox, pSprite->x, interpolation); - pTSprite->y = dy+interpolate(pSprite->oy, pSprite->y, interpolation); - pTSprite->z = dz+interpolate(pSprite->oz, pSprite->z, interpolation); - pTSprite->ang = pSprite->interpolatedang(interpolation); - spritesortcnt++; - } - } - } - } - } - for (int nTSprite = spritesortcnt-1; nTSprite >= nViewSprites; nTSprite--) - { - tspritetype *pTSprite = &tsprite[nTSprite]; - int nAnim = 0; - switch (picanm[pTSprite->picnum].extra&7) - { - case 1: - { - int dX = x - pTSprite->x; - int dY = y - pTSprite->y; - RotateVector(&dX, &dY, 128 - pTSprite->ang); - nAnim = GetOctant(dX, dY); - if (nAnim <= 4) - { - pTSprite->cstat &= ~4; - } - else - { - nAnim = 8 - nAnim; - pTSprite->cstat |= 4; - } - break; - } - case 2: - { - int dX = x - pTSprite->x; - int dY = y - pTSprite->y; - RotateVector(&dX, &dY, 128 - pTSprite->ang); - nAnim = GetOctant(dX, dY); - break; - } - } - while (nAnim > 0) - { - pTSprite->picnum += picanm[pTSprite->picnum].num+1; - nAnim--; - } - } -} - -void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer) -{ - for (int i = mirrorcnt - 1; i >= 0; i--) - { - int nTile = 4080+i; - if (TestBitString(gotpic, nTile)) - { - ClearBitString(gotpic, nTile); - switch (mirror[i].type) - { - case 0: - { - int nWall = mirror[i].link; - int nSector = sectorofwall(nWall); - walltype *pWall = &wall[nWall]; - int nNextWall = pWall->nextwall; - int nNextSector = pWall->nextsector; - pWall->nextwall = mirrorwall[0]; - pWall->nextsector = mirrorsector; - wall[mirrorwall[0]].nextwall = nWall; - wall[mirrorwall[0]].nextsector = nSector; - wall[mirrorwall[0]].x = wall[pWall->point2].x; - wall[mirrorwall[0]].y = wall[pWall->point2].y; - wall[mirrorwall[1]].x = pWall->x; - wall[mirrorwall[1]].y = pWall->y; - wall[mirrorwall[2]].x = wall[mirrorwall[1]].x+(wall[mirrorwall[1]].x-wall[mirrorwall[0]].x)*16; - wall[mirrorwall[2]].y = wall[mirrorwall[1]].y+(wall[mirrorwall[1]].y-wall[mirrorwall[0]].y)*16; - wall[mirrorwall[3]].x = wall[mirrorwall[0]].x+(wall[mirrorwall[0]].x-wall[mirrorwall[1]].x)*16; - wall[mirrorwall[3]].y = wall[mirrorwall[0]].y+(wall[mirrorwall[0]].y-wall[mirrorwall[1]].y)*16; - sector[mirrorsector].floorz = sector[nSector].floorz; - sector[mirrorsector].ceilingz = sector[nSector].ceilingz; - int cx, cy, ca; - if (GetWallType(nWall) == kWallStack) - { - cx = x - (wall[pWall->hitag].x-wall[pWall->point2].x); - cy = y - (wall[pWall->hitag].y-wall[pWall->point2].y); - ca = a; - } - else - { - renderPrepareMirror(x,y,z,a,horiz,nWall,&cx,&cy,&ca); - } - int32_t didmirror = renderDrawRoomsQ16(cx, cy, z, ca,horiz,mirrorsector|MAXSECTORS); - viewProcessSprites(cx,cy,z,FixedToInt(ca),smooth); - renderDrawMasks(); - if (GetWallType(nWall) != kWallStack) - renderCompleteMirror(); - if (wall[nWall].pal != 0 || wall[nWall].shade != 0) - TranslateMirrorColors(wall[nWall].shade, wall[nWall].pal); - pWall->nextwall = nNextWall; - pWall->nextsector = nNextSector; - return; - } - case 1: - { - r_rorphase = 1; - int nSector = mirror[i].link; - int bakCstat; - if (viewPlayer >= 0) - { - bakCstat = gPlayer[viewPlayer].pSprite->cstat; - if (gViewPos == 0) - { - gPlayer[viewPlayer].pSprite->cstat |= 32768; - } - else - { - gPlayer[viewPlayer].pSprite->cstat |= 514; - } - } - renderDrawRoomsQ16(x+mirror[i].dx, y+mirror[i].dy, z+mirror[i].dz, a, horiz, nSector|MAXSECTORS); - viewProcessSprites(x+mirror[i].dx, y+mirror[i].dy, z+mirror[i].dz, FixedToInt(a), smooth); - short fstat = sector[nSector].floorstat; - sector[nSector].floorstat |= 1; - renderDrawMasks(); - sector[nSector].floorstat = fstat; - for (int i = 0; i < 16; i++) - ClearBitString(gotpic, 4080+i); - if (viewPlayer >= 0) - { - gPlayer[viewPlayer].pSprite->cstat = bakCstat; - } - r_rorphase = 0; - return; - } - case 2: - { - r_rorphase = 1; - int nSector = mirror[i].link; - int bakCstat; - if (viewPlayer >= 0) - { - bakCstat = gPlayer[viewPlayer].pSprite->cstat; - if (gViewPos == 0) - { - gPlayer[viewPlayer].pSprite->cstat |= 32768; - } - else - { - gPlayer[viewPlayer].pSprite->cstat |= 514; - } - } - renderDrawRoomsQ16(x+mirror[i].dx, y+mirror[i].dy, z+mirror[i].dz, a, horiz, nSector|MAXSECTORS); - viewProcessSprites(x+mirror[i].dx, y+mirror[i].dy, z+mirror[i].dz, FixedToInt(a), smooth); - short cstat = sector[nSector].ceilingstat; - sector[nSector].ceilingstat |= 1; - renderDrawMasks(); - sector[nSector].ceilingstat = cstat; - for (int i = 0; i < 16; i++) - ClearBitString(gotpic, 4080+i); - if (viewPlayer >= 0) - { - gPlayer[viewPlayer].pSprite->cstat = bakCstat; - } - r_rorphase = 0; - return; - } - } - } - } -} - //--------------------------------------------------------------------------- // // diff --git a/source/games/blood/src/misc.h b/source/games/blood/src/misc.h index f4943eb37..cea185bf6 100644 --- a/source/games/blood/src/misc.h +++ b/source/games/blood/src/misc.h @@ -37,8 +37,8 @@ void FireInit(void); void FireProcess(void); void UpdateNetworkMenus(void); void InitMirrors(void); -void sub_5571C(char mode); -void sub_557C4(int x, int y, int interpolation); +void setPortalFlags(char mode); +void processSpritesOnOtherSideOfPortal(int x, int y, int interpolation); void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer); int qanimateoffs(int a1, int a2); void HookReplaceFunctions(); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index f90fb1199..d06e420b0 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -34,7 +34,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "mmulti.h" #include "blood.h" #include "savegamehelp.h" -#include "bloodactor.h" BEGIN_BLD_NS diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index bb678dccb..3a1ef8f85 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -355,10 +355,11 @@ XSPRITE* evrListRedirectors(int objType, int objXIndex, XSPRITE* pXRedir, int* t XSPRITE* evrIsRedirector(int nSprite); int listTx(XSPRITE* pXRedir, int tx); void seqSpawnerOffSameTx(XSPRITE* pXSource); -#endif //////////////////////////////////////////////////////////////////////// // This file provides modern features for mappers. // For full documentation please visit http://cruo.bloodgame.ru/xxsystem //////////////////////////////////////////////////////////////////////////////////// END_BLD_NS + +#endif diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp index 3430425d7..1bfc9f1fd 100644 --- a/source/games/blood/src/view.cpp +++ b/source/games/blood/src/view.cpp @@ -42,8 +42,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "automap.h" #include "gamefuncs.h" #include "v_draw.h" +#include "render.h" #include "glbackend/glbackend.h" +EXTERN_CVAR(Bool, testnewrenderer) BEGIN_BLD_NS FixedBitArray gInterpolateSprite; @@ -450,6 +452,101 @@ static void DrawMap(spritetype* pSprite) setViewport(hud_size); } +void SetupView(int &cX, int& cY, int& cZ, binangle& cA, fixedhoriz& cH, int& nSectnum, double& zDelta) +{ + int bobWidth, bobHeight; + lookangle rotscrnang; + double shakeX, shakeY; + nSectnum = gView->pSprite->sectnum; + if (numplayers > 1 && gView == gMe && gPrediction && gMe->pXSprite->health > 0) + { + nSectnum = predict.sectnum; + cX = interpolate(predictOld.x, predict.x, gInterpolate); + cY = interpolate(predictOld.y, predict.y, gInterpolate); + cZ = interpolate(predictOld.viewz, predict.viewz, gInterpolate); + zDelta = finterpolate(predictOld.weaponZ, predict.weaponZ, gInterpolate); + bobWidth = interpolate(predictOld.bobWidth, predict.bobWidth, gInterpolate); + bobHeight = interpolate(predictOld.bobHeight, predict.bobHeight, gInterpolate); + shakeX = finterpolate(predictOld.shakeBobX, predict.shakeBobX, gInterpolate); + shakeY = finterpolate(predictOld.shakeBobY, predict.shakeBobY, gInterpolate); + + if (!SyncInput()) + { + cA = bamang(predict.angle.asbam() + predict.look_ang.asbam()); + cH = predict.horiz + predict.horizoff; + rotscrnang = predict.rotscrnang; + } + else + { + uint32_t oang = predictOld.angle.asbam() + predictOld.look_ang.asbam(); + uint32_t ang = predict.angle.asbam() + predict.look_ang.asbam(); + cA = interpolateangbin(oang, ang, gInterpolate); + + fixed_t ohoriz = (predictOld.horiz + predictOld.horizoff).asq16(); + fixed_t horiz = (predict.horiz + predict.horizoff).asq16(); + cH = q16horiz(interpolate(ohoriz, horiz, gInterpolate)); + + rotscrnang = interpolateanglook(predictOld.rotscrnang.asbam(), predict.rotscrnang.asbam(), gInterpolate); + } + } + else + { + VIEW* pView = &gPrevView[gViewIndex]; + cX = interpolate(pView->x, gView->pSprite->x, gInterpolate); + cY = interpolate(pView->y, gView->pSprite->y, gInterpolate); + cZ = interpolate(pView->viewz, gView->zView, gInterpolate); + zDelta = finterpolate(pView->weaponZ, gView->zWeapon - gView->zView - (12 << 8), gInterpolate); + bobWidth = interpolate(pView->bobWidth, gView->bobWidth, gInterpolate); + bobHeight = interpolate(pView->bobHeight, gView->bobHeight, gInterpolate); + shakeX = finterpolate(pView->shakeBobX, gView->swayWidth, gInterpolate); + shakeY = finterpolate(pView->shakeBobY, gView->swayHeight, gInterpolate); + + if (!SyncInput()) + { + cA = gView->angle.sum(); + cH = gView->horizon.sum(); + rotscrnang = gView->angle.rotscrnang; + } + else + { + cA = gView->angle.interpolatedsum(gInterpolate); + cH = gView->horizon.interpolatedsum(gInterpolate); + rotscrnang = gView->angle.interpolatedrotscrn(gInterpolate); + } + } + + viewUpdateShake(); + cH += buildhoriz(shakeHoriz); + cA += buildang(shakeAngle); + cX += shakeX; + cY += shakeY; + cZ += shakeZ; + shakeX += shakeBobX; + shakeY += shakeBobY; + cH += buildhoriz(MulScale(0x40000000 - Cos(gView->tiltEffect << 2), 30, 30)); + if (gViewPos == 0) + { + if (cl_viewhbob) + { + cX -= MulScale(bobWidth, Sin(cA.asbuild()), 30) >> 4; + cY += MulScale(bobWidth, Cos(cA.asbuild()), 30) >> 4; + } + if (cl_viewvbob) + { + cZ += bobHeight; + } + cZ += xs_CRoundToInt(cH.asq16() / 6553.6); + cameradist = -1; + cameraclock = PlayClock + MulScale(4, (int)gInterpolate, 16); + } + else + { + calcChaseCamPos((int*)&cX, (int*)&cY, (int*)&cZ, gView->pSprite, (short*)&nSectnum, cA, cH, gInterpolate); + } + CheckLink((int*)&cX, (int*)&cY, (int*)&cZ, &nSectnum); + renderSetRollAngle(rotscrnang.asbuildf()); +} + void renderCrystalBall() { #if 0 @@ -541,23 +638,7 @@ RORHACKOTHER: #endif } -void render3DViewPolymost() -{ - int yxAspect = yxaspect; - int viewingRange = viewingrange; - videoSetCorrectedAspect(); - - int v1 = xs_CRoundToInt(double(viewingrange) * tan(r_fov * (pi::pi() / 360.))); - - renderSetAspect(v1, yxaspect); - -} - -// The hackery in this code necessitates separating the main render functions because the modern renderer does not need -// the messed up way to render portals. -void render3DViewModern() -{ -} +void render3DViewPolymost(int nSectnum, int cX, int cY, int cZ, binangle cA, fixedhoriz cH); void viewDrawScreen(bool sceneonly) { @@ -600,113 +681,25 @@ void viewDrawScreen(bool sceneonly) UpdateDacs(basepal); UpdateBlend(); - int cX, cY, cZ, bobWidth, bobHeight; - lookangle rotscrnang; + int cX, cY, cZ; binangle cA; fixedhoriz cH; - double zDelta, shakeX, shakeY; - int nSectnum = gView->pSprite->sectnum; - if (numplayers > 1 && gView == gMe && gPrediction && gMe->pXSprite->health > 0) - { - nSectnum = predict.sectnum; - cX = interpolate(predictOld.x, predict.x, gInterpolate); - cY = interpolate(predictOld.y, predict.y, gInterpolate); - cZ = interpolate(predictOld.viewz, predict.viewz, gInterpolate); - zDelta = finterpolate(predictOld.weaponZ, predict.weaponZ, gInterpolate); - bobWidth = interpolate(predictOld.bobWidth, predict.bobWidth, gInterpolate); - bobHeight = interpolate(predictOld.bobHeight, predict.bobHeight, gInterpolate); - shakeX = finterpolate(predictOld.shakeBobX, predict.shakeBobX, gInterpolate); - shakeY = finterpolate(predictOld.shakeBobY, predict.shakeBobY, gInterpolate); + int nSectnum; + double zDelta; + SetupView(cX, cY, cZ, cA, cH, nSectnum, zDelta); - if (!SyncInput()) - { - cA = bamang(predict.angle.asbam() + predict.look_ang.asbam()); - cH = predict.horiz + predict.horizoff; - rotscrnang = predict.rotscrnang; - } - else - { - uint32_t oang = predictOld.angle.asbam() + predictOld.look_ang.asbam(); - uint32_t ang = predict.angle.asbam() + predict.look_ang.asbam(); - cA = interpolateangbin(oang, ang, gInterpolate); - - fixed_t ohoriz = (predictOld.horiz + predictOld.horizoff).asq16(); - fixed_t horiz = (predict.horiz + predict.horizoff).asq16(); - cH = q16horiz(interpolate(ohoriz, horiz, gInterpolate)); - - rotscrnang = interpolateanglook(predictOld.rotscrnang.asbam(), predict.rotscrnang.asbam(), gInterpolate); - } - } - else - { - VIEW* pView = &gPrevView[gViewIndex]; - cX = interpolate(pView->x, gView->pSprite->x, gInterpolate); - cY = interpolate(pView->y, gView->pSprite->y, gInterpolate); - cZ = interpolate(pView->viewz, gView->zView, gInterpolate); - zDelta = finterpolate(pView->weaponZ, gView->zWeapon - gView->zView - (12 << 8), gInterpolate); - bobWidth = interpolate(pView->bobWidth, gView->bobWidth, gInterpolate); - bobHeight = interpolate(pView->bobHeight, gView->bobHeight, gInterpolate); - shakeX = finterpolate(pView->shakeBobX, gView->swayWidth, gInterpolate); - shakeY = finterpolate(pView->shakeBobY, gView->swayHeight, gInterpolate); - - if (!SyncInput()) - { - cA = gView->angle.sum(); - cH = gView->horizon.sum(); - rotscrnang = gView->angle.rotscrnang; - } - else - { - cA = gView->angle.interpolatedsum(gInterpolate); - cH = gView->horizon.interpolatedsum(gInterpolate); - rotscrnang = gView->angle.interpolatedrotscrn(gInterpolate); - } - } - - viewUpdateShake(); - cH += buildhoriz(shakeHoriz); - cA += buildang(shakeAngle); - cX += shakeX; - cY += shakeY; - cZ += shakeZ; - shakeX += shakeBobX; - shakeY += shakeBobY; - cH += buildhoriz(MulScale(0x40000000 - Cos(gView->tiltEffect << 2), 30, 30)); - if (gViewPos == 0) - { - if (cl_viewhbob) - { - cX -= MulScale(bobWidth, Sin(cA.asbuild()), 30) >> 4; - cY += MulScale(bobWidth, Cos(cA.asbuild()), 30) >> 4; - } - if (cl_viewvbob) - { - cZ += bobHeight; - } - cZ += xs_CRoundToInt(cH.asq16() / 6553.6); - cameradist = -1; - cameraclock = PlayClock + MulScale(4, (int)gInterpolate, 16); - } - else - { - calcChaseCamPos((int*)&cX, (int*)&cY, (int*)&cZ, gView->pSprite, (short*)&nSectnum, cA, cH, gInterpolate); - } - CheckLink((int*)&cX, (int*)&cY, (int*)&cZ, &nSectnum); - int v78 = interpolateang(gScreenTiltO, gScreenTilt, gInterpolate); + int tilt = interpolateang(gScreenTiltO, gScreenTilt, gInterpolate); uint8_t v14 = 0; uint8_t v10 = 0; bool bDelirium = powerupCheck(gView, kPwUpDeliriumShroom) > 0; static bool bDeliriumOld = false; //int tiltcs, tiltdim; - uint8_t v4 = powerupCheck(gView, kPwUpCrystalBall) > 0; -#ifdef USE_OPENGL - renderSetRollAngle(rotscrnang.asbuildf()); -#endif - if (v78 || bDelirium) + uint8_t otherview = powerupCheck(gView, kPwUpCrystalBall) > 0; + if (tilt || bDelirium) { - renderSetRollAngle(v78); + renderSetRollAngle(tilt); } - else if (v4 && gNetPlayers > 1) + else if (otherview && gNetPlayers > 1) { #if 0 renderCrystalBall(); @@ -723,7 +716,7 @@ void viewDrawScreen(bool sceneonly) deliriumTurn = 0; deliriumPitch = 0; } - int unk = 0; + int brightness = 0; int nSprite; StatIterator it(kStatExplosion); @@ -735,7 +728,7 @@ void viewDrawScreen(bool sceneonly) XSPRITE* pXSprite = &xsprite[nXSprite]; if (TestBitString(gotsector, pSprite->sectnum)) { - unk += pXSprite->data3 * 32; + brightness += pXSprite->data3 * 32; } } it.Reset(kStatProjectile); @@ -747,81 +740,49 @@ void viewDrawScreen(bool sceneonly) case kMissileTeslaAlt: case kMissileFlareAlt: case kMissileTeslaRegular: - if (TestBitString(gotsector, pSprite->sectnum)) unk += 256; + if (TestBitString(gotsector, pSprite->sectnum)) brightness += 256; break; } } - g_visibility = (int32_t)(ClipLow(gVisibility - 32 * gView->visibility - unk, 0)); + g_visibility = (int32_t)(ClipLow(gVisibility - 32 * gView->visibility - brightness, 0)); cA += q16ang(interpolateangfix16(IntToFixed(deliriumTurnO), IntToFixed(deliriumTurn), gInterpolate)); - int vfc, vf8; - getzsofslope(nSectnum, cX, cY, &vfc, &vf8); - if (cZ >= vf8) + + int ceilingZ, floorZ; + getzsofslope(nSectnum, cX, cY, &ceilingZ, &floorZ); + if (cZ >= floorZ) { - cZ = vf8 - (gUpperLink[nSectnum] >= 0 ? 0 : (8 << 8)); + cZ = floorZ - (gUpperLink[nSectnum] >= 0 ? 0 : (8 << 8)); } - if (cZ <= vfc) + if (cZ <= ceilingZ) { - cZ = vfc + (gLowerLink[nSectnum] >= 0 ? 0 : (8 << 8)); + cZ = ceilingZ + (gLowerLink[nSectnum] >= 0 ? 0 : (8 << 8)); } cH = q16horiz(ClipRange(cH.asq16(), gi->playerHorizMin(), gi->playerHorizMax())); - RORHACK: - int ror_status[16]; - for (int i = 0; i < 16; i++) - ror_status[i] = TestBitString(gotpic, 4080 + i); - fixed_t deliriumPitchI = interpolate(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate); - DrawMirrors(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, gInterpolate, gViewIndex); - int bakCstat = gView->pSprite->cstat; - if (gViewPos == 0) - { - gView->pSprite->cstat |= 32768; - } - else - { - gView->pSprite->cstat |= 514; - } - renderDrawRoomsQ16(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, nSectnum); - viewProcessSprites(cX, cY, cZ, cA.asbuild(), gInterpolate); - bool do_ror_hack = false; - for (int i = 0; i < 16; i++) - if (ror_status[i] != TestBitString(gotpic, 4080 + i)) - do_ror_hack = true; - if (do_ror_hack) - { - gView->pSprite->cstat = bakCstat; - spritesortcnt = 0; - goto RORHACK; - } - sub_5571C(1); - int nSpriteSortCnt = spritesortcnt; - renderDrawMasks(); - spritesortcnt = nSpriteSortCnt; - sub_5571C(0); - sub_557C4(cX, cY, gInterpolate); - renderDrawMasks(); - gView->pSprite->cstat = bakCstat; - - if ((v78 || bDelirium) && !sceneonly) + if ((tilt || bDelirium) && !sceneonly) { if (gDeliriumBlur) { - // todo: Implement using modern techniques instead of relying on deprecated old stuff that isn't well supported anymore. - /* names broken up so that searching for GL keywords won't find them anymore - if (!bDeliriumOld) - { - g lAccum(GL_LOAD, 1.f); - } - else - { - const float fBlur = pow(1.f/3.f, 30.f/g_frameRate); - g lAccum(GL _MULT, fBlur); - g lAccum(GL _ACCUM, 1.f-fBlur); - g lAccum(GL _RETURN, 1.f); - } - */ + // todo: Set up a blurring postprocessing shader. + //const float fBlur = pow(1.f/3.f, 30.f/g_frameRate); + //g lAccum(GL _MULT, fBlur); + //g lAccum(GL _ACCUM, 1.f-fBlur); + //g lAccum(GL _RETURN, 1.f); } } + if (testnewrenderer) + { + fixed_t deliriumPitchI = interpolate(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate); + int bakCstat = gView->pSprite->cstat; + gView->pSprite->cstat |= (gViewPos == 0) ? CSTAT_SPRITE_INVISIBLE : CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_TRANSLUCENT_INVERT; + render_drawrooms(gView->pSprite, { cX, cY, cZ }, nSectnum, cA.asq16(), cH.asq16() + deliriumPitchI, 0, RSF_UPDATESECTOR); + gView->pSprite->cstat = bakCstat; + } + else + { + render3DViewPolymost(nSectnum, cX, cY, cZ, cA, cH); + } bDeliriumOld = bDelirium && gDeliriumBlur; int nClipDist = gView->pSprite->clipdist << 2;