mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-15 20:20:54 +00:00
- set up engine portals for SW.
Also moving more code to _polymost.cpp which is only needed for ad-hoc lookup of portals with a client side implementation of a two-layer renderer.
This commit is contained in:
parent
a36377111c
commit
09a9e14feb
8 changed files with 407 additions and 324 deletions
|
@ -40,7 +40,8 @@ enum
|
||||||
PORTAL_SECTOR_CEILING_REFLECT = 4,
|
PORTAL_SECTOR_CEILING_REFLECT = 4,
|
||||||
PORTAL_WALL_VIEW = 5,
|
PORTAL_WALL_VIEW = 5,
|
||||||
PORTAL_WALL_MIRROR = 6,
|
PORTAL_WALL_MIRROR = 6,
|
||||||
PORTAL_SECTOR_GEOMETRY = 7,
|
PORTAL_WALL_TO_SPRITE = 7,
|
||||||
|
PORTAL_SECTOR_GEOMETRY = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,7 +120,7 @@ struct walltype
|
||||||
float xpan_, ypan_;
|
float xpan_, ypan_;
|
||||||
angle_t clipangle;
|
angle_t clipangle;
|
||||||
uint8_t portalflags;
|
uint8_t portalflags;
|
||||||
uint8_t portalnum;
|
uint16_t portalnum;
|
||||||
|
|
||||||
int xpan() const { return int(xpan_); }
|
int xpan() const { return int(xpan_); }
|
||||||
int ypan() const { return int(ypan_); }
|
int ypan() const { return int(ypan_); }
|
||||||
|
|
|
@ -87,7 +87,7 @@ void InitMirrors(void)
|
||||||
{
|
{
|
||||||
mirrorcnt++;
|
mirrorcnt++;
|
||||||
wall[i].portalflags = PORTAL_WALL_VIEW;
|
wall[i].portalflags = PORTAL_WALL_VIEW;
|
||||||
wall[i].portalnum = portalAdd(PORTAL_WALL_VIEW, j);
|
wall[i].portalnum = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,5 +1,350 @@
|
||||||
BEGIN_SW_NS
|
BEGIN_SW_NS
|
||||||
|
|
||||||
|
short GlobStackSect[2];
|
||||||
|
|
||||||
|
void
|
||||||
|
GetUpperLowerSector(short match, int x, int y, short* upper, short* lower)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
short sectorlist[16];
|
||||||
|
int sln = 0;
|
||||||
|
int SpriteNum;
|
||||||
|
SPRITEp sp;
|
||||||
|
|
||||||
|
// keep a list of the last stacked sectors the view was in and
|
||||||
|
// check those fisrt
|
||||||
|
sln = 0;
|
||||||
|
for (i = 0; i < (int)SIZ(GlobStackSect); i++)
|
||||||
|
{
|
||||||
|
// will not hurt if GlobStackSect is invalid - inside checks for this
|
||||||
|
if (inside(x, y, GlobStackSect[i]) == 1)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
SectIterator it(GlobStackSect[i]);
|
||||||
|
while ((SpriteNum = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[SpriteNum];
|
||||||
|
|
||||||
|
if (sp->statnum == STAT_FAF &&
|
||||||
|
(sp->hitag >= VIEW_LEVEL1 && sp->hitag <= VIEW_LEVEL6)
|
||||||
|
&& sp->lotag == match)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sectorlist[sln] = GlobStackSect[i];
|
||||||
|
sln++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// didn't find it yet so test ALL sectors
|
||||||
|
if (sln < 2)
|
||||||
|
{
|
||||||
|
sln = 0;
|
||||||
|
for (i = numsectors - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (inside(x, y, (short)i) == 1)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
SectIterator it(i);
|
||||||
|
while ((SpriteNum = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[SpriteNum];
|
||||||
|
|
||||||
|
if (sp->statnum == STAT_FAF &&
|
||||||
|
(sp->hitag >= VIEW_LEVEL1 && sp->hitag <= VIEW_LEVEL6)
|
||||||
|
&& sp->lotag == match)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sln < (int)SIZ(GlobStackSect))
|
||||||
|
GlobStackSect[sln] = i;
|
||||||
|
if (sln < (int)SIZ(sectorlist))
|
||||||
|
sectorlist[sln] = i;
|
||||||
|
sln++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// might not find ANYTHING if not tagged right
|
||||||
|
if (sln == 0)
|
||||||
|
{
|
||||||
|
*upper = -1;
|
||||||
|
*lower = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Map rooms have NOT been dragged on top of each other
|
||||||
|
else if (sln == 1)
|
||||||
|
{
|
||||||
|
*lower = sectorlist[0];
|
||||||
|
*upper = sectorlist[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Map rooms HAVE been dragged on top of each other
|
||||||
|
// inside will somtimes find that you are in two different sectors if the x,y
|
||||||
|
// is exactly on a sector line.
|
||||||
|
else if (sln > 2)
|
||||||
|
{
|
||||||
|
//DSPRINTF(ds, "TOO MANY SECTORS FOUND: x=%d, y=%d, match=%d, num sectors %d, %d, %d, %d, %d, %d", x, y, match, sln, sectorlist[0], sectorlist[1], sectorlist[2], sectorlist[3], sectorlist[4]);
|
||||||
|
MONO_PRINT(ds);
|
||||||
|
// try again moving the x,y pos around until you only get two sectors
|
||||||
|
GetUpperLowerSector(match, x - 1, y, upper, lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sln == 2)
|
||||||
|
{
|
||||||
|
if (sector[sectorlist[0]].floorz < sector[sectorlist[1]].floorz)
|
||||||
|
{
|
||||||
|
// swap
|
||||||
|
// make sectorlist[0] the LOW sector
|
||||||
|
short hold;
|
||||||
|
|
||||||
|
hold = sectorlist[0];
|
||||||
|
sectorlist[0] = sectorlist[1];
|
||||||
|
sectorlist[1] = hold;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lower = sectorlist[0];
|
||||||
|
*upper = sectorlist[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FindCeilingView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum)
|
||||||
|
{
|
||||||
|
int xoff = 0;
|
||||||
|
int yoff = 0;
|
||||||
|
int i;
|
||||||
|
SPRITEp sp = NULL;
|
||||||
|
int pix_diff;
|
||||||
|
int newz;
|
||||||
|
|
||||||
|
save.zcount = 0;
|
||||||
|
|
||||||
|
// Search Stat List For closest ceiling view sprite
|
||||||
|
// Get the match, xoff, yoff from this point
|
||||||
|
StatIterator it(STAT_FAF);
|
||||||
|
while ((i = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[i];
|
||||||
|
|
||||||
|
if (sp->hitag == VIEW_THRU_CEILING && sp->lotag == match)
|
||||||
|
{
|
||||||
|
xoff = *x - sp->x;
|
||||||
|
yoff = *y - sp->y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it.Reset(STAT_FAF);
|
||||||
|
while ((i = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[i];
|
||||||
|
|
||||||
|
if (sp->lotag == match)
|
||||||
|
{
|
||||||
|
// determine x,y position
|
||||||
|
if (sp->hitag == VIEW_THRU_FLOOR)
|
||||||
|
{
|
||||||
|
short upper, lower;
|
||||||
|
|
||||||
|
*x = sp->x + xoff;
|
||||||
|
*y = sp->y + yoff;
|
||||||
|
|
||||||
|
// get new sector
|
||||||
|
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
||||||
|
*sectnum = upper;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*sectnum < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ASSERT(sp);
|
||||||
|
ASSERT(sp->hitag == VIEW_THRU_FLOOR);
|
||||||
|
|
||||||
|
pix_diff = labs(z - sector[sp->sectnum].floorz) >> 8;
|
||||||
|
newz = sector[sp->sectnum].floorz + ((pix_diff / 128) + 1) * Z(128);
|
||||||
|
|
||||||
|
it.Reset(STAT_FAF);
|
||||||
|
while ((i = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[i];
|
||||||
|
|
||||||
|
if (sp->lotag == match)
|
||||||
|
{
|
||||||
|
// move lower levels ceilings up for the correct view
|
||||||
|
if (sp->hitag == VIEW_LEVEL2)
|
||||||
|
{
|
||||||
|
// save it off
|
||||||
|
save.sectnum[save.zcount] = sp->sectnum;
|
||||||
|
save.zval[save.zcount] = sector[sp->sectnum].floorz;
|
||||||
|
save.pic[save.zcount] = sector[sp->sectnum].floorpicnum;
|
||||||
|
save.slope[save.zcount] = sector[sp->sectnum].floorheinum;
|
||||||
|
|
||||||
|
sector[sp->sectnum].floorz = newz;
|
||||||
|
// don't change FAF_MIRROR_PIC - ConnectArea
|
||||||
|
if (sector[sp->sectnum].floorpicnum != FAF_MIRROR_PIC)
|
||||||
|
sector[sp->sectnum].floorpicnum = FAF_MIRROR_PIC + 1;
|
||||||
|
sector[sp->sectnum].floorheinum = 0;
|
||||||
|
|
||||||
|
save.zcount++;
|
||||||
|
PRODUCTION_ASSERT(save.zcount < ZMAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FindFloorView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum)
|
||||||
|
{
|
||||||
|
int xoff = 0;
|
||||||
|
int yoff = 0;
|
||||||
|
int i;
|
||||||
|
SPRITEp sp = NULL;
|
||||||
|
int newz;
|
||||||
|
int pix_diff;
|
||||||
|
|
||||||
|
save.zcount = 0;
|
||||||
|
|
||||||
|
// Search Stat List For closest ceiling view sprite
|
||||||
|
// Get the match, xoff, yoff from this point
|
||||||
|
StatIterator it(STAT_FAF);
|
||||||
|
while ((i = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[i];
|
||||||
|
|
||||||
|
if (sp->hitag == VIEW_THRU_FLOOR && sp->lotag == match)
|
||||||
|
{
|
||||||
|
xoff = *x - sp->x;
|
||||||
|
yoff = *y - sp->y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
it.Reset(STAT_FAF);
|
||||||
|
while ((i = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[i];
|
||||||
|
|
||||||
|
if (sp->lotag == match)
|
||||||
|
{
|
||||||
|
// determine x,y position
|
||||||
|
if (sp->hitag == VIEW_THRU_CEILING)
|
||||||
|
{
|
||||||
|
short upper, lower;
|
||||||
|
|
||||||
|
*x = sp->x + xoff;
|
||||||
|
*y = sp->y + yoff;
|
||||||
|
|
||||||
|
// get new sector
|
||||||
|
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
||||||
|
*sectnum = lower;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*sectnum < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ASSERT(sp);
|
||||||
|
ASSERT(sp->hitag == VIEW_THRU_CEILING);
|
||||||
|
|
||||||
|
// move ceiling multiple of 128 so that the wall tile will line up
|
||||||
|
pix_diff = labs(z - sector[sp->sectnum].ceilingz) >> 8;
|
||||||
|
newz = sector[sp->sectnum].ceilingz - ((pix_diff / 128) + 1) * Z(128);
|
||||||
|
|
||||||
|
it.Reset(STAT_FAF);
|
||||||
|
while ((i = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[i];
|
||||||
|
|
||||||
|
if (sp->lotag == match)
|
||||||
|
{
|
||||||
|
// move upper levels floors down for the correct view
|
||||||
|
if (sp->hitag == VIEW_LEVEL1)
|
||||||
|
{
|
||||||
|
// save it off
|
||||||
|
save.sectnum[save.zcount] = sp->sectnum;
|
||||||
|
save.zval[save.zcount] = sector[sp->sectnum].ceilingz;
|
||||||
|
save.pic[save.zcount] = sector[sp->sectnum].ceilingpicnum;
|
||||||
|
save.slope[save.zcount] = sector[sp->sectnum].ceilingheinum;
|
||||||
|
|
||||||
|
sector[sp->sectnum].ceilingz = newz;
|
||||||
|
|
||||||
|
// don't change FAF_MIRROR_PIC - ConnectArea
|
||||||
|
if (sector[sp->sectnum].ceilingpicnum != FAF_MIRROR_PIC)
|
||||||
|
sector[sp->sectnum].ceilingpicnum = FAF_MIRROR_PIC + 1;
|
||||||
|
sector[sp->sectnum].ceilingheinum = 0;
|
||||||
|
|
||||||
|
save.zcount++;
|
||||||
|
PRODUCTION_ASSERT(save.zcount < ZMAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
short
|
||||||
|
ViewSectorInScene(short cursectnum, short level)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
SPRITEp sp;
|
||||||
|
short match;
|
||||||
|
|
||||||
|
StatIterator it(STAT_FAF);
|
||||||
|
while ((i = it.NextIndex()) >= 0)
|
||||||
|
{
|
||||||
|
sp = &sprite[i];
|
||||||
|
|
||||||
|
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
|
||||||
|
match = sp->lotag;
|
||||||
|
|
||||||
|
if (!PicInView(FAF_MIRROR_PIC, true))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DrawOverlapRoom(int tx, int ty, int tz, fixed_t tq16ang, fixed_t tq16horiz, short tsectnum)
|
DrawOverlapRoom(int tx, int ty, int tz, fixed_t tq16ang, fixed_t tq16horiz, short tsectnum)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1416,6 +1416,33 @@ void DoPlayerDiveMeter(PLAYERp pp);
|
||||||
void polymost_drawscreen(PLAYERp pp, int tx, int ty, int tz, binangle tang, fixedhoriz thoriz, int tsectnum);
|
void polymost_drawscreen(PLAYERp pp, int tx, int ty, int tz, binangle tang, fixedhoriz thoriz, int tsectnum);
|
||||||
|
|
||||||
|
|
||||||
|
void UpdateWallPortalState()
|
||||||
|
{
|
||||||
|
// This is too obtuse to be maintained statically, but with 8 mirrors at most easy to be kept up to date.
|
||||||
|
for (int i = 0; i < MAXMIRRORS; i++)
|
||||||
|
{
|
||||||
|
auto wal = &wall[mirror[i].mirrorwall];
|
||||||
|
wal->portalflags = 0;
|
||||||
|
wal->portalnum = 0;
|
||||||
|
|
||||||
|
if (!mirror[i].ismagic)
|
||||||
|
{
|
||||||
|
// a simple mirror
|
||||||
|
wal->portalflags = PORTAL_WALL_MIRROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto sp = &sprite[mirror[i].camera];
|
||||||
|
if (!TEST_BOOL1(sp))
|
||||||
|
{
|
||||||
|
wal->portalflags = PORTAL_WALL_TO_SPRITE;
|
||||||
|
wal->portalnum = mirror[i].camera;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
drawscreen(PLAYERp pp, double smoothratio)
|
drawscreen(PLAYERp pp, double smoothratio)
|
||||||
{
|
{
|
||||||
|
@ -1568,6 +1595,7 @@ drawscreen(PLAYERp pp, double smoothratio)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
UpdateWallPortalState();
|
||||||
render_drawrooms(pp->SpriteP, { tx, ty, tz }, tsectnum, tang.asq16(), thoriz.asq16(), trotscrnang.asbuildf());
|
render_drawrooms(pp->SpriteP, { tx, ty, tz }, tsectnum, tang.asq16(), thoriz.asq16(), trotscrnang.asbuildf());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -407,6 +407,7 @@ void InitLevel(MapRecord *maprec)
|
||||||
PlaceActorsOnTracks();
|
PlaceActorsOnTracks();
|
||||||
PostSetupSectorObject();
|
PostSetupSectorObject();
|
||||||
SetupMirrorTiles();
|
SetupMirrorTiles();
|
||||||
|
SetupSectorPortals();
|
||||||
initlava();
|
initlava();
|
||||||
|
|
||||||
// reset NewGame
|
// reset NewGame
|
||||||
|
|
|
@ -2135,6 +2135,7 @@ void DrawOverlapRoom(int tx,int ty,int tz,fixed_t tq16ang,fixed_t tq16horiz,shor
|
||||||
void SetupMirrorTiles(void); // rooms.c
|
void SetupMirrorTiles(void); // rooms.c
|
||||||
bool FAF_Sector(short sectnum); // rooms.c
|
bool FAF_Sector(short sectnum); // rooms.c
|
||||||
int GetZadjustment(short sectnum,short hitag); // rooms.c
|
int GetZadjustment(short sectnum,short hitag); // rooms.c
|
||||||
|
void SetupSectorPortals();
|
||||||
|
|
||||||
void InitSetup(void); // setup.c
|
void InitSetup(void); // setup.c
|
||||||
|
|
||||||
|
|
|
@ -354,7 +354,7 @@ void JS_InitMirrors(void)
|
||||||
if (sp->hitag == MIRROR_CAM && sp->lotag == wall[i].hitag)
|
if (sp->hitag == MIRROR_CAM && sp->lotag == wall[i].hitag)
|
||||||
{
|
{
|
||||||
mirror[mirrorcnt].camera = ii;
|
mirror[mirrorcnt].camera = ii;
|
||||||
// Set up camera varialbes
|
// Set up camera variables
|
||||||
SP_TAG5(sp) = sp->ang; // Set current angle to
|
SP_TAG5(sp) = sp->ang; // Set current angle to
|
||||||
// sprite angle
|
// sprite angle
|
||||||
Found_Cam = true;
|
Found_Cam = true;
|
||||||
|
@ -370,7 +370,7 @@ void JS_InitMirrors(void)
|
||||||
if (sp->hitag == MIRROR_CAM && sp->lotag == wall[i].hitag)
|
if (sp->hitag == MIRROR_CAM && sp->lotag == wall[i].hitag)
|
||||||
{
|
{
|
||||||
mirror[mirrorcnt].camera = ii;
|
mirror[mirrorcnt].camera = ii;
|
||||||
// Set up camera varialbes
|
// Set up camera variables
|
||||||
SP_TAG5(sp) = sp->ang; // Set current angle to
|
SP_TAG5(sp) = sp->ang; // Set current angle to
|
||||||
// sprite angle
|
// sprite angle
|
||||||
Found_Cam = true;
|
Found_Cam = true;
|
||||||
|
@ -536,6 +536,7 @@ int lastcamclock;
|
||||||
// views
|
// views
|
||||||
short camplayerview = 1; // Don't show yourself!
|
short camplayerview = 1; // Don't show yourself!
|
||||||
|
|
||||||
|
|
||||||
// Hack job alert!
|
// Hack job alert!
|
||||||
// Mirrors and cameras are maintained in the same data structure, but for hardware rendering they cannot be interleaved.
|
// Mirrors and cameras are maintained in the same data structure, but for hardware rendering they cannot be interleaved.
|
||||||
// So this function replicates JS_DrawMirrors to only process the camera textures but not change any global state.
|
// So this function replicates JS_DrawMirrors to only process the camera textures but not change any global state.
|
||||||
|
|
|
@ -678,344 +678,50 @@ SetupMirrorTiles(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
short GlobStackSect[2];
|
|
||||||
|
|
||||||
void
|
void SetupSectorPortals()
|
||||||
GetUpperLowerSector(short match, int x, int y, short *upper, short *lower)
|
|
||||||
{
|
{
|
||||||
int i;
|
TArray<int> foundf, foundc;
|
||||||
short sectorlist[16];
|
|
||||||
int sln = 0;
|
|
||||||
int SpriteNum;
|
|
||||||
SPRITEp sp;
|
|
||||||
|
|
||||||
// keep a list of the last stacked sectors the view was in and
|
|
||||||
// check those fisrt
|
|
||||||
sln = 0;
|
|
||||||
for (i = 0; i < (int)SIZ(GlobStackSect); i++)
|
|
||||||
{
|
|
||||||
// will not hurt if GlobStackSect is invalid - inside checks for this
|
|
||||||
if (inside(x, y, GlobStackSect[i]) == 1)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
SectIterator it(GlobStackSect[i]);
|
|
||||||
while ((SpriteNum = it.NextIndex()) >= 0)
|
|
||||||
{
|
|
||||||
sp = &sprite[SpriteNum];
|
|
||||||
|
|
||||||
if (sp->statnum == STAT_FAF &&
|
|
||||||
(sp->hitag >= VIEW_LEVEL1 && sp->hitag <= VIEW_LEVEL6)
|
|
||||||
&& sp->lotag == match)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sectorlist[sln] = GlobStackSect[i];
|
|
||||||
sln++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// didn't find it yet so test ALL sectors
|
|
||||||
if (sln < 2)
|
|
||||||
{
|
|
||||||
sln = 0;
|
|
||||||
for (i = numsectors - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (inside(x, y, (short) i) == 1)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
SectIterator it(i);
|
|
||||||
while ((SpriteNum = it.NextIndex()) >= 0)
|
|
||||||
{
|
|
||||||
sp = &sprite[SpriteNum];
|
|
||||||
|
|
||||||
if (sp->statnum == STAT_FAF &&
|
|
||||||
(sp->hitag >= VIEW_LEVEL1 && sp->hitag <= VIEW_LEVEL6)
|
|
||||||
&& sp->lotag == match)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (sln < (int)SIZ(GlobStackSect))
|
|
||||||
GlobStackSect[sln] = i;
|
|
||||||
if (sln < (int)SIZ(sectorlist))
|
|
||||||
sectorlist[sln] = i;
|
|
||||||
sln++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// might not find ANYTHING if not tagged right
|
|
||||||
if (sln == 0)
|
|
||||||
{
|
|
||||||
*upper = -1;
|
|
||||||
*lower = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Map rooms have NOT been dragged on top of each other
|
|
||||||
else if (sln == 1)
|
|
||||||
{
|
|
||||||
*lower = sectorlist[0];
|
|
||||||
*upper = sectorlist[0];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Map rooms HAVE been dragged on top of each other
|
|
||||||
// inside will somtimes find that you are in two different sectors if the x,y
|
|
||||||
// is exactly on a sector line.
|
|
||||||
else if (sln > 2)
|
|
||||||
{
|
|
||||||
//DSPRINTF(ds, "TOO MANY SECTORS FOUND: x=%d, y=%d, match=%d, num sectors %d, %d, %d, %d, %d, %d", x, y, match, sln, sectorlist[0], sectorlist[1], sectorlist[2], sectorlist[3], sectorlist[4]);
|
|
||||||
MONO_PRINT(ds);
|
|
||||||
// try again moving the x,y pos around until you only get two sectors
|
|
||||||
GetUpperLowerSector(match, x - 1, y, upper, lower);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sln == 2)
|
|
||||||
{
|
|
||||||
if (sector[sectorlist[0]].floorz < sector[sectorlist[1]].floorz)
|
|
||||||
{
|
|
||||||
// swap
|
|
||||||
// make sectorlist[0] the LOW sector
|
|
||||||
short hold;
|
|
||||||
|
|
||||||
hold = sectorlist[0];
|
|
||||||
sectorlist[0] = sectorlist[1];
|
|
||||||
sectorlist[1] = hold;
|
|
||||||
}
|
|
||||||
|
|
||||||
*lower = sectorlist[0];
|
|
||||||
*upper = sectorlist[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FindCeilingView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum)
|
|
||||||
{
|
|
||||||
int xoff = 0;
|
|
||||||
int yoff = 0;
|
|
||||||
int i;
|
|
||||||
SPRITEp sp = NULL;
|
|
||||||
int pix_diff;
|
|
||||||
int newz;
|
|
||||||
|
|
||||||
save.zcount = 0;
|
|
||||||
|
|
||||||
// Search Stat List For closest ceiling view sprite
|
// Search Stat List For closest ceiling view sprite
|
||||||
// Get the match, xoff, yoff from this point
|
// Get the match, xoff, yoff from this point
|
||||||
StatIterator it(STAT_FAF);
|
StatIterator it(STAT_FAF);
|
||||||
while ((i = it.NextIndex()) >= 0)
|
|
||||||
{
|
|
||||||
sp = &sprite[i];
|
|
||||||
|
|
||||||
if (sp->hitag == VIEW_THRU_CEILING && sp->lotag == match)
|
|
||||||
{
|
|
||||||
xoff = *x - sp->x;
|
|
||||||
yoff = *y - sp->y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
it.Reset(STAT_FAF);
|
|
||||||
while ((i = it.NextIndex()) >= 0)
|
|
||||||
{
|
|
||||||
sp = &sprite[i];
|
|
||||||
|
|
||||||
if (sp->lotag == match)
|
|
||||||
{
|
|
||||||
// determine x,y position
|
|
||||||
if (sp->hitag == VIEW_THRU_FLOOR)
|
|
||||||
{
|
|
||||||
short upper, lower;
|
|
||||||
|
|
||||||
*x = sp->x + xoff;
|
|
||||||
*y = sp->y + yoff;
|
|
||||||
|
|
||||||
// get new sector
|
|
||||||
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
|
||||||
*sectnum = upper;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*sectnum < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ASSERT(sp);
|
|
||||||
ASSERT(sp->hitag == VIEW_THRU_FLOOR);
|
|
||||||
|
|
||||||
pix_diff = labs(z - sector[sp->sectnum].floorz) >> 8;
|
|
||||||
newz = sector[sp->sectnum].floorz + ((pix_diff / 128) + 1) * Z(128);
|
|
||||||
|
|
||||||
it.Reset(STAT_FAF);
|
|
||||||
while ((i = it.NextIndex()) >= 0)
|
|
||||||
{
|
|
||||||
sp = &sprite[i];
|
|
||||||
|
|
||||||
if (sp->lotag == match)
|
|
||||||
{
|
|
||||||
// move lower levels ceilings up for the correct view
|
|
||||||
if (sp->hitag == VIEW_LEVEL2)
|
|
||||||
{
|
|
||||||
// save it off
|
|
||||||
save.sectnum[save.zcount] = sp->sectnum;
|
|
||||||
save.zval[save.zcount] = sector[sp->sectnum].floorz;
|
|
||||||
save.pic[save.zcount] = sector[sp->sectnum].floorpicnum;
|
|
||||||
save.slope[save.zcount] = sector[sp->sectnum].floorheinum;
|
|
||||||
|
|
||||||
sector[sp->sectnum].floorz = newz;
|
|
||||||
// don't change FAF_MIRROR_PIC - ConnectArea
|
|
||||||
if (sector[sp->sectnum].floorpicnum != FAF_MIRROR_PIC)
|
|
||||||
sector[sp->sectnum].floorpicnum = FAF_MIRROR_PIC+1;
|
|
||||||
sector[sp->sectnum].floorheinum = 0;
|
|
||||||
|
|
||||||
save.zcount++;
|
|
||||||
PRODUCTION_ASSERT(save.zcount < ZMAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FindFloorView(short match, int32_t* x, int32_t* y, int32_t z, int16_t* sectnum)
|
|
||||||
{
|
|
||||||
int xoff = 0;
|
|
||||||
int yoff = 0;
|
|
||||||
int i;
|
int i;
|
||||||
SPRITEp sp = NULL;
|
|
||||||
int newz;
|
|
||||||
int pix_diff;
|
|
||||||
|
|
||||||
save.zcount = 0;
|
|
||||||
|
|
||||||
// Search Stat List For closest ceiling view sprite
|
|
||||||
// Get the match, xoff, yoff from this point
|
|
||||||
StatIterator it(STAT_FAF);
|
|
||||||
while ((i = it.NextIndex()) >= 0)
|
while ((i = it.NextIndex()) >= 0)
|
||||||
{
|
{
|
||||||
sp = &sprite[i];
|
auto sp = &sprite[i];
|
||||||
|
|
||||||
if (sp->hitag == VIEW_THRU_FLOOR && sp->lotag == match)
|
if (sp->hitag == VIEW_THRU_CEILING) foundc.Push(i);
|
||||||
{
|
if (sp->hitag == VIEW_THRU_FLOOR) foundf.Push(i);
|
||||||
xoff = *x - sp->x;
|
|
||||||
yoff = *y - sp->y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
portalClear();
|
||||||
it.Reset(STAT_FAF);
|
while (foundf.Size())
|
||||||
while ((i = it.NextIndex()) >= 0)
|
|
||||||
{
|
{
|
||||||
sp = &sprite[i];
|
auto spf = &sprite[foundf[0]];
|
||||||
|
auto cindex = foundc.FindEx([=](int i) { return spf->lotag == sprite[i].lotag; });
|
||||||
if (sp->lotag == match)
|
if (cindex != foundc.Size())
|
||||||
{
|
{
|
||||||
// determine x,y position
|
auto spc = &sprite[foundf[cindex]];
|
||||||
if (sp->hitag == VIEW_THRU_CEILING)
|
sector[spf->sectnum].portalflags = PORTAL_SECTOR_FLOOR;
|
||||||
{
|
sector[spf->sectnum].portalnum = portalAdd(PORTAL_SECTOR_FLOOR, spc->sectnum, spc->x - spf->x, spc->y - spf->y, 0);
|
||||||
short upper, lower;
|
|
||||||
|
|
||||||
*x = sp->x + xoff;
|
sector[spc->sectnum].portalflags = PORTAL_SECTOR_CEILING;
|
||||||
*y = sp->y + yoff;
|
sector[spc->sectnum].portalnum = portalAdd(PORTAL_SECTOR_CEILING, spf->sectnum, spf->x - spc->x, spf->y - spc->y, 0);
|
||||||
|
|
||||||
// get new sector
|
//Printf("Portal with tag %d\n", sprite[foundf[0]].lotag);
|
||||||
GetUpperLowerSector(match, *x, *y, &upper, &lower);
|
foundf.Delete(0);
|
||||||
*sectnum = lower;
|
foundc.Delete(cindex);
|
||||||
break;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
//Printf("Floor portal %d without partner\n", sprite[foundf[0]].lotag);
|
||||||
|
foundf.Delete(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto c : foundc)
|
||||||
if (*sectnum < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ASSERT(sp);
|
|
||||||
ASSERT(sp->hitag == VIEW_THRU_CEILING);
|
|
||||||
|
|
||||||
// move ceiling multiple of 128 so that the wall tile will line up
|
|
||||||
pix_diff = labs(z - sector[sp->sectnum].ceilingz) >> 8;
|
|
||||||
newz = sector[sp->sectnum].ceilingz - ((pix_diff / 128) + 1) * Z(128);
|
|
||||||
|
|
||||||
it.Reset(STAT_FAF);
|
|
||||||
while ((i = it.NextIndex()) >= 0)
|
|
||||||
{
|
{
|
||||||
sp = &sprite[i];
|
//Printf("Ceiling portal %d without partner\n", sprite[c].lotag);
|
||||||
|
|
||||||
if (sp->lotag == match)
|
|
||||||
{
|
|
||||||
// move upper levels floors down for the correct view
|
|
||||||
if (sp->hitag == VIEW_LEVEL1)
|
|
||||||
{
|
|
||||||
// save it off
|
|
||||||
save.sectnum[save.zcount] = sp->sectnum;
|
|
||||||
save.zval[save.zcount] = sector[sp->sectnum].ceilingz;
|
|
||||||
save.pic[save.zcount] = sector[sp->sectnum].ceilingpicnum;
|
|
||||||
save.slope[save.zcount] = sector[sp->sectnum].ceilingheinum;
|
|
||||||
|
|
||||||
sector[sp->sectnum].ceilingz = newz;
|
|
||||||
|
|
||||||
// don't change FAF_MIRROR_PIC - ConnectArea
|
|
||||||
if (sector[sp->sectnum].ceilingpicnum != FAF_MIRROR_PIC)
|
|
||||||
sector[sp->sectnum].ceilingpicnum = FAF_MIRROR_PIC+1;
|
|
||||||
sector[sp->sectnum].ceilingheinum = 0;
|
|
||||||
|
|
||||||
save.zcount++;
|
|
||||||
PRODUCTION_ASSERT(save.zcount < ZMAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
short
|
|
||||||
ViewSectorInScene(short cursectnum, short level)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
SPRITEp sp;
|
|
||||||
short match;
|
|
||||||
|
|
||||||
StatIterator it(STAT_FAF);
|
|
||||||
while ((i = it.NextIndex()) >= 0)
|
|
||||||
{
|
|
||||||
sp = &sprite[i];
|
|
||||||
|
|
||||||
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
|
|
||||||
match = sp->lotag;
|
|
||||||
|
|
||||||
if (!PicInView(FAF_MIRROR_PIC, true))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
END_SW_NS
|
END_SW_NS
|
||||||
|
|
Loading…
Reference in a new issue