2009-02-17 15:07:44 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-24 18:31:05 +00:00
|
|
|
#include "sci/tools.h"
|
2009-03-01 06:02:17 +00:00
|
|
|
#include "sci/sfx/core.h"
|
2009-03-06 18:11:12 +00:00
|
|
|
#include "sci/sfx/iterator.h"
|
2009-02-24 05:39:10 +00:00
|
|
|
#include "sci/sci_memory.h"
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
namespace Sci {
|
|
|
|
|
2009-02-15 06:10:59 +00:00
|
|
|
#define debug_stream stderr
|
|
|
|
|
2009-03-06 07:25:06 +00:00
|
|
|
song_t *song_new(song_handle_t handle, SongIterator *it, int priority) {
|
2009-02-15 06:10:59 +00:00
|
|
|
song_t *retval;
|
|
|
|
retval = (song_t*) sci_malloc(sizeof(song_t));
|
|
|
|
|
|
|
|
#ifdef SATISFY_PURIFY
|
|
|
|
memset(retval, 0, sizeof(song_t));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
retval->handle = handle;
|
|
|
|
retval->priority = priority;
|
|
|
|
retval->next = NULL;
|
2009-03-09 16:15:35 +00:00
|
|
|
retval->_delay = 0;
|
|
|
|
retval->_wakeupTime = Audio::Timestamp();
|
2009-02-15 06:10:59 +00:00
|
|
|
retval->it = it;
|
|
|
|
retval->status = SOUND_STATUS_STOPPED;
|
|
|
|
retval->next_playing = NULL;
|
|
|
|
retval->next_stopping = NULL;
|
|
|
|
retval->restore_behavior = RESTORE_BEHAVIOR_CONTINUE;
|
|
|
|
retval->restore_time = 0;
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
void song_lib_add(songlib_t songlib, song_t *song) {
|
2009-02-15 06:10:59 +00:00
|
|
|
song_t **seeker = NULL;
|
|
|
|
int pri = song->priority;
|
|
|
|
|
|
|
|
if (NULL == song) {
|
2009-02-15 22:34:41 +00:00
|
|
|
sciprintf("song_lib_add(): NULL passed for song\n");
|
|
|
|
return;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (*(songlib.lib) == NULL) {
|
|
|
|
*(songlib.lib) = song;
|
|
|
|
song->next = NULL;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
seeker = (songlib.lib);
|
|
|
|
while (*seeker && ((*seeker)->priority > pri))
|
|
|
|
seeker = &((*seeker)->next);
|
|
|
|
|
|
|
|
song->next = *seeker;
|
|
|
|
*seeker = song;
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
static void _songfree_chain(song_t *song) {
|
|
|
|
/* Recursively free a chain of songs */
|
2009-02-15 06:10:59 +00:00
|
|
|
if (song) {
|
|
|
|
_songfree_chain(song->next);
|
2009-03-06 17:53:11 +00:00
|
|
|
delete song->it;
|
2009-02-15 06:10:59 +00:00
|
|
|
song->it = NULL;
|
|
|
|
free(song);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
void song_lib_init(songlib_t *songlib) {
|
2009-02-15 06:10:59 +00:00
|
|
|
songlib->lib = &(songlib->_s);
|
|
|
|
songlib->_s = NULL;
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
void song_lib_free(songlib_t songlib) {
|
2009-02-15 06:10:59 +00:00
|
|
|
_songfree_chain(*(songlib.lib));
|
|
|
|
*(songlib.lib) = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
song_t *song_lib_find(songlib_t songlib, song_handle_t handle) {
|
2009-02-15 06:10:59 +00:00
|
|
|
song_t *seeker = *(songlib.lib);
|
|
|
|
|
|
|
|
while (seeker) {
|
|
|
|
if (seeker->handle == handle)
|
|
|
|
break;
|
|
|
|
seeker = seeker->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return seeker;
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
song_t *song_lib_find_next_active(songlib_t songlib, song_t *other) {
|
2009-02-15 22:34:41 +00:00
|
|
|
song_t *seeker = other ? other->next : *(songlib.lib);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
while (seeker) {
|
|
|
|
if ((seeker->status == SOUND_STATUS_WAITING) ||
|
2009-02-15 22:34:41 +00:00
|
|
|
(seeker->status == SOUND_STATUS_PLAYING))
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
seeker = seeker->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only return songs that have equal priority */
|
|
|
|
if (other && seeker && other->priority > seeker->priority)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return seeker;
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
song_t *song_lib_find_active(songlib_t songlib) {
|
2009-02-15 06:10:59 +00:00
|
|
|
return song_lib_find_next_active(songlib, NULL);
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
int song_lib_remove(songlib_t songlib, song_handle_t handle) {
|
2009-02-15 06:10:59 +00:00
|
|
|
int retval;
|
|
|
|
song_t *goner = *(songlib.lib);
|
|
|
|
|
|
|
|
if (!goner)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (goner->handle == handle)
|
|
|
|
*(songlib.lib) = goner->next;
|
|
|
|
|
|
|
|
else {
|
|
|
|
while ((goner->next) && (goner->next->handle != handle))
|
|
|
|
goner = goner->next;
|
|
|
|
|
|
|
|
if (goner->next) { /* Found him? */
|
|
|
|
song_t *oldnext = goner->next;
|
|
|
|
|
|
|
|
goner->next = goner->next->next;
|
|
|
|
goner = oldnext;
|
|
|
|
} else return -1; /* No. */
|
|
|
|
}
|
|
|
|
|
|
|
|
retval = goner->status;
|
|
|
|
|
2009-03-06 17:53:11 +00:00
|
|
|
delete goner->it;
|
2009-02-15 06:10:59 +00:00
|
|
|
free(goner);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
void song_lib_resort(songlib_t songlib, song_t *song) {
|
2009-02-15 06:10:59 +00:00
|
|
|
if (*(songlib.lib) == song)
|
|
|
|
*(songlib.lib) = song->next;
|
|
|
|
else {
|
|
|
|
song_t *seeker = *(songlib.lib);
|
|
|
|
|
|
|
|
while (seeker->next && (seeker->next != song))
|
|
|
|
seeker = seeker->next;
|
|
|
|
|
|
|
|
if (seeker->next)
|
|
|
|
seeker->next = seeker->next->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
song_lib_add(songlib, song);
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
int song_lib_count(songlib_t songlib) {
|
2009-02-15 06:10:59 +00:00
|
|
|
song_t *seeker = *(songlib.lib);
|
|
|
|
int retval = 0;
|
|
|
|
|
|
|
|
while (seeker) {
|
|
|
|
retval++;
|
|
|
|
seeker = seeker->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
void song_lib_set_restore_behavior(songlib_t songlib, song_handle_t handle, RESTORE_BEHAVIOR action) {
|
2009-02-15 06:10:59 +00:00
|
|
|
song_t *seeker = song_lib_find(songlib, handle);
|
|
|
|
|
|
|
|
seeker->restore_behavior = action;
|
|
|
|
}
|
|
|
|
|
2009-02-21 16:20:53 +00:00
|
|
|
void song_lib_dump(songlib_t songlib, int line) {
|
2009-02-15 06:10:59 +00:00
|
|
|
song_t *seeker = *(songlib.lib);
|
|
|
|
|
2009-02-15 22:34:41 +00:00
|
|
|
fprintf(debug_stream, "L%d:", line);
|
2009-02-15 06:10:59 +00:00
|
|
|
do {
|
2009-02-15 22:34:41 +00:00
|
|
|
fprintf(debug_stream, " %p", (void *)seeker);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (seeker) {
|
2009-02-15 22:34:41 +00:00
|
|
|
fprintf(debug_stream, "[%04lx,p=%d,s=%d]->", seeker->handle, seeker->priority, seeker->status);
|
2009-02-15 06:10:59 +00:00
|
|
|
seeker = seeker->next;
|
|
|
|
}
|
2009-02-15 22:34:41 +00:00
|
|
|
fprintf(debug_stream, "\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
} while (seeker);
|
2009-02-15 22:34:41 +00:00
|
|
|
fprintf(debug_stream, "\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
} // End of namespace Sci
|