diff options
Diffstat (limited to 'engines/mohawk/myst.cpp')
-rw-r--r-- | engines/mohawk/myst.cpp | 268 |
1 files changed, 116 insertions, 152 deletions
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp index 6ed7a313a0..b4ec087b61 100644 --- a/engines/mohawk/myst.cpp +++ b/engines/mohawk/myst.cpp @@ -27,9 +27,9 @@ #include "common/debug-channels.h" #include "common/translation.h" +#include "mohawk/cursors.h" #include "mohawk/graphics.h" #include "mohawk/myst.h" -#include "mohawk/myst_scripts.h" #include "mohawk/myst_saveload.h" #include "mohawk/dialogs.h" #include "mohawk/resource.h" @@ -64,6 +64,14 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription _needsUpdate = false; _curResource = -1; + _gfx = NULL; + _console = NULL; + _scriptParser = NULL; + _varStore = NULL; + _saveLoad = NULL; + _loadDialog = NULL; + _optionsDialog = NULL; + _cursorHintCount = 0; _cursorHints = NULL; @@ -83,6 +91,8 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription } MohawkEngine_Myst::~MohawkEngine_Myst() { + DebugMan.clearAllDebugChannels(); + delete _gfx; delete _console; delete _scriptParser; @@ -90,10 +100,17 @@ MohawkEngine_Myst::~MohawkEngine_Myst() { delete _saveLoad; delete _loadDialog; delete _optionsDialog; + + delete[] _cursorHints; + delete[] _view.conditionalImages; delete[] _view.scriptResources; - delete[] _cursorHints; - _resources.clear(); + + while(!_resources.empty()) { + MystResource *temp = _resources.back(); + _resources.pop_back(); + delete temp; + } } // Uses cached data objects in preference to disk access @@ -105,7 +122,7 @@ Common::SeekableReadStream *MohawkEngine_Myst::getRawData(uint32 tag, uint16 id) for (uint32 i = 0; i < _mhk.size(); i++) if (_mhk[i]->hasResource(tag, id)) { - ret = _mhk[i]->getRawData(tag, id); + ret = _mhk[i]->getResource(tag, id); _cache.add(tag, id, ret); return ret; } @@ -121,19 +138,19 @@ void MohawkEngine_Myst::cachePreload(uint32 tag, uint16 id) { for (uint32 i = 0; i < _mhk.size(); i++) { // Check for MJMP in Myst ME if ((getFeatures() & GF_ME) && tag == ID_MSND && _mhk[i]->hasResource(ID_MJMP, id)) { - Common::SeekableReadStream *tempData = _mhk[i]->getRawData(ID_MJMP, id); + Common::SeekableReadStream *tempData = _mhk[i]->getResource(ID_MJMP, id); uint16 msndId = tempData->readUint16LE(); delete tempData; // We've found where the real MSND data is, so go get that - tempData = _mhk[i]->getRawData(tag, msndId); + tempData = _mhk[i]->getResource(tag, msndId); _cache.add(tag, id, tempData); delete tempData; return; } if (_mhk[i]->hasResource(tag, id)) { - Common::SeekableReadStream *tempData = _mhk[i]->getRawData(tag, id); + Common::SeekableReadStream *tempData = _mhk[i]->getResource(tag, id); _cache.add(tag, id, tempData); delete tempData; return; @@ -170,7 +187,7 @@ static const char *mystFiles[] = { // qtw/myst/gar4wbf1.mov: gar4wbf2.mov has two butterflies instead of one // qtw/myst/libelev.mov: libup.mov is basically the same with sound -Common::String MohawkEngine_Myst::wrapMovieFilename(Common::String movieName, uint16 stack) { +Common::String MohawkEngine_Myst::wrapMovieFilename(const Common::String &movieName, uint16 stack) { // The Macintosh release of Myst ME stores its videos in a different folder if ((getFeatures() & GF_ME) && getPlatform() == Common::kPlatformMacintosh) return Common::String("CD Data/m/") + movieName + ".mov"; @@ -222,6 +239,7 @@ Common::Error MohawkEngine_Myst::run() { _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load")); _loadDialog->setSaveMode(false); _optionsDialog = new MystOptionsDialog(this); + _cursor = new MystCursorManager(this); // Start us on the first stack. if (getGameType() == GType_MAKINGOF) @@ -248,7 +266,8 @@ Common::Error MohawkEngine_Myst::run() { // Load Help System (Masterpiece Edition Only) if (getFeatures() & GF_ME) { MohawkArchive *mhk = new MohawkArchive(); - mhk->open("help.dat"); + if (!mhk->open("help.dat")) + error("Could not load help.dat"); _mhk.push_back(mhk); } @@ -256,8 +275,8 @@ Common::Error MohawkEngine_Myst::run() { loadHelp(10000); // Set the cursor - _gfx->changeCursor(_currentCursor); - _gfx->showCursor(); + _cursor->setCursor(_currentCursor); + _cursor->showCursor(); Common::Event event; while (!shouldQuit()) { @@ -282,9 +301,7 @@ Common::Error MohawkEngine_Myst::run() { _resources[_curResource]->handleMouseUp(); } - for (uint16 i = 0; i < _resources.size(); i++) - if (_resources[i]->isEnabled()) - _resources[i]->drawDataToScreen(); + drawResourceImages(); break; case Common::EVENT_LBUTTONDOWN: if (_curResource >= 0) { @@ -346,14 +363,17 @@ void MohawkEngine_Myst::changeToStack(uint16 stack) { _mhk[0] = new MohawkArchive(); } - _mhk[0]->open(mystFiles[_curStack]); + if (!_mhk[0]->open(mystFiles[_curStack])) + error("Could not open %s", mystFiles[_curStack]); if (getPlatform() == Common::kPlatformMacintosh) _gfx->loadExternalPictureFile(_curStack); _runExitScript = false; + // Clear the resource cache and the image cache _cache.clear(); + _gfx->clearCache(); } void MohawkEngine_Myst::changeToCard(uint16 card) { @@ -371,7 +391,9 @@ void MohawkEngine_Myst::changeToCard(uint16 card) { unloadCard(); + // Clear the resource cache and image cache _cache.clear(); + _gfx->clearCache(); _curCard = card; @@ -433,6 +455,9 @@ void MohawkEngine_Myst::changeToCard(uint16 card) { error("Unknown sound action %d", soundAction); } + // Update the images of each area too + drawResourceImages(); + // TODO: Handle Script Resources // Run the entrance script (if present) @@ -685,43 +710,11 @@ void MohawkEngine_Myst::runInitScript() { debugC(kDebugINIT, "Running INIT script"); Common::SeekableReadStream *initStream = getRawData(ID_INIT, _view.init); - - uint16 scriptCount = initStream->readUint16LE(); - - debugC(kDebugINIT, "\tOpcode Count: %d", scriptCount); - - MystScriptEntry *scripts = new MystScriptEntry[scriptCount]; - - for (uint16 i = 0; i < scriptCount; i++) { - // TODO: u0 is likely variable reference for boolean to - // determine whether or not to execute opcode - uint16 u0 = initStream->readUint16LE(); - scripts[i].opcode = initStream->readUint16LE(); - // If variable indicates not to execute opcode, rewrite to NOP - //if (!_varStore->getVar(u0)) - // scripts[i].opcode = 0xFFFF; - scripts[i].var = initStream->readUint16LE(); - scripts[i].numValues = initStream->readUint16LE(); - scripts[i].values = new uint16[scripts[i].numValues]; - - debugC(kDebugINIT, "\tu0: %d", u0); - debugC(kDebugINIT, "\tOpcode %d: %s", i, _scriptParser->getOpcodeDesc(scripts[i].opcode)); - debugC(kDebugINIT, "\t\tUses Variable %d", scripts[i].var); - debugC(kDebugINIT, "\t\tHas %d Arguments:", scripts[i].numValues); - - for (uint16 j = 0; j < scripts[i].numValues; j++) { - scripts[i].values[j] = initStream->readUint16LE(); - debugC(kDebugINIT, "\t\tArgument %d: %d", j, scripts[i].values[j]); - } - } - + MystScript script = _scriptParser->readScript(initStream, kMystScriptInit); delete initStream; - _scriptParser->runScript(scriptCount, scripts); - - for (uint16 i = 0; i < scriptCount; i++) - delete[] scripts[i].values; - delete[] scripts; + _scriptParser->runScript(script); + _gfx->updateScreen(); } void MohawkEngine_Myst::runExitScript() { @@ -733,48 +726,11 @@ void MohawkEngine_Myst::runExitScript() { debugC(kDebugEXIT, "Running EXIT script"); Common::SeekableReadStream *exitStream = getRawData(ID_EXIT, _view.exit); - - uint16 scriptCount = exitStream->readUint16LE(); - - debugC(kDebugEXIT, "\tOpcode Count: %d", scriptCount); - - MystScriptEntry *scripts = new MystScriptEntry[scriptCount]; - - for (uint16 i = 0; i < scriptCount; i++) { - // TODO: u0 is likely variable reference for boolean to - // to determine whether or not to execute opcode (i.e. door - // close noises only when door is open). - uint16 u0 = exitStream->readUint16LE(); - scripts[i].opcode = exitStream->readUint16LE(); - // If variable indicates not to execute opcode, rewrite to NOP - //if (!_varStore->getVar(u0)) - // scripts[i].opcode = 0xFFFF; - scripts[i].var = exitStream->readUint16LE(); - scripts[i].numValues = exitStream->readUint16LE(); - scripts[i].values = new uint16[scripts[i].numValues]; - - debugC(kDebugEXIT, "\tu0: %d", u0); - debugC(kDebugEXIT, "\tOpcode %d: %s", i, _scriptParser->getOpcodeDesc(scripts[i].opcode)); - debugC(kDebugEXIT, "\t\tUses Variable %d", scripts[i].var); - debugC(kDebugEXIT, "\t\tHas %d Arguments:", scripts[i].numValues); - - for (uint16 j = 0; j < scripts[i].numValues; j++) { - scripts[i].values[j] = exitStream->readUint16LE(); - debugC(kDebugEXIT, "\t\tArgument %d: %d", j, scripts[i].values[j]); - } - - uint16 u1 = exitStream->readUint16LE(); - if (u1 != 1) - warning("Myst EXIT u1 not 1"); - } - + MystScript script = _scriptParser->readScript(exitStream, kMystScriptExit); delete exitStream; - _scriptParser->runScript(scriptCount, scripts); - - for (uint16 i = 0; i < scriptCount; i++) - delete[] scripts[i].values; - delete[] scripts; + _scriptParser->runScript(script); + _gfx->updateScreen(); } void MohawkEngine_Myst::loadHelp(uint16 id) { @@ -868,7 +824,7 @@ void MohawkEngine_Myst::loadCursorHints() { void MohawkEngine_Myst::setMainCursor(uint16 cursor) { _currentCursor = _mainCursor = cursor; - _gfx->changeCursor(_currentCursor); + _cursor->setCursor(_currentCursor); } void MohawkEngine_Myst::checkCursorHints() { @@ -887,7 +843,7 @@ void MohawkEngine_Myst::checkCursorHints() { _currentCursor = _cursorHints[i].variableHint.values[var_value]; if (_currentCursor == 0) _currentCursor = _mainCursor; - _gfx->changeCursor(_currentCursor); + _cursor->setCursor(_currentCursor); } } else if (_currentCursor != _cursorHints[i].cursor) { if (_cursorHints[i].cursor == 0) @@ -895,14 +851,14 @@ void MohawkEngine_Myst::checkCursorHints() { else _currentCursor = _cursorHints[i].cursor; - _gfx->changeCursor(_currentCursor); + _cursor->setCursor(_currentCursor); } return; } if (_currentCursor != _mainCursor) { _currentCursor = _mainCursor; - _gfx->changeCursor(_currentCursor); + _cursor->setCursor(_currentCursor); } } @@ -913,6 +869,15 @@ void MohawkEngine_Myst::setResourceEnabled(uint16 resourceId, bool enable) { warning("Attempt to change unknown resource enable state"); } +void MohawkEngine_Myst::drawResourceImages() { + for (uint16 i = 0; i < _resources.size(); i++) + if (_resources[i]->isEnabled()) + _resources[i]->drawDataToScreen(); + + // Make sure the screen is updated + _gfx->updateScreen(); +} + static MystResource *loadResource(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent) { uint16 type = rlstStream->readUint16LE(); @@ -949,7 +914,11 @@ static MystResource *loadResource(MohawkEngine_Myst *vm, Common::SeekableReadStr } void MohawkEngine_Myst::loadResources() { - _resources.clear(); + while(!_resources.empty()) { + MystResource *temp = _resources.back(); + _resources.pop_back(); + delete temp; + } if (!_view.rlst) { debugC(kDebugResource, "No RLST present"); @@ -1011,6 +980,9 @@ MystResource::MystResource(MohawkEngine_Myst *vm, Common::SeekableReadStream *rl (_flags & kMystSubimageEnableFlag) != 0); } +MystResource::~MystResource() { +} + void MystResource::handleMouseUp() { if (_dest != 0) _vm->changeToCard(_dest); @@ -1021,37 +993,15 @@ void MystResource::handleMouseUp() { MystResourceType5::MystResourceType5(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent) : MystResource(vm, rlstStream, parent) { debugC(kDebugResource, "\tResource Type 5 Script:"); - _scriptCount = rlstStream->readUint16LE(); - - debugC(kDebugResource, "\tOpcode Count: %d", _scriptCount); - - if (_scriptCount == 0) - return; - - _scripts = new MystScriptEntry[_scriptCount]; - for (uint16 i = 0; i < _scriptCount; i++) { - _scripts[i].opcode = rlstStream->readUint16LE(); - _scripts[i].var = rlstStream->readUint16LE(); - _scripts[i].numValues = rlstStream->readUint16LE(); - _scripts[i].values = new uint16[_scripts[i].numValues]; - - debugC(kDebugResource, "\tOpcode %d: %s", i, _vm->_scriptParser->getOpcodeDesc(_scripts[i].opcode)); - debugC(kDebugResource, "\t\tUses Variable %d", _scripts[i].var); - debugC(kDebugResource, "\t\tHas %d Arguments:", _scripts[i].numValues); - - for (uint16 j = 0; j < _scripts[i].numValues; j++) { - _scripts[i].values[j] = rlstStream->readUint16LE(); - debugC(kDebugResource, "\t\tArgument %d: %d", j, _scripts[i].values[j]); - } - } + _script = vm->_scriptParser->readScript(rlstStream, kMystScriptNormal); } void MystResourceType5::handleMouseUp() { - _vm->_scriptParser->runScript(_scriptCount, _scripts, this); + _vm->_scriptParser->runScript(_script, this); } // In Myst/Making of Myst, the paths are hardcoded ala Windows style without extension. Convert them. -Common::String MystResourceType6::convertMystVideoName(Common::String name) { +Common::String MystResourceType6::convertMystVideoName(const Common::String &name) { Common::String temp; for (uint32 i = 1; i < name.size(); i++) { @@ -1133,6 +1083,14 @@ MystResourceType7::MystResourceType7(MohawkEngine_Myst *vm, Common::SeekableRead _subResources.push_back(loadResource(vm, rlstStream, this)); } +MystResourceType7::~MystResourceType7() { + while(!_subResources.empty()) { + MystResource *temp = _subResources.back(); + _subResources.pop_back(); + delete temp; + } +} + // TODO: All these functions to switch subresource are very similar. // Find way to share code (function pointer pass?) void MystResourceType7::drawDataToScreen() { @@ -1273,9 +1231,12 @@ MystResourceType8::MystResourceType8(MohawkEngine_Myst *vm, Common::SeekableRead _subImages[i].rect.right = rlstStream->readSint16LE(); _subImages[i].rect.bottom = rlstStream->readSint16LE(); } else { - _subImages[i].rect.top = 0; - _subImages[i].rect.right = 0; - _subImages[i].rect.bottom = 0; + // Use the hotspot rect as the source rect since the subimage is fullscreen + // Convert to bitmap coordinates (upside down) + _subImages[i].rect.left = _rect.left; + _subImages[i].rect.top = 333 - _rect.bottom; + _subImages[i].rect.right = _rect.right; + _subImages[i].rect.bottom = 333 - _rect.top; } debugC(kDebugResource, "\twdib: %d", _subImages[i].wdib); @@ -1286,6 +1247,10 @@ MystResourceType8::MystResourceType8(MohawkEngine_Myst *vm, Common::SeekableRead } } +MystResourceType8::~MystResourceType8() { + delete[] _subImages; +} + void MystResourceType8::drawDataToScreen() { // Need to call overidden Type 7 function to ensure // switch section is processed correctly. @@ -1336,24 +1301,7 @@ void MystResourceType8::drawDataToScreen() { } else imageToDraw = _subImages[subImageId].wdib; - if (_subImages[subImageId].rect.left == -1) - _vm->_gfx->copyImageSectionToScreen(imageToDraw, _rect, _rect); - //vm->_gfx->copyImageToScreen(imageToDraw, Common::Rect(0, 0, 544, 333)); - // TODO: Think this is the case when the image is full screen.. need to modify graphics to add functions for returning size of image. - // This is not right either... - //else if (_rect.width() != _subImages[draw_subimage_id].rect.width() || _rect.height() != _subImages[draw_subimage_id].rect.height()) - // HACK: Hardcode cases of this until general rule can be ascertained - // These cases seem to have the source rect in the wdib with an vertical i.e. top+X, bottom+X where X is a constant, but could - // be negative, translations, when in fact both the source and dest should be equal... - //else if ((vm->getCurStack() == kSeleniticStack && vm->getCurCard() == 1155 && tmp == 1) || // X= - // (vm->getCurStack() == kSeleniticStack && vm->getCurCard() == 1225 && tmp == 1) || // X= - // (vm->getCurStack() == kMystStack && vm->getCurCard() == 4247 && tmp == 0) || // X= - // (vm->getCurStack() == kChannelwoodStack && vm->getCurCard() == 3161 && tmp == 0)) // X= - // vm->_gfx->copyImageSectionToScreen(imageToDraw, _rect, _rect); - // // TODO: Small vertical movement remains on change. Suspect off by one error from these to real - // // solution. - else - _vm->_gfx->copyImageSectionToScreen(imageToDraw, _subImages[subImageId].rect, _rect); + _vm->_gfx->copyImageSectionToScreen(imageToDraw, _subImages[subImageId].rect, _rect); } } @@ -1396,9 +1344,9 @@ MystResourceType10::MystResourceType10(MohawkEngine_Myst *vm, Common::SeekableRe // TODO: Not sure about order of Mouse Down, Mouse Drag and Mouse Up // Or whether this is slightly different... - printf("Type 10 _mouseDownOpcode: %d\n", _mouseDownOpcode); - printf("Type 10 _mouseDragOpcode: %d\n", _mouseDragOpcode); - printf("Type 10 _mouseUpOpcode: %d\n", _mouseUpOpcode); + debugCN(kDebugResource, "Type 10 _mouseDownOpcode: %d\n", _mouseDownOpcode); + debugCN(kDebugResource, "Type 10 _mouseDragOpcode: %d\n", _mouseDragOpcode); + debugCN(kDebugResource, "Type 10 _mouseUpOpcode: %d\n", _mouseUpOpcode); for (byte i = 0; i < 4; i++) { debugC(kDebugResource, "\tList %d:", i); @@ -1416,6 +1364,11 @@ MystResourceType10::MystResourceType10(MohawkEngine_Myst *vm, Common::SeekableRe warning("TODO: Card contains Type 10 Resource - Function not yet implemented"); } +MystResourceType10::~MystResourceType10() { + for (byte i = 0; i < 4; i++) + delete[] _lists[i].list; +} + void MystResourceType10::handleMouseUp() { // TODO } @@ -1452,9 +1405,9 @@ MystResourceType11::MystResourceType11(MohawkEngine_Myst *vm, Common::SeekableRe // TODO: Not sure about order of Mouse Down, Mouse Drag and Mouse Up // Or whether this is slightly different... - printf("Type 11 _mouseDownOpcode: %d\n", _mouseDownOpcode); - printf("Type 11 _mouseDragOpcode: %d\n", _mouseDragOpcode); - printf("Type 11 _mouseUpOpcode: %d\n", _mouseUpOpcode); + debugCN(kDebugResource, "Type 11 _mouseDownOpcode: %d\n", _mouseDownOpcode); + debugCN(kDebugResource, "Type 11 _mouseDragOpcode: %d\n", _mouseDragOpcode); + debugCN(kDebugResource, "Type 11 _mouseUpOpcode: %d\n", _mouseUpOpcode); for (byte i = 0; i < 3; i++) { debugC(kDebugResource, "\tList %d:", i); @@ -1472,6 +1425,11 @@ MystResourceType11::MystResourceType11(MohawkEngine_Myst *vm, Common::SeekableRe warning("TODO: Card contains Type 11 Resource - Function not yet implemented"); } +MystResourceType11::~MystResourceType11() { + for (byte i = 0; i < 3; i++) + delete[] _lists[i].list; +} + void MystResourceType11::handleMouseUp() { // TODO @@ -1511,14 +1469,14 @@ MystResourceType12::MystResourceType12(MohawkEngine_Myst *vm, Common::SeekableRe // TODO: Think that u0 and u1 are animation frames to be // drawn for var == 0 and var == 1 - printf("Type 12 _state0Frame: %d\n", _state0Frame); - printf("Type 12 _state1Frame: %d\n", _state1Frame); + debugCN(kDebugResource, "Type 12 _state0Frame: %d\n", _state0Frame); + debugCN(kDebugResource, "Type 12 _state1Frame: %d\n", _state1Frame); // TODO: Not sure about order of Mouse Down, Mouse Drag and Mouse Up // Or whether this is slightly different... - printf("Type 12 _mouseDownOpcode: %d\n", _mouseDownOpcode); - printf("Type 12 _mouseDragOpcode: %d\n", _mouseDragOpcode); - printf("Type 12 _mouseUpOpcode: %d\n", _mouseUpOpcode); + debugCN(kDebugResource, "Type 12 _mouseDownOpcode: %d\n", _mouseDownOpcode); + debugCN(kDebugResource, "Type 12 _mouseDragOpcode: %d\n", _mouseDragOpcode); + debugCN(kDebugResource, "Type 12 _mouseUpOpcode: %d\n", _mouseUpOpcode); for (byte i = 0; i < 3; i++) { debugC(kDebugResource, "\tList %d:", i); @@ -1557,10 +1515,16 @@ MystResourceType12::MystResourceType12(MohawkEngine_Myst *vm, Common::SeekableRe _doAnimation = false; } +MystResourceType12::~MystResourceType12() { + for (byte i = 0; i < 3; i++) + delete[] _lists[i].list; +} + void MystResourceType12::handleAnimation() { // TODO: Probably not final version. Variable/Type 11 Controlled? if (_doAnimation) { _vm->_gfx->copyImageToScreen(_currentFrame++, _frameRect); + _vm->_gfx->updateScreen(); if ((_currentFrame - _firstFrame) >= _numFrames) _doAnimation = false; } |