[Scummvm-git-logs] scummvm master -> 34c5d3f2a22e06cd84179421c1a587b6a6559efd

yuv422 yuv422 at users.noreply.github.com
Thu May 21 08:06:18 UTC 2020


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

Summary:
39c264d853 DRAGONS: Implementing midi music player
34c5d3f2a2 DRAGONS: Moved midi data size init to initializer list


Commit: 39c264d853133ca95f224f52c98e52dd2bbe983b
    https://github.com/scummvm/scummvm/commit/39c264d853133ca95f224f52c98e52dd2bbe983b
Author: Eric Fry (yuv422 at users.noreply.github.com)
Date: 2020-05-21T18:06:13+10:00

Commit Message:
DRAGONS: Implementing midi music player

Changed paths:
  A engines/dragons/midimusicplayer.cpp
  A engines/dragons/midimusicplayer.h
    engines/dragons/dragons.cpp
    engines/dragons/minigame2.cpp
    engines/dragons/minigame3.cpp
    engines/dragons/module.mk
    engines/dragons/scriptopcodes.cpp
    engines/dragons/sound.cpp
    engines/dragons/sound.h
    engines/dragons/specialopcodes.cpp
    engines/dragons/talk.cpp


diff --git a/engines/dragons/dragons.cpp b/engines/dragons/dragons.cpp
index ceda9f75c5..440ae7e2e2 100644
--- a/engines/dragons/dragons.cpp
+++ b/engines/dragons/dragons.cpp
@@ -654,7 +654,9 @@ void DragonsEngine::updateHandler() {
 
 	// 0x8001b200
 	if (isFlagSet(ENGINE_FLAG_8000) && !_sound->isSpeechPlaying()) {
+		//dialog finished playing.
 		clearFlags(ENGINE_FLAG_8000);
+		_sound->resumeMusic();
 	}
 
 	//TODO logic here
diff --git a/engines/dragons/midimusicplayer.cpp b/engines/dragons/midimusicplayer.cpp
new file mode 100644
index 0000000000..3034cb6c29
--- /dev/null
+++ b/engines/dragons/midimusicplayer.cpp
@@ -0,0 +1,132 @@
+/* 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.
+ *
+ */
+#include "common/stream.h"
+#include "audio/midiparser.h"
+#include "midimusicplayer.h"
+
+
+namespace Dragons {
+
+MidiMusicPlayer::MidiMusicPlayer(VabSound *musicVab): _musicVab(musicVab) {
+	_midiData = nullptr;
+	_midiDataSize = 0;
+	MidiPlayer::createDriver();
+
+	int ret = _driver->open();
+	if (ret == 0) {
+		if (_nativeMT32)
+			_driver->sendMT32Reset();
+		else
+			_driver->sendGMReset();
+
+		_driver->setTimerCallback(this, &timerCallback);
+	}
+}
+
+MidiMusicPlayer::~MidiMusicPlayer() {
+	if (isPlaying()) {
+		stop();
+	}
+}
+
+void MidiMusicPlayer::playSong(Common::SeekableReadStream *seqData) {
+	Common::StackLock lock(_mutex);
+
+	if (isPlaying()) {
+		stop();
+	}
+
+	if (seqData->readUint32LE() != MKTAG('S', 'E', 'Q', 'p'))
+		error("Failed to find SEQp tag");
+
+	// Make sure we don't have a SEP file (with multiple SEQ's inside)
+	if (seqData->readUint32BE() != 1)
+		error("Can only play SEQ files, not SEP");
+
+	uint16 ppqn = seqData->readUint16BE();
+	uint32 tempo = seqData->readUint16BE() << 8;
+	tempo |= seqData->readByte();
+	/* uint16 beat = */ seqData->readUint16BE();
+
+	// SEQ is directly based on SMF and we'll use that to our advantage here
+	// and convert to SMF and then use the SMF MidiParser.
+
+	// Calculate the SMF size we'll need
+	uint32 dataSize = seqData->size() - 15;
+	uint32 actualSize = dataSize + 7 + 22;
+
+	// Resize the buffer if necessary
+	byte *midiData = resizeMidiBuffer(actualSize);
+
+	// Now construct the header
+	WRITE_BE_UINT32(midiData, MKTAG('M', 'T', 'h', 'd'));
+	WRITE_BE_UINT32(midiData + 4, 6); // header size
+	WRITE_BE_UINT16(midiData + 8, 0); // type 0
+	WRITE_BE_UINT16(midiData + 10, 1); // one track
+	WRITE_BE_UINT16(midiData + 12, ppqn);
+	WRITE_BE_UINT32(midiData + 14, MKTAG('M', 'T', 'r', 'k'));
+	WRITE_BE_UINT32(midiData + 18, dataSize + 7); // SEQ data size + tempo change event size
+
+	// Add in a fake tempo change event
+	WRITE_BE_UINT32(midiData + 22, 0x00FF5103); // no delta, meta event, tempo change, param size = 3
+	WRITE_BE_UINT16(midiData + 26, tempo >> 8);
+	midiData[28] = tempo & 0xFF;
+
+	// Now copy in the rest of the events
+	seqData->read(midiData + 29, dataSize);
+
+	MidiParser *parser = MidiParser::createParser_SMF();
+	if (parser->loadMusic(midiData, actualSize)) {
+		parser->setTrack(0);
+		parser->setMidiDriver(this);
+		parser->setTimerRate(getBaseTempo());
+		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+		parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
+
+		_parser = parser;
+
+		_isLooping = true;
+		_isPlaying = true;
+	} else {
+		delete parser;
+	}
+}
+
+byte *MidiMusicPlayer::resizeMidiBuffer(uint32 desiredSize) {
+	if (_midiData == nullptr) {
+		_midiData = (byte *)malloc(desiredSize);
+		_midiDataSize = desiredSize;
+	} else {
+		if (desiredSize > _midiDataSize) {
+			_midiData = (byte *)realloc(_midiData, desiredSize);
+			_midiDataSize = desiredSize;
+		}
+	}
+	return _midiData;
+}
+
+void MidiMusicPlayer::setVolume(int volume) {
+//	_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume); TODO do we need this?
+	MidiPlayer::setVolume(volume);
+}
+
+} // End of namespace Dragons
diff --git a/engines/dragons/midimusicplayer.h b/engines/dragons/midimusicplayer.h
new file mode 100644
index 0000000000..4a57b10bae
--- /dev/null
+++ b/engines/dragons/midimusicplayer.h
@@ -0,0 +1,51 @@
+/* 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 DRAGONS_MIDIMUSICPLAYER_H
+#define DRAGONS_MIDIMUSICPLAYER_H
+
+#include "audio/midiplayer.h"
+#include "vabsound.h"
+
+namespace Dragons {
+
+class MidiMusicPlayer : public Audio::MidiPlayer {
+private:
+	VabSound *_musicVab;
+	uint32 _midiDataSize;
+public:
+	MidiMusicPlayer(VabSound *musicVab);
+	~MidiMusicPlayer();
+
+	void setVolume(int volume) override;
+
+	void playSong(Common::SeekableReadStream *seqData);
+
+	// The original sets the "sequence timing" to 109 Hz, whatever that
+	// means. The default is 120.
+	uint32 getBaseTempo()	{ return _driver ? (109 * _driver->getBaseTempo()) / 120 : 0; }
+private:
+	byte *resizeMidiBuffer(uint32 desiredSize);
+};
+
+} // End of namespace Dragons
+
+#endif //DRAGONS_MIDIMUSICPLAYER_H
diff --git a/engines/dragons/minigame2.cpp b/engines/dragons/minigame2.cpp
index f45ef6bb25..e198b0e015 100644
--- a/engines/dragons/minigame2.cpp
+++ b/engines/dragons/minigame2.cpp
@@ -693,7 +693,7 @@ void Minigame2::run(int16 param_1, uint16 param_2, int16 param_3) {
 
 	_vm->fadeToBlack();
 	_vm->_fontManager->clearText();
-	_vm->_sound->PauseCDMusic();
+	_vm->_sound->resumeMusic();
 //	DisableVSyncEvent();
 	_vm->_dragonINIResource->getRecord(0)->x = 0x91;
 	_vm->_dragonINIResource->getRecord(0)->y = 0x9b;
diff --git a/engines/dragons/minigame3.cpp b/engines/dragons/minigame3.cpp
index 5159ec1a28..6df42746ff 100644
--- a/engines/dragons/minigame3.cpp
+++ b/engines/dragons/minigame3.cpp
@@ -731,7 +731,7 @@ void Minigame3::run() {
 		_vm->_dragonINIResource->getRecord(0x178)->objectState2 = 0;
 	}
 	_vm->waitForFrames(0x3c * 2);
-	_vm->_sound->PauseCDMusic();
+	_vm->_sound->resumeMusic();
 	_vm->fadeToBlack();
 //	fun_80017f28_noop();
 //	DAT_80093234 = DAT_80093234 + 1;
diff --git a/engines/dragons/module.mk b/engines/dragons/module.mk
index 5af8bbef9b..d87d67b15b 100644
--- a/engines/dragons/module.mk
+++ b/engines/dragons/module.mk
@@ -19,6 +19,7 @@ MODULE_OBJS := \
 	dragons.o \
 	font.o \
 	inventory.o \
+	midimusicplayer.o \
 	minigame1.o \
 	minigame2.o \
 	minigame3.o \
diff --git a/engines/dragons/scriptopcodes.cpp b/engines/dragons/scriptopcodes.cpp
index 9f1a794cd7..5c5dde41d2 100644
--- a/engines/dragons/scriptopcodes.cpp
+++ b/engines/dragons/scriptopcodes.cpp
@@ -477,10 +477,10 @@ void ScriptOpcodes::opActorLoadSequence(ScriptOpCall &scriptOpCall) {
 }
 
 void ScriptOpcodes::opPlayMusic(ScriptOpCall &scriptOpCall) {
-	//byte *code = scriptOpCall._code;
-	scriptOpCall._code += 4;
+	ARG_SKIP(2);
+	ARG_INT16(songNumber);
 	if (scriptOpCall._field8 == 0) {
-		//TODO play music here.
+		_vm->_sound->playMusic(songNumber);
 	}
 }
 
@@ -534,7 +534,7 @@ void ScriptOpcodes::opPreLoadSceneData(ScriptOpCall &scriptOpCall) {
 	ARG_INT16(field0);
 	ARG_INT16(sceneId);
 
-	_vm->_sound->PauseCDMusic();
+	_vm->_sound->resumeMusic();
 	_vm->_isLoadingDialogAudio = true;
 
 	if (sceneId >= 2) {
@@ -547,7 +547,7 @@ void ScriptOpcodes::opPauseCurrentSpeechAndFetchNextDialog(ScriptOpCall &scriptO
 	ARG_UINT32(textIndex);
 
 	if (scriptOpCall._field8 == 0) {
-		_vm->_sound->PauseCDMusic();
+		_vm->_sound->resumeMusic();
 		//The original starts seeking the CD-ROM here for the `textIndex` dialog but we don't need to do that.
 	}
 }
@@ -907,7 +907,7 @@ void ScriptOpcodes::opLoadScene(ScriptOpCall &scriptOpCall) {
 
 	_vm->fadeToBlack();
 	_vm->clearSceneUpdateFunction();
-	_vm->_sound->PauseCDMusic();
+	_vm->_sound->resumeMusic();
 
 	if (newSceneID != 0) {
 		_vm->_scene->_mapTransitionEffectSceneID = _vm->_scene->getSceneId();
diff --git a/engines/dragons/sound.cpp b/engines/dragons/sound.cpp
index 67d6508ab7..f2ab4d7782 100644
--- a/engines/dragons/sound.cpp
+++ b/engines/dragons/sound.cpp
@@ -79,6 +79,9 @@ void SoundManager::playSpeech(uint32 textIndex) {
 		return;
 	}
 
+	// Reduce music volume while playing dialog.
+	_midiPlayer->setVolume(_musicVolume / 2);
+
 	struct SpeechLocation speechLocation;
 	if (!getSpeechLocation(textIndex, &speechLocation)) {
 		return;
@@ -132,12 +135,14 @@ bool SoundManager::getSpeechLocation(uint32 talkId, struct SpeechLocation *locat
 	return foundId;
 }
 
-void SoundManager::PauseCDMusic() {
-	//TODO check PauseCDMusic() to see if we need any more logic.
+void SoundManager::resumeMusic() {
 	if (isSpeechPlaying()) {
 		_vm->_mixer->stopHandle(_speechHandle);
 		_vm->clearFlags(ENGINE_FLAG_8000);
 	}
+	if (_currentSong != -1) {
+		_midiPlayer->resume();
+	}
 }
 
 SoundManager::PSXAudioTrack::PSXAudioTrack() {
@@ -262,6 +267,7 @@ SoundManager::SoundManager(DragonsEngine *vm, BigfileArchive *bigFileArchive, Dr
 		  _bigFileArchive(bigFileArchive),
 		  _dragonRMS(dragonRMS) {
 	_dat_8006bb60_sound_related = 0;
+	_currentSong = -1;
 
 	bool allSoundIsMuted = false;
 	if (ConfMan.hasKey("mute")) {
@@ -284,7 +290,9 @@ SoundManager::SoundManager(DragonsEngine *vm, BigfileArchive *bigFileArchive, Dr
 	}
 
 	SomeInitSound_FUN_8003f64c();
-	loadMusAndGlob();
+	initVabData();
+	_midiPlayer = new MidiMusicPlayer(_vabMusx);
+	_midiPlayer->setVolume(_musicVolume);
 }
 
 SoundManager::~SoundManager() {
@@ -294,7 +302,11 @@ SoundManager::~SoundManager() {
 
 	stopAllVoices();
 
+	_midiPlayer->stop();
+
+	delete _midiPlayer;
 	delete _vabMusx;
+	delete _vabMsf;
 	delete _vabGlob;
 }
 
@@ -360,8 +372,9 @@ void SoundManager::SomeInitSound_FUN_8003f64c() {
 	_soundArr[1612] = 0x0b;
 }
 
-void SoundManager::loadMusAndGlob() {
+void SoundManager::initVabData() {
 	_vabMusx = loadVab("musx.vh", "musx.vb");
+	_vabMsf = loadVab("musx.vh", "musx.vb");
 	_vabGlob = loadVab("glob.vh", "glob.vb");
 }
 
@@ -402,7 +415,7 @@ void SoundManager::playSound(uint16 soundId, uint16 volumeId) {
 	volume = _soundArr[volumeId];
 	_soundArr[volumeId] = _soundArr[volumeId] | 0x40u;      // Set bit 0x40
 
-	VabSound *vabSound = ((soundId & 0x8000u) != 0) ? _vabGlob : _vabMusx;
+	VabSound *vabSound = ((soundId & 0x8000u) != 0) ? _vabGlob : _vabMsf;
 
 	// TODO: CdVolume!
 	int cdVolume = 1;
@@ -452,8 +465,8 @@ void SoundManager::loadMsf(uint32 sceneId) {
 
 		stopAllVoices();
 
-		delete _vabMusx;
-		_vabMusx = new VabSound(msfStream, _vm);
+		delete _vabMsf;
+		_vabMsf = new VabSound(msfStream, _vm);
 	}
 }
 
@@ -491,4 +504,25 @@ void SoundManager::stopAllVoices() {
 	}
 }
 
+void SoundManager::playMusic(int16 song) {
+	char sceneName[5] = "nnnn";
+	char filename[12] = "xxxxznn.msq";
+
+	if (_currentSong == song) {
+		return;
+	}
+
+	_currentSong = song;
+
+	memcpy(sceneName, _vm->_dragonRMS->getSceneName(_vm->getCurrentSceneId()), 4);
+	snprintf(filename, 12, "%sz%02d.msq", sceneName, song);
+	debug("Load music file %s", filename);
+
+	uint32 dataSize;
+	byte *seqData = _bigFileArchive->load(filename, dataSize);
+	Common::MemoryReadStream *seq = new Common::MemoryReadStream(seqData, dataSize, DisposeAfterUse::YES);
+	_midiPlayer->playSong(seq);
+	delete seq;
+}
+
 } // End of namespace Dragons
diff --git a/engines/dragons/sound.h b/engines/dragons/sound.h
index fe0bec174a..b01ad87387 100644
--- a/engines/dragons/sound.h
+++ b/engines/dragons/sound.h
@@ -25,6 +25,7 @@
 #include "common/scummsys.h"
 #include "audio/mixer.h"
 #include "audio/audiostream.h"
+#include "midimusicplayer.h"
 
 
 namespace Dragons {
@@ -54,9 +55,10 @@ public:
 	void loadMsf(uint32 sceneId);
 	void playOrStopSound(uint16 soundId);
 
+	void playMusic(int16 song);
 	void playSpeech(uint32 textIndex);
 	bool isSpeechPlaying();
-	void PauseCDMusic();
+	void resumeMusic();
 
 public:
 	uint16 _dat_8006bb60_sound_related;
@@ -74,15 +76,19 @@ private:
 	uint8 _soundArr[0x780];
 
 	VabSound* _vabMusx;
+	VabSound* _vabMsf;
 	VabSound* _vabGlob;
 
 	Audio::SoundHandle _speechHandle;
+	MidiMusicPlayer *_midiPlayer;
+
 	Voice _voice[NUM_VOICES];
+	int16 _currentSong;
 
 private:
 	void SomeInitSound_FUN_8003f64c();
 
-	void loadMusAndGlob();
+	void initVabData();
 
 	void playSound(uint16 soundId, uint16 i);
 
diff --git a/engines/dragons/specialopcodes.cpp b/engines/dragons/specialopcodes.cpp
index 156e89eef9..09175f6d42 100644
--- a/engines/dragons/specialopcodes.cpp
+++ b/engines/dragons/specialopcodes.cpp
@@ -330,7 +330,7 @@ void SpecialOpcodes::spcLadyOfTheLakeCapturedSceneLogic() {
 
 void SpecialOpcodes::spcStopLadyOfTheLakeCapturedSceneLogic() {
 	_vm->clearSceneUpdateFunction();
-	_vm->_sound->PauseCDMusic();
+	_vm->_sound->resumeMusic();
 	if ((_dat_80083148 != 0) || (_uint16_t_80083154 != 0)) {
 		//TODO FUN_8001ac5c((uint)_dat_80083148, (uint)DAT_80083150, (uint)_uint16_t_80083154, (uint)DAT_80083158);
 	}
diff --git a/engines/dragons/talk.cpp b/engines/dragons/talk.cpp
index 2a3fdb7aa6..aba7ca2337 100644
--- a/engines/dragons/talk.cpp
+++ b/engines/dragons/talk.cpp
@@ -427,7 +427,7 @@ uint8 Talk::conversation_related_maybe(uint16 *dialogText, uint16 x, uint16 y, u
 	}
 	if (param_5 != 0) {
 		if (_vm->isFlagSet(ENGINE_FLAG_8000)) {
-			_vm->_sound->PauseCDMusic();
+			_vm->_sound->resumeMusic();
 		}
 		if (isFlag8Set) {
 			_vm->setFlags(ENGINE_FLAG_8);


Commit: 34c5d3f2a22e06cd84179421c1a587b6a6559efd
    https://github.com/scummvm/scummvm/commit/34c5d3f2a22e06cd84179421c1a587b6a6559efd
Author: Eric Fry (yuv422 at users.noreply.github.com)
Date: 2020-05-21T18:06:13+10:00

Commit Message:
DRAGONS: Moved midi data size init to initializer list

Changed paths:
    engines/dragons/midimusicplayer.cpp


diff --git a/engines/dragons/midimusicplayer.cpp b/engines/dragons/midimusicplayer.cpp
index 3034cb6c29..e4342de516 100644
--- a/engines/dragons/midimusicplayer.cpp
+++ b/engines/dragons/midimusicplayer.cpp
@@ -26,9 +26,8 @@
 
 namespace Dragons {
 
-MidiMusicPlayer::MidiMusicPlayer(VabSound *musicVab): _musicVab(musicVab) {
+MidiMusicPlayer::MidiMusicPlayer(VabSound *musicVab): _musicVab(musicVab), _midiDataSize(0) {
 	_midiData = nullptr;
-	_midiDataSize = 0;
 	MidiPlayer::createDriver();
 
 	int ret = _driver->open();




More information about the Scummvm-git-logs mailing list