When deleting sprites, insert them at the tail (instead of head) of the freelist.

The major outside-visible change is that this fixes the sound cutoff bugs that
happened because newly-spawned sprites took the place of those whose sounds
had not yet finished playing.

Besides, there are these changes:
 - remove deletesprite{sect,stat}
 - we have a new engine variable 'tailspritefree' that keeps track of the
   sprite freelist tail
 - we need to store it in savegames and mapstates, so bump the savegame
   minor version

git-svn-id: https://svn.eduke32.com/eduke32@2470 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-03-13 20:07:17 +00:00
parent f996995fe5
commit b044502709
6 changed files with 46 additions and 33 deletions

View file

@ -341,6 +341,11 @@ EXTERN int32_t pskymultiyscale[MAXPSKYMULTIS];
EXTERN int16_t pskymultilist[MAXPSKYMULTIS], pskymultibits[MAXPSKYMULTIS];
EXTERN int16_t pskymultioff[MAXPSKYMULTIS][MAXPSKYTILES];
// last sprite in the freelist, that is the spritenum for which
// .statnum==MAXSTATUS && nextspritestat[spritenum]==-1
// (or -1 if freelist is empty):
EXTERN int16_t tailspritefree;
EXTERN int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1];
EXTERN int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES];
EXTERN int16_t nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES];

View file

@ -7505,7 +7505,7 @@ int32_t getclosestcol(int32_t r, int32_t g, int32_t b)
////////// SPRITE LIST MANIPULATION FUNCTIONS //////////
///// sprite lists /////
///// sector lists of sprites /////
// insert sprite at the head of sector list, change .sectnum
static void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sectnum)
@ -7556,23 +7556,9 @@ static void do_deletespritesect(int16_t deleteme)
prevspritesect[next] = prev;
}
// deletespritesect (internal)
static int32_t deletespritesect(int16_t deleteme)
{
// only non-redundant from deletesprite():
if (sprite[deleteme].sectnum == MAXSECTORS)
return(-1); // already not in the world
do_deletespritesect(deleteme);
// put the deleted sprite at the head of the sectnum-freelist:
do_insertsprite_at_headofsect(deleteme, MAXSECTORS);
return(0);
}
///// the same thing, now for status lists /////
// insert sprite at the head of status list, change .statnum
// insert sprite at head of status list, change .statnum
static void do_insertsprite_at_headofstat(int16_t spritenum, int16_t statnum)
{
int16_t ohead = headspritestat[statnum];
@ -7601,6 +7587,8 @@ static int32_t insertspritestat(int16_t statnum)
// make back-link of the new freelist head point to nil
if (headspritestat[MAXSTATUS] >= 0)
prevspritestat[headspritestat[MAXSTATUS]] = -1;
else
tailspritefree = -1;
do_insertsprite_at_headofstat(blanktouse, statnum);
@ -7621,20 +7609,6 @@ static void do_deletespritestat(int16_t deleteme)
prevspritestat[next] = prev;
}
// deletespritestat (internal)
static int32_t deletespritestat(int16_t deleteme)
{
// only non-redundant from deletesprite():
if (sprite[deleteme].statnum == MAXSTATUS)
return(-1); // already not in the world
do_deletespritestat(deleteme);
// put the deleted sprite at the head of the statnum-freelist
do_insertsprite_at_headofstat(deleteme, MAXSTATUS);
return(0);
}
//
// insertsprite
@ -7650,8 +7624,36 @@ int32_t insertsprite(int16_t sectnum, int16_t statnum)
//
int32_t deletesprite(int16_t spritenum)
{
deletespritestat(spritenum);
return(deletespritesect(spritenum));
assert((sprite[spritenum].statnum == MAXSTATUS)
== (sprite[spritenum].sectnum == MAXSECTORS));
if (sprite[spritenum].statnum == MAXSTATUS)
return(-1); // already not in the world
do_deletespritestat(spritenum);
do_deletespritesect(spritenum);
// insert at tail of sector freelist
prevspritesect[spritenum] = tailspritefree;
nextspritesect[spritenum] = -1;
if (tailspritefree >= 0)
nextspritesect[tailspritefree] = spritenum;
else
headspritesect[MAXSECTORS] = spritenum;
sprite[spritenum].sectnum = MAXSECTORS;
// insert at tail of status freelist
prevspritestat[spritenum] = tailspritefree;
nextspritestat[spritenum] = -1;
if (tailspritefree >= 0)
nextspritestat[tailspritefree] = spritenum;
else
headspritestat[MAXSTATUS] = spritenum;
sprite[spritenum].statnum = MAXSTATUS;
tailspritefree = spritenum;
return 0;
}
//
@ -8148,6 +8150,8 @@ void initspritelists(void)
}
prevspritestat[0] = -1;
nextspritestat[MAXSPRITES-1] = -1;
tailspritefree = MAXSPRITES-1;
}

View file

@ -5053,6 +5053,7 @@ void G_SaveMapState(mapstate_t *save)
for (i=0; i<MAXSPRITES; i++)
spriteext[i].tspr = NULL;
Bmemcpy(&save->spriteext[0],&spriteext[0],sizeof(spriteext_t)*MAXSPRITES);
save->tailspritefree = tailspritefree;
Bmemcpy(&save->headspritesect[0],&headspritesect[0],sizeof(headspritesect));
Bmemcpy(&save->prevspritesect[0],&prevspritesect[0],sizeof(prevspritesect));
Bmemcpy(&save->nextspritesect[0],&nextspritesect[0],sizeof(nextspritesect));
@ -5149,6 +5150,7 @@ void G_RestoreMapState(mapstate_t *save)
else
for (i=0; i<MAXSPRITES; i++)
spriteext[i].tspr = NULL;
tailspritefree = save->tailspritefree;
Bmemcpy(&headspritesect[0],&save->headspritesect[0],sizeof(headspritesect));
Bmemcpy(&prevspritesect[0],&save->prevspritesect[0],sizeof(prevspritesect));
Bmemcpy(&nextspritesect[0],&save->nextspritesect[0],sizeof(nextspritesect));

View file

@ -880,6 +880,7 @@ static const dataspec_t svgm_secwsp[] =
{ DS_CNT(numwalls), yax_nextwall, sizeof(yax_nextwall[0]), (intptr_t)&numwalls },
{ DS_LOADFN|DS_PROTECTFN, (void *)&sv_postyaxload, 0, 1 },
#endif
{ 0, &tailspritefree, sizeof(tailspritefree), 1 },
{ 0, &headspritesect[0], sizeof(headspritesect[0]), MAXSECTORS+1 },
{ 0, &prevspritesect[0], sizeof(prevspritesect[0]), MAXSPRITES },
{ 0, &nextspritesect[0], sizeof(nextspritesect[0]), MAXSPRITES },

View file

@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define __savegame_h__
#define SV_MAJOR_VER 1
#define SV_MINOR_VER 1
#define SV_MINOR_VER 2
#pragma pack(push,1)
# if 0

View file

@ -53,6 +53,7 @@ typedef struct {
int16_t g_numAnimWalls;
int16_t g_numClouds,clouds[128],cloudx[128],cloudy[128];
int16_t g_numCyclers;
int16_t tailspritefree;
int16_t headspritesect[MAXSECTORS+1];
int16_t headspritestat[MAXSTATUS+1];
int16_t nextspritesect[MAXSPRITES];