[Scummvm-cvs-logs] SF.net SVN: scummvm: [25774] scummvm/trunk/engines/parallaction

sev at users.sourceforge.net sev at users.sourceforge.net
Wed Feb 21 22:42:38 CET 2007


Revision: 25774
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25774&view=rev
Author:   sev
Date:     2007-02-21 13:42:37 -0800 (Wed, 21 Feb 2007)

Log Message:
-----------
Add support for MIDI music. THough the music is not yet heard since
there are no instrument assignments yet.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/callables.cpp
    scummvm/trunk/engines/parallaction/intro.cpp
    scummvm/trunk/engines/parallaction/location.cpp
    scummvm/trunk/engines/parallaction/menu.cpp
    scummvm/trunk/engines/parallaction/music.cpp
    scummvm/trunk/engines/parallaction/music.h
    scummvm/trunk/engines/parallaction/parallaction.cpp
    scummvm/trunk/engines/parallaction/parallaction.h

Modified: scummvm/trunk/engines/parallaction/callables.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/callables.cpp	2007-02-21 20:57:10 UTC (rev 25773)
+++ scummvm/trunk/engines/parallaction/callables.cpp	2007-02-21 21:42:37 UTC (rev 25774)
@@ -51,9 +51,7 @@
 		return;
 	flag = 0;
 
-	stopMusic();
-	loadMusic("boogie2");
-	playMusic();
+	_vm->_midiPlayer->play("boogie2");
 
 	return;
 }

Modified: scummvm/trunk/engines/parallaction/intro.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/intro.cpp	2007-02-21 20:57:10 UTC (rev 25773)
+++ scummvm/trunk/engines/parallaction/intro.cpp	2007-02-21 21:42:37 UTC (rev 25774)
@@ -124,9 +124,7 @@
 
 void _c_startIntro(void *parm) {
 	_rightHandAnim = findAnimation("righthand");
-	stopMusic();
-	loadMusic("intro");
-	playMusic();
+	_vm->_midiPlayer->play("intro");
 	_engineFlags |= kEngineMouse;
 
 	return;

Modified: scummvm/trunk/engines/parallaction/location.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/location.cpp	2007-02-21 20:57:10 UTC (rev 25773)
+++ scummvm/trunk/engines/parallaction/location.cpp	2007-02-21 21:42:37 UTC (rev 25774)
@@ -333,23 +333,19 @@
 //	printf("changeLocation('%s')", location);
 	if (_musicData1 != 0) {
 		if (!scumm_stricmp(_characterName, "dino"))
-			loadMusic("dino");
+			_vm->_midiPlayer->play("dino");
+		else if (!scumm_stricmp(_characterName, "donna"))
+			_vm->_midiPlayer->play("donna");
 		else
-		if (!scumm_stricmp(_characterName, "donna"))
-			loadMusic("donna");
-		else
-			loadMusic("nuts");
+			_vm->_midiPlayer->play("nuts");
 
-		playMusic();
 		_musicData1 = 0;
 
 		debugC(2, kDebugLocation, "changeLocation: started character specific music");
 	}
 
 	if (!scumm_stricmp(location, "night") || !scumm_stricmp(location, "intsushi")) {
-		stopMusic();
-		loadMusic("soft");
-		playMusic();
+		_vm->_midiPlayer->play("soft");
 
 		debugC(2, kDebugLocation, "changeLocation: started music 'soft'");
 	}
@@ -362,7 +358,7 @@
 		!scumm_stricmp(location, "endtgz") ||
 		!scumm_stricmp(location, "common")) {
 
-		stopMusic();
+		_vm->_midiPlayer->stop();
 		_musicData1 = 1;
 
 		debugC(2, kDebugLocation, "changeLocation: music stopped");

Modified: scummvm/trunk/engines/parallaction/menu.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/menu.cpp	2007-02-21 20:57:10 UTC (rev 25773)
+++ scummvm/trunk/engines/parallaction/menu.cpp	2007-02-21 21:42:37 UTC (rev 25774)
@@ -313,7 +313,7 @@
 	v14._height = BLOCK_HEIGHT;
 
 	_engine->changeCursor(kCursorArrow);
-	stopMusic();
+	_vm->_midiPlayer->stop();
 	_vm->_graphics->_proportionalFont = false;
 
 	_vm->_graphics->loadExternalCnv("slidecnv", &Graphics::_font);

Modified: scummvm/trunk/engines/parallaction/music.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/music.cpp	2007-02-21 20:57:10 UTC (rev 25773)
+++ scummvm/trunk/engines/parallaction/music.cpp	2007-02-21 21:42:37 UTC (rev 25774)
@@ -20,69 +20,35 @@
  *
  */
 
+#include "common/stdafx.h"
 #include "common/file.h"
 #include "parallaction/parallaction.h"
 
-namespace Parallaction {
+#include "common/stream.h"
 
-// NOTE: these two guys are never changed.
-static int16 _musicFlag2 = 1;
-static int16 _musicFlag1 = 1;
+#include "sound/midiparser.h"
 
-static bool _allocated = false;
-static bool _playing = false;
-// UNUSED
-// static char byte_14D22[10] = { 0 };
-static const char *_musicFilesNames[] = { "intro", "dino", "donna", "nuts", "soft", "boogie2" };
-static uint16 _musicFilesSizes[] = { 18805, 5486, 6195, 13006, 15818, 7507 };
-static byte *_musicBits = NULL;
+#include "parallaction/music.h"
 
-// TODO
-// move this into a proper midi driver and decode the numeric commands
-void _music_command(const void*, const void*, const void*, const void*) {
 
-}
+namespace Parallaction {
 
-void stopMusic() {
+MidiPlayer::MidiPlayer(MidiDriver *driver)
+	: _driver(driver), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _masterVolume(0) {
+	assert(_driver);
+	memset(_channelsTable, 0, sizeof(_channelsTable));
+	memset(_channelsVolume, 0, sizeof(_channelsVolume));
 
-	if (_musicFlag1 == 0 && _musicFlag2 == 0) return;
-	if (_playing == false) return;
-	if (_allocated == false) return;
-
-	_music_command((const void*)4, (const void*)0, (const void*)0, (const void*)0);     // stop
-	_music_command((const void*)5, (const void*)0, (const void*)0, (const void*)0);     // reset timer
-
-	memFree(_musicBits);
-
-	_allocated = false;
-	_playing = false;
-
-	return;
+	open();
 }
 
-void playMusic() {
-
-	if (_musicFlag1 == 0 && _musicFlag2 == 0) return;
-	if (_playing == true) return;
-	if (_allocated == false) return;
-
-	_music_command(0, 0, 0, 0);     // init driver
-	_music_command((const void*)1, 0, 0, 0);     // init timer
-	_music_command((const void*)17, (const void*)1, 0, 0);    // set source segment
-	_music_command((const void*)7, (const void*)1, 0, 0);     // set source offset and do SOMETHING
-
-	// FIXME: casting pointer to uint32
-	_music_command((const void*)2, (const void*)_musicBits, 0, 0);    // play
-
-	_playing = true;
-
-	return;
+MidiPlayer::~MidiPlayer() {
+	close();
 }
 
-void loadMusic(const char *filename) {
+void MidiPlayer::play(const char *filename) {
+	stop();
 
-	uint16 _di = 0;
-
 	if (!scumm_strnicmp(_location, "museo", 5)) return;
 	if (!scumm_strnicmp(_location, "intgrottadopo", 13)) return;
 	if (!scumm_strnicmp(_location, "caveau", 6)) return;
@@ -90,20 +56,6 @@
 	if (!scumm_strnicmp(_location, "plaza1", 6)) return;
 	if (!scumm_strnicmp(_location, "endtgz", 6)) return;
 
-	if (_musicFlag1 == 0 && _musicFlag2 == 0) return;
-	if (_allocated == true) return;
-
-//  UNUSED
-//	strcpy(byte_14D22, filename);
-
-	for (uint16 _si = 0; _si < 6; _si++) {
-		if (!strcmp(filename, _musicFilesNames[_si])) {
-			_di = _musicFilesSizes[_si];
-		}
-	}
-
-	if (_di == 0 ) return;
-
 	char path[PATH_LEN];
 	sprintf(path, "%s.mid", filename);
 
@@ -112,15 +64,120 @@
 	if (!stream.open(path))
 		return;
 
-	_musicBits = (byte*)memAlloc(_di);
-	if (!_musicBits) return;
+	int size = stream.size();
 
-	stream.read(_musicBits, _di);
-	stream.close();
+	_midiData = (uint8 *)malloc(size);
+	if (_midiData) {
+		stream.read(_midiData, size);
+		_mutex.lock();
+		_parser->loadMusic(_midiData, size);
+		_parser->setTrack(0);
+		_isLooping = true;
+		_isPlaying = true;
+		_mutex.unlock();
+	}
+}
 
-	_allocated = true;
+void MidiPlayer::stop() {
+	_mutex.lock();
+	if (_isPlaying) {
+		_isPlaying = false;
+		_parser->unloadMusic();
+		free(_midiData);
+		_midiData = 0;
+	}
+	_mutex.unlock();
+}
 
-	return;
+void MidiPlayer::updateTimer() {
+	_mutex.lock();
+	if (_isPlaying) {
+		_parser->onTimer();
+	}
+	_mutex.unlock();
 }
 
+void MidiPlayer::adjustVolume(int diff) {
+	setVolume(_masterVolume + diff);
+}
+
+void MidiPlayer::setVolume(int volume) {
+	_masterVolume = CLIP(volume, 0, 255);
+	_mutex.lock();
+	for (int i = 0; i < NUM_CHANNELS; ++i) {
+		if (_channelsTable[i]) {
+			_channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255);
+		}
+	}
+	_mutex.unlock();
+}
+
+int MidiPlayer::open() {
+	int ret = _driver->open();
+	if (ret == 0) {
+		_parser = MidiParser::createParser_SMF();
+		_parser->setMidiDriver(this);
+		_parser->setTimerRate(_driver->getBaseTempo());
+		_driver->setTimerCallback(this, &timerCallback);
+	}
+	return ret;
+}
+
+void MidiPlayer::close() {
+	stop();
+	_mutex.lock();
+	_driver->setTimerCallback(NULL, NULL);
+	_driver->close();
+	_driver = 0;
+	_parser->setMidiDriver(NULL);
+	delete _parser;
+	_mutex.unlock();
+}
+
+void MidiPlayer::send(uint32 b) {
+	byte volume, ch = (byte)(b & 0xF);
+	switch (b & 0xFFF0) {
+	case 0x07B0: // volume change
+		volume = (byte)((b >> 16) & 0x7F);
+		_channelsVolume[ch] = volume;
+		volume = volume * _masterVolume / 255;
+		b = (b & 0xFF00FFFF) | (volume << 16);
+		break;
+	case 0x7BB0: // all notes off
+		if (!_channelsTable[ch]) {
+			// channel not yet allocated, no need to send the event
+			return;
+		}
+		break;
+	}
+
+	if (!_channelsTable[ch]) {
+		_channelsTable[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
+	}
+	if (_channelsTable[ch]) {
+		_channelsTable[ch]->send(b);
+	}
+}
+
+void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) {
+	switch (type) {
+	case 0x2F: // end of Track
+		if (_isLooping) {
+			_parser->jumpToTick(0);
+		} else {
+			stop();
+		}
+		break;
+	default:
+//		warning("Unhandled meta event: %02x", type);
+		break;
+	}
+}
+
+void MidiPlayer::timerCallback(void *p) {
+	MidiPlayer *player = (MidiPlayer *)p;
+
+	player->updateTimer();
+}
+
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/music.h
===================================================================
--- scummvm/trunk/engines/parallaction/music.h	2007-02-21 20:57:10 UTC (rev 25773)
+++ scummvm/trunk/engines/parallaction/music.h	2007-02-21 21:42:37 UTC (rev 25774)
@@ -23,12 +23,58 @@
 #ifndef PARALLACTION_MUSIC_H
 #define PARALLACTION_MUSIC_H
 
+#include "common/util.h"
+#include "common/mutex.h"
+
+#include "sound/mididrv.h"
+
+class MidiParser;
+
 namespace Parallaction {
 
-void stopMusic();
-void playMusic();
-void loadMusic(const char *filename);
+class MidiPlayer : public MidiDriver {
+public:
 
+	enum {
+		NUM_CHANNELS = 16
+	};
+
+	MidiPlayer(MidiDriver *driver);
+	~MidiPlayer();
+
+	void play(const char *filename);
+	void stop();
+	void updateTimer();
+	void adjustVolume(int diff);
+	void setVolume(int volume);
+	int getVolume() const { return _masterVolume; }
+	void setLooping(bool loop) { _isLooping = loop; }
+
+	// MidiDriver interface
+	int open();
+	void close();
+	void send(uint32 b);
+	void metaEvent(byte type, byte *data, uint16 length);
+	void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { }
+	uint32 getBaseTempo() { return _driver ? _driver->getBaseTempo() : 0; }
+	MidiChannel *allocateChannel() { return 0; }
+	MidiChannel *getPercussionChannel() { return 0; }
+
+private:
+
+	static void timerCallback(void *p);
+
+	MidiDriver *_driver;
+	MidiParser *_parser;
+	uint8 *_midiData;
+	bool _isLooping;
+	bool _isPlaying;
+	int _masterVolume;
+	MidiChannel *_channelsTable[NUM_CHANNELS];
+	uint8 _channelsVolume[NUM_CHANNELS];
+	Common::Mutex _mutex;
+};
+
 } // namespace Parallaction
 
 #endif

Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp	2007-02-21 20:57:10 UTC (rev 25773)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp	2007-02-21 21:42:37 UTC (rev 25774)
@@ -20,6 +20,15 @@
  *
  */
 
+#include "common/stdafx.h"
+
+#include "common/util.h"
+#include "common/file.h"
+#include "common/config-manager.h"
+
+#include "sound/mididrv.h"
+#include "sound/mixer.h"
+
 #include "parallaction/parallaction.h"
 #include "parallaction/menu.h"
 #include "parallaction/parser.h"
@@ -29,9 +38,6 @@
 #include "parallaction/graphics.h"
 #include "parallaction/zone.h"
 
-#include "common/util.h"
-#include "common/file.h"
-#include "common/config-manager.h"
 
 namespace Parallaction {
 
@@ -170,6 +176,7 @@
 	_musicData1 = 0;
 	strcpy(_characterName1, "null");
 
+	_midiPlayer = 0;
 
 	_baseTime = 0;
 
@@ -195,7 +202,7 @@
 
 
 Parallaction::~Parallaction() {
-
+	delete _midiPlayer;
 }
 
 
@@ -270,7 +277,12 @@
 	addNode(&_animations, &_yourself._zone._node);
 	_graphics = new Graphics(this);
 
+	int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
+	MidiDriver *driver = MidiDriver::createMidi(midiDriver);
+	_midiPlayer = new MidiPlayer(driver);
 
+	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+
 	return 0;
 }
 
@@ -856,19 +868,14 @@
 
 			refreshInventory(name);
 
-			stopMusic();
-
 			if (scumm_stricmp(name, "night") && scumm_stricmp(name, "intsushi")) {
 				if (!scumm_stricmp(name, "dino") || !scumm_stricmp(name, "minidino")) {
-					loadMusic("dino");
-				} else
-				if (!scumm_stricmp(name, "donna") || !scumm_stricmp(name, "minidonna")) {
-					loadMusic("donna");
+					_midiPlayer->play("dino");
+				} else if (!scumm_stricmp(name, "donna") || !scumm_stricmp(name, "minidonna")) {
+					_midiPlayer->play("donna");
 				} else {
-					loadMusic("nuts");
+					_midiPlayer->play("nuts");
 				}
-
-				playMusic();
 			}
 
 		}

Modified: scummvm/trunk/engines/parallaction/parallaction.h
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.h	2007-02-21 20:57:10 UTC (rev 25773)
+++ scummvm/trunk/engines/parallaction/parallaction.h	2007-02-21 21:42:37 UTC (rev 25774)
@@ -212,6 +212,7 @@
 
 class Graphics;
 class Menu;
+class MidiPlayer;
 
 class Parallaction : public Engine {
 
@@ -256,6 +257,8 @@
 
 public:
 
+	MidiPlayer *_midiPlayer;
+
 	Graphics*	_graphics;
 	Menu*	_menu;
 	char	_characterName[30];


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