[Scummvm-git-logs] scummvm master -> e5bfead3458661140d17863ffe33af5f71638387

sev- sev at scummvm.org
Sun Feb 4 12:56:10 CET 2018


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
e5bfead345 SCUMM HE: Use Miles AdLib driver


Commit: e5bfead3458661140d17863ffe33af5f71638387
    https://github.com/scummvm/scummvm/commit/e5bfead3458661140d17863ffe33af5f71638387
Author: nukeykt (alexeytf2 at icloud.com)
Date: 2018-02-04T12:56:06+01:00

Commit Message:
SCUMM HE: Use Miles AdLib driver

Changed paths:
  A engines/scumm/players/player_he.cpp
  A engines/scumm/players/player_he.h
    audio/miles_adlib.cpp
    devtools/scumm-md5.txt
    engines/scumm/detection_tables.h
    engines/scumm/he/sound_he.cpp
    engines/scumm/module.mk
    engines/scumm/music.h
    engines/scumm/scumm-md5.h
    engines/scumm/scumm.cpp


diff --git a/audio/miles_adlib.cpp b/audio/miles_adlib.cpp
index 790e389..4bdb770 100644
--- a/audio/miles_adlib.cpp
+++ b/audio/miles_adlib.cpp
@@ -1035,6 +1035,15 @@ void MidiDriver_Miles_AdLib::pitchBendChange(byte midiChannel, byte parameter1,
 		return;
 	}
 	_midiChannels[midiChannel].currentPitchBender = parameter1 | (parameter2 << 7);
+	for (byte virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+		if (_virtualFmVoices[virtualFmVoice].inUse) {
+			// used
+			if (_virtualFmVoices[virtualFmVoice].actualMidiChannel == midiChannel) {
+				// by our current MIDI channel -> update
+				updatePhysicalFmVoice(virtualFmVoice, true, kMilesAdLibUpdateFlags_Reg_A0);
+			}
+		}
+	}
 }
 
 void MidiDriver_Miles_AdLib::setRegister(int reg, int value) {
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index ab32653..7e7d0ac 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -772,7 +772,7 @@ puttmoon	Putt-Putt Goes to the Moon
 	9c92eeaf517a31b7221ec2546ab669fd	-1	en	Windows	HE 70	-	-	khalek
 	3c4c471342bd95505a42334367d8f127	12161	ru	Windows	HE 70	-	-	sev
 
-	aa6a91b7f6f119d1b7b1f2a4c9e24d59	6233	en	DOS	-	Demo	-
+	aa6a91b7f6f119d1b7b1f2a4c9e24d59	6233	en	DOS	Demo	Demo	-
 	4af4a6b248103c1fe9edef619677f540	-1	en	Mac	-	Demo	-	khalek
 	9c143c5905055d5df7a0f014ab379aee	-1	en	Windows	HE 70	Demo	-	khalek
 
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 65891e0..ce8eecf 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -284,6 +284,7 @@ static const GameSettings gameVariantsTable[] = {
 	{"fbear", "HE 70", 0, GID_FBEAR, 6, 70, MDT_NONE,             GF_USE_KEY, Common::kPlatformWindows, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
 
 	{"puttmoon", "", 0, GID_PUTTMOON, 6, 62, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO1(GUIO_NOLAUNCHLOAD)},
+	{"puttmoon", "Demo", 0, GID_HEGAME, 6, 62, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO1(GUIO_NOLAUNCHLOAD)},
 	{"puttmoon", "HE 70", 0, GID_PUTTMOON, 6, 70, MDT_NONE,             GF_USE_KEY, Common::kPlatformWindows, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
 
 	{"puttputt", "HE 60", 0, GID_HEGAME,   6, 60, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO1(GUIO_NOLAUNCHLOAD)},
diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp
index 9da3641..07a81f5 100644
--- a/engines/scumm/he/sound_he.cpp
+++ b/engines/scumm/he/sound_he.cpp
@@ -765,6 +765,10 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags,
 			_vm->_imuse->stopSound(_currentMusic);
 			_currentMusic = soundID;
 			_vm->_imuse->startSoundWithNoteOffset(soundID, heOffset);
+		} else if (_vm->_musicEngine) {
+			_vm->_musicEngine->stopSound(_currentMusic);
+			_currentMusic = soundID;
+			_vm->_musicEngine->startSoundWithTrackID(soundID, heOffset);
 		}
 	}
 }
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index fee61ec..f5ba4ba 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -38,6 +38,7 @@ MODULE_OBJS := \
 	palette.o \
 	players/player_ad.o \
 	players/player_apple2.o \
+	players/player_he.o \
 	players/player_mac.o \
 	players/player_mod.o \
 	players/player_nes.o \
diff --git a/engines/scumm/music.h b/engines/scumm/music.h
index 9404ce7..06f45fe 100644
--- a/engines/scumm/music.h
+++ b/engines/scumm/music.h
@@ -55,6 +55,13 @@ public:
 	virtual void startSound(int sound) = 0;
 
 	/**
+	 * Start playing the sound with the given id and track id.
+	 * @param sound		the sound to start
+	 * @param track		the track to start
+	 */
+	virtual void startSoundWithTrackID(int sound, int track) { startSound(sound); }
+
+	/**
 	 * Stop playing the sound with the given id.
 	 * @param sound		the sound to stop
 	 */
diff --git a/engines/scumm/players/player_he.cpp b/engines/scumm/players/player_he.cpp
new file mode 100644
index 0000000..163f4f1
--- /dev/null
+++ b/engines/scumm/players/player_he.cpp
@@ -0,0 +1,243 @@
+/* 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.
+ *
+ */
+
+#ifdef ENABLE_HE
+
+#include "scumm/players/player_he.h"
+#include "scumm/scumm.h"
+#include "scumm/file.h"
+#include "audio/miles.h"
+#include "audio/midiparser.h"
+#include "audio/mixer.h"
+#include "common/memstream.h"
+
+namespace Scumm {
+Player_HE::Player_HE(ScummEngine *scumm) :
+	_vm(scumm),
+	_currentMusic(-1),
+	_bank(NULL),
+	_parser(NULL),
+	_midi(NULL),
+	_masterVolume(256) {
+
+	for (int chan = 0; chan < 16; chan++)
+		_channelVolume[chan] = 127;
+
+	loadAdLibBank();
+
+	Common::MemoryReadStream *bankStream = new Common::MemoryReadStream(_bank, _bankSize);
+
+	_midi = Audio::MidiDriver_Miles_AdLib_create("", "", bankStream);
+	if (!_midi) {
+		error("Player_HE::Player_HE: could not create midi driver");
+	}
+	if (_midi->open() != 0) {
+		error("Player_HE::Player_HE: could not open midi driver");
+	}
+}
+
+Player_HE::~Player_HE() {
+	if (_parser) {
+		_parser->stopPlaying();
+		delete _parser;
+		_parser = NULL;
+	}
+	if (_midi) {
+		_midi->setTimerCallback(0, 0);
+		_midi->close();
+		delete _midi;
+		_midi = NULL;
+	}
+	if (_bank) {
+		free(_bank);
+	}
+}
+
+void Player_HE::setMusicVolume(int vol) {
+	_masterVolume = vol;
+	for (int chan = 0; chan < 16; chan++)
+	{
+		byte volume = (_channelVolume[chan] * vol) / 256;
+		if (_midi)
+			_midi->send(0x07b0 | chan | (volume << 16));
+	}
+}
+
+void Player_HE::onTimer(void *data) {
+	Player_HE *player = (Player_HE*)data;
+	Common::StackLock lock(player->_mutex);
+	if (player->_parser)
+		player->_parser->onTimer();
+}
+
+void Player_HE::startSoundWithTrackID(int sound, int track) {
+	Common::StackLock lock(_mutex);
+	byte *ptr = _vm->getResourceAddress(rtSound, sound);
+	if (ptr == NULL)
+		return;
+
+	if (_parser) {
+		_parser->stopPlaying();
+		delete _parser;
+	}
+	_parser = MidiParser::createParser_XMIDI();
+	_parser->setMidiDriver(this);
+	_parser->loadMusic(ptr + 40, 0);
+	_parser->setTrack(track);
+	_parser->setTimerRate(_midi->getBaseTempo());
+	_midi->setTimerCallback(this, &Player_HE::onTimer);
+
+	_currentMusic = sound;
+}
+
+void Player_HE::stopSound(int sound) {
+	Common::StackLock lock(_mutex);
+	if (!_parser || _currentMusic != sound)
+		return;
+	_parser->stopPlaying();
+	delete _parser;
+	_parser = NULL;
+}
+
+void Player_HE::stopAllSounds() {
+	Common::StackLock lock(_mutex);
+	if (!_parser)
+		return;
+	_parser->stopPlaying();
+	delete _parser;
+	_parser = NULL;
+}
+
+int Player_HE::getSoundStatus(int sound) const {
+	Common::StackLock lock(_mutex);
+	return (_parser && _currentMusic == sound) ? _parser->isPlaying() : 0;
+}
+
+int Player_HE::getMusicTimer() {
+	Common::StackLock lock(_mutex);
+	return _parser ? _parser->getTick() : 0;
+}
+
+void Player_HE::loadAdLibBank() {
+	ScummFile file;
+	Common::String drvName;
+	char entryName[14];
+	uint32 tag, entrySize, fileSize;
+	Common::String bankName;
+
+	if (_vm->_game.id == GID_PUTTMOON) {
+		// Use GM bank
+		bankName = "FAT.AD";
+	} else {
+		// Use MT32-like bank
+		bankName = "MIDPAK.AD";
+	}
+
+	const char *ptr = strchr(_vm->_filenamePattern.pattern, '.');
+	if (ptr) {
+		drvName = Common::String(_vm->_filenamePattern.pattern, ptr - _vm->_filenamePattern.pattern + 1);
+	} else {
+		drvName = _vm->_filenamePattern.pattern;
+		drvName += '.';
+	}
+
+	drvName += "drv";
+
+	if (!file.open(drvName))
+		error("Player_HE::loadAdLibBank(): could not open %s", drvName.c_str());
+
+	uint32 size = (uint32)file.size();
+
+	for (uint32 offset = 0; offset < size;) {
+		file.seek(offset, SEEK_SET);
+		if (size - offset < 31)
+			error("Player_HE::loadAdLibBank(): unexpected end of file");
+
+		tag = file.readUint32BE();
+		entrySize = file.readUint32BE();
+		if (size - offset < entrySize)
+			error("Player_HE::loadAdLibBank(): unexpected end of file");
+		fileSize = entrySize - 31;
+		file.read(entryName, 13);
+		entryName[13] = 0;
+
+		if (tag != MKTAG('F', 'I', 'L', 'E'))
+			error("Player_HE::loadAdLibBank(): unknown entry format");
+
+		if (entryName == bankName) {
+			_bank = (byte*)malloc(fileSize);
+			file.read(_bank, fileSize);
+			_bankSize = fileSize;
+			return;
+		}
+
+		offset += entrySize;
+	}
+	error("Player_HE::loadAdLibBank(): could not find %s entry", bankName.c_str());
+}
+
+int Player_HE::open() {
+	if (_midi)
+		return _midi->open();
+	return 0;
+}
+
+bool Player_HE::isOpen() const {
+	if (_midi)
+		return _midi->isOpen();
+	return false;
+}
+
+void Player_HE::close() {
+	if (_midi)
+		_midi->close();
+}
+
+void Player_HE::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+	if (_midi)
+		_midi->setTimerCallback(timerParam, timerProc);
+}
+
+uint32 Player_HE::getBaseTempo() {
+	if (_midi)
+		return _midi->getBaseTempo();
+	return 0;
+}
+
+void Player_HE::send(uint32 b) {
+	byte chan = b & 0x0f;
+	byte cmd = b & 0xf0;
+	byte op1 = (b >> 8) & 0x7f;
+	byte op2 = (b >> 16) & 0x7f;
+	if (cmd == 0xb0 && op1 == 0x07)
+	{
+		_channelVolume[chan] = op2;
+		op2 = (op2 * _masterVolume) / 256;
+		b = (b & 0xffff) | (op2 << 16);
+	}
+	if (_midi)
+		_midi->send(b);
+}
+
+}
+
+#endif
diff --git a/engines/scumm/players/player_he.h b/engines/scumm/players/player_he.h
new file mode 100644
index 0000000..1405a05
--- /dev/null
+++ b/engines/scumm/players/player_he.h
@@ -0,0 +1,76 @@
+/* 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.
+ *
+ */
+
+#ifndef SCUMM_PLAYERS_PLAYER_HE_H
+#define SCUMM_PLAYERS_PLAYER_HE_H
+
+#include "scumm/music.h"
+#include "audio/mixer.h"
+#include "audio/mididrv.h"
+#include "common/mutex.h"
+
+class MidiParser;
+
+#ifdef ENABLE_HE
+
+namespace Scumm {
+class ScummEngine;
+
+class Player_HE : public MusicEngine, public MidiDriver {
+public:
+	Player_HE(ScummEngine *scumm);
+	~Player_HE();
+	void setMusicVolume(int vol);
+	void startSound(int sound) { startSoundWithTrackID(sound, 0); }
+	void startSoundWithTrackID(int sound, int track);
+	void stopSound(int sound);
+	void stopAllSounds();
+	int  getSoundStatus(int sound) const;
+	int  getMusicTimer();
+
+	int open();
+	bool isOpen() const;
+	void close();
+	void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
+	uint32 getBaseTempo();
+	MidiChannel *allocateChannel() { return NULL; };
+	MidiChannel *getPercussionChannel() { return NULL; };
+	void send(uint32 b);
+
+private:
+	ScummEngine *_vm;
+	MidiParser *_parser;
+	MidiDriver *_midi;
+	Common::Mutex _mutex;
+	byte *_bank;
+	int _bankSize;
+	int _currentMusic;
+	int _masterVolume;
+	byte _channelVolume[16];
+	static void onTimer(void *data);
+	void loadAdLibBank();
+};
+}
+
+#endif
+
+#endif
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 50ed673..0afa5f5 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
 /*
-  This file was generated by the md5table tool on Fri Dec 22 04:43:47 2017
+  This file was generated by the md5table tool on Thu Feb 01 01:05:11 2018
   DO NOT EDIT MANUALLY!
  */
 
@@ -496,7 +496,7 @@ static const MD5Table md5table[] = {
 	{ "a9543ef0d79bcb47cd76ec197ad0a967", "puttmoon", "", "", -1, Common::EN_ANY, Common::kPlatform3DO },
 	{ "a99c39ba65b6086be28aef576da69595", "spyozon", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
 	{ "a9f2f04b1ecaab9495b59befffe9bf88", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
-	{ "aa6a91b7f6f119d1b7b1f2a4c9e24d59", "puttmoon", "", "Demo", 6233, Common::EN_ANY, Common::kPlatformDOS },
+	{ "aa6a91b7f6f119d1b7b1f2a4c9e24d59", "puttmoon", "Demo", "Demo", 6233, Common::EN_ANY, Common::kPlatformDOS },
 	{ "aa7a07d94ae853f6460be4ce0a1bf530", "monkey", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS },
 	{ "aa81aa6d5545ce172fdba81f2e2f9d36", "puttzoo", "", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
 	{ "aa8a0cb65f3afbbe2c14c3f9f92775a3", "monkey", "CD", "CD", 8955, Common::FR_FRA, Common::kPlatformDOS },
@@ -711,3 +711,4 @@ static const MD5Table md5table[] = {
 	{ "ff05c07990061d97647f059c48c1d05a", "zak", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAtariST },
 	{ 0, 0, 0, 0, 0, Common::UNK_LANG, Common::kPlatformUnknown }
 };
+
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 77d82c8..fc64df4 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -64,6 +64,7 @@
 #include "scumm/players/player_v3m.h"
 #include "scumm/players/player_v4a.h"
 #include "scumm/players/player_v5m.h"
+#include "scumm/players/player_he.h"
 #include "scumm/resource.h"
 #include "scumm/he/resource_he.h"
 #include "scumm/he/moonbase/moonbase.h"
@@ -1954,6 +1955,10 @@ void ScummEngine::setupMusic(int midi) {
 		// support this with the Player_AD code at the moment. The reason here
 		// is that multi MIDI is supported internally by our iMuse output.
 		_musicEngine = new Player_AD(this);
+#ifdef ENABLE_HE
+	} else if (_game.platform == Common::kPlatformDOS && _sound->_musicType == MDT_ADLIB && _game.heversion >= 60) {
+		_musicEngine = new Player_HE(this);
+#endif
 	} else if (_game.version >= 3 && _game.heversion <= 62) {
 		MidiDriver *nativeMidiDriver = 0;
 		MidiDriver *adlibMidiDriver = 0;





More information about the Scummvm-git-logs mailing list