mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 09:21:12 +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 fixspritesectors(void)
|
||||||
{
|
{
|
||||||
int32_t i, j, dax, day, cz, fz;
|
int32_t i;
|
||||||
int32_t numfixedsprites = 0, printfirsttime = 0;
|
int32_t numfixedsprites = 0, printfirsttime = 0;
|
||||||
|
|
||||||
for (i=numsectors-1; i>=0; i--)
|
for (i=numsectors-1; i>=0; i--)
|
||||||
|
@ -8566,11 +8566,12 @@ int32_t fixspritesectors(void)
|
||||||
for (i=0; i<MAXSPRITES; i++)
|
for (i=0; i<MAXSPRITES; i++)
|
||||||
if (sprite[i].statnum < MAXSTATUS)
|
if (sprite[i].statnum < MAXSTATUS)
|
||||||
{
|
{
|
||||||
dax = sprite[i].x;
|
const int32_t dax=sprite[i].x, day=sprite[i].y;
|
||||||
day = sprite[i].y;
|
|
||||||
|
|
||||||
if (inside(dax,day,sprite[i].sectnum) != 1)
|
if (inside(dax,day,sprite[i].sectnum) != 1)
|
||||||
{
|
{
|
||||||
|
int32_t j, cz, fz;
|
||||||
|
|
||||||
spriteoncfz(i, &cz, &fz);
|
spriteoncfz(i, &cz, &fz);
|
||||||
|
|
||||||
for (j=0; j<numsectors; j++)
|
for (j=0; j<numsectors; j++)
|
||||||
|
@ -8589,7 +8590,8 @@ int32_t fixspritesectors(void)
|
||||||
initprintf("--------------------\n");
|
initprintf("--------------------\n");
|
||||||
printfirsttime = 1;
|
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);
|
changespritesect(i, j);
|
||||||
}
|
}
|
||||||
break;
|
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)
|
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
|
#if !defined USE_OPENGL || !defined POLYMER
|
||||||
UNREFERENCED_PARAMETER(myflags);
|
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++)
|
for (i=0; i<numsprites; i++)
|
||||||
{
|
{
|
||||||
|
int32_t removeit = 0;
|
||||||
|
|
||||||
if ((sprite[i].cstat & 48) == 48)
|
if ((sprite[i].cstat & 48) == 48)
|
||||||
sprite[i].cstat &= ~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);
|
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!
|
//Must be after loading sectors, etc!
|
||||||
updatesector(dapos->x, dapos->y, dacursectnum);
|
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 MYMAXWALLS() (MAXSECTORS==MAXSECTORSV7 || mapversion <= 7 ? MAXWALLSV7 : MAXWALLSV8)
|
||||||
#define MYMAXSPRITES() (MAXSECTORS==MAXSECTORSV7 || mapversion <= 7 ? MAXSPRITESV7 : MAXSPRITESV8)
|
#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)
|
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));
|
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);
|
updatesector(sprite[i].x, sprite[i].y, &sprite[i].sectnum);
|
||||||
|
|
||||||
if (sprite[i].sectnum < 0)
|
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 sector (%d) ",
|
||||||
{
|
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), osectnum);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((unsigned)sprite[i].picnum >= MAXTILES)
|
if (sprite[i].statnum != MAXSTATUS)
|
||||||
{
|
initprintf_nowarn("changed to sector %d.\n", TrackerCast(sprite[i].sectnum));
|
||||||
initprintf_nowarn(OSD_ERROR "Map error: sprite #%d (%d,%d) with illegal picnum (%d). Map is corrupt!\n",
|
else
|
||||||
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), TrackerCast(sprite[i].sectnum));
|
initprintf_nowarn("REMOVED.\n");
|
||||||
sprite[i].picnum = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9777,6 +9825,9 @@ int32_t loadboard(char *filename, char flags, vec3_t *dapos, int16_t *daang, int
|
||||||
|
|
||||||
kread(fil, sprite, sizeof(spritetype)*numsprites);
|
kread(fil, sprite, sizeof(spritetype)*numsprites);
|
||||||
|
|
||||||
|
kclose(fil);
|
||||||
|
// Done reading file.
|
||||||
|
|
||||||
for (i=numsprites-1; i>=0; i--)
|
for (i=numsprites-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
sprite[i].x = B_LITTLE32(sprite[i].x);
|
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);
|
check_sprite(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
kclose(fil);
|
|
||||||
// Done reading file.
|
|
||||||
|
|
||||||
#ifdef YAX_ENABLE
|
#ifdef YAX_ENABLE
|
||||||
yax_update(mapversion<9);
|
yax_update(mapversion<9);
|
||||||
if (editstatus)
|
if (editstatus)
|
||||||
|
|
|
@ -11467,20 +11467,25 @@ static int32_t check_spritelist_consistency()
|
||||||
|
|
||||||
for (i=0; i<MAXSPRITES; i++)
|
for (i=0; i<MAXSPRITES; i++)
|
||||||
{
|
{
|
||||||
|
const int32_t sectnum=sprite[i].sectnum, statnum=sprite[i].statnum;
|
||||||
|
|
||||||
csc_i = i;
|
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
|
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
|
return 3; // oob sectnum or statnum
|
||||||
|
|
||||||
if (sprite[i].statnum != MAXSTATUS)
|
if (statnum != MAXSTATUS)
|
||||||
ournumsprites++;
|
ournumsprites++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ournumsprites != Numsprites)
|
if (ournumsprites != Numsprites)
|
||||||
|
{
|
||||||
|
initprintf("ournumsprites=%d, Numsprites=%d\n", ournumsprites, Numsprites);
|
||||||
return 4; // counting sprites by statnum!=MAXSTATUS inconsistent with Numsprites
|
return 4; // counting sprites by statnum!=MAXSTATUS inconsistent with Numsprites
|
||||||
|
}
|
||||||
|
|
||||||
// SECTOR LIST
|
// SECTOR LIST
|
||||||
|
|
||||||
|
@ -11917,8 +11922,8 @@ int32_t CheckMapCorruption(int32_t printfromlev, uint64_t tryfixing)
|
||||||
{
|
{
|
||||||
int32_t onumct = numcorruptthings;
|
int32_t onumct = numcorruptthings;
|
||||||
|
|
||||||
CORRUPTCHK_PRINT(3, CORRUPT_SPRITE|i, "SPRITE %d at [%d, %d] is out of the maximal grid range [%d, %d]",
|
CORRUPTCHK_PRINT(3, CORRUPT_SPRITE|i, "SPRITE %d at [%d, %d] is outside the maximal grid range [%d, %d]",
|
||||||
TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), i, -BXY_MAX, BXY_MAX);
|
i, TrackerCast(sprite[i].x), TrackerCast(sprite[i].y), -BXY_MAX, BXY_MAX);
|
||||||
|
|
||||||
if (onumct < MAXCORRUPTTHINGS)
|
if (onumct < MAXCORRUPTTHINGS)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue