From b0445027095cfe8e37f42fbedee84657489e7efd Mon Sep 17 00:00:00 2001 From: helixhorned Date: Tue, 13 Mar 2012 20:07:17 +0000 Subject: [PATCH] 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 --- polymer/eduke32/build/include/build.h | 5 ++ polymer/eduke32/build/src/engine.c | 68 ++++++++++++++------------- polymer/eduke32/source/gameexec.c | 2 + polymer/eduke32/source/savegame.c | 1 + polymer/eduke32/source/savegame.h | 2 +- polymer/eduke32/source/sector.h | 1 + 6 files changed, 46 insertions(+), 33 deletions(-) diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index db45dcf1e..106a3f0ad 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -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]; diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 74eabc411..de48991a7 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -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; } diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index 47708d6b0..ae46f6464 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -5053,6 +5053,7 @@ void G_SaveMapState(mapstate_t *save) for (i=0; ispriteext[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; itailspritefree; Bmemcpy(&headspritesect[0],&save->headspritesect[0],sizeof(headspritesect)); Bmemcpy(&prevspritesect[0],&save->prevspritesect[0],sizeof(prevspritesect)); Bmemcpy(&nextspritesect[0],&save->nextspritesect[0],sizeof(nextspritesect)); diff --git a/polymer/eduke32/source/savegame.c b/polymer/eduke32/source/savegame.c index d90a33126..83b375fc8 100644 --- a/polymer/eduke32/source/savegame.c +++ b/polymer/eduke32/source/savegame.c @@ -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 }, diff --git a/polymer/eduke32/source/savegame.h b/polymer/eduke32/source/savegame.h index 0e842a47f..5ff2d2987 100644 --- a/polymer/eduke32/source/savegame.h +++ b/polymer/eduke32/source/savegame.h @@ -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 diff --git a/polymer/eduke32/source/sector.h b/polymer/eduke32/source/sector.h index efef1c7a7..ecb45cfea 100644 --- a/polymer/eduke32/source/sector.h +++ b/polymer/eduke32/source/sector.h @@ -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];