* Apply patch #879 by Buginator with some heavy modifications by me

* Upon removing BASE_OBJECTs loop through the lists of outstanding AUDIO_SAMPLEs to delete all of those that refer to this BASE_OBJECT


git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@3023 4a71c877-e1ca-e34f-864e-861f7616d084
master
Giel van Schijndel 2007-12-09 22:36:06 +00:00
parent 6c4c61fbb7
commit cc12f08b1a
3 changed files with 82 additions and 0 deletions

View File

@ -988,3 +988,79 @@ SDWORD audio_GetTrackID( const char *fileName )
return sound_GetTrackID( psTrack ); return sound_GetTrackID( psTrack );
} }
/** Loop through the list of playing and queued audio samples, and destroy any
* of them that refer to the given object.
* \param psObj pointer to the object for which we must destroy all of its
* outstanding audio samples.
*/
void audio_RemoveObj(const void* psObj)
{
unsigned int count = 0;
// loop through queued sounds and check if a sample needs to be removed
AUDIO_SAMPLE *psSample = g_psSampleQueue;
while (psSample != NULL)
{
if (psSample->psObj == psObj)
{
// The current audio sample seems to refer to an object
// that is about to be destroyed. So destroy this
// sample as well.
AUDIO_SAMPLE* toRemove = psSample;
// Make sure to keep our linked list iterator valid
psSample = psSample->psNext;
// Perform the actual task of destroying this sample
audio_RemoveSample(&g_psSampleQueue, toRemove);
free(psSample);
// Increment the deletion count
++count;
}
else
{
psSample = psSample->psNext;
}
}
if (count)
debug(LOG_MEMORY, "audio_RemoveObj: BASE_OBJECT* 0x%p was found %u times in the audio sample queue", psObj, count);
// Reset the deletion count
count = 0;
// loop through list of currently playing sounds and check if a sample needs to be removed
psSample = g_psSampleList;
while (psSample != NULL)
{
if (psSample->psObj == psObj)
{
// The current audio sample seems to refer to an object
// that is about to be destroyed. So destroy this
// sample as well.
AUDIO_SAMPLE* toRemove = psSample;
// Make sure to keep our linked list iterator valid
psSample = psSample->psNext;
// Stop this sound sample
sound_StopTrack(psSample);
// Perform the actual task of destroying this sample
audio_RemoveSample(&g_psSampleList, toRemove);
free(psSample);
// Increment the deletion count
++count;
}
else
{
psSample = psSample->psNext;
}
}
if (count)
debug(LOG_MEMORY, "audio_RemoveObj: ***Warning! psOBJ %p was found %u times in the list of playing audio samples", psObj, count);
}

View File

@ -68,6 +68,7 @@ extern void audio_ResumeAll( void );
extern void audio_StopAll( void ); extern void audio_StopAll( void );
extern SDWORD audio_GetTrackID( const char *fileName ); extern SDWORD audio_GetTrackID( const char *fileName );
extern void audio_RemoveObj(const void* psObj);
/***************************************************************************/ /***************************************************************************/

View File

@ -26,6 +26,7 @@
#include <string.h> #include <string.h>
#include "lib/framework/frame.h" #include "lib/framework/frame.h"
#include "lib/sound/audio.h"
#include "objects.h" #include "objects.h"
#include "deliverance.h" #include "deliverance.h"
#include "lib/gamelib/gtime.h" #include "lib/gamelib/gtime.h"
@ -119,7 +120,11 @@ static void objmemDestroy(BASE_OBJECT *psObj)
default: default:
ASSERT(!"unknown object type", "objmemDestroy: unknown object type in destroyed list at 0x%p", psObj); ASSERT(!"unknown object type", "objmemDestroy: unknown object type in destroyed list at 0x%p", psObj);
} }
// Make sure to get rid of some final references in the sound code to this object first
audio_RemoveObj(psObj);
free(psObj); free(psObj);
debug(LOG_MEMORY, "objmemDestroy: BASE_OBJECT* 0x%p is freed.", psObj);
} }
/* General housekeeping for the object system */ /* General housekeeping for the object system */