aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/lol.cpp55
-rw-r--r--engines/kyra/lol.h8
-rw-r--r--engines/kyra/screen_lol.cpp5
-rw-r--r--engines/kyra/screen_lol.h1
-rw-r--r--engines/kyra/script_lol.cpp16
-rw-r--r--engines/kyra/sound.cpp10
-rw-r--r--engines/kyra/sound.h2
-rw-r--r--engines/kyra/text_lol.cpp143
-rw-r--r--engines/kyra/text_lol.h10
9 files changed, 197 insertions, 53 deletions
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index f2ec3950fa..b6b655bd9c 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -190,7 +190,8 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
memset(_activeTim, 0, sizeof(_activeTim));
memset(_activeVoiceFile, 0, sizeof(_activeVoiceFile));
memset(_openDoorState, 0, sizeof(_openDoorState));
-
+
+ _activeVoiceFileTotalTime = 0;
_pageBuffer1 = _pageBuffer2 = 0;
memset(_charStatsTemp, 0, sizeof(_charStatsTemp));
@@ -359,8 +360,7 @@ Common::Error LoLEngine::init() {
_pageBuffer2 = new uint8[0xfa00];
memset(_pageBuffer2, 0, 0xfa00);
- // FIXME: Why do we allocate a 401 entry array, if only 400 entries are used?
- _itemsInPlay = new ItemInPlay[401];
+ _itemsInPlay = new ItemInPlay[400];
memset(_itemsInPlay, 0, sizeof(ItemInPlay) * 400);
_characters = new LoLCharacter[4];
@@ -416,7 +416,7 @@ Common::Error LoLEngine::init() {
memset(_tmpData136, 0, 136);
memset(_gameFlags, 0, 16 * sizeof(uint16));
- memset(_unkEMC46, 0, 16 * sizeof(uint16));
+ memset(_globalScriptVars, 0, 16 * sizeof(uint16));
_levelFileData = 0;
_lvlShpFileHandle = 0;
@@ -1167,9 +1167,44 @@ void LoLEngine::restoreAfterAnimatedDialogue(int redraw) {
}
void LoLEngine::initNonAnimatedDialogue(int controlMode, int pageNum) {
+ if (controlMode) {
+ _timer->disable(11);
+ _fadeText = false;
+ int cp = _screen->setCurPage(pageNum);
+
+ _screen->fillRect(0, 128, 319, 199, 1);
+ gui_drawBox(0, 129, 320, 71, 136, 251, -1);
+ gui_drawBox(1, 130, 318, 69, 136, 251, 252);
+
+ _screen->modifyScreenDim(5, 8, 131, 304, 66);
+ _screen->modifyScreenDim(4, 1, 133, 38, 60);
+ _screen->clearDim(4);
+
+ _updateFlags |= 2;
+ _hideControls = controlMode;
+ calcCharPortraitXpos();
+
+ if (!textEnabled() && (!(controlMode & 2))) {
+ int nc = countActiveCharacters();
+ for (int i = 0; i < nc; i++) {
+ _portraitSpeechAnimMode = 2;
+ _updateCharNum = i;
+ _screen->drawShape(0, _gameShapes[88], _activeCharsXpos[_updateCharNum] + 8, 142, 0, 0);
+ updatePortraits();
+ }
+ }
+
+ _screen->setCurPage(cp);
+
+ } else {
+ _txt->setupField(true);
+ _txt->expandField();
+ setupScreenDims();
+ _screen->clearDim(4);
+ }
- _dialogueField = true;
-
+ _hideControls = controlMode;
+ _dialogueField = true;
}
void LoLEngine::restoreAfterNonAnimatedDialogue(int controlMode) {
@@ -1327,7 +1362,7 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) {
};
strcpy(_activeVoiceFile, *playList.begin());
- _sound->voicePlayFromList(playList);
+ _activeVoiceFileTotalTime = _sound->voicePlayFromList(playList);
for (Common::List<const char*>::iterator i = playList.begin(); i != playList.end(); i++)
delete []*i;
@@ -1343,6 +1378,7 @@ int LoLEngine::snd_characterSpeaking() {
return 2;
_lastSpeechId = _lastSpeaker = -1;
+ _activeVoiceFileTotalTime = 0;
return 1;
}
@@ -1353,11 +1389,16 @@ void LoLEngine::snd_stopSpeech(bool setFlag) {
//_dlgTimer = 0;
_sound->voiceStop(_activeVoiceFile);
+ _activeVoiceFileTotalTime = 0;
if (setFlag)
_tim->_abortFlag = 1;
}
+uint32 LoLEngine::snd_getElapsedSpeechTime() {
+ return _sound->voicePlayedTime(_activeVoiceFile);
+}
+
void LoLEngine::snd_playSoundEffect(int track, int volume) {
debugC(9, kDebugLevelMain | kDebugLevelSound, "LoLEngine::snd_playSoundEffect(%d, %d)", track, volume);
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 91883117a1..3e7ab12547 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -327,6 +327,7 @@ private:
bool snd_playCharacterSpeech(int id, int8 speaker, int);
int snd_characterSpeaking();
void snd_stopSpeech(bool setFlag);
+ uint32 snd_getElapsedSpeechTime();
void snd_playSoundEffect(int track, int volume);
void snd_processEnvironmentalSoundEffect(int soundId, int block);
void snd_loadSoundFile(int track);
@@ -336,6 +337,7 @@ private:
int _lastSpeechId;
int _lastSpeaker;
char _activeVoiceFile[13];
+ uint32 _activeVoiceFileTotalTime;
int _lastSfxTrack;
int _lastMusicTrack;
int _curMusicFileIndex;
@@ -494,7 +496,7 @@ private:
bool _sceneUpdateRequired;
int16 _currentBlockPropertyIndex[18];
uint16 _gameFlags[16];
- uint16 _unkEMC46[16];
+ uint16 _globalScriptVars[16];
// emc opcode
int olol_drawScene(EMCState *script);
@@ -519,8 +521,8 @@ private:
int olol_getDirection(EMCState *script);
int olol_setMusicTrack(EMCState *script);
int olol_clearDialogueField(EMCState *script);
- int olol_getUnkArrayVal(EMCState *script);
- int olol_setUnkArrayVal(EMCState *script);
+ int olol_getGlobalScriptVar(EMCState *script);
+ int olol_setGlobalScriptVar(EMCState *script);
int olol_getGlobalVar(EMCState *script);
int olol_setGlobalVar(EMCState *script);
int olol_triggerDoorSwitch(EMCState *script);
diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp
index 615dd0c4b3..884dee4712 100644
--- a/engines/kyra/screen_lol.cpp
+++ b/engines/kyra/screen_lol.cpp
@@ -92,11 +92,6 @@ void Screen_LoL::clearDim(int dim) {
fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, tmp->unkA);
}
-void Screen_LoL::clearCurDim() {
- fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _curDim->unkA);
- _dimLineCount = 0;
-}
-
void Screen_LoL::fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...) {
debugC(9, kDebugLevelScreen, "Screen_LoL::fprintString('%s', %d, %d, %d, %d, %d, ...)", format, x, y, col1, col2, flags);
if (!format)
diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h
index 1b1842bffc..4de43788b1 100644
--- a/engines/kyra/screen_lol.h
+++ b/engines/kyra/screen_lol.h
@@ -44,7 +44,6 @@ public:
int curDimIndex() { return _curDimIndex; }
void modifyScreenDim(int dim, int x, int y, int w, int h);
void clearDim(int dim);
- void clearCurDim();
void fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...);
void fprintStringIntro(const char *format, int x, int y, uint8 c1, uint8 c2, uint8 c3, uint16 flags, ...);
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index b4127a7774..31414f3b50 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -452,12 +452,16 @@ int LoLEngine::olol_clearDialogueField(EMCState *script) {
return 1;
}
-int LoLEngine::olol_getUnkArrayVal(EMCState *script) {
- return _unkEMC46[stackPos(0)];
+int LoLEngine::olol_getGlobalScriptVar(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getGlobalScriptVar(%p) (%d)", (const void *)script, stackPos(0));
+ assert(stackPos(0) < 16);
+ return _globalScriptVars[stackPos(0)];
}
-int LoLEngine::olol_setUnkArrayVal(EMCState *script) {
- _unkEMC46[stackPos(0)] = stackPos(1);
+int LoLEngine::olol_setGlobalScriptVar(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setGlobalScriptVar(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ assert(stackPos(0) < 16);
+ _globalScriptVars[stackPos(0)] = stackPos(1);
return 1;
}
@@ -1194,8 +1198,8 @@ void LoLEngine::setupOpcodeTable() {
// 0x2C
OpcodeUnImpl();
- Opcode(olol_getUnkArrayVal);
- Opcode(olol_setUnkArrayVal);
+ Opcode(olol_getGlobalScriptVar);
+ Opcode(olol_setGlobalScriptVar);
Opcode(olol_getGlobalVar);
// 0x30
diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp
index 47045c21cd..4b4439c1e3 100644
--- a/engines/kyra/sound.cpp
+++ b/engines/kyra/sound.cpp
@@ -115,21 +115,22 @@ int32 Sound::voicePlay(const char *file, uint8 volume, bool isSfx) {
return audioStream->getTotalPlayTime();
}
-void Sound::voicePlayFromList(Common::List<const char*> fileList) {
+uint32 Sound::voicePlayFromList(Common::List<const char*> fileList) {
int h = 0;
while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles)
h++;
if (h >= kNumChannelHandles)
- return;
+ return 0;
Audio::AppendableAudioStream *out = Audio::makeAppendableAudioStream(22050, Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED);
for (Common::List<const char*>::iterator i = fileList.begin(); i != fileList.end(); i++) {
Common::SeekableReadStream *file = _vm->resource()->createReadStream(*i);
- // TODO: Maybe output an warning like "file not found"?
- if (!file)
+ if (!file) {
+ warning("Couldn't load voice file: %s", *i);
continue;
+ }
int size, rate;
uint8 *data = Audio::loadVOCFromStream(*file, size, rate);
@@ -151,6 +152,7 @@ void Sound::voicePlayFromList(Common::List<const char*> fileList) {
_soundChannels[h].file = *fileList.begin();
_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, out);
+ return out->getTotalPlayTime();
}
void Sound::voiceStop(const char *file) {
diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h
index 6f6a088b8b..7b7fba8e3a 100644
--- a/engines/kyra/sound.h
+++ b/engines/kyra/sound.h
@@ -203,7 +203,7 @@ public:
*
* @param fileList: files to be played
*/
- virtual void voicePlayFromList(Common::List<const char*> fileList);
+ virtual uint32 voicePlayFromList(Common::List<const char*> fileList);
/**
* Checks if a voice is being played.
diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp
index ac7d7c4a6c..5996712bd3 100644
--- a/engines/kyra/text_lol.cpp
+++ b/engines/kyra/text_lol.cpp
@@ -31,7 +31,7 @@
namespace Kyra {
TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm), _screen(screen),
- _scriptParameter(0), _stringLength(0), _animWidth(0), _animColour1(0), _animColour2(0), _animFlag(true),
+ _scriptParameter(0), _animWidth(0), _animColour1(0), _animColour2(0), _animFlag(true),
_printFlag(false), _lineWidth(0), _numChars(0), _numCharsPrinted(0), _posX(0), _posY(0), _colour1(0), _colour2(0) {
memset(_stringParameters, 0, 15 * sizeof(char*));
@@ -184,10 +184,10 @@ void TextDisplayer_LoL::printMessage(uint16 type, char *str, ...) {
if (_vm->_updateFlags & 2) {
_screen->setScreenDim(4);
- _screen->clearCurDim();
+ clearCurDim();
} else {
_screen->setScreenDim(3);
- _screen->clearCurDim();
+ clearCurDim();
_screen->copyColour(192, col);
_vm->enableTimer(11);
}
@@ -360,10 +360,7 @@ void TextDisplayer_LoL::displayText(char *str, ...) {
switch (c - 1) {
case 0:
printLine(_currentLine);
- //if (!_dlgAnimCallback)
- // break;
-
- portraitAnimation2();
+ textPageBreak();
_numCharsPrinted = 0;
break;
@@ -478,10 +475,8 @@ void TextDisplayer_LoL::printLine(char *str) {
while (_posY >= lines) {
if (lines <= _screen->_dimLineCount && _animFlag) {
_screen->_dimLineCount = 0;
- //if (_dlgAnimCallback) {
- portraitAnimation2();
- _numCharsPrinted = 0;
- //}
+ textPageBreak();
+ _numCharsPrinted = 0;
}
int h1 = ((sd->h / fh) - 1) * fh;
@@ -490,9 +485,9 @@ void TextDisplayer_LoL::printLine(char *str) {
if (h2)
_screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK);
- _screen->fillRect(sd->sx << 3, sd->sy + h1, (sd->sx + sd->w - 1) << 3, sd->sy + sd->h - 1, _colour2);
-
- _posY--;
+ _screen->fillRect(sd->sx << 3, sd->sy + h1, (sd->sx + sd->w - 1) << 3, sd->sy + sd->h - 1, _colour2);
+ if (_posY)
+ _posY--;
}
int x1 = (sd->sx << 3) + _posX;
@@ -567,12 +562,122 @@ void TextDisplayer_LoL::printLine(char *str) {
printLine(str);
}
-/*void TextDisplayer_LoL::portraitAnimation1(const char *str, uint16 lineWidth, uint8 col1, uint8 col2, uint16 numCharsPrinted) {
-
-}*/
+void TextDisplayer_LoL::textPageBreak() {
+ int cp = _screen->setCurPage(0);
+ Screen::FontId cf = _screen->setFont(Screen::FID_6_FNT);
+
+ _vm->_timer->pauseSingleTimer(11, true);
+
+ _vm->_fadeText = false;
+ int updateCharV3 = 0;
+ int updatePortraitSpeechAnimDuration = 0;
+
+ if (_vm->_updateCharNum != -1) {
+ updateCharV3 = _vm->_updateCharV3;
+ _vm->_updateCharV3 = 0;
+ updatePortraitSpeechAnimDuration = _vm->_updatePortraitSpeechAnimDuration;
+ if (_vm->_updatePortraitSpeechAnimDuration > 36)
+ _vm->_updatePortraitSpeechAnimDuration = 36;
+ }
+
+ uint32 speechPartTime = 0;
+ if (_vm->_speechFlag && _vm->_activeVoiceFileTotalTime && _numChars)
+ speechPartTime = _vm->_system->getMillis() + ((_numCharsPrinted * _vm->_activeVoiceFileTotalTime) / _numChars);
+
+ const ScreenDim *dim = _screen->getScreenDim(_screen->curDimIndex());
+
+ int x = ((dim->sx + dim->w) << 3) - 77;
+ int y = 0;
+
+ if (_vm->_hideInventory && (_vm->_updateFlags & 2)) {
+ if (_vm->_hideControls || !(_vm->_updateFlags & 2)) {
+ y = dim->sy + dim->h - 5;
+ } else {
+ x += 6;
+ y = dim->sy + dim->h - 2;
+ }
+ } else {
+ y = dim->sy + dim->h - 10;
+ }
+
+ _vm->gui_drawBox(x, y, 74, 9, 136, 251, -1);
+ char *txt = _vm->getLangString(0x4073);
+ _vm->_screen->printText(txt, x + 37 - (_vm->_screen->getTextWidth(txt) >> 1), y + 2, 144, 0);
+
+ _vm->removeInputTop();
+
+ bool loop = true;
+ bool target = false;
+
+ do {
+ int inputFlag = _vm->checkInput(0, false) & 0xFF;
+ _vm->removeInputTop();
+
+ while (!inputFlag) {
+ _vm->update();
+
+ if (_vm->_speechFlag) {
+ if (((_vm->_system->getMillis() > speechPartTime) || (_vm->snd_characterSpeaking() != 2)) && speechPartTime) {
+ loop = false;
+ inputFlag = 43;
+ break;
+ }
+ }
+
+ inputFlag = _vm->checkInput(0, false) & 0xFF;
+ _vm->removeInputTop();
+ }
+
+ _vm->gui_notifyButtonListChanged();
+
+ switch (inputFlag) {
+ case 43:
+ case 61:
+ loop = false;
+ break;
+
+ case 199:
+ case 201:
+ if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, y, x + 74, y + 9))
+ target = true;
+ break;
+
+ case 200:
+ case 202:
+ if (target)
+ loop = false;
+ break;
+
+ default:
+ break;
+ }
+ } while (loop);
+
+ _screen->fillRect(x, y, x + 74, y + 9, _colour2);
+ clearCurDim();
+
+ _vm->_timer->pauseSingleTimer(11, false);
+
+ if (_vm->_updateCharNum != -1) {
+ _vm->_updateCharV3 = updateCharV3;
+ if (updatePortraitSpeechAnimDuration > 36)
+ updatePortraitSpeechAnimDuration -= 36;
+ else
+ updatePortraitSpeechAnimDuration >>= 1;
+
+ _vm->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration;
+ }
+
+ _screen->setFont(cf);
+ _screen->setCurPage(cp);
+ _vm->removeInputTop();
+}
-void TextDisplayer_LoL::portraitAnimation2() {
- // TODO
+void TextDisplayer_LoL::clearCurDim() {
+ const ScreenDim *tmp = _screen->getScreenDim(_screen->curDimIndex());
+ _screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _colour2);
+ _screen->_dimLineCount = 0;
+ _posX = _posY = 0;
}
} // end of namespace Kyra
diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h
index 82eebd862d..9876bfbb56 100644
--- a/engines/kyra/text_lol.h
+++ b/engines/kyra/text_lol.h
@@ -55,12 +55,9 @@ private:
void readNextPara();
void printLine(char *str);
void preprocessString(char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
-
- //typedef void (LoLEngine::*DialogueAnimCallback)(const char *str, uint16 lineWidth, uint8 col1, uint8 col2);
- //DialogueAnimCallback _dlgAnimCallback;
- //void portraitAnimation1(const char *str);
- void portraitAnimation2();
-
+ void textPageBreak();
+
+ void clearCurDim();
char *_stringParameters[15];
char *_buffer;
@@ -71,7 +68,6 @@ private:
char _ctrl[3];
char _scriptParaString[11];
- uint32 _stringLength;
uint16 _lineWidth;
uint32 _numChars;