mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-05 01:38:36 +00:00
NANCY: Common sound handling changes
SoundManager is now responsible for loading and storing all common sounds (sounds with their own BOOT chunk). All playSound() calls with a hardcoded channel ID now use the chunk name instead. Also fixed some sound inaccuracies when switching between states.
This commit is contained in:
parent
a8a7f0ee57
commit
9bb543a69e
@ -64,7 +64,7 @@ void ActionManager::handleInput(NancyInput &input) {
|
||||
}
|
||||
|
||||
if (!shouldTrigger) {
|
||||
g_nancy->_sound->playSound(17); // Hardcoded by original engine
|
||||
g_nancy->_sound->playSound("CANT");
|
||||
}
|
||||
} else {
|
||||
shouldTrigger = true;
|
||||
|
@ -398,7 +398,7 @@ void ShowInventoryItem::execute() {
|
||||
break;
|
||||
}
|
||||
case kActionTrigger:
|
||||
g_nancy->_sound->playSound(24); // Hardcoded by original engine
|
||||
g_nancy->_sound->playSound("BUOK");
|
||||
NancySceneState.addItemToInventory(_objectID);
|
||||
setVisible(false);
|
||||
_hasHotspot = false;
|
||||
|
@ -317,25 +317,11 @@ void NancyEngine::bootGameEngine() {
|
||||
"CLOK", "SPEC"
|
||||
};
|
||||
|
||||
Common::String persistentSounds[] = {
|
||||
"BUOK", "BUDE", "BULS", "GLOB", "CURT",
|
||||
"CANT"
|
||||
};
|
||||
|
||||
SoundDescription desc;
|
||||
|
||||
for (auto const &n : names) {
|
||||
addBootChunk(n, boot->getChunkStream(n));
|
||||
}
|
||||
|
||||
// Persistent sounds that are used across the engine. These originally get loaded inside Logo
|
||||
for (auto const &s : persistentSounds) {
|
||||
Common::SeekableReadStream *str = g_nancy->getBootChunkStream(s);
|
||||
if (str) {
|
||||
desc.read(*str, SoundDescription::kNormal);
|
||||
g_nancy->_sound->loadSound(desc);
|
||||
}
|
||||
}
|
||||
_sound->loadCommonSounds();
|
||||
|
||||
delete boot;
|
||||
|
||||
|
@ -215,6 +215,36 @@ SoundManager::SoundManager() {
|
||||
initSoundChannels();
|
||||
}
|
||||
|
||||
void SoundManager::loadCommonSounds() {
|
||||
// Persistent sounds that are used across the engine. These originally get loaded inside Logo
|
||||
Common::String chunkNames[] = {
|
||||
"CANT", // channel 17
|
||||
"CURT", // channel 18
|
||||
"GLOB", // channel 20
|
||||
"BULS", // channel 22
|
||||
"BUDE", // channel 23
|
||||
"BUOK", // channel 24
|
||||
};
|
||||
|
||||
Common::SeekableReadStream *chunk = nullptr;
|
||||
for (auto const &s : chunkNames) {
|
||||
chunk = g_nancy->getBootChunkStream(s);
|
||||
if (chunk) {
|
||||
SoundDescription &desc = _commonSounds.getOrCreateVal(s);
|
||||
desc.read(*chunk, SoundDescription::kNormal);
|
||||
g_nancy->_sound->loadSound(desc);
|
||||
}
|
||||
}
|
||||
|
||||
// Menu sound is special since it's stored differently and can be
|
||||
// unloaded and loaded again
|
||||
chunk = g_nancy->getBootChunkStream("MSND"); // channel 28
|
||||
if (chunk) {
|
||||
SoundDescription &desc = _commonSounds.getOrCreateVal("MSND");
|
||||
desc.read(*chunk, SoundDescription::kMenu);
|
||||
}
|
||||
}
|
||||
|
||||
SoundManager::~SoundManager() {
|
||||
stopAllSounds();
|
||||
}
|
||||
@ -262,6 +292,16 @@ void SoundManager::playSound(const SoundDescription &description) {
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::playSound(const Common::String &chunkName) {
|
||||
const SoundDescription &desc = _commonSounds[chunkName];
|
||||
|
||||
if (!isSoundPlaying(desc)) {
|
||||
loadSound(desc);
|
||||
}
|
||||
|
||||
playSound(desc);
|
||||
}
|
||||
|
||||
void SoundManager::pauseSound(uint16 channelID, bool pause) {
|
||||
if (channelID > 31)
|
||||
return;
|
||||
@ -277,6 +317,10 @@ void SoundManager::pauseSound(const SoundDescription &description, bool pause) {
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::pauseSound(const Common::String &chunkName, bool pause) {
|
||||
pauseSound(_commonSounds[chunkName], pause);
|
||||
}
|
||||
|
||||
bool SoundManager::isSoundPlaying(uint16 channelID) const {
|
||||
if (channelID > 31)
|
||||
return false;
|
||||
@ -292,6 +336,10 @@ bool SoundManager::isSoundPlaying(const SoundDescription &description) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool SoundManager::isSoundPlaying(const Common::String &chunkName) const {
|
||||
return isSoundPlaying(_commonSounds[chunkName]);
|
||||
}
|
||||
|
||||
void SoundManager::stopSound(uint16 channelID) {
|
||||
if (channelID > 31)
|
||||
return;
|
||||
@ -310,6 +358,10 @@ void SoundManager::stopSound(const SoundDescription &description) {
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::stopSound(const Common::String &chunkName) {
|
||||
stopSound(_commonSounds[chunkName]);
|
||||
}
|
||||
|
||||
// Returns whether the exception was skipped
|
||||
void SoundManager::stopAllSounds() {
|
||||
for (uint i = 0; i < 31; ++i) {
|
||||
@ -323,6 +375,8 @@ void SoundManager::stopAndUnloadSpecificSounds() {
|
||||
for (uint i = 0; i < 10; ++i) {
|
||||
stopSound(i);
|
||||
}
|
||||
|
||||
stopSound(_commonSounds["MSND"]);
|
||||
}
|
||||
|
||||
void SoundManager::initSoundChannels() {
|
||||
|
@ -23,6 +23,8 @@
|
||||
#ifndef NANCY_SOUND_H
|
||||
#define NANCY_SOUND_H
|
||||
|
||||
#include "engines/nancy/commontypes.h"
|
||||
|
||||
#include "audio/mixer.h"
|
||||
|
||||
namespace Common {
|
||||
@ -36,27 +38,32 @@ class SeekableAudioStream;
|
||||
namespace Nancy {
|
||||
|
||||
class NancyEngine;
|
||||
struct SoundDescription;
|
||||
|
||||
class SoundManager {
|
||||
public:
|
||||
SoundManager();
|
||||
~SoundManager();
|
||||
|
||||
void loadCommonSounds();
|
||||
|
||||
// Load a sound into a channel without starting it
|
||||
void loadSound(const SoundDescription &description);
|
||||
|
||||
void playSound(uint16 channelID);
|
||||
void playSound(const SoundDescription &description);
|
||||
void playSound(const Common::String &chunkName);
|
||||
|
||||
void pauseSound(uint16 channelID, bool pause);
|
||||
void pauseSound(const SoundDescription &description, bool pause);
|
||||
void pauseSound(const Common::String &chunkName, bool pause);
|
||||
|
||||
bool isSoundPlaying(uint16 channelID) const;
|
||||
bool isSoundPlaying(const SoundDescription &description) const;
|
||||
bool isSoundPlaying(const Common::String &chunkName) const;
|
||||
|
||||
void stopSound(uint16 channelID);
|
||||
void stopSound(const SoundDescription &description);
|
||||
void stopSound(const Common::String &chunkName);
|
||||
void stopAllSounds();
|
||||
|
||||
// Used when changing scenes
|
||||
@ -78,6 +85,7 @@ protected:
|
||||
Audio::Mixer *_mixer;
|
||||
|
||||
Channel _channels[32];
|
||||
Common::HashMap<Common::String, SoundDescription> _commonSounds;
|
||||
};
|
||||
|
||||
} // End of namespace Nancy
|
||||
|
@ -73,6 +73,8 @@ void Credits::init() {
|
||||
_text._drawSurface.create(_fullTextSurface, src);
|
||||
_text.init();
|
||||
|
||||
g_nancy->_sound->stopSound("MSND");
|
||||
|
||||
g_nancy->_sound->loadSound(_sound);
|
||||
g_nancy->_sound->playSound(_sound);
|
||||
|
||||
|
@ -66,16 +66,13 @@ void Help::init() {
|
||||
_hotspot.right = chunk->readUint16LE();
|
||||
_hotspot.bottom = chunk->readUint16LE();
|
||||
|
||||
chunk = g_nancy->getBootChunkStream("MSND");
|
||||
chunk->seek(0);
|
||||
_sound.read(*chunk, SoundDescription::kMenu);
|
||||
|
||||
_state = kBegin;
|
||||
}
|
||||
|
||||
void Help::begin() {
|
||||
g_nancy->_sound->loadSound(_sound);
|
||||
g_nancy->_sound->playSound(_sound);
|
||||
if (!g_nancy->_sound->isSoundPlaying("MSND")) {
|
||||
g_nancy->_sound->playSound("MSND");
|
||||
}
|
||||
|
||||
_image.registerGraphics();
|
||||
_image.setVisible(true);
|
||||
@ -89,14 +86,14 @@ void Help::run() {
|
||||
NancyInput input = g_nancy->_input->getInput();
|
||||
|
||||
if (_hotspot.contains(input.mousePos) && input.input & NancyInput::kLeftMouseButtonUp) {
|
||||
g_nancy->_sound->playSound(0x18); // Hardcoded by original engine
|
||||
g_nancy->_sound->playSound("BUOK");
|
||||
_state = kWaitForSound;
|
||||
}
|
||||
}
|
||||
|
||||
void Help::waitForSound() {
|
||||
if (!g_nancy->_sound->isSoundPlaying(18)) {
|
||||
g_nancy->_sound->stopSound(_sound);
|
||||
if (!g_nancy->_sound->isSoundPlaying("BUOK")) {
|
||||
g_nancy->_sound->stopSound("BUOK");
|
||||
g_nancy->setToPreviousState();
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,6 @@ private:
|
||||
State _state;
|
||||
UI::FullScreenImage _image;
|
||||
Common::Rect _hotspot; // Can be an array, but isn't in nancy1
|
||||
SoundDescription _sound;
|
||||
};
|
||||
|
||||
#define NancyHelpState Nancy::State::Help::instance()
|
||||
|
@ -50,7 +50,6 @@ void Logo::process() {
|
||||
}
|
||||
|
||||
void Logo::onStateExit() {
|
||||
g_nancy->_sound->stopSound(_msnd);
|
||||
destroy();
|
||||
}
|
||||
|
||||
@ -65,9 +64,7 @@ void Logo::init() {
|
||||
}
|
||||
|
||||
void Logo::startSound() {
|
||||
_msnd.read(*g_nancy->getBootChunkStream("MSND"), SoundDescription::kMenu);
|
||||
g_nancy->_sound->loadSound(_msnd);
|
||||
g_nancy->_sound->playSound(_msnd);
|
||||
g_nancy->_sound->playSound("MSND");
|
||||
|
||||
_startTicks = g_nancy->getTotalPlayTime();
|
||||
_state = kRun;
|
||||
@ -83,9 +80,6 @@ void Logo::stop() {
|
||||
// The original engine checks for N+D and N+C key combos here.
|
||||
// For the N+C key combo it looks for some kind of cheat file
|
||||
// to initialize the game state with.
|
||||
|
||||
g_nancy->_sound->stopSound(_msnd);
|
||||
|
||||
g_nancy->setState(NancyState::kScene);
|
||||
}
|
||||
|
||||
|
@ -80,10 +80,9 @@ void Map::init() {
|
||||
|
||||
// Load the audio
|
||||
chunk->seek(0x18 + _mapID * 0x20, SEEK_SET);
|
||||
SoundDescription sound;
|
||||
sound.read(*chunk, SoundDescription::kMenu);
|
||||
g_nancy->_sound->loadSound(sound);
|
||||
g_nancy->_sound->playSound(0x14);
|
||||
_sound.read(*chunk, SoundDescription::kMenu);
|
||||
g_nancy->_sound->loadSound(_sound);
|
||||
g_nancy->_sound->playSound("GLOB");
|
||||
|
||||
_locations.clear();
|
||||
|
||||
@ -126,8 +125,8 @@ void Map::init() {
|
||||
}
|
||||
|
||||
void Map::run() {
|
||||
if (!g_nancy->_sound->isSoundPlaying(0x14) && !g_nancy->_sound->isSoundPlaying(0x13)) {
|
||||
g_nancy->_sound->playSound(0x13);
|
||||
if (!g_nancy->_sound->isSoundPlaying("GLOB") && !g_nancy->_sound->isSoundPlaying(_sound)) {
|
||||
g_nancy->_sound->playSound(_sound);
|
||||
}
|
||||
|
||||
NancyInput input = g_nancy->_input->getInput();
|
||||
@ -159,22 +158,18 @@ void Map::run() {
|
||||
}
|
||||
|
||||
void Map::onStateExit() {
|
||||
Common::SeekableReadStream *chunk = g_nancy->getBootChunkStream("MAP");
|
||||
SoundDescription sound;
|
||||
chunk->seek(0x18 + _mapID * 0x20, SEEK_SET);
|
||||
sound.read(*chunk, SoundDescription::kMenu);
|
||||
g_nancy->_sound->stopSound(sound);
|
||||
g_nancy->_sound->stopSound(_sound);
|
||||
|
||||
if (_pickedLocationID != -1) {
|
||||
auto &loc = _locations[_pickedLocationID];
|
||||
NancySceneState.changeScene(loc.scenes[_mapID].sceneID, loc.scenes[_mapID].frameID, loc.scenes[_mapID].verticalOffset, false);
|
||||
_pickedLocationID = -1;
|
||||
|
||||
g_nancy->_sound->playSound(0x18);
|
||||
g_nancy->_sound->playSound("BUOK");
|
||||
}
|
||||
|
||||
// The two sounds play at the same time if a location was picked
|
||||
g_nancy->_sound->playSound(0x14);
|
||||
g_nancy->_sound->playSound("GLOB");
|
||||
|
||||
_mapButtonClicked = false;
|
||||
|
||||
|
@ -100,6 +100,7 @@ private:
|
||||
Nancy::UI::Viewport _viewport;
|
||||
MapLabel _label;
|
||||
MapButton _button;
|
||||
SoundDescription _sound;
|
||||
|
||||
State _state;
|
||||
uint16 _mapID;
|
||||
|
@ -121,6 +121,7 @@ void Scene::onStateEnter() {
|
||||
g_nancy->setTotalPlayTime((uint32)_timers.pushedPlayTime);
|
||||
|
||||
unpauseSceneSpecificSounds();
|
||||
g_nancy->_sound->stopSound("MSND");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ void MenuButton::init() {
|
||||
|
||||
void MenuButton::onClick() {
|
||||
NancySceneState.requestStateChange(NancyState::kMainMenu);
|
||||
g_nancy->_sound->playSound(0x18);
|
||||
g_nancy->_sound->playSound("GLOB");
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ void HelpButton::init() {
|
||||
|
||||
void HelpButton::onClick() {
|
||||
NancySceneState.requestStateChange(NancyState::kHelp);
|
||||
g_nancy->_sound->playSound(0x18);
|
||||
g_nancy->_sound->playSound("GLOB");
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
|
@ -118,13 +118,13 @@ void InventoryBox::handleInput(NancyInput &input) {
|
||||
g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
|
||||
if (input.input & NancyInput::kLeftMouseButtonUp) {
|
||||
NancySceneState.addItemToInventory(NancySceneState.getHeldItem());
|
||||
g_nancy->_sound->playSound(0x16);
|
||||
g_nancy->_sound->playSound("BULS");
|
||||
}
|
||||
} else if (_itemHotspots[i].itemID != -1) {
|
||||
g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
|
||||
if (input.input & NancyInput::kLeftMouseButtonUp) {
|
||||
NancySceneState.removeItemFromInventory(_itemHotspots[i].itemID);
|
||||
g_nancy->_sound->playSound(0x18);
|
||||
g_nancy->_sound->playSound("GLOB");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -242,7 +242,7 @@ void InventoryBox::Shades::updateGraphics() {
|
||||
|
||||
if (!_soundTriggered) {
|
||||
_soundTriggered = true;
|
||||
g_nancy->_sound->playSound(0x12);
|
||||
g_nancy->_sound->playSound("CURT");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -252,7 +252,7 @@ void InventoryBox::Shades::updateGraphics() {
|
||||
|
||||
if (!_soundTriggered) {
|
||||
_soundTriggered = true;
|
||||
g_nancy->_sound->playSound(0x12);
|
||||
g_nancy->_sound->playSound("CURT");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user