[Scummvm-git-logs] scummvm master -> 4a7aa7014674d2f45d3b084bb1bd963ac25f1006

sev- sev at scummvm.org
Fri Jul 2 22:39:16 UTC 2021


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:
4a7aa70146 SAGA2: Added music player


Commit: 4a7aa7014674d2f45d3b084bb1bd963ac25f1006
    https://github.com/scummvm/scummvm/commit/4a7aa7014674d2f45d3b084bb1bd963ac25f1006
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-07-03T00:39:05+02:00

Commit Message:
SAGA2: Added music player

Changed paths:
  A engines/saga2/music.cpp
  A engines/saga2/music.h
    engines/saga2/audio.cpp
    engines/saga2/audio.h
    engines/saga2/loadsave.cpp
    engines/saga2/module.mk
    engines/saga2/noise.cpp
    engines/saga2/saga2.cpp


diff --git a/engines/saga2/audio.cpp b/engines/saga2/audio.cpp
index ec2b158a80..94e93e7e72 100644
--- a/engines/saga2/audio.cpp
+++ b/engines/saga2/audio.cpp
@@ -29,6 +29,7 @@
 #include "saga2/fta.h"
 #include "saga2/shorten.h"
 #include "saga2/hresmgr.h"
+#include "saga2/music.h"
 
 #include "saga2/rect.h"
 #include "saga2/idtypes.h"
@@ -53,15 +54,15 @@ void cleanupAudio() {
 }
 
 audioInterface::audioInterface() {
-	warning("STUB: audioInteraface::audioInterface()");
+	_music = nullptr;
 }
 
 audioInterface::~audioInterface() {
-	warning("STUB: audioInteraface::~audioInterface()");
+	delete _music;
 }
 
-void audioInterface::initAudioInterface() {
-	warning("STUB: audioInterface::initAudioInterface()");
+void audioInterface::initAudioInterface(hResContext *musicContext) {
+	_music = new Music(musicContext, g_system->getMixer());
 }
 
 void audioInterface::cleanupAudioInterface(void) {
@@ -96,15 +97,17 @@ void audioInterface::playMe(void) {
 }
 
 void audioInterface::playMusic(soundSegment s, int16 loopFactor, sampleLocation where) {
-	warning("STUB: audioInterface::queueMusic()");
+	warning("STUB: audioInterface::playMusic()");
+	_music->play(s, loopFactor ? MUSIC_LOOP : MUSIC_NORMAL);
 }
 
 void audioInterface::stopMusic(void) {
 	warning("STUB: audioInterface::stopMusic()");
+	_music->stop();
 }
 
 void audioInterface::queueSound(soundSegment s, int16 loopFactor, sampleLocation where) {
-	warning("STUB: audioInterface::queueSound(%d,  @%d,%d)", s, where.x, where.y);
+	warning("STUB: audioInterface::queueSound(%s,  @%d,%d)", tag2strP(s), where.x, where.y);
 	SoundInstance si;
 
 	si.seg = s;
diff --git a/engines/saga2/audio.h b/engines/saga2/audio.h
index 6a476caa76..69e5d0213c 100644
--- a/engines/saga2/audio.h
+++ b/engines/saga2/audio.h
@@ -31,6 +31,9 @@
 
 namespace Saga2 {
 
+class Music;
+class hResContext;
+
 #define QUEUES_EXTERNAL_ALLOCATION 1
 
 // TODO: FIXME. STUB
@@ -88,13 +91,10 @@ struct SoundInstance {
 
 class audioInterface {
 private:
-	int16                   initialized;
-
-	HTIMER                  gameTimer;
-
-	soundSegment            playing;           // ID of music currently playing
 	soundSegment            looping;           // ID of music currently playing
 
+	Music *_music;
+
 public:
 	Audio::SoundHandle _speechSoundHandle;
 	Audio::SoundHandle _sfxSoundHandle;
@@ -113,7 +113,7 @@ public:
 	~audioInterface();
 
 	// init, cleanup
-	void initAudioInterface();
+	void initAudioInterface(hResContext *musicContext);
 	void cleanupAudioInterface(void);
 
 	// timer calls
@@ -127,9 +127,6 @@ public:
 	// music calls
 	void playMusic(soundSegment s, int16 loopFactor = 1, sampleLocation where = Here);
 	void stopMusic(void);
-	soundSegment currentMusic(void) {
-		return playing;    // ID of music currently playing
-	}
 
 	// sound calls
 	void queueSound(soundSegment s, int16 loopFactor = 1, sampleLocation where = Here);
diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index a835fb22ac..f1a19021d1 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -94,7 +94,6 @@ void initGameState(void) {
 	initGlobals();
 	initImageCache();
 	initTimer();
-	initAudio();
 	initCalender();
 	initWorlds();
 	initActors();
diff --git a/engines/saga2/module.mk b/engines/saga2/module.mk
index ea202cfba9..5d5eb4a1eb 100644
--- a/engines/saga2/module.mk
+++ b/engines/saga2/module.mk
@@ -44,6 +44,7 @@ MODULE_OBJS := \
 	motion.o \
 	mouseimg.o \
 	msgbox.o \
+	music.o \
 	noise.o \
 	objects.o \
 	objproto.o \
diff --git a/engines/saga2/music.cpp b/engines/saga2/music.cpp
new file mode 100644
index 0000000000..e5f862aa89
--- /dev/null
+++ b/engines/saga2/music.cpp
@@ -0,0 +1,187 @@
+/* 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.
+ *
+ */
+
+// MIDI music class
+
+#include "saga2/saga2.h"
+#include "saga2/fta.h"
+
+#include "saga2/music.h"
+#include "saga2/hresmgr.h"
+
+#include "audio/audiostream.h"
+#include "audio/mididrv.h"
+#include "audio/midiparser.h"
+#include "audio/midiparser_qt.h"
+#include "audio/miles.h"
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/substream.h"
+
+namespace Saga2 {
+
+#define BUFFER_SIZE 4096
+#define MUSIC_SUNSPOT 26
+
+MusicDriver::MusicDriver() {
+	MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+	_driverType = MidiDriver::getMusicType(dev);
+
+	switch (_driverType) {
+	case MT_ADLIB:
+		if (Common::File::exists("SAMPLE.AD") && Common::File::exists("SAMPLE.OPL")) {
+			_milesAudioMode = true;
+			_driver = Audio::MidiDriver_Miles_AdLib_create("SAMPLE.AD", "SAMPLE.OPL");
+			warning("*** YES MILES FILES");
+		} else {
+			_milesAudioMode = false;
+			MidiPlayer::createDriver();
+
+			warning("*** NO MILES FILES");
+		}
+		break;
+	case MT_MT32:
+		_milesAudioMode = true;
+		_driver = Audio::MidiDriver_Miles_MT32_create("");
+		break;
+	default:
+		_milesAudioMode = false;
+		MidiPlayer::createDriver();
+		break;
+	}
+
+	int retValue = _driver->open();
+	if (retValue == 0) {
+		if (_driverType != MT_ADLIB) {
+			if (_driverType == MT_MT32 || _nativeMT32)
+				_driver->sendMT32Reset();
+			else
+				_driver->sendGMReset();
+		}
+
+		_driver->setTimerCallback(this, &timerCallback);
+	}
+}
+
+void MusicDriver::send(uint32 b) {
+	if (_milesAudioMode) {
+		_driver->send(b);
+		return;
+	}
+
+	if ((b & 0xF0) == 0xC0 && !_nativeMT32) {
+		// Remap MT32 instruments to General Midi
+		b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
+	}
+	Audio::MidiPlayer::send(b);
+}
+
+void MusicDriver::metaEvent(byte type, byte *data, uint16 length) {
+	// TODO: Seems SAGA does not want / need to handle end-of-track events?
+}
+
+void MusicDriver::play(byte *data, uint32 size, bool loop) {
+	if (size < 4) {
+		error("Music::play() wrong music resource size");
+	}
+
+	// Check if the game is using XMIDI or SMF music
+	if (!memcmp(data, "FORM", 4)) {
+		_parser = MidiParser::createParser_XMIDI();
+	} else {
+		error("MusicDriver::play(): Unsupported music format");
+	}
+
+	if (!_parser->loadMusic(data, size))
+		error("Music::play() wrong music resource");
+
+	_parser->setTrack(0);
+	_parser->setMidiDriver(this);
+	_parser->setTimerRate(_driver->getBaseTempo());
+	_parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+	_parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
+
+	// Handle music looping
+	_parser->property(MidiParser::mpAutoLoop, loop);
+
+	_isPlaying = true;
+}
+
+void MusicDriver::pause() {
+	_isPlaying = false;
+}
+
+void MusicDriver::resume() {
+	_isPlaying = true;
+}
+
+
+Music::Music(hResContext *musicRes, Audio::Mixer *mixer) : _mixer(mixer), _player(0), _musicContext(musicRes) {
+	_currentVolume = 0;
+	_currentMusicBuffer = nullptr;
+
+	_player = new MusicDriver();
+
+	_trackNumber = 0;
+}
+
+Music::~Music() {
+	_mixer->stopHandle(_musicHandle);
+	delete _player;
+}
+
+bool Music::isPlaying() {
+	return _mixer->isSoundHandleActive(_musicHandle) || _player->isPlaying();
+}
+
+void Music::play(uint32 resourceId, MusicFlags flags) {
+	debug(2, "Music::play %d, %d", resourceId, flags);
+
+	if (isPlaying() && _trackNumber == resourceId)
+		return;
+
+	_trackNumber = resourceId;
+	_mixer->stopHandle(_musicHandle);
+	_player->stop();
+
+	delete _currentMusicBuffer;
+
+	_currentMusicBuffer = (byte *)LoadResource(_musicContext, resourceId, "music data");
+	uint32 size = _musicContext->size(resourceId);
+
+	_player->play(_currentMusicBuffer, size, (flags & MUSIC_LOOP));
+}
+
+void Music::pause() {
+	_player->pause();
+	_player->setVolume(0);
+}
+
+void Music::resume() {
+	_player->resume();
+}
+
+void Music::stop() {
+	_player->stop();
+}
+
+} // End of namespace Saga
diff --git a/engines/saga2/music.h b/engines/saga2/music.h
new file mode 100644
index 0000000000..75000db079
--- /dev/null
+++ b/engines/saga2/music.h
@@ -0,0 +1,96 @@
+/* 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.
+ *
+ */
+
+// Music class
+
+#ifndef SAGA2_MUSIC_H
+#define SAGA2_MUSIC_H
+
+#include "audio/mididrv.h"
+#include "audio/midiplayer.h"
+#include "audio/midiparser.h"
+#include "audio/mixer.h"
+
+namespace Saga2 {
+
+enum MusicFlags {
+	MUSIC_NORMAL = 0,
+	MUSIC_LOOP = 0x0001
+};
+
+class MusicDriver : public Audio::MidiPlayer {
+public:
+	MusicDriver();
+
+	void play(byte *data, uint32 size, bool loop);
+	void pause() override;
+	void resume() override;
+
+	bool isAdlib() const { return _driverType == MT_ADLIB; }
+
+	// FIXME
+	bool isPlaying() const { return _parser && _parser->isPlaying(); }
+
+	// MidiDriver_BASE interface implementation
+	void send(uint32 b) override;
+	void metaEvent(byte type, byte *data, uint16 length) override;
+
+protected:
+	MusicType _driverType;
+	bool _milesAudioMode;
+};
+
+class Music {
+public:
+
+	Music(hResContext *musicRes, Audio::Mixer *mixer);
+	~Music();
+	bool isPlaying();
+
+	void play(uint32 resourceId, MusicFlags flags = MUSIC_NORMAL);
+	void pause();
+	void resume();
+	void stop();
+
+	void setVolume(int volume, int time = 1);
+	int getVolume() { return _currentVolume; }
+
+	bool isAdlib() const { return _player->isAdlib(); }
+
+private:
+	Saga2Engine *_vm;
+	Audio::Mixer *_mixer;
+
+	MusicDriver *_player;
+	Audio::SoundHandle _musicHandle;
+	uint32 _trackNumber;
+
+	int _currentVolume;
+
+	hResContext *_musicContext;
+
+	byte *_currentMusicBuffer;
+};
+
+} // End of namespace Saga2
+
+#endif
diff --git a/engines/saga2/noise.cpp b/engines/saga2/noise.cpp
index 1006c64bd0..d05b87b2e1 100644
--- a/engines/saga2/noise.cpp
+++ b/engines/saga2/noise.cpp
@@ -157,7 +157,7 @@ void startAudio(void) {
 	if (voiceRes == NULL)
 		error("Laryngitis Error (No voice resource context)!\n");
 
-	audio->initAudioInterface();
+	audio->initAudioInterface(musicRes);
 	audio->setMusicFadeStyle(0, 0, 0);
 	oldAttenuator = audio->setAttenuator(&volumeFromDist);
 
diff --git a/engines/saga2/saga2.cpp b/engines/saga2/saga2.cpp
index 965273c9b1..449d098424 100644
--- a/engines/saga2/saga2.cpp
+++ b/engines/saga2/saga2.cpp
@@ -60,6 +60,8 @@ Saga2Engine::Saga2Engine(OSystem *syst)
 	_loadedWeapons = 0;
 
 	SearchMan.addSubDirectoryMatching(gameDataDir, "res");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "dos/drivers"); // For Miles Sound files
+	SearchMan.addSubDirectoryMatching(gameDataDir, "drivers");
 
 	_loadedWeapons = 0;
 }




More information about the Scummvm-git-logs mailing list