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

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Mon Apr 20 21:28:55 CEST 2009


Revision: 40032
          http://scummvm.svn.sourceforge.net/scummvm/?rev=40032&view=rev
Author:   fingolfin
Date:     2009-04-20 19:28:55 +0000 (Mon, 20 Apr 2009)

Log Message:
-----------
SCI: Replaced memory ref counting code in the SongIterator code by a simple Common::Array<byte> object; also doxygenified some source comments

Modified Paths:
--------------
    scummvm/trunk/engines/sci/sfx/iterator.cpp
    scummvm/trunk/engines/sci/sfx/iterator_internal.h

Modified: scummvm/trunk/engines/sci/sfx/iterator.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/iterator.cpp	2009-04-20 19:28:33 UTC (rev 40031)
+++ scummvm/trunk/engines/sci/sfx/iterator.cpp	2009-04-20 19:28:55 UTC (rev 40032)
@@ -26,6 +26,7 @@
 /* Song iterators */
 
 #include "common/util.h"
+
 #include "sci/sfx/iterator_internal.h"
 #include "sci/sfx/player.h"
 #include "sci/tools.h"
@@ -36,103 +37,7 @@
 
 namespace Sci {
 
-/****************************************/
-/* Refcounting garbage collected memory */
-/****************************************/
 
-#define REFCOUNT_OVERHEAD (sizeof(uint32) * 3)
-#define REFCOUNT_MAGIC_LIVE_1 0xebdc1741
-#define REFCOUNT_MAGIC_LIVE_2 0x17015ac9
-#define REFCOUNT_MAGIC_DEAD_1 0x11dead11
-#define REFCOUNT_MAGIC_DEAD_2 0x22dead22
-
-#define REFCOUNT_CHECK(p) ((((uint32 *)(p))[-3] == REFCOUNT_MAGIC_LIVE_2) && (((uint32 *)(p))[-1] == REFCOUNT_MAGIC_LIVE_1))
-
-#define REFCOUNT(p) (((uint32 *)p)[-2])
-
-#undef TRACE_REFCOUNT
-
-/* Allocates "garbage" memory
-** Parameters: (size_t) length: Number of bytes to allocate
-** Returns   : (void *) The allocated memory
-** Memory allocated in this fashion will be marked as holding one reference.
-** It cannot be freed with 'free()', only by using sci_refcount_decref().
-*/
-static void *sci_refcount_alloc(size_t length) {
-	uint32 *data = (uint32 *)sci_malloc(REFCOUNT_OVERHEAD + length);
-#ifdef TRACE_REFCOUNT
-	fprintf(stderr, "[] REF: Real-alloc at %p\n", data);
-#endif
-	data += 3;
-
-	data[-1] = REFCOUNT_MAGIC_LIVE_1;
-	data[-3] = REFCOUNT_MAGIC_LIVE_2;
-	REFCOUNT(data) = 1;
-#ifdef TRACE_REFCOUNT
-	fprintf(stderr, "[] REF: Alloc'd %p (ref=%d) OK=%d\n", data, REFCOUNT(data),
-	        REFCOUNT_CHECK(data));
-#endif
-	return data;
-}
-
-/* Adds another reference to refcounted memory
-** Parameters: (void *) data: The data to add a reference to
-** Returns   : (void *) data
-*/
-static void *sci_refcount_incref(void *data) {
-	if (!REFCOUNT_CHECK(data)) {
-		BREAKPOINT();
-	} else
-		REFCOUNT(data)++;
-
-#ifdef TRACE_REFCOUNT
-	fprintf(stderr, "[] REF: Inc'ing %p (now ref=%d)\n", data, REFCOUNT(data));
-#endif
-	return data;
-}
-
-/* Decrements the reference count for refcounted memory
-** Parameters: (void *) data: The data to add a reference to
-** Returns   : (void *) data
-** If the refcount reaches zero, the memory will be deallocated
-*/
-static void sci_refcount_decref(void *data) {
-#ifdef TRACE_REFCOUNT
-	fprintf(stderr, "[] REF: Dec'ing %p (prev ref=%d) OK=%d\n", data, REFCOUNT(data),
-	        REFCOUNT_CHECK(data));
-#endif
-	if (!REFCOUNT_CHECK(data)) {
-		BREAKPOINT();
-	} else if (--REFCOUNT(data) == 0) {
-		uint32 *fdata = (uint32 *)data;
-
-		fdata[-1] = REFCOUNT_MAGIC_DEAD_1;
-		fdata[-3] = REFCOUNT_MAGIC_DEAD_2;
-
-#ifdef TRACE_REFCOUNT
-		fprintf(stderr, "[] REF: Freeing (%p)...\n", fdata - 3);
-#endif
-		free(fdata - 3);
-#ifdef TRACE_REFCOUNT
-		fprintf(stderr, "[] REF: Done.\n");
-#endif
-	}
-}
-
-/* Duplicates non-refcounted memory into a refcounted block
-** Parameters: (void *) data: The memory to copy from
-**             (size_t) len: The number of bytes to copy/allocate
-** Returns   : (void *) Newly allocated refcounted memory
-** The number of references accounted for will be one.
-*/
-static void *sci_refcount_memdup(void *data, size_t len) {
-	void *dest = sci_refcount_alloc(len);
-	memcpy(dest, data, len);
-	return dest;
-}
-
-
-
 static const int MIDI_cmdlen[16] = {0, 0, 0, 0, 0, 0, 0, 0,
                                     2, 2, 2, 2, 1, 1, 2, 0
                                    };
@@ -147,54 +52,11 @@
 	fprintf(stderr, "[%08lx] ", id);
 }
 
-static byte *sci_memchr(byte *data, int c, int n) {
-	while (n && *data != c) {
-		++data;
-		--n;
-	}
-
-	if (n)
-		return data;
-	else
-		return NULL;
-}
-
-BaseSongIterator::BaseSongIterator(byte *data, uint size, songit_id_t id) {
+BaseSongIterator::BaseSongIterator(byte *data, uint size, songit_id_t id)
+	: _data(data, size) {
 	ID = id;
-
-	_data = (byte *)sci_refcount_memdup(data, size);
-	_size = size;
 }
 
-BaseSongIterator::BaseSongIterator(const BaseSongIterator& bsi) : SongIterator(bsi) {
-	memcpy(polyphony, bsi.polyphony, sizeof(polyphony));
-	memcpy(importance, bsi.importance, sizeof(importance));
-	ccc = bsi.ccc;
-	resetflag = bsi.resetflag;
-	_deviceId = bsi._deviceId;
-	active_channels = bsi.active_channels;
-	_size = bsi._size;
-	_data = bsi._data;
-	loops = bsi.loops;
-	recover_delay = bsi.recover_delay;
-
-	if (_data) {
-#ifdef DEBUG_VERBOSE
-		fprintf(stderr, "** CLONE INCREF for new %p from %p at %p\n", mem, this, mem->_data);
-#endif
-		sci_refcount_incref(_data);
-	}
-}
-
-BaseSongIterator::~BaseSongIterator() {
-#ifdef DEBUG_VERBOSE
-	fprintf(stderr, "** FREEING it %p: data at %p\n", this, _data);
-#endif
-	if (_data)
-		sci_refcount_decref(_data);
-	_data = NULL;
-}
-
 /************************************/
 /*-- SCI0 iterator implementation --*/
 /************************************/
@@ -207,8 +69,8 @@
 #define SCI0_PCM_DATA_OFFSET 0x2c
 
 #define CHECK_FOR_END_ABSOLUTE(offset) \
-	if (offset > self->_size) { \
-		warning(SIPFX "Reached end of song without terminator (%x/%x) at %d!", offset, self->_size, __LINE__); \
+	if (offset > self->_data.size()) { \
+		warning(SIPFX "Reached end of song without terminator (%x/%x) at %d!", offset, self->_data.size(), __LINE__); \
 		return SI_FINISHED; \
 	}
 
@@ -307,7 +169,7 @@
 
 
 	CHECK_FOR_END(paramsleft);
-	memcpy(buf + 1, self->_data + channel->offset, paramsleft);
+	memcpy(buf + 1, self->_data.begin() + channel->offset, paramsleft);
 	*result = 1 + paramsleft;
 
 	channel->offset += paramsleft;
@@ -477,8 +339,8 @@
 	switch (channel->state) {
 
 	case SI_STATE_PCM: {
-		if (*(self->_data + channel->offset) == 0
-		        && *(self->_data + channel->offset + 1) == SCI_MIDI_EOT)
+		if (self->_data[channel->offset] == 0
+		        && self->_data[channel->offset + 1] == SCI_MIDI_EOT)
 			/* Fake one extra tick to trick the interpreter into not killing the song iterator right away */
 			channel->state = SI_STATE_PCM_MAGIC_DELTA;
 		else
@@ -510,9 +372,9 @@
 
 	case SI_STATE_DELTA_TIME: {
 		int offset;
-		int ticks = _parse_ticks(self->_data + channel->offset,
+		int ticks = _parse_ticks(self->_data.begin() + channel->offset,
 		                         &offset,
-		                         self->_size - channel->offset);
+		                         self->_data.size() - channel->offset);
 
 		channel->offset += offset;
 		channel->delay += ticks;
@@ -589,7 +451,7 @@
 static int _sci0_get_pcm_data(Sci0SongIterator *self,
 	sfx_pcm_config_t *format, int *xoffset, uint *xsize) {
 	int tries = 2;
-	int found_it = 0;
+	bool found_it = false;
 	byte *pcm_data;
 	int size;
 	uint offset = SCI0_MIDI_OFFSET;
@@ -598,23 +460,23 @@
 		return 1;
 	/* No such luck */
 
-	while ((tries--) && (offset < self->_size) && (!found_it)) {
-		/* Search through the garbage manually */
-		byte *fc = sci_memchr(self->_data + offset,
-		                    SCI0_END_OF_SONG,
-		                    self->_size - offset);
+	while ((tries--) && (offset < self->_data.size()) && (!found_it)) {
+		// Search through the garbage manually
+		// FIXME: Replace offset by an iterator
+		Common::Array<byte>::iterator iter = Common::find(self->_data.begin() + offset, self->_data.end(), SCI0_END_OF_SONG);
 
-		if (!fc) {
+		if (iter == self->_data.end()) {
 			warning(SIPFX "Playing unterminated song!");
 			return 1;
 		}
 
-		/* add one to move it past the END_OF_SONG marker */
-		offset = fc - self->_data + 1;
+		// add one to move it past the END_OF_SONG marker
+		iter++;
+		offset = iter - self->_data.begin();	// FIXME
 
 
-		if (_sci0_header_magic_p(self->_data, offset, self->_size))
-			found_it = 1;
+		if (_sci0_header_magic_p(self->_data.begin(), offset, self->_data.size()))
+			found_it = true;
 	}
 
 	if (!found_it) {
@@ -624,7 +486,7 @@
 		return 1;
 	}
 
-	pcm_data = self->_data + offset;
+	pcm_data = self->_data.begin() + offset;
 
 	size = READ_LE_UINT16(pcm_data + SCI0_PCM_SIZE_OFFSET);
 
@@ -633,12 +495,12 @@
 	format->stereo = SFX_PCM_MONO;
 	format->rate = READ_LE_UINT16(pcm_data + SCI0_PCM_SAMPLE_RATE_OFFSET);
 
-	if (offset + SCI0_PCM_DATA_OFFSET + size != self->_size) {
-		int d = offset + SCI0_PCM_DATA_OFFSET + size - self->_size;
+	if (offset + SCI0_PCM_DATA_OFFSET + size != self->_data.size()) {
+		int d = offset + SCI0_PCM_DATA_OFFSET + size - self->_data.size();
 
 		warning(SIPFX "PCM advertizes %d bytes of data, but %d"
 		        " bytes are trailing in the resource!",
-		        size, self->_size - (offset + SCI0_PCM_DATA_OFFSET));
+		        size, self->_data.size() - (offset + SCI0_PCM_DATA_OFFSET));
 
 		if (d > 0)
 			size -= d; /* Fix this */
@@ -682,7 +544,7 @@
 
 	channel.state = SI_STATE_FINISHED; /* Don't play both PCM and music */
 
-	return makeStream(_data + offset + SCI0_PCM_DATA_OFFSET, size, conf);
+	return makeStream(_data.begin() + offset + SCI0_PCM_DATA_OFFSET, size, conf);
 }
 
 SongIterator *Sci0SongIterator::handleMessage(Message msg) {
@@ -692,7 +554,7 @@
 		case _SIMSG_BASEMSG_PRINT:
 			print_tabs_id(msg._arg.i, ID);
 			fprintf(stderr, "SCI0: dev=%d, active-chan=%d, size=%d, loops=%d\n",
-			        _deviceId, active_channels, _size, loops);
+			        _deviceId, active_channels, _data.size(), loops);
 			break;
 
 		case _SIMSG_BASEMSG_SET_LOOPS:
@@ -787,7 +649,7 @@
 
 	ccc = 0; /* Reset cumulative cue counter */
 	active_channels = 1;
-	_base_init_channel(&channel, 0, SCI0_MIDI_OFFSET, _size);
+	_base_init_channel(&channel, 0, SCI0_MIDI_OFFSET, _data.size());
 	channel.resetSynthChannels();
 
 	if (_data[0] == 2) /* Do we have an embedded PCM? */
@@ -833,20 +695,20 @@
 		sciprintf("[iterator-1] In sample at offset 0x04x: Byte #1 is %02x instead of zero\n",
 		          self->_data[offset + 1]);
 
-	rate = (int16)READ_LE_UINT16(self->_data + offset + 2);
-	length = READ_LE_UINT16(self->_data + offset + 4);
-	begin = (int16)READ_LE_UINT16(self->_data + offset + 6);
-	end = (int16)READ_LE_UINT16(self->_data + offset + 8);
+	rate = (int16)READ_LE_UINT16(self->_data.begin() + offset + 2);
+	length = READ_LE_UINT16(self->_data.begin() + offset + 4);
+	begin = (int16)READ_LE_UINT16(self->_data.begin() + offset + 6);
+	end = (int16)READ_LE_UINT16(self->_data.begin() + offset + 8);
 
 	CHECK_FOR_END_ABSOLUTE((uint)(offset + 10 + length));
 
 	sample.delta = begin;
 	sample.size = length;
-	sample._data = self->_data + offset + 10;
+	sample._data = self->_data.begin() + offset + 10;
 
 #ifdef DEBUG_VERBOSE
 	fprintf(stderr, "[SAMPLE] %x/%x/%x/%x l=%x\n",
-	        offset + 10, begin, end, self->_size, length);
+	        offset + 10, begin, end, self->_data.size(), length);
 #endif
 
 	sample.format.format = SFX_PCM_FORMAT_U8;
@@ -904,8 +766,8 @@
 
 		CHECK_FOR_END_ABSOLUTE(offset + 4);
 
-		track_offset = READ_LE_UINT16(self->_data + offset);
-		end = READ_LE_UINT16(self->_data + offset + 2);
+		track_offset = READ_LE_UINT16(self->_data.begin() + offset);
+		end = READ_LE_UINT16(self->_data.begin() + offset + 2);
 
 		CHECK_FOR_END_ABSOLUTE(track_offset - 1);
 

Modified: scummvm/trunk/engines/sci/sfx/iterator_internal.h
===================================================================
--- scummvm/trunk/engines/sci/sfx/iterator_internal.h	2009-04-20 19:28:33 UTC (rev 40031)
+++ scummvm/trunk/engines/sci/sfx/iterator_internal.h	2009-04-20 19:28:55 UTC (rev 40032)
@@ -29,21 +29,11 @@
 #include "sci/sfx/iterator.h"
 #include "sci/sfx/sci_midi.h"
 
+#include "common/array.h"
 #include "common/list.h"
 
 namespace Sci {
 
-/* States */
-
-#define SI_STATE_UNINITIALISED -1
-#define SI_STATE_DELTA_TIME 0 /* Now at a delta time */
-#define SI_STATE_COMMAND 1 /* Now at a MIDI operation */
-#define SI_STATE_PENDING 2 /* Pending for loop */
-#define SI_STATE_FINISHED 3 /* End of song */
-#define SI_STATE_PCM 4 /* Should report a PCM next (-> DELTA_TIME) */
-#define SI_STATE_PCM_MAGIC_DELTA 5 /* Should report a ``magic'' one tick delta time next (goes on to FINISHED) */
-
-
 /* Iterator types */
 
 #define SCI_SONG_ITERATOR_TYPE_SCI0 0
@@ -52,57 +42,64 @@
 #define SIPFX __FILE__" : "
 
 
+enum {
+	SI_STATE_UNINITIALISED		= -1,
+	SI_STATE_DELTA_TIME			= 0,	//!< Now at a delta time
+	SI_STATE_COMMAND			= 1,	//!< Now at a MIDI operation
+	SI_STATE_PENDING			= 2,	//!< Pending for loop
+	SI_STATE_FINISHED			= 3,	//!< End of song
+	SI_STATE_PCM				= 4,	//!< Should report a PCM next (-> DELTA_TIME)
+	SI_STATE_PCM_MAGIC_DELTA	= 5		//!< Should report a ``magic'' one tick delta time next (goes on to FINISHED)
+};
+
 struct SongIteratorChannel {
-	int state;	/* SI_STATE_* */
-	int offset;     /* Offset into the data chunk */
-	int end;	/* Last allowed byte in track */
-	int id;		/* Some channel ID */
-	int loop_offset;
-	int delay;	/* Number of ticks before the
-			** specified channel is next
-			** used, or
-			** CHANNEL_DELAY_MISSING to
-			** indicate that the delay has
-			** not yet been read  */
+	
+	int state;	//!< State of this song iterator channel
+	int offset;     //!< Offset into the data chunk */
+	int end;	//!< Last allowed byte in track */
+	int id;		//!< Some channel ID */
 
+	/**
+	 * Number of ticks before the specified channel is next used, or
+	 * CHANNEL_DELAY_MISSING to indicate that the delay has not yet
+	 * been read.
+	 */
+	int delay;
+
 	/* Two additional offsets for recovering: */
+	int loop_offset;
 	int initial_offset;
-	int playmask; /* Active playmask (MIDI channels to play in here) */
-	int notes_played; /* #of notes played since the last loop start */
-	int loop_timepos; /* Total delay for this channel's loop marker */
-	int total_timepos; /* Number of ticks since the beginning, ignoring loops */
-	int timepos_increment; /* Number of ticks until the next command (to add) */
 
-	int saw_notes;  /* Bitmask of channels we have currently played notes on */
-	byte last_cmd;	/* Last operation executed, for running status */
+	int playmask; //!< Active playmask (MIDI channels to play in here) */
+	int notes_played; //!< #of notes played since the last loop start */
+	int loop_timepos; //!< Total delay for this channel's loop marker */
+	int total_timepos; //!< Number of ticks since the beginning, ignoring loops */
+	int timepos_increment; //!< Number of ticks until the next command (to add) */
 
+	int saw_notes;  //!< Bitmask of channels we have currently played notes on */
+	byte last_cmd;	//!< Last operation executed, for running status */
+
 public:
 	void resetSynthChannels();
 };
 
 class BaseSongIterator : public SongIterator {
 public:
-	int polyphony[MIDI_CHANNELS]; /* # of simultaneous notes on each */
-	int importance[MIDI_CHANNELS]; /* priority rating for each channel, 0 means unrated. */
+	int polyphony[MIDI_CHANNELS]; //!< # of simultaneous notes on each
+	int importance[MIDI_CHANNELS]; //!< priority rating for each channel, 0 means unrated.
 
 
-	int ccc; /* Cumulative cue counter, for those who need it */
-	byte resetflag; /* for 0x4C -- on DoSound StopSound, do we return to start? */
-	int _deviceId; /* ID of the device we generating events for */
-	int active_channels; /* Number of active channels */
-	uint _size; /* Song size */
-	byte *_data;
+	int ccc; //!< Cumulative cue counter, for those who need it
+	byte resetflag; //!< for 0x4C -- on DoSound StopSound, do we return to start?
+	int _deviceId; //!< ID of the device we generating events for
+	int active_channels; //!< Number of active channels
+	Common::Array<byte> _data;	//!< Song data
 
-	int loops; /* Number of loops remaining */
+	int loops; //!< Number of loops remaining
 	int recover_delay;
 
 public:
 	BaseSongIterator(byte *data, uint size, songit_id_t id);
-
-	// Copy constructor taking care of memory handling
-	BaseSongIterator(const BaseSongIterator&);
-
-	~BaseSongIterator();
 };
 
 /********************************/
@@ -131,7 +128,8 @@
 
 
 struct Sci1Sample {
-	/* Time left-- initially, this is 'Sample point 1'.
+	/**
+	 * Time left-- initially, this is 'Sample point 1'.
 	 * After initialisation, it is 'sample point 1 minus the sample
 	 * point of the previous sample'
 	 */


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