[Scummvm-git-logs] scummvm master -> c0878a9b6eba3fb754732d6515a4d08ccabcc26d
mduggan
noreply at scummvm.org
Sun May 24 03:40:28 UTC 2026
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
c0878a9b6e ACCESS: Add OGG music support to Noctropolis
Commit: c0878a9b6eba3fb754732d6515a4d08ccabcc26d
https://github.com/scummvm/scummvm/commit/c0878a9b6eba3fb754732d6515a4d08ccabcc26d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2026-05-24T13:38:56+10:00
Commit Message:
ACCESS: Add OGG music support to Noctropolis
The remake ships with pre-rendered OGG music as an alternative. Add support
for it.
Hidden behind an INI file option `ogg_music`. Still need to add a UI for it.
Changed paths:
engines/access/access.cpp
engines/access/amazon/amazon_logic.cpp
engines/access/files.cpp
engines/access/noctropolis/noctropolis_game.cpp
engines/access/room.cpp
engines/access/scripts.cpp
engines/access/sound.cpp
engines/access/sound.h
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 70c3f2a6804..19d5b5af5ed 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -190,7 +190,7 @@ void AccessEngine::initialize() {
_player = Player::init(this);
_screen = new Screen(this);
_sound = new SoundManager(this, _mixer);
- _midi = new MusicManager(this);
+ _midi = new MusicManagerMIDI(this);
_curPlayer = _player;
syncSoundSettings();
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
index e4925d1b253..4f8fa57862c 100644
--- a/engines/access/amazon/amazon_logic.cpp
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -1337,7 +1337,7 @@ void Cast::doCast(int param1) {
break;
if (_yCam < -7550) {
- while (!_vm->shouldQuit() && !_vm->_midi->checkMidiDone())
+ while (!_vm->shouldQuit() && _vm->_midi->isPlaying())
_vm->_events->pollEventsAndWait();
break;
}
diff --git a/engines/access/files.cpp b/engines/access/files.cpp
index 882c8eb7088..7280d95b917 100644
--- a/engines/access/files.cpp
+++ b/engines/access/files.cpp
@@ -96,15 +96,14 @@ FileManager::~FileManager() {
Resource *FileManager::loadFile(int fileNum, int subfile) {
Resource *res = nullptr;
const Common::Path &filepath = _vm->_res->FILENAMES[fileNum];
- Common::File file;
// Noctropolis remastered has music in OGG or MID format broken
// out into the individual files.
- if (_vm->getGameID() == kGameNoctropolis && fileNum == 98 && !file.exists(filepath)) {
+ if (_vm->getGameID() == kGameNoctropolis && fileNum == 98 && !SearchMan.hasFile(filepath)) {
Common::Path path = Common::Path(Common::String::format("MUSIC/M%02d.mid", subfile));
// TODO: Also check for OGG file here. Make it a configuration
// variable - originally hidef_music, default true.
- if (file.exists(path))
+ if (SearchMan.hasFile(path))
res = loadRawFile(path);
} else {
res = new Resource();
diff --git a/engines/access/noctropolis/noctropolis_game.cpp b/engines/access/noctropolis/noctropolis_game.cpp
index f535c584bb0..f1c86124d90 100644
--- a/engines/access/noctropolis/noctropolis_game.cpp
+++ b/engines/access/noctropolis/noctropolis_game.cpp
@@ -58,6 +58,16 @@ void NoctropolisEngine::initObjects() {
// Current defaults to screen in Noctropolis.
_current = _screen;
+
+ // If we are using "high definition" audio then replace the midi manager
+ if (ConfMan.getBool("ogg_music") && SearchMan.hasFile("MUSIC/M00.ogg")) {
+#ifdef USE_VORBIS
+ delete _midi;
+ _midi = new MusicManagerOGG(this);
+#else
+ warning("OGG music requested but Vorbis support not in build - falling back to MIDI");
+#endif // USE_VORBIS
+ }
}
void NoctropolisEngine::setupGame() {
@@ -845,7 +855,7 @@ void NoctropolisEngine::showNightdiveCredits() {
const Font *font = _fonts.getFont(1);
const Common::Path nightDive("DARK/nds.png");
- if (!Common::File().exists(nightDive))
+ if (!SearchMan.hasFile(nightDive))
return;
_events->clearEvents();
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
index f773aac2dc6..be08fdfd034 100644
--- a/engines/access/room.cpp
+++ b/engines/access/room.cpp
@@ -325,7 +325,7 @@ void Room::roomInit() {
}
void Room::clearRoom() {
- if (_vm->_midi->_music) {
+ if (_vm->_midi->isMusicLoaded()) {
_vm->_midi->stopSong();
_vm->_midi->freeMusic();
}
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index 047c60b242b..23f72fa9c2f 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -351,7 +351,7 @@ void Scripts::cmdEndObject_v3() {
_vm->_bubbleBox->placeBubble(subtitle);
}
- warning("TODO: duck the sound here.. SetRelVolume(0x32);");
+ debug("cmdEndObject_v3: TODO: duck music volume to 50%% here.");
VideoPlayer_v2 vidPlayer(_vm);
vidPlayer.VideoPlayer::setVideo(_vm->_screen, Common::Point(100, 100), Common::Path(vidfile), 0);
@@ -1173,7 +1173,7 @@ void Scripts::cmdCharSpeak_v3() {
_vm->_screen->_printOrg = _charsOrg;
_vm->_screen->_printStart = _charsOrg;
- // TODO: Duck (reduce) music volume to 50%
+ //debug("cmdCharSpeak_v3: duck music volume to 50%% here.");
Common::String str = _data->readString();
debugC(1, kDebugScripts, "cmdCharSpeak(%d, %d, str=\"%s\")", x, y, str.c_str());
@@ -2001,7 +2001,7 @@ void Scripts::cmdLockInterface() {
void Scripts::cmdUnlockInterface() {
debugC(1, kDebugScripts, "cmdUnlockInterface()");
_vm->_events->_interfaceOff = false;
- warning("TODO: cmdUnlockInterface - restore cursor");
+ debug("TODO: cmdUnlockInterface - restore cursor");
_vm->_events->setCursor(CURSOR_ARROW);
}
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index 30336f69359..0f7f4dc861a 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -26,6 +26,7 @@
#include "audio/midiparser.h"
#include "audio/decoders/raw.h"
#include "audio/decoders/wave.h"
+#include "audio/decoders/vorbis.h"
#include "audio/miles.h"
#include "audio/midiparser_smf.h"
@@ -264,7 +265,28 @@ void SoundManager::freeSounds() {
/******************************************************************************************/
-MusicManager::MusicManager(AccessEngine *vm) : _vm(vm) {
+MusicManager::~MusicManager() {
+ delete _music;
+ delete _tempMusic;
+}
+
+void MusicManager::loadMusic(int fileNum, int subfile) {
+ debugC(1, kDebugSound, "loadMusic(%d, %d)", fileNum, subfile);
+
+ _music = _vm->_files->loadFile(fileNum, subfile);
+}
+
+
+void MusicManager::freeMusic() {
+ debugC(3, kDebugSound, "freeMusic");
+
+ delete _music;
+ _music = nullptr;
+}
+
+/*******************/
+
+MusicManagerMIDI::MusicManagerMIDI(AccessEngine *vm) : MusicManager(vm), Audio::MidiPlayer() {
_music = nullptr;
_tempMusic = nullptr;
_isLooping = false;
@@ -327,12 +349,10 @@ MusicManager::MusicManager(AccessEngine *vm) : _vm(vm) {
}
}
-MusicManager::~MusicManager() {
- delete _music;
- delete _tempMusic;
+MusicManagerMIDI::~MusicManagerMIDI() {
}
-void MusicManager::send(uint32 b) {
+void MusicManagerMIDI::send(uint32 b) {
// Pass data directly to driver
_driver->send(b);
#if 0
@@ -344,7 +364,7 @@ void MusicManager::send(uint32 b) {
#endif
}
-void MusicManager::midiPlay() {
+void MusicManagerMIDI::midiPlay() {
debugC(1, kDebugSound, "midiPlay");
if (!_driver)
@@ -403,12 +423,7 @@ void MusicManager::midiPlay() {
}
}
-bool MusicManager::checkMidiDone() {
- debugC(1, kDebugSound, "checkMidiDone");
- return (!_isPlaying);
-}
-
-void MusicManager::midiRepeat() {
+void MusicManagerMIDI::midiRepeat() {
debugC(1, kDebugSound, "midiRepeat");
if (!_driver)
@@ -422,7 +437,7 @@ void MusicManager::midiRepeat() {
_parser->setTrack(0);
}
-void MusicManager::stopSong() {
+void MusicManagerMIDI::stopSong() {
debugC(1, kDebugSound, "stopSong");
if (!_driver)
@@ -431,19 +446,7 @@ void MusicManager::stopSong() {
stop();
}
-void MusicManager::loadMusic(int fileNum, int subfile) {
- debugC(1, kDebugSound, "loadMusic(%d, %d)", fileNum, subfile);
-
- _music = _vm->_files->loadFile(fileNum, subfile);
-}
-
-void MusicManager::loadMusic(FileIdent file) {
- debugC(1, kDebugSound, "loadMusic(%d, %d)", file._fileNum, file._subFile);
-
- _music = _vm->_files->loadFile(file);
-}
-
-void MusicManager::newMusic(int musicId, int mode) {
+void MusicManagerMIDI::newMusic(int musicId, int mode) {
debugC(1, kDebugSound, "newMusic(%d, %d)", musicId, mode);
if (!_driver)
@@ -467,14 +470,7 @@ void MusicManager::newMusic(int musicId, int mode) {
midiPlay();
}
-void MusicManager::freeMusic() {
- debugC(3, kDebugSound, "freeMusic");
-
- delete _music;
- _music = nullptr;
-}
-
-void MusicManager::startMusicFade() {
+void MusicManagerMIDI::startMusicFade() {
debugC(3, kDebugSound, "fadeMusic");
if (!isPlaying())
return;
@@ -483,11 +479,106 @@ void MusicManager::startMusicFade() {
warning("TODO: Implement MusicManager::fadeMusic - fade over 700ms from startVol %d", startVol);
}
-void MusicManager::setLoop(bool loop) {
+void MusicManagerMIDI::setLoop(bool loop) {
debugC(3, kDebugSound, "setLoop");
_isLooping = loop;
if (_parser)
_parser->property(MidiParser::mpAutoLoop, _isLooping);
}
+
+/******************/
+
+#ifdef USE_VORBIS
+
+MusicManagerOGG::MusicManagerOGG(AccessEngine *vm) : MusicManager(vm) {
+ _handle = new Audio::SoundHandle();
+}
+
+MusicManagerOGG::~MusicManagerOGG() {
+ delete _handle;
+}
+
+void MusicManagerOGG::midiPlay() {
+ if (isPlaying())
+ stopSong();
+
+ if (!_music) {
+ warning("midiPlay called with nothing loaded");
+ return;
+ }
+
+ Audio::SeekableAudioStream *audio = Audio::makeVorbisStream(_music->_stream, DisposeAfterUse::NO);
+ _vm->_mixer->playStream(Audio::Mixer::kMusicSoundType, _handle,
+ audio, -1, _vm->_mixer->kMaxChannelVolume, 0,
+ DisposeAfterUse::YES);
+}
+
+bool MusicManagerOGG::isPlaying() {
+ return _vm->_mixer->isSoundHandleActive(*_handle);
+}
+
+void MusicManagerOGG::midiRepeat() {
+
+}
+
+void MusicManagerOGG::stopSong() {
+ _vm->_mixer->stopHandle(*_handle);
+}
+
+void MusicManagerOGG::newMusic(int musicId, int mode) {
+ debugC(1, kDebugSound, "newMusic(%d, %d)", musicId, mode);
+
+ bool doLoop = false;
+
+ if (mode == 1) {
+ // Resume previous music
+ stopSong();
+ freeMusic();
+ _music = _tempMusic;
+ _tempMusic = nullptr;
+ doLoop = true;
+ } else {
+ doLoop = (mode == 2);
+ _tempMusic = _music;
+ stopSong();
+ loadMusic(98, musicId);
+ }
+
+ if (_music)
+ midiPlay();
+
+ if (doLoop)
+ setLoop(true);
+}
+
+void MusicManagerOGG::loadMusic(int fileNum, int subfile) {
+ Common::Path path = Common::Path(Common::String::format("MUSIC/M%02d.ogg", subfile));
+ if (!_vm->_files->existFile(path)) {
+ warning("Don't have requested music file %s", path.toString().c_str());
+ return;
+ }
+
+ _music = _vm->_files->loadRawFile(path);
+}
+
+void MusicManagerOGG::startMusicFade() {
+ warning("TODO: Implement MusicManagerOGG::startMusicFade");
+}
+
+void MusicManagerOGG::setLoop(bool loop) {
+ if (loop)
+ _vm->_mixer->loopChannel(*_handle);
+}
+
+void MusicManagerOGG::syncVolume() {
+ bool mute = ConfMan.getBool("mute");
+ _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType,
+ mute ? 0 : ConfMan.getInt("music_volume"));
+}
+
+
+#endif // USE_VORBIS
+
+
} // End of namespace Access
diff --git a/engines/access/sound.h b/engines/access/sound.h
index 80e16fbb391..61ab0d74c85 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -99,41 +99,75 @@ public:
bool hasSounds() const { return _soundTable.size() > 0 && _soundTable[0]._res; }
};
-class MusicManager : public Audio::MidiPlayer {
-private:
- AccessEngine *_vm;
+class MusicManager : public Manager {
+public:
+ MusicManager(AccessEngine *vm) : Manager(vm), _music(nullptr), _tempMusic(nullptr) {};
+ virtual ~MusicManager();
+ bool isMusicLoaded() { return _music != nullptr; }
+ void freeMusic();
+ virtual void loadMusic(int fileNum, int subfile);
+ void loadMusic(FileIdent ident) { loadMusic(ident._fileNum, ident._subFile); };
+
+ virtual void midiPlay() = 0;
+ virtual bool isPlaying() = 0;
+ virtual void midiRepeat() = 0;
+ virtual void stopSong() = 0;
+ virtual void newMusic(int musicId, int mode) = 0;
+ virtual void startMusicFade() = 0;
+ virtual void setLoop(bool loop) = 0;
+ virtual void syncVolume() = 0;
+
+protected:
+ Resource *_music;
Resource *_tempMusic;
+};
+
+class MusicManagerMIDI : private Audio::MidiPlayer, public MusicManager {
+private:
// MidiDriver_BASE interface implementation
void send(uint32 b) override;
public:
- Resource *_music;
-
-public:
- MusicManager(AccessEngine *vm);
- ~MusicManager() override;
-
- void midiPlay();
-
- bool checkMidiDone();
-
- void midiRepeat();
-
- void stopSong();
+ MusicManagerMIDI(AccessEngine *vm);
+ ~MusicManagerMIDI() override;
+
+ void midiPlay() override;
+ bool isPlaying() override { return MidiPlayer::isPlaying(); }
+ void midiRepeat() override;
+ void stopSong() override;
+ void newMusic(int musicId, int mode) override;
+ void startMusicFade() override;
+ void setLoop(bool loop) override;
+
+ void syncVolume() override { MidiPlayer::syncVolume(); }
+};
- void newMusic(int musicId, int mode);
+#ifdef USE_VORBIS
- void freeMusic();
+class MusicManagerOGG : public MusicManager {
+private:
+ Audio::SoundHandle *_handle;
- void startMusicFade();
+public:
+ MusicManagerOGG(AccessEngine *vm);
+ ~MusicManagerOGG() override;
+
+ void midiPlay() override;
+ bool isPlaying() override;
+ void midiRepeat() override;
+ void stopSong() override;
+ void newMusic(int musicId, int mode) override;
+ void startMusicFade() override;
+ void setLoop(bool loop) override;
+ void syncVolume() override;
+
+ void loadMusic(int fileNum, int subfile) override;
+};
- void loadMusic(int fileNum, int subfile);
- void loadMusic(FileIdent file);
+#endif
- void setLoop(bool loop);
-};
} // End of namespace Access
#endif /* ACCESS_SOUND_H*/
More information about the Scummvm-git-logs
mailing list