[Scummvm-cvs-logs] SF.net SVN: scummvm: [31682] scummvm/trunk/engines/made

john_doe at users.sourceforge.net john_doe at users.sourceforge.net
Thu Apr 24 01:22:03 CEST 2008


Revision: 31682
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31682&view=rev
Author:   john_doe
Date:     2008-04-23 16:22:02 -0700 (Wed, 23 Apr 2008)

Log Message:
-----------
Added (early) midi player code.
Added "screen flash" effect.
Implemented opcodes:
- o1_PLAYMUS
- o1_STOPMUS
- o1_ISMUS
- o1_FLASH
- o1_LOADSND
- o1_LOADMUS

Modified Paths:
--------------
    scummvm/trunk/engines/made/made.cpp
    scummvm/trunk/engines/made/made.h
    scummvm/trunk/engines/made/module.mk
    scummvm/trunk/engines/made/resource.cpp
    scummvm/trunk/engines/made/resource.h
    scummvm/trunk/engines/made/screen.cpp
    scummvm/trunk/engines/made/screen.h
    scummvm/trunk/engines/made/scriptfuncs.cpp

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

Modified: scummvm/trunk/engines/made/made.cpp
===================================================================
--- scummvm/trunk/engines/made/made.cpp	2008-04-23 22:53:19 UTC (rev 31681)
+++ scummvm/trunk/engines/made/made.cpp	2008-04-23 23:22:02 UTC (rev 31682)
@@ -44,6 +44,7 @@
 #include "made/screen.h"
 #include "made/script.h"
 #include "made/sound.h"
+#include "made/music.h"
 #include "made/redreader.h"
 
 namespace Made {
@@ -88,6 +89,24 @@
 	_dat = new GameDatabase();
 	_script = new ScriptInterpreter(this);
 
+	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 *driver = MidiDriver::createMidi(midiDriver);
+	if (native_mt32)
+		driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+
+	_music = new Music(driver, _musicVolume);
+	_music->setNativeMT32(native_mt32);
+	_music->setAdlib(adlib);
+
+	_musicVolume = ConfMan.getInt("music_volume");
+
+	if (!_musicVolume) {
+		debug(1, "Music disabled.");
+	}
+
 }
 
 MadeEngine::~MadeEngine() {
@@ -97,6 +116,7 @@
 	delete _screen;
 	delete _dat;
 	delete _script;
+	delete _music;
 }
 
 int MadeEngine::init() {

Modified: scummvm/trunk/engines/made/made.h
===================================================================
--- scummvm/trunk/engines/made/made.h	2008-04-23 22:53:19 UTC (rev 31681)
+++ scummvm/trunk/engines/made/made.h	2008-04-23 23:22:02 UTC (rev 31682)
@@ -61,6 +61,7 @@
 class Screen;
 class ScriptInterpreter;
 class GameDatabase;
+class Music;
 
 class MadeEngine : public ::Engine {
 	int _gameId;
@@ -93,10 +94,12 @@
 	Screen *_screen;
 	GameDatabase *_dat;
 	ScriptInterpreter *_script;
+	Music *_music;
 
 	int _eventMouseX, _eventMouseY;
+	uint16 _eventKey;
 	int _soundRate;
-	uint16 _eventKey;
+	int _musicVolume;
 
 	int32 _timers[50];
 	int16 getTimer(int16 timerNum);

Modified: scummvm/trunk/engines/made/module.mk
===================================================================
--- scummvm/trunk/engines/made/module.mk	2008-04-23 22:53:19 UTC (rev 31681)
+++ scummvm/trunk/engines/made/module.mk	2008-04-23 23:22:02 UTC (rev 31682)
@@ -5,6 +5,7 @@
 	detection.o \
 	graphics.o \
 	made.o \
+	music.o \
 	pmvplayer.o \
 	redreader.o \
 	resource.o \

Added: scummvm/trunk/engines/made/music.cpp
===================================================================
--- scummvm/trunk/engines/made/music.cpp	                        (rev 0)
+++ scummvm/trunk/engines/made/music.cpp	2008-04-23 23:22:02 UTC (rev 31682)
@@ -0,0 +1,274 @@
+/* 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$
+ * $Id$
+ *
+ */
+
+// 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 "made/music.h"
+
+namespace Made {
+
+MusicPlayer::MusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false) {
+	memset(_channel, 0, sizeof(_channel));
+	_masterVolume = 0;
+	this->open();
+}
+
+MusicPlayer::~MusicPlayer() {
+	_driver->setTimerCallback(NULL, NULL);
+	stopMusic();
+	this->close();
+}
+
+void MusicPlayer::setVolume(int volume) {
+	volume = CLIP(volume, 0, 255);
+
+	if (_masterVolume == volume)
+		return;
+
+	_masterVolume = volume;
+
+	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() {
+	stopMusic();
+	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
+			stopMusic();
+		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::playMusic() {
+	_isPlaying = true;
+}
+
+void MusicPlayer::stopMusic() {
+	Common::StackLock lock(_mutex);
+
+	_isPlaying = false;
+	if (_parser) {
+		_parser->unloadMusic();
+		_parser = NULL;
+	}
+}
+
+Music::Music(MidiDriver *driver, int enabled) : _enabled(enabled), _adlib(false) {
+	_player = new MusicPlayer(driver);
+	_currentVolume = 0;
+
+	xmidiParser = MidiParser::createParser_XMIDI();
+
+	_songTableLen = 0;
+	_songTable = 0;
+
+	_midiMusicData = NULL;
+}
+
+Music::~Music() {
+	delete _player;
+	xmidiParser->setMidiDriver(NULL);
+	delete xmidiParser;
+
+	free(_songTable);
+	if (_midiMusicData)
+		delete[] _midiMusicData;
+}
+
+void Music::setVolume(int volume, int time) {
+	_targetVolume = volume * 2; // ScummVM has different volume scale
+	_currentVolumePercent = 0;
+
+	if (volume == -1) // Set Full volume
+		volume = 255;
+
+	if (time == 1) {
+		_player->setVolume(volume);
+		_currentVolume = volume;
+		return;
+	}
+
+}
+
+bool Music::isPlaying() {
+	return _player->isPlaying();
+}
+
+void Music::play(XmidiResource *midiResource, MusicFlags flags) {
+	MidiParser *parser;
+	byte *resourceData;
+	size_t resourceSize;
+
+	debug(2, "Music::play %d", flags);
+
+	if (!_enabled) {
+		return;
+	}
+
+	if (isPlaying()) {
+		return;
+	}
+
+	_player->stopMusic();
+
+	/*
+	if (!_vm->_musicVolume) {
+		return;
+	}
+	*/
+
+	if (flags == MUSIC_DEFAULT) {
+		flags = MUSIC_NORMAL;
+	}
+
+	// Load MIDI/XMI resource data
+
+	_player->setGM(true);
+
+	resourceSize = midiResource->getSize();
+	resourceData = new byte[resourceSize];
+	memcpy(resourceData, midiResource->getData(), resourceSize);
+
+	if (resourceSize < 4) {
+		error("Music::play() wrong music resource size");
+	}
+
+	if (xmidiParser->loadMusic(resourceData, resourceSize)) {
+		//_player->setGM(false);
+		parser = xmidiParser;
+	}
+
+	parser->setTrack(0);
+	parser->setMidiDriver(_player);
+	parser->setTimerRate(_player->getBaseTempo());
+	parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+
+	_player->_parser = parser;
+	//setVolume(_vm->_musicVolume == 10 ? 255 : _vm->_musicVolume * 25);
+	setVolume(255);
+
+	if (flags & MUSIC_LOOP)
+		_player->setLoop(true);
+	else
+		_player->setLoop(false);
+
+	_player->playMusic();
+	if (_midiMusicData)
+		delete[] _midiMusicData;
+	_midiMusicData = resourceData;
+}
+
+void Music::pause(void) {
+	_player->setVolume(-1);
+	_player->setPlaying(false);
+}
+
+void Music::resume(void) {
+	//_player->setVolume(_vm->_musicVolume == 10 ? 255 : _vm->_musicVolume * 25);
+	setVolume(255);
+	_player->setPlaying(true);
+}
+
+void Music::stop(void) {
+	_player->stopMusic();
+}
+
+} // End of namespace Made


Property changes on: scummvm/trunk/engines/made/music.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/made/music.h
===================================================================
--- scummvm/trunk/engines/made/music.h	                        (rev 0)
+++ scummvm/trunk/engines/made/music.h	2008-04-23 23:22:02 UTC (rev 31682)
@@ -0,0 +1,150 @@
+/* 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$
+ * $Id$
+ *
+ */
+
+// Music class
+
+#ifndef MADE_MUSIC_H
+#define MADE_MUSIC_H
+
+#include "sound/audiocd.h"
+#include "sound/mididrv.h"
+#include "sound/midiparser.h"
+#include "sound/mp3.h"
+#include "sound/vorbis.h"
+#include "sound/flac.h"
+#include "common/mutex.h"
+
+#include "made/resource.h"
+
+namespace Made {
+
+enum MusicFlags {
+	MUSIC_NORMAL = 0,
+	MUSIC_LOOP = 0x0001,
+	MUSIC_DEFAULT = 0xffff
+};
+
+class MusicPlayer : public MidiDriver {
+public:
+	MusicPlayer(MidiDriver *driver);
+	~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 playMusic();
+	void stopMusic();
+	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;
+	byte _channelVolume[16];
+	bool _nativeMT32;
+	bool _isGM;
+	bool _passThrough;
+
+	bool _isPlaying;
+	bool _looping;
+	bool _randomLoop;
+	byte _masterVolume;
+
+	byte *_musicData;
+	uint16 *_buf;
+	size_t _musicDataSize;
+};
+
+class Music {
+public:
+
+	Music(MidiDriver *driver, int enabled);
+	~Music(void);
+	void setNativeMT32(bool b)	{ _player->setNativeMT32(b); }
+	bool hasNativeMT32()		{ return _player->hasNativeMT32(); }
+	void setAdlib(bool b)		{ _adlib = b; }
+	bool hasAdlib()			{ return _adlib; }
+	void setPassThrough(bool b)	{ _player->setPassThrough(b); }
+	bool isPlaying(void);
+
+	void play(XmidiResource *midiResource, MusicFlags flags = MUSIC_DEFAULT);
+	void pause(void);
+	void resume(void);
+	void stop(void);
+
+	void setVolume(int volume, int time = 1);
+	int getVolume() { return _currentVolume; }
+
+	int32 *_songTable;
+	int _songTableLen;
+
+private:
+
+	MusicPlayer *_player;
+	uint32 _trackNumber;
+
+	int _enabled;
+	bool _adlib;
+
+	int _targetVolume;
+	int _currentVolume;
+	int _currentVolumePercent;
+
+	MidiParser *xmidiParser;
+
+	byte *_midiMusicData;
+
+};
+
+} // End of namespace Made
+
+#endif


Property changes on: scummvm/trunk/engines/made/music.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Modified: scummvm/trunk/engines/made/resource.cpp
===================================================================
--- scummvm/trunk/engines/made/resource.cpp	2008-04-23 22:53:19 UTC (rev 31681)
+++ scummvm/trunk/engines/made/resource.cpp	2008-04-23 23:22:02 UTC (rev 31682)
@@ -205,6 +205,22 @@
 		return NULL;
 }
 
+/* XmidiResource */
+
+XmidiResource::XmidiResource() : _data(NULL), _size(0) {
+}
+
+XmidiResource::~XmidiResource() {
+	if (_data)
+		delete[] _data;
+}
+
+void XmidiResource::load(byte *source, int size) {
+	_data = new byte[size];
+	_size = size;
+	memcpy(_data, source, size);
+}
+
 /* ProjectReader */
 
 ProjectReader::ProjectReader() {
@@ -269,6 +285,10 @@
 	return createResource<MenuResource>(kResMENU, index);
 }
 
+XmidiResource *ProjectReader::getXmidi(int index) {
+	return createResource<XmidiResource>(kResXMID, index);
+}
+
 void ProjectReader::loadIndex(ResourceSlots *slots) {
 	_fd->readUint32LE(); // skip INDX
 	_fd->readUint32LE(); // skip index size

Modified: scummvm/trunk/engines/made/resource.h
===================================================================
--- scummvm/trunk/engines/made/resource.h	2008-04-23 22:53:19 UTC (rev 31681)
+++ scummvm/trunk/engines/made/resource.h	2008-04-23 23:22:02 UTC (rev 31682)
@@ -44,7 +44,8 @@
 	kResFLEX = MKID_BE('FLEX'),
 	kResSNDS = MKID_BE('SNDS'),
 	kResANIM = MKID_BE('ANIM'),
-	kResMENU = MKID_BE('MENU')
+	kResMENU = MKID_BE('MENU'),
+	kResXMID = MKID_BE('XMID')
 };
 
 struct ResourceSlot;
@@ -110,6 +111,18 @@
 	Common::Array<Common::String> _strings;
 };
 
+class XmidiResource : public Resource {
+public:
+	XmidiResource();
+	~XmidiResource();
+	void load(byte *source, int size);
+	byte *getData() const { return _data; }
+	int getSize() const { return _size; }
+protected:
+	byte *_data;
+	int _size;
+};
+
 struct ResourceSlot {
 	uint32 offs;
 	uint32 size;
@@ -133,6 +146,7 @@
 	AnimationResource *getAnimation(int index);
 	SoundResource *getSound(int index);
 	MenuResource *getMenu(int index);
+	XmidiResource *getXmidi(int index);
 
 	void freeResource(Resource *resource);
 

Modified: scummvm/trunk/engines/made/screen.cpp
===================================================================
--- scummvm/trunk/engines/made/screen.cpp	2008-04-23 22:53:19 UTC (rev 31681)
+++ scummvm/trunk/engines/made/screen.cpp	2008-04-23 23:22:02 UTC (rev 31682)
@@ -472,4 +472,20 @@
 
 }
 
+void Screen::flash(int flashCount) {
+	int palSize = _paletteColorCount * 3;
+	if (flashCount < 1)
+		flashCount = 1;
+	for (int i = 0; i < palSize; i++)
+		_fxPalette[i] = CLIP<byte>(255 - _palette[i], 0, 255);
+	while (flashCount--) {
+		setRGBPalette(_fxPalette, 0, _paletteColorCount);
+		_vm->_system->updateScreen();
+		_vm->_system->delayMillis(30);
+		setRGBPalette(_palette, 0, _paletteColorCount);
+		_vm->_system->updateScreen();
+		_vm->_system->delayMillis(30);
+	}
+}
+
 } // End of namespace Made

Modified: scummvm/trunk/engines/made/screen.h
===================================================================
--- scummvm/trunk/engines/made/screen.h	2008-04-23 22:53:19 UTC (rev 31681)
+++ scummvm/trunk/engines/made/screen.h	2008-04-23 23:22:02 UTC (rev 31682)
@@ -102,6 +102,7 @@
 	uint16 placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, int16 y, uint16 fontNum, int16 textColor, int16 outlineColor);
 	
 	void show();
+	void flash(int count);
 	
 	byte _screenPalette[256 * 4];
 
@@ -111,7 +112,7 @@
 	bool _screenLock;
 	bool _paletteLock;
 
-	byte _palette[768], _newPalette[768];
+	byte _palette[768], _newPalette[768], _fxPalette[768];
 	int _paletteColorCount, _oldPaletteColorCount;
 	bool _paletteInitialized, _needPalette;
 

Modified: scummvm/trunk/engines/made/scriptfuncs.cpp
===================================================================
--- scummvm/trunk/engines/made/scriptfuncs.cpp	2008-04-23 22:53:19 UTC (rev 31681)
+++ scummvm/trunk/engines/made/scriptfuncs.cpp	2008-04-23 23:22:02 UTC (rev 31682)
@@ -36,6 +36,7 @@
 #include "made/script.h"
 #include "made/pmvplayer.h"
 #include "made/scriptfuncs.h"
+#include "made/music.h"
 
 namespace Made {
 
@@ -288,15 +289,25 @@
 }
 
 int16 ScriptFunctionsRtz::o1_PLAYMUS(int16 argc, int16 *argv) {
+	int16 musicId = argv[0];
+	if (musicId > 0) {
+		XmidiResource *xmidi = _vm->_res->getXmidi(musicId);
+		_vm->_music->play(xmidi);
+		_vm->_res->freeResource(xmidi);
+	}
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_STOPMUS(int16 argc, int16 *argv) {
+	_vm->_music->stop();
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_ISMUS(int16 argc, int16 *argv) {
-	return 0;
+	if (_vm->_music->isPlaying())
+		return 1;
+	else
+		return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_TEXTPOS(int16 argc, int16 *argv) {
@@ -304,6 +315,7 @@
 }
 
 int16 ScriptFunctionsRtz::o1_FLASH(int16 argc, int16 *argv) {
+	_vm->_screen->flash(argv[0]);
 	return 0;
 }
 
@@ -536,10 +548,20 @@
 }
 
 int16 ScriptFunctionsRtz::o1_LOADSND(int16 argc, int16 *argv) {
+	SoundResource *sound = _vm->_res->getSound(argv[0]);
+	if (sound) {
+		_vm->_res->freeResource(sound);
+		return 1;
+	}
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_LOADMUS(int16 argc, int16 *argv) {
+	XmidiResource *xmidi = _vm->_res->getXmidi(argv[0]);
+	if (xmidi) {
+		_vm->_res->freeResource(xmidi);
+		return 1;
+	}
 	return 0;
 }
 


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