[Scummvm-cvs-logs] CVS: scummvm/simon midi.cpp,1.40,1.41 midi.h,1.16,1.17 simon.cpp,1.205,1.206

Jamieson Christian jamieson630 at users.sourceforge.net
Fri May 23 18:27:03 CEST 2003


Update of /cvsroot/scummvm/scummvm/simon
In directory sc8-pr-cvs1:/tmp/cvs-serv3456

Modified Files:
	midi.cpp midi.h simon.cpp 
Log Message:
Added support for simultaneous music and MIDI sound effects to simon1dos.
Note that 's' still toggles MIDI sound effects on and off.

Index: midi.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/simon/midi.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- midi.cpp	23 May 2003 15:27:08 -0000	1.40
+++ midi.cpp	24 May 2003 01:26:05 -0000	1.41
@@ -34,23 +34,18 @@
 	_system = system;
 	_mutex = system->create_mutex();
 	_driver = 0;
-	_parser = 0;
 	
-	_data = 0;
+	_enable_sfx = true;
+	_current = 0;
+
 	memset(_volumeTable, 127, sizeof(_volumeTable));
 	_masterVolume = 255;
 	_paused = false;
+
 	_currentTrack = 255;
 	_loopTrack = 0;
-
 	_queuedTrack = 255;
 	_loopQueuedTrack = 0;
-
-	_num_songs = 0;
-	memset(_songs, 0, sizeof(_songs));
-	memset(_song_sizes, 0, sizeof(_song_sizes));
-	
-	_midi_sfx_toggle = false;
 }
 
 MidiPlayer::~MidiPlayer() {
@@ -83,6 +78,9 @@
 }
 
 void MidiPlayer::send (uint32 b) {
+	if (!_current)
+		return;
+
 	byte volume;
 
 	if ((b & 0xFFF0) == 0x07B0) {
@@ -90,9 +88,16 @@
 		volume = (byte) ((b >> 16) & 0xFF) * _masterVolume / 255;
 		_volumeTable [b & 0xF] = volume;
 		b = (b & 0xFF00FFFF) | (volume << 16);
-	} else if ((b & 0xF0) == 0xE0) {
-		// Skip pitch bends completely. They're screwed up in Simon games.
-		return;
+	} else if ((b & 0xF0) == 0xC0) {
+		int chan = b & 0x0F;
+		if (!_current->in_use [chan])
+			_driver->send (0x007BB0 | chan); // All Notes Off
+		_current->in_use [chan] = true;
+	} else if ((b & 0xFFF0) == 0x007BB0) {
+		// Only respond to an All Notes Off if this channel
+		// has already been marked "in use" by this parser.
+		if (!_current->in_use [b & 0x0F])
+			return;
 	}
 
 	_driver->send (b);
@@ -100,11 +105,11 @@
 
 void MidiPlayer::metaEvent (byte type, byte *data, uint16 length) {
 	// Only thing we care about is End of Track.
-	if (type != 0x2F)
+	if (!_current || type != 0x2F || _current == &_sfx)
 		return;
 
 	if (_loopTrack) {
-		_parser->jumpToTick (0);
+		_current->parser->jumpToTick (0);
 	} else if (_queuedTrack != 255) {
 		_currentTrack = 255;
 		byte destination = _queuedTrack;
@@ -125,48 +130,57 @@
 }
 
 void MidiPlayer::onTimer (void *data) {
-	MidiPlayer *player = (MidiPlayer *) data;
-	player->_system->lock_mutex (player->_mutex);
-	if (!player->_paused && player->_parser && player->_currentTrack != 255)
-		player->_parser->onTimer();
-	player->_system->unlock_mutex (player->_mutex);
+	MidiPlayer *p = (MidiPlayer *) data;
+	p->_system->lock_mutex (p->_mutex);
+	if (!p->_paused) {
+		if (p->_music.parser && p->_currentTrack != 255) {
+			p->_current = &p->_music;
+			p->_music.parser->onTimer();
+		}
+		if (p->_sfx.parser) {
+			p->_current = &p->_sfx;
+			p->_sfx.parser->onTimer();
+		}
+		p->_current = 0;
+	}
+	p->_system->unlock_mutex (p->_mutex);
 }
 
 void MidiPlayer::startTrack (int track) {
 	if (track == _currentTrack)
 		return;
 
-	if (_num_songs > 0) {
-		if (track >= _num_songs)
+	if (_music.num_songs > 0) {
+		if (track >= _music.num_songs)
 			return;
 
 		_system->lock_mutex (_mutex);
 
-		if (_parser) {
-			delete _parser;
-			_parser = 0;
+		if (_music.parser) {
+			delete _music.parser;
+			_music.parser = 0;
 		}
 
 		MidiParser *parser = MidiParser::createParser_SMF();
 		parser->property (MidiParser::mpMalformedPitchBends, 1);
 		parser->setMidiDriver (this);
 		parser->setTimerRate (_driver->getBaseTempo());
-		if (!parser->loadMusic (_songs[track], _song_sizes[track])) {
+		if (!parser->loadMusic (_music.songs[track], _music.song_sizes[track])) {
 			printf ("Error reading track!\n");
 			delete parser;
 			parser = 0;
 		}
 
 		_currentTrack = (byte) track;
-		_parser = parser; // That plugs the power cord into the wall
-	} else if (_parser) {
+		_music.parser = parser; // That plugs the power cord into the wall
+	} else if (_music.parser) {
 		_system->lock_mutex (_mutex);
-		if (!_parser->setTrack (track)) {
+		if (!_music.parser->setTrack (track)) {
 			_system->unlock_mutex (_mutex);
 			return;
 		}
 		_currentTrack = (byte) track;
-		_parser->jumpToTick (0);
+		_music.parser->jumpToTick (0);
 	}
 
 	_system->unlock_mutex (_mutex);
@@ -174,8 +188,8 @@
 
 void MidiPlayer::stop() {
 	_system->lock_mutex (_mutex);
-	if (_parser)
-		_parser->jumpToTick(0);
+	if (_music.parser)
+		_music.parser->jumpToTick(0);
 	_currentTrack = 255;
 	_system->unlock_mutex (_mutex);
 }
@@ -239,23 +253,21 @@
 }
 
 void MidiPlayer::clearConstructs() {
-	if (_num_songs > 0) {
-		byte i;
-		for (i = 0; i < _num_songs; ++i) {
-			free (_songs [i]);
-		}
-		_num_songs = 0;
-	}
-
-	if (_data) {
-		free (_data);
-		_data = 0;
-	}
+	clearConstructs (_music);
+	clearConstructs (_sfx);
+}
 
-	if (_parser) {
-		delete _parser;
-		_parser = 0;
+void MidiPlayer::clearConstructs (MusicInfo &info) {
+	if (info.num_songs > 0) {
+		byte i;
+		for (i = 0; i < info.num_songs; ++i)
+			free (info.songs [i]);
 	}
+	if (info.data)
+		free (info.data);
+	if (info.parser)
+		delete info.parser;
+	info.clear();
 }
 
 static int simon1_gmf_size[] = {
@@ -265,9 +277,10 @@
 	17256, 5103, 8794, 4884, 16
 };
 
-void MidiPlayer::loadSMF (File *in, int song) {
+void MidiPlayer::loadSMF (File *in, int song, bool sfx) {
 	_system->lock_mutex (_mutex);
-	clearConstructs();
+	MusicInfo *p = sfx ? &_sfx : &_music;
+	clearConstructs (*p);
 
 	uint32 size = in->size() - in->pos();
 	if (size > 64000)
@@ -276,31 +289,33 @@
 	// When allocating space, add 4 bytes in case
 	// this is a GMF and we have to tack on our own
 	// End of Track event.
-	_data = (byte *) calloc (size + 4, 1);
-	in->read (_data, size);
+	p->data = (byte *) calloc (size + 4, 1);
+	in->read (p->data, size);
 
 	// For GMF files, we're going to have to use
 	// hardcoded size tables.
-	if (!memcmp (_data, "GMF\x1", 4) && size == 64000)
+	if (!memcmp (p->data, "GMF\x1", 4) && size == 64000)
 		size = simon1_gmf_size [song];
 
 	MidiParser *parser = MidiParser::createParser_SMF();
 	parser->property (MidiParser::mpMalformedPitchBends, 1);
 	parser->setMidiDriver (this);
 	parser->setTimerRate (_driver->getBaseTempo());
-	if (!parser->loadMusic (_data, size)) {
+	if (!parser->loadMusic (p->data, size)) {
 		printf ("Error reading track!\n");
 		delete parser;
 		parser = 0;
 	}
 
-	_currentTrack = 255;
-	memset(_volumeTable, 127, sizeof(_volumeTable));
-	_parser = parser; // That plugs the power cord into the wall
+	if (!sfx) {
+		_currentTrack = 255;
+		memset(_volumeTable, 127, sizeof(_volumeTable));
+	}
+	p->parser = parser; // That plugs the power cord into the wall
 	_system->unlock_mutex (_mutex);
 }
 
-void MidiPlayer::loadMultipleSMF (File *in) {
+void MidiPlayer::loadMultipleSMF (File *in, bool sfx) {
 	// This is a special case for Simon 2 Windows.
 	// Instead of having multiple sequences as
 	// separate tracks in a Type 2 file, simon2win
@@ -311,16 +326,18 @@
 	// treat them as separate tracks -- for the
 	// purpose of jumps, anyway.
 	_system->lock_mutex (_mutex);
-	clearConstructs();
-	_num_songs = in->readByte();
-	if (_num_songs > 16) {
-		printf ("playMultipleSMF: %d is too many songs to keep track of!\n", (int) _num_songs);
+	MusicInfo *p = sfx ? &_sfx : &_music;
+	clearConstructs (*p);
+
+	p->num_songs = in->readByte();
+	if (p->num_songs > 16) {
+		printf ("playMultipleSMF: %d is too many songs to keep track of!\n", (int) p->num_songs);
 		_system->unlock_mutex (_mutex);
 		return;
 	}
 
 	byte i;
-	for (i = 0; i < _num_songs; ++i) {
+	for (i = 0; i < p->num_songs; ++i) {
 		byte buf[5];
 		uint32 pos = in->pos();
 
@@ -343,20 +360,23 @@
 
 		uint32 pos2 = in->pos() - 4;
 		uint32 size = pos2 - pos;
-		_songs[i] = (byte *) calloc (size, 1);
+		p->songs[i] = (byte *) calloc (size, 1);
 		in->seek (pos, SEEK_SET);
-		in->read (_songs[i], size);
-		_song_sizes[i] = size;
+		in->read (p->songs[i], size);
+		p->song_sizes[i] = size;
 	}
 
-	_currentTrack = 255;
-	memset(_volumeTable, 127, sizeof(_volumeTable));
+	if (!sfx) {
+		_currentTrack = 255;
+		memset(_volumeTable, 127, sizeof(_volumeTable));
+	}
 	_system->unlock_mutex (_mutex);
 }
 
-void MidiPlayer::loadXMIDI (File *in) {
+void MidiPlayer::loadXMIDI (File *in, bool sfx) {
 	_system->lock_mutex (_mutex);
-	clearConstructs();
+	MusicInfo *p = sfx ? &_sfx : &_music;
+	clearConstructs (*p);
 
 	char buf[4];
 	uint32 pos = in->pos();
@@ -378,8 +398,8 @@
 		}
 		size += 4 + in->readUint32BE();
 		in->seek (pos, 0);
-		_data = (byte *) calloc (size, 1);
-		in->read (_data, size);
+		p->data = (byte *) calloc (size, 1);
+		in->read (p->data, size);
 	} else {
 		printf ("ERROR! Expected 'FORM' tag but found '%c%c%c%c' instead!\n", buf[0], buf[1], buf[2], buf[3]);
 		_system->unlock_mutex (_mutex);
@@ -389,14 +409,16 @@
 	MidiParser *parser = MidiParser::createParser_XMIDI();
 	parser->setMidiDriver (this);
 	parser->setTimerRate (_driver->getBaseTempo());
-	if (!parser->loadMusic (_data, size)) {
+	if (!parser->loadMusic (p->data, size)) {
 		printf ("Error reading track!\n");
 		delete parser;
 		parser = 0;
 	}
 
-	_currentTrack = 255;
-	memset(_volumeTable, 127, sizeof(_volumeTable));
-	_parser = parser; // That plugs the power cord into the wall
+	if (!sfx) {
+		_currentTrack = 255;
+		memset(_volumeTable, 127, sizeof(_volumeTable));
+	}
+	p->parser = parser; // That plugs the power cord into the wall
 	_system->unlock_mutex (_mutex);
 }

Index: midi.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/simon/midi.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- midi.h	23 May 2003 04:16:37 -0000	1.16
+++ midi.h	24 May 2003 01:26:05 -0000	1.17
@@ -28,38 +28,58 @@
 class File;
 class OSystem;
 
+struct MusicInfo {
+	MidiParser *parser;
+	byte * data;
+	byte   num_songs;      // For Type 1 SMF resources
+	byte * songs[16];      // For Type 1 SMF resources
+	uint32 song_sizes[16]; // For Type 1 SMF resources
+	bool   in_use[16];     // Tracks which resource is using which MIDI channels
+
+	MusicInfo() { clear(); }
+	void clear() {
+		parser = 0; data = 0; num_songs = 0;
+		memset (songs, 0, sizeof (songs));
+		memset (song_sizes, 0, sizeof (song_sizes));
+		memset (in_use, 0, sizeof (in_use));
+	}
+};
+
 class MidiPlayer : public MidiDriver {
 protected:
 	OSystem *_system;
 	void *_mutex;
 	MidiDriver *_driver;
-	MidiParser *_parser;
 
-	byte *_data;
+	MusicInfo _music;
+	MusicInfo _sfx;
+	MusicInfo *_current; // Allows us to establish current context for operations.
+
+	// These are maintained for both music and SFX
 	byte _volumeTable[16]; // 0-127
 	byte _masterVolume;    // 0-255
 	bool _paused;
+
+	// These are only used for music.
 	byte _currentTrack;
 	bool _loopTrack;
 	byte _queuedTrack;
 	bool _loopQueuedTrack;
 
-	byte _num_songs;
-	byte *_songs[16];
-	uint32 _song_sizes[16];
-
 	static void onTimer (void *data);
 	void clearConstructs();
+	void clearConstructs (MusicInfo &info);
 
 public:
-	bool _midi_sfx_toggle;
+	bool _enable_sfx;
 
+public:
 	MidiPlayer (OSystem *system);
 	virtual ~MidiPlayer();
 
-	void loadSMF (File *in, int song);
-	void loadMultipleSMF (File *in);
-	void loadXMIDI (File *in);
+	void loadSMF (File *in, int song, bool sfx = false);
+	void loadMultipleSMF (File *in, bool sfx = false);
+	void loadXMIDI (File *in, bool sfx = false);
 
 	void setLoop (bool loop);
 	void startTrack(int track);

Index: simon.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/simon/simon.cpp,v
retrieving revision 1.205
retrieving revision 1.206
diff -u -d -r1.205 -r1.206
--- simon.cpp	23 May 2003 15:44:57 -0000	1.205
+++ simon.cpp	24 May 2003 01:26:05 -0000	1.206
@@ -1065,7 +1065,7 @@
 }
 
 void SimonState::playSting(uint a) {
-	if (!midi._midi_sfx_toggle)
+	if (!midi._enable_sfx)
 		return;
 
 	char filename[11];
@@ -1088,7 +1088,7 @@
 
 	// midi.shutdown();
 	_mus_file->seek(_mus_offsets[a], SEEK_SET);
-	midi.loadSMF (_mus_file, a);
+	midi.loadSMF (_mus_file, a, true);
 	midi.startTrack (0);
 }
 
@@ -3335,13 +3335,9 @@
 			break;
 
 		case 's':
-			if (_game == GAME_SIMON1DOS) {
-				midi._midi_sfx_toggle ^= 1;
-				if (midi._midi_sfx_toggle)
-					midi.stop();
-				else
-					loadMusic(_last_music_played);
-			} else
+			if (_game == GAME_SIMON1DOS)
+				midi._enable_sfx ^= 1;
+			else
 				_sound->effectsPause(_effects_paused ^= 1);
 			break;
 
@@ -4990,8 +4986,6 @@
 	if  (_language >= 2)
 		_subtitles = true;
 
-	midi._midi_sfx_toggle = false;
-
 	while (1) {
 		hitarea_stuff();
 		handle_verb_clicked(_verb_hitarea);
@@ -5292,9 +5286,6 @@
 }
 
 void SimonState::loadMusic (uint music) {
-	if (midi._midi_sfx_toggle)
-		return;
-
 	if (_game & GF_SIMON2) {        // Simon 2 music
 		midi.stop();
 		_game_file->seek(_game_offsets_ptr[gss->MUSIC_INDEX_BASE + music - 1], SEEK_SET);





More information about the Scummvm-git-logs mailing list