2021-03-21 11:22:50 +00:00
|
|
|
BEGIN_SW_NS
|
|
|
|
|
2021-11-25 18:06:52 +00:00
|
|
|
bool FindCeilingView(int match, int* x, int* y, int z, sectortype** sectnum);
|
|
|
|
bool FindFloorView(int match, int* x, int* y, int z, sectortype** sectnum);
|
2021-03-21 16:04:06 +00:00
|
|
|
|
|
|
|
|
2021-11-21 20:47:37 +00:00
|
|
|
int ViewSectorInScene(int cursectnum, int level)
|
2021-03-21 16:04:06 +00:00
|
|
|
{
|
2021-10-29 19:01:22 +00:00
|
|
|
SWStatIterator it(STAT_FAF);
|
|
|
|
while (auto actor = it.Next())
|
2021-03-21 16:04:06 +00:00
|
|
|
{
|
2021-11-21 20:47:37 +00:00
|
|
|
auto sp = &actor->s();
|
2021-03-21 16:04:06 +00:00
|
|
|
|
|
|
|
if (sp->hitag == level)
|
|
|
|
{
|
|
|
|
if (cursectnum == sp->sectnum)
|
|
|
|
{
|
|
|
|
// ignore case if sprite is pointing up
|
|
|
|
if (sp->ang == 1536)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// only gets to here is sprite is pointing down
|
|
|
|
|
|
|
|
// found a potential match
|
2021-11-21 20:47:37 +00:00
|
|
|
int match = sp->lotag;
|
2021-03-21 16:04:06 +00:00
|
|
|
|
2021-05-09 07:05:42 +00:00
|
|
|
if (!testgotpic(FAF_MIRROR_PIC, true))
|
2021-03-21 16:04:06 +00:00
|
|
|
return -1;
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-25 18:06:52 +00:00
|
|
|
void DrawOverlapRoom(int tx, int ty, int tz, fixed_t tq16ang, fixed_t tq16horiz, sectortype* tsect)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
|
|
|
save.zcount = 0;
|
|
|
|
|
2021-11-25 18:06:52 +00:00
|
|
|
int match = ViewSectorInScene(sectnum(tsect), VIEW_LEVEL1);
|
2021-03-21 11:22:50 +00:00
|
|
|
if (match != -1)
|
|
|
|
{
|
2021-11-25 18:06:52 +00:00
|
|
|
FindCeilingView(match, &tx, &ty, tz, &tsect);
|
2021-03-21 11:22:50 +00:00
|
|
|
|
2021-11-25 18:06:52 +00:00
|
|
|
if (tsect == nullptr)
|
2021-03-21 11:22:50 +00:00
|
|
|
return;
|
|
|
|
|
2021-11-25 18:06:52 +00:00
|
|
|
renderDrawRoomsQ16(tx, ty, tz, tq16ang, tq16horiz, sectnum(tsect), false);
|
2021-03-21 11:22:50 +00:00
|
|
|
|
|
|
|
// reset Z's
|
2021-11-21 20:47:37 +00:00
|
|
|
for (int i = 0; i < save.zcount; i++)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-11-24 22:16:28 +00:00
|
|
|
save.sect[i]->floorz = save.zval[i];
|
|
|
|
save.sect[i]->floorpicnum = save.pic[i];
|
|
|
|
save.sect[i]->floorheinum = save.slope[i];
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
|
|
|
|
2021-04-02 08:28:40 +00:00
|
|
|
analyzesprites(pm_tsprite, pm_spritesortcnt, tx, ty, tz, false);
|
|
|
|
post_analyzesprites(pm_tsprite, pm_spritesortcnt);
|
2021-03-21 11:22:50 +00:00
|
|
|
renderDrawMasks();
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-11-25 18:06:52 +00:00
|
|
|
int match = ViewSectorInScene(sectnum(tsect), VIEW_LEVEL2);
|
2021-03-21 11:22:50 +00:00
|
|
|
if (match != -1)
|
|
|
|
{
|
2021-11-25 18:06:52 +00:00
|
|
|
FindFloorView(match, &tx, &ty, tz, &tsect);
|
2021-03-21 11:22:50 +00:00
|
|
|
|
2021-11-25 18:06:52 +00:00
|
|
|
if (tsect == nullptr)
|
2021-03-21 11:22:50 +00:00
|
|
|
return;
|
|
|
|
|
2021-11-25 18:06:52 +00:00
|
|
|
renderDrawRoomsQ16(tx, ty, tz, tq16ang, tq16horiz, sectnum(tsect), false);
|
2021-03-21 11:22:50 +00:00
|
|
|
|
|
|
|
// reset Z's
|
2021-11-21 20:47:37 +00:00
|
|
|
for (int i = 0; i < save.zcount; i++)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-11-24 22:16:28 +00:00
|
|
|
save.sect[i]->ceilingz = save.zval[i];
|
|
|
|
save.sect[i]->ceilingpicnum = save.pic[i];
|
|
|
|
save.sect[i]->ceilingheinum = save.slope[i];
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
|
|
|
|
2021-04-02 08:28:40 +00:00
|
|
|
analyzesprites(pm_tsprite, pm_spritesortcnt, tx, ty, tz, false);
|
|
|
|
post_analyzesprites(pm_tsprite, pm_spritesortcnt);
|
2021-03-21 11:22:50 +00:00
|
|
|
renderDrawMasks();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-21 20:47:37 +00:00
|
|
|
void FAF_DrawRooms(int x, int y, int z, fixed_t q16ang, fixed_t q16horiz, int sectnum)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-10-29 19:01:22 +00:00
|
|
|
SWStatIterator it(STAT_CEILING_FLOOR_PIC_OVERRIDE);
|
|
|
|
while (auto actor = it.Next())
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-10-29 19:01:22 +00:00
|
|
|
auto sp = &actor->s();
|
2021-10-12 20:21:08 +00:00
|
|
|
if (SP_TAG3(sp) == 0)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
|
|
|
// back up ceilingpicnum and ceilingstat
|
2021-11-19 21:03:18 +00:00
|
|
|
SP_TAG5(sp) = sp->sector()->ceilingpicnum;
|
|
|
|
sp->sector()->ceilingpicnum = SP_TAG2(sp);
|
|
|
|
SP_TAG4(sp) = sp->sector()->ceilingstat;
|
|
|
|
SET(sp->sector()->ceilingstat, SP_TAG6(sp));
|
|
|
|
RESET(sp->sector()->ceilingstat, CEILING_STAT_PLAX);
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
2021-10-12 20:21:08 +00:00
|
|
|
else if (SP_TAG3(sp) == 1)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-11-19 21:03:18 +00:00
|
|
|
SP_TAG5(sp) = sp->sector()->floorpicnum;
|
|
|
|
sp->sector()->floorpicnum = SP_TAG2(sp);
|
|
|
|
SP_TAG4(sp) = sp->sector()->floorstat;
|
|
|
|
SET(sp->sector()->floorstat, SP_TAG6(sp));
|
|
|
|
RESET(sp->sector()->floorstat, FLOOR_STAT_PLAX);
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-08 22:40:57 +00:00
|
|
|
renderDrawRoomsQ16(x,y,z,q16ang,q16horiz,sectnum, false);
|
2021-03-21 11:22:50 +00:00
|
|
|
|
|
|
|
it.Reset(STAT_CEILING_FLOOR_PIC_OVERRIDE);
|
2021-10-29 19:01:22 +00:00
|
|
|
while (auto actor = it.Next())
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-10-29 19:01:22 +00:00
|
|
|
auto sp = &actor->s();
|
2021-03-21 11:22:50 +00:00
|
|
|
// manually set gotpic
|
2021-10-12 20:21:08 +00:00
|
|
|
if (gotsector[sp->sectnum])
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-05-09 07:05:42 +00:00
|
|
|
setgotpic(FAF_MIRROR_PIC);
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
|
|
|
|
2021-10-12 20:21:08 +00:00
|
|
|
if (SP_TAG3(sp) == 0)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
|
|
|
// restore ceilingpicnum and ceilingstat
|
2021-11-19 21:03:18 +00:00
|
|
|
sp->sector()->ceilingpicnum = SP_TAG5(sp);
|
|
|
|
sp->sector()->ceilingstat = SP_TAG4(sp);
|
|
|
|
//RESET(sp->sector()->ceilingstat, CEILING_STAT_TYPE_MASK);
|
|
|
|
RESET(sp->sector()->ceilingstat, CEILING_STAT_PLAX);
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
2021-10-12 20:21:08 +00:00
|
|
|
else if (SP_TAG3(sp) == 1)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-11-19 21:03:18 +00:00
|
|
|
sp->sector()->floorpicnum = SP_TAG5(sp);
|
|
|
|
sp->sector()->floorstat = SP_TAG4(sp);
|
|
|
|
//RESET(sp->sector()->floorstat, FLOOR_STAT_TYPE_MASK);
|
|
|
|
RESET(sp->sector()->floorstat, FLOOR_STAT_PLAX);
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-25 18:06:52 +00:00
|
|
|
void polymost_drawscreen(PLAYERp pp, int tx, int ty, int tz, binangle tang, fixedhoriz thoriz, sectortype* tsect)
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
|
|
|
videoSetCorrectedAspect();
|
|
|
|
renderSetAspect(xs_CRoundToInt(double(viewingrange) * tan(r_fov * (pi::pi() / 360.))), yxaspect);
|
|
|
|
OverlapDraw = true;
|
2021-11-25 18:06:52 +00:00
|
|
|
DrawOverlapRoom(tx, ty, tz, tang.asq16(), thoriz.asq16(), tsect);
|
2021-03-21 11:22:50 +00:00
|
|
|
OverlapDraw = false;
|
|
|
|
|
|
|
|
if (automapMode != am_full)// && !ScreenSavePic)
|
|
|
|
{
|
|
|
|
// TEST this! Changed to camerapp
|
|
|
|
//JS_DrawMirrors(camerapp, tx, ty, tz, tang.asq16(), thoriz.asq16());
|
|
|
|
JS_DrawMirrors(pp, tx, ty, tz, tang.asq16(), thoriz.asq16());
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: This call is redundant if the tiled overhead map is shown, but the
|
|
|
|
// HUD elements should be properly outputted with hardware rendering first.
|
|
|
|
if (!FAF_DebugView)
|
2021-11-25 18:06:52 +00:00
|
|
|
FAF_DrawRooms(tx, ty, tz, tang.asq16(), thoriz.asq16(), sectnum(tsect));
|
2021-03-21 11:22:50 +00:00
|
|
|
|
2021-04-02 08:28:40 +00:00
|
|
|
analyzesprites(pm_tsprite, pm_spritesortcnt, tx, ty, tz, tang.asbuild());
|
|
|
|
post_analyzesprites(pm_tsprite, pm_spritesortcnt);
|
2021-03-21 11:22:50 +00:00
|
|
|
renderDrawMasks();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, fixed_t tpq16ang, fixed_t tpq16horiz)
|
|
|
|
{
|
|
|
|
int j, cnt;
|
|
|
|
int dist;
|
|
|
|
int tposx, tposy; // Camera
|
|
|
|
int *longptr;
|
|
|
|
fixed_t tang;
|
|
|
|
|
|
|
|
// int tx, ty, tz, tpang; // Interpolate so mirror doesn't
|
|
|
|
// drift!
|
|
|
|
bool bIsWallMirror = false;
|
|
|
|
|
|
|
|
{
|
|
|
|
for (cnt = MAXMIRRORS - 1; cnt >= 0; cnt--)
|
2021-05-09 07:05:42 +00:00
|
|
|
//if (testgotpic(cnt + MIRRORLABEL) || testgotpic(cnt + CAMSPRITE))
|
|
|
|
if (testgotpic(cnt + MIRRORLABEL) || ((unsigned)mirror[cnt].campic < MAXTILES && testgotpic(mirror[cnt].campic)))
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
|
|
|
bIsWallMirror = false;
|
2021-05-09 07:05:42 +00:00
|
|
|
if (testgotpic(cnt + MIRRORLABEL, true))
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
|
|
|
bIsWallMirror = true;
|
|
|
|
}
|
2021-05-09 07:05:42 +00:00
|
|
|
else if ((unsigned)mirror[cnt].campic < MAXTILES && testgotpic(mirror[cnt].campic))
|
2021-03-21 11:22:50 +00:00
|
|
|
{
|
2021-05-09 07:05:42 +00:00
|
|
|
cleargotpic(mirror[cnt].campic);
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mirrorinview = true;
|
|
|
|
|
2021-04-11 06:45:19 +00:00
|
|
|
// tx = interpolatedvalue(pp->oposx, pp->posx, smoothratio);
|
|
|
|
// ty = interpolatedvalue(pp->oposy, pp->posy, smoothratio);
|
|
|
|
// tz = interpolatedvalue(pp->oposz, pp->posz, smoothratio);
|
2021-03-21 11:22:50 +00:00
|
|
|
// tpq16ang = pp->angle.ang.asq16();
|
|
|
|
|
|
|
|
|
|
|
|
dist = 0x7fffffff;
|
|
|
|
|
|
|
|
if (bIsWallMirror)
|
|
|
|
{
|
2021-11-24 17:18:23 +00:00
|
|
|
j = abs(mirror[cnt].mirrorWall->x - tx);
|
|
|
|
j += abs(mirror[cnt].mirrorWall->y - ty);
|
2021-03-21 11:22:50 +00:00
|
|
|
if (j < dist)
|
|
|
|
dist = j;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPRITEp tp;
|
|
|
|
|
2021-11-02 17:40:03 +00:00
|
|
|
tp = &mirror[cnt].camspriteActor->s();
|
2021-03-21 11:22:50 +00:00
|
|
|
|
|
|
|
j = abs(tp->x - tx);
|
|
|
|
j += abs(tp->y - ty);
|
|
|
|
if (j < dist)
|
|
|
|
dist = j;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mirror[cnt].ismagic)
|
|
|
|
{
|
2021-07-10 12:25:18 +00:00
|
|
|
SPRITEp sp=nullptr;
|
2021-03-21 11:22:50 +00:00
|
|
|
int camhoriz;
|
2021-11-21 20:47:37 +00:00
|
|
|
int w;
|
2021-03-21 11:22:50 +00:00
|
|
|
int dx, dy, dz, tdx, tdy, tdz, midx, midy;
|
|
|
|
|
|
|
|
|
2021-11-02 17:40:03 +00:00
|
|
|
ASSERT(mirror[cnt].cameraActor != nullptr);
|
2021-03-21 11:22:50 +00:00
|
|
|
|
2021-11-02 17:40:03 +00:00
|
|
|
sp = &mirror[cnt].cameraActor->s();
|
2021-03-21 11:22:50 +00:00
|
|
|
|
|
|
|
// Calculate the angle of the mirror wall
|
2021-11-24 17:18:23 +00:00
|
|
|
auto wal = mirror[cnt].mirrorWall;
|
2021-03-21 11:22:50 +00:00
|
|
|
|
|
|
|
// Get wall midpoint for offset in mirror view
|
2021-11-24 17:18:23 +00:00
|
|
|
midx = (wal->x + wal->point2Wall()->x) / 2;
|
|
|
|
midy = (wal->y + wal->point2Wall()->y) / 2;
|
2021-03-21 11:22:50 +00:00
|
|
|
|
|
|
|
// Finish finding offsets
|
|
|
|
tdx = abs(midx - tx);
|
|
|
|
tdy = abs(midy - ty);
|
|
|
|
|
|
|
|
if (midx >= tx)
|
|
|
|
dx = sp->x - tdx;
|
|
|
|
else
|
|
|
|
dx = sp->x + tdx;
|
|
|
|
|
|
|
|
if (midy >= ty)
|
|
|
|
dy = sp->y - tdy;
|
|
|
|
else
|
|
|
|
dy = sp->y + tdy;
|
|
|
|
|
|
|
|
tdz = abs(tz - sp->z);
|
|
|
|
if (tz >= sp->z)
|
|
|
|
dz = sp->z + tdz;
|
|
|
|
else
|
|
|
|
dz = sp->z - tdz;
|
|
|
|
|
|
|
|
|
|
|
|
// Is it a TV cam or a teleporter that shows destination?
|
|
|
|
// true = It's a TV cam
|
|
|
|
mirror[cnt].mstate = m_normal;
|
|
|
|
if (TEST_BOOL1(sp))
|
|
|
|
mirror[cnt].mstate = m_viewon;
|
|
|
|
|
|
|
|
// Show teleport destination
|
2021-11-09 08:06:54 +00:00
|
|
|
// NOTE: Adding true lets you draw a room, even if
|
2021-03-21 11:22:50 +00:00
|
|
|
// you are outside of it!
|
|
|
|
if (mirror[cnt].mstate != m_viewon)
|
|
|
|
{
|
|
|
|
tileDelete(MIRROR);
|
|
|
|
// Set TV camera sprite size to 0 to show mirror
|
|
|
|
// behind in this case!
|
|
|
|
|
|
|
|
if (mirror[cnt].campic != -1)
|
|
|
|
tileDelete(mirror[cnt].campic);
|
2021-11-08 22:40:57 +00:00
|
|
|
renderDrawRoomsQ16(dx, dy, dz, tpq16ang, tpq16horiz, sp->sectnum, true);
|
2021-04-02 08:28:40 +00:00
|
|
|
analyzesprites(pm_tsprite, pm_spritesortcnt, dx, dy, dz, false);
|
2021-03-21 11:22:50 +00:00
|
|
|
renderDrawMasks();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// It's just a mirror
|
|
|
|
// Prepare drawrooms for drawing mirror and calculate
|
|
|
|
// reflected
|
|
|
|
// position into tposx, tposy, and tang (tposz == cposz)
|
|
|
|
// Must call preparemirror before drawrooms and
|
|
|
|
// completemirror after drawrooms
|
2021-03-29 19:48:23 +00:00
|
|
|
display_mirror = true;
|
2021-03-21 11:22:50 +00:00
|
|
|
renderPrepareMirror(tx, ty, tz, tpq16ang, tpq16horiz,
|
2021-11-24 17:18:23 +00:00
|
|
|
wallnum(mirror[cnt].mirrorWall), /*mirror[cnt].mirrorsector,*/ &tposx, &tposy, &tang);
|
2021-03-21 11:22:50 +00:00
|
|
|
|
2021-11-24 17:18:23 +00:00
|
|
|
renderDrawRoomsQ16(tposx, tposy, tz, (tang), tpq16horiz, sectnum(mirror[cnt].mirrorSector), true);
|
2021-03-21 11:22:50 +00:00
|
|
|
|
2021-04-02 08:28:40 +00:00
|
|
|
analyzesprites(pm_tsprite, pm_spritesortcnt, tposx, tposy, tz, tang >> 16);
|
2021-03-21 11:22:50 +00:00
|
|
|
renderDrawMasks();
|
|
|
|
|
|
|
|
renderCompleteMirror(); // Reverse screen x-wise in this
|
2021-03-29 19:48:23 +00:00
|
|
|
display_mirror = false;
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clean up anything that the camera view might have done
|
|
|
|
tileDelete(MIRROR);
|
2021-11-24 17:18:23 +00:00
|
|
|
mirror[cnt].mirrorWall->overpicnum = MIRRORLABEL + cnt;
|
2021-03-21 11:22:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
mirrorinview = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
END_SW_NS
|