2019-11-20 16:21:32 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
|
|
|
Copyright (C) 2019 sirlemonhead, Nuke.YKT
|
|
|
|
This file is part of PCExhumed.
|
|
|
|
PCExhumed is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License version 2
|
|
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
2019-11-22 23:11:37 +00:00
|
|
|
#include "ns.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "engine.h"
|
2021-02-18 11:14:32 +00:00
|
|
|
#include "gamefuncs.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "names.h"
|
|
|
|
#include "view.h"
|
|
|
|
#include "status.h"
|
|
|
|
#include "exhumed.h"
|
|
|
|
#include "player.h"
|
2020-08-18 07:52:08 +00:00
|
|
|
#include "aistuff.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "sound.h"
|
2020-08-23 14:24:54 +00:00
|
|
|
#include "mapinfo.h"
|
2020-01-12 19:28:07 +00:00
|
|
|
#include "v_video.h"
|
2020-11-26 17:29:20 +00:00
|
|
|
#include "interpolate.h"
|
2020-10-13 19:38:24 +00:00
|
|
|
#include "v_draw.h"
|
2021-03-21 10:48:18 +00:00
|
|
|
#include "render.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2021-03-21 10:48:18 +00:00
|
|
|
EXTERN_CVAR(Bool, testnewrenderer)
|
|
|
|
|
2019-11-22 23:11:37 +00:00
|
|
|
BEGIN_PS_NS
|
|
|
|
|
2021-11-21 19:34:15 +00:00
|
|
|
bool bSubTitles = true;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
int zbob;
|
|
|
|
|
2021-11-21 20:09:27 +00:00
|
|
|
int16_t dVertPan[kMaxPlayers];
|
2019-08-26 03:59:14 +00:00
|
|
|
int nCamerax;
|
|
|
|
int nCameray;
|
|
|
|
int nCameraz;
|
|
|
|
|
2020-08-19 22:55:31 +00:00
|
|
|
|
2021-11-21 20:09:27 +00:00
|
|
|
bool bTouchFloor;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-21 20:09:27 +00:00
|
|
|
int16_t nQuake[kMaxPlayers] = { 0 };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-21 20:09:27 +00:00
|
|
|
int nChunkTotal = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2020-10-07 21:08:40 +00:00
|
|
|
binangle nCameraa;
|
2020-10-07 06:40:59 +00:00
|
|
|
fixedhoriz nCamerapan;
|
2021-11-21 20:09:27 +00:00
|
|
|
int nViewTop;
|
2020-09-27 05:46:04 +00:00
|
|
|
bool bCamera = false;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
int viewz;
|
|
|
|
|
2021-10-19 09:19:50 +00:00
|
|
|
DExhumedActor* pEnemy;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-21 20:09:27 +00:00
|
|
|
int nEnemyPal = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-04-02 08:28:40 +00:00
|
|
|
// We cannot drag these through the entire event system... :(
|
|
|
|
spritetype* mytsprite;
|
|
|
|
int* myspritesortcnt;
|
|
|
|
|
2019-08-26 03:59:14 +00:00
|
|
|
// NOTE - not to be confused with Ken's analyzesprites()
|
2021-04-02 08:28:40 +00:00
|
|
|
static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y, int z, double const smoothratio)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2020-11-26 08:15:49 +00:00
|
|
|
tspritetype *pTSprite;
|
|
|
|
|
2021-04-02 08:28:40 +00:00
|
|
|
mytsprite = tsprite;
|
|
|
|
myspritesortcnt = &spritesortcnt;
|
|
|
|
|
2020-11-26 08:15:49 +00:00
|
|
|
for (int i = 0; i < spritesortcnt; i++) {
|
|
|
|
pTSprite = &tsprite[i];
|
|
|
|
|
|
|
|
if (pTSprite->owner != -1)
|
|
|
|
{
|
|
|
|
// interpolate sprite position
|
2021-01-05 12:47:56 +00:00
|
|
|
pTSprite->pos = pTSprite->interpolatedvec3(smoothratio);
|
|
|
|
pTSprite->ang = pTSprite->interpolatedang(smoothratio);
|
2020-11-26 08:15:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 20:39:17 +00:00
|
|
|
auto pPlayerActor = PlayerList[nLocalPlayer].Actor();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_38 = 20;
|
|
|
|
int var_2C = 30000;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-10-21 20:39:17 +00:00
|
|
|
spritetype *pPlayerSprite = &pPlayerActor->s();
|
2019-10-11 12:49:39 +00:00
|
|
|
|
2021-10-21 20:18:29 +00:00
|
|
|
bestTarget = nullptr;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2021-11-09 16:27:54 +00:00
|
|
|
int nSector =pPlayerSprite->sectnum;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-10-11 12:49:39 +00:00
|
|
|
int nAngle = (2048 - pPlayerSprite->ang) & kAngleMask;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-10-11 12:49:39 +00:00
|
|
|
int nTSprite;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-11-20 16:21:32 +00:00
|
|
|
// int var_20 = var_24;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-10-11 12:49:39 +00:00
|
|
|
for (nTSprite = spritesortcnt-1, pTSprite = &tsprite[nTSprite]; nTSprite >= 0; nTSprite--, pTSprite--)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-10-11 12:49:39 +00:00
|
|
|
int nSprite = pTSprite->owner;
|
2021-10-21 20:18:29 +00:00
|
|
|
auto pActor = &exhumedActors[nSprite];
|
|
|
|
spritetype *pSprite = &pActor->s();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-10-11 12:49:39 +00:00
|
|
|
if (pTSprite->sectnum >= 0)
|
|
|
|
{
|
2021-11-22 21:38:27 +00:00
|
|
|
sectortype *pSector = pTSprite->sector();
|
2019-10-11 12:49:39 +00:00
|
|
|
int nSectShade = (pSector->ceilingstat & 1) ? pSector->ceilingshade : pSector->floorshade;
|
|
|
|
int nShade = pTSprite->shade + nSectShade + 6;
|
|
|
|
pTSprite->shade = clamp(nShade, -128, 127);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-10-11 12:49:39 +00:00
|
|
|
|
2019-10-27 13:53:20 +00:00
|
|
|
pTSprite->pal = RemapPLU(pTSprite->pal);
|
|
|
|
|
2020-12-06 16:04:24 +00:00
|
|
|
// PowerSlaveGDX: Torch bouncing fix
|
2020-12-07 16:02:38 +00:00
|
|
|
if ((pTSprite->picnum == kTorch1 || pTSprite->picnum == kTorch2) && (pTSprite->cstat & 0x80) == 0)
|
2020-12-06 16:04:24 +00:00
|
|
|
{
|
|
|
|
pTSprite->cstat |= 0x80;
|
2020-12-07 16:02:38 +00:00
|
|
|
int nTileY = (tileHeight(pTSprite->picnum) * pTSprite->yrepeat) * 2;
|
2020-12-06 16:04:24 +00:00
|
|
|
pTSprite->z -= nTileY;
|
|
|
|
}
|
|
|
|
|
2019-10-11 12:49:39 +00:00
|
|
|
if (pSprite->statnum > 0)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-10-28 16:57:50 +00:00
|
|
|
RunListEvent ev{};
|
|
|
|
ev.pTSprite = pTSprite;
|
|
|
|
runlist_SignalRun(pSprite->lotag - 1, nTSprite, &ExhumedAI::Draw, &ev);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 20:39:17 +00:00
|
|
|
if ((pSprite->statnum < 150) && (pSprite->cstat & 0x101) && (pActor != pPlayerActor))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-10-11 12:49:39 +00:00
|
|
|
int xval = pSprite->x - x;
|
|
|
|
int yval = pSprite->y - y;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-11-14 08:45:08 +00:00
|
|
|
int vcos = bcos(nAngle);
|
|
|
|
int vsin = bsin(nAngle);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
|
2019-10-11 12:49:39 +00:00
|
|
|
int edx = ((vcos * yval) + (xval * vsin)) >> 14;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
|
2021-01-04 12:02:00 +00:00
|
|
|
int ebx = abs(((vcos * xval) - (yval * vsin)) >> 14);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-10-11 12:49:39 +00:00
|
|
|
if (!ebx)
|
|
|
|
continue;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-01-04 12:02:00 +00:00
|
|
|
edx = (abs(edx) * 32) / ebx;
|
2019-10-11 12:49:39 +00:00
|
|
|
if (ebx < 1000 && ebx < var_2C && edx < 10)
|
|
|
|
{
|
2021-10-21 20:18:29 +00:00
|
|
|
bestTarget = pActor;
|
2019-10-11 12:49:39 +00:00
|
|
|
var_38 = edx;
|
|
|
|
var_2C = ebx;
|
|
|
|
}
|
|
|
|
else if (ebx < 30000)
|
|
|
|
{
|
|
|
|
int t = var_38 - edx;
|
2021-01-04 12:02:00 +00:00
|
|
|
if (t > 3 || (ebx < var_2C && abs(t) < 5))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-10-11 12:49:39 +00:00
|
|
|
var_38 = edx;
|
|
|
|
var_2C = ebx;
|
2021-10-21 20:18:29 +00:00
|
|
|
bestTarget = pActor;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-10-11 12:49:39 +00:00
|
|
|
}
|
2021-10-21 20:18:29 +00:00
|
|
|
if (bestTarget != nullptr)
|
2019-10-11 12:49:39 +00:00
|
|
|
{
|
2021-10-21 20:18:29 +00:00
|
|
|
spritetype *pTarget = &bestTarget->s();
|
2019-10-11 12:49:39 +00:00
|
|
|
|
2019-11-03 17:32:02 +00:00
|
|
|
nCreepyTimer = kCreepyCount;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-21 20:18:29 +00:00
|
|
|
if (!cansee(x, y, z, nSector, pTarget->x, pTarget->y, pTarget->z - GetActorHeight(bestTarget), pTarget->sectnum))
|
2019-10-11 12:49:39 +00:00
|
|
|
{
|
2021-10-21 20:18:29 +00:00
|
|
|
bestTarget = nullptr;
|
2019-10-11 12:49:39 +00:00
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2021-04-02 08:28:40 +00:00
|
|
|
|
|
|
|
mytsprite = nullptr;
|
|
|
|
myspritesortcnt = nullptr;
|
|
|
|
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ResetView()
|
|
|
|
{
|
2021-11-21 19:13:19 +00:00
|
|
|
EraseScreen(0);
|
2019-10-12 22:27:12 +00:00
|
|
|
#ifdef USE_OPENGL
|
|
|
|
videoTintBlood(0, 0, 0);
|
|
|
|
#endif
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2020-08-22 09:56:54 +00:00
|
|
|
static TextOverlay subtitleOverlay;
|
|
|
|
|
2020-08-24 03:22:52 +00:00
|
|
|
void DrawView(double smoothRatio, bool sceneonly)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
int playerX;
|
|
|
|
int playerY;
|
|
|
|
int playerZ;
|
2021-11-06 18:27:51 +00:00
|
|
|
int nSector;
|
2021-04-11 05:43:11 +00:00
|
|
|
binangle nAngle, rotscrnang;
|
2021-11-14 14:03:50 +00:00
|
|
|
fixedhoriz pan = {};
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-11-14 08:45:08 +00:00
|
|
|
zbob = bsin(2 * bobangle, -3);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-11-26 17:29:20 +00:00
|
|
|
DoInterpolations(smoothRatio / 65536.);
|
2021-04-04 08:33:29 +00:00
|
|
|
pm_smoothratio = (int)smoothRatio;
|
2020-11-26 17:29:20 +00:00
|
|
|
|
2021-10-21 20:39:17 +00:00
|
|
|
auto pPlayerActor = PlayerList[nLocalPlayer].Actor();
|
|
|
|
auto pPlayerSprite = &pPlayerActor->s();
|
2021-09-06 06:33:02 +00:00
|
|
|
int nPlayerOldCstat = pPlayerSprite->cstat;
|
2021-10-21 17:54:39 +00:00
|
|
|
auto pDop = &PlayerList[nLocalPlayer].pDoppleSprite->s();
|
|
|
|
int nDoppleOldCstat = pDop->cstat;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2020-01-14 20:48:01 +00:00
|
|
|
if (nSnakeCam >= 0 && !sceneonly)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-10-19 09:19:50 +00:00
|
|
|
auto pActor = SnakeList[nSnakeCam].pSprites[0];
|
|
|
|
auto pSprite = &pActor->s();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-09-06 06:33:02 +00:00
|
|
|
playerX = pSprite->x;
|
|
|
|
playerY = pSprite->y;
|
|
|
|
playerZ = pSprite->z;
|
|
|
|
nSector = pSprite->sectnum;
|
|
|
|
nAngle = buildang(pSprite->ang);
|
2021-04-11 05:43:11 +00:00
|
|
|
rotscrnang = buildang(0);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
SetGreenPal();
|
|
|
|
|
2021-10-19 09:19:50 +00:00
|
|
|
pEnemy = SnakeList[nSnakeCam].pEnemy;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-10-19 09:19:50 +00:00
|
|
|
if (pEnemy == nullptr || totalmoves & 1)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
nEnemyPal = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-19 09:19:50 +00:00
|
|
|
nEnemyPal = pEnemy->s().pal;
|
|
|
|
pEnemy->s().pal = 5;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-21 20:39:17 +00:00
|
|
|
playerX = pPlayerSprite->interpolatedx(smoothRatio);
|
|
|
|
playerY = pPlayerSprite->interpolatedy(smoothRatio);
|
|
|
|
playerZ = pPlayerSprite->interpolatedz(smoothRatio) + interpolatedvalue(PlayerList[nLocalPlayer].oeyelevel, PlayerList[nLocalPlayer].eyelevel, smoothRatio);
|
2021-01-10 17:15:28 +00:00
|
|
|
|
2021-10-21 10:51:16 +00:00
|
|
|
nSector = PlayerList[nLocalPlayer].nPlayerViewSect;
|
2020-09-04 22:21:10 +00:00
|
|
|
updatesector(playerX, playerY, &nSector);
|
2021-11-30 20:29:43 +00:00
|
|
|
if (nSector == -1) PlayerList[nLocalPlayer].nPlayerViewSect;
|
2020-09-21 10:37:09 +00:00
|
|
|
|
2020-11-30 22:40:16 +00:00
|
|
|
if (!SyncInput())
|
2020-09-21 10:37:09 +00:00
|
|
|
{
|
2021-02-18 11:14:32 +00:00
|
|
|
pan = PlayerList[nLocalPlayer].horizon.sum();
|
2020-10-07 21:08:40 +00:00
|
|
|
nAngle = PlayerList[nLocalPlayer].angle.sum();
|
|
|
|
rotscrnang = PlayerList[nLocalPlayer].angle.rotscrnang;
|
2020-09-21 10:37:09 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-02-18 11:14:32 +00:00
|
|
|
pan = PlayerList[nLocalPlayer].horizon.interpolatedsum(smoothRatio);
|
2020-10-07 21:08:40 +00:00
|
|
|
nAngle = PlayerList[nLocalPlayer].angle.interpolatedsum(smoothRatio);
|
|
|
|
rotscrnang = PlayerList[nLocalPlayer].angle.interpolatedrotscrn(smoothRatio);
|
2020-09-21 10:37:09 +00:00
|
|
|
}
|
2019-11-03 17:20:05 +00:00
|
|
|
|
2019-11-12 12:25:16 +00:00
|
|
|
if (!bCamera)
|
|
|
|
{
|
2021-09-06 06:33:02 +00:00
|
|
|
pPlayerSprite->cstat |= CSTAT_SPRITE_INVISIBLE;
|
2021-10-21 17:54:39 +00:00
|
|
|
pDop->cstat |= CSTAT_SPRITE_INVISIBLE;
|
2019-11-12 12:25:16 +00:00
|
|
|
}
|
2021-02-18 11:14:32 +00:00
|
|
|
else
|
|
|
|
{
|
2021-09-06 06:33:02 +00:00
|
|
|
pPlayerSprite->cstat |= CSTAT_SPRITE_TRANSLUCENT;
|
2021-10-21 17:54:39 +00:00
|
|
|
pDop->cstat |= CSTAT_SPRITE_INVISIBLE;
|
2021-02-18 11:14:32 +00:00
|
|
|
}
|
|
|
|
pan = q16horiz(clamp(pan.asq16(), gi->playerHorizMin(), gi->playerHorizMax()));
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nCameraa = nAngle;
|
|
|
|
|
2021-02-18 11:14:32 +00:00
|
|
|
if (nSnakeCam >= 0 && !sceneonly)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-02-18 11:14:32 +00:00
|
|
|
pan = q16horiz(0);
|
|
|
|
viewz = playerZ;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-02-18 11:14:32 +00:00
|
|
|
viewz = playerZ + nQuake[nLocalPlayer];
|
2021-11-08 23:24:04 +00:00
|
|
|
int floorZ = pPlayerSprite->sector()->floorz;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-02-18 11:14:32 +00:00
|
|
|
if (viewz > floorZ)
|
|
|
|
viewz = floorZ;
|
|
|
|
|
|
|
|
nCameraa += buildang((nQuake[nLocalPlayer] >> 7) % 31);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-02-18 11:14:32 +00:00
|
|
|
if (bCamera)
|
|
|
|
{
|
|
|
|
viewz -= 2560;
|
2021-10-21 20:39:17 +00:00
|
|
|
if (!calcChaseCamPos(&playerX, &playerY, &viewz, pPlayerSprite, &nSector, nAngle, pan, smoothRatio))
|
2021-02-18 11:14:32 +00:00
|
|
|
{
|
|
|
|
viewz += 2560;
|
2021-10-21 20:39:17 +00:00
|
|
|
calcChaseCamPos(&playerX, &playerY, &viewz, pPlayerSprite, &nSector, nAngle, pan, smoothRatio);
|
2021-02-18 11:14:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
nCamerax = playerX;
|
|
|
|
nCameray = playerY;
|
|
|
|
nCameraz = playerZ;
|
|
|
|
|
2021-11-30 20:29:43 +00:00
|
|
|
if (nSector != -1)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2021-11-30 20:29:43 +00:00
|
|
|
auto pSector = §or[nSector];
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-11-30 20:29:43 +00:00
|
|
|
int Z = pSector->ceilingz + 256;
|
|
|
|
if (Z <= viewz)
|
|
|
|
{
|
|
|
|
Z = pSector->floorz - 256;
|
|
|
|
|
|
|
|
if (Z < viewz)
|
|
|
|
viewz = Z;
|
|
|
|
}
|
|
|
|
else {
|
2019-08-31 07:47:15 +00:00
|
|
|
viewz = Z;
|
2021-11-30 20:29:43 +00:00
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nCamerapan = pan;
|
|
|
|
|
|
|
|
if (nFreeze == 2 || nFreeze == 1)
|
|
|
|
{
|
|
|
|
nSnakeCam = -1;
|
|
|
|
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
|
|
|
|
}
|
|
|
|
|
2019-11-18 20:31:08 +00:00
|
|
|
UpdateMap();
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (nFreeze != 3)
|
|
|
|
{
|
2021-11-11 22:34:03 +00:00
|
|
|
TArray<uint8_t> paldata(numsectors * 2 + numwalls, true);
|
2019-10-11 12:14:30 +00:00
|
|
|
int const viewingRange = viewingrange;
|
2021-05-12 15:09:07 +00:00
|
|
|
int const vr = xs_CRoundToInt(65536. * tan(r_fov * (pi::pi() / 360.)));
|
2019-10-11 12:14:30 +00:00
|
|
|
|
2020-08-28 07:06:49 +00:00
|
|
|
|
|
|
|
videoSetCorrectedAspect();
|
2021-01-04 11:36:54 +00:00
|
|
|
renderSetAspect(MulScale(vr, viewingrange, 16), yxaspect);
|
2019-10-11 12:14:30 +00:00
|
|
|
|
2019-10-27 13:53:20 +00:00
|
|
|
if (HavePLURemap())
|
|
|
|
{
|
2021-11-22 20:17:43 +00:00
|
|
|
auto p = paldata.Data();
|
|
|
|
for (auto& sect : sectors())
|
2019-10-27 13:53:20 +00:00
|
|
|
{
|
2021-11-22 20:17:43 +00:00
|
|
|
uint8_t v;
|
|
|
|
v = *p++ = sect.floorpal;
|
|
|
|
sect.floorpal = RemapPLU(v);
|
|
|
|
v = *p++ = sect.ceilingpal;
|
|
|
|
sect.ceilingpal = RemapPLU(v);
|
2019-10-27 13:53:20 +00:00
|
|
|
}
|
2021-11-22 20:17:43 +00:00
|
|
|
for (auto& wal : walls())
|
2019-10-27 13:53:20 +00:00
|
|
|
{
|
2021-11-22 20:17:43 +00:00
|
|
|
uint8_t v;
|
|
|
|
v = *p++ = wal.pal;
|
|
|
|
wal.pal = RemapPLU(v);
|
2019-10-27 13:53:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-21 10:48:18 +00:00
|
|
|
if (!testnewrenderer)
|
|
|
|
{
|
2021-05-12 15:09:07 +00:00
|
|
|
renderSetRollAngle((float)rotscrnang.asbuildf());
|
2021-11-08 22:40:57 +00:00
|
|
|
renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa.asq16(), nCamerapan.asq16(), nSector, false);
|
2021-04-02 08:28:40 +00:00
|
|
|
analyzesprites(pm_tsprite, pm_spritesortcnt, nCamerax, nCameray, viewz, smoothRatio);
|
2021-03-21 10:48:18 +00:00
|
|
|
renderDrawMasks();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-04-14 19:17:32 +00:00
|
|
|
render_drawrooms(nullptr, { nCamerax, nCameray, viewz }, nSector, nCameraa, nCamerapan, rotscrnang, smoothRatio);
|
2021-03-21 10:48:18 +00:00
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-10-27 13:53:20 +00:00
|
|
|
if (HavePLURemap())
|
|
|
|
{
|
2021-11-22 20:17:43 +00:00
|
|
|
auto p = paldata.Data();
|
|
|
|
for (auto& sect : sectors())
|
2019-10-27 13:53:20 +00:00
|
|
|
{
|
2021-11-22 20:17:43 +00:00
|
|
|
sect.floorpal = *p++;
|
|
|
|
sect.ceilingpal = *p++;
|
2019-10-27 13:53:20 +00:00
|
|
|
}
|
2021-11-22 20:17:43 +00:00
|
|
|
for (auto& wal : walls())
|
2019-10-27 13:53:20 +00:00
|
|
|
{
|
2021-11-22 20:17:43 +00:00
|
|
|
wal.pal = *p++;
|
2019-10-27 13:53:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (nFreeze)
|
|
|
|
{
|
|
|
|
nSnakeCam = -1;
|
|
|
|
|
|
|
|
if (nFreeze == 2)
|
|
|
|
{
|
|
|
|
if (nHeadStage == 4)
|
|
|
|
{
|
|
|
|
nHeadStage = 5;
|
|
|
|
|
2021-09-06 06:33:02 +00:00
|
|
|
pPlayerSprite->cstat |= 0x8000;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2021-09-06 06:33:02 +00:00
|
|
|
int ang2 = nCameraa.asbuild() - pPlayerSprite->ang;
|
2019-08-31 07:47:15 +00:00
|
|
|
if (ang2 < 0)
|
|
|
|
ang2 = -ang2;
|
2019-11-20 16:21:32 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (ang2 > 10)
|
|
|
|
{
|
|
|
|
inita -= (ang2 >> 3);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bSubTitles)
|
|
|
|
{
|
2020-09-06 07:10:45 +00:00
|
|
|
subtitleOverlay.Start(I_GetTimeNS() * (120. / 1'000'000'000));
|
2021-05-02 13:54:19 +00:00
|
|
|
subtitleOverlay.ReadyCinemaText(currentLevel->ex_ramses_text);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2020-08-26 20:22:46 +00:00
|
|
|
inputState.ClearAllInput();
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2020-08-26 20:22:46 +00:00
|
|
|
else if (nHeadStage == 5)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2020-09-06 07:10:45 +00:00
|
|
|
if ((bSubTitles && !subtitleOverlay.AdvanceCinemaText(I_GetTimeNS() * (120. / 1'000'000'000))) || inputState.CheckAllInput())
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2020-08-26 20:22:46 +00:00
|
|
|
inputState.ClearAllInput();
|
2020-09-24 18:14:25 +00:00
|
|
|
LevelFinished();
|
2020-09-04 19:59:38 +00:00
|
|
|
EndLevel = 1;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-11-28 20:40:17 +00:00
|
|
|
if (CDplaying()) {
|
2019-08-31 07:47:15 +00:00
|
|
|
fadecdaudio();
|
2019-11-28 20:40:17 +00:00
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2020-08-26 20:22:46 +00:00
|
|
|
else subtitleOverlay.DisplayText();
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-01-14 20:48:01 +00:00
|
|
|
else if (!sceneonly)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
if (nSnakeCam < 0)
|
|
|
|
{
|
2019-11-08 16:55:26 +00:00
|
|
|
DrawWeapons(smoothRatio);
|
2021-01-02 07:23:01 +00:00
|
|
|
DrawMap(smoothRatio);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RestoreGreenPal();
|
|
|
|
if (nEnemyPal > -1) {
|
2021-10-19 09:19:50 +00:00
|
|
|
pEnemy->s().pal = (uint8_t)nEnemyPal;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-01-02 07:23:01 +00:00
|
|
|
DrawMap(smoothRatio);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-12 18:52:01 +00:00
|
|
|
twod->ClearScreen();
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 06:33:02 +00:00
|
|
|
pPlayerSprite->cstat = nPlayerOldCstat;
|
2021-10-21 17:54:39 +00:00
|
|
|
pDop->cstat = nDoppleOldCstat;
|
2020-11-26 17:29:20 +00:00
|
|
|
RestoreInterpolations();
|
2019-11-03 17:20:05 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
flash = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2020-01-14 20:48:01 +00:00
|
|
|
bool GameInterface::GenerateSavePic()
|
|
|
|
{
|
|
|
|
DrawView(65536, true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-04-02 08:28:40 +00:00
|
|
|
void GameInterface::processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
|
2021-03-26 00:35:23 +00:00
|
|
|
{
|
2021-04-02 08:28:40 +00:00
|
|
|
analyzesprites(tsprite, spritesortcnt, viewx, viewy, viewz, smoothRatio);
|
2021-03-26 00:35:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-08-26 03:59:14 +00:00
|
|
|
void NoClip()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Clip()
|
|
|
|
{
|
|
|
|
}
|
2019-12-26 21:00:04 +00:00
|
|
|
|
2020-11-29 22:32:28 +00:00
|
|
|
void SerializeView(FSerializer& arc)
|
|
|
|
{
|
2021-11-07 20:45:51 +00:00
|
|
|
if (arc.BeginObject("view"))
|
|
|
|
{
|
|
|
|
arc("camerax", nCamerax)
|
|
|
|
("cameray", nCameray)
|
|
|
|
("cameraz", nCameraz)
|
|
|
|
("touchfloor", bTouchFloor)
|
|
|
|
("chunktotal", nChunkTotal)
|
|
|
|
("cameraa", nCameraa)
|
|
|
|
("camerapan", nCamerapan)
|
|
|
|
("camera", bCamera)
|
|
|
|
("viewz", viewz)
|
|
|
|
("enemy", pEnemy)
|
|
|
|
("enemypal", nEnemyPal)
|
|
|
|
.Array("vertpan", dVertPan, countof(dVertPan))
|
|
|
|
.Array("quake", nQuake, countof(nQuake))
|
|
|
|
.EndObject();
|
|
|
|
}
|
2020-11-29 22:32:28 +00:00
|
|
|
}
|
2019-12-26 21:00:04 +00:00
|
|
|
|
2019-11-22 23:11:37 +00:00
|
|
|
END_PS_NS
|