This commit is contained in:
Christoph Oelckers 2021-03-20 23:01:16 +01:00
parent 4109a256ac
commit d42ce0ee7e
22 changed files with 612 additions and 520 deletions

View file

@ -1284,6 +1284,7 @@ set (PCH_SOURCES
games/exhumed/all.cpp games/exhumed/all.cpp
games/blood/all.cpp games/blood/all.cpp
games/sw/all.cpp games/sw/all.cpp
) )
if( ${HAVE_VM_JIT} ) if( ${HAVE_VM_JIT} )

View file

@ -32,6 +32,20 @@ enum
CSTAT_SECTOR_METHOD = 384 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 //40 bytes
struct sectortype struct sectortype
{ {
@ -53,6 +67,7 @@ struct sectortype
uint8_t dirty; uint8_t dirty;
float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_; float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_;
uint8_t portalflags;
int ceilingxpan() const { return int(ceilingxpan_); } int ceilingxpan() const { return int(ceilingxpan_); }
int ceilingypan() const { return int(ceilingypan_); } int ceilingypan() const { return int(ceilingypan_); }
@ -104,6 +119,7 @@ struct walltype
int16_t extra; int16_t extra;
float xpan_, ypan_; float xpan_, ypan_;
angle_t clipangle; angle_t clipangle;
uint8_t portalflags;
int xpan() const { return int(xpan_); } int xpan() const { return int(xpan_); }
int ypan() const { return int(ypan_); } int ypan() const { return int(ypan_); }

View file

@ -849,71 +849,42 @@ CVAR(Bool, testnewinterface, true, 0)
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
fixed_t daang, fixed_t dahoriz, int16_t dacursectnum) fixed_t daang, fixed_t dahoriz, int16_t dacursectnum)
{ {
for (int i = 0; i < numwalls; ++i) checkRotatedWalls();
{
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;
if (gl_fogmode == 1) gl_fogmode = 2; // only radial fog works with Build's screwed up coordinate system. 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). // Update starting sector number (common to classic and Polymost).
// ADJUST_GLOBALCURSECTNUM. // ADJUST_GLOBALCURSECTNUM.
if (globalcursectnum >= MAXSECTORS) if (dacursectnum >= MAXSECTORS)
globalcursectnum -= MAXSECTORS; dacursectnum -= MAXSECTORS;
else else
{ {
i = globalcursectnum; int i = dacursectnum;
updatesector(globalposx,globalposy,&globalcursectnum); updatesector(daposx, daposy, &dacursectnum);
if (globalcursectnum < 0) globalcursectnum = i; if (dacursectnum < 0) dacursectnum = i;
// PK 20110123: I'm not sure what the line above is supposed to do, but '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... // *can* be negative, so let's just quit here in that case...
if (globalcursectnum<0) if (dacursectnum < 0)
return 0; return 0;
} }
if (!testnewrenderer) 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(); Polymost::polymost_drawrooms();
} }
else else
{ {
vec3_t pos = { daposx, daposy, daposz }; vec3_t pos = { daposx, daposy, daposz };
//if (!testnewinterface) render_drawrooms_(pos, globalcursectnum, daang, dahoriz, rollang, r_fov, false, false); render_drawrooms(nullptr, pos, dacursectnum, daang, dahoriz, rollang, 0);
/*else*/ render_drawrooms(pos, globalcursectnum, daang, dahoriz, rollang, false, false);
} }
return inpreparemirror; return inpreparemirror;

View file

@ -2075,7 +2075,7 @@ void polymost_drawrooms()
{ {
polymost_outputGLDebugMessage(3, "polymost_drawrooms()"); polymost_outputGLDebugMessage(3, "polymost_drawrooms()");
GLInterface.ClearDepth(); GLInterface.ClearDepth();
GLInterface.EnableBlend(false); GLInterface.EnableBlend(false);
GLInterface.EnableAlphaTest(false); GLInterface.EnableAlphaTest(false);
GLInterface.EnableDepthTest(true); 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); gvrcorrection = viewingrange*(1.f/65536.f);
//if (glprojectionhacks == 2) //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 verticalfovtan = (fviewingrange * (windowxy2.y-windowxy1.y) * 5.f) / ((float)yxaspect * (windowxy2.x-windowxy1.x) * 4.f);
float verticalfov = atanf(verticalfovtan) * (2.f / pi::pi()); float verticalfov = atanf(verticalfovtan) * (2.f / pi::pi());
static constexpr float const maxhorizangle = 0.6361136f; // horiz of 199 in degrees static constexpr float const maxhorizangle = 0.6361136f; // horiz of 199 in degrees

View file

@ -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 // vector serializers

View file

@ -12,6 +12,7 @@ void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, fl
void setWallSectors(); void setWallSectors();
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out); void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out);
void GetFlatSpritePosition(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. // 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! // The render code should NOT use Build coordinates for anything!

View file

@ -101,6 +101,7 @@ struct GameInterface
virtual int chaseCamX(binangle ang) { return 0; } virtual int chaseCamX(binangle ang) { return 0; }
virtual int chaseCamY(binangle ang) { return 0; } virtual int chaseCamY(binangle ang) { return 0; }
virtual int chaseCamZ(fixedhoriz horiz) { return 0; } virtual int chaseCamZ(fixedhoriz horiz) { return 0; }
virtual void processSprites(int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) {}
virtual FString statFPS() virtual FString statFPS()
{ {

View file

@ -43,6 +43,7 @@
#include "gamecontrol.h" #include "gamecontrol.h"
#include "gamefuncs.h" #include "gamefuncs.h"
#include "sectorgeometry.h" #include "sectorgeometry.h"
#include "render.h"
static void ReadSectorV7(FileReader& fr, sectortype& sect) static void ReadSectorV7(FileReader& fr, sectortype& sect)

View file

@ -31,16 +31,10 @@
//#include "a_dynlight.h" //#include "a_dynlight.h"
#include "v_video.h" #include "v_video.h"
#include "m_png.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 "i_time.h"
#include "hw_dynlightdata.h" #include "hw_dynlightdata.h"
#include "hw_clock.h" #include "hw_clock.h"
#include "flatvertices.h" #include "flatvertices.h"
//#include "v_palette.h"
//#include "d_main.h"
#include "hw_renderstate.h" #include "hw_renderstate.h"
#include "hw_lightbuffer.h" #include "hw_lightbuffer.h"
@ -49,12 +43,12 @@
#include "hw_clipper.h" #include "hw_clipper.h"
//#include "hwrenderer/scene/hw_portal.h" //#include "hwrenderer/scene/hw_portal.h"
#include "hw_vrmodes.h" #include "hw_vrmodes.h"
//#include "g_levellocals.h"
#include "hw_drawstructs.h" #include "hw_drawstructs.h"
#include "hw_drawlist.h" #include "hw_drawlist.h"
#include "hw_drawinfo.h" #include "hw_drawinfo.h"
#include "gamecvars.h" #include "gamecvars.h"
#include "render.h"
EXTERN_CVAR(Bool, cl_capfps) EXTERN_CVAR(Bool, cl_capfps)
bool NoInterpolateView; 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{}; FRenderViewpoint r_viewpoint{};
r_viewpoint.CameraSprite = cam;
r_viewpoint.SectNum = sectnum; r_viewpoint.SectNum = sectnum;
r_viewpoint.Pos = { position.x / 16.f, position.y / -16.f, position.z / -256.f }; r_viewpoint.Pos = { position.x / 16.f, position.y / -16.f, position.z / -256.f };
r_viewpoint.HWAngles.Yaw = -90.f + q16ang(q16angle).asdeg(); r_viewpoint.HWAngles.Yaw = -90.f + 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, &sect);
if (sect >= 0) sectnum = sect;
if (sectnum < 0) return;
}
auto RenderState = screen->RenderState(); auto RenderState = screen->RenderState();
RenderState->SetVertexBuffer(screen->mVertexData); RenderState->SetVertexBuffer(screen->mVertexData);
screen->mVertexData->Reset(); 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; iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
checkBenchActive(); 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. 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(); All.Unclock();
} }

View file

@ -1,4 +1,11 @@
#pragma once #pragma once
#include "build.h" #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,
};

View file

@ -35,6 +35,7 @@ class FRenderState;
struct FRenderViewpoint struct FRenderViewpoint
{ {
spritetype* CameraSprite;
DVector3 Pos; DVector3 Pos;
FRotator HWAngles; FRotator HWAngles;
FAngle FieldOfView; FAngle FieldOfView;

View file

@ -554,6 +554,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectort
("lotag", c.lotag, def->lotag) ("lotag", c.lotag, def->lotag)
("hitag", c.hitag, def->hitag) ("hitag", c.hitag, def->hitag)
("extra", c.extra, def->extra) ("extra", c.extra, def->extra)
("portalflags", c.portalflags, def->portalflags)
.EndObject(); .EndObject();
} }
return arc; return arc;
@ -580,6 +581,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype
("lotag", c.lotag, def->lotag) ("lotag", c.lotag, def->lotag)
("hitag", c.hitag, def->hitag) ("hitag", c.hitag, def->hitag)
("extra", c.extra, def->extra) ("extra", c.extra, def->extra)
("portalflags", c.portalflags, def->portalflags)
.EndObject(); .EndObject();
} }
return arc; return arc;

View file

@ -66,5 +66,9 @@
#include "src/view.cpp" #include "src/view.cpp"
#include "src/warp.cpp" #include "src/warp.cpp"
#include "src/weapon.cpp" #include "src/weapon.cpp"
#include "src/_polymost.cpp"
// This includes the VM so it is last // This includes the VM so it is last
#include "src/d_menu.cpp" #include "src/d_menu.cpp"

View file

@ -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

View file

@ -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 END_BLD_NS

View file

@ -35,7 +35,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "ai.h" #include "ai.h"
#include "aistate.h" #include "aistate.h"
#include "aiunicult.h" #include "aiunicult.h"
#include "blood.h"
#include "callback.h" #include "callback.h"
#include "db.h" #include "db.h"
#include "endgame.h" #include "endgame.h"
@ -83,6 +82,20 @@ void ProcessFrame(void);
void ScanINIFiles(void); void ScanINIFiles(void);
void EndLevel(); 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) inline bool DemoRecordStatus(void)
{ {
return false; return false;
@ -131,9 +144,10 @@ struct GameInterface : ::GameInterface
void ToggleThirdPerson() override; void ToggleThirdPerson() override;
void SwitchCoopView() override; void SwitchCoopView() override;
void ToggleShowWeapon() override; void ToggleShowWeapon() override;
int chaseCamX(binangle ang) { return MulScale(-Cos(ang.asbuild()), 1280, 30); } int chaseCamX(binangle ang) override { return MulScale(-Cos(ang.asbuild()), 1280, 30); }
int chaseCamY(binangle ang) { return MulScale(-Sin(ang.asbuild()), 1280, 30); } int chaseCamY(binangle ang) override { return MulScale(-Sin(ang.asbuild()), 1280, 30); }
int chaseCamZ(fixedhoriz horiz) { return FixedToInt(MulScale(horiz.asq16(), 1280, 3)) - (16 << 8); } 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; GameStats getStats() override;
}; };

View file

@ -1,13 +1,5 @@
#pragma once #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 BEGIN_BLD_NS
extern int cumulDamage[kMaxXSprites]; extern int cumulDamage[kMaxXSprites];

View file

@ -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 "ns.h" // Must come before everything else!
#include "build.h" #include "build.h"
#include "compat.h" #include "automap.h"
#include "blood.h" #include "mmulti.h"
#include "savegamehelp.h"
#include "blood.h"
BEGIN_BLD_NS BEGIN_BLD_NS
int mirrorcnt, mirrorsector, mirrorwall[4]; int mirrorcnt, mirrorsector, mirrorwall[4];
typedef struct
{
int type;
int link;
int dx;
int dy;
int dz;
int wallnum;
} MIRROR;
MIRROR mirror[16]; MIRROR mirror[16];
void InitMirrors(void) void InitMirrors(void)
@ -64,6 +57,7 @@ void InitMirrors(void)
if (wall[i].extra > 0 && GetWallType(i) == kWallStack) if (wall[i].extra > 0 && GetWallType(i) == kWallStack)
{ {
wall[i].overpicnum = nTile; wall[i].overpicnum = nTile;
wall[i].portalflags = PORTAL_WALL_VIEW;
mirror[mirrorcnt].wallnum = i; mirror[mirrorcnt].wallnum = i;
mirror[mirrorcnt].type = 0; mirror[mirrorcnt].type = 0;
wall[i].cstat |= 32; wall[i].cstat |= 32;
@ -96,6 +90,7 @@ void InitMirrors(void)
wall[i].picnum = nTile; wall[i].picnum = nTile;
mirror[mirrorcnt].type = 0; mirror[mirrorcnt].type = 0;
wall[i].cstat |= 32; wall[i].cstat |= 32;
wall[i].portalflags = PORTAL_WALL_MIRROR;
mirrorcnt++; mirrorcnt++;
continue; continue;
} }
@ -121,6 +116,7 @@ void InitMirrors(void)
mirror[mirrorcnt].wallnum = i; mirror[mirrorcnt].wallnum = i;
mirror[mirrorcnt].link = j; mirror[mirrorcnt].link = j;
sector[i].floorpicnum = 4080+mirrorcnt; sector[i].floorpicnum = 4080+mirrorcnt;
sector[i].portalflags = PORTAL_SECTOR_FLOOR;
mirrorcnt++; mirrorcnt++;
mirror[mirrorcnt].type = 1; mirror[mirrorcnt].type = 1;
mirror[mirrorcnt].dx = sprite[nLink].x-sprite[nLink2].x; mirror[mirrorcnt].dx = sprite[nLink].x-sprite[nLink2].x;
@ -129,10 +125,12 @@ void InitMirrors(void)
mirror[mirrorcnt].wallnum = j; mirror[mirrorcnt].wallnum = j;
mirror[mirrorcnt].link = i; mirror[mirrorcnt].link = i;
sector[j].ceilingpicnum = 4080+mirrorcnt; sector[j].ceilingpicnum = 4080+mirrorcnt;
sector[j].portalflags = PORTAL_SECTOR_CEILING;
mirrorcnt++; mirrorcnt++;
} }
} }
mirrorsector = numsectors; mirrorsector = numsectors;
#if 1 // The new backend won't need this shit anymore.
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
mirrorwall[i] = numwalls+i; mirrorwall[i] = numwalls+i;
@ -148,270 +146,13 @@ void InitMirrors(void)
sector[mirrorsector].floorpicnum = 504; sector[mirrorsector].floorpicnum = 504;
sector[mirrorsector].wallptr = mirrorwall[0]; sector[mirrorsector].wallptr = mirrorwall[0];
sector[mirrorsector].wallnum = 4; sector[mirrorsector].wallnum = 4;
#endif
} }
void TranslateMirrorColors(int nShade, int nPalette) 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;
}
}
}
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //

View file

@ -37,8 +37,8 @@ void FireInit(void);
void FireProcess(void); void FireProcess(void);
void UpdateNetworkMenus(void); void UpdateNetworkMenus(void);
void InitMirrors(void); void InitMirrors(void);
void sub_5571C(char mode); void setPortalFlags(char mode);
void sub_557C4(int x, int y, int interpolation); 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); void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer);
int qanimateoffs(int a1, int a2); int qanimateoffs(int a1, int a2);
void HookReplaceFunctions(); void HookReplaceFunctions();

View file

@ -34,7 +34,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mmulti.h" #include "mmulti.h"
#include "blood.h" #include "blood.h"
#include "savegamehelp.h" #include "savegamehelp.h"
#include "bloodactor.h"
BEGIN_BLD_NS BEGIN_BLD_NS

View file

@ -355,10 +355,11 @@ XSPRITE* evrListRedirectors(int objType, int objXIndex, XSPRITE* pXRedir, int* t
XSPRITE* evrIsRedirector(int nSprite); XSPRITE* evrIsRedirector(int nSprite);
int listTx(XSPRITE* pXRedir, int tx); int listTx(XSPRITE* pXRedir, int tx);
void seqSpawnerOffSameTx(XSPRITE* pXSource); void seqSpawnerOffSameTx(XSPRITE* pXSource);
#endif
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// This file provides modern features for mappers. // This file provides modern features for mappers.
// For full documentation please visit http://cruo.bloodgame.ru/xxsystem // For full documentation please visit http://cruo.bloodgame.ru/xxsystem
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
END_BLD_NS END_BLD_NS
#endif

View file

@ -42,8 +42,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "automap.h" #include "automap.h"
#include "gamefuncs.h" #include "gamefuncs.h"
#include "v_draw.h" #include "v_draw.h"
#include "render.h"
#include "glbackend/glbackend.h" #include "glbackend/glbackend.h"
EXTERN_CVAR(Bool, testnewrenderer)
BEGIN_BLD_NS BEGIN_BLD_NS
FixedBitArray<kMaxSprites> gInterpolateSprite; FixedBitArray<kMaxSprites> gInterpolateSprite;
@ -450,6 +452,101 @@ static void DrawMap(spritetype* pSprite)
setViewport(hud_size); 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() void renderCrystalBall()
{ {
#if 0 #if 0
@ -541,23 +638,7 @@ RORHACKOTHER:
#endif #endif
} }
void render3DViewPolymost() 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);
}
// 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 viewDrawScreen(bool sceneonly) void viewDrawScreen(bool sceneonly)
{ {
@ -600,113 +681,25 @@ void viewDrawScreen(bool sceneonly)
UpdateDacs(basepal); UpdateDacs(basepal);
UpdateBlend(); UpdateBlend();
int cX, cY, cZ, bobWidth, bobHeight; int cX, cY, cZ;
lookangle rotscrnang;
binangle cA; binangle cA;
fixedhoriz cH; fixedhoriz cH;
double zDelta, shakeX, shakeY; int nSectnum;
int nSectnum = gView->pSprite->sectnum; double zDelta;
if (numplayers > 1 && gView == gMe && gPrediction && gMe->pXSprite->health > 0) SetupView(cX, cY, cZ, cA, cH, nSectnum, zDelta);
{
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()) int tilt = interpolateang(gScreenTiltO, gScreenTilt, gInterpolate);
{
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);
uint8_t v14 = 0; uint8_t v14 = 0;
uint8_t v10 = 0; uint8_t v10 = 0;
bool bDelirium = powerupCheck(gView, kPwUpDeliriumShroom) > 0; bool bDelirium = powerupCheck(gView, kPwUpDeliriumShroom) > 0;
static bool bDeliriumOld = false; static bool bDeliriumOld = false;
//int tiltcs, tiltdim; //int tiltcs, tiltdim;
uint8_t v4 = powerupCheck(gView, kPwUpCrystalBall) > 0; uint8_t otherview = powerupCheck(gView, kPwUpCrystalBall) > 0;
#ifdef USE_OPENGL if (tilt || bDelirium)
renderSetRollAngle(rotscrnang.asbuildf());
#endif
if (v78 || bDelirium)
{ {
renderSetRollAngle(v78); renderSetRollAngle(tilt);
} }
else if (v4 && gNetPlayers > 1) else if (otherview && gNetPlayers > 1)
{ {
#if 0 #if 0
renderCrystalBall(); renderCrystalBall();
@ -723,7 +716,7 @@ void viewDrawScreen(bool sceneonly)
deliriumTurn = 0; deliriumTurn = 0;
deliriumPitch = 0; deliriumPitch = 0;
} }
int unk = 0; int brightness = 0;
int nSprite; int nSprite;
StatIterator it(kStatExplosion); StatIterator it(kStatExplosion);
@ -735,7 +728,7 @@ void viewDrawScreen(bool sceneonly)
XSPRITE* pXSprite = &xsprite[nXSprite]; XSPRITE* pXSprite = &xsprite[nXSprite];
if (TestBitString(gotsector, pSprite->sectnum)) if (TestBitString(gotsector, pSprite->sectnum))
{ {
unk += pXSprite->data3 * 32; brightness += pXSprite->data3 * 32;
} }
} }
it.Reset(kStatProjectile); it.Reset(kStatProjectile);
@ -747,81 +740,49 @@ void viewDrawScreen(bool sceneonly)
case kMissileTeslaAlt: case kMissileTeslaAlt:
case kMissileFlareAlt: case kMissileFlareAlt:
case kMissileTeslaRegular: case kMissileTeslaRegular:
if (TestBitString(gotsector, pSprite->sectnum)) unk += 256; if (TestBitString(gotsector, pSprite->sectnum)) brightness += 256;
break; 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)); cA += q16ang(interpolateangfix16(IntToFixed(deliriumTurnO), IntToFixed(deliriumTurn), gInterpolate));
int vfc, vf8;
getzsofslope(nSectnum, cX, cY, &vfc, &vf8); int ceilingZ, floorZ;
if (cZ >= vf8) 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())); 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); if ((tilt || bDelirium) && !sceneonly)
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 (gDeliriumBlur) if (gDeliriumBlur)
{ {
// todo: Implement using modern techniques instead of relying on deprecated old stuff that isn't well supported anymore. // todo: Set up a blurring postprocessing shader.
/* names broken up so that searching for GL keywords won't find them anymore //const float fBlur = pow(1.f/3.f, 30.f/g_frameRate);
if (!bDeliriumOld) //g lAccum(GL _MULT, fBlur);
{ //g lAccum(GL _ACCUM, 1.f-fBlur);
g lAccum(GL_LOAD, 1.f); //g lAccum(GL _RETURN, 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);
}
*/
} }
} }
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; bDeliriumOld = bDelirium && gDeliriumBlur;
int nClipDist = gView->pSprite->clipdist << 2; int nClipDist = gView->pSprite->clipdist << 2;