Reorganized the sound code a bit and fixed bug # 1404414 (Missing speech patterns).
svn-id: r20006
This commit is contained in:
parent
d04475121e
commit
d2de796c31
8 changed files with 207 additions and 79 deletions
24
kyra/gui.cpp
24
kyra/gui.cpp
|
@ -96,11 +96,19 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
|
||||||
return 1;
|
return 1;
|
||||||
if (_itemInHand != -1) {
|
if (_itemInHand != -1) {
|
||||||
assert(_putDownFirst);
|
assert(_putDownFirst);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(2000);
|
||||||
|
}
|
||||||
characterSays(_putDownFirst[0], 0, -2);
|
characterSays(_putDownFirst[0], 0, -2);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (queryGameFlag(0xF1)) {
|
if (queryGameFlag(0xF1)) {
|
||||||
assert(_waitForAmulet);
|
assert(_waitForAmulet);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(2001);
|
||||||
|
}
|
||||||
characterSays(_waitForAmulet[0], 0, -2);
|
characterSays(_waitForAmulet[0], 0, -2);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -108,6 +116,10 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
|
||||||
assert(_blackJewel);
|
assert(_blackJewel);
|
||||||
makeBrandonFaceMouse();
|
makeBrandonFaceMouse();
|
||||||
drawJewelPress(jewel, 1);
|
drawJewelPress(jewel, 1);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(2002);
|
||||||
|
}
|
||||||
characterSays(_blackJewel[0], 0, -2);
|
characterSays(_blackJewel[0], 0, -2);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -135,6 +147,10 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
|
||||||
} else if (_brandonStatusBit == 0) {
|
} else if (_brandonStatusBit == 0) {
|
||||||
seq_brandonHealing();
|
seq_brandonHealing();
|
||||||
assert(_healingTip);
|
assert(_healingTip);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(2003);
|
||||||
|
}
|
||||||
characterSays(_healingTip[0], 0, -2);
|
characterSays(_healingTip[0], 0, -2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -146,6 +162,10 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
|
||||||
case 2:
|
case 2:
|
||||||
if (_brandonStatusBit & 1) {
|
if (_brandonStatusBit & 1) {
|
||||||
assert(_wispJewelStrings);
|
assert(_wispJewelStrings);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(2004);
|
||||||
|
}
|
||||||
characterSays(_wispJewelStrings[0], 0, -2);
|
characterSays(_wispJewelStrings[0], 0, -2);
|
||||||
} else {
|
} else {
|
||||||
if (_brandonStatusBit & 2) {
|
if (_brandonStatusBit & 2) {
|
||||||
|
@ -170,6 +190,10 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
|
||||||
case 3:
|
case 3:
|
||||||
seq_dispelMagicAnimation();
|
seq_dispelMagicAnimation();
|
||||||
assert(_magicJewelString);
|
assert(_magicJewelString);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(2007);
|
||||||
|
}
|
||||||
characterSays(_magicJewelString[0], 0, -2);
|
characterSays(_magicJewelString[0], 0, -2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
105
kyra/kyra.cpp
105
kyra/kyra.cpp
|
@ -34,8 +34,6 @@
|
||||||
|
|
||||||
#include "sound/mixer.h"
|
#include "sound/mixer.h"
|
||||||
#include "sound/mididrv.h"
|
#include "sound/mididrv.h"
|
||||||
#include "sound/voc.h"
|
|
||||||
#include "sound/audiostream.h"
|
|
||||||
|
|
||||||
#include "gui/message.h"
|
#include "gui/message.h"
|
||||||
|
|
||||||
|
@ -264,7 +262,6 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *system)
|
||||||
}
|
}
|
||||||
|
|
||||||
int KyraEngine::init(GameDetector &detector) {
|
int KyraEngine::init(GameDetector &detector) {
|
||||||
_currentVocFile = 0;
|
|
||||||
_system->beginGFXTransaction();
|
_system->beginGFXTransaction();
|
||||||
initCommonGFX(detector);
|
initCommonGFX(detector);
|
||||||
_system->initSize(320, 200);
|
_system->initSize(320, 200);
|
||||||
|
@ -282,10 +279,10 @@ int KyraEngine::init(GameDetector &detector) {
|
||||||
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
|
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
|
||||||
}
|
}
|
||||||
|
|
||||||
_midi = new MusicPlayer(driver, this);
|
_sound = new SoundPC(driver, _mixer, this);
|
||||||
assert(_midi);
|
assert(_sound);
|
||||||
_midi->hasNativeMT32(native_mt32);
|
static_cast<SoundPC*>(_sound)->hasNativeMT32(native_mt32);
|
||||||
_midi->setVolume(255);
|
_sound->setVolume(255);
|
||||||
|
|
||||||
_saveFileMan = _system->getSavefileManager();
|
_saveFileMan = _system->getSavefileManager();
|
||||||
assert(_saveFileMan);
|
assert(_saveFileMan);
|
||||||
|
@ -431,7 +428,7 @@ KyraEngine::~KyraEngine() {
|
||||||
delete _animator;
|
delete _animator;
|
||||||
delete _screen;
|
delete _screen;
|
||||||
delete _res;
|
delete _res;
|
||||||
delete _midi;
|
delete _sound;
|
||||||
delete _saveFileMan;
|
delete _saveFileMan;
|
||||||
delete _seq;
|
delete _seq;
|
||||||
delete _scriptInterpreter;
|
delete _scriptInterpreter;
|
||||||
|
@ -869,7 +866,7 @@ void KyraEngine::seq_demo() {
|
||||||
_screen->fadeFromBlack();
|
_screen->fadeFromBlack();
|
||||||
waitTicks(60);
|
waitTicks(60);
|
||||||
_screen->fadeToBlack();
|
_screen->fadeToBlack();
|
||||||
_midi->stopMusic();
|
_sound->stopMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyraEngine::seq_intro() {
|
void KyraEngine::seq_intro() {
|
||||||
|
@ -897,7 +894,7 @@ void KyraEngine::seq_intro() {
|
||||||
_text->setTalkCoords(136);
|
_text->setTalkCoords(136);
|
||||||
waitTicks(30);
|
waitTicks(30);
|
||||||
_seq->setCopyViewOffs(false);
|
_seq->setCopyViewOffs(false);
|
||||||
_midi->stopMusic();
|
_sound->stopMusic();
|
||||||
if (_features & GF_TALKIE) {
|
if (_features & GF_TALKIE) {
|
||||||
_res->unloadPakFile("INTRO.VRM");
|
_res->unloadPakFile("INTRO.VRM");
|
||||||
}
|
}
|
||||||
|
@ -1107,7 +1104,15 @@ void KyraEngine::seq_brandonHealing2() {
|
||||||
freeShapes123();
|
freeShapes123();
|
||||||
_screen->showMouse();
|
_screen->showMouse();
|
||||||
assert(_poisonGone);
|
assert(_poisonGone);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(2010);
|
||||||
|
}
|
||||||
characterSays(_poisonGone[0], 0, -2);
|
characterSays(_poisonGone[0], 0, -2);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(2011);
|
||||||
|
}
|
||||||
characterSays(_poisonGone[1], 0, -2);
|
characterSays(_poisonGone[1], 0, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1121,13 +1126,29 @@ void KyraEngine::seq_poisonDeathNow(int now) {
|
||||||
if (_poisonDeathCounter >= 2) {
|
if (_poisonDeathCounter >= 2) {
|
||||||
snd_playWanderScoreViaMap(1, 1);
|
snd_playWanderScoreViaMap(1, 1);
|
||||||
assert(_thePoison);
|
assert(_thePoison);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(7000);
|
||||||
|
}
|
||||||
characterSays(_thePoison[0], 0, -2);
|
characterSays(_thePoison[0], 0, -2);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(7001);
|
||||||
|
}
|
||||||
characterSays(_thePoison[1], 0, -2);
|
characterSays(_thePoison[1], 0, -2);
|
||||||
seq_poisonDeathNowAnim();
|
seq_poisonDeathNowAnim();
|
||||||
_deathHandler = 3;
|
_deathHandler = 3;
|
||||||
} else {
|
} else {
|
||||||
assert(_thePoison);
|
assert(_thePoison);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(7002);
|
||||||
|
}
|
||||||
characterSays(_thePoison[2], 0, -2);
|
characterSays(_thePoison[2], 0, -2);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(7004);
|
||||||
|
}
|
||||||
characterSays(_thePoison[3], 0, -2);
|
characterSays(_thePoison[3], 0, -2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1190,10 +1211,11 @@ void KyraEngine::seq_playFluteAnimation() {
|
||||||
snd_playSoundEffect(0x63);
|
snd_playSoundEffect(0x63);
|
||||||
delayTime = 9;
|
delayTime = 9;
|
||||||
soundType = 3;
|
soundType = 3;
|
||||||
} else if (queryGameFlag(0x86)) {
|
} else if (!queryGameFlag(0x86)) {
|
||||||
snd_playSoundEffect(0x61);
|
snd_playSoundEffect(0x61);
|
||||||
delayTime = 2;
|
delayTime = 2;
|
||||||
soundType = 1;
|
soundType = 1;
|
||||||
|
setGameFlag(0x86);
|
||||||
} else {
|
} else {
|
||||||
snd_playSoundEffect(0x62);
|
snd_playSoundEffect(0x62);
|
||||||
delayTime = 2;
|
delayTime = 2;
|
||||||
|
@ -1219,9 +1241,17 @@ void KyraEngine::seq_playFluteAnimation() {
|
||||||
|
|
||||||
if (soundType == 1) {
|
if (soundType == 1) {
|
||||||
assert(_fluteString);
|
assert(_fluteString);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(1000);
|
||||||
|
}
|
||||||
characterSays(_fluteString[0], 0, -2);
|
characterSays(_fluteString[0], 0, -2);
|
||||||
} else if (soundType == 2) {
|
} else if (soundType == 2) {
|
||||||
assert(_fluteString);
|
assert(_fluteString);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(1001);
|
||||||
|
}
|
||||||
characterSays(_fluteString[1], 0, -2);
|
characterSays(_fluteString[1], 0, -2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1481,6 +1511,10 @@ void KyraEngine::seq_fillFlaskWithWater(int item, int type) {
|
||||||
|
|
||||||
if (item >= 60 && item <= 77) {
|
if (item >= 60 && item <= 77) {
|
||||||
assert(_flaskFull);
|
assert(_flaskFull);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
snd_playVoiceFile(8006);
|
||||||
|
}
|
||||||
characterSays(_flaskFull[0], 0, -2);
|
characterSays(_flaskFull[0], 0, -2);
|
||||||
} else if (item == 78) {
|
} else if (item == 78) {
|
||||||
assert(type >= 0 && type < ARRAYSIZE(flaskTable1));
|
assert(type >= 0 && type < ARRAYSIZE(flaskTable1));
|
||||||
|
@ -1499,6 +1533,14 @@ void KyraEngine::seq_fillFlaskWithWater(int item, int type) {
|
||||||
_itemInHand = newItem;
|
_itemInHand = newItem;
|
||||||
assert(_fullFlask);
|
assert(_fullFlask);
|
||||||
assert(type < _fullFlask_Size && type >= 0);
|
assert(type < _fullFlask_Size && type >= 0);
|
||||||
|
if (_features & GF_TALKIE) {
|
||||||
|
snd_voiceWaitForFinish();
|
||||||
|
static const uint16 voiceEntries[] = {
|
||||||
|
0x1F40, 0x1F41, 0x1F42, 0x1F45
|
||||||
|
};
|
||||||
|
assert(type < ARRAYSIZE(voiceEntries));
|
||||||
|
snd_playVoiceFile(voiceEntries[type]);
|
||||||
|
}
|
||||||
characterSays(_fullFlask[type], 0, -2);
|
characterSays(_fullFlask[type], 0, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1700,19 +1742,19 @@ void KyraEngine::snd_playTheme(int file, int track) {
|
||||||
debug(9, "KyraEngine::snd_playTheme(%d)", file);
|
debug(9, "KyraEngine::snd_playTheme(%d)", file);
|
||||||
assert(file < _xmidiFilesCount);
|
assert(file < _xmidiFilesCount);
|
||||||
_curMusicTheme = _newMusicTheme = file;
|
_curMusicTheme = _newMusicTheme = file;
|
||||||
_midi->playMusic(_xmidiFiles[file]);
|
_sound->playMusic(_xmidiFiles[file]);
|
||||||
_midi->playTrack(track, false);
|
_sound->playTrack(track, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyraEngine::snd_playTrack(int track, bool looping) {
|
void KyraEngine::snd_playTrack(int track, bool looping) {
|
||||||
debug(9, "KyraEngine::snd_playTrack(%d, %d)", track, looping);
|
debug(9, "KyraEngine::snd_playTrack(%d, %d)", track, looping);
|
||||||
_midi->playTrack(track, looping);
|
_sound->playTrack(track, looping);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyraEngine::snd_setSoundEffectFile(int file) {
|
void KyraEngine::snd_setSoundEffectFile(int file) {
|
||||||
debug(9, "KyraEngine::snd_setSoundEffectFile(%d)", file);
|
debug(9, "KyraEngine::snd_setSoundEffectFile(%d)", file);
|
||||||
assert(file < _xmidiFilesCount);
|
assert(file < _xmidiFilesCount);
|
||||||
_midi->loadSoundEffectFile(_xmidiFiles[file]);
|
_sound->loadSoundEffectFile(_xmidiFiles[file]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyraEngine::snd_playSoundEffect(int track) {
|
void KyraEngine::snd_playSoundEffect(int track) {
|
||||||
|
@ -1720,7 +1762,7 @@ void KyraEngine::snd_playSoundEffect(int track) {
|
||||||
if (track == 49) {
|
if (track == 49) {
|
||||||
snd_playWanderScoreViaMap(56, 1);
|
snd_playWanderScoreViaMap(56, 1);
|
||||||
} else {
|
} else {
|
||||||
_midi->playSoundEffect(track);
|
_sound->playSoundEffect(track);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1762,7 +1804,7 @@ void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_lastMusicCommand = 1;
|
_lastMusicCommand = 1;
|
||||||
_midi->beginFadeOut();
|
_sound->beginFadeOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1771,31 +1813,32 @@ void KyraEngine::snd_playVoiceFile(int id) {
|
||||||
char vocFile[9];
|
char vocFile[9];
|
||||||
assert(id >= 0 && id < 9999);
|
assert(id >= 0 && id < 9999);
|
||||||
sprintf(vocFile, "%03d.VOC", id);
|
sprintf(vocFile, "%03d.VOC", id);
|
||||||
uint32 fileSize = 0;
|
_sound->voicePlay(vocFile);
|
||||||
byte *fileData = 0;
|
|
||||||
fileData = _res->fileData(vocFile, &fileSize);
|
|
||||||
assert(fileData);
|
|
||||||
Common::MemoryReadStream vocStream(fileData, fileSize);
|
|
||||||
_mixer->stopHandle(_vocHandle);
|
|
||||||
_currentVocFile = makeVOCStream(vocStream);
|
|
||||||
if (_currentVocFile)
|
|
||||||
_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandle, _currentVocFile);
|
|
||||||
delete fileData;
|
|
||||||
fileSize = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KyraEngine::snd_voicePlaying() {
|
bool KyraEngine::snd_voicePlaying() {
|
||||||
return _mixer->isSoundHandleActive(_vocHandle);
|
return _sound->voiceIsPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KyraEngine::snd_voiceWaitForFinish(bool ingame) {
|
||||||
|
debug(9, "KyraEngine::snd_voiceWaitForFinish(%d)", ingame);
|
||||||
|
while (snd_voicePlaying() && !_fastMode) {
|
||||||
|
if (ingame) {
|
||||||
|
delay(10, true);
|
||||||
|
} else {
|
||||||
|
waitTicks(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyraEngine::snd_startTrack() {
|
void KyraEngine::snd_startTrack() {
|
||||||
debug(9, "KyraEngine::snd_startTrack()");
|
debug(9, "KyraEngine::snd_startTrack()");
|
||||||
_midi->startTrack();
|
_sound->startTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyraEngine::snd_haltTrack() {
|
void KyraEngine::snd_haltTrack() {
|
||||||
debug(9, "KyraEngine::snd_haltTrack()");
|
debug(9, "KyraEngine::snd_haltTrack()");
|
||||||
_midi->haltTrack();
|
_sound->haltTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyraEngine::loadMouseShapes() {
|
void KyraEngine::loadMouseShapes() {
|
||||||
|
|
|
@ -118,7 +118,7 @@ struct BeadState {
|
||||||
|
|
||||||
class Movie;
|
class Movie;
|
||||||
|
|
||||||
class MusicPlayer;
|
class Sound;
|
||||||
class SeqPlayer;
|
class SeqPlayer;
|
||||||
class Resource;
|
class Resource;
|
||||||
class PAKFile;
|
class PAKFile;
|
||||||
|
@ -186,7 +186,7 @@ public:
|
||||||
Screen *screen() { return _screen; }
|
Screen *screen() { return _screen; }
|
||||||
ScreenAnimator *animator() { return _animator; }
|
ScreenAnimator *animator() { return _animator; }
|
||||||
TextDisplayer *text() { return _text; }
|
TextDisplayer *text() { return _text; }
|
||||||
MusicPlayer *midi() { return _midi; }
|
Sound *sound() { return _sound; }
|
||||||
uint32 tickLength() const { return _tickLength; }
|
uint32 tickLength() const { return _tickLength; }
|
||||||
Movie *createWSAMovie();
|
Movie *createWSAMovie();
|
||||||
|
|
||||||
|
@ -218,6 +218,7 @@ public:
|
||||||
void snd_playTrack(int track, bool looping = false);
|
void snd_playTrack(int track, bool looping = false);
|
||||||
void snd_playVoiceFile(int id);
|
void snd_playVoiceFile(int id);
|
||||||
bool snd_voicePlaying();
|
bool snd_voicePlaying();
|
||||||
|
void snd_voiceWaitForFinish(bool ingame = true);
|
||||||
void snd_playSoundEffect(int track);
|
void snd_playSoundEffect(int track);
|
||||||
void snd_playWanderScoreViaMap(int command, int restart);
|
void snd_playWanderScoreViaMap(int command, int restart);
|
||||||
|
|
||||||
|
@ -715,13 +716,11 @@ protected:
|
||||||
int _curMusicTheme;
|
int _curMusicTheme;
|
||||||
int _newMusicTheme;
|
int _newMusicTheme;
|
||||||
int16 _lastMusicCommand;
|
int16 _lastMusicCommand;
|
||||||
AudioStream *_currentVocFile;
|
|
||||||
Audio::SoundHandle _vocHandle;
|
|
||||||
|
|
||||||
Resource *_res;
|
Resource *_res;
|
||||||
Screen *_screen;
|
Screen *_screen;
|
||||||
ScreenAnimator *_animator;
|
ScreenAnimator *_animator;
|
||||||
MusicPlayer *_midi;
|
Sound *_sound;
|
||||||
SeqPlayer *_seq;
|
SeqPlayer *_seq;
|
||||||
Sprites *_sprites;
|
Sprites *_sprites;
|
||||||
TextDisplayer *_text;
|
TextDisplayer *_text;
|
||||||
|
|
|
@ -50,9 +50,7 @@ int KyraEngine::cmd_characterSays(ScriptState *script) {
|
||||||
|
|
||||||
if (_features & GF_TALKIE) {
|
if (_features & GF_TALKIE) {
|
||||||
debug(3, "cmd_characterSays(0x%X) (%d, '%s', %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3));
|
debug(3, "cmd_characterSays(0x%X) (%d, '%s', %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3));
|
||||||
while (snd_voicePlaying() && !_fastMode) {
|
snd_voiceWaitForFinish();
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
snd_playVoiceFile(stackPos(0));
|
snd_playVoiceFile(stackPos(0));
|
||||||
characterSays(stackPosString(1), stackPos(2), stackPos(3));
|
characterSays(stackPosString(1), stackPos(2), stackPos(3));
|
||||||
} else {
|
} else {
|
||||||
|
@ -614,9 +612,7 @@ int KyraEngine::cmd_loadPageFromDisk(ScriptState *script) {
|
||||||
int KyraEngine::cmd_customPrintTalkString(ScriptState *script) {
|
int KyraEngine::cmd_customPrintTalkString(ScriptState *script) {
|
||||||
if (_features & GF_TALKIE) {
|
if (_features & GF_TALKIE) {
|
||||||
debug(3, "cmd_customPrintTalkString(0x%X) (%d, '%s', %d, %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF);
|
debug(3, "cmd_customPrintTalkString(0x%X) (%d, '%s', %d, %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF);
|
||||||
while (snd_voicePlaying() && !_fastMode) {
|
snd_voiceWaitForFinish();
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
snd_playVoiceFile(stackPos(0));
|
snd_playVoiceFile(stackPos(0));
|
||||||
_text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2);
|
_text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -42,7 +42,7 @@ SeqPlayer::SeqPlayer(KyraEngine* vm, OSystem* system) {
|
||||||
_system = system;
|
_system = system;
|
||||||
|
|
||||||
_screen = vm->screen();
|
_screen = vm->screen();
|
||||||
_midi = vm->midi();
|
_sound = vm->sound();
|
||||||
_res = vm->resource();
|
_res = vm->resource();
|
||||||
|
|
||||||
_copyViewOffs = false;
|
_copyViewOffs = false;
|
||||||
|
@ -374,7 +374,7 @@ void SeqPlayer::s1_fillRect() {
|
||||||
void SeqPlayer::s1_playEffect() {
|
void SeqPlayer::s1_playEffect() {
|
||||||
uint8 track = *_seqData++;
|
uint8 track = *_seqData++;
|
||||||
_vm->waitTicks(3);
|
_vm->waitTicks(3);
|
||||||
_midi->playSoundEffect(track);
|
_sound->playSoundEffect(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SeqPlayer::s1_playTrack() {
|
void SeqPlayer::s1_playTrack() {
|
||||||
|
@ -387,7 +387,7 @@ void SeqPlayer::s1_playTrack() {
|
||||||
// nothing to do here...
|
// nothing to do here...
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
_midi->beginFadeOut();
|
_sound->beginFadeOut();
|
||||||
break;
|
break;
|
||||||
case 56:
|
case 56:
|
||||||
_vm->snd_playTheme(KyraEngine::MUSIC_INTRO, 3);
|
_vm->snd_playTheme(KyraEngine::MUSIC_INTRO, 3);
|
||||||
|
@ -406,7 +406,7 @@ void SeqPlayer::s1_playTrack() {
|
||||||
if (msg == 0) {
|
if (msg == 0) {
|
||||||
// nothing to do here...
|
// nothing to do here...
|
||||||
} else if (msg == 1) {
|
} else if (msg == 1) {
|
||||||
_midi->beginFadeOut();
|
_sound->beginFadeOut();
|
||||||
} else {
|
} else {
|
||||||
_vm->snd_playTrack(msg);
|
_vm->snd_playTrack(msg);
|
||||||
}
|
}
|
||||||
|
@ -445,9 +445,7 @@ void SeqPlayer::s1_loadIntroVRM() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SeqPlayer::s1_playVocFile() {
|
void SeqPlayer::s1_playVocFile() {
|
||||||
while (_vm->snd_voicePlaying()) {
|
_vm->snd_voiceWaitForFinish(false);
|
||||||
_system->delayMillis(10);
|
|
||||||
}
|
|
||||||
uint8 a = *_seqData++;
|
uint8 a = *_seqData++;
|
||||||
_vm->snd_playVoiceFile(a);
|
_vm->snd_playVoiceFile(a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ protected:
|
||||||
KyraEngine *_vm;
|
KyraEngine *_vm;
|
||||||
OSystem *_system;
|
OSystem *_system;
|
||||||
Screen *_screen;
|
Screen *_screen;
|
||||||
MusicPlayer *_midi;
|
Sound *_sound;
|
||||||
Resource *_res;
|
Resource *_res;
|
||||||
|
|
||||||
uint8 *_handShapes[3];
|
uint8 *_handShapes[3];
|
||||||
|
|
|
@ -24,9 +24,13 @@
|
||||||
#include "kyra/resource.h"
|
#include "kyra/resource.h"
|
||||||
#include "kyra/sound.h"
|
#include "kyra/sound.h"
|
||||||
|
|
||||||
|
#include "sound/mixer.h"
|
||||||
|
#include "sound/voc.h"
|
||||||
|
#include "sound/audiostream.h"
|
||||||
|
|
||||||
namespace Kyra {
|
namespace Kyra {
|
||||||
|
|
||||||
MusicPlayer::MusicPlayer(MidiDriver *driver, KyraEngine *engine) {
|
SoundPC::SoundPC(MidiDriver *driver, Audio::Mixer *mixer, KyraEngine *engine) : Sound() {
|
||||||
_engine = engine;
|
_engine = engine;
|
||||||
_driver = driver;
|
_driver = driver;
|
||||||
_passThrough = false;
|
_passThrough = false;
|
||||||
|
@ -49,14 +53,17 @@ MusicPlayer::MusicPlayer(MidiDriver *driver, KyraEngine *engine) {
|
||||||
if (ret != MERR_ALREADY_OPEN && ret != 0) {
|
if (ret != MERR_ALREADY_OPEN && ret != 0) {
|
||||||
error("couldn't open midi driver");
|
error("couldn't open midi driver");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_currentVocFile = 0;
|
||||||
|
_mixer = mixer;
|
||||||
}
|
}
|
||||||
|
|
||||||
MusicPlayer::~MusicPlayer() {
|
SoundPC::~SoundPC() {
|
||||||
_driver->setTimerCallback(NULL, NULL);
|
_driver->setTimerCallback(NULL, NULL);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::setVolume(int volume) {
|
void SoundPC::setVolume(int volume) {
|
||||||
if (volume < 0)
|
if (volume < 0)
|
||||||
volume = 0;
|
volume = 0;
|
||||||
else if (volume > 255)
|
else if (volume > 255)
|
||||||
|
@ -77,7 +84,7 @@ void MusicPlayer::setVolume(int volume) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int MusicPlayer::open() {
|
int SoundPC::open() {
|
||||||
// Don't ever call open without first setting the output driver!
|
// Don't ever call open without first setting the output driver!
|
||||||
if (!_driver)
|
if (!_driver)
|
||||||
return 255;
|
return 255;
|
||||||
|
@ -90,13 +97,13 @@ int MusicPlayer::open() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::close() {
|
void SoundPC::close() {
|
||||||
if (_driver)
|
if (_driver)
|
||||||
_driver->close();
|
_driver->close();
|
||||||
_driver = 0;
|
_driver = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::send(uint32 b) {
|
void SoundPC::send(uint32 b) {
|
||||||
if (_passThrough) {
|
if (_passThrough) {
|
||||||
if ((b & 0xFFF0) == 0x007BB0)
|
if ((b & 0xFFF0) == 0x007BB0)
|
||||||
return;
|
return;
|
||||||
|
@ -140,7 +147,7 @@ void MusicPlayer::send(uint32 b) {
|
||||||
_channel[_virChannel[channel]]->send(b);
|
_channel[_virChannel[channel]]->send(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) {
|
void SoundPC::metaEvent(byte type, byte *data, uint16 length) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0x2F: // End of Track
|
case 0x2F: // End of Track
|
||||||
if (_eventFromMusic) {
|
if (_eventFromMusic) {
|
||||||
|
@ -161,7 +168,7 @@ void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::playMusic(const char *file) {
|
void SoundPC::playMusic(const char *file) {
|
||||||
uint32 size;
|
uint32 size;
|
||||||
uint8 *data = (_engine->resource())->fileData(file, &size);
|
uint8 *data = (_engine->resource())->fileData(file, &size);
|
||||||
|
|
||||||
|
@ -173,7 +180,7 @@ void MusicPlayer::playMusic(const char *file) {
|
||||||
playMusic(data, size);
|
playMusic(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::playMusic(uint8 *data, uint32 size) {
|
void SoundPC::playMusic(uint8 *data, uint32 size) {
|
||||||
stopMusic();
|
stopMusic();
|
||||||
|
|
||||||
_parserSource = data;
|
_parserSource = data;
|
||||||
|
@ -193,7 +200,7 @@ void MusicPlayer::playMusic(uint8 *data, uint32 size) {
|
||||||
_parser->property(MidiParser::mpAutoLoop, false);
|
_parser->property(MidiParser::mpAutoLoop, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::loadSoundEffectFile(const char *file) {
|
void SoundPC::loadSoundEffectFile(const char *file) {
|
||||||
uint32 size;
|
uint32 size;
|
||||||
uint8 *data = (_engine->resource())->fileData(file, &size);
|
uint8 *data = (_engine->resource())->fileData(file, &size);
|
||||||
|
|
||||||
|
@ -205,7 +212,7 @@ void MusicPlayer::loadSoundEffectFile(const char *file) {
|
||||||
loadSoundEffectFile(data, size);
|
loadSoundEffectFile(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::loadSoundEffectFile(uint8 *data, uint32 size) {
|
void SoundPC::loadSoundEffectFile(uint8 *data, uint32 size) {
|
||||||
stopSoundEffect();
|
stopSoundEffect();
|
||||||
|
|
||||||
_soundEffectSource = data;
|
_soundEffectSource = data;
|
||||||
|
@ -225,7 +232,7 @@ void MusicPlayer::loadSoundEffectFile(uint8 *data, uint32 size) {
|
||||||
_soundEffect->property(MidiParser::mpAutoLoop, false);
|
_soundEffect->property(MidiParser::mpAutoLoop, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::stopMusic() {
|
void SoundPC::stopMusic() {
|
||||||
_isLooping = false;
|
_isLooping = false;
|
||||||
_isPlaying = false;
|
_isPlaying = false;
|
||||||
if (_parser) {
|
if (_parser) {
|
||||||
|
@ -241,7 +248,7 @@ void MusicPlayer::stopMusic() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::stopSoundEffect() {
|
void SoundPC::stopSoundEffect() {
|
||||||
_sfxIsPlaying = false;
|
_sfxIsPlaying = false;
|
||||||
if (_soundEffect) {
|
if (_soundEffect) {
|
||||||
_soundEffect->unloadMusic();
|
_soundEffect->unloadMusic();
|
||||||
|
@ -252,8 +259,8 @@ void MusicPlayer::stopSoundEffect() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::onTimer(void *refCon) {
|
void SoundPC::onTimer(void *refCon) {
|
||||||
MusicPlayer *music = (MusicPlayer *)refCon;
|
SoundPC *music = (SoundPC *)refCon;
|
||||||
|
|
||||||
// this should be set to the fadeToBlack value
|
// this should be set to the fadeToBlack value
|
||||||
static const uint32 musicFadeTime = 2 * 1000;
|
static const uint32 musicFadeTime = 2 * 1000;
|
||||||
|
@ -295,7 +302,7 @@ void MusicPlayer::onTimer(void *refCon) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::playTrack(uint8 track, bool loop) {
|
void SoundPC::playTrack(uint8 track, bool loop) {
|
||||||
if (_parser) {
|
if (_parser) {
|
||||||
_isPlaying = true;
|
_isPlaying = true;
|
||||||
_isLooping = loop;
|
_isLooping = loop;
|
||||||
|
@ -306,7 +313,7 @@ void MusicPlayer::playTrack(uint8 track, bool loop) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::playSoundEffect(uint8 track) {
|
void SoundPC::playSoundEffect(uint8 track) {
|
||||||
if (_soundEffect) {
|
if (_soundEffect) {
|
||||||
_sfxIsPlaying = true;
|
_sfxIsPlaying = true;
|
||||||
_soundEffect->setTrack(track);
|
_soundEffect->setTrack(track);
|
||||||
|
@ -315,10 +322,27 @@ void MusicPlayer::playSoundEffect(uint8 track) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicPlayer::beginFadeOut() {
|
void SoundPC::beginFadeOut() {
|
||||||
// this should be something like fade out...
|
// this should be something like fade out...
|
||||||
_fadeMusicOut = true;
|
_fadeMusicOut = true;
|
||||||
_fadeStartTime = _engine->_system->getMillis();
|
_fadeStartTime = _engine->_system->getMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundPC::voicePlay(const char *file) {
|
||||||
|
uint32 fileSize = 0;
|
||||||
|
byte *fileData = 0;
|
||||||
|
fileData = _engine->resource()->fileData(file, &fileSize);
|
||||||
|
assert(fileData);
|
||||||
|
Common::MemoryReadStream vocStream(fileData, fileSize);
|
||||||
|
_mixer->stopHandle(_vocHandle);
|
||||||
|
_currentVocFile = makeVOCStream(vocStream);
|
||||||
|
if (_currentVocFile)
|
||||||
|
_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandle, _currentVocFile);
|
||||||
|
delete fileData;
|
||||||
|
fileSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundPC::voiceIsPlaying() {
|
||||||
|
return _mixer->isSoundHandleActive(_vocHandle);
|
||||||
|
}
|
||||||
} // end of namespace Kyra
|
} // end of namespace Kyra
|
||||||
|
|
66
kyra/sound.h
66
kyra/sound.h
|
@ -28,13 +28,50 @@
|
||||||
#include "sound/midiparser.h"
|
#include "sound/midiparser.h"
|
||||||
#include "kyra/kyra.h"
|
#include "kyra/kyra.h"
|
||||||
|
|
||||||
|
class AudioStream;
|
||||||
|
|
||||||
|
namespace Audio {
|
||||||
|
class Mixer;
|
||||||
|
class SoundHandle;
|
||||||
|
} // end of namespace Audio
|
||||||
|
|
||||||
namespace Kyra {
|
namespace Kyra {
|
||||||
|
|
||||||
class MusicPlayer : public MidiDriver {
|
class Sound {
|
||||||
|
public:
|
||||||
|
Sound() {}
|
||||||
|
virtual ~Sound() {}
|
||||||
|
|
||||||
|
virtual void setVolume(int volume) = 0;
|
||||||
|
virtual int getVolume() = 0;
|
||||||
|
|
||||||
|
virtual void playMusic(const char *file) = 0;
|
||||||
|
virtual void playMusic(uint8 *data, uint32 size) = 0;
|
||||||
|
virtual void stopMusic() = 0;
|
||||||
|
|
||||||
|
virtual void playTrack(uint8 track, bool looping = true) = 0;
|
||||||
|
virtual void haltTrack() = 0;
|
||||||
|
virtual void startTrack() = 0;
|
||||||
|
|
||||||
|
virtual void loadSoundEffectFile(const char *file) = 0;
|
||||||
|
virtual void loadSoundEffectFile(uint8 *data, uint32 size) = 0;
|
||||||
|
virtual void stopSoundEffect() = 0;
|
||||||
|
|
||||||
|
virtual void playSoundEffect(uint8 track) = 0;
|
||||||
|
|
||||||
|
virtual void beginFadeOut() = 0;
|
||||||
|
virtual bool fadeOut() = 0;
|
||||||
|
|
||||||
|
virtual void voicePlay(const char *file) = 0;
|
||||||
|
virtual void voiceUnload() = 0;
|
||||||
|
virtual bool voiceIsPlaying() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundPC : public MidiDriver, public Sound {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MusicPlayer(MidiDriver *driver, KyraEngine *engine);
|
SoundPC(MidiDriver *driver, Audio::Mixer *mixer, KyraEngine *engine);
|
||||||
~MusicPlayer();
|
~SoundPC();
|
||||||
|
|
||||||
void setVolume(int volume);
|
void setVolume(int volume);
|
||||||
int getVolume() { return _volume; }
|
int getVolume() { return _volume; }
|
||||||
|
@ -42,23 +79,27 @@ public:
|
||||||
void hasNativeMT32(bool nativeMT32) { _nativeMT32 = nativeMT32; }
|
void hasNativeMT32(bool nativeMT32) { _nativeMT32 = nativeMT32; }
|
||||||
bool isMT32() { return _nativeMT32; }
|
bool isMT32() { return _nativeMT32; }
|
||||||
|
|
||||||
void playMusic(const char* file);
|
void playMusic(const char *file);
|
||||||
void playMusic(uint8* data, uint32 size);
|
void playMusic(uint8 *data, uint32 size);
|
||||||
void stopMusic();
|
void stopMusic();
|
||||||
|
|
||||||
void playTrack(uint8 track, bool looping = true);
|
void playTrack(uint8 track, bool looping);
|
||||||
void haltTrack() { _isPlaying = false; }
|
void haltTrack() { _isPlaying = false; }
|
||||||
void startTrack() { _isPlaying = true; }
|
void startTrack() { _isPlaying = true; }
|
||||||
void setPassThrough(bool b) { _passThrough = b; }
|
void setPassThrough(bool b) { _passThrough = b; }
|
||||||
|
|
||||||
void loadSoundEffectFile(const char* file);
|
void loadSoundEffectFile(const char *file);
|
||||||
void loadSoundEffectFile(uint8* data, uint32 size);
|
void loadSoundEffectFile(uint8 *data, uint32 size);
|
||||||
void stopSoundEffect();
|
void stopSoundEffect();
|
||||||
|
|
||||||
void playSoundEffect(uint8 track);
|
void playSoundEffect(uint8 track);
|
||||||
|
|
||||||
void beginFadeOut();
|
void beginFadeOut();
|
||||||
bool fadeOut() { return _fadeMusicOut; }
|
bool fadeOut() { return _fadeMusicOut; }
|
||||||
|
|
||||||
|
void voicePlay(const char *file);
|
||||||
|
void voiceUnload() {};
|
||||||
|
bool voiceIsPlaying();
|
||||||
|
|
||||||
//MidiDriver interface implementation
|
//MidiDriver interface implementation
|
||||||
int open();
|
int open();
|
||||||
|
@ -77,10 +118,10 @@ protected:
|
||||||
|
|
||||||
static void onTimer(void *data);
|
static void onTimer(void *data);
|
||||||
|
|
||||||
MidiChannel* _channel[32];
|
MidiChannel *_channel[32];
|
||||||
int _virChannel[16];
|
int _virChannel[16];
|
||||||
uint8 _channelVolume[16];
|
uint8 _channelVolume[16];
|
||||||
MidiDriver* _driver;
|
MidiDriver *_driver;
|
||||||
bool _nativeMT32;
|
bool _nativeMT32;
|
||||||
bool _passThrough;
|
bool _passThrough;
|
||||||
uint8 _volume;
|
uint8 _volume;
|
||||||
|
@ -95,8 +136,11 @@ protected:
|
||||||
MidiParser *_soundEffect;
|
MidiParser *_soundEffect;
|
||||||
byte *_soundEffectSource;
|
byte *_soundEffectSource;
|
||||||
KyraEngine *_engine;
|
KyraEngine *_engine;
|
||||||
|
|
||||||
|
Audio::Mixer *_mixer;
|
||||||
|
AudioStream *_currentVocFile;
|
||||||
|
Audio::SoundHandle _vocHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Kyra
|
} // end of namespace Kyra
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue