From 09a9e14febf1229b392de3742dbbb505ae2f0c58 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Mar 2021 17:04:06 +0100 Subject: [PATCH] - 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. --- source/build/include/buildtypes.h | 5 +- source/games/blood/src/mirrors.cpp | 2 +- source/games/sw/src/_polymost.cpp | 345 +++++++++++++++++++++++++++++ source/games/sw/src/draw.cpp | 28 +++ source/games/sw/src/game.cpp | 1 + source/games/sw/src/game.h | 1 + source/games/sw/src/jsector.cpp | 5 +- source/games/sw/src/rooms.cpp | 344 +++------------------------- 8 files changed, 407 insertions(+), 324 deletions(-) diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 52b82791a..3a207932a 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -40,7 +40,8 @@ enum PORTAL_SECTOR_CEILING_REFLECT = 4, PORTAL_WALL_VIEW = 5, 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_; angle_t clipangle; uint8_t portalflags; - uint8_t portalnum; + uint16_t portalnum; int xpan() const { return int(xpan_); } int ypan() const { return int(ypan_); } diff --git a/source/games/blood/src/mirrors.cpp b/source/games/blood/src/mirrors.cpp index 794cfe469..5ad0d2100 100644 --- a/source/games/blood/src/mirrors.cpp +++ b/source/games/blood/src/mirrors.cpp @@ -87,7 +87,7 @@ void InitMirrors(void) { mirrorcnt++; wall[i].portalflags = PORTAL_WALL_VIEW; - wall[i].portalnum = portalAdd(PORTAL_WALL_VIEW, j); + wall[i].portalnum = j; } } continue; diff --git a/source/games/sw/src/_polymost.cpp b/source/games/sw/src/_polymost.cpp index 6c51db73b..739faf36b 100644 --- a/source/games/sw/src/_polymost.cpp +++ b/source/games/sw/src/_polymost.cpp @@ -1,5 +1,350 @@ 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 DrawOverlapRoom(int tx, int ty, int tz, fixed_t tq16ang, fixed_t tq16horiz, short tsectnum) { diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index 499e01186..dc985a28e 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -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 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 drawscreen(PLAYERp pp, double smoothratio) { @@ -1568,6 +1595,7 @@ drawscreen(PLAYERp pp, double smoothratio) } else { + UpdateWallPortalState(); render_drawrooms(pp->SpriteP, { tx, ty, tz }, tsectnum, tang.asq16(), thoriz.asq16(), trotscrnang.asbuildf()); } diff --git a/source/games/sw/src/game.cpp b/source/games/sw/src/game.cpp index ec39e50a8..411b67e70 100644 --- a/source/games/sw/src/game.cpp +++ b/source/games/sw/src/game.cpp @@ -407,6 +407,7 @@ void InitLevel(MapRecord *maprec) PlaceActorsOnTracks(); PostSetupSectorObject(); SetupMirrorTiles(); + SetupSectorPortals(); initlava(); // reset NewGame diff --git a/source/games/sw/src/game.h b/source/games/sw/src/game.h index 3705d0ac9..dff4408a0 100644 --- a/source/games/sw/src/game.h +++ b/source/games/sw/src/game.h @@ -2135,6 +2135,7 @@ void DrawOverlapRoom(int tx,int ty,int tz,fixed_t tq16ang,fixed_t tq16horiz,shor void SetupMirrorTiles(void); // rooms.c bool FAF_Sector(short sectnum); // rooms.c int GetZadjustment(short sectnum,short hitag); // rooms.c +void SetupSectorPortals(); void InitSetup(void); // setup.c diff --git a/source/games/sw/src/jsector.cpp b/source/games/sw/src/jsector.cpp index fa74ca783..1cbe99b10 100644 --- a/source/games/sw/src/jsector.cpp +++ b/source/games/sw/src/jsector.cpp @@ -354,7 +354,7 @@ void JS_InitMirrors(void) if (sp->hitag == MIRROR_CAM && sp->lotag == wall[i].hitag) { mirror[mirrorcnt].camera = ii; - // Set up camera varialbes + // Set up camera variables SP_TAG5(sp) = sp->ang; // Set current angle to // sprite angle Found_Cam = true; @@ -370,7 +370,7 @@ void JS_InitMirrors(void) if (sp->hitag == MIRROR_CAM && sp->lotag == wall[i].hitag) { mirror[mirrorcnt].camera = ii; - // Set up camera varialbes + // Set up camera variables SP_TAG5(sp) = sp->ang; // Set current angle to // sprite angle Found_Cam = true; @@ -536,6 +536,7 @@ int lastcamclock; // views short camplayerview = 1; // Don't show yourself! + // Hack job alert! // 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. diff --git a/source/games/sw/src/rooms.cpp b/source/games/sw/src/rooms.cpp index 121393aec..36017230a 100644 --- a/source/games/sw/src/rooms.cpp +++ b/source/games/sw/src/rooms.cpp @@ -678,344 +678,50 @@ SetupMirrorTiles(void) } } -short GlobStackSect[2]; -void -GetUpperLowerSector(short match, int x, int y, short *upper, short *lower) +void SetupSectorPortals() { - 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; - + TArray foundf, foundc; // 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]; + auto sp = &sprite[i]; - if (sp->hitag == VIEW_THRU_FLOOR && sp->lotag == match) - { - xoff = *x - sp->x; - yoff = *y - sp->y; - break; - } + if (sp->hitag == VIEW_THRU_CEILING) foundc.Push(i); + if (sp->hitag == VIEW_THRU_FLOOR) foundf.Push(i); } - - it.Reset(STAT_FAF); - while ((i = it.NextIndex()) >= 0) + portalClear(); + while (foundf.Size()) { - sp = &sprite[i]; - - if (sp->lotag == match) + auto spf = &sprite[foundf[0]]; + auto cindex = foundc.FindEx([=](int i) { return spf->lotag == sprite[i].lotag; }); + if (cindex != foundc.Size()) { - // determine x,y position - if (sp->hitag == VIEW_THRU_CEILING) - { - short upper, lower; + auto spc = &sprite[foundf[cindex]]; + 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); - *x = sp->x + xoff; - *y = sp->y + yoff; + sector[spc->sectnum].portalflags = PORTAL_SECTOR_CEILING; + sector[spc->sectnum].portalnum = portalAdd(PORTAL_SECTOR_CEILING, spf->sectnum, spf->x - spc->x, spf->y - spc->y, 0); - // get new sector - GetUpperLowerSector(match, *x, *y, &upper, &lower); - *sectnum = lower; - break; - } + //Printf("Portal with tag %d\n", sprite[foundf[0]].lotag); + foundf.Delete(0); + foundc.Delete(cindex); + } + else + { + //Printf("Floor portal %d without partner\n", sprite[foundf[0]].lotag); + foundf.Delete(0); } } - - 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) + for (auto c : foundc) { - 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); - } - } + //Printf("Ceiling portal %d without partner\n", sprite[c].lotag); } - - 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