From 6f7e7459ea8eafcbb2cdbd067d47e879778eed95 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Mar 2021 10:58:11 +0100 Subject: [PATCH] - did some cleanup on Duke's render code to prepare for the new way of handling portals. Like for Blood, the Polymost-only code has been moved aside. Closer examination of the preparations the engine is doing for rendering SE40/150-portals shows that all this was merely done to avoid glitches with a two-phase rendering setup - nothing of this will be needed for doing it properly. They can just be treated as run-of-the-mill stacked sectors. when using hardware rendering capabilities for clipping. --- source/games/blood/src/view.cpp | 13 +- source/games/duke/src/_polymost.cpp | 279 ++++++++++++++++++++++++ source/games/duke/src/premap.cpp | 6 + source/games/duke/src/render.cpp | 320 ++++------------------------ source/games/duke/src/sectors_d.cpp | 1 + source/games/duke/src/sectors_r.cpp | 1 + 6 files changed, 330 insertions(+), 290 deletions(-) create mode 100644 source/games/duke/src/_polymost.cpp diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp index b2e990627..5c9a6158a 100644 --- a/source/games/blood/src/view.cpp +++ b/source/games/blood/src/view.cpp @@ -458,10 +458,10 @@ static void DrawMap(spritetype* pSprite) setViewport(hud_size); } -void SetupView(int &cX, int& cY, int& cZ, binangle& cA, fixedhoriz& cH, int& nSectnum, double& zDelta, double& shakeX, double& shakeY) +void SetupView(int &cX, int& cY, int& cZ, binangle& cA, fixedhoriz& cH, int& nSectnum, double& zDelta, double& shakeX, double& shakeY, lookangle& rotscrnang) { int bobWidth, bobHeight; - lookangle rotscrnang; + nSectnum = gView->pSprite->sectnum; if (numplayers > 1 && gView == gMe && gPrediction && gMe->pXSprite->health > 0) { @@ -542,7 +542,6 @@ void SetupView(int &cX, int& cY, int& cZ, binangle& cA, fixedhoriz& cH, int& nSe 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() @@ -685,7 +684,8 @@ void viewDrawScreen(bool sceneonly) int nSectnum; double zDelta; double shakeX, shakeY; - SetupView(cX, cY, cZ, cA, cH, nSectnum, zDelta, shakeX, shakeY); + lookangle rotscrnang; + SetupView(cX, cY, cZ, cA, cH, nSectnum, zDelta, shakeX, shakeY, rotscrnang); int tilt = interpolateang(gScreenTiltO, gScreenTilt, gInterpolate); uint8_t v14 = 0; @@ -696,7 +696,7 @@ void viewDrawScreen(bool sceneonly) uint8_t otherview = powerupCheck(gView, kPwUpCrystalBall) > 0; if (tilt || bDelirium) { - renderSetRollAngle(tilt); + rotscrnang = buildlook(tilt); } else if (otherview && gNetPlayers > 1) { @@ -775,11 +775,12 @@ void viewDrawScreen(bool sceneonly) 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); + render_drawrooms(gView->pSprite, { cX, cY, cZ }, nSectnum, cA.asq16(), cH.asq16() + deliriumPitchI, rotscrnang.asbuildf(), RSF_UPDATESECTOR); gView->pSprite->cstat = bakCstat; } else { + renderSetRollAngle(rotscrnang.asbuildf()); render3DViewPolymost(nSectnum, cX, cY, cZ, cA, cH); } bDeliriumOld = bDelirium && gDeliriumBlur; diff --git a/source/games/duke/src/_polymost.cpp b/source/games/duke/src/_polymost.cpp new file mode 100644 index 000000000..dca0f795d --- /dev/null +++ b/source/games/duke/src/_polymost.cpp @@ -0,0 +1,279 @@ +BEGIN_DUKE_NS + +extern int tempsectorz[MAXSECTORS]; +extern int tempsectorpicnum[MAXSECTORS]; + + +void SE40_Draw(int tag, spritetype *spr, int x, int y, int z, binangle a, fixedhoriz h, int smoothratio) +{ + int i, j = 0, k = 0; + int ok = 0, fofmode = 0; + int offx, offy; + spritetype* floor1, *floor2 = nullptr; + + if (spr->ang != 512) return; + + i = FOF; //Effect TILE + tileDelete(FOF); + if (!(gotpic[i >> 3] & (1 << (i & 7)))) return; + gotpic[i >> 3] &= ~(1 << (i & 7)); + + floor1 = spr; + + if (spr->lotag == tag + 2) fofmode = tag + 0; + if (spr->lotag == tag + 3) fofmode = tag + 1; + if (spr->lotag == tag + 4) fofmode = tag + 0; + if (spr->lotag == tag + 5) fofmode = tag + 1; + + ok++; + + DukeStatIterator it(STAT_RAROR); + while (auto act = it.Next()) + { + auto spr = &act->s; + if ( + spr->picnum == SECTOREFFECTOR && + spr->lotag == fofmode && + spr->hitag == floor1->hitag + ) + { + floor1 = spr; + fofmode = spr->lotag; + ok++; + break; + } + } + // if(ok==1) { Message("no floor1",RED); return; } + + if (fofmode == tag + 0) k = tag + 1; else k = tag + 0; + + it.Reset(STAT_RAROR); + while (auto act = it.Next()) + { + auto spr = &act->s; + if ( + spr->picnum == SECTOREFFECTOR && + spr->lotag == k && + spr->hitag == floor1->hitag + ) + { + floor2 = spr; + ok++; + break; + } + } + + // if(ok==2) { Message("no floor2",RED); return; } + + it.Reset(STAT_RAROR); + while (auto act = it.Next()) + { + auto spr = &act->s; + if (spr->picnum == SECTOREFFECTOR && + spr->lotag == k + 2 && + spr->hitag == floor1->hitag + ) + { + if (k == tag + 0) + { + tempsectorz[spr->sectnum] = sector[spr->sectnum].floorz; + sector[spr->sectnum].floorz += (((z - sector[spr->sectnum].floorz) / 32768) + 1) * 32768; + tempsectorpicnum[spr->sectnum] = sector[spr->sectnum].floorpicnum; + sector[spr->sectnum].floorpicnum = 13; + } + if (k == tag + 1) + { + tempsectorz[spr->sectnum] = sector[spr->sectnum].ceilingz; + sector[spr->sectnum].ceilingz += (((z - sector[spr->sectnum].ceilingz) / 32768) - 1) * 32768; + tempsectorpicnum[spr->sectnum] = sector[spr->sectnum].ceilingpicnum; + sector[spr->sectnum].ceilingpicnum = 13; + } + } + } + + offx = x - floor1->x; + offy = y - floor1->y; + + renderDrawRoomsQ16(floor2->x + offx, floor2->y + offy, z, a.asq16(), h.asq16(), floor2->sectnum); + fi.animatesprites(offx + floor2->x, offy + floor2->y, a.asbuild(), smoothratio); + renderDrawMasks(); + + it.Reset(STAT_RAROR); + while (auto act = it.Next()) + { + auto spr = &act->s; + if (spr->picnum == 1 && + spr->lotag == k + 2 && + spr->hitag == floor1->hitag + ) + { + if (k == tag + 0) + { + sector[spr->sectnum].floorz = tempsectorz[spr->sectnum]; + sector[spr->sectnum].floorpicnum = tempsectorpicnum[spr->sectnum]; + } + if (k == tag + 1) + { + sector[spr->sectnum].ceilingz = tempsectorz[spr->sectnum]; + sector[spr->sectnum].ceilingpicnum = tempsectorpicnum[spr->sectnum]; + } + }// end if + }// end for + +} // end SE40 + + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void se40code(int x, int y, int z, binangle a, fixedhoriz h, int smoothratio) +{ + int tag; + if (!isRR()) tag = 40; + else if (isRRRA()) tag = 150; + else return; + + DukeStatIterator it(STAT_RAROR); + while (auto act = it.Next()) + { + switch (act->s.lotag - tag + 40) + { + // case 40: + // case 41: + // SE40_Draw(i,x,y,a,smoothratio); + // break; + case 42: + case 43: + case 44: + case 45: + if (ps[screenpeek].cursectnum == act->s.sectnum) + SE40_Draw(tag, &act->s, x, y, z, a, h, smoothratio); + break; + } + } +} + + +//--------------------------------------------------------------------------- +// +// split out so it can also be applied to camera views +// +//--------------------------------------------------------------------------- + +void renderMirror(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int smoothratio) +{ + if ((gotpic[TILE_MIRROR >> 3] & (1 << (TILE_MIRROR & 7))) > 0) + { + int dst = 0x7fffffff, i = 0; + for (int k = 0; k < mirrorcnt; k++) + { + int j = abs(wall[mirrorwall[k]].x - cposx) + abs(wall[mirrorwall[k]].y - cposy); + if (j < dst) dst = j, i = k; + } + + if (wall[mirrorwall[i]].overpicnum == TILE_MIRROR) + { + int tposx, tposy; + fixed_t tang; + + renderPrepareMirror(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), mirrorwall[i], &tposx, &tposy, &tang); + + int j = g_visibility; + g_visibility = (j >> 1) + (j >> 2); + + renderDrawRoomsQ16(tposx, tposy, cposz, tang, choriz.asq16(), mirrorsector[i] + MAXSECTORS); + + display_mirror = 1; + fi.animatesprites(tposx, tposy, tang, smoothratio); + display_mirror = 0; + + renderDrawMasks(); + renderCompleteMirror(); //Reverse screen x-wise in this function + g_visibility = j; + } + gotpic[TILE_MIRROR >> 3] &= ~(1 << (TILE_MIRROR & 7)); + } +} + +//--------------------------------------------------------------------------- +// +// used by RR to inject some external geometry into a scene. +// +//--------------------------------------------------------------------------- + +static void geometryEffect(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int sect, int smoothratio) +{ + short gs, tgsect, geosect, geoid = 0; + renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); + fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio); + renderDrawMasks(); + for (gs = 0; gs < geocnt; gs++) + { + tgsect = geosector[gs]; + + DukeSectIterator it(tgsect); + while (auto act = it.Next()) + { + changespritesect(act, geosectorwarp[gs]); + setsprite(act, act->s.x -= geox[gs], act->s.y -= geoy[gs], act->s.z); + } + if (geosector[gs] == sect) + { + geosect = geosectorwarp[gs]; + geoid = gs; + } + } + cposx -= geox[geoid]; + cposy -= geoy[geoid]; + renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); + cposx += geox[geoid]; + cposy += geoy[geoid]; + for (gs = 0; gs < geocnt; gs++) + { + tgsect = geosectorwarp[gs]; + DukeSectIterator it(tgsect); + while (auto act = it.Next()) + { + changespritesect(act, geosector[gs]); + setsprite(act, act->s.x += geox[gs], act->s.y += geoy[gs], act->s.z); + } + } + fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio); + renderDrawMasks(); + for (gs = 0; gs < geocnt; gs++) + { + tgsect = geosector[gs]; + DukeSectIterator it(tgsect); + while (auto act = it.Next()) + { + changespritesect(act, geosectorwarp2[gs]); + setsprite(act, act->s.x -= geox2[gs], act->s.y -= geoy2[gs], act->s.z); + } + if (geosector[gs] == sect) + { + geosect = geosectorwarp2[gs]; + geoid = gs; + } + } + cposx -= geox2[geoid]; + cposy -= geoy2[geoid]; + renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); + cposx += geox2[geoid]; + cposy += geoy2[geoid]; + for (gs = 0; gs < geocnt; gs++) + { + tgsect = geosectorwarp2[gs]; + DukeSectIterator it(tgsect); + while (auto act = it.Next()) + { + changespritesect(act, geosector[gs]); + setsprite(act, act->s.x += geox2[gs], act->s.y += geoy2[gs], act->s.z); + } + } + fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio); + renderDrawMasks(); +} +END_DUKE_NS diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index fb4893935..b9a4a3b22 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -853,6 +853,12 @@ static int LoadTheMap(MapRecord *mi, struct player_struct *p, int gamemode) } engineLoadBoard(mi->fileName, isShareware(), &p->pos, &lbang, &p->cursectnum); + for(int i = 0; i < numsectors; i++) + { + if (sector[i].ceilingpicnum == FOF) sector[i].portalflags |= PORTAL_SECTOR_CEILING; + if (sector[i].floorpicnum == FOF) sector[i].portalflags |= PORTAL_SECTOR_FLOOR; + if (wall[i].overpicnum == TILE_MIRROR) wall[i].portalflags |= PORTAL_WALL_MIRROR; + } currentLevel = mi; SECRET_SetMapName(mi->DisplayName(), mi->name); diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp index c3c3101cb..138cf0df2 100644 --- a/source/games/duke/src/render.cpp +++ b/source/games/duke/src/render.cpp @@ -33,11 +33,15 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) #include "automap.h" #include "dukeactor.h" #include "interpolate.h" +#include "render.h" + +#include "_polymost.cpp" // temporary hack to pass along RRRA's global fog. Needs to be done better later. extern PalEntry GlobalMapFog; extern float GlobalFogDensity; +EXTERN_CVAR(Bool, testnewrenderer) BEGIN_DUKE_NS @@ -59,201 +63,26 @@ BEGIN_DUKE_NS // //--------------------------------------------------------------------------- -static int tempsectorz[MAXSECTORS]; -static int tempsectorpicnum[MAXSECTORS]; +/*static*/ int tempsectorz[MAXSECTORS]; +/*static*/ int tempsectorpicnum[MAXSECTORS]; //short tempcursectnum; -void SE40_Draw(int tag, spritetype *spr, int x, int y, int z, binangle a, fixedhoriz h, int smoothratio) +void renderView(spritetype* playersprite, int sectnum, int x, int y, int z, binangle a, fixedhoriz h, lookangle rotscrnang, int smoothratio) { - int i, j = 0, k = 0; - int ok = 0, fofmode = 0; - int offx, offy; - spritetype* floor1, *floor2 = nullptr; - - if (spr->ang != 512) return; - - i = FOF; //Effect TILE - tileDelete(FOF); - if (!(gotpic[i >> 3] & (1 << (i & 7)))) return; - gotpic[i >> 3] &= ~(1 << (i & 7)); - - floor1 = spr; - - if (spr->lotag == tag + 2) fofmode = tag + 0; - if (spr->lotag == tag + 3) fofmode = tag + 1; - if (spr->lotag == tag + 4) fofmode = tag + 0; - if (spr->lotag == tag + 5) fofmode = tag + 1; - - ok++; - - DukeStatIterator it(STAT_RAROR); - while (auto act = it.Next()) + if (!testnewrenderer) { - auto spr = &act->s; - if ( - spr->picnum == SECTOREFFECTOR && - spr->lotag == fofmode && - spr->hitag == floor1->hitag - ) - { - floor1 = spr; - fofmode = spr->lotag; - ok++; - break; - } + // do screen rotation. + renderSetRollAngle(rotscrnang.asbuildf()); + + se40code(x, y, z, a, h, smoothratio); + renderMirror(x, y, z, a, h, smoothratio); + renderDrawRoomsQ16(x, y, z - (4 << 8), a.asq16(), h.asq16(), sectnum); + fi.animatesprites(x, y, a.asbuild(), smoothratio); + renderDrawMasks(); } - // if(ok==1) { Message("no floor1",RED); return; } - - if (fofmode == tag + 0) k = tag + 1; else k = tag + 0; - - it.Reset(STAT_RAROR); - while (auto act = it.Next()) + else { - auto spr = &act->s; - if ( - spr->picnum == SECTOREFFECTOR && - spr->lotag == k && - spr->hitag == floor1->hitag - ) - { - floor2 = spr; - ok++; - break; - } - } - - // if(ok==2) { Message("no floor2",RED); return; } - - it.Reset(STAT_RAROR); - while (auto act = it.Next()) - { - auto spr = &act->s; - if (spr->picnum == SECTOREFFECTOR && - spr->lotag == k + 2 && - spr->hitag == floor1->hitag - ) - { - if (k == tag + 0) - { - tempsectorz[spr->sectnum] = sector[spr->sectnum].floorz; - sector[spr->sectnum].floorz += (((z - sector[spr->sectnum].floorz) / 32768) + 1) * 32768; - tempsectorpicnum[spr->sectnum] = sector[spr->sectnum].floorpicnum; - sector[spr->sectnum].floorpicnum = 13; - } - if (k == tag + 1) - { - tempsectorz[spr->sectnum] = sector[spr->sectnum].ceilingz; - sector[spr->sectnum].ceilingz += (((z - sector[spr->sectnum].ceilingz) / 32768) - 1) * 32768; - tempsectorpicnum[spr->sectnum] = sector[spr->sectnum].ceilingpicnum; - sector[spr->sectnum].ceilingpicnum = 13; - } - } - } - - offx = x - floor1->x; - offy = y - floor1->y; - - renderDrawRoomsQ16(floor2->x + offx, floor2->y + offy, z, a.asq16(), h.asq16(), floor2->sectnum); - fi.animatesprites(offx + floor2->x, offy + floor2->y, a.asbuild(), smoothratio); - renderDrawMasks(); - - it.Reset(STAT_RAROR); - while (auto act = it.Next()) - { - auto spr = &act->s; - if (spr->picnum == 1 && - spr->lotag == k + 2 && - spr->hitag == floor1->hitag - ) - { - if (k == tag + 0) - { - sector[spr->sectnum].floorz = tempsectorz[spr->sectnum]; - sector[spr->sectnum].floorpicnum = tempsectorpicnum[spr->sectnum]; - } - if (k == tag + 1) - { - sector[spr->sectnum].ceilingz = tempsectorz[spr->sectnum]; - sector[spr->sectnum].ceilingpicnum = tempsectorpicnum[spr->sectnum]; - } - }// end if - }// end for - -} // end SE40 - - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void se40code(int x, int y, int z, binangle a, fixedhoriz h, int smoothratio) -{ - int tag; - if (!isRR()) tag = 40; - else if (isRRRA()) tag = 150; - else return; - - DukeStatIterator it(STAT_RAROR); - while (auto act = it.Next()) - { - switch (act->s.lotag - tag + 40) - { - // case 40: - // case 41: - // SE40_Draw(i,x,y,a,smoothratio); - // break; - case 42: - case 43: - case 44: - case 45: - if (ps[screenpeek].cursectnum == act->s.sectnum) - SE40_Draw(tag, &act->s, x, y, z, a, h, smoothratio); - break; - } - } -} - - -//--------------------------------------------------------------------------- -// -// split out so it can also be applied to camera views -// -//--------------------------------------------------------------------------- - -void renderMirror(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int smoothratio) -{ - if ((gotpic[TILE_MIRROR >> 3] & (1 << (TILE_MIRROR & 7))) > 0) - { - int dst = 0x7fffffff, i = 0; - for (int k = 0; k < mirrorcnt; k++) - { - int j = abs(wall[mirrorwall[k]].x - cposx) + abs(wall[mirrorwall[k]].y - cposy); - if (j < dst) dst = j, i = k; - } - - if (wall[mirrorwall[i]].overpicnum == TILE_MIRROR) - { - int tposx, tposy; - fixed_t tang; - - renderPrepareMirror(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), mirrorwall[i], &tposx, &tposy, &tang); - - int j = g_visibility; - g_visibility = (j >> 1) + (j >> 2); - - renderDrawRoomsQ16(tposx, tposy, cposz, tang, choriz.asq16(), mirrorsector[i] + MAXSECTORS); - - display_mirror = 1; - fi.animatesprites(tposx, tposy, tang, smoothratio); - display_mirror = 0; - - renderDrawMasks(); - renderCompleteMirror(); //Reverse screen x-wise in this function - g_visibility = j; - } - gotpic[TILE_MIRROR >> 3] &= ~(1 << (TILE_MIRROR & 7)); + render_drawrooms(playersprite, { x, y, z }, sectnum, a.asq16(), h.asq16(), rotscrnang.asbuildf() , RSF_UPDATESECTOR); } } @@ -287,10 +116,17 @@ void animatecamsprite(double smoothratio) { auto camera = &camsprite->GetOwner()->s; auto ang = buildang(camera->interpolatedang(smoothratio)); - // Note: no ROR or camera here for now - the current setup has no means to detect these things before rendering the scene itself. - renderDrawRoomsQ16(camera->x, camera->y, camera->z, ang.asq16(), IntToFixed(camera->shade), camera->sectnum); // why 'shade'...? display_mirror = 1; // should really be 'display external view'. - fi.animatesprites(camera->x, camera->y, ang.asbuild(), smoothratio); + if (!testnewrenderer) + { + // Note: no ROR or camera here - Polymost has no means to detect these things before rendering the scene itself. + renderDrawRoomsQ16(camera->x, camera->y, camera->z, ang.asq16(), IntToFixed(camera->shade), camera->sectnum); // why 'shade'...? + fi.animatesprites(camera->x, camera->y, ang.asbuild(), smoothratio); + } + else + { + render_drawrooms(camera, camera->pos, camera->sectnum, ang.asq16(), IntToFixed(camera->shade), 0, RSF_UPDATESECTOR); + } display_mirror = 0; renderDrawMasks(); }); @@ -383,84 +219,6 @@ static int getdrugmode(player_struct *p, int oyrepeat) } } -//--------------------------------------------------------------------------- -// -// used by RR to inject some external geometry into a scene. -// -//--------------------------------------------------------------------------- - -static void geometryEffect(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int sect, int smoothratio) -{ - short gs, tgsect, geosect, geoid = 0; - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); - fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio); - renderDrawMasks(); - for (gs = 0; gs < geocnt; gs++) - { - tgsect = geosector[gs]; - - DukeSectIterator it(tgsect); - while (auto act = it.Next()) - { - changespritesect(act, geosectorwarp[gs]); - setsprite(act, act->s.x -= geox[gs], act->s.y -= geoy[gs], act->s.z); - } - if (geosector[gs] == sect) - { - geosect = geosectorwarp[gs]; - geoid = gs; - } - } - cposx -= geox[geoid]; - cposy -= geoy[geoid]; - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); - cposx += geox[geoid]; - cposy += geoy[geoid]; - for (gs = 0; gs < geocnt; gs++) - { - tgsect = geosectorwarp[gs]; - DukeSectIterator it(tgsect); - while (auto act = it.Next()) - { - changespritesect(act, geosector[gs]); - setsprite(act, act->s.x += geox[gs], act->s.y += geoy[gs], act->s.z); - } - } - fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio); - renderDrawMasks(); - for (gs = 0; gs < geocnt; gs++) - { - tgsect = geosector[gs]; - DukeSectIterator it(tgsect); - while (auto act = it.Next()) - { - changespritesect(act, geosectorwarp2[gs]); - setsprite(act, act->s.x -= geox2[gs], act->s.y -= geoy2[gs], act->s.z); - } - if (geosector[gs] == sect) - { - geosect = geosectorwarp2[gs]; - geoid = gs; - } - } - cposx -= geox2[geoid]; - cposy -= geoy2[geoid]; - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); - cposx += geox2[geoid]; - cposy += geoy2[geoid]; - for (gs = 0; gs < geocnt; gs++) - { - tgsect = geosectorwarp2[gs]; - DukeSectIterator it(tgsect); - while (auto act = it.Next()) - { - changespritesect(act, geosector[gs]); - setsprite(act, act->s.x += geox2[gs], act->s.y += geoy2[gs], act->s.z); - } - } - fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio); - renderDrawMasks(); -} //--------------------------------------------------------------------------- // // @@ -515,11 +273,7 @@ void displayrooms(int snum, double smoothratio) cang = buildfang(ud.cameraactor->tempang + MulScaleF(((s->ang + 1024 - ud.cameraactor->tempang) & 2047) - 1024, smoothratio, 16)); auto bh = buildhoriz(s->yvel); - se40code(s->x, s->y, s->z, cang, bh, smoothratio); - renderMirror(s->x, s->y, s->z, cang, bh, smoothratio); - renderDrawRoomsQ16(s->x, s->y, s->z - (4 << 8), cang.asq16(), bh.asq16(), s->sectnum); - fi.animatesprites(s->x, s->y, cang.asbuild(), smoothratio); - renderDrawMasks(); + renderView(s, s->sectnum, s->x, s->y, s->z, cang, bh, buildlook(0), smoothratio); } else { @@ -573,6 +327,7 @@ void displayrooms(int snum, double smoothratio) } } + spritetype* viewer; if (p->newOwner != nullptr) { auto spr = &p->newOwner->s; @@ -584,10 +339,12 @@ void displayrooms(int snum, double smoothratio) sect = spr->sectnum; rotscrnang = buildlook(0); smoothratio = MaxSmoothRatio; + viewer = spr; } else if (p->over_shoulder_on == 0) { if (cl_viewbob) cposz += p->opyoff + xs_CRoundToInt(MulScaleF(p->pyoff - p->opyoff, smoothratio, 16)); + viewer = &p->GetActor()->s; } else { @@ -598,11 +355,9 @@ void displayrooms(int snum, double smoothratio) cposz += isRR() ? 3840 : 3072; calcChaseCamPos(&cposx, &cposy, &cposz, &p->GetActor()->s, §, cang, choriz, smoothratio); } + viewer = &p->GetActor()->s; } - // do screen rotation. - renderSetRollAngle(rotscrnang.asbuildf()); - cz = p->GetActor()->ceilingz; fz = p->GetActor()->floorz; @@ -629,17 +384,14 @@ void displayrooms(int snum, double smoothratio) choriz = clamp(choriz, q16horiz(gi->playerHorizMin()), q16horiz(gi->playerHorizMax())); - if (isRR() && sector[sect].lotag == 848) + if (isRR() && sector[sect].lotag == 848 && !testnewrenderer) { + renderSetRollAngle(rotscrnang.asbuildf()); geometryEffect(cposx, cposy, cposz, cang, choriz, sect, smoothratio); } else { - se40code(cposx, cposy, cposz, cang, choriz, smoothratio); - renderMirror(cposx, cposy, cposz, cang, choriz, smoothratio); - renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect); - fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio); - renderDrawMasks(); + renderView(viewer, sect, cposx, cposy, cposz, cang, choriz, rotscrnang, smoothratio); } } //GLInterface.SetMapFog(false); diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 257643069..8693df3bb 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -660,6 +660,7 @@ void checkhitwall_d(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw lotsofglass(spr, dawallnum, 70); wal->cstat &= ~16; wal->overpicnum = MIRRORBROKE; + wal->portalflags = 0; S_PlayActorSound(GLASS_HEAVYBREAK, spr); return; } diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 5dc02bcfe..3c1681540 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -998,6 +998,7 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw lotsofglass(spr, dawallnum, 70); wal->cstat &= ~16; wal->overpicnum = MIRRORBROKE; + wal->portalflags = 0; S_PlayActorSound(GLASS_HEAVYBREAK, spr); return; }