[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