[Scummvm-cvs-logs] CVS: scummvm/scumm player_v1.cpp,1.1,1.2 player_v1.h,1.1,1.2 player_v2.cpp,2.20,2.21 player_v2.h,2.9,2.10 resource_v2.cpp,1.25,1.26 scummvm.cpp,2.334,2.335

Jochen Hoenicke hoenicke at users.sourceforge.net
Thu Aug 14 12:52:09 CEST 2003


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv26807/scumm

Modified Files:
	player_v1.cpp player_v1.h player_v2.cpp player_v2.h 
	resource_v2.cpp scummvm.cpp 
Log Message:
Don't create imuse for v1 and v2 games (otherwise getSoundStatus doesn't work).
PCjr support for V1 games, bug fix in speaker support.
set_pcjr is now called by Player_V2 constructor according to midi driver.
Renaming of member variables to begin with an underscore.


Index: player_v1.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/player_v1.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- player_v1.cpp	14 Aug 2003 02:30:54 -0000	1.1
+++ player_v1.cpp	14 Aug 2003 19:41:39 -0000	1.2
@@ -22,7 +22,6 @@
 #include "common/engine.h"
 #include "player_v1.h"
 #include "scumm.h"
-#include "sound/mixer.h"
 
 #define TIMER_BASE_FREQ 1193000
 #define FIXP_SHIFT  16
@@ -35,209 +34,408 @@
 
 
 Player_V1::Player_V1(Scumm *scumm) : Player_V2(scumm) {	
-	/* pcjr not yet supported */
-	set_pcjr(false);
+	// Initialize channel code
+	for (int i = 0; i < 4; ++i)
+		clear_channel(i);
 
-	_freq_current = 0;
+	_mplex_step = (_sample_rate << FIXP_SHIFT) / 1193000;
+	_next_chunk = _repeat_chunk = 0;
+	_forced_level = 0;
 }
 
 Player_V1::~Player_V1() {
 }
 
 void Player_V1::chainSound(int nr, byte *data) {
-	int offset = _pcjr ? READ_LE_UINT16(data+4) : 6;
+	uint i;
+	for (i = 0; i < 4; ++i)
+		clear_channel(i);
 
-	current_nr = nr;
-	current_data = data;
-	_next_cmd = data + (_pcjr ? offset + 2 : offset + 4);
-	_repeat_ptr = _next_cmd;
+	_current_nr = nr;
+	_current_data = data;
+	_repeat_chunk = _next_chunk = data + (_pcjr ? 2 : 4);
 	_music_timer = 0;
 
 	debug(4, "Chaining new sound %d", nr);
-	parse_chunk();
+	if (_pcjr)
+		parsePCjrChunk();
+	else
+		parseSpeakerChunk();
 }
 
 void Player_V1::startSound(int nr, byte *data) {
 	mutex_up();
 
 	int offset = _pcjr ? READ_LE_UINT16(data+4) : 6;
-	int cprio = current_data ? *(current_data + offset) & 0x7f : 0;
-	int prio  = *(data + _header_len) & 0x7f;
-	int nprio = next_data ? *(next_data + _header_len) & 0x7f : 0;
-
-	int restartable = *(data + _header_len) & 0x80;
+	int cprio = _current_data ? *(_current_data) & 0x7f : 0;
+	int prio  = *(data + offset) & 0x7f;
+	int restartable = *(data + offset) & 0x80;
 
-	if (!current_nr || cprio <= prio) {
-		int tnr = current_nr;
-		int tprio = cprio;
-		byte *tdata  = current_data;
+	debug(4, "startSound %d: prio %d%s, cprio %d",
+		  nr, prio, restartable ? " restartable" : "", cprio);
 
-		chainSound(nr, data);
-		nr   = tnr;
-		prio = tprio;
-		data = tdata;
-		restartable = data ? *(data + _header_len) & 0x80 : 0;
-	}
-	
-	if (!current_nr) {
-		nr = 0;
-		next_nr = 0;
-		next_data = 0;
-	}
-	
-	if (nr != current_nr
-	    && restartable
-	    && (!next_nr
-		|| nprio <= prio)) {
+	if (!_current_nr || cprio <= prio) {
+		if (_current_data && (*(_current_data) & 0x80)) {
+			_next_nr = _current_nr;
+			_next_data = _current_data;
+		}
 
-		next_nr = nr;
-		next_data = data;
+		chainSound(nr, data + offset);
 	}
+	mutex_down();
+}
 
+void Player_V1::stopAllSounds() {
+	mutex_up();
+	for (int i = 0; i < 4; i++)
+		clear_channel(i);
+	_repeat_chunk = _next_chunk = 0;
+	_next_nr = _current_nr = 0;
+	_next_data = _current_data = 0;
 	mutex_down();
 }
 
-void Player_V1::restartSound() {
-	if (*(current_data + _header_len) & 0x80) {
-		/* current sound is restartable */
-		chainSound(current_nr, current_data);
-	} else {
+void Player_V1::stopSound(int nr) {
+	mutex_up();
+	if (_next_nr == nr) {
+		_next_nr = 0;
+		_next_data = 0;
+	}
+	if (_current_nr == nr) {
+		for (int i = 0; i < 4; i++) {
+			clear_channel(i);
+		}
+		_repeat_chunk = _next_chunk = 0;
+		_current_nr = 0;
+		_current_data = 0;
 		chainNextSound();
 	}
+	mutex_down();
+}
+
+void Player_V1::clear_channel(int i) {
+	_channels[i].freq   = 0;
+	_channels[i].volume = 15;
 }
 
 int Player_V1::getMusicTimer() const {
-	return _music_timer;
+	/* Do V1 games have a music timer? */
+	return 0;
 }
 
-void Player_V1::parse_chunk() {
+void Player_V1::parseSpeakerChunk() {
 	set_mplex(3000);
 	_forced_level = 0;
 
  parse_again:
-	_chunk_type = READ_LE_UINT16(_next_cmd);
-	debug(4, "parse_chunk: sound %d, offset %4x, chunk %x", 
-		  current_nr, _next_cmd - current_data, _chunk_type);
+	_chunk_type = READ_LE_UINT16(_next_chunk);
+	debug(6, "parseSpeakerChunk: sound %d, offset %4x, chunk %x", 
+		  _current_nr, _next_chunk - _current_data, _chunk_type);
 
-	_next_cmd += 2;
+	_next_chunk += 2;
 	switch (_chunk_type) {
 	case 0xffff:
-		current_nr = 0;
-		current_data = 0;
-		_freq_current = 0;
+		_current_nr = 0;
+		_current_data = 0;
+		_channels[0].freq = 0;
+		_next_chunk = 0;
 		chainNextSound();
 		break;
 	case 0xfffe:
-		_repeat_ptr = _next_cmd;
+		_repeat_chunk = _next_chunk;
 		goto parse_again;
 
 	case 0xfffd:
-		_next_cmd = _repeat_ptr;
+		_next_chunk = _repeat_chunk;
 		goto parse_again;
 
 	case 0xfffc:
-		/* handle reset. We don't need this don't we? */
+		/* handle reset. We don't need this do we? */
 		goto parse_again;
 
 	case 0:
 		_time_left = 1;
-		set_mplex(READ_LE_UINT16(_next_cmd));
-		_next_cmd += 2;
+		set_mplex(READ_LE_UINT16(_next_chunk));
+		_next_chunk += 2;
 		break;
 	case 1:
-		set_mplex(READ_LE_UINT16(_next_cmd));
-		_freq_start = READ_LE_UINT16(_next_cmd + 2);
-		_freq_end   = READ_LE_UINT16(_next_cmd + 4);
-		_freq_delta = READ_LE_UINT16(_next_cmd + 6);
-		_repeat_ctr = READ_LE_UINT16(_next_cmd + 8);
-		_freq_current = _freq_start;
-		_next_cmd += 10;
-		debug(4, "chunk 1: mplex %d, freq %d -> %d step %d  x %d", 
-			  _mplex, _freq_start, _freq_end, _freq_delta, _repeat_ctr);
+		set_mplex(READ_LE_UINT16(_next_chunk));
+		_start = READ_LE_UINT16(_next_chunk + 2);
+		_end   = READ_LE_UINT16(_next_chunk + 4);
+		_delta = (int16) READ_LE_UINT16(_next_chunk + 6);
+		_repeat_ctr = READ_LE_UINT16(_next_chunk + 8);
+		_channels[0].freq = _start;
+		_next_chunk += 10;
+		debug(6, "chunk 1: mplex %d, freq %d -> %d step %d  x %d", 
+			  _mplex, _start, _end, _delta, _repeat_ctr);
 		break;
 	case 2:
-		_freq_start = READ_LE_UINT16(_next_cmd);
-		_freq_end   = READ_LE_UINT16(_next_cmd + 2);
-		_freq_delta = READ_LE_UINT16(_next_cmd + 4);
-		_freq_current = 0;
-		_next_cmd += 6;
-		debug(4, "chunk 2: %d -> %d step %d", 
-			  _freq_start, _freq_end, _freq_delta);
+		_start = READ_LE_UINT16(_next_chunk);
+		_end   = READ_LE_UINT16(_next_chunk + 2);
+		_delta = (int16) READ_LE_UINT16(_next_chunk + 4);
+		_channels[0].freq = 0;
+		_next_chunk += 6;
+		debug(6, "chunk 2: %d -> %d step %d", 
+			  _start, _end, _delta);
 		break;
 	case 3:
-		_freq_start = READ_LE_UINT16(_next_cmd);
-		_freq_end   = READ_LE_UINT16(_next_cmd + 2);
-		_freq_delta = READ_LE_UINT16(_next_cmd + 4);
-		_freq_current = 0;
-		_next_cmd += 6;
-		debug(4, "chunk 3: %d -> %d step %d", 
-			  _freq_start, _freq_end, _freq_delta);
+		_start = READ_LE_UINT16(_next_chunk);
+		_end   = READ_LE_UINT16(_next_chunk + 2);
+		_delta = (int16) READ_LE_UINT16(_next_chunk + 4);
+		_channels[0].freq = 0;
+		_next_chunk += 6;
+		debug(6, "chunk 3: %d -> %d step %d", 
+			  _start, _end, _delta);
 		break;
 	}
 }
 
-void Player_V1::next_speaker_cmd() {
+void Player_V1::nextSpeakerCmd() {
 	uint16 lsr;
 	switch (_chunk_type) {
 	case 0:
 		if (--_time_left)
 			return;
-		_time_left = READ_LE_UINT16(_next_cmd);
-		_next_cmd += 2;
+		_time_left = READ_LE_UINT16(_next_chunk);
+		_next_chunk += 2;
 		if (_time_left == 0xfffb) {
 			/* handle 0xfffb?? */
-			_time_left = READ_LE_UINT16(_next_cmd);
-			_next_cmd += 2;
+			_time_left = READ_LE_UINT16(_next_chunk);
+			_next_chunk += 2;
 		}
-		debug(4, "next_speaker_cmd: chunk %d, offset %4x: notelen %d", 
-			  _chunk_type, _next_cmd - 2 - current_data, _time_left);
+		debug(7, "nextSpeakerCmd: chunk %d, offset %4x: notelen %d", 
+			  _chunk_type, _next_chunk - 2 - _current_data, _time_left);
 
 		if (_time_left == 0) {
-			parse_chunk();
+			parseSpeakerChunk();
 		} else {
-			_freq_current = READ_LE_UINT16(_next_cmd);
-			_next_cmd += 2;
-			debug(4, "freq_current: %d", _freq_current);
+			_channels[0].freq = READ_LE_UINT16(_next_chunk);
+			_next_chunk += 2;
+			debug(7, "freq_current: %d", _channels[0].freq);
 		}
 		break;
 
 	case 1:
-		_freq_current = (_freq_current + _freq_delta) & 0xffff;
-		if (_freq_current == _freq_end) {
-			if (!--_repeat_ctr)
-				parse_chunk();
-			_freq_current = _freq_start;
+		_channels[0].freq = (_channels[0].freq + _delta) & 0xffff;
+		if (_channels[0].freq == _end) {
+			if (!--_repeat_ctr) {
+				parseSpeakerChunk();
+				return;
+			}
+			_channels[0].freq = _start;
 		}
 		break;
 
 	case 2:
-		_freq_start = (_freq_start + _freq_delta) & 0xffff;
-		if (_freq_start == _freq_end) {
-			parse_chunk();
+		_start = (_start + _delta) & 0xffff;
+		if (_start == _end) {
+			parseSpeakerChunk();
+			return;
 		}
-		set_mplex(_freq_start);
+		set_mplex(_start);
 		_forced_level ^= 1;
 		break;
 	case 3:
-		_freq_start = (_freq_start + _freq_delta) & 0xffff;
-		if (_freq_start == _freq_end) {
-			parse_chunk();
+		_start = (_start + _delta) & 0xffff;
+		if (_start == _end) {
+			parseSpeakerChunk();
+			return;
 		}
 		lsr = _random_lsr + 0x9248;
 		lsr = (lsr >> 3) | (lsr << 13);
 		_random_lsr = lsr;
-		set_mplex((_freq_start & lsr) | 0x180);
+		set_mplex((_start & lsr) | 0x180);
 		_forced_level ^= 1;
 		break;
 	}
 }
 
+void Player_V1::parsePCjrChunk() {
+	uint tmp;
+	uint i;
+
+	set_mplex(3000);
+	_forced_level = 0;
+
+ parse_again:
+
+	_chunk_type = READ_LE_UINT16(_next_chunk);
+	debug(6, "parsePCjrChunk: sound %d, offset %4x, chunk %x", 
+		  _current_nr, _next_chunk - _current_data, _chunk_type);
+
+	_next_chunk += 2;
+	switch (_chunk_type) {
+	case 1: /* FIXME: implement! */
+		warning("Unimplemented PCjr chunk in sound %d:", _current_nr);
+		hexdump(_next_chunk-2, 160);
+		/* fall through*/
+	case 0xffff:
+		for (i = 0; i < 4; ++i)
+			clear_channel(i);
+		_current_nr = 0;
+		_current_data = 0;
+		_repeat_chunk = _next_chunk = 0;
+		chainNextSound();
+		break;
+
+	case 0xfffe:
+		_repeat_chunk = _next_chunk;
+		goto parse_again;
+
+	case 0xfffd:
+		_next_chunk = _repeat_chunk;
+		goto parse_again;
+
+	case 0xfffc:
+		/* handle reset. We don't need this do we? */
+		goto parse_again;
+
+	case 0:
+		set_mplex(READ_LE_UINT16(_next_chunk));
+		_next_chunk += 2;
+		for (i = 0; i < 4; i++) {
+			tmp = READ_LE_UINT16(_next_chunk);
+			_next_chunk += 2;
+			if (tmp == 0xffff) {
+				_channels[i].cmd_ptr = 0;
+				continue;
+			}
+			_channels[i].attack    = READ_LE_UINT16(_current_data + tmp);
+			_channels[i].decay     = READ_LE_UINT16(_current_data + tmp + 2);
+			_channels[i].level     = READ_LE_UINT16(_current_data + tmp + 4);
+			_channels[i].sustain_1 = READ_LE_UINT16(_current_data + tmp + 6);
+			_channels[i].sustain_2 = READ_LE_UINT16(_current_data + tmp + 8);
+			_channels[i].notelen   = 1;
+			_channels[i].volume    = 15;
+			_channels[i].cmd_ptr   = _current_data + tmp + 10;
+		}
+		break;
+
+	case 2:
+		_start = READ_LE_UINT16(_next_chunk);
+		_end   = READ_LE_UINT16(_next_chunk + 2);
+		_delta = (int16) READ_LE_UINT16(_next_chunk + 4);
+		_channels[0].freq = 0;
+		_next_chunk += 6;
+		debug(6, "chunk 2: %d -> %d step %d", 
+			  _start, _end, _delta);
+		break;
+	case 3: 
+		set_mplex(READ_LE_UINT16(_next_chunk));
+		tmp = READ_LE_UINT16(_next_chunk + 2);
+		assert((tmp & 0xf0) == 0xe0);
+		_channels[3].freq = tmp & 0xf;
+		if ((tmp & 3) == 3) {
+			_next_chunk += 2;
+			_channels[2].freq = READ_LE_UINT16(_next_chunk + 2);
+		}
+		_channels[3].volume = READ_LE_UINT16(_next_chunk + 4);
+		_repeat_ctr = READ_LE_UINT16(_next_chunk + 6);
+		_delta = (int16) READ_LE_UINT16(_next_chunk + 8);
+		_next_chunk += 10;
+		break;
+	}
+}
+
+void Player_V1::nextPCjrCmd() {
+	uint i;
+	int dummy;
+	switch (_chunk_type) {
+	case 0:
+		for (i = 0; i < 4; i++) {
+			if (!_channels[i].cmd_ptr)
+				continue;
+			if (!--_channels[i].notelen) {
+				dummy = READ_LE_UINT16(_channels[i].cmd_ptr);
+				if (dummy >= 0xfffe) {
+					if (dummy == 0xfffe)
+						_next_chunk = _current_data + 2;
+					parsePCjrChunk();
+					return;
+				}
+				_channels[i].notelen = 4 * dummy;
+				dummy = READ_LE_UINT16(_channels[i].cmd_ptr + 2);
+				if (dummy == 0) {
+					_channels[i].hull_counter = 4;
+					_channels[i].sustctr = _channels[i].sustain_2;
+				} else {
+					_channels[i].hull_counter = 1;
+					_channels[i].freq = dummy;
+				}
+				debug(7, "chunk 0: channel %d play %d for %d", 
+					  i, dummy, _channels[i].notelen);
+				_channels[i].cmd_ptr += 4;
+			}
+
+
+			switch (_channels[i].hull_counter) {
+			case 1:
+				_channels[i].volume -= _channels[i].attack;
+				if ((int) _channels[i].volume <= 0) {
+					_channels[i].volume = 0;
+					_channels[i].hull_counter++;
+				}
+				break;
+			case 2:
+				_channels[i].volume += _channels[i].decay;
+				if (_channels[i].volume >= _channels[i].level) {
+					_channels[i].volume = _channels[i].level;
+					_channels[i].hull_counter++;
+				}
+				break;
+			case 4:
+				if (--_channels[i].sustctr < 0) {
+					_channels[i].sustctr = _channels[i].sustain_2;
+					_channels[i].volume += _channels[i].sustain_1;
+					if ((int) _channels[i].volume >= 15) {
+						_channels[i].volume = 15;
+						_channels[i].hull_counter++;
+					}
+				}
+				break;
+			}
+		}
+		break;
+
+	case 1:
+		break;
+
+	case 2:
+		_start += _delta;
+		if (_start == _end) {
+			parsePCjrChunk();
+			return;
+		}
+		set_mplex(_start);
+		debug(7, "chunk 2: mplex %d  curve %d", _start, _forced_level);
+		_forced_level ^= 1;
+		break;
+	case 3:
+		dummy = _channels[3].volume + _delta;
+		if (dummy >= 15) {
+			_channels[3].volume = 15;
+		} else if (dummy <= 0) {
+			_channels[3].volume = 0;
+		} else {
+			_channels[3].volume = dummy;
+			break;
+		}
+		
+		if (!--_repeat_ctr) {
+			parsePCjrChunk();
+			return;
+		}
+		_delta = READ_LE_UINT16(_next_chunk);
+		_next_chunk += 2;
+		break;
+	}
+}
+
 void Player_V1::set_mplex (uint mplex) {
 	if (mplex == 0)
 		mplex = 65536;
 	_mplex = mplex;
-	_tick_len = (_sample_rate << FIXP_SHIFT) 
-		/ (TIMER_BASE_FREQ / mplex);
+	_tick_len = _mplex_step * mplex;
 }
 
 void Player_V1::do_mix (int16 *data, uint len) {
@@ -248,13 +446,21 @@
 		step = len;
 		if (step > (_next_tick >> FIXP_SHIFT))
 			step = (_next_tick >> FIXP_SHIFT);
-		generateSpkSamples(data, step);
+		if (_pcjr)
+			generatePCjrSamples(data, step);
+		else
+			generateSpkSamples(data, step);
 		data += step;
 		_next_tick -= step << FIXP_SHIFT;
 
 		if (!(_next_tick >> FIXP_SHIFT)) {
 			_next_tick += _tick_len;
-			next_speaker_cmd();
+			if (_next_chunk) {
+				if (_pcjr)
+					nextPCjrCmd();
+				else
+					nextSpeakerCmd();
+			}
 		}
 	} while (len -= step);
 	mutex_down();
@@ -264,16 +470,79 @@
 	uint i;
 
 	memset (data, 0, sizeof(int16) * len);
-	if (_freq_current == 0) {
+	if (_channels[0].freq == 0) {
 		if (_forced_level) {
 			for (i = 0; i < len; i++) {
 				data[i] = _volumetable[0];
 			}
+			debug(9, "speaker: %8x: forced one", _tick_len);
 		} else if (!_level) {
 			return;
 		}
 	} else {
-		squareGenerator(0, _freq_current, 0, 0, data, len);
+		squareGenerator(0, _channels[0].freq, 0, 0, data, len);
+		debug(9, "speaker: %8x: freq %d %.1f", _tick_len,
+			  _channels[0].freq, 1193000.0/_channels[0].freq);
 	}
 	lowPassFilter(data, len);
+}
+
+void Player_V1::generatePCjrSamples(int16 *data, uint len) {
+	uint i, j;
+	uint freq, vol;
+	bool hasdata = false;
+
+	memset(data, 0, sizeof(int16) * len);
+
+	if (_forced_level) {
+		for (i = 0; i < len; i++)
+			data[i] = _volumetable[0];
+		hasdata = true;
+		debug(9, "channel[4]: %8x: forced one", _tick_len);
+	}
+
+	for (i = 1; i < 3; i++) {
+		freq = _channels[i].freq;
+		if (freq) {
+			for (j = 0; j < i; j++) {
+				if (freq == _channels[j].freq) {
+					/* HACK: this channel is playing at
+					 * the same frequency as another.
+					 * Synchronize it to the same phase to
+					 * prevent interference. 
+					 */
+					_timer_count[i] = _timer_count[j];
+					_timer_output ^= (1 << i) &
+						(_timer_output ^ _timer_output << (i - j));
+				}
+			}
+		}
+	}
+
+	for (i = 0; i < 4; i++) {
+		freq = _channels[i].freq;
+		vol  = _channels[i].volume;
+		if (!freq || !_volumetable[_channels[i].volume]) {
+			_timer_count[i] -= len << FIXP_SHIFT;
+			if (_timer_count[i] < 0)
+				_timer_count[i] = 0;
+		} else if (i < 3) {
+			hasdata = true;
+			squareGenerator(i, freq, vol, 0, data, len);
+			debug(9, "channel[%d]: %8x: freq %d %.1f ; volume %d", 
+				  i, _tick_len, freq, 111860.0/freq,  vol);
+		} else {
+			int noiseFB = (freq & 4) ? FB_WNOISE : FB_PNOISE;
+			int n = (freq & 3);
+			
+			freq = (n == 3) ? 2 * (_channels[2].freq) : 1 << (5 + n);
+			hasdata = true;
+			squareGenerator(i, freq, vol, noiseFB, data, len);
+			debug(9, "channel[%d]: %x: noise freq %d %.1f ; volume %d", 
+				  i, _tick_len, freq, 111860.0/freq,  vol);
+		}
+	}
+
+	if (_level || hasdata)
+		lowPassFilter(data, len);
 }

Index: player_v1.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/player_v1.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- player_v1.h	14 Aug 2003 02:30:54 -0000	1.1
+++ player_v1.h	14 Aug 2003 19:41:39 -0000	1.2
@@ -25,39 +25,70 @@
 
 #include "player_v2.h"
 
+#define FB_WNOISE 0x12000       /* feedback for white noise */
+#define FB_PNOISE 0x08000       /* feedback for periodic noise */
+
+struct channel_data_v1 {
+	uint freq;
+	uint volume;
+	byte *cmd_ptr;
+	uint notelen;
+	uint hull_counter;
+	uint attack;
+	uint decay;
+	uint level;
+	uint sustain_1;
+	uint sustain_2;
+	int  sustctr;
+};
+
 class Player_V1 : public Player_V2 {
 public:
 	Player_V1(Scumm *scumm);
 	~Player_V1();
 
 	void startSound(int nr, byte *data);
+	void stopAllSounds();
+	void stopSound(int nr);
 	int  getMusicTimer() const;
 
 protected:
 	void restartSound();
 	void next_speaker_cmd(ChannelInfo *channel);
+	void clear_channel(int i);
 	void chainSound(int nr, byte *data);
 
 	void do_mix (int16 *buf, uint len);
 
 	void set_mplex(uint mplex);
-	void parse_chunk();
-	void next_speaker_cmd();
+	void parseSpeakerChunk();
+	void nextSpeakerCmd();
+	void parsePCjrChunk();
+	void nextPCjrCmd();
 	void generateSpkSamples(int16 *data, uint len);
+	void generatePCjrSamples(int16 *data, uint len);
+
+	channel_data_v1 _channels[4];
 
 private:
-	byte *_next_cmd;
-	byte *_repeat_ptr;
+	byte *_next_chunk;
+	byte *_repeat_chunk;
 	uint  _chunk_type;
-	uint  _time_left;
+	uint  _mplex_step;
 	uint  _mplex;
-	uint  _freq_start;
-	uint  _freq_end;
-	uint  _freq_delta;
 	uint  _repeat_ctr;
 	uint  _freq_current;
 	uint  _forced_level;
 	uint16 _random_lsr;
+	uint  _channel;
+	uint  _time_left;
+	uint  _start;
+	uint  _end;
+	int   _delta;
+	uint  _time_left_2;
+	uint  _start_2;
+	int   _delta_2;
+	uint  _channel_2;
 };
 
 #endif

Index: player_v2.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/player_v2.cpp,v
retrieving revision 2.20
retrieving revision 2.21
diff -u -d -r2.20 -r2.21
--- player_v2.cpp	13 Aug 2003 17:38:05 -0000	2.20
+++ player_v2.cpp	14 Aug 2003 19:41:39 -0000	2.21
@@ -22,6 +22,7 @@
 #include "common/engine.h"
 #include "player_v2.h"
 #include "scumm.h"
+#include "sound/mididrv.h"
 #include "sound/mixer.h"
 
 #define FREQ_HZ 236 // Don't change!
@@ -342,8 +343,8 @@
 	_header_len = (scumm->_features & GF_OLD_BUNDLE) ? 4 : 6;
 
 	// Initialize sound queue 
-	current_nr = next_nr = 0;
-	current_data = next_data = 0;
+	_current_nr = _next_nr = 0;
+	_current_data = _next_data = 0;
 	
 	// Initialize channel code
 	for (i = 0; i < 4; ++i)
@@ -361,7 +362,7 @@
 
 	_RNG = NG_PRESET;
 
-	set_pcjr(true);
+	set_pcjr(scumm->_midiDriver != MD_PCSPK);
 	set_master_volume(255);
 
 	_mixer->setupPremix(this, premix_proc);
@@ -401,8 +402,6 @@
 	for (i = 0; i < 4; i++)
 		_timer_count[i] = 0;
 
-	if (current_data)
-		restartSound();
 	mutex_down();
 }
 
@@ -429,27 +428,27 @@
 void Player_V2::chainSound(int nr, byte *data) {
 	int offset = _header_len + (_pcjr ? 10 : 2);
 
-	current_nr = nr;
-	current_data = data;
+	_current_nr = nr;
+	_current_data = data;
 
 	for (int i = 0; i < 4; i++) {
 		clear_channel(i);
 
-		channels[i].d.music_script_nr = nr;
+		_channels[i].d.music_script_nr = nr;
 		if (data) {
-			channels[i].d.next_cmd = READ_LE_UINT16(data+offset+2*i);
-			if (channels[i].d.next_cmd)
-				channels[i].d.time_left = 1;
+			_channels[i].d.next_cmd = READ_LE_UINT16(data+offset+2*i);
+			if (_channels[i].d.next_cmd)
+				_channels[i].d.time_left = 1;
 		}
 	}
 	_music_timer = 0;
 }
 
 void Player_V2::chainNextSound() {
-	if (next_nr) {
-		chainSound(next_nr, next_data);
-		next_nr = 0;
-		next_data = 0;
+	if (_next_nr) {
+		chainSound(_next_nr, _next_data);
+		_next_nr = 0;
+		_next_data = 0;
 	}
 }
 
@@ -458,23 +457,23 @@
 	for (int i = 0; i < 4; i++) {
 		clear_channel(i);
 	}
-	next_nr = current_nr = 0;
-	next_data = current_data = 0;
+	_next_nr = _current_nr = 0;
+	_next_data = _current_data = 0;
 	mutex_down();
 }
 
 void Player_V2::stopSound(int nr) {
 	mutex_up();
-	if (next_nr == nr) {
-		next_nr = 0;
-		next_data = 0;
+	if (_next_nr == nr) {
+		_next_nr = 0;
+		_next_data = 0;
 	}
-	if (current_nr == nr) {
+	if (_current_nr == nr) {
 		for (int i = 0; i < 4; i++) {
 			clear_channel(i);
 		}
-		current_nr = 0;
-		current_data = 0;
+		_current_nr = 0;
+		_current_data = 0;
 		chainNextSound();
 	}
 	mutex_down();
@@ -483,16 +482,16 @@
 void Player_V2::startSound(int nr, byte *data) {
 	mutex_up();
 
-	int cprio = current_data ? *(current_data + _header_len) : 0;
+	int cprio = _current_data ? *(_current_data + _header_len) : 0;
 	int prio  = *(data + _header_len);
-	int nprio = next_data ? *(next_data + _header_len) : 0;
+	int nprio = _next_data ? *(_next_data + _header_len) : 0;
 
 	int restartable = *(data + _header_len + 1);
 
-	if (!current_nr || cprio <= prio) {
-		int tnr = current_nr;
+	if (!_current_nr || cprio <= prio) {
+		int tnr = _current_nr;
 		int tprio = cprio;
-		byte *tdata  = current_data;
+		byte *tdata  = _current_data;
 
 		chainSound(nr, data);
 		nr   = tnr;
@@ -501,35 +500,26 @@
 		restartable = data ? *(data + _header_len + 1) : 0;
 	}
 	
-	if (!current_nr) {
+	if (!_current_nr) {
 		nr = 0;
-		next_nr = 0;
-		next_data = 0;
+		_next_nr = 0;
+		_next_data = 0;
 	}
 	
-	if (nr != current_nr
+	if (nr != _current_nr
 	    && restartable
-	    && (!next_nr
+	    && (!_next_nr
 		|| nprio <= prio)) {
 
-		next_nr = nr;
-		next_data = data;
+		_next_nr = nr;
+		_next_data = data;
 	}
 
 	mutex_down();
 }
 
-void Player_V2::restartSound() {
-	if (*(current_data + _header_len + 1)) {
-		/* current sound is restartable */
-		chainSound(current_nr, current_data);
-	} else {
-		chainNextSound();
-	}
-}
-
 bool Player_V2::getSoundStatus(int nr) const {
-	return current_nr == nr || next_nr == nr;
+	return _current_nr == nr || _next_nr == nr;
 }
 
 
@@ -538,7 +528,7 @@
 }
 
 void Player_V2::clear_channel(int i) {
-	ChannelInfo *channel = &channels[i];
+	ChannelInfo *channel = &_channels[i];
 	channel->d.time_left  = 0;
 	channel->d.next_cmd   = 0;
 	channel->d.base_freq  = 0;
@@ -563,7 +553,7 @@
 	if (_isV3Game)
 		return _music_timer;
 	else
-		return channels[0].d.music_timer;
+		return _channels[0].d.music_timer;
 }
 
 void Player_V2::execute_cmd(ChannelInfo *channel) {
@@ -577,7 +567,7 @@
 
 	if (channel->d.next_cmd == 0)
 		return;
-	script_ptr = &current_data[channel->d.next_cmd];
+	script_ptr = &_current_data[channel->d.next_cmd];
 
 	for (;;) {
 		uint8 opcode = *script_ptr++;
@@ -585,14 +575,14 @@
 			switch (opcode) {
 			case 0xf8: // set hull curve
 				debug(9, "channels[%d]: hull curve %2d", 
-				channel - channels, *script_ptr);
+				channel - _channels, *script_ptr);
 				channel->d.hull_curve = hull_offsets[*script_ptr/2];
 				script_ptr++;
 				break;
 
 			case 0xf9: // set freqmod curve
 				debug(9, "channels[%d]: freqmod curve %2d", 
-				channel - channels, *script_ptr);
+				channel - _channels, *script_ptr);
 				channel->d.freqmod_table = freqmod_offsets[*script_ptr/4];
 				channel->d.freqmod_modulo = freqmod_lengths[*script_ptr/4];
 				script_ptr++;
@@ -602,7 +592,7 @@
 				value = READ_LE_UINT16 (script_ptr);
 				debug(9, "clear channel %d", value/50);
 				script_ptr += 2;
-				channel = &channels[value / sizeof(ChannelInfo)];
+				channel = &_channels[value / sizeof(ChannelInfo)];
 				// fall through
 
 			case 0xfa: // clear current channel
@@ -628,15 +618,15 @@
 
 			case 0xfb: // ret from subroutine
 				debug(9, "ret from sub");
-				script_ptr = retaddr;
+				script_ptr = _retaddr;
 				break;
 
 			case 0xfc: // call subroutine
 				offset = READ_LE_UINT16 (script_ptr);
 				debug(9, "subroutine %d", offset);
 				script_ptr += 2;
-				retaddr = script_ptr;
-				script_ptr = current_data + offset;
+				_retaddr = script_ptr;
+				script_ptr = _current_data + offset;
 				debug(9, "XXX1: %p -> %04x", script_ptr, offset);
 				break;
 
@@ -654,7 +644,7 @@
 				value = READ_LE_UINT16 (script_ptr);
 				channel->array[opcode/2] = value;
 				debug(9, "channels[%d]: set param %2d = %5d", 
-				channel - &channels[0], opcode, value);
+				channel - &_channels[0], opcode, value);
 				script_ptr += 2;
 				if (opcode == 14) {
 				    /* tempo var */
@@ -668,7 +658,7 @@
 			for (;;) {
 				int16 note, octave;
 				int is_last_note;
-				dest_channel = &channels[(opcode >> 5) & 3];
+				dest_channel = &_channels[(opcode >> 5) & 3];
 
 				if (!(opcode & 0x80)) {
 
@@ -695,7 +685,7 @@
 
 
 				debug(9, "channels[%d]: @%04x note: %3d+%d len: %2d hull: %d mod: %d/%d/%d %s", 
-				      dest_channel - channel, script_ptr ? script_ptr - current_data - 2 : 0,
+				      dest_channel - channel, script_ptr ? script_ptr - _current_data - 2 : 0,
 				      note, (signed short) dest_channel->d.transpose, channel->d.time_left,
 				      dest_channel->d.hull_curve, dest_channel->d.freqmod_table,
 				      dest_channel->d.freqmod_incr,dest_channel->d.freqmod_multiplier,
@@ -713,7 +703,7 @@
 				note = note % 12;
 				dest_channel->d.hull_offset = 0;
 				dest_channel->d.hull_counter = 1;
-				if (_pcjr && dest_channel == &channels[3]) {
+				if (_pcjr && dest_channel == &_channels[3]) {
 					dest_channel->d.hull_curve = 180 + note * 12;
 					myfreq = 384 - 64 * octave;
 				} else {
@@ -735,17 +725,17 @@
 	channel->d.next_cmd = 0;
 	int i;
 	for (i = 0; i< 4; i++) {
-		if (channels[i].d.time_left)
+		if (_channels[i].d.time_left)
 			goto finish;
 	}
 
-	current_nr = 0;
-	current_data = 0;
+	_current_nr = 0;
+	_current_data = 0;
 	chainNextSound();
 	return;
 
 finish:
-	channel->d.next_cmd = script_ptr - current_data;
+	channel->d.next_cmd = script_ptr - _current_data;
 	return;
 }
 
@@ -778,7 +768,7 @@
 
 #if 0
 	debug(9, "channels[%d]: freq %d hull %d/%d/%d", 
-	      channel - &channels[0], channel->d.freq,
+	      channel - &_channels[0], channel->d.freq,
 	      channel->d.hull_curve, channel->d.hull_offset,
 	      channel->d.hull_counter);
 #endif
@@ -819,9 +809,9 @@
 
 		if (!(_next_tick >> FIXP_SHIFT)) {
 			for (int i = 0; i < 4; i++) {
-				if (!channels[i].d.time_left)
+				if (!_channels[i].d.time_left)
 					continue;
-				next_freqs(&channels[i]);
+				next_freqs(&_channels[i]);
 			}
 			_next_tick += _tick_len;
 			if (_music_timer_ctr++ >= _ticks_per_music_timer) {
@@ -887,15 +877,15 @@
 	int winning_channel = -1;
 	for (int i = 0; i < 4; i++) {
 		if (winning_channel == -1
-		    && channels[i].d.volume
-		    && channels[i].d.time_left) {
+		    && _channels[i].d.volume
+		    && _channels[i].d.time_left) {
 			winning_channel = i;
 		}
 	}
 
 	memset (data, 0, sizeof(int16) * len);
 	if (winning_channel != -1) {
-		squareGenerator(0, channels[winning_channel].d.freq, 0, 
+		squareGenerator(0, _channels[winning_channel].d.freq, 0, 
 				0, data, len);
 	} else if (_level == 0)
 		/* shortcut: no sound is being played. */
@@ -912,12 +902,12 @@
 	bool hasdata = false;
 
 	for (i = 1; i < 3; i++) {
-		freq = channels[i].d.freq >> 6;
-		if (channels[i].d.volume && channels[i].d.time_left) {
+		freq = _channels[i].d.freq >> 6;
+		if (_channels[i].d.volume && _channels[i].d.time_left) {
 			for (j = 0; j < i; j++) {
-				if (channels[j].d.volume
-				    && channels[j].d.time_left
-				    && freq == (channels[j].d.freq >> 6)) {
+				if (_channels[j].d.volume
+				    && _channels[j].d.time_left
+				    && freq == (_channels[j].d.freq >> 6)) {
 					/* HACK: this channel is playing at
 					 * the same frequency as another.
 					 * Synchronize it to the same phase to
@@ -932,9 +922,9 @@
 	}
 
 	for (i = 0; i < 4; i++) {
-		freq = channels[i].d.freq >> 6;
-		vol  = (65535 - channels[i].d.volume) >> 12;
-		if (!channels[i].d.volume || !channels[i].d.time_left) {
+		freq = _channels[i].d.freq >> 6;
+		vol  = (65535 - _channels[i].d.volume) >> 12;
+		if (!_channels[i].d.volume || !_channels[i].d.time_left) {
 			_timer_count[i] -= len << FIXP_SHIFT;
 			if (_timer_count[i] < 0)
 				_timer_count[i] = 0;
@@ -945,7 +935,7 @@
 			int noiseFB = (freq & 4) ? FB_WNOISE : FB_PNOISE;
 			int n = (freq & 3);
 			
-			freq = (n == 3) ? 2 * (channels[2].d.freq>>6) : 1 << (5 + n);
+			freq = (n == 3) ? 2 * (_channels[2].d.freq>>6) : 1 << (5 + n);
 			hasdata = true;
 			squareGenerator(i, freq, vol, noiseFB, data, len);
 		}

Index: player_v2.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/player_v2.h,v
retrieving revision 2.9
retrieving revision 2.10
diff -u -d -r2.9 -r2.10
--- player_v2.h	14 Aug 2003 02:28:19 -0000	2.9
+++ player_v2.h	14 Aug 2003 19:41:39 -0000	2.10
@@ -75,7 +75,6 @@
 	Player_V2(Scumm *scumm);
 	virtual ~Player_V2();
 
-	virtual void set_pcjr(bool pcjr);
 	virtual void set_master_volume(int vol);
 
 	virtual void startSound(int nr, byte *data);
@@ -109,19 +108,19 @@
 
 	const uint16 *_freqs_table;
 
-	ChannelInfo channels[4];
+	ChannelInfo _channels[4];
 
-	int   current_nr;
-	byte *current_data;
-	int   next_nr;
-	byte *next_data;
-	byte *retaddr;
+	int   _current_nr;
+	byte *_current_data;
+	int   _next_nr;
+	byte *_next_data;
+	byte *_retaddr;
 
 	OSystem::MutexRef _mutex;
 	void mutex_up() { _system->lock_mutex (_mutex); }
 	void mutex_down() { _system->unlock_mutex (_mutex); }
 
-	virtual void restartSound();
+	virtual void set_pcjr(bool pcjr);
 	void execute_cmd(ChannelInfo *channel);
 	virtual void next_freqs(ChannelInfo *channel);
 	virtual void clear_channel(int i);

Index: resource_v2.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource_v2.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- resource_v2.cpp	14 Aug 2003 11:40:50 -0000	1.25
+++ resource_v2.cpp	14 Aug 2003 19:41:39 -0000	1.26
@@ -109,11 +109,8 @@
 void Scumm_v2::readEnhancedIndexFile() {
 
 	//FIXME the music driver was previously been set before detection of classic/enchanced version.
-	if (!(_features & GF_AMIGA)) {
+	if (!(_features & GF_AMIGA))
 		_playerV2 = new Player_V2(this);
-		if (_midiDriver == MD_PCSPK)
-			_playerV2->set_pcjr(false);
-	}
 
 	_numGlobalObjects = _fileHandle.readUint16LE();
 	_fileHandle.seek(_numGlobalObjects, SEEK_CUR); // Skip object flags

Index: scummvm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scummvm.cpp,v
retrieving revision 2.334
retrieving revision 2.335
diff -u -d -r2.334 -r2.335
--- scummvm.cpp	14 Aug 2003 11:40:50 -0000	2.334
+++ scummvm.cpp	14 Aug 2003 19:41:40 -0000	2.335
@@ -628,9 +628,7 @@
 		_playerV2 = NULL;
 	} else if (((_midiDriver == MD_PCJR) || (_midiDriver == MD_PCSPK)) && ((_version > 2) && (_version < 5))) {
 		_playerV2 = new Player_V2(this);
-		if (_midiDriver == MD_PCSPK)
-			_playerV2->set_pcjr(false);
-	} else {
+	} else if (_version > 2) {
 		_imuse = IMuse::create (syst, _mixer, detector->createMidi());
 		if (_imuse) {
 			if (detector->_gameTempo != 0)





More information about the Scummvm-git-logs mailing list