[Scummvm-git-logs] scummvm master -> 9da2293650a8e4239f4c18cfc0a04bf566c2b6eb
dreammaster
paulfgilbert at gmail.com
Thu May 7 04:03:22 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:
9343c45451 ULTIMA4: Remove deprecated in-game music & sfx volume levels
9da2293650 ULTIMA4: Implementing music player
Commit: 9343c45451ebf6dc9c0c7c4a17909404cc4e9efa
https://github.com/scummvm/scummvm/commit/9343c45451ebf6dc9c0c7c4a17909404cc4e9efa
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-05-06T19:16:02-07:00
Commit Message:
ULTIMA4: Remove deprecated in-game music & sfx volume levels
Changed paths:
engines/ultima/ultima4/controllers/intro_controller.cpp
engines/ultima/ultima4/controllers/intro_controller.h
engines/ultima/ultima4/core/settings.cpp
engines/ultima/ultima4/core/settings.h
engines/ultima/ultima4/sound/music.cpp
engines/ultima/ultima4/sound/music.h
engines/ultima/ultima4/sound/sound.cpp
diff --git a/engines/ultima/ultima4/controllers/intro_controller.cpp b/engines/ultima/ultima4/controllers/intro_controller.cpp
index 38766223da..aa0c776827 100644
--- a/engines/ultima/ultima4/controllers/intro_controller.cpp
+++ b/engines/ultima/ultima4/controllers/intro_controller.cpp
@@ -227,8 +227,6 @@ IntroController::IntroController() : Controller(1),
_soundMenu.setTitle("Sound Options:", 0, 0);
- _soundMenu.add(MI_SOUND_01, new IntMenuItem("Music Volume %s", 2, 2,/*'m'*/ 0, &_settingsChanged._musicVol, 0, MAX_VOLUME, 1, MENU_OUTPUT_VOLUME));
- _soundMenu.add(MI_SOUND_02, new IntMenuItem("Sound Effect Volume %s", 2, 3,/*'s'*/ 0, &_settingsChanged._soundVol, 0, MAX_VOLUME, 1, MENU_OUTPUT_VOLUME));
_soundMenu.add(MI_SOUND_03, new BoolMenuItem("Fading %s", 2, 4,/*'f'*/ 0, &_settingsChanged._volumeFades));
_soundMenu.add(USE_SETTINGS, "\010 Use These Settings", 2, 11,/*'u'*/ 2);
_soundMenu.add(CANCEL, "\010 Cancel", 2, 12,/*'c'*/ 2);
@@ -1108,13 +1106,6 @@ void IntroController::updateSoundMenu(MenuEvent &event) {
event.getType() == MenuEvent::DECREMENT) {
switch (event.getMenuItem()->getId()) {
- case MI_SOUND_01:
- g_music->setMusicVolume(_settingsChanged._musicVol);
- break;
- case MI_SOUND_02:
- g_music->setSoundVolume(_settingsChanged._soundVol);
- soundPlay(SOUND_FLEE);
- break;
case USE_SETTINGS:
// save settings
settings.setData(_settingsChanged);
@@ -1122,8 +1113,6 @@ void IntroController::updateSoundMenu(MenuEvent &event) {
g_music->intro();
break;
case CANCEL:
- g_music->setMusicVolume(settings._musicVol);
- g_music->setSoundVolume(settings._soundVol);
// discard settings
_settingsChanged = settings;
break;
diff --git a/engines/ultima/ultima4/controllers/intro_controller.h b/engines/ultima/ultima4/controllers/intro_controller.h
index b133f1f55f..1d437be6eb 100644
--- a/engines/ultima/ultima4/controllers/intro_controller.h
+++ b/engines/ultima/ultima4/controllers/intro_controller.h
@@ -291,8 +291,6 @@ private:
MI_GFX_TILE_TRANSPARENCY_SHADOW_SIZE,
MI_GFX_TILE_TRANSPARENCY_SHADOW_OPACITY,
MI_GFX_RETURN,
- MI_SOUND_01,
- MI_SOUND_02,
MI_SOUND_03,
MI_INPUT_01,
MI_INPUT_02,
diff --git a/engines/ultima/ultima4/core/settings.cpp b/engines/ultima/ultima4/core/settings.cpp
index 3912c1a8ee..24c672226a 100644
--- a/engines/ultima/ultima4/core/settings.cpp
+++ b/engines/ultima/ultima4/core/settings.cpp
@@ -136,10 +136,6 @@ bool Settings::write() {
}
void Settings::synchronize(Shared::ConfSerializer &s) {
- // TODO: Deprecate these
- _musicVol = DEFAULT_MUSIC_VOLUME;
- _soundVol = DEFAULT_SOUND_VOLUME;
-
// General settings
bool isEnhanced = g_ultima->isEnhanced();
s.syncAsString("video", _videoType, isEnhanced ? "new" : "EGA");
diff --git a/engines/ultima/ultima4/core/settings.h b/engines/ultima/ultima4/core/settings.h
index 9b986d2478..b6b51b2321 100644
--- a/engines/ultima/ultima4/core/settings.h
+++ b/engines/ultima/ultima4/core/settings.h
@@ -48,8 +48,6 @@ namespace Ultima4 {
#define DEFAULT_LINEOFSIGHT "DOS"
#define DEFAULT_SCREEN_SHAKES 1
#define DEFAULT_GAMMA 100
-#define DEFAULT_MUSIC_VOLUME 10
-#define DEFAULT_SOUND_VOLUME 10
#define DEFAULT_VOLUME_FADES 1
#define DEFAULT_SHORTCUT_COMMANDS 0
#define DEFAULT_KEY_DELAY 500
@@ -123,14 +121,12 @@ public:
int _keyDelay;
int _keyInterval;
MouseOptions _mouseOptions;
- int _musicVol;
uint _scale;
bool _screenShakes;
int _gamma;
int _shakeInterval;
bool _shortcutCommands;
int _shrineTime;
- int _soundVol;
int _spellEffectSpeed;
bool _validateXml;
bool _volumeFades;
diff --git a/engines/ultima/ultima4/sound/music.cpp b/engines/ultima/ultima4/sound/music.cpp
index 97bd7e5734..267eed1669 100644
--- a/engines/ultima/ultima4/sound/music.cpp
+++ b/engines/ultima/ultima4/sound/music.cpp
@@ -76,8 +76,8 @@ Music::Music() : _introMid(TOWNS), _current(NONE), _playing(nullptr) {
create_sys(); // Call the Sound System specific creation file.
- // Set up the volume.
- _on = settings._musicVol;
+ // TODO: Deprecate this
+ _on = 10;
}
Music::~Music() {
@@ -178,39 +178,6 @@ void Music::fadeIn(int msecs, bool loadFromMap) {
}
}
-int Music::increaseMusicVolume() {
- if (++settings._musicVol > MAX_VOLUME)
- settings._musicVol = MAX_VOLUME;
- else
- setMusicVolume(settings._musicVol);
- return (settings._musicVol * 100 / MAX_VOLUME); // percentage
-}
-
-int Music::decreaseMusicVolume() {
- if (--settings._musicVol < 0)
- settings._musicVol = 0;
- else
- setMusicVolume(settings._musicVol);
- return (settings._musicVol * 100 / MAX_VOLUME); // percentage
-}
-
-int Music::increaseSoundVolume() {
- if (++settings._soundVol > MAX_VOLUME)
- settings._soundVol = MAX_VOLUME;
- else
- setSoundVolume(settings._soundVol);
- return (settings._soundVol * 100 / MAX_VOLUME); // percentage
-}
-
-int Music::decreaseSoundVolume() {
- if (--settings._soundVol < 0)
- settings._soundVol = 0;
- else
- setSoundVolume(settings._soundVol);
- return (settings._soundVol * 100 / MAX_VOLUME); // percentage
-}
-
-
void Music::create_sys() {
_functional = true;
}
diff --git a/engines/ultima/ultima4/sound/music.h b/engines/ultima/ultima4/sound/music.h
index e6a9a3e37c..ffbede7bf0 100644
--- a/engines/ultima/ultima4/sound/music.h
+++ b/engines/ultima/ultima4/sound/music.h
@@ -154,17 +154,6 @@ public:
*/
bool toggle();
- int decreaseMusicVolume();
- int increaseMusicVolume();
- void setMusicVolume(int volume) {
- setMusicVolume_sys(volume);
- }
- int decreaseSoundVolume();
- int increaseSoundVolume();
- void setSoundVolume(int volume) {
- setSoundVolume_sys(volume);
- }
-
private:
void create_sys();
void destroy_sys();
diff --git a/engines/ultima/ultima4/sound/sound.cpp b/engines/ultima/ultima4/sound/sound.cpp
index 9b84efe883..410f99d0cb 100644
--- a/engines/ultima/ultima4/sound/sound.cpp
+++ b/engines/ultima/ultima4/sound/sound.cpp
@@ -80,7 +80,7 @@ bool SoundManager::load(Sound sound) {
ASSERT(sound < SOUND_MAX, "Attempted to load an invalid sound in soundLoad()");
// If music didn't initialize correctly, then we can't play it anyway
- if (!Music::_functional || !settings._soundVol)
+ if (!Music::_functional)
return false;
if (_sounds[sound] == nullptr) {
@@ -97,7 +97,7 @@ void SoundManager::play(Sound sound, bool onlyOnce, int specificDurationInTicks)
ASSERT(sound < SOUND_MAX, "Attempted to play an invalid sound in soundPlay()");
// If music didn't initialize correctly, then we can't play it anyway
- if (!Music::_functional || !settings._soundVol)
+ if (!Music::_functional)
return;
if (_sounds[sound] == nullptr) {
Commit: 9da2293650a8e4239f4c18cfc0a04bf566c2b6eb
https://github.com/scummvm/scummvm/commit/9da2293650a8e4239f4c18cfc0a04bf566c2b6eb
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-05-06T21:02:25-07:00
Commit Message:
ULTIMA4: Implementing music player
Currently only .mp3 and .mid files are supported. The .it music
files aren't yet
Changed paths:
engines/ultima/ultima4/controllers/camp_controller.cpp
engines/ultima/ultima4/controllers/combat_controller.cpp
engines/ultima/ultima4/controllers/game_controller.cpp
engines/ultima/ultima4/core/debugger.cpp
engines/ultima/ultima4/core/debugger.h
engines/ultima/ultima4/game/codex.cpp
engines/ultima/ultima4/game/death.cpp
engines/ultima/ultima4/game/person.cpp
engines/ultima/ultima4/game/portal.cpp
engines/ultima/ultima4/game/script.cpp
engines/ultima/ultima4/game/spell.cpp
engines/ultima/ultima4/map/shrine.cpp
engines/ultima/ultima4/sound/music.cpp
engines/ultima/ultima4/sound/music.h
engines/ultima/ultima4/sound/sound.cpp
engines/ultima/ultima4/ultima4.cpp
diff --git a/engines/ultima/ultima4/controllers/camp_controller.cpp b/engines/ultima/ultima4/controllers/camp_controller.cpp
index 6162066e9a..40013b019c 100644
--- a/engines/ultima/ultima4/controllers/camp_controller.cpp
+++ b/engines/ultima/ultima4/controllers/camp_controller.cpp
@@ -67,7 +67,7 @@ void CampController::begin() {
if (settings._campingAlwaysCombat || (xu4_random(8) == 0)) {
const Creature *m = creatureMgr->randomAmbushing();
- g_music->play();
+ g_music->playMapMusic();
g_screen->screenMessage("Ambushed!\n");
/* create an ambushing creature (so it leaves a chest) */
diff --git a/engines/ultima/ultima4/controllers/combat_controller.cpp b/engines/ultima/ultima4/controllers/combat_controller.cpp
index 8123c2fb99..5ab79ecd33 100644
--- a/engines/ultima/ultima4/controllers/combat_controller.cpp
+++ b/engines/ultima/ultima4/controllers/combat_controller.cpp
@@ -290,7 +290,7 @@ void CombatController::begin() {
/* FIXME: there should be a better way to accomplish this */
if (!_camping) {
- g_music->play();
+ g_music->playMapMusic();
}
/* Set focus to the first active party member, if there is one */
@@ -325,7 +325,7 @@ void CombatController::end(bool adjustKarma) {
bool won = isWon();
g_game->exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
if (_winOrLose) {
if (won) {
diff --git a/engines/ultima/ultima4/controllers/game_controller.cpp b/engines/ultima/ultima4/controllers/game_controller.cpp
index b6557d31af..b7ee10e243 100644
--- a/engines/ultima/ultima4/controllers/game_controller.cpp
+++ b/engines/ultima/ultima4/controllers/game_controller.cpp
@@ -65,7 +65,7 @@ void GameController::initScreen() {
}
void GameController::initScreenWithoutReloadingState() {
- g_music->play();
+ g_music->playMapMusic();
imageMgr->get(BKGD_BORDERS)->_image->draw(0, 0);
g_context->_stats->update(); /* draw the party stats */
@@ -516,7 +516,7 @@ void GameController::avatarMoved(MoveEvent &event) {
if (event._result & MOVE_EXIT_TO_PARENT) {
g_screen->screenMessage("%cLeaving...%c\n", FG_GREY, FG_WHITE);
exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
}
/* things that happen while not on board the balloon */
@@ -554,7 +554,7 @@ void GameController::avatarMovedInDungeon(MoveEvent &event) {
if (event._result & MOVE_EXIT_TO_PARENT) {
g_screen->screenMessage("%cLeaving...%c\n", FG_GREY, FG_WHITE);
exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
}
/* check to see if we're entering a dungeon room */
@@ -699,7 +699,7 @@ bool GameController::checkMoongates() {
return true;
setMap(shrine_spirituality, 1, nullptr);
- g_music->play();
+ g_music->playMapMusic();
shrine_spirituality->enter();
}
diff --git a/engines/ultima/ultima4/core/debugger.cpp b/engines/ultima/ultima4/core/debugger.cpp
index e99bc2a8d0..fe19f2d4d9 100644
--- a/engines/ultima/ultima4/core/debugger.cpp
+++ b/engines/ultima/ultima4/core/debugger.cpp
@@ -86,7 +86,6 @@ Debugger::Debugger() : Shared::Debugger() {
registerCmd("speed", WRAP_METHOD(Debugger, cmdSpeed));
registerCmd("combat_speed", WRAP_METHOD(Debugger, cmdCombatSpeed));
- registerCmd("musicToggle", WRAP_METHOD(Debugger, cmdMusicToggle));
registerCmd("3d", WRAP_METHOD(Debugger, cmd3d));
registerCmd("abyss", WRAP_METHOD(Debugger, cmdAbyss));
@@ -821,16 +820,6 @@ bool Debugger::cmdMixReagents(int argc, const char **argv) {
return isDebuggerActive();
}
-bool Debugger::cmdMusicToggle(int argc, const char **argv) {
- if (g_music->toggle())
- print("Volume On!");
- else
- print("Volume Off!");
-
- dontEndTurn();
- return isDebuggerActive();
-}
-
bool Debugger::cmdNewOrder(int argc, const char **argv) {
printN("New Order!\nExchange # ");
@@ -1496,7 +1485,7 @@ bool Debugger::cmdLeave(int argc, const char **argv) {
if (!g_game->exitToParentMap()) {
print("Not Here");
} else {
- g_music->play();
+ g_music->playMapMusic();
print("Exited");
}
@@ -1710,7 +1699,7 @@ bool Debugger::cmdUp(int argc, const char **argv) {
} else {
print("Leaving...");
g_game->exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
return isDebuggerActive();
}
diff --git a/engines/ultima/ultima4/core/debugger.h b/engines/ultima/ultima4/core/debugger.h
index 36d61e9a78..5cdbaa7477 100644
--- a/engines/ultima/ultima4/core/debugger.h
+++ b/engines/ultima/ultima4/core/debugger.h
@@ -163,11 +163,6 @@ private:
*/
bool cmdMixReagents(int argc, const char **argv);
- /**
- * Toggles music
- */
- bool cmdMusicToggle(int argc, const char **argv);
-
/**
* Exchanges the position of two players in the party. Prompts the
* user for the player numbers.
diff --git a/engines/ultima/ultima4/game/codex.cpp b/engines/ultima/ultima4/game/codex.cpp
index eb12942498..db024efa14 100644
--- a/engines/ultima/ultima4/game/codex.cpp
+++ b/engines/ultima/ultima4/game/codex.cpp
@@ -169,7 +169,7 @@ void Codex::eject(CodexEjectCode code) {
// Return view to normal and exit the Abyss
gameSetViewMode(VIEW_NORMAL);
g_game->exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
/*
* if being ejected because of a missed virtue question,
diff --git a/engines/ultima/ultima4/game/death.cpp b/engines/ultima/ultima4/game/death.cpp
index 3d824f89d5..005e717426 100644
--- a/engines/ultima/ultima4/game/death.cpp
+++ b/engines/ultima/ultima4/game/death.cpp
@@ -135,7 +135,7 @@ void Death::revive() {
g_context->_aura->set();
g_context->_horseSpeed = 0;
g_context->_lastCommandTime = g_system->getMillis();
- g_music->play();
+ g_music->playMapMusic();
g_context->_party->reviveParty();
diff --git a/engines/ultima/ultima4/game/person.cpp b/engines/ultima/ultima4/game/person.cpp
index 5732a44d3e..bf2cdd8cf5 100644
--- a/engines/ultima/ultima4/game/person.cpp
+++ b/engines/ultima/ultima4/game/person.cpp
@@ -388,7 +388,7 @@ void Person::runCommand(Conversation *cnv, const ResponsePart &command) {
} else if (command == g_responseParts->STARTMUSIC_HW) {
g_music->hawkwind();
} else if (command == g_responseParts->STOPMUSIC) {
- g_music->play();
+ g_music->playMapMusic();
} else if (command == g_responseParts->HAWKWIND) {
g_context->_party->adjustKarma(KA_HAWKWIND);
} else {
diff --git a/engines/ultima/ultima4/game/portal.cpp b/engines/ultima/ultima4/game/portal.cpp
index 7fbfa55c28..3f7ba33423 100644
--- a/engines/ultima/ultima4/game/portal.cpp
+++ b/engines/ultima/ultima4/game/portal.cpp
@@ -139,14 +139,14 @@ int usePortalAt(Location *location, MapCoords coords, PortalTriggerAction action
/* portal just exits to parent map */
if (portal->_exitPortal) {
g_game->exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
return 1;
} else if (portal->_destid == location->_map->_id)
location->_coords = portal->_start;
else {
g_game->setMap(destination, portal->_saveLocation, portal);
- g_music->play();
+ g_music->playMapMusic();
}
/* if the portal changes the map retroactively, do it here */
diff --git a/engines/ultima/ultima4/game/script.cpp b/engines/ultima/ultima4/game/script.cpp
index bb330b6ed3..f955d2ab42 100644
--- a/engines/ultima/ultima4/game/script.cpp
+++ b/engines/ultima/ultima4/game/script.cpp
@@ -1273,12 +1273,12 @@ Script::ReturnCode Script::karma(Shared::XMLNode *script, Shared::XMLNode *curre
Script::ReturnCode Script::music(Shared::XMLNode *script, Shared::XMLNode *current) {
if (current->getPropertyBool("reset"))
- g_music->play();
+ g_music->playMapMusic();
else {
Common::String type = getPropAsStr(current, "type");
if (current->getPropertyBool("play"))
- g_music->play();
+ g_music->playMapMusic();
if (current->getPropertyBool("stop"))
g_music->stop();
else if (type == "shopping")
diff --git a/engines/ultima/ultima4/game/spell.cpp b/engines/ultima/ultima4/game/spell.cpp
index bb33770012..7800017989 100644
--- a/engines/ultima/ultima4/game/spell.cpp
+++ b/engines/ultima/ultima4/game/spell.cpp
@@ -730,7 +730,7 @@ int Spells::spellXit(int unused) {
if (!g_context->_location->_map->isWorldMap()) {
g_screen->screenMessage("Leaving...\n");
g_game->exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
return 1;
}
return 0;
@@ -757,7 +757,7 @@ int Spells::spellYup(int unused) {
} else {
g_screen->screenMessage("Leaving...\n");
g_game->exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
return 1;
}
diff --git a/engines/ultima/ultima4/map/shrine.cpp b/engines/ultima/ultima4/map/shrine.cpp
index 3770346720..456916b827 100644
--- a/engines/ultima/ultima4/map/shrine.cpp
+++ b/engines/ultima/ultima4/map/shrine.cpp
@@ -292,7 +292,7 @@ void Shrine::showVision(bool elevated) {
void Shrine::eject() {
g_game->exitToParentMap();
- g_music->play();
+ g_music->playMapMusic();
g_context->_location->_turnCompleter->finishTurn();
}
diff --git a/engines/ultima/ultima4/sound/music.cpp b/engines/ultima/ultima4/sound/music.cpp
index 267eed1669..17d1d68b0b 100644
--- a/engines/ultima/ultima4/sound/music.cpp
+++ b/engines/ultima/ultima4/sound/music.cpp
@@ -33,28 +33,28 @@
#include "ultima/shared/core/file.h"
#include "audio/decoders/mp3.h"
#include "audio/mods/mod_xm_s3m.h"
+#include "audio/midiparser.h"
namespace Ultima {
namespace Ultima4 {
-/*
- * Static variables
- */
Music *g_music;
-bool Music::_fading;
-bool Music::_on;
-bool Music::_functional;
+Music::Music(Audio::Mixer *mixer) :
+ Audio::MidiPlayer(), _mixer(mixer), _introMid(TOWNS) {
+ g_music = this;
+ Audio::MidiPlayer::createDriver();
-/*
- * Constructors/Destructors
- */
+ int ret = _driver->open();
+ if (ret == 0) {
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+
+ _driver->setTimerCallback(this, &timerCallback);
+ }
-Music::Music() : _introMid(TOWNS), _current(NONE), _playing(nullptr) {
- g_music = this;
- _fading = false;
- _on = false;
- _functional = true;
_filenames.reserve(MAX);
_filenames.push_back(""); // filename for MUSIC_NONE;
@@ -73,188 +73,113 @@ Music::Music() : _introMid(TOWNS), _current(NONE), _playing(nullptr) {
_filenames.push_back(i->getString("file"));
}
-
- create_sys(); // Call the Sound System specific creation file.
-
- // TODO: Deprecate this
- _on = 10;
}
Music::~Music() {
+ stop();
g_music = nullptr;
- eventHandler->getTimer()->remove(&Music::callback);
- destroy_sys(); // Call the Sound System specific destruction file.
-}
-
-bool Music::isPlaying() {
- return g_music->isPlaying_sys();
}
-
-bool Music::load(Type music) {
- ASSERT(music < MAX, "Attempted to load an invalid piece of music in Music::load()");
-
- /* music already loaded */
- if (music == _current) {
- /* tell calling function it didn't load correctly (because it's already playing) */
- if (isPlaying())
- return false;
- /* it loaded correctly */
- else
- return true;
- }
-
- Common::String pathName(u4find_music(_filenames[music]));
- if (!pathName.empty()) {
- bool status = load_sys(pathName);
- if (status)
- _current = music;
- return status;
+void Music::sendToChannel(byte channel, uint32 b) {
+ if (!_channelsTable[channel]) {
+ _channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
+ // If a new channel is allocated during the playback, make sure
+ // its volume is correctly initialized.
+ if (_channelsTable[channel])
+ _channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255);
}
- return false;
-}
-void Music::callback(void *data) {
- eventHandler->getTimer()->remove(&Music::callback);
-
- if (g_music->_on && !isPlaying())
- g_music->play();
- else if (!g_music->_on && isPlaying())
- g_music->stop();
+ if (_channelsTable[channel])
+ _channelsTable[channel]->send(b);
}
-void Music::play() {
- playMid(g_context->_location->_map->_music);
+void Music::playMusic(Type music) {
+ playMusic(_filenames[music]);
}
-void Music::introSwitch(int n) {
- if (n > NONE && n < MAX) {
- _introMid = static_cast<Type>(n);
- intro();
- }
+void Music::playMapMusic() {
+ playMusic(g_context->_location->_map->_music);
}
-bool Music::toggle() {
- eventHandler->getTimer()->remove(&Music::callback);
-
- _on = !_on;
- if (!_on)
- fadeOut(1000);
- else
- fadeIn(1000, true);
-
- eventHandler->getTimer()->add(&Music::callback, settings._gameCyclesPerSecond);
- return _on;
-}
-
-void Music::fadeOut(int msecs) {
- // fade the music out even if '_on' is false
- if (!_functional)
- return;
-
- if (isPlaying()) {
- if (!settings._volumeFades)
- stop();
- else {
- fadeOut_sys(msecs);
- }
- }
-}
+void Music::playMusic(const Common::String &filename) {
+ stop();
+ Common::StackLock lock(_mutex);
-void Music::fadeIn(int msecs, bool loadFromMap) {
- if (!_functional || !_on)
+ // First try opening the file with whatever filename is provided
+ if (startMusic(filename))
return;
- if (!isPlaying()) {
- // make sure we've got something loaded to play
- if (loadFromMap || !_playing)
- load(g_context->_location->_map->_music);
-
- if (!settings._volumeFades)
- play();
- else {
- fadeIn_sys(msecs, loadFromMap);
- }
+ // TODO: Since the player doesn't yet support xu4 .it files,
+ // try starting the file with other extensions - which some have
+ const char *const EXTENSIONS[2] = { ".mp3", ".mid" };
+ for (int idx = 0; idx < 2; ++idx) {
+ size_t dotIndex = filename.findLastOf('.');
+ Common::String fname = (dotIndex != Common::String::npos) ?
+ Common::String(filename.c_str(), dotIndex) + EXTENSIONS[idx] :
+ filename + EXTENSIONS[idx];
+ if (startMusic(fname))
+ return;
}
-}
-
-void Music::create_sys() {
- _functional = true;
-}
-void Music::destroy_sys() {
+ // At this point, we couldn't open the given music file
+ warning("No support for playing music file - %s", filename.c_str());
}
-bool Music::load_sys(const Common::String &pathName) {
- delete _playing;
- _playing = nullptr;
+bool Music::startMusic(const Common::String &filename) {
+ Common::File musicFile;
+ if (!musicFile.open(Common::String::format("data/mid/%s", filename.c_str())))
+ // No such file exists
+ return false;
- if (pathName.hasSuffixIgnoreCase(".it")) {
- warning("TODO: Play music file - %s", pathName.c_str());
+ if (filename.hasSuffixIgnoreCase(".mp3")) {
+ Audio::SeekableAudioStream *audioStream = Audio::makeMP3Stream(
+ musicFile.readStream(musicFile.size()), DisposeAfterUse::YES);
+ _mixer->playStream(Audio::Mixer::kMusicSoundType,
+ &_soundHandle, audioStream);
return true;
- }
- Shared::File f;
- if (!f.open(pathName)) {
- warning("unable to load music file %s", pathName.c_str());
- return false;
- }
+ } else if (filename.hasSuffixIgnoreCase(".mid")) {
+ // Load MIDI resource data
+ int midiMusicSize = musicFile.size();
+ free(_midiData);
+ _midiData = (byte *)malloc(midiMusicSize);
+ musicFile.read(_midiData, midiMusicSize);
+ musicFile.close();
- if (pathName.hasSuffixIgnoreCase(".mp3")) {
-#ifdef USE_MAD
- Common::SeekableReadStream *s = f.readStream(f.size());
- _playing = Audio::makeMP3Stream(s, DisposeAfterUse::YES);
-#endif
- } else if (pathName.hasSuffixIgnoreCase(".it"))
- _playing = nullptr;
- else
- error("Unknown sound file");
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(_midiData, midiMusicSize)) {
+ parser->setTrack(0);
+ parser->setMidiDriver(this);
+ parser->setTimerRate(_driver->getBaseTempo());
+ parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
- return true;
-}
+ _parser = parser;
-void Music::playMid(Type music) {
- if (!_functional || !_on)
- return;
+ syncVolume();
- // loaded a new piece of music
- if (load(music)) {
- stopMid();
- g_ultima->_mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, _playing,
- -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES);
+ _isLooping = false;
+ _isPlaying = true;
+ return true;
+ } else {
+ delete parser;
+ return false;
+ }
+ } else {
+ return false;
}
}
-void Music::stopMid() {
- g_ultima->_mixer->stopHandle(_soundHandle);
-}
-
-void Music::setSoundVolume_sys(int volume) {
- uint vol = 255 * volume / MAX_VOLUME;
- g_ultima->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol);
-}
-
-bool Music::isPlaying_sys() {
- return g_ultima->_mixer->isSoundHandleActive(_soundHandle);
+void Music::stop() {
+ Common::StackLock lock(_mutex);
+ _mixer->stopHandle(_soundHandle);
+ Audio::MidiPlayer::stop();
}
-void Music::setMusicVolume_sys(int volume) {
- uint vol = 255 * volume / MAX_VOLUME;
- g_ultima->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol);
-}
-
-void Music::fadeIn_sys(int msecs, bool loadFromMap) {
-#ifdef TODO
- if (Mix_FadeInMusic(playing, NLOOPS, msecs) == -1)
- warning("Mix_FadeInMusic: %s\n", Mix_GetError());
-#endif
-}
-
-void Music::fadeOut_sys(int msecs) {
-#ifdef TODO
- if (Mix_FadeOutMusic(msecs) == -1)
- warning("Mix_FadeOutMusic: %s\n", Mix_GetError());
-#endif
+void Music::introSwitch(int n) {
+ if (n > NONE &&n < MAX) {
+ _introMid = static_cast<Type>(n);
+ intro();
+ }
}
} // End of namespace Ultima4
diff --git a/engines/ultima/ultima4/sound/music.h b/engines/ultima/ultima4/sound/music.h
index ffbede7bf0..f2275a53e4 100644
--- a/engines/ultima/ultima4/sound/music.h
+++ b/engines/ultima/ultima4/sound/music.h
@@ -25,6 +25,7 @@
#include "ultima/shared/std/containers.h"
#include "audio/audiostream.h"
+#include "audio/midiplayer.h"
#include "audio/mixer.h"
namespace Ultima {
@@ -36,13 +37,9 @@ namespace Ultima4 {
#define INN_FADE_IN_TIME 5000
#define NLOOPS -1
-struct _Mix_Music;
-typedef _Mix_Music OSMusicMixer;
-class Music {
+class Music : public Audio::MidiPlayer {
public:
- static bool _functional;
-
enum Type {
NONE,
OUTSIDE,
@@ -57,71 +54,67 @@ public:
MAX
};
- /*
- * Properties
- */
- Std::vector<Common::String> _filenames;
Type _introMid;
- Type _current;
- Audio::AudioStream *_playing;
+private:
+ Audio::Mixer *_mixer;
Audio::SoundHandle _soundHandle;
-public:
- /**
- * Initiliaze the music
- */
- Music();
+ Std::vector<Common::String> _filenames;
/**
- * Stop playing the music and cleanup
+ * Play a given music file if is exists
*/
- ~Music();
+ bool startMusic(const Common::String &filename);
+protected:
+ // Overload Audio::MidiPlayer method
+ void sendToChannel(byte channel, uint32 b) override;
+public:
+ Music(Audio::Mixer *mixer);
+ ~Music() override;
/**
- * Returns true if the mixer is playing any audio
+ * Play music
*/
- static bool isPlaying();
+ void playMusic(const Common::String &filename);
/**
- * Ensures that the music is playing if it is supposed to be, or off
- * if it is supposed to be turned off.
+ * Play music of a given type
*/
- static void callback(void *);
+ void playMusic(Type music);
/**
- * Main music loop
+ * Play the designated music for the current map
*/
- void play();
+ void playMapMusic();
+
+ void stop() override;
- /**
- * Stop playing music
- */
- void stop() {
- _on = false;
- stopMid();
- }
/**
* Fade out the music
*/
- void fadeOut(int msecs);
+ void fadeOut(int msecs) {
+ // TODO
+ }
/**
* Fade in the music
*/
- void fadeIn(int msecs, bool loadFromMap);
+ void fadeIn(int msecs, bool loadFromMap) {
+ // TODO
+ }
/**
* Music when you talk to Lord British
*/
void lordBritish() {
- playMid(RULEBRIT);
+ playMusic(RULEBRIT);
}
/**
* Music when you talk to Hawkwind
*/
void hawkwind() {
- playMid(SHOPPING);
+ playMusic(SHOPPING);
}
/**
@@ -135,64 +128,20 @@ public:
* Music when talking to a vendor
*/
void shopping() {
- playMid(SHOPPING);
+ playMusic(SHOPPING);
}
+
void intro() {
#ifdef IOS_ULTIMA4
_on = true; // Force iOS to turn this back on from going in the background.
#endif
- playMid(_introMid);
+ playMusic(_introMid);
}
/**
* Cycle through the introduction music
*/
void introSwitch(int n);
-
- /**
- * Toggle the music on/off (usually by pressing 'v')
- */
- bool toggle();
-
-private:
- void create_sys();
- void destroy_sys();
-
- /**
- * Set, increase, and decrease music volume
- */
- void setMusicVolume_sys(int volume);
-
- /**
- * Set, increase, and decrease sound volume
- */
- void setSoundVolume_sys(int volume);
- void fadeOut_sys(int msecs);
- void fadeIn_sys(int msecs, bool loadFromMap);
-
- /**
- * System specific version to check if the version is still playing.
- */
- bool isPlaying_sys();
-
- static Music *_instance;
- static bool _fading;
- static bool _on;
-
-
- bool load_sys(const Common::String &pathName);
-
- /**
- * Play a midi file
- */
- void playMid(Type music);
-
- /**
- * Stop playing a MIDI file.
- */
- void stopMid();
-
- bool load(Type music);
};
extern Music *g_music;
diff --git a/engines/ultima/ultima4/sound/sound.cpp b/engines/ultima/ultima4/sound/sound.cpp
index 410f99d0cb..25918ae34b 100644
--- a/engines/ultima/ultima4/sound/sound.cpp
+++ b/engines/ultima/ultima4/sound/sound.cpp
@@ -77,11 +77,7 @@ SoundManager::~SoundManager() {
}
bool SoundManager::load(Sound sound) {
- ASSERT(sound < SOUND_MAX, "Attempted to load an invalid sound in soundLoad()");
-
- // If music didn't initialize correctly, then we can't play it anyway
- if (!Music::_functional)
- return false;
+ ASSERT(sound < SOUND_MAX, "Attempted to load an invalid sound");
if (_sounds[sound] == nullptr) {
Common::String pathname(u4find_sound(_soundFilenames[sound]));
@@ -94,11 +90,7 @@ bool SoundManager::load(Sound sound) {
}
void SoundManager::play(Sound sound, bool onlyOnce, int specificDurationInTicks) {
- ASSERT(sound < SOUND_MAX, "Attempted to play an invalid sound in soundPlay()");
-
- // If music didn't initialize correctly, then we can't play it anyway
- if (!Music::_functional)
- return;
+ ASSERT(sound < SOUND_MAX, "Attempted to play an invalid sound");
if (_sounds[sound] == nullptr) {
if (!load(sound)) {
@@ -121,20 +113,20 @@ bool SoundManager::load_sys(Sound sound, const Common::String &filename) {
Audio::SeekableAudioStream *audioStream = nullptr;
#ifdef USE_FLAC
- if (filename.hasSuffix(".fla"))
+ if (filename.hasSuffixIgnoreCase(".fla"))
audioStream = Audio::makeFLACStream(f.readStream(f.size()), DisposeAfterUse::YES);
#endif
#ifdef USE_VORBIS
- if (filename.hasSuffix(".ogg"))
+ if (filename.hasSuffixIgnoreCase(".ogg"))
audioStream = Audio::makeVorbisStream(f.readStream(f.size()), DisposeAfterUse::YES);
#endif
#ifdef USE_MAD
- if (filename.hasSuffix(".mp3"))
+ if (filename.hasSuffixIgnoreCase(".mp3"))
audioStream = Audio::makeMP3Stream(f.readStream(f.size()), DisposeAfterUse::YES);
#endif
- if (filename.hasSuffix(".wav"))
+ if (filename.hasSuffixIgnoreCase(".wav"))
audioStream = Audio::makeWAVStream(f.readStream(f.size()), DisposeAfterUse::YES);
- if (filename.hasSuffix(".voc"))
+ if (filename.hasSuffixIgnoreCase(".voc"))
audioStream = Audio::makeVOCStream(f.readStream(f.size()), DisposeAfterUse::YES);
_sounds[sound] = audioStream;
diff --git a/engines/ultima/ultima4/ultima4.cpp b/engines/ultima/ultima4/ultima4.cpp
index 6a2cc75758..aebc1bacaf 100644
--- a/engines/ultima/ultima4/ultima4.cpp
+++ b/engines/ultima/ultima4/ultima4.cpp
@@ -73,6 +73,7 @@ Ultima4Engine::Ultima4Engine(OSystem *syst, const Ultima::UltimaGameDescription
g_items = nullptr;
g_mapLoaders = nullptr;
g_moongates = nullptr;
+ g_music = nullptr;
g_responseParts = nullptr;
g_screen = nullptr;
g_shrines = nullptr;
@@ -127,18 +128,18 @@ bool Ultima4Engine::initialize() {
_items = new Items();
_mapLoaders = new MapLoaders();
_moongates = new Moongates();
+ _music = new Music(_mixer);
+ _soundManager = new SoundManager(_mixer);
_responseParts = new ResponseParts();
_screen = new Screen();
_screen->init();
_shrines = new Shrines();
- _soundManager = new SoundManager(_mixer);
_spells = new Spells();
_tileRules = new TileRules();
_tileSets = new TileSets();
_tileMaps = new TileMaps();
_game = new GameController();
_imageLoaders = new ImageLoaders();
- _music = new Music();
_saveGame = new SaveGame();
_weapons = new Weapons();
More information about the Scummvm-git-logs
mailing list