MOHAWK: Implement Myst demo opcodes 298 and 299, sneak preview speech.

This commit is contained in:
Bastien Bouclet 2011-08-13 20:18:23 +02:00
parent 0e8840568b
commit 0bbd43eb32
6 changed files with 169 additions and 32 deletions

View File

@ -672,6 +672,14 @@ void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
_nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
}
void MystGraphics::fadeToBlack() {
// TODO: Implement
}
void MystGraphics::fadeFromBlack() {
// TODO: Implement
}
#endif // ENABLE_MYST
#ifdef ENABLE_RIVEN

View File

@ -129,6 +129,8 @@ public:
void drawRect(Common::Rect rect, RectState state);
void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color);
void enableDrawingTimeSimulation(bool enable);
void fadeToBlack();
void fadeFromBlack();
protected:
MohawkSurface *decodeImage(uint16 id);

View File

@ -40,8 +40,8 @@ public:
Myst(MohawkEngine_Myst *vm);
~Myst();
void disablePersistentScripts();
void runPersistentScripts();
virtual void disablePersistentScripts();
virtual void runPersistentScripts();
private:
void setupOpcodes();

View File

@ -60,13 +60,24 @@ void Preview::setupOpcodes() {
OVERRIDE_OPCODE(199, opcode_199);
// "Init" Opcodes
OPCODE(298, opcode_298);
OPCODE(299, opcode_299);
OPCODE(298, o_speech_init);
OPCODE(299, o_library_init);
}
#undef OPCODE
#undef OVERRIDE_OPCODE
void Preview::disablePersistentScripts() {
Myst::disablePersistentScripts();
}
void Preview::runPersistentScripts() {
Myst::runPersistentScripts();
if (_speechRunning)
speech_run();
}
void Preview::opcode_196(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
@ -103,37 +114,138 @@ void Preview::opcode_199(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
// Voice Over and Card Advance?
}
void Preview::opcode_298(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
void Preview::speechUpdateCue() {
// This is a callback in the original, handling audio events.
if (!_vm->_sound->isPlaying(3001)) {
return;
}
// Used for Card 3000 (Closed Myst Book)
// TODO: Fill in logic.
// Start Voice Over... which controls book opening
_vm->_sound->replaceSoundMyst(3001);
// then link to Myst - Trigger of Hotspot? then opcode 199/196/197 for voice over continue?
// TODO: Sync Voice and Actions to Original
// TODO: Flash Library Red
// TODO: Move to run process based delay to prevent
// blocking...
_vm->_system->updateScreen();
_vm->_system->delayMillis(20 * 1000);
for (uint16 imageId = 3001; imageId <= 3012; imageId++) {
_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
_vm->_system->updateScreen();
_vm->_system->delayMillis(5 * 1000);
uint samples = _vm->_sound->getNumSamplesPlayed(3001);
for (int16 i = 0; i < _cueList.pointCount; i++) {
if (_cueList.points[i].sampleFrame > samples)
return;
if (i > _currentCue - 1) {
_currentCue++;
debugC(kDebugScript, "Sneak speech advanced to cue %d", _currentCue);
}
}
}
void Preview::opcode_299(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
void Preview::speech_run() {
uint32 time = _vm->_system->getMillis();
// Update current speech sound cue
speechUpdateCue();
switch (_speechStep) {
case 0: // Start Voice Over... which controls book opening
_currentCue = 0;
_vm->_sound->playSound(3001, Audio::Mixer::kMaxChannelVolume, false, &_cueList);
_speechStep++;
break;
case 1: // Open book
if (_currentCue >= 1) {
_vm->changeToCard(3001, true);
_speechStep++;
}
break;
case 2: // Go to Myst
if (_currentCue >= 2) {
_vm->_gfx->fadeToBlack();
_vm->changeToCard(3002, true);
_vm->_gfx->fadeFromBlack();
_speechStep++;
}
break;
case 3: // Start blinking the library
if (_currentCue >= 3) {
_libraryState = 1;
_speechNextTime = 0;
_speechStep++;
}
break;
case 4: // Library blinking, zoom in library
if (_currentCue >= 4) {
_library->drawConditionalDataToScreen(0);
_vm->changeToCard(3003, true);
_speechNextTime = time + 2000;
_speechStep++;
} else {
if (time < _speechNextTime)
break;
_library->drawConditionalDataToScreen(_libraryState);
_libraryState = (_libraryState + 1) % 2;
_speechNextTime = time + 500;
}
break;
case 5: // Go to library near view
if (time < _speechNextTime)
break;
_vm->changeToCard(3004, true);
_speechNextTime = time + 2000;
_speechStep++;
break;
case 6: // Fade to courtyard
if (time < _speechNextTime)
break;
_vm->_gfx->fadeToBlack();
_vm->changeToCard(3005, true);
_vm->_gfx->fadeFromBlack();
_speechNextTime = time + 1000;
_speechStep++;
break;
case 7: // Walk to library
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
if (time < _speechNextTime)
break;
_vm->changeToCard(3006 + _speechStep - 7, true);
_speechNextTime = time + 2000;
_speechStep++;
break;
case 14: // Go to playable library card
if (time < _speechNextTime)
break;
_vm->changeToCard(4329, true);
_speechRunning = false;
_globals.currentAge = 2;
_vm->_cursor->showCursor();
break;
default:
warning("Unknown speech step");
break;
}
}
void Preview::o_speech_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Speech init", op);
// Used for Card 3000 (Closed Myst Book)
_speechStep = 0;
_speechRunning = true;
}
void Preview::o_library_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Library init", op);
// Used for Card 3002 (Myst Island Overview)
// TODO: Fill in logic.
// Zoom into Island?
// On this card is a Type 8 controlled by Var 0, which
// can change the Myst Library to Red..
_library = static_cast<MystResourceType8 *>(_invokingResource);
}
} // End of namespace MystStacks

View File

@ -40,6 +40,9 @@ public:
Preview(MohawkEngine_Myst *vm);
~Preview();
void disablePersistentScripts();
void runPersistentScripts();
private:
void setupOpcodes();
@ -48,8 +51,20 @@ private:
DECLARE_OPCODE(opcode_198);
DECLARE_OPCODE(opcode_199);
DECLARE_OPCODE(opcode_298);
DECLARE_OPCODE(opcode_299);
DECLARE_OPCODE(o_speech_init);
DECLARE_OPCODE(o_library_init);
uint16 _libraryState; // 4
MystResourceType8 *_library; // 32
bool _speechRunning;
uint _speechStep;
CueList _cueList;
int16 _currentCue;
uint32 _speechNextTime; // 6
void speech_run();
void speechUpdateCue();
};
} // End of namespace MystStacks

View File

@ -85,7 +85,7 @@ Audio::AudioStream *Sound::makeAudioStream(uint16 id, CueList *cueList) {
if (_vm->getFeatures() & GF_ME)
audStream = Audio::makeWAVStream(_vm->getResource(ID_MSND, convertMystID(id)), DisposeAfterUse::YES);
else
audStream = makeMohawkWaveStream(_vm->getResource(ID_MSND, id));
audStream = makeMohawkWaveStream(_vm->getResource(ID_MSND, id), cueList);
break;
case GType_ZOOMBINI:
audStream = makeMohawkWaveStream(_vm->getResource(ID_SND, id));