[Scummvm-cvs-logs] SF.net SVN: scummvm:[39263] scummvm/trunk/engines/sci

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Mon Mar 9 17:15:35 CET 2009


Revision: 39263
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39263&view=rev
Author:   fingolfin
Date:     2009-03-09 16:15:35 +0000 (Mon, 09 Mar 2009)

Log Message:
-----------
SCI: Rewrote handling of song wakeup times & (iterator) delays, to avoid rounding issues between ticks (1/60s) and milliseconds; also fixed a bug (coming from Glutton ;) where delays measured in millisecs were treated as ticks instead. Thanks to Walter for the precursor of this patch

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/savegame.cfsml
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/sfx/core.cpp
    scummvm/trunk/engines/sci/sfx/core.h
    scummvm/trunk/engines/sci/sfx/player/realtime.cpp
    scummvm/trunk/engines/sci/sfx/songlib.cpp
    scummvm/trunk/engines/sci/sfx/songlib.h

Modified: scummvm/trunk/engines/sci/engine/savegame.cfsml
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cfsml	2009-03-09 16:15:25 UTC (rev 39262)
+++ scummvm/trunk/engines/sci/engine/savegame.cfsml	2009-03-09 16:15:35 UTC (rev 39263)
@@ -505,7 +505,7 @@
 	*foo = (song_t*) malloc(sizeof(song_t));
 	token = _cfsml_get_identifier(fh, line, hiteof, &assignment);
 	%CFSMLREAD song_t (*foo) FROM fh ERRVAR *hiteof FIRSTTOKEN token LINECOUNTER *line;
-	(*foo)->delay = 0;
+	(*foo)->_delay = 0;
 	(*foo)->it = NULL;
 	(*foo)->next_playing = (*foo)->next_stopping = (*foo)->next = NULL;
 	return 0;

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2009-03-09 16:15:25 UTC (rev 39262)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2009-03-09 16:15:35 UTC (rev 39263)
@@ -4129,7 +4129,7 @@
 	}
 // End of auto-generated CFSML data reader code
 #line 508 "engines/sci/engine/savegame.cfsml"
-	(*foo)->delay = 0;
+	(*foo)->_delay = 0;
 	(*foo)->it = NULL;
 	(*foo)->next_playing = (*foo)->next_stopping = (*foo)->next = NULL;
 	return 0;

Modified: scummvm/trunk/engines/sci/sfx/core.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/core.cpp	2009-03-09 16:15:25 UTC (rev 39262)
+++ scummvm/trunk/engines/sci/sfx/core.cpp	2009-03-09 16:15:35 UTC (rev 39263)
@@ -73,14 +73,13 @@
 
 static void _freeze_time(sfx_state_t *self) {
 	/* Freezes the top song delay time */
-	uint32 ctime = g_system->getMillis();
+	const Audio::Timestamp ctime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC);
 	song_t *song = self->song;
 
 	while (song) {
-		if (ctime > song->wakeup_time)
-			song->delay = 0;
-		else
-			song->delay = song->wakeup_time - ctime;
+		song->_delay = song->_wakeupTime.frameDiff(ctime);
+		if (song->_delay < 0)
+			song->_delay = 0;
 
 		song = song->next_playing;
 	}
@@ -132,11 +131,11 @@
 
 static void _thaw_time(sfx_state_t *self) {
 	/* inverse of _freeze_time() */
-	uint32 ctime = g_system->getMillis();
+	const Audio::Timestamp ctime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC);
 	song_t *song = self->song;
 
 	while (song) {
-		song->wakeup_time = ctime + song->delay;
+		song->_wakeupTime = ctime.addFrames(song->_delay);
 
 		song = song->next_playing;
 	}
@@ -156,21 +155,21 @@
 }
 
 static void _sfx_set_song_status(sfx_state_t *self, song_t *song, int status) {
+	const Audio::Timestamp ctime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC);
+
 	switch (status) {
 
 	case SOUND_STATUS_STOPPED:
-		/* Reset */
+		// Reset
 		song->it->init();
 		break;
 
 	case SOUND_STATUS_SUSPENDED:
 	case SOUND_STATUS_WAITING:
 		if (song->status == SOUND_STATUS_PLAYING) {
-			/* Update delay, set wakeup_time */
-			uint32 time = g_system->getMillis();
-
-			song->delay -= long(time) - long(song->wakeup_time);
-			song->wakeup_time = time;
+			// Update delay, set wakeup_time
+			song->_delay += song->_wakeupTime.frameDiff(ctime);
+			song->_wakeupTime = ctime;
 		}
 		if (status == SOUND_STATUS_SUSPENDED)
 			break;
@@ -178,9 +177,10 @@
 		/* otherwise... */
 
 	case SOUND_STATUS_PLAYING:
-		if (song->status == SOUND_STATUS_STOPPED)
-			/* Starting anew */
-			song->wakeup_time = g_system->getMillis();
+		if (song->status == SOUND_STATUS_STOPPED) {
+			// Starting anew
+			song->_wakeupTime = ctime;
+		}
 
 		if (is_playing(self, song))
 			status = SOUND_STATUS_PLAYING;
@@ -244,10 +244,9 @@
 		_thaw_time(self); /* Recover song delay time */
 
 		if (newsong && player) {
-			SongIterator *clonesong
-			= songit_clone(newsong->it, newsong->delay);
+			SongIterator *clonesong = songit_clone(newsong->it, newsong->_delay);
 
-			player->add_iterator(clonesong, newsong->wakeup_time);
+			player->add_iterator(clonesong, newsong->_wakeupTime.msecs());
 		}
 	}
 }
@@ -310,15 +309,13 @@
 			oldseeker->next_playing = NULL; /* Clear this pointer; we don't need the tag anymore */
 		}
 
-	for (newseeker = newsong; newseeker;
-	        newseeker = newseeker->next_playing) {
+	for (newseeker = newsong; newseeker; newseeker = newseeker->next_playing) {
 		if (newseeker->status != SOUND_STATUS_PLAYING && player) {
 			if (self->debug & SFX_DEBUG_SONGS)
 				sciprintf("[SFX] Adding song %lx\n", newseeker->it->ID);
 
-			player->add_iterator(songit_clone(newseeker->it,
-			                                  newseeker->delay),
-			                     g_system->getMillis());
+			SongIterator *clonesong = songit_clone(newseeker->it, newseeker->_delay);
+			player->add_iterator(clonesong, g_system->getMillis());
 		}
 		_sfx_set_song_status(self, newseeker,
 		                     SOUND_STATUS_PLAYING);
@@ -351,8 +348,7 @@
 	return 0;
 }
 
-#define FREQ 60
-#define DELAY (1000000 / FREQ)
+#define DELAY (1000000 / SFX_TICKS_PER_SEC)
 
 
 static void _sfx_timer_callback(void *data) {
@@ -483,7 +479,7 @@
 }
 
 int sfx_poll_specific(sfx_state_t *self, song_handle_t handle, int *cue) {
-	uint32 ctime = g_system->getMillis();
+	const Audio::Timestamp ctime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC);
 	song_t *song = self->song;
 
 	while (song && song->handle != handle)
@@ -497,13 +493,11 @@
 	}
 
 	while (1) {
-		unsigned char buf[8];
-		int result;
-
-		if (song->wakeup_time > ctime)
+		if (song->_wakeupTime.frameDiff(ctime) > 0)
 			return 0; /* Patience, young hacker! */
 
-		result = songit_next(&(song->it), buf, cue, IT_READER_MASK_ALL);
+		unsigned char buf[8];
+		int result = songit_next(&(song->it), buf, cue, IT_READER_MASK_ALL);
 
 		switch (result) {
 
@@ -532,7 +526,7 @@
 
 		default:
 			if (result > 0)
-				song->wakeup_time += result * SOUND_TICK;
+				song->_wakeupTime = song->_wakeupTime.addFrames(result);
 
 			/* Delay */
 			break;
@@ -587,7 +581,7 @@
 	song->resource_num = number;
 	song->hold = 0;
 	song->loops = 0;
-	song->wakeup_time = g_system->getMillis(); /* No need to delay */
+	song->_wakeupTime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC);
 	song_lib_add(self->songlib, song);
 	self->song = NULL; /* As above */
 	_update(self);

Modified: scummvm/trunk/engines/sci/sfx/core.h
===================================================================
--- scummvm/trunk/engines/sci/sfx/core.h	2009-03-09 16:15:25 UTC (rev 39262)
+++ scummvm/trunk/engines/sci/sfx/core.h	2009-03-09 16:15:35 UTC (rev 39263)
@@ -36,8 +36,7 @@
 class SongIterator;
 struct fade_params_t;
 
-#define SOUND_TICK 1000 / 60
-/* Approximately 17 milliseconds */
+#define SFX_TICKS_PER_SEC 60 /* MIDI ticks per second */
 
 
 #define SFX_STATE_FLAG_MULTIPLAY (1 << 0) /* More than one song playable

Modified: scummvm/trunk/engines/sci/sfx/player/realtime.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/player/realtime.cpp	2009-03-09 16:15:25 UTC (rev 39262)
+++ scummvm/trunk/engines/sci/sfx/player/realtime.cpp	2009-03-09 16:15:35 UTC (rev 39263)
@@ -100,7 +100,7 @@
 
 			default:
 				play_moredelay = delay - 1;
-				*wakeup_time += delay * SOUND_TICK;
+				*wakeup_time += delay * 1000 / SFX_TICKS_PER_SEC;
 				if (seq->delay)
 					seq->delay(delay);
 			}

Modified: scummvm/trunk/engines/sci/sfx/songlib.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/songlib.cpp	2009-03-09 16:15:25 UTC (rev 39262)
+++ scummvm/trunk/engines/sci/sfx/songlib.cpp	2009-03-09 16:15:35 UTC (rev 39263)
@@ -43,7 +43,8 @@
 	retval->handle = handle;
 	retval->priority = priority;
 	retval->next = NULL;
-	retval->delay = 0;
+	retval->_delay = 0;
+	retval->_wakeupTime = Audio::Timestamp();
 	retval->it = it;
 	retval->status = SOUND_STATUS_STOPPED;
 	retval->next_playing = NULL;

Modified: scummvm/trunk/engines/sci/sfx/songlib.h
===================================================================
--- scummvm/trunk/engines/sci/sfx/songlib.h	2009-03-09 16:15:25 UTC (rev 39262)
+++ scummvm/trunk/engines/sci/sfx/songlib.h	2009-03-09 16:15:35 UTC (rev 39263)
@@ -29,6 +29,7 @@
 #define SCI_SFX_SFX_SONGLIB_H
 
 #include "common/scummsys.h"
+#include "sound/timestamp.h"
 
 namespace Sci {
 
@@ -63,11 +64,9 @@
 	int hold;
 
 	SongIterator *it;
-	long delay; /* Delay before accessing the iterator, in microseconds */
+	int _delay; /* Delay before accessing the iterator, in ticks */
 
-	uint32 wakeup_time; /* Used by the sound core:
-			      ** Playing -> time at which 'delay' has elapsed
-			      ** Suspended/Waiting -> stopping time */
+	Audio::Timestamp _wakeupTime; /**< Timestamp indicating the next MIDI event */
 
 	song_t *next; /* Next song or NULL if this is the last one */
 	song_t *next_playing; /* Next playing song; used by the


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list