- fixed Blood's mirror render hack for Polymost.

This adds 4 walls and 1 sector without counting them, so we must adjust allocations and array access to handle OOB access and temporarily increase the counter for the mirror render pass.

The new renderer does not need this stuff.
This commit is contained in:
Christoph Oelckers 2021-11-21 18:19:47 +01:00
parent 8cca55c24a
commit d30bf8c8bb
5 changed files with 64 additions and 59 deletions

View file

@ -2333,6 +2333,7 @@ static void polymost_drawmaskwallinternal(int32_t wallIndex)
{ {
auto const wal = (uwallptr_t)&wall[wallIndex]; auto const wal = (uwallptr_t)&wall[wallIndex];
auto const wal2 = (uwallptr_t)&wall[wal->point2]; auto const wal2 = (uwallptr_t)&wall[wal->point2];
if (wal->nextwall == -1) return;
int32_t const sectnum = wall[wal->nextwall].nextsector; int32_t const sectnum = wall[wal->nextwall].nextsector;
auto const sec = (usectorptr_t)&sector[sectnum]; auto const sec = (usectorptr_t)&sector[sectnum];

View file

@ -195,9 +195,11 @@ void setPortalFlags(int mode)
} }
} }
// Note: wall range checks on wall[] need to be disabled because this writes beyond the regular part.
void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer) void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int viewPlayer)
{ {
auto wallarr = wall.Data(); // this disables the range checks for the wall TArray,
for (int i = mirrorcnt - 1; i >= 0; i--) for (int i = mirrorcnt - 1; i >= 0; i--)
{ {
int nTile = 4080 + i; int nTile = 4080 + i;
@ -207,6 +209,8 @@ void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int
{ {
case 0: case 0:
{ {
numwalls += 4; // hack alert. Blood adds some dummy walls and sectors that must not be among the counter, but here they have to be valid.
numsectors++;
int nWall = mirror[i].link; int nWall = mirror[i].link;
int nSector = sectorofwall(nWall); int nSector = sectorofwall(nWall);
walltype* pWall = &wall[nWall]; walltype* pWall = &wall[nWall];
@ -214,18 +218,18 @@ void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int
int nNextSector = pWall->nextsector; int nNextSector = pWall->nextsector;
pWall->nextwall = mirrorwall[0]; pWall->nextwall = mirrorwall[0];
pWall->nextsector = mirrorsector; pWall->nextsector = mirrorsector;
wall[mirrorwall[0]].nextwall = nWall; wallarr[mirrorwall[0]].nextwall = nWall;
wall[mirrorwall[0]].nextsector = nSector; wallarr[mirrorwall[0]].nextsector = nSector;
wall[mirrorwall[0]].x = pWall->point2Wall()->x; wallarr[mirrorwall[0]].x = pWall->point2Wall()->x;
wall[mirrorwall[0]].y = pWall->point2Wall()->y; wallarr[mirrorwall[0]].y = pWall->point2Wall()->y;
wall[mirrorwall[1]].x = pWall->x; wallarr[mirrorwall[1]].x = pWall->x;
wall[mirrorwall[1]].y = pWall->y; wallarr[mirrorwall[1]].y = pWall->y;
wall[mirrorwall[2]].x = wall[mirrorwall[1]].x + (wall[mirrorwall[1]].x - wall[mirrorwall[0]].x) * 16; wallarr[mirrorwall[2]].x = wallarr[mirrorwall[1]].x + (wallarr[mirrorwall[1]].x - wallarr[mirrorwall[0]].x) * 16;
wall[mirrorwall[2]].y = wall[mirrorwall[1]].y + (wall[mirrorwall[1]].y - wall[mirrorwall[0]].y) * 16; wallarr[mirrorwall[2]].y = wallarr[mirrorwall[1]].y + (wallarr[mirrorwall[1]].y - wallarr[mirrorwall[0]].y) * 16;
wall[mirrorwall[3]].x = wall[mirrorwall[0]].x + (wall[mirrorwall[0]].x - wall[mirrorwall[1]].x) * 16; wallarr[mirrorwall[3]].x = wallarr[mirrorwall[0]].x + (wallarr[mirrorwall[0]].x - wallarr[mirrorwall[1]].x) * 16;
wall[mirrorwall[3]].y = wall[mirrorwall[0]].y + (wall[mirrorwall[0]].y - wall[mirrorwall[1]].y) * 16; wallarr[mirrorwall[3]].y = wallarr[mirrorwall[0]].y + (wallarr[mirrorwall[0]].y - wallarr[mirrorwall[1]].y) * 16;
sector[mirrorsector].floorz = sector[nSector].floorz; sector.Data()[mirrorsector].floorz = sector[nSector].floorz;
sector[mirrorsector].ceilingz = sector[nSector].ceilingz; sector.Data()[mirrorsector].ceilingz = sector[nSector].ceilingz;
int cx, cy, ca; int cx, cy, ca;
if (GetWallType(nWall) == kWallStack) if (GetWallType(nWall) == kWallStack)
{ {
@ -242,10 +246,11 @@ void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int
renderDrawMasks(); renderDrawMasks();
if (GetWallType(nWall) != kWallStack) if (GetWallType(nWall) != kWallStack)
renderCompleteMirror(); renderCompleteMirror();
if (wall[nWall].pal != 0 || wall[nWall].shade != 0)
TranslateMirrorColors(wall[nWall].shade, wall[nWall].pal);
pWall->nextwall = nNextWall; pWall->nextwall = nNextWall;
pWall->nextsector = nNextSector; pWall->nextsector = nNextSector;
numwalls -= 4;
numsectors--;
return; return;
} }
case 1: case 1:
@ -318,5 +323,35 @@ void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int
} }
void InitPolymostMirrorHack()
{
mirrorsector = numsectors;
for (int i = 0; i < 4; i++)
{
mirrorwall[i] = numwalls + i;
auto pWall = &(wall.Data()[mirrorwall[i]]);
pWall->picnum = 504;
pWall->overpicnum = 504;
pWall->cstat = 0;
pWall->nextsector = -1;
pWall->nextwall = -1;
pWall->point2 = numwalls + i + 1;
}
wall.Data()[mirrorwall[3]].point2 = mirrorwall[0];
sector.Data()[mirrorsector].ceilingpicnum = 504;
sector.Data()[mirrorsector].floorpicnum = 504;
sector.Data()[mirrorsector].wallptr = mirrorwall[0];
sector.Data()[mirrorsector].wallnum = 4;
}
void PolymostAllocFakeSector()
{
// these additional entries are needed by Blood's mirror code. We must get them upon map load to avoid a later occuring reallocation. Ugh...
// We do not want to actually increase the array size for this, though because it may screw with the savegame code.
// Before rendering this will temporarily be bumped up.
sector.Reserve(1);
wall.Reserve(4);
sector.Resize(numsectors);
wall.Resize(numwalls);
}
END_BLD_NS END_BLD_NS

View file

@ -95,6 +95,11 @@ struct MIRROR
extern MIRROR mirror[16]; extern MIRROR mirror[16];
extern int mirrorcnt, mirrorsector, mirrorwall[4]; extern int mirrorcnt, mirrorsector, mirrorwall[4];
//polymost needs to do some voodoo for mirrors.
void InitPolymostMirrorHack();
void PolymostAllocFakeSector();
inline bool DemoRecordStatus(void) inline bool DemoRecordStatus(void)
{ {

View file

@ -490,6 +490,10 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, int*
numsectors = mapHeader.numsectors; numsectors = mapHeader.numsectors;
numwalls = mapHeader.numwalls; numwalls = mapHeader.numwalls;
allocateMapArrays(mapHeader.numsprites); allocateMapArrays(mapHeader.numsprites);
#if 1 // bad, bad hack, just for making Polymost happy...
PolymostAllocFakeSector();
#endif
dbInit(); dbInit();
if (encrypted) if (encrypted)
{ {

View file

@ -145,28 +145,7 @@ void InitMirrors(void)
} }
mirrorsector = numsectors; mirrorsector = numsectors;
mergePortals(); mergePortals();
#if 1 // The new backend won't need this shit anymore. InitPolymostMirrorHack();
for (int i = 0; i < 4; i++)
{
mirrorwall[i] = numwalls+i;
auto pWall = &wall[mirrorwall[i]];
pWall->picnum = 504;
pWall->overpicnum = 504;
pWall->cstat = 0;
pWall->nextsector = -1;
pWall->nextwall = -1;
pWall->point2 = numwalls+i+1;
}
wall[mirrorwall[3]].point2 = mirrorwall[0];
sector[mirrorsector].ceilingpicnum = 504;
sector[mirrorsector].floorpicnum = 504;
sector[mirrorsector].wallptr = mirrorwall[0];
sector[mirrorsector].wallnum = 4;
#endif
}
void TranslateMirrorColors(int nShade, int nPalette)
{
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -194,10 +173,8 @@ void SerializeMirrors(FSerializer& arc)
{ {
if (arc.BeginObject("mirror")) if (arc.BeginObject("mirror"))
{ {
arc("mirrorcnt", mirrorcnt) arc("mirrorcnt", mirrorcnt)
("mirrorsector", mirrorsector) .Array("mirror", mirror, countof(mirror))
.Array("mirror", mirror, countof(mirror))
.Array("mirrorwall", mirrorwall, countof(mirrorwall))
.EndObject(); .EndObject();
} }
@ -206,32 +183,15 @@ void SerializeMirrors(FSerializer& arc)
tileDelete(504); tileDelete(504);
#ifdef USE_OPENGL
r_rortexture = 4080; r_rortexture = 4080;
r_rortexturerange = 16; r_rortexturerange = 16;
#endif
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
tileDelete(4080 + i); tileDelete(4080 + i);
} }
for (int i = 0; i < 4; i++) InitPolymostMirrorHack();
{ }
auto pWall = &wall[mirrorwall[i]];
pWall->picnum = 504;
pWall->overpicnum = 504;
pWall->cstat = 0;
pWall->nextsector = -1;
pWall->nextwall = -1;
pWall->point2 = numwalls + i + 1;
}
wall[mirrorwall[3]].point2 = mirrorwall[0];
sector[mirrorsector].ceilingpicnum = 504;
sector[mirrorsector].floorpicnum = 504;
sector[mirrorsector].wallptr = mirrorwall[0];
sector[mirrorsector].wallnum = 4;
}
} }
END_BLD_NS END_BLD_NS