mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 01:11:28 +00:00
Engine: stricter map load time checking for sprites with oob sectnums.
Sprites are now considered to have out of bounds sector numbers if it is < 0 or >= numsectors (not merely >= MAXSECTORS). If such a sprite is now encountered during post-load, an attempt is made first to assign it a sector number (using updatesector()). If that fails, the sprite is removed from the map. The background is that a dozen of maps do come with such sprites and could previously corrupt the sprite list when loaded. git-svn-id: https://svn.eduke32.com/eduke32@3696 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
08b10ca03c
commit
520b608094
3 changed files with 83 additions and 28 deletions
|
@ -8547,7 +8547,7 @@ static int32_t deletesector(int16_t sucksect)
|
|||
|
||||
int32_t fixspritesectors(void)
|
||||
{
|
||||
int32_t i, j, dax, day, cz, fz;
|
||||
int32_t i;
|
||||
int32_t numfixedsprites = 0, printfirsttime = 0;
|
||||
|
||||
for (i=numsectors-1; i>=0; i--)
|
||||
|
@ -8566,11 +8566,12 @@ int32_t fixspritesectors(void)
|
|||
for (i=0; i<MAXSPRITES; i++)
|
||||
if (sprite[i].statnum < MAXSTATUS)
|
||||
{
|
||||
dax = sprite[i].x;
|
||||
day = sprite[i].y;
|
||||
const int32_t dax=sprite[i].x, day=sprite[i].y;
|
||||
|
||||
if (inside(dax,day,sprite[i].sectnum) != 1)
|
||||
{
|
||||
int32_t j, cz, fz;
|
||||
|
||||
spriteoncfz(i, &cz, &fz);
|
||||
|
||||
for (j=0; j<numsectors; j++)
|
||||
|
@ -8589,7 +8590,8 @@ int32_t fixspritesectors(void)
|
|||
initprintf("--------------------\n");
|
||||
printfirsttime = 1;
|
||||
}
|
||||
initprintf_nowarn("Changed sectnum of sprite %d from %d to %d\n", i, TrackerCast(sprite[i].sectnum), j);
|
||||
initprintf_nowarn("Changed sectnum of sprite #%d from %d to %d\n",
|
||||
i, TrackerCast(sprite[i].sectnum), j);
|
||||
changespritesect(i, j);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -9601,7 +9601,7 @@ static void prepare_loadboard(int32_t fil, vec3_t *dapos, int16_t *daang, int16_
|
|||
|
||||
static void finish_loadboard(const vec3_t *dapos, int16_t *dacursectnum, int16_t numsprites, char myflags)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t i, realnumsprites=numsprites;
|
||||
|
||||
#if !defined USE_OPENGL || !defined POLYMER
|
||||
UNREFERENCED_PARAMETER(myflags);
|
||||
|
@ -9609,12 +9609,44 @@ static void finish_loadboard(const vec3_t *dapos, int16_t *dacursectnum, int16_t
|
|||
|
||||
for (i=0; i<numsprites; i++)
|
||||
{
|
||||
int32_t removeit = 0;
|
||||
|
||||
if ((sprite[i].cstat & 48) == 48)
|
||||
sprite[i].cstat &= ~48;
|
||||
|
||||
if (sprite[i].statnum == MAXSTATUS)
|
||||
{
|
||||
// Sprite was removed in loadboard() -> check_sprite(). Insert it
|
||||
// for now, because we must maintain the sprite numbering.
|
||||
sprite[i].statnum = sprite[i].sectnum = 0;
|
||||
removeit = 1;
|
||||
}
|
||||
|
||||
insertsprite(sprite[i].sectnum, sprite[i].statnum);
|
||||
|
||||
if (removeit)
|
||||
{
|
||||
// Flag .statnum==MAXSTATUS, temporarily creating an inconsistency
|
||||
// with sprite list.
|
||||
sprite[i].statnum = MAXSTATUS;
|
||||
realnumsprites--;
|
||||
}
|
||||
}
|
||||
|
||||
if (numsprites != realnumsprites)
|
||||
{
|
||||
for (i=0; i<numsprites; i++)
|
||||
if (sprite[i].statnum == MAXSTATUS)
|
||||
{
|
||||
// Now remove it for real!
|
||||
sprite[i].statnum = 0;
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
|
||||
numsprites = realnumsprites;
|
||||
Bassert(numsprites == Numsprites);
|
||||
|
||||
//Must be after loading sectors, etc!
|
||||
updatesector(dapos->x, dapos->y, dacursectnum);
|
||||
|
||||
|
@ -9645,31 +9677,47 @@ static void finish_loadboard(const vec3_t *dapos, int16_t *dacursectnum, int16_t
|
|||
#define MYMAXWALLS() (MAXSECTORS==MAXSECTORSV7 || mapversion <= 7 ? MAXWALLSV7 : MAXWALLSV8)
|
||||
#define MYMAXSPRITES() (MAXSECTORS==MAXSECTORSV7 || mapversion <= 7 ? MAXSPRITESV7 : MAXSPRITESV8)
|
||||
|
||||
// Sprite checking
|
||||
|
||||
static void remove_sprite(int32_t i)
|
||||
{
|
||||
Bmemset(&sprite[i], 0, sizeof(spritetype));
|
||||
sprite[i].statnum = MAXSTATUS;
|
||||
sprite[i].sectnum = MAXSECTORS;
|
||||
}
|
||||
|
||||
// This is only to be run after reading the sprite array!
|
||||
static void check_sprite(int32_t i)
|
||||
{
|
||||
if ((unsigned)sprite[i].sectnum >= MYMAXSECTORS())
|
||||
if ((unsigned)sprite[i].statnum >= MAXSTATUS)
|
||||
{
|
||||
initprintf_nowarn(OSD_ERROR "Map error: sprite #%d (%d,%d) with illegal sector (%d). Map is corrupt!\n",
|
||||
initprintf_nowarn(OSD_ERROR "Map error: sprite #%d (%d,%d) with illegal statnum (%d) REMOVED.\n",
|
||||
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), TrackerCast(sprite[i].statnum));
|
||||
remove_sprite(i);
|
||||
}
|
||||
else if ((unsigned)sprite[i].picnum >= MAXTILES)
|
||||
{
|
||||
initprintf_nowarn(OSD_ERROR "Map error: sprite #%d (%d,%d) with illegal picnum (%d) REMOVED.\n",
|
||||
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), TrackerCast(sprite[i].sectnum));
|
||||
remove_sprite(i);
|
||||
}
|
||||
else if ((unsigned)sprite[i].sectnum >= (unsigned)numsectors)
|
||||
{
|
||||
const int32_t osectnum = sprite[i].sectnum;
|
||||
|
||||
sprite[i].sectnum = -1;
|
||||
updatesector(sprite[i].x, sprite[i].y, &sprite[i].sectnum);
|
||||
|
||||
if (sprite[i].sectnum < 0)
|
||||
sprite[i].sectnum = 0;
|
||||
}
|
||||
remove_sprite(i);
|
||||
|
||||
if ((unsigned)sprite[i].statnum >= MAXSTATUS)
|
||||
{
|
||||
initprintf_nowarn(OSD_ERROR "Map error: sprite #%d (%d,%d) with illegal statnum (%d). Map is corrupt!\n",
|
||||
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), TrackerCast(sprite[i].statnum));
|
||||
sprite[i].statnum = 0;
|
||||
}
|
||||
initprintf_nowarn(OSD_ERROR "Map error: sprite #%d (%d,%d) with illegal sector (%d) ",
|
||||
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), osectnum);
|
||||
|
||||
if ((unsigned)sprite[i].picnum >= MAXTILES)
|
||||
{
|
||||
initprintf_nowarn(OSD_ERROR "Map error: sprite #%d (%d,%d) with illegal picnum (%d). Map is corrupt!\n",
|
||||
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), TrackerCast(sprite[i].sectnum));
|
||||
sprite[i].picnum = 0;
|
||||
if (sprite[i].statnum != MAXSTATUS)
|
||||
initprintf_nowarn("changed to sector %d.\n", TrackerCast(sprite[i].sectnum));
|
||||
else
|
||||
initprintf_nowarn("REMOVED.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9777,6 +9825,9 @@ int32_t loadboard(char *filename, char flags, vec3_t *dapos, int16_t *daang, int
|
|||
|
||||
kread(fil, sprite, sizeof(spritetype)*numsprites);
|
||||
|
||||
kclose(fil);
|
||||
// Done reading file.
|
||||
|
||||
for (i=numsprites-1; i>=0; i--)
|
||||
{
|
||||
sprite[i].x = B_LITTLE32(sprite[i].x);
|
||||
|
@ -9798,9 +9849,6 @@ int32_t loadboard(char *filename, char flags, vec3_t *dapos, int16_t *daang, int
|
|||
check_sprite(i);
|
||||
}
|
||||
|
||||
kclose(fil);
|
||||
// Done reading file.
|
||||
|
||||
#ifdef YAX_ENABLE
|
||||
yax_update(mapversion<9);
|
||||
if (editstatus)
|
||||
|
|
|
@ -11467,20 +11467,25 @@ static int32_t check_spritelist_consistency()
|
|||
|
||||
for (i=0; i<MAXSPRITES; i++)
|
||||
{
|
||||
const int32_t sectnum=sprite[i].sectnum, statnum=sprite[i].statnum;
|
||||
|
||||
csc_i = i;
|
||||
|
||||
if ((sprite[i].statnum==MAXSTATUS) != (sprite[i].sectnum==MAXSECTORS))
|
||||
if ((statnum==MAXSTATUS) != (sectnum==MAXSECTORS))
|
||||
return 2; // violation of .statnum==MAXSTATUS iff .sectnum==MAXSECTORS
|
||||
|
||||
if ((unsigned)sprite[i].statnum > MAXSTATUS || (unsigned)sprite[i].sectnum > MAXSECTORS)
|
||||
if ((unsigned)statnum > MAXSTATUS || (sectnum!=MAXSECTORS && (unsigned)sectnum > (unsigned)numsectors))
|
||||
return 3; // oob sectnum or statnum
|
||||
|
||||
if (sprite[i].statnum != MAXSTATUS)
|
||||
if (statnum != MAXSTATUS)
|
||||
ournumsprites++;
|
||||
}
|
||||
|
||||
if (ournumsprites != Numsprites)
|
||||
{
|
||||
initprintf("ournumsprites=%d, Numsprites=%d\n", ournumsprites, Numsprites);
|
||||
return 4; // counting sprites by statnum!=MAXSTATUS inconsistent with Numsprites
|
||||
}
|
||||
|
||||
// SECTOR LIST
|
||||
|
||||
|
@ -11917,8 +11922,8 @@ int32_t CheckMapCorruption(int32_t printfromlev, uint64_t tryfixing)
|
|||
{
|
||||
int32_t onumct = numcorruptthings;
|
||||
|
||||
CORRUPTCHK_PRINT(3, CORRUPT_SPRITE|i, "SPRITE %d at [%d, %d] is out of the maximal grid range [%d, %d]",
|
||||
TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), i, -BXY_MAX, BXY_MAX);
|
||||
CORRUPTCHK_PRINT(3, CORRUPT_SPRITE|i, "SPRITE %d at [%d, %d] is outside the maximal grid range [%d, %d]",
|
||||
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), -BXY_MAX, BXY_MAX);
|
||||
|
||||
if (onumct < MAXCORRUPTTHINGS)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue