aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2008-03-21 16:18:27 +0000
committerJohannes Schickel2008-03-21 16:18:27 +0000
commita169619526c811f1718bbeb5ed980f68b9d2c8e7 (patch)
treee419518022095bd4b43ec0de8a4d5e23c88bfe2f
parent88069c943a6bd94da8d183f943200076d5638148 (diff)
downloadscummvm-rg350-a169619526c811f1718bbeb5ed980f68b9d2c8e7.tar.gz
scummvm-rg350-a169619526c811f1718bbeb5ed980f68b9d2c8e7.tar.bz2
scummvm-rg350-a169619526c811f1718bbeb5ed980f68b9d2c8e7.zip
- Implemented opcode 97: o2_isAnySoundPlaying
- reworked sound channel handling in HoF => fixed some voice related bugs svn-id: r31209
-rw-r--r--engines/kyra/kyra.cpp1
-rw-r--r--engines/kyra/kyra.h8
-rw-r--r--engines/kyra/kyra_v2.cpp11
-rw-r--r--engines/kyra/kyra_v2.h7
-rw-r--r--engines/kyra/script_v2.cpp7
-rw-r--r--engines/kyra/sequences_v2.cpp3
-rw-r--r--engines/kyra/sound.cpp81
-rw-r--r--engines/kyra/sound.h24
-rw-r--r--engines/kyra/sound_towns.cpp4
-rw-r--r--engines/kyra/sound_v1.cpp1
10 files changed, 104 insertions, 43 deletions
diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp
index 6bb92f9566..b1af49a5ae 100644
--- a/engines/kyra/kyra.cpp
+++ b/engines/kyra/kyra.cpp
@@ -53,6 +53,7 @@ KyraEngine::KyraEngine(OSystem *system, const GameFlags &flags)
_quitFlag = false;
+ _speechFile = "";
_trackMap = 0;
_trackMapSize = 0;
_lastMusicCommand = -1;
diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h
index 7207c63090..b024432b36 100644
--- a/engines/kyra/kyra.h
+++ b/engines/kyra/kyra.h
@@ -84,6 +84,12 @@ enum kDebugLevels {
kDebugLevelTimer = 1 << 10 // prints debug output of "TimerManager" functions
};
+enum kMusicDataID {
+ kMusicIntro = 0,
+ kMusicIngame,
+ kMusicFinale
+};
+
class Screen;
class Resource;
class Sound;
@@ -191,6 +197,8 @@ protected:
uint8 _flagsTable[100]; // TODO: check this value
// sound
+ Common::String _speechFile;
+
int _curMusicTheme;
int _curSfxFile;
int16 _lastMusicCommand;
diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp
index 4b242b0f32..927b7e5c3e 100644
--- a/engines/kyra/kyra_v2.cpp
+++ b/engines/kyra/kyra_v2.cpp
@@ -1708,6 +1708,7 @@ void KyraEngine_v2::restoreGfxRect32x32(int x, int y) {
#pragma mark -
void KyraEngine_v2::openTalkFile(int newFile) {
+ debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::openTalkFile(%d)", newFile);
char talkFilename[16];
if (_oldTalkFile > 0) {
@@ -1732,10 +1733,17 @@ void KyraEngine_v2::snd_playVoiceFile(int id) {
char vocFile[9];
assert(id >= 0 && id <= 9999999);
sprintf(vocFile, "%07d", id);
- _sound->voicePlay(vocFile);
+ if (_sound->voiceFileIsPresent(vocFile)) {
+ while (!_sound->voicePlay(vocFile)) {
+ updateWithText();
+ _system->delayMillis(10);
+ }
+ _speechFile = vocFile;
+ }
}
void KyraEngine_v2::snd_loadSoundFile(int id) {
+ debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::snd_loadSoundFile(%d)", id);
if (id < 0 || !_trackMap)
return;
@@ -1746,6 +1754,7 @@ void KyraEngine_v2::snd_loadSoundFile(int id) {
}
void KyraEngine_v2::playVoice(int high, int low) {
+ debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v2::playVoice(%d, %d)", high, low);
if (!_flags.isTalkie)
return;
int vocFile = high * 10000 + low * 10;
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index cfd11a425d..ac6e5a3628 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -158,12 +158,6 @@ struct NestedSequence {
uint16 finalCommand;
};
-enum kMusicDataID {
- kMusicIntro = 0,
- kMusicIngame,
- kMusicFinale
-};
-
class KyraEngine_v2 : public KyraEngine {
friend class Debugger_v2;
friend class TextDisplayer_v2;
@@ -1036,6 +1030,7 @@ protected:
int o2_setCauldronState(ScriptState *script);
int o2_showItemString(ScriptState *script);
int o2_getRand(ScriptState *script);
+ int o2_isAnySoundPlaying(ScriptState *script);
int o2_setDeathHandlerFlag(ScriptState *script);
int o2_setDrawNoShapeFlag(ScriptState *script);
int o2_setRunFlag(ScriptState *script);
diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp
index 88350c3cc7..78b720d6e9 100644
--- a/engines/kyra/script_v2.cpp
+++ b/engines/kyra/script_v2.cpp
@@ -884,6 +884,11 @@ int KyraEngine_v2::o2_getRand(ScriptState *script) {
return _rnd.getRandomNumberRng(stackPos(0), stackPos(1));
}
+int KyraEngine_v2::o2_isAnySoundPlaying(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_isAnySoundPlaying(%p) ()", (const void *)script);
+ return _sound->voiceIsPlaying();
+}
+
int KyraEngine_v2::o2_setDeathHandlerFlag(ScriptState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0));
_deathHandler = stackPos(0);
@@ -1782,7 +1787,7 @@ void KyraEngine_v2::setupOpcodeTable() {
Opcode(o2_showItemString),
// 0x60
Opcode(o2_getRand),
- OpcodeUnImpl(),
+ Opcode(o2_isAnySoundPlaying),
Opcode(o2_setDeathHandlerFlag),
Opcode(o2_setDrawNoShapeFlag),
// 0x64
diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp
index f0688d6e3d..41f98f8caf 100644
--- a/engines/kyra/sequences_v2.cpp
+++ b/engines/kyra/sequences_v2.cpp
@@ -1968,13 +1968,14 @@ void KyraEngine_v2::seq_cmpFadeFrame(const char *cmpFile) {
}
void KyraEngine_v2::seq_playTalkText(uint8 chatNum) {
- debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_playIntroChat(%i)", chatNum);
+ debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_playTalkText(%i)", chatNum);
assert(chatNum < _sequenceSoundListSize);
if (chatNum < 12 && !_flags.isDemo && textEnabled())
seq_setTextEntry(chatNum, 160, 168, _sequenceStringsDuration[chatNum], 160);
+ _speechFile = _sequenceSoundList[chatNum];
_sound->voicePlay(_sequenceSoundList[chatNum]);
}
diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp
index 692db54af5..7dee4908fe 100644
--- a/engines/kyra/sound.cpp
+++ b/engines/kyra/sound.cpp
@@ -39,26 +39,44 @@
namespace Kyra {
Sound::Sound(KyraEngine *vm, Audio::Mixer *mixer)
- : _vm(vm), _mixer(mixer), _currentVocFile(0), _vocHandles(),
- _musicEnabled(1), _sfxEnabled(true), _soundDataList(0) {
+ : _vm(vm), _mixer(mixer), _soundChannels(), _musicEnabled(1),
+ _sfxEnabled(true), _soundDataList(0) {
}
Sound::~Sound() {
}
-void Sound::voicePlay(const char *file) {
+bool Sound::voiceFileIsPresent(const char *file) {
+ char filenamebuffer[25];
+ for (int i = 0; _supportedCodes[i].fileext; ++i) {
+ strcpy(filenamebuffer, file);
+ strcat(filenamebuffer, _supportedCodes[i].fileext);
+ if (_vm->resource()->getFileSize(filenamebuffer) > 0)
+ return true;
+ }
+
+ strcpy(filenamebuffer, file);
+ strcat(filenamebuffer, ".VOC");
+
+ if (_vm->resource()->getFileSize(filenamebuffer) > 0)
+ return true;
+
+ return false;
+}
+
+bool Sound::voicePlay(const char *file, bool isSfx) {
uint32 fileSize = 0;
byte *fileData = 0;
bool found = false;
char filenamebuffer[25];
int h = 0;
- if (_currentVocFile) {
- while (_mixer->isSoundHandleActive(_vocHandles[h]))
- h++;
- if (h >= kNumVocHandles)
- return;
- }
+ while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles)
+ h++;
+ if (h >= kNumChannelHandles)
+ return false;
+
+ Audio::AudioStream *audioStream = 0;
for (int i = 0; _supportedCodes[i].fileext; ++i) {
strcpy(filenamebuffer, file);
@@ -67,7 +85,7 @@ void Sound::voicePlay(const char *file) {
Common::SeekableReadStream *stream = _vm->resource()->getFileStream(filenamebuffer);
if (!stream)
continue;
- _currentVocFile = _supportedCodes[i].streamFunc(stream, true, 0, 0, 1);
+ audioStream = _supportedCodes[i].streamFunc(stream, true, 0, 0, 1);
found = true;
break;
}
@@ -78,30 +96,47 @@ void Sound::voicePlay(const char *file) {
fileData = _vm->resource()->fileData(filenamebuffer, &fileSize);
if (!fileData)
- return;
+ return false;
Common::MemoryReadStream vocStream(fileData, fileSize);
- _currentVocFile = Audio::makeVOCStream(vocStream);
+ audioStream = Audio::makeVOCStream(vocStream);
}
- _mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandles[h], _currentVocFile);
+ _soundChannels[h].file = file;
+ _mixer->playInputStream(isSfx ? Audio::Mixer::kSFXSoundType : Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, audioStream);
delete [] fileData;
fileSize = 0;
+
+ return true;
}
-void Sound::voiceStop() {
- for (int h = 0; h < kNumVocHandles; h++) {
- if (_mixer->isSoundHandleActive(_vocHandles[h]))
- _mixer->stopHandle(_vocHandles[h]);
+void Sound::voiceStop(const char *file) {
+ if (!file) {
+ for (int h = 0; h < kNumChannelHandles; h++) {
+ if (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle))
+ _mixer->stopHandle(_soundChannels[h].channelHandle);
+ }
+ } else {
+ for (int i = 0; i < kNumChannelHandles; ++i) {
+ if (_soundChannels[i].file == file)
+ _mixer->stopHandle(_soundChannels[i].channelHandle);
+ }
}
}
-bool Sound::voiceIsPlaying() {
+bool Sound::voiceIsPlaying(const char *file) {
bool res = false;
- for (int h = 0; h < kNumVocHandles; h++) {
- if (_mixer->isSoundHandleActive(_vocHandles[h]))
- res = true;
+ if (!file) {
+ for (int h = 0; h < kNumChannelHandles; h++) {
+ if (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle))
+ res = true;
+ }
+ } else {
+ for (int i = 0; i < kNumChannelHandles; ++i) {
+ if (_soundChannels[i].file == file)
+ res = true;
+ }
}
return res;
}
@@ -510,12 +545,12 @@ void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) {
void KyraEngine::snd_stopVoice() {
debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_stopVoice()");
- _sound->voiceStop();
+ _sound->voiceStop(_speechFile.empty() ? 0 : _speechFile.c_str());
}
bool KyraEngine::snd_voiceIsPlaying() {
debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_voiceIsPlaying()");
- return _sound->voiceIsPlaying();
+ return _sound->voiceIsPlaying(_speechFile.empty() ? 0 : _speechFile.c_str());
}
// static res
diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h
index 919cc3ceab..7c3bce38bc 100644
--- a/engines/kyra/sound.h
+++ b/engines/kyra/sound.h
@@ -52,7 +52,6 @@
#include "sound/softsynth/ym2612.h"
#include "kyra/kyra.h"
-#include "kyra/kyra_v2.h"
namespace Audio {
class AudioStream;
@@ -149,6 +148,8 @@ public:
void enableSFX(bool enable) { _sfxEnabled = enable; }
bool sfxEnabled() const { return _sfxEnabled; }
+ virtual bool voiceFileIsPresent(const char *file);
+
/**
* Plays the specified voice file.
*
@@ -160,28 +161,29 @@ public:
* files
*
* @param file file to be played
+ * @param isSfx marks file as sfx instead of voice
+ * @return channel the voice file is played on
*/
- virtual void voicePlay(const char *file);
+ virtual bool voicePlay(const char *file, bool isSfx = false);
/**
* Checks if a voice is being played.
*
* @return true when playing, else false
*/
- bool voiceIsPlaying();
+ bool voiceIsPlaying(const char *file = 0);
/**
* Stops playback of the current voice.
*/
- void voiceStop();
-
+ void voiceStop(const char *file = 0);
protected:
const char *fileListEntry(int file) const { return (_soundDataList != 0 && file >= 0 && file < _soundDataList->_fileListLen) ? _soundDataList->_fileList[file] : ""; }
const void *cdaData() const { return _soundDataList != 0 ? _soundDataList->_cdaTracks : 0; }
const int cdaTrackNum() const { return _soundDataList != 0 ? _soundDataList->_cdaNumTracks : 0; }
enum {
- kNumVocHandles = 4
+ kNumChannelHandles = 4
};
int _musicEnabled;
@@ -194,8 +196,12 @@ protected:
private:
const AudioDataStruct *_soundDataList;
- Audio::AudioStream *_currentVocFile;
- Audio::SoundHandle _vocHandles[kNumVocHandles];
+
+ struct SoundChannel {
+ Common::String file;
+ Audio::SoundHandle channelHandle;
+ };
+ SoundChannel _soundChannels[kNumChannelHandles];
struct SpeechCodecs {
const char *fileext;
@@ -429,7 +435,7 @@ private:
int _lastTrack;
Audio::AudioStream *_currentSFX;
- Audio::SoundHandle _sfxHandles[kNumVocHandles];
+ Audio::SoundHandle _sfxHandles[kNumChannelHandles];
//SoundTowns_v2_TwnDriver *_driver;
uint8 *_twnTrackData;
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index e3102d747b..e34f7d014c 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -1437,9 +1437,9 @@ void SoundTowns_v2::voicePlay(const char *file) {
int h = 0;
if (_currentSFX) {
- while (_mixer->isSoundHandleActive(_sfxHandles[h]))
+ while (_mixer->isSoundHandleActive(_sfxHandles[h]) && h < kNumChannelHandles)
h++;
- if (h >= kNumVocHandles)
+ if (h >= kNumChannelHandles)
return;
}
diff --git a/engines/kyra/sound_v1.cpp b/engines/kyra/sound_v1.cpp
index 6c6d086882..9cb135983d 100644
--- a/engines/kyra/sound_v1.cpp
+++ b/engines/kyra/sound_v1.cpp
@@ -66,6 +66,7 @@ void KyraEngine_v1::snd_playVoiceFile(int id) {
char vocFile[9];
assert(id >= 0 && id < 9999);
sprintf(vocFile, "%03d", id);
+ _speechFile = vocFile;
_sound->voicePlay(vocFile);
}