SCI: Objectified SongLibrary

svn-id: r41343
This commit is contained in:
Max Horn 2009-06-07 17:06:51 +00:00
parent f2ca788004
commit d07e9dfb13
5 changed files with 121 additions and 131 deletions

View File

@ -493,7 +493,7 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) {
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING); s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
s->_sound.sfx_song_set_loops(handle, looping); s->_sound.sfx_song_set_loops(handle, looping);
s->_sound.sfx_song_renice(handle, pri); s->_sound.sfx_song_renice(handle, pri);
song_lib_set_restore_behavior(s->_sound._songlib, handle, rb); s->_sound._songlib.setSongRestoreBehavior(handle, rb);
} }
break; break;
@ -798,7 +798,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) {
int looping = GET_SEL32V(obj, loop); int looping = GET_SEL32V(obj, loop);
//int vol = GET_SEL32V(obj, vol); //int vol = GET_SEL32V(obj, vol);
int pri = GET_SEL32V(obj, pri); int pri = GET_SEL32V(obj, pri);
Song *song = song_lib_find(s->_sound._songlib, handle); Song *song = s->_sound._songlib.findSong(handle);
if (GET_SEL32V(obj, nodePtr) && (song && number != song->_resourceNum)) { if (GET_SEL32V(obj, nodePtr) && (song && number != song->_resourceNum)) {
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);

View File

@ -404,15 +404,15 @@ void StringFrag::saveLoadWithSerializer(Common::Serializer &s) {
static void sync_songlib_t(Common::Serializer &s, SongLibrary &obj) { static void sync_songlib_t(Common::Serializer &s, SongLibrary &obj) {
int songcount = 0; int songcount = 0;
if (s.isSaving()) if (s.isSaving())
songcount = song_lib_count(obj); songcount = obj.countSongs();
s.syncAsUint32LE(songcount); s.syncAsUint32LE(songcount);
if (s.isLoading()) { if (s.isLoading()) {
song_lib_init(&obj); obj.initSounds();
while (songcount--) { while (songcount--) {
Song *newsong = (Song *)calloc(1, sizeof(Song)); Song *newsong = (Song *)calloc(1, sizeof(Song));
sync_song_t(s, *newsong); sync_song_t(s, *newsong);
song_lib_add(obj, newsong); obj.addSong(newsong);
} }
} else { } else {
Song *seeker = *(obj._lib); Song *seeker = *(obj._lib);
@ -698,7 +698,7 @@ static void reconstruct_sounds(EngineState *s) {
if (s->_sound._songlib._lib) if (s->_sound._songlib._lib)
seeker = *(s->_sound._songlib._lib); seeker = *(s->_sound._songlib._lib);
else { else {
song_lib_init(&s->_sound._songlib); s->_sound._songlib.initSounds();
seeker = NULL; seeker = NULL;
} }
@ -782,7 +782,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
temp = retval->_sound._songlib; temp = retval->_sound._songlib;
retval->_sound.sfx_init(retval->resmgr, s->sfx_init_flags); retval->_sound.sfx_init(retval->resmgr, s->sfx_init_flags);
retval->sfx_init_flags = s->sfx_init_flags; retval->sfx_init_flags = s->sfx_init_flags;
song_lib_free(retval->_sound._songlib); retval->_sound._songlib.freeSounds();
retval->_sound._songlib = temp; retval->_sound._songlib = temp;
_reset_graphics_input(retval); _reset_graphics_input(retval);

View File

@ -346,7 +346,6 @@ int sfx_get_player_polyphony() {
SfxState::SfxState() { SfxState::SfxState() {
_it = NULL; _it = NULL;
_flags = 0; _flags = 0;
memset(&_songlib, 0, sizeof(_songlib));
_song = NULL; _song = NULL;
_suspended = 0; _suspended = 0;
_soundSync = 0; _soundSync = 0;
@ -485,7 +484,7 @@ void SfxState::setSongStatus(Song *song, int status) {
/* Update internal state iff only one song may be played */ /* Update internal state iff only one song may be played */
void SfxState::updateSingleSong() { void SfxState::updateSingleSong() {
Song *newsong = song_lib_find_active(_songlib); Song *newsong = _songlib.findFirstActive();
if (newsong != _song) { if (newsong != _song) {
freezeTime(); /* Store song delay time */ freezeTime(); /* Store song delay time */
@ -544,7 +543,7 @@ void SfxState::updateSingleSong() {
void SfxState::updateMultiSong() { void SfxState::updateMultiSong() {
Song *oldfirst = _song; Song *oldfirst = _song;
Song *oldseeker; Song *oldseeker;
Song *newsong = song_lib_find_active(_songlib); Song *newsong = _songlib.findFirstActive();
Song *newseeker; Song *newseeker;
Song not_playing_anymore; /* Dummy object, referenced by Song not_playing_anymore; /* Dummy object, referenced by
** songs which are no longer ** songs which are no longer
@ -575,10 +574,8 @@ void SfxState::updateMultiSong() {
} }
/* Second, re-generate the new song queue. */ /* Second, re-generate the new song queue. */
for (newseeker = newsong; newseeker; for (newseeker = newsong; newseeker; newseeker = newseeker->_nextPlaying) {
newseeker = newseeker->_nextPlaying) { newseeker->_nextPlaying = _songlib.findNextActive(newseeker);
newseeker->_nextPlaying
= song_lib_find_next_active(_songlib, newseeker);
if (newseeker == newseeker->_nextPlaying) { if (newseeker == newseeker->_nextPlaying) {
error("updateMultiSong() failed. Breakpoint in %s, line %d", __FILE__, __LINE__); error("updateMultiSong() failed. Breakpoint in %s, line %d", __FILE__, __LINE__);
@ -641,7 +638,7 @@ static int sfx_play_iterator_pcm(SongIterator *it, SongHandle handle) {
#define DELAY (1000000 / SFX_TICKS_PER_SEC) #define DELAY (1000000 / SFX_TICKS_PER_SEC)
void SfxState::sfx_init(ResourceManager *resmgr, int flags) { void SfxState::sfx_init(ResourceManager *resmgr, int flags) {
song_lib_init(&_songlib); _songlib.initSounds();
_song = NULL; _song = NULL;
_flags = flags; _flags = flags;
_soundSync = NULL; _soundSync = NULL;
@ -691,7 +688,7 @@ void SfxState::sfx_exit() {
g_system->getMixer()->stopAll(); g_system->getMixer()->stopAll();
song_lib_free(_songlib); _songlib.freeSounds();
// Delete audio resources for CD talkie games // Delete audio resources for CD talkie games
if (_audioResource) { if (_audioResource) {
@ -793,7 +790,7 @@ int SfxState::sfx_poll_specific(SongHandle handle, int *cue) {
/*****************/ /*****************/
void SfxState::sfx_add_song(SongIterator *it, int priority, SongHandle handle, int number) { void SfxState::sfx_add_song(SongIterator *it, int priority, SongHandle handle, int number) {
Song *song = song_lib_find(_songlib, handle); Song *song = _songlib.findSong(handle);
#ifdef DEBUG_SONG_API #ifdef DEBUG_SONG_API
fprintf(stderr, "[sfx-core] Adding song: %08lx at %d, it=%p\n", handle, priority, it); fprintf(stderr, "[sfx-core] Adding song: %08lx at %d, it=%p\n", handle, priority, it);
@ -822,7 +819,7 @@ void SfxState::sfx_add_song(SongIterator *it, int priority, SongHandle handle, i
handle, song->_status); handle, song->_status);
return; return;
} else { } else {
song_lib_remove(_songlib, handle); /* No duplicates */ _songlib.removeSong(handle); /* No duplicates */
} }
} }
@ -832,7 +829,7 @@ void SfxState::sfx_add_song(SongIterator *it, int priority, SongHandle handle, i
song->_hold = 0; song->_hold = 0;
song->_loops = 0; song->_loops = 0;
song->_wakeupTime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC); song->_wakeupTime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC);
song_lib_add(_songlib, song); _songlib.addSong(song);
_song = NULL; /* As above */ _song = NULL; /* As above */
update(); update();
@ -846,7 +843,7 @@ void SfxState::sfx_remove_song(SongHandle handle) {
if (_song && _song->_handle == handle) if (_song && _song->_handle == handle)
_song = NULL; _song = NULL;
song_lib_remove(_songlib, handle); _songlib.removeSong(handle);
update(); update();
} }
@ -859,7 +856,7 @@ void SfxState::sfx_remove_song(SongHandle handle) {
#define ASSERT_SONG(s) if (!(s)) { warning("Looking up song handle %08lx failed in %s, L%d", handle, __FILE__, __LINE__); return; } #define ASSERT_SONG(s) if (!(s)) { warning("Looking up song handle %08lx failed in %s, L%d", handle, __FILE__, __LINE__); return; }
void SfxState::sfx_song_set_status(SongHandle handle, int status) { void SfxState::sfx_song_set_status(SongHandle handle, int status) {
Song *song = song_lib_find(_songlib, handle); Song *song = _songlib.findSong(handle);
ASSERT_SONG(song); ASSERT_SONG(song);
#ifdef DEBUG_SONG_API #ifdef DEBUG_SONG_API
fprintf(stderr, "[sfx-core] Setting song status to %d" fprintf(stderr, "[sfx-core] Setting song status to %d"
@ -875,7 +872,7 @@ void SfxState::sfx_song_set_fade(SongHandle handle, fade_params_t *params) {
#ifdef DEBUG_SONG_API #ifdef DEBUG_SONG_API
static const char *stopmsg[] = {"??? Should not happen", "Do not stop afterwards", "Stop afterwards"}; static const char *stopmsg[] = {"??? Should not happen", "Do not stop afterwards", "Stop afterwards"};
#endif #endif
Song *song = song_lib_find(_songlib, handle); Song *song = _songlib.findSong(handle);
ASSERT_SONG(song); ASSERT_SONG(song);
@ -892,7 +889,7 @@ void SfxState::sfx_song_set_fade(SongHandle handle, fade_params_t *params) {
} }
void SfxState::sfx_song_renice(SongHandle handle, int priority) { void SfxState::sfx_song_renice(SongHandle handle, int priority) {
Song *song = song_lib_find(_songlib, handle); Song *song = _songlib.findSong(handle);
ASSERT_SONG(song); ASSERT_SONG(song);
#ifdef DEBUG_SONG_API #ifdef DEBUG_SONG_API
fprintf(stderr, "[sfx-core] Renicing song %08lx to %d\n", fprintf(stderr, "[sfx-core] Renicing song %08lx to %d\n",
@ -905,7 +902,7 @@ void SfxState::sfx_song_renice(SongHandle handle, int priority) {
} }
void SfxState::sfx_song_set_loops(SongHandle handle, int loops) { void SfxState::sfx_song_set_loops(SongHandle handle, int loops) {
Song *song = song_lib_find(_songlib, handle); Song *song = _songlib.findSong(handle);
SongIterator::Message msg = SongIterator::Message(handle, SIMSG_SET_LOOPS(loops)); SongIterator::Message msg = SongIterator::Message(handle, SIMSG_SET_LOOPS(loops));
ASSERT_SONG(song); ASSERT_SONG(song);
@ -922,7 +919,7 @@ void SfxState::sfx_song_set_loops(SongHandle handle, int loops) {
} }
void SfxState::sfx_song_set_hold(SongHandle handle, int hold) { void SfxState::sfx_song_set_hold(SongHandle handle, int hold) {
Song *song = song_lib_find(_songlib, handle); Song *song = _songlib.findSong(handle);
SongIterator::Message msg = SongIterator::Message(handle, SIMSG_SET_HOLD(hold)); SongIterator::Message msg = SongIterator::Message(handle, SIMSG_SET_HOLD(hold));
ASSERT_SONG(song); ASSERT_SONG(song);
@ -1003,7 +1000,7 @@ void SfxState::sfx_all_stop() {
fprintf(stderr, "[sfx-core] All stop\n"); fprintf(stderr, "[sfx-core] All stop\n");
#endif #endif
song_lib_free(_songlib); _songlib.freeSounds();
update(); update();
} }

View File

@ -54,23 +54,23 @@ Song *song_new(SongHandle handle, SongIterator *it, int priority) {
return retval; return retval;
} }
void song_lib_add(const SongLibrary &songlib, Song *song) { void SongLibrary::addSong(Song *song) {
Song **seeker = NULL; Song **seeker = NULL;
int pri = song->_priority; int pri = song->_priority;
if (NULL == song) { if (NULL == song) {
sciprintf("song_lib_add(): NULL passed for song\n"); sciprintf("addSong(): NULL passed for song\n");
return; return;
} }
if (*(songlib._lib) == NULL) { if (*_lib == NULL) {
*(songlib._lib) = song; *_lib = song;
song->_next = NULL; song->_next = NULL;
return; return;
} }
seeker = (songlib._lib); seeker = _lib;
while (*seeker && ((*seeker)->_priority > pri)) while (*seeker && ((*seeker)->_priority > pri))
seeker = &((*seeker)->_next); seeker = &((*seeker)->_next);
@ -78,29 +78,26 @@ void song_lib_add(const SongLibrary &songlib, Song *song) {
*seeker = song; *seeker = song;
} }
static void _songfree_chain(Song *song) { void SongLibrary::initSounds() {
/* Recursively free a chain of songs */ _lib = &_s;
if (song) { _s = NULL;
_songfree_chain(song->_next); }
void SongLibrary::freeSounds() {
Song *next = *_lib;
while (next) {
Song *song = next;
delete song->_it; delete song->_it;
song->_it = NULL; song->_it = NULL;
next = song->_next;
free(song); free(song);
} }
} *_lib = NULL;
void song_lib_init(SongLibrary *songlib) {
songlib->_lib = &(songlib->_s);
songlib->_s = NULL;
}
void song_lib_free(const SongLibrary &songlib) {
_songfree_chain(*(songlib._lib));
*(songlib._lib) = NULL;
} }
Song *song_lib_find(const SongLibrary &songlib, SongHandle handle) { Song *SongLibrary::findSong(SongHandle handle) {
Song *seeker = *(songlib._lib); Song *seeker = *_lib;
while (seeker) { while (seeker) {
if (seeker->_handle == handle) if (seeker->_handle == handle)
@ -111,8 +108,8 @@ Song *song_lib_find(const SongLibrary &songlib, SongHandle handle) {
return seeker; return seeker;
} }
Song *song_lib_find_next_active(const SongLibrary &songlib, Song *other) { Song *SongLibrary::findNextActive(Song *other) {
Song *seeker = other ? other->_next : *(songlib._lib); Song *seeker = other ? other->_next : *_lib;
while (seeker) { while (seeker) {
if ((seeker->_status == SOUND_STATUS_WAITING) || if ((seeker->_status == SOUND_STATUS_WAITING) ||
@ -128,19 +125,19 @@ Song *song_lib_find_next_active(const SongLibrary &songlib, Song *other) {
return seeker; return seeker;
} }
Song *song_lib_find_active(const SongLibrary &songlib) { Song *SongLibrary::findFirstActive() {
return song_lib_find_next_active(songlib, NULL); return findNextActive(NULL);
} }
int song_lib_remove(const SongLibrary &songlib, SongHandle handle) { int SongLibrary::removeSong(SongHandle handle) {
int retval; int retval;
Song *goner = *(songlib._lib); Song *goner = *_lib;
if (!goner) if (!goner)
return -1; return -1;
if (goner->_handle == handle) if (goner->_handle == handle)
*(songlib._lib) = goner->_next; *_lib = goner->_next;
else { else {
while ((goner->_next) && (goner->_next->_handle != handle)) while ((goner->_next) && (goner->_next->_handle != handle))
@ -162,11 +159,11 @@ int song_lib_remove(const SongLibrary &songlib, SongHandle handle) {
return retval; return retval;
} }
void song_lib_resort(const SongLibrary &songlib, Song *song) { void SongLibrary::resortSong(Song *song) {
if (*(songlib._lib) == song) if (*_lib == song)
*(songlib._lib) = song->_next; *_lib = song->_next;
else { else {
Song *seeker = *(songlib._lib); Song *seeker = *_lib;
while (seeker->_next && (seeker->_next != song)) while (seeker->_next && (seeker->_next != song))
seeker = seeker->_next; seeker = seeker->_next;
@ -175,11 +172,11 @@ void song_lib_resort(const SongLibrary &songlib, Song *song) {
seeker->_next = seeker->_next->_next; seeker->_next = seeker->_next->_next;
} }
song_lib_add(songlib, song); addSong(song);
} }
int song_lib_count(const SongLibrary &songlib) { int SongLibrary::countSongs() {
Song *seeker = *(songlib._lib); Song *seeker = *_lib;
int retval = 0; int retval = 0;
while (seeker) { while (seeker) {
@ -190,8 +187,8 @@ int song_lib_count(const SongLibrary &songlib) {
return retval; return retval;
} }
void song_lib_set_restore_behavior(const SongLibrary &songlib, SongHandle handle, RESTORE_BEHAVIOR action) { void SongLibrary::setSongRestoreBehavior(SongHandle handle, RESTORE_BEHAVIOR action) {
Song *seeker = song_lib_find(songlib, handle); Song *seeker = findSong(handle);
seeker->_restoreBehavior = action; seeker->_restoreBehavior = action;
} }

View File

@ -83,11 +83,6 @@ struct Song {
}; };
struct SongLibrary {
Song **_lib;
Song *_s;
};
/**************************/ /**************************/
/* Song library commands: */ /* Song library commands: */
/**************************/ /**************************/
@ -102,78 +97,79 @@ struct SongLibrary {
Song *song_new(SongHandle handle, SongIterator *it, int priority); Song *song_new(SongHandle handle, SongIterator *it, int priority);
/* Initializes a static song library class SongLibrary {
** Parameters: (SongLibrary *) songlib: Pointer to the library public:
** to initialize Song **_lib;
** Returns : (void) Song *_s;
*/
void song_lib_init(SongLibrary *songlib);
/* Frees a song library public:
** Parameters: (SongLibrary) songlib: The library to free SongLibrary() {}
** Returns : (void)
*/
void song_lib_free(const SongLibrary &songlib);
/* Adds a song to a song library. /** Initializes a static song library */
** Parameters: (SongLibrary) songlib: An existing sound library, or NULL void initSounds();
** (Song *) song: The song to add
** Returns : (void)
*/
void song_lib_add(const SongLibrary &songlib, Song *song);
/* Looks up the song with the specified handle /** Frees a song library. */
** Parameters: (SongLibrary) songlib: An existing sound library, may point to NULL void freeSounds();
** (SongHandle) handle: The sound handle to look for
** Returns : (Song *) The song or NULL if it wasn't found
*/
Song *song_lib_find(const SongLibrary &songlib, SongHandle handle);
/* Finds the first song playing with the highest priority /**
** Parameters: (SongLibrary) songlib: An existing sound library * Adds a song to a song library.
** Returns : (Song *) The song that should be played next, or NULL if there is none * @param song song to add
*/ */
Song *song_lib_find_active(const SongLibrary &songlib); void addSong(Song *song);
/* Finds the next song playing with the highest priority /**
** Parameters: (SongLibrary) songlib: The song library to operate on * Looks up the song with the specified handle.
** (Song *) song: A song previously returned from the song library * @param handle sound handle to look for
** Returns : (Song *) The next song to play relative to 'song', or * @return the song or NULL if it wasn't found
** NULL if none are left */
** The functions 'song_lib_find_active' and 'song_lib_find_next_active Song *findSong(SongHandle handle);
** allow to iterate over all songs that satisfy the requirement of
** being 'playable'.
*/
Song *song_lib_find_next_active(const SongLibrary &songlib, Song *song);
/* Removes a song from the library /**
** Parameters: (SongLibrary) songlib: An existing sound library * Finds the first song playing with the highest priority.
** (SongHandle) handle: Handle of the song to remove * @return the song that should be played next, or NULL if there is none
** Returns : (int) The status of the song that was removed */
*/ Song *findFirstActive();
int song_lib_remove(const SongLibrary &songlib, SongHandle handle);
/* Removes a song from the library and sorts it in again; for use after renicing /**
** Parameters: (SongLibrary) songlib: An existing sound library * Finds the next song playing with the highest priority.
** (Song *) song: The song to work on *
** Returns : (void) * The functions 'findFirstActive' and 'findNextActive'
*/ * allow to iterate over all songs that satisfy the requirement of
void song_lib_resort(const SongLibrary &songlib, Song *song); * being 'playable'.
*
* @param song a song previously returned from the song library
* @return the next song to play relative to 'song', or NULL if none are left
*/
Song *findNextActive(Song *song);
/* Counts the number of songs in a song library /**
** Parameters: (SongLibrary) songlib: The library to count * Removes a song from the library.
** Returns : (int) The number of songs * @param handle handle of the song to remove
*/ * @return the status of the song that was removed
int song_lib_count(const SongLibrary &songlib); */
int removeSong(SongHandle handle);
/* Determines what should be done with the song "handle" when /**
** restoring it from a saved game. * Removes a song from the library and sorts it in again; for use after renicing.
** Parameters: (SongLibrary) songlib: The library that contains the song * @param son song to work on
** (SongHandle) handle: Its handle */
** (RESTORE_BEHAVIOR) action: The desired action void resortSong(Song *song);
*/
void song_lib_set_restore_behavior(const SongLibrary &songlib, SongHandle handle, /**
RESTORE_BEHAVIOR action); * Counts the number of songs in a song library.
* @return the number of songs
*/
int countSongs();
/**
* Determines what should be done with the song "handle" when restoring
* it from a saved game.
* @param handle sound handle being restored
* @param action desired action
*/
void setSongRestoreBehavior(SongHandle handle,
RESTORE_BEHAVIOR action);
};
} // End of namespace Sci } // End of namespace Sci