Initial commit
This commit is contained in:
177
engines/crab/music/MusicManager.cpp
Normal file
177
engines/crab/music/MusicManager.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "crab/crab.h"
|
||||
#include "crab/GameParam.h"
|
||||
#include "crab/ScreenSettings.h"
|
||||
#include "crab/XMLDoc.h"
|
||||
#include "crab/music/MusicManager.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::music;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Clear stored data
|
||||
//------------------------------------------------------------------------
|
||||
void MusicManager::freeMusic() {
|
||||
delete _musicHandle;
|
||||
}
|
||||
|
||||
void MusicManager::freeChunk() {
|
||||
for (auto &i : _effects) {
|
||||
i._value->_file.close();
|
||||
delete i._value->_handle;
|
||||
delete i._value->_stream;
|
||||
delete i._value;
|
||||
}
|
||||
|
||||
_effects.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Play or queue music
|
||||
//------------------------------------------------------------------------
|
||||
void MusicManager::playMusic(const MusicKey &id) {
|
||||
if (_bg._id != id) {
|
||||
XMLDoc trackList(g_engine->_filePath->_soundMusic);
|
||||
if (trackList.ready()) {
|
||||
rapidxml::xml_node<char> *node = trackList.doc()->first_node("music");
|
||||
for (auto n = node->first_node(); n != nullptr; n = n->next_sibling()) {
|
||||
rapidxml::xml_attribute<char> *att = n->first_attribute("id");
|
||||
if (att != nullptr && id == stringToNumber<MusicKey>(att->value())) {
|
||||
if (g_system->getMixer()->isSoundHandleActive(*_musicHandle))
|
||||
g_system->getMixer()->stopHandle(*_musicHandle);
|
||||
_bg.reset();
|
||||
_bg.load(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_bg._track != nullptr && id >= 0)
|
||||
g_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, _musicHandle, _bg._track, (int)_bg._id);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Play or queue sound effects
|
||||
//------------------------------------------------------------------------
|
||||
void MusicManager::playEffect(const ChunkKey &id, const int &loops) {
|
||||
// I am not sure if the game uses a value of more than 0 anywhere.
|
||||
// For now error out in case loops > 0.
|
||||
assert(loops == 0);
|
||||
|
||||
if (_effects.contains(id)) {
|
||||
EffectAudio *audio = _effects[id];
|
||||
audio->_stream->rewind();
|
||||
g_system->getMixer()->playStream(Audio::Mixer::kSFXSoundType, audio->_handle, audio->_stream, id, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MusicManager::syncSettings() {
|
||||
bool mute = false;
|
||||
if (ConfMan.hasKey("mute"))
|
||||
mute = ConfMan.getBool("mute");
|
||||
|
||||
int volumeEff = mute ? 0 : ConfMan.getInt("sfx_volume");
|
||||
int volumeMus = mute ? 0 : ConfMan.getInt("music_volume");
|
||||
|
||||
// Set the volume from the settings
|
||||
volEffects(volumeEff);
|
||||
volMusic(volumeMus);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Initialize the music subsystem and load sound effects
|
||||
//------------------------------------------------------------------------
|
||||
bool MusicManager::load(rapidxml::xml_node<char> *node) {
|
||||
_musicHandle = new Audio::SoundHandle();
|
||||
syncSettings();
|
||||
|
||||
// Load sound effects
|
||||
XMLDoc trackList(g_engine->_filePath->_soundEffect);
|
||||
if (trackList.ready()) {
|
||||
rapidxml::xml_node<char> *tnode = trackList.doc()->first_node("effects");
|
||||
if (nodeValid(tnode)) {
|
||||
loadNum(_notify, "notify", tnode);
|
||||
loadNum(_repInc, "rep_inc", tnode);
|
||||
loadNum(_repDec, "rep_dec", tnode);
|
||||
|
||||
for (auto n = tnode->first_node(); n != nullptr; n = n->next_sibling()) {
|
||||
rapidxml::xml_attribute<char> *id = n->first_attribute("id"), *path = n->first_attribute("path");
|
||||
if (id != nullptr && path != nullptr) {
|
||||
EffectAudio *audio = new EffectAudio();
|
||||
Common::Path cleansedPath = cleansePath(Common::Path(path->value(), '/'));
|
||||
if (audio->_file.open(cleansedPath)) {
|
||||
audio->_handle = new Audio::SoundHandle();
|
||||
audio->_stream = Audio::makeWAVStream(&audio->_file, DisposeAfterUse::NO);
|
||||
_effects[stringToNumber<ChunkKey>(id->value())] = audio;
|
||||
} else {
|
||||
delete audio;
|
||||
warning("Could not open audio file : %s", cleansedPath.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MusicManager::saveState() {
|
||||
bool unmute = volEffects() > 0 || volMusic() > 0;
|
||||
|
||||
// set flag in case either value is greater than 0
|
||||
if (ConfMan.hasKey("mute"))
|
||||
ConfMan.setBool("mute", !unmute);
|
||||
|
||||
ConfMan.setInt("sfx_volume", volEffects());
|
||||
ConfMan.setInt("music_volume", volMusic());
|
||||
|
||||
ConfMan.flushToDisk();
|
||||
|
||||
g_engine->syncSoundSettings();
|
||||
|
||||
#if 0
|
||||
rapidxml::xml_node<char> *child = doc.allocate_node(rapidxml::node_element, "sound");
|
||||
child->append_attribute(doc.allocate_attribute("music", g_engine->_stringPool->Get(Mix_VolumeMusic(-1))));
|
||||
child->append_attribute(doc.allocate_attribute("effects", g_engine->_stringPool->Get(Mix_Volume(0, -1))));
|
||||
child->append_attribute(doc.allocate_attribute("frequency", g_engine->_stringPool->Get(freq)));
|
||||
child->append_attribute(doc.allocate_attribute("channels", g_engine->_stringPool->Get(channels)));
|
||||
child->append_attribute(doc.allocate_attribute("chunk_size", g_engine->_stringPool->Get(chunksize)));
|
||||
root->append_node(child);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
126
engines/crab/music/MusicManager.h
Normal file
126
engines/crab/music/MusicManager.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_MUSICMANAGER_H
|
||||
#define CRAB_MUSICMANAGER_H
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "audio/decoders/wave.h"
|
||||
#include "crab/music/musicparam.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace music {
|
||||
class MusicManager {
|
||||
struct EffectAudio {
|
||||
Common::File _file;
|
||||
Audio::SeekableAudioStream *_stream;
|
||||
Audio::SoundHandle *_handle;
|
||||
};
|
||||
|
||||
// The background music for our current level
|
||||
MusicData _bg;
|
||||
|
||||
Common::HashMap<ChunkKey, EffectAudio *> _effects;
|
||||
|
||||
Audio::SoundHandle *_musicHandle;
|
||||
|
||||
public:
|
||||
// The notification sound
|
||||
ChunkKey _notify, _repInc, _repDec;
|
||||
|
||||
MusicManager() {
|
||||
_notify = -1;
|
||||
_repInc = -1;
|
||||
_repDec = -1;
|
||||
|
||||
_musicHandle = nullptr;
|
||||
}
|
||||
~MusicManager() {}
|
||||
|
||||
bool load(rapidxml::xml_node<char> *node);
|
||||
|
||||
void syncSettings();
|
||||
|
||||
void playMusic(const MusicKey &id);
|
||||
void playEffect(const ChunkKey &id, const int &loops);
|
||||
|
||||
static void pause() {
|
||||
g_system->getMixer()->pauseAll(true);
|
||||
}
|
||||
|
||||
static void resume() {
|
||||
g_system->getMixer()->pauseAll(false);
|
||||
}
|
||||
|
||||
static void stop() {
|
||||
g_system->getMixer()->stopAll();
|
||||
}
|
||||
|
||||
static void volEffects(const int &volume, const bool &unmute = false) {
|
||||
if (unmute)
|
||||
g_system->getMixer()->muteSoundType(Audio::Mixer::kSFXSoundType, false);
|
||||
g_system->getMixer()->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
|
||||
}
|
||||
|
||||
static int volEffects() {
|
||||
return g_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
|
||||
}
|
||||
|
||||
static void volMusic(const int &volume, const bool &unmute = false) {
|
||||
if (unmute)
|
||||
g_system->getMixer()->muteSoundType(Audio::Mixer::kMusicSoundType, false);
|
||||
g_system->getMixer()->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
|
||||
}
|
||||
|
||||
static int volMusic() {
|
||||
return g_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
|
||||
}
|
||||
|
||||
void saveState();
|
||||
|
||||
void freeMusic();
|
||||
void freeChunk();
|
||||
|
||||
void quit() {
|
||||
g_system->getMixer()->stopAll();
|
||||
|
||||
freeMusic();
|
||||
freeChunk();
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace music
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_MUSICMANAGER_H
|
||||
93
engines/crab/music/musicparam.h
Normal file
93
engines/crab/music/musicparam.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_MUSICPARAM_H
|
||||
#define CRAB_MUSICPARAM_H
|
||||
#include "audio/audiostream.h"
|
||||
#include "audio/decoders/vorbis.h"
|
||||
#include "common/file.h"
|
||||
#include "crab/loaders.h"
|
||||
#include "crab/filesystem.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace music {
|
||||
// We use this object as key for music tracks
|
||||
// Empty sounds are represented by -1
|
||||
typedef int MusicKey;
|
||||
|
||||
// We use this object as key for sound effects
|
||||
// Empty sounds are represented by -1
|
||||
typedef int ChunkKey;
|
||||
|
||||
struct MusicData {
|
||||
// The id of this track
|
||||
MusicKey _id;
|
||||
Audio::AudioStream *_track;
|
||||
Common::File _file;
|
||||
|
||||
// Sound parameters
|
||||
uint32 _fadeInDuration;
|
||||
|
||||
MusicData() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_id = -1;
|
||||
_track = nullptr;
|
||||
_fadeInDuration = 100;
|
||||
|
||||
if (_file.isOpen()) {
|
||||
_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node) {
|
||||
loadNum(_id, "id", node);
|
||||
loadNum(_fadeInDuration, "fade_in", node);
|
||||
|
||||
Common::Path cleansedPath = cleansePath(Common::Path(node->first_attribute("path")->value(), '/'));
|
||||
if (_file.open(cleansedPath)) {
|
||||
Audio::SeekableAudioStream *stream = Audio::makeVorbisStream(&_file, DisposeAfterUse::NO);
|
||||
// loops=0 means infinite here.
|
||||
_track = Audio::makeLoopingAudioStream(stream, 0, 0, 0);
|
||||
} else {
|
||||
warning("Could not open file %s", cleansedPath.toString().c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
} // End of namespace music
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_MUSICPARAM_H
|
||||
Reference in New Issue
Block a user