[Scummvm-cvs-logs] SF.net SVN: scummvm:[45298] scummvm/trunk/engines/draci

spalek at users.sourceforge.net spalek at users.sourceforge.net
Wed Oct 21 10:42:03 CEST 2009


Revision: 45298
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45298&view=rev
Author:   spalek
Date:     2009-10-21 08:41:57 +0000 (Wed, 21 Oct 2009)

Log Message:
-----------
Enabled music.

Several TODO's added.

Modified Paths:
--------------
    scummvm/trunk/engines/draci/draci.cpp
    scummvm/trunk/engines/draci/draci.h
    scummvm/trunk/engines/draci/game.cpp
    scummvm/trunk/engines/draci/module.mk

Added Paths:
-----------
    scummvm/trunk/engines/draci/music.cpp
    scummvm/trunk/engines/draci/music.h

Modified: scummvm/trunk/engines/draci/draci.cpp
===================================================================
--- scummvm/trunk/engines/draci/draci.cpp	2009-10-21 08:28:39 UTC (rev 45297)
+++ scummvm/trunk/engines/draci/draci.cpp	2009-10-21 08:41:57 UTC (rev 45298)
@@ -61,6 +61,7 @@
 const char *stringsPath = "RETEZCE.DFW";
 const char *soundsPath = "CD2.SAM";
 const char *dubbingPath = "CD.SAM";
+const char *musicPathMask = "HUDBA%d.MID";
 
 const uint kSoundsFrequency = 13000;
 const uint kDubbingFrequency = 22000;
@@ -117,6 +118,18 @@
 	_dubbingArchive = new SoundArchive(dubbingPath, kDubbingFrequency);
 	_sound = new Sound(_mixer);
 
+	int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
+	bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
+	//bool adlib = (midiDriver == MD_ADLIB);
+
+	_midiDriver = MidiDriver::createMidi(midiDriver);
+	if (native_mt32)
+		_midiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+
+	_music = new MusicPlayer(_midiDriver, musicPathMask);
+	_music->setNativeMT32(native_mt32);
+	//_music->setAdlib(adlib);
+
 	// Load the game's fonts
 	_smallFont = new Font(kFontSmall);
 	_bigFont = new Font(kFontBig);
@@ -303,6 +316,8 @@
 	delete _soundsArchive;
 	delete _dubbingArchive;
 	delete _sound;
+	delete _music;
+	delete _midiDriver;
 
 	// Remove all of our debug levels here
 	Common::clearAllDebugChannels();
@@ -332,10 +347,12 @@
 		_anims->pauseAnimations();
 		_sound->pauseSound();
 		_sound->pauseVoice();
+		_music->pause();
 	} else {
 		_anims->unpauseAnimations();
 		_sound->resumeSound();
 		_sound->resumeVoice();
+		_music->resume();
 
 		// Adjust engine start time
 		const int delta = _system->getMillis() - _pauseStartTime;
@@ -349,6 +366,7 @@
 	Engine::syncSoundSettings();
 
 	_sound->setVolume();
+	_music->setVolume(ConfMan.getInt("music_volume"));
 }
 
 const char *DraciEngine::getSavegameFile(int saveGameIdx) {

Modified: scummvm/trunk/engines/draci/draci.h
===================================================================
--- scummvm/trunk/engines/draci/draci.h	2009-10-21 08:28:39 UTC (rev 45297)
+++ scummvm/trunk/engines/draci/draci.h	2009-10-21 08:41:57 UTC (rev 45298)
@@ -29,6 +29,7 @@
 #include "common/system.h"
 #include "engines/engine.h"
 #include "engines/advancedDetector.h"
+#include "sound/mididrv.h"
 
 #include "draci/game.h"
 #include "draci/mouse.h"
@@ -38,6 +39,7 @@
 #include "draci/barchive.h"
 #include "draci/animation.h"
 #include "draci/sound.h"
+#include "draci/music.h"
 
 namespace Draci {
 
@@ -67,6 +69,8 @@
 	Script *_script;
 	AnimationManager *_anims;
 	Sound *_sound;
+	MusicPlayer *_music;
+	MidiDriver *_midiDriver;
 
 	Font *_smallFont;
 	Font *_bigFont;

Modified: scummvm/trunk/engines/draci/game.cpp
===================================================================
--- scummvm/trunk/engines/draci/game.cpp	2009-10-21 08:28:39 UTC (rev 45297)
+++ scummvm/trunk/engines/draci/game.cpp	2009-10-21 08:41:57 UTC (rev 45298)
@@ -1123,6 +1123,12 @@
 
 	Animation *map = _vm->_anims->addAnimation(kWalkingMapOverlay, 255, false);
 	map->addFrame(ov, NULL);
+
+	if (_currentRoom._music) {
+		_vm->_music->playSMF(_currentRoom._music, true);
+	} else {
+		_vm->_music->stop();
+	}
 }
 
 int Game::loadAnimation(uint animNum, uint z) {

Modified: scummvm/trunk/engines/draci/module.mk
===================================================================
--- scummvm/trunk/engines/draci/module.mk	2009-10-21 08:28:39 UTC (rev 45297)
+++ scummvm/trunk/engines/draci/module.mk	2009-10-21 08:41:57 UTC (rev 45298)
@@ -8,6 +8,7 @@
 	font.o \
 	saveload.o \
 	sound.o \
+	music.o \
 	sprite.o \
 	screen.o \
 	surface.o \

Added: scummvm/trunk/engines/draci/music.cpp
===================================================================
--- scummvm/trunk/engines/draci/music.cpp	                        (rev 0)
+++ scummvm/trunk/engines/draci/music.cpp	2009-10-21 08:41:57 UTC (rev 45298)
@@ -0,0 +1,213 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/made/music.cpp $
+ * $Id: music.cpp 35843 2009-01-13 10:11:52Z thebluegr $
+ *
+ */
+
+// FIXME: This code is taken from SAGA and needs more work (e.g. setVolume).
+
+// MIDI and digital music class
+
+#include "sound/audiostream.h"
+#include "sound/mididrv.h"
+#include "sound/midiparser.h"
+#include "common/config-manager.h"
+#include "common/file.h"
+
+#include "draci/draci.h"
+#include "draci/music.h"
+
+namespace Draci {
+
+MusicPlayer::MusicPlayer(MidiDriver *driver, const char *pathMask) : _parser(0), _driver(driver), _pathMask(pathMask), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false) {
+	memset(_channel, 0, sizeof(_channel));
+	_masterVolume = 0;
+	this->open();
+	_smfParser = MidiParser::createParser_SMF();
+	_midiMusicData = NULL;
+}
+
+MusicPlayer::~MusicPlayer() {
+	_driver->setTimerCallback(NULL, NULL);
+	stop();
+	this->close();
+	_smfParser->setMidiDriver(NULL);
+	delete _smfParser;
+	delete _midiMusicData;
+}
+
+void MusicPlayer::setVolume(int volume) {
+	volume = CLIP(volume, 0, 255);
+
+	if (_masterVolume == volume)
+		return;
+
+	_masterVolume = volume;
+
+	Common::StackLock lock(_mutex);
+
+	for (int i = 0; i < 16; ++i) {
+		if (_channel[i]) {
+			_channel[i]->volume(_channelVolume[i] * _masterVolume / 255);
+		}
+	}
+}
+
+int MusicPlayer::open() {
+	// Don't ever call open without first setting the output driver!
+	if (!_driver)
+		return 255;
+
+	int ret = _driver->open();
+	if (ret)
+		return ret;
+
+	_driver->setTimerCallback(this, &onTimer);
+	return 0;
+}
+
+void MusicPlayer::close() {
+	stop();
+	if (_driver)
+		_driver->close();
+	_driver = 0;
+}
+
+void MusicPlayer::send(uint32 b) {
+	if (_passThrough) {
+		_driver->send(b);
+		return;
+	}
+
+	byte channel = (byte)(b & 0x0F);
+	if ((b & 0xFFF0) == 0x07B0) {
+		// Adjust volume changes by master volume
+		byte volume = (byte)((b >> 16) & 0x7F);
+		_channelVolume[channel] = volume;
+		volume = volume * _masterVolume / 255;
+		b = (b & 0xFF00FFFF) | (volume << 16);
+	} else if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
+		b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
+	}
+	else if ((b & 0xFFF0) == 0x007BB0) {
+		//Only respond to All Notes Off if this channel
+		//has currently been allocated
+		if (_channel[b & 0x0F])
+			return;
+	}
+
+	if (!_channel[channel])
+		_channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
+
+	if (_channel[channel])
+		_channel[channel]->send(b);
+}
+
+void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) {
+
+	switch (type) {
+	case 0x2F:	// End of Track
+		if (_looping)
+			_parser->jumpToTick(0);
+		else
+			stop();
+		break;
+	default:
+		//warning("Unhandled meta event: %02x", type);
+		break;
+	}
+}
+
+void MusicPlayer::onTimer(void *refCon) {
+	MusicPlayer *music = (MusicPlayer *)refCon;
+	Common::StackLock lock(music->_mutex);
+
+	if (music->_isPlaying)
+		music->_parser->onTimer();
+}
+
+void MusicPlayer::playSMF(int track, bool loop) {
+	if (_isPlaying && track == _track)
+		return;
+
+	stop();
+
+	_isGM = true;
+
+	debugC(2, kDraciSoundDebugLevel, "Playing track %d", track);
+
+	// Load MIDI resource data
+	Common::File musicFile;
+	char musicFileName[40];
+	sprintf(musicFileName, _pathMask.c_str(), track);
+	musicFile.open(musicFileName);
+	int midiMusicSize = musicFile.size();
+	delete _midiMusicData;
+	_midiMusicData = new byte[midiMusicSize];
+	musicFile.read(_midiMusicData, midiMusicSize);
+	musicFile.close();
+
+	if (_smfParser->loadMusic(_midiMusicData, midiMusicSize)) {
+		MidiParser *parser = _smfParser;
+		parser->setTrack(0);
+		parser->setMidiDriver(this);
+		parser->setTimerRate(getBaseTempo());
+		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+
+		_parser = parser;
+
+		setVolume(127);
+
+		_looping = loop;
+		_isPlaying = true;
+		_track = track;
+	}
+}
+
+void MusicPlayer::stop() {
+	Common::StackLock lock(_mutex);
+
+	_isPlaying = false;
+	if (_parser) {
+		_parser->unloadMusic();
+		_parser = NULL;
+	}
+}
+
+void MusicPlayer::pause() {
+	setVolume(-1);
+	_isPlaying = false;
+}
+
+void MusicPlayer::resume() {
+	setVolume(127);
+	_isPlaying = true;
+}
+
+// TODO:
+// - volume support
+// - bindings to GPL2 scripting
+// - load cmf.ins
+// - enable Adlib
+// - resuming after load
+
+} // End of namespace Draci


Property changes on: scummvm/trunk/engines/draci/music.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Added: scummvm/trunk/engines/draci/music.h
===================================================================
--- scummvm/trunk/engines/draci/music.h	                        (rev 0)
+++ scummvm/trunk/engines/draci/music.h	2009-10-21 08:41:57 UTC (rev 45298)
@@ -0,0 +1,101 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/made/music.h $
+ * $Id: music.h 31873 2008-05-05 12:51:50Z john_doe $
+ *
+ */
+
+// Music class
+
+#ifndef DRACI_MUSIC_H
+#define DRACI_MUSIC_H
+
+#include "sound/mididrv.h"
+#include "sound/midiparser.h"
+#include "common/mutex.h"
+
+namespace Draci {
+
+// Taken from MADE, which took it from SAGA.
+
+class MusicPlayer : public MidiDriver {
+public:
+	MusicPlayer(MidiDriver *driver, const char *pathMask);
+	~MusicPlayer();
+
+	bool isPlaying() { return _isPlaying; }
+	void setPlaying(bool playing) { _isPlaying = playing; }
+
+	void setVolume(int volume);
+	int getVolume() { return _masterVolume; }
+
+	void setNativeMT32(bool b) { _nativeMT32 = b; }
+	bool hasNativeMT32() { return _nativeMT32; }
+	void playSMF(int track, bool loop);
+	void stop();
+	void pause();
+	void resume();
+	void setLoop(bool loop) { _looping = loop; }
+	void setPassThrough(bool b) { _passThrough = b; }
+
+	void setGM(bool isGM) { _isGM = isGM; }
+
+	//MidiDriver interface implementation
+	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(void)	{ return _driver ? _driver->getBaseTempo() : 0; }
+
+	//Channel allocation functions
+	MidiChannel *allocateChannel()		{ return 0; }
+	MidiChannel *getPercussionChannel()	{ return 0; }
+
+	MidiParser *_parser;
+	Common::Mutex _mutex;
+
+protected:
+
+	static void onTimer(void *data);
+
+	MidiChannel *_channel[16];
+	MidiDriver *_driver;
+	MidiParser *_smfParser;
+	Common::String _pathMask;
+	byte _channelVolume[16];
+	bool _nativeMT32;
+	bool _isGM;
+	bool _passThrough;
+
+	bool _isPlaying;
+	bool _looping;
+	byte _masterVolume;
+	int _track;
+
+	byte *_midiMusicData;
+};
+
+} // End of namespace Draci
+
+#endif


Property changes on: scummvm/trunk/engines/draci/music.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native


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