mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
From nancy8 on, a new method of writing and evaluating data started being used. This commit expands the existing TableData struct to accommodate it.
324 lines
8.5 KiB
C++
324 lines
8.5 KiB
C++
/* 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/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/random.h"
|
|
#include "common/config-manager.h"
|
|
|
|
#include "engines/nancy/nancy.h"
|
|
#include "engines/nancy/sound.h"
|
|
#include "engines/nancy/util.h"
|
|
|
|
#include "engines/nancy/action/soundrecords.h"
|
|
|
|
#include "engines/nancy/state/scene.h"
|
|
|
|
namespace Nancy {
|
|
namespace Action {
|
|
|
|
void SetVolume::readData(Common::SeekableReadStream &stream) {
|
|
channel = stream.readUint16LE();
|
|
volume = stream.readByte();
|
|
}
|
|
|
|
void SetVolume::execute() {
|
|
g_nancy->_sound->setVolume(channel, volume);
|
|
_isDone = true;
|
|
}
|
|
|
|
void PlaySound::readData(Common::SeekableReadStream &stream) {
|
|
_sound.readDIGI(stream);
|
|
|
|
if (g_nancy->getGameType() >= kGameTypeNancy3) {
|
|
_soundEffect = new SoundEffectDescription;
|
|
_soundEffect->readData(stream);
|
|
|
|
if (g_nancy->getGameType() >= kGameTypeNancy6) {
|
|
_changeSceneImmediately = stream.readByte();
|
|
}
|
|
}
|
|
|
|
_sceneChange.readData(stream, g_nancy->getGameType() == kGameTypeVampire);
|
|
|
|
_flag.label = stream.readSint16LE();
|
|
_flag.flag = stream.readByte();
|
|
stream.skip(2); // VIDEO_STOP_RENDERING, VIDEO_CONTINUE_RENDERING
|
|
}
|
|
|
|
void PlaySound::execute() {
|
|
switch (_state) {
|
|
case kBegin:
|
|
g_nancy->_sound->loadSound(_sound, &_soundEffect);
|
|
g_nancy->_sound->playSound(_sound);
|
|
|
|
if (g_nancy->getGameType() >= kGameTypeNancy8) {
|
|
NancySceneState.setEventFlag(_flag);
|
|
}
|
|
|
|
if (_changeSceneImmediately) {
|
|
NancySceneState.changeScene(_sceneChange);
|
|
finishExecution();
|
|
break;
|
|
}
|
|
|
|
_state = kRun;
|
|
break;
|
|
case kRun:
|
|
if (!g_nancy->_sound->isSoundPlaying(_sound)) {
|
|
_state = kActionTrigger;
|
|
}
|
|
|
|
break;
|
|
case kActionTrigger:
|
|
NancySceneState.changeScene(_sceneChange);
|
|
|
|
if (g_nancy->getGameType() <= kGameTypeNancy7) {
|
|
NancySceneState.setEventFlag(_flag);
|
|
}
|
|
|
|
g_nancy->_sound->stopSound(_sound);
|
|
|
|
finishExecution();
|
|
break;
|
|
}
|
|
}
|
|
|
|
Common::String PlaySound::getRecordTypeName() const {
|
|
if (g_nancy->getGameType() <= kGameTypeNancy2) {
|
|
return "PlayDigiSoundAndDie";
|
|
} else if (g_nancy->getGameType() <= kGameTypeNancy5) {
|
|
return "PlayDigiSound";
|
|
} else {
|
|
return "PlaySound";
|
|
}
|
|
}
|
|
|
|
void PlaySoundCC::readData(Common::SeekableReadStream &stream) {
|
|
PlaySound::readData(stream);
|
|
readCCText(stream, _ccText);
|
|
}
|
|
|
|
void PlaySoundCC::execute() {
|
|
if (_state == kBegin && _ccText.size() && ConfMan.getBool("subtitles", ConfMan.getActiveDomainName())) {
|
|
NancySceneState.getTextbox().clear();
|
|
NancySceneState.getTextbox().addTextLine(_ccText);
|
|
}
|
|
PlaySound::execute();
|
|
}
|
|
|
|
void PlaySoundCC::readCCText(Common::SeekableReadStream &stream, Common::String &out) {
|
|
int16 textSize = stream.readUint16LE();
|
|
|
|
if (textSize > 0) {
|
|
char *strBuf = new char[textSize];
|
|
stream.read(strBuf, textSize);
|
|
assembleTextLine(strBuf, out, textSize);
|
|
delete[] strBuf;
|
|
} else if (textSize == -1) {
|
|
// Text is in Autotext chunk
|
|
Common::String key;
|
|
readFilename(stream, key);
|
|
const CVTX *autotext = (const CVTX *)g_nancy->getEngineData("AUTOTEXT");
|
|
assert(autotext);
|
|
|
|
out = autotext->texts[key];
|
|
}
|
|
}
|
|
|
|
Common::String PlaySoundCC::getRecordTypeName() const {
|
|
if (g_nancy->getGameType() <= kGameTypeNancy5) {
|
|
return "PlayDigiSoundCC";
|
|
} else {
|
|
return "PlaySoundCC";
|
|
}
|
|
}
|
|
|
|
void PlaySoundTerse::readData(Common::SeekableReadStream &stream) {
|
|
_sound.readTerse(stream);
|
|
_changeSceneImmediately = stream.readByte();
|
|
_sceneChange.sceneID = stream.readUint16LE();
|
|
|
|
_sceneChange.continueSceneSound = kContinueSceneSound;
|
|
_soundEffect = new SoundEffectDescription;
|
|
|
|
readCCText(stream, _ccText);
|
|
}
|
|
|
|
void PlaySoundEventFlagTerse::readData(Common::SeekableReadStream &stream) {
|
|
_sound.readTerse(stream);
|
|
_changeSceneImmediately = stream.readByte();
|
|
_sceneChange.sceneID = stream.readUint16LE();
|
|
_flag.label = stream.readUint16LE();
|
|
_flag.flag = stream.readByte();
|
|
|
|
_sceneChange.continueSceneSound = kContinueSceneSound;
|
|
_soundEffect = new SoundEffectDescription;
|
|
|
|
readCCText(stream, _ccText);
|
|
}
|
|
|
|
void PlaySoundFrameAnchor::readData(Common::SeekableReadStream &stream) {
|
|
_sound.readDIGI(stream);
|
|
stream.skip(2);
|
|
_sound.isPanning = true;
|
|
}
|
|
|
|
void PlaySoundFrameAnchor::execute() {
|
|
g_nancy->_sound->loadSound(_sound);
|
|
g_nancy->_sound->playSound(_sound);
|
|
_isDone = true;
|
|
}
|
|
|
|
Common::String PlaySoundFrameAnchor::getRecordTypeName() const {
|
|
if (g_nancy->getGameType() <= kGameTypeNancy2) {
|
|
return "PlaySoundPanFrameAnchorAndDie";
|
|
} else {
|
|
return "PlaySoundFrameAnchor";
|
|
}
|
|
}
|
|
|
|
void PlaySoundMultiHS::readData(Common::SeekableReadStream &stream) {
|
|
_sound.readNormal(stream);
|
|
|
|
if (g_nancy->getGameType() != kGameTypeVampire) {
|
|
_sceneChange.readData(stream);
|
|
_flag.label = stream.readSint16LE();
|
|
_flag.flag = stream.readByte();
|
|
stream.skip(2);
|
|
} else {
|
|
_flag.label = kEvNoEvent;
|
|
_sceneChange.sceneID = kNoScene;
|
|
}
|
|
|
|
uint16 numHotspots = stream.readUint16LE();
|
|
|
|
_hotspots.reserve(numHotspots);
|
|
for (uint i = 0; i < numHotspots; ++i) {
|
|
_hotspots.push_back(HotspotDescription());
|
|
_hotspots.back().frameID = stream.readUint16LE();
|
|
readRect(stream, _hotspots.back().coords);
|
|
}
|
|
}
|
|
|
|
void PlaySoundMultiHS::execute() {
|
|
switch (_state) {
|
|
case kBegin:
|
|
_state = kRun;
|
|
// fall through
|
|
case kRun: {
|
|
_hasHotspot = false;
|
|
uint currentFrame = NancySceneState.getSceneInfo().frameID;
|
|
|
|
for (uint i = 0; i < _hotspots.size(); ++i) {
|
|
if (_hotspots[i].frameID == currentFrame) {
|
|
_hotspot = _hotspots[i].coords;
|
|
_hasHotspot = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case kActionTrigger:
|
|
g_nancy->_sound->loadSound(_sound);
|
|
g_nancy->_sound->playSound(_sound);
|
|
NancySceneState.changeScene(_sceneChange);
|
|
NancySceneState.setEventFlag(_flag);
|
|
finishExecution();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void StopSound::readData(Common::SeekableReadStream &stream) {
|
|
_channelID = stream.readUint16LE();
|
|
_sceneChange.readData(stream);
|
|
}
|
|
|
|
void StopSound::execute() {
|
|
g_nancy->_sound->stopSound(_channelID);
|
|
_sceneChange.execute();
|
|
}
|
|
|
|
void PlayRandomSound::readData(Common::SeekableReadStream &stream) {
|
|
uint16 numSounds = stream.readUint16LE();
|
|
readFilenameArray(stream, _soundNames, numSounds - 1);
|
|
|
|
PlaySound::readData(stream);
|
|
_soundNames.push_back(_sound.name);
|
|
}
|
|
|
|
void PlayRandomSound::execute() {
|
|
if (_state == kBegin) {
|
|
_sound.name = _soundNames[g_nancy->_randomSource->getRandomNumber(_soundNames.size() - 1)];
|
|
}
|
|
|
|
PlaySound::execute();
|
|
}
|
|
|
|
void PlayRandomSoundTerse::readData(Common::SeekableReadStream &stream) {
|
|
uint16 numSounds = stream.readUint16LE();
|
|
readFilenameArray(stream, _soundNames, numSounds - 1);
|
|
|
|
PlaySoundTerse::readData(stream);
|
|
|
|
// The call above will have read the last sound name and the first cc text
|
|
_soundNames.push_back(_sound.name);
|
|
_ccTexts.push_back(_ccText);
|
|
|
|
for (int i = 0; i < numSounds - 1; ++i) {
|
|
_ccTexts.push_back(Common::String());
|
|
readCCText(stream, _ccTexts.back());
|
|
}
|
|
}
|
|
|
|
void PlayRandomSoundTerse::execute() {
|
|
if (_state == kBegin) {
|
|
uint16 randomID = g_nancy->_randomSource->getRandomNumber(_soundNames.size() - 1);
|
|
_sound.name = _soundNames[randomID];
|
|
_ccText = _ccTexts[randomID];
|
|
}
|
|
|
|
PlaySoundCC::execute();
|
|
}
|
|
|
|
void TableIndexPlaySound::readData(Common::SeekableReadStream &stream) {
|
|
_tableIndex = stream.readUint16LE();
|
|
PlaySound::readData(stream); // Data does NOT contain captions, so we call the PlaySound version
|
|
}
|
|
|
|
void TableIndexPlaySound::execute() {
|
|
TableData *playerTable = (TableData *)NancySceneState.getPuzzleData(TableData::getTag());
|
|
assert(playerTable);
|
|
auto *tabl = GetEngineData(TABL);
|
|
assert(tabl);
|
|
|
|
if (_lastIndexVal != playerTable->singleValues[_tableIndex - 1]) {
|
|
g_nancy->_sound->stopSound(_sound);
|
|
NancySceneState.getTextbox().clear();
|
|
_lastIndexVal = playerTable->singleValues[_tableIndex - 1];
|
|
_sound.name = Common::String::format("%s%u", tabl->soundBaseName.c_str(), playerTable->singleValues[_tableIndex - 1]);
|
|
_ccText = tabl->strings[playerTable->singleValues[_tableIndex - 1] - 1];
|
|
}
|
|
|
|
PlaySoundCC::execute();
|
|
}
|
|
|
|
} // End of namespace Action
|
|
} // End of namespace Nancy
|