2019-09-19 22:42:45 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
|
|
|
Copyright (C) 2019 Nuke.YKT
|
|
|
|
|
|
|
|
This file is part of NBlood.
|
|
|
|
|
|
|
|
NBlood 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-09-21 18:59:54 +00:00
|
|
|
#include "ns.h" // Must come before everything else!
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
#include "build.h"
|
|
|
|
#include "mmulti.h"
|
|
|
|
#include "common_game.h"
|
|
|
|
#include "levels.h"
|
|
|
|
#include "map2d.h"
|
|
|
|
#include "trig.h"
|
|
|
|
#include "view.h"
|
2019-12-31 18:50:27 +00:00
|
|
|
#include "v_2ddrawer.h"
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2019-09-22 06:39:22 +00:00
|
|
|
BEGIN_BLD_NS
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
void sub_2541C(int x, int y, int z, short a)
|
|
|
|
{
|
|
|
|
int tmpydim = (xdim * 5) / 8;
|
|
|
|
renderSetAspect(65536, divscale16(tmpydim * 320, xdim * 200));
|
|
|
|
int nCos = z*sintable[(0-a)&2047];
|
|
|
|
int nSin = z*sintable[(1536-a)&2047];
|
|
|
|
int nCos2 = mulscale16(nCos, yxaspect);
|
|
|
|
int nSin2 = mulscale16(nSin, yxaspect);
|
|
|
|
for (int i = 0; i < numsectors; i++)
|
|
|
|
{
|
2019-09-17 12:17:07 +00:00
|
|
|
if (gFullMap || (show2dsector[i>>3]&(1<<(i&7))))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
int nStartWall = sector[i].wallptr;
|
|
|
|
int nEndWall = nStartWall+sector[i].wallnum;
|
|
|
|
int nZCeil = sector[i].ceilingz;
|
|
|
|
int nZFloor = sector[i].floorz;
|
|
|
|
walltype *pWall = &wall[nStartWall];
|
|
|
|
for (int j = nStartWall; j < nEndWall; j++, pWall++)
|
|
|
|
{
|
|
|
|
int nNextWall = pWall->nextwall;
|
|
|
|
if (nNextWall < 0)
|
|
|
|
continue;
|
|
|
|
if (sector[pWall->nextsector].ceilingz == nZCeil && sector[pWall->nextsector].floorz == nZFloor
|
|
|
|
&& ((wall[nNextWall].cstat | pWall->cstat) & 0x30) == 0)
|
|
|
|
continue;
|
2019-09-17 12:17:07 +00:00
|
|
|
if (gFullMap)
|
2019-09-19 22:42:45 +00:00
|
|
|
continue;
|
|
|
|
if (show2dsector[pWall->nextsector>>3]&(1<<(pWall->nextsector&7)))
|
|
|
|
continue;
|
|
|
|
int wx = pWall->x-x;
|
|
|
|
int wy = pWall->y-y;
|
|
|
|
int cx = xdim<<11;
|
|
|
|
int x1 = cx+dmulscale16(wx, nCos, -wy, nSin);
|
|
|
|
int cy = ydim<<11;
|
|
|
|
int y1 = cy+dmulscale16(wy, nCos2, wx, nSin2);
|
|
|
|
walltype *pWall2 = &wall[pWall->point2];
|
|
|
|
wx = pWall2->x-x;
|
|
|
|
wy = pWall2->y-y;
|
|
|
|
int x2 = cx+dmulscale16(wx, nCos, -wy, nSin);
|
|
|
|
int y2 = cy+dmulscale16(wy, nCos2, wx, nSin2);
|
|
|
|
renderDrawLine(x1,y1,x2,y2,24);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int nPSprite = gView->pSprite->index;
|
|
|
|
for (int i = 0; i < numsectors; i++)
|
|
|
|
{
|
2019-09-17 12:17:07 +00:00
|
|
|
if (gFullMap || (show2dsector[i>>3]&(1<<(i&7))))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
for (int nSprite = headspritesect[i]; nSprite >= 0; nSprite = nextspritesect[nSprite])
|
|
|
|
{
|
|
|
|
spritetype *pSprite = &sprite[nSprite];
|
|
|
|
if (nSprite == nPSprite)
|
|
|
|
continue;
|
|
|
|
if (pSprite->cstat&32768)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < numsectors; i++)
|
|
|
|
{
|
2019-09-17 12:17:07 +00:00
|
|
|
if (gFullMap || (show2dsector[i>>3]&(1<<(i&7))))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
int nStartWall = sector[i].wallptr;
|
|
|
|
int nEndWall = nStartWall+sector[i].wallnum;
|
|
|
|
walltype *pWall = &wall[nStartWall];
|
|
|
|
int nNWall = -1;
|
|
|
|
int x1, y1, x2 = 0, y2 = 0;
|
|
|
|
for (int j = nStartWall; j < nEndWall; j++, pWall++)
|
|
|
|
{
|
|
|
|
int nNextWall = pWall->nextwall;
|
|
|
|
if (nNextWall >= 0)
|
|
|
|
continue;
|
|
|
|
if (!tilesiz[pWall->picnum].x || !tilesiz[pWall->picnum].y)
|
|
|
|
continue;
|
|
|
|
if (nNWall == j)
|
|
|
|
{
|
|
|
|
x1 = x2;
|
|
|
|
y1 = y2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int wx = pWall->x-x;
|
|
|
|
int wy = pWall->y-y;
|
|
|
|
x1 = (xdim<<11)+dmulscale16(wx, nCos, -wy, nSin);
|
|
|
|
y1 = (ydim<<11)+dmulscale16(wy, nCos2, wx, nSin2);
|
|
|
|
}
|
|
|
|
nNWall = pWall->point2;
|
|
|
|
walltype *pWall2 = &wall[nNWall];
|
|
|
|
int wx = pWall2->x-x;
|
|
|
|
int wy = pWall2->y-y;
|
|
|
|
x2 = (xdim<<11)+dmulscale16(wx, nCos, -wy, nSin);
|
|
|
|
y2 = (ydim<<11)+dmulscale16(wy, nCos2, wx, nSin2);
|
|
|
|
renderDrawLine(x1,y1,x2,y2,24);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
videoSetCorrectedAspect();
|
|
|
|
|
|
|
|
for (int i = connecthead; i >= 0; i = connectpoint2[i])
|
|
|
|
{
|
2019-10-21 19:46:41 +00:00
|
|
|
if (gViewMap.bFollowMode || gView->nPlayer != i)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
PLAYER *pPlayer = &gPlayer[i];
|
|
|
|
spritetype *pSprite = pPlayer->pSprite;
|
|
|
|
int px = pSprite->x-x;
|
|
|
|
int py = pSprite->y-y;
|
|
|
|
int pa = (pSprite->ang-a)&2047;
|
2019-10-21 19:46:41 +00:00
|
|
|
if (i == gView->nPlayer)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
px = 0;
|
|
|
|
py = 0;
|
|
|
|
pa = 0;
|
|
|
|
}
|
|
|
|
int x1 = dmulscale16(px, nCos, -py, nSin);
|
|
|
|
int y1 = dmulscale16(py, nCos2, px, nSin2);
|
2019-10-21 19:46:41 +00:00
|
|
|
if (i == gView->nPlayer || gGameOptions.nGameType == 1)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
int nTile = pSprite->picnum;
|
|
|
|
int ceilZ, ceilHit, floorZ, floorHit;
|
2019-09-07 13:53:42 +00:00
|
|
|
GetZRange(pSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, (pSprite->clipdist<<2)+16, CLIPMASK0, PARALLAXCLIP_CEILING|PARALLAXCLIP_FLOOR);
|
2019-09-19 22:42:45 +00:00
|
|
|
int nTop, nBottom;
|
|
|
|
GetSpriteExtents(pSprite, &nTop, &nBottom);
|
|
|
|
int nScale = mulscale((pSprite->yrepeat+((floorZ-nBottom)>>8))*z, yxaspect, 16);
|
|
|
|
nScale = ClipRange(nScale, 8000, 65536<<1);
|
|
|
|
rotatesprite((xdim<<15)+(x1<<4), (ydim<<15)+(y1<<4), nScale, pa, nTile, pSprite->shade, pSprite->pal, (pSprite->cstat&2)>>1,
|
|
|
|
windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CViewMap::CViewMap()
|
|
|
|
{
|
|
|
|
bActive = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CViewMap::sub_25C38(int _x, int _y, int _angle, short zoom, char unk1)
|
|
|
|
{
|
|
|
|
bActive = 1;
|
|
|
|
x = _x;
|
|
|
|
y = _y;
|
|
|
|
angle = _angle;
|
|
|
|
nZoom = zoom;
|
|
|
|
FollowMode(unk1);
|
|
|
|
forward = 0;
|
|
|
|
turn = 0;
|
|
|
|
strafe = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CViewMap::sub_25C74(void)
|
|
|
|
{
|
|
|
|
char pBuffer[128];
|
|
|
|
if (!bActive)
|
|
|
|
return;
|
|
|
|
char tm = 0;
|
|
|
|
int viewSize = gViewSize;
|
|
|
|
if (gViewSize > 3)
|
|
|
|
{
|
|
|
|
viewResizeView(3);
|
|
|
|
tm = 1;
|
|
|
|
}
|
2019-12-31 18:50:27 +00:00
|
|
|
// only clear the actual window.
|
|
|
|
twod->AddColorOnlyQuad(windowxy1.x, windowxy1.y, windowxy2.x - windowxy1.x + 1, windowxy2.y - windowxy1.y - 1, 0xff000000);
|
2019-09-19 22:42:45 +00:00
|
|
|
renderDrawMapView(x,y,nZoom>>2,angle);
|
|
|
|
sub_2541C(x,y,nZoom>>2,angle);
|
2019-12-10 23:57:53 +00:00
|
|
|
const char *pTitle = levelGetTitle();
|
|
|
|
const char *pFilename = levelGetFilename(gGameOptions.nEpisode, gGameOptions.nLevel);
|
2019-09-19 22:42:45 +00:00
|
|
|
if (pTitle)
|
|
|
|
sprintf(pBuffer, "%s: %s", pFilename, pTitle);
|
|
|
|
else
|
|
|
|
sprintf(pBuffer, "%s", pFilename);
|
|
|
|
int nViewY;
|
|
|
|
if (gViewSize > 3)
|
|
|
|
nViewY = gViewY1S-16;
|
|
|
|
else
|
|
|
|
nViewY = gViewY0S+1;
|
|
|
|
viewDrawText(3, pBuffer, gViewX1S, nViewY, -128, 0, 2, 0, 256);
|
|
|
|
|
2019-12-09 01:01:30 +00:00
|
|
|
#if 0 // needs to be generalized
|
2019-09-19 22:42:45 +00:00
|
|
|
if (gViewMap.bFollowMode)
|
|
|
|
viewDrawText(3, "MAP FOLLOW MODE", gViewX1S, nViewY+8, -128, 0, 2, 0, 256);
|
|
|
|
else
|
|
|
|
viewDrawText(3, "MAP SCROLL MODE", gViewX1S, nViewY+8, -128, 0, 2, 0, 256);
|
2019-12-09 01:01:30 +00:00
|
|
|
#endif
|
2019-09-19 22:42:45 +00:00
|
|
|
if (tm)
|
|
|
|
viewResizeView(viewSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CViewMap::sub_25DB0(spritetype *pSprite)
|
|
|
|
{
|
|
|
|
nZoom = gZoom;
|
|
|
|
if (bFollowMode)
|
|
|
|
{
|
|
|
|
x = pSprite->x;
|
|
|
|
y = pSprite->y;
|
|
|
|
angle = pSprite->ang;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
angle += turn>>3;
|
|
|
|
x += mulscale24(forward, Cos(angle));
|
|
|
|
y += mulscale24(forward, Sin(angle));
|
|
|
|
x -= mulscale24(strafe, Cos(angle+512));
|
|
|
|
y -= mulscale24(strafe, Sin(angle+512));
|
|
|
|
forward = 0;
|
|
|
|
strafe = 0;
|
|
|
|
turn = 0;
|
|
|
|
}
|
|
|
|
sub_25C74();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CViewMap::sub_25E84(int *_x, int *_y)
|
|
|
|
{
|
|
|
|
if (_x)
|
|
|
|
*_x = x;
|
|
|
|
if (_y)
|
|
|
|
*_y = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CViewMap::FollowMode(char mode)
|
|
|
|
{
|
|
|
|
bFollowMode = mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
CViewMap gViewMap;
|
2019-09-22 06:39:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
END_BLD_NS
|