[Scummvm-cvs-logs] CVS: scummvm/simon midiparser_s1d.cpp,NONE,1.1 midi.cpp,1.45,1.46 midi.h,1.18,1.19 simon.cpp,1.215,1.216

Jamieson Christian jamieson630 at users.sourceforge.net
Sat May 24 20:20:01 CEST 2003


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

Modified Files:
	midi.cpp midi.h simon.cpp 
Added Files:
	midiparser_s1d.cpp 
Log Message:
Added music support for simon1demo

--- NEW FILE: midiparser_s1d.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001-2003 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/simon/midiparser_s1d.cpp,v 1.1 2003/05/25 03:19:21 jamieson630 Exp $
 *
 */

#include "sound/midiparser.h"
#include "sound/mididrv.h"
#include "common/util.h"

#include <stdio.h>
#include <memory.h>

//////////////////////////////////////////////////
//
// Simon 1 Demo version of MidiParser
//
//////////////////////////////////////////////////

class MidiParser_S1D : public MidiParser {
protected:
	byte *_data;
	bool _no_delta;

protected:
	void parseNextEvent (EventInfo &info);
	void resetTracking();
	uint32 readVLQ2 (byte * &data);

public:
	MidiParser_S1D() : _data(0), _no_delta(false) {}

	bool loadMusic (byte *data, uint32 size);
	void unloadMusic();
};



//////////////////////////////////////////////////
//
// MidiParser_S1D implementation
//
// This parser is the result of eyeballing the
// one MUS file that's included with simon1demo.
// So there might be some things missing.
// I've tried to notate question-mark areas
// where they occur.
//
//////////////////////////////////////////////////

// The VLQs for simon1demo seem to be
// in Little Endian format.
uint32 MidiParser_S1D::readVLQ2 (byte * &data) {
	byte str;
	uint32 value = 0;
	int i;

	for (i = 0; i < 4; ++i) {
		str = data[0];
		++data;
		value |= (str & 0x7F) << (i * 7);
		if (!(str & 0x80))
			break;
	}
	return value;
}

void MidiParser_S1D::parseNextEvent (EventInfo &info) {
	info.start = _position._play_pos;
	info.delta = _no_delta ? 0 : readVLQ2 (_position._play_pos);

	_no_delta = false;
	info.event = *(_position._play_pos++);
	if (info.command() < 0x8) {
		_no_delta = true;
		info.event += 0x80;
	}

	switch (info.command()) {
	case 0x8:
		info.basic.param1 = *(_position._play_pos++);
		info.basic.param2 = 0;
		info.length = 0;
		break;

	case 0x9:
		info.basic.param1 = *(_position._play_pos++);
		info.basic.param2 = *(_position._play_pos++); // I'm ASSUMING this byte is velocity!
		info.length = 0;
		break;

	case 0xC:
		info.basic.param1 = *(_position._play_pos++);
		info.basic.param2 = 0;
		++_position._play_pos; // I have NO IDEA what the second byte is for.
		break;

	case 0xF:
		if (info.event == 0xFC) {
			// This means End of Track.
			// Rewrite in SMF (MIDI transmission) form.
			info.event = 0xFF;
			info.ext.type = 0x2F;
			info.length = 0;
			break;
		}
		// OTherwise fall through to default.

	default:
		printf ("MidiParser_S1D: Warning! Unexpected byte 0x%02X found!\n", (int) info.event);
		_abort_parse = true;
		_position._play_pos = 0;
	}
}

bool MidiParser_S1D::loadMusic (byte *data, uint32 size) {
	unloadMusic();

	byte *pos = data;
	if (*(pos++) != 0xFC) {
		printf ("Warning: Expected 0xFC header but found 0x%02X instead\n", (int) *pos);
		return false;
	}

	// The next 3 bytes MIGHT be tempo, but we skip them and use the default.
//	setTempo (*(pos++) | (*(pos++) << 8) | (*(pos++) << 16));
	pos += 3;

	// And now we're at the actual data. Only one track.
	_num_tracks = 1;
	_data = pos;
	_tracks[0] = pos;

	// Note that we assume the original data passed in
	// will persist beyond this call, i.e. we do NOT
	// copy the data to our own buffer. Take warning....
	resetTracking();
	setTempo (500000);
	setTrack (0);
	return true;
}

void MidiParser_S1D::resetTracking() {
	MidiParser::resetTracking();
	_no_delta = false;
}

void MidiParser_S1D::unloadMusic() {
	resetTracking();
	allNotesOff();
	_data = 0;
	_num_tracks = 0;
	_active_track = 255;
}

MidiParser *MidiParser_createS1D() { return new MidiParser_S1D; }
Index: midi.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/simon/midi.cpp,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- midi.cpp	24 May 2003 04:39:47 -0000	1.45
+++ midi.cpp	25 May 2003 03:19:21 -0000	1.46
@@ -27,6 +27,13 @@
 #include "sound/mixer.h"
 #include "simon/simon.h"
 
+// MidiParser_S1D is not considered part of the standard
+// MidiParser suite, but we still try to mask its details
+// and just provide a factory function.
+extern MidiParser *MidiParser_createS1D();
+
+
+
 MidiPlayer::MidiPlayer (OSystem *system) {
 	// Since initialize() is called every time the music changes,
 	// this is where we'll initialize stuff that must persist
@@ -433,6 +440,38 @@
 	}
 
 	MidiParser *parser = MidiParser::createParser_XMIDI();
+	parser->setMidiDriver (this);
+	parser->setTimerRate (_driver->getBaseTempo());
+	if (!parser->loadMusic (p->data, size)) {
+		printf ("Error reading track!\n");
+		delete parser;
+		parser = 0;
+	}
+
+	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::loadS1D (File *in, bool sfx) {
+	_system->lock_mutex (_mutex);
+	MusicInfo *p = sfx ? &_sfx : &_music;
+	clearConstructs (*p);
+
+	uint32 size = in->readByte() | (in->readByte() << 8);
+	if (size != in->size() - 2) {
+		printf ("ERROR! Size mismatch in simon1demo MUS file (%ld versus reported %d)\n", (long) in->size() - 2, (long) size);
+		_system->unlock_mutex (_mutex);
+		return;
+	}
+
+	p->data = (byte *) calloc (size, 1);
+	in->read (p->data, size);
+
+	MidiParser *parser = MidiParser_createS1D();
 	parser->setMidiDriver (this);
 	parser->setTimerRate (_driver->getBaseTempo());
 	if (!parser->loadMusic (p->data, size)) {

Index: midi.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/simon/midi.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- midi.h	24 May 2003 03:55:37 -0000	1.18
+++ midi.h	25 May 2003 03:19:21 -0000	1.19
@@ -80,6 +80,7 @@
 	void loadSMF (File *in, int song, bool sfx = false);
 	void loadMultipleSMF (File *in, bool sfx = false);
 	void loadXMIDI (File *in, bool sfx = false);
+	void loadS1D (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.215
retrieving revision 1.216
diff -u -d -r1.215 -r1.216
--- simon.cpp	25 May 2003 03:03:40 -0000	1.215
+++ simon.cpp	25 May 2003 03:19:21 -0000	1.216
@@ -5300,7 +5300,19 @@
 			// TODO Add Protracker support for simon1amiga/cd32
 			warning("playMusic - Load %dtune attempt", music);
 		} else if (_game & GF_DEMO) {
-			// TODO Add music support for simon1demo
+			midi.stop();
+			midi.setLoop (true);
+			char buf[50];
+			File *f = new File();
+			sprintf(buf, "MOD%d.MUS", music);
+			f->open(buf, _gameDataPath);
+			if (f->isOpen() == false) {
+				warning("Can't load music from '%s'", buf);
+				return;
+			}
+			midi.loadS1D (f);
+			delete f;
+			midi.startTrack (0);
 		} else {
 			midi.stop();
 			midi.setLoop (true); // Must do this BEFORE loading music. (GMF may have its own override.)





More information about the Scummvm-git-logs mailing list