aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk/myst.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mohawk/myst.cpp')
-rw-r--r--engines/mohawk/myst.cpp581
1 files changed, 299 insertions, 282 deletions
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index b6a6c27329..c16fab9131 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -66,38 +66,22 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription
DebugMan.addDebugChannel(kDebugHelp, "Help", "Track Help File (HELP) Parsing");
DebugMan.addDebugChannel(kDebugCache, "Cache", "Track Resource Cache Accesses");
- // Engine tweaks
- // Disabling this makes engine behavior as per
- // original, including bugs, missing bits etc. :)
- _tweaksEnabled = true;
-
_currentCursor = 0;
_mainCursor = kDefaultMystCursor;
_showResourceRects = false;
_curCard = 0;
_needsUpdate = false;
+ _canSafelySaveLoad = false;
_curResource = -1;
- _hoverResource = 0;
- _dragResource = 0;
-
- _gfx = NULL;
- _console = NULL;
- _scriptParser = NULL;
- _gameState = NULL;
- _loadDialog = NULL;
- _optionsDialog = NULL;
-
- _cursorHintCount = 0;
- _cursorHints = NULL;
-
- _prevStack = NULL;
-
- _view.conditionalImageCount = 0;
- _view.conditionalImages = NULL;
- _view.soundList = NULL;
- _view.soundListVolume = NULL;
- _view.scriptResCount = 0;
- _view.scriptResources = NULL;
+ _hoverResource = nullptr;
+
+ _gfx = nullptr;
+ _console = nullptr;
+ _scriptParser = nullptr;
+ _gameState = nullptr;
+ _optionsDialog = nullptr;
+
+ _prevStack = nullptr;
}
MohawkEngine_Myst::~MohawkEngine_Myst() {
@@ -107,20 +91,12 @@ MohawkEngine_Myst::~MohawkEngine_Myst() {
delete _console;
delete _scriptParser;
delete _gameState;
- delete _loadDialog;
delete _optionsDialog;
delete _prevStack;
delete _rnd;
- delete[] _cursorHints;
-
- delete[] _view.conditionalImages;
- delete[] _view.scriptResources;
-
for (uint32 i = 0; i < _resources.size(); i++)
delete _resources[i];
-
- _resources.clear();
}
// Uses cached data objects in preference to disk access
@@ -138,7 +114,11 @@ Common::SeekableReadStream *MohawkEngine_Myst::getResource(uint32 tag, uint16 id
}
error("Could not find a \'%s\' resource with ID %04x", tag2str(tag), id);
- return NULL;
+ return nullptr;
+}
+
+Common::Array<uint16> MohawkEngine_Myst::getResourceIDList(uint32 type) const {
+ return _mhk[0]->getResourceIDList(type);
}
void MohawkEngine_Myst::cachePreload(uint32 tag, uint16 id) {
@@ -242,7 +222,6 @@ Common::Error MohawkEngine_Myst::run() {
_gfx = new MystGraphics(this);
_console = new MystConsole(this);
_gameState = new MystGameState(this, _saveFileMan);
- _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false);
_optionsDialog = new MystOptionsDialog(this);
_cursor = new MystCursorManager(this);
_rnd = new Common::RandomSource("myst");
@@ -251,9 +230,9 @@ Common::Error MohawkEngine_Myst::run() {
_cursor->showCursor();
// Load game from launcher/command line if requested
- if (ConfMan.hasKey("save_slot") && canLoadGameStateCurrently()) {
+ if (ConfMan.hasKey("save_slot") && hasGameSaveSupport()) {
uint32 gameToLoad = ConfMan.getInt("save_slot");
- Common::StringArray savedGamesList = _gameState->generateSaveGameList();
+ Common::StringArray savedGamesList = MystGameState::generateSaveGameList();
if (gameToLoad > savedGamesList.size())
error ("Could not find saved game");
_gameState->load(savedGamesList[gameToLoad]);
@@ -284,7 +263,7 @@ Common::Error MohawkEngine_Myst::run() {
_needsUpdate = _video->updateMovies();
_scriptParser->runPersistentScripts();
- while (_eventMan->pollEvent(event)) {
+ while (pollEvent(event)) {
switch (event.type) {
case Common::EVENT_MOUSEMOVE: {
_needsUpdate = true;
@@ -324,17 +303,15 @@ Common::Error MohawkEngine_Myst::run() {
case Common::KEYCODE_SPACE:
pauseGame();
break;
- case Common::KEYCODE_F4:
- _showResourceRects = !_showResourceRects;
- if (_showResourceRects)
- drawResourceRects();
- break;
case Common::KEYCODE_F5:
_needsPageDrop = false;
_needsShowMap = false;
_needsShowDemoMenu = false;
+ _needsShowCredits = false;
+ _canSafelySaveLoad = true;
runDialog(*_optionsDialog);
+ _canSafelySaveLoad = false;
if (_needsPageDrop) {
dropPage();
@@ -350,6 +327,12 @@ Common::Error MohawkEngine_Myst::run() {
changeToStack(kDemoStack, 2002, 0, 0);
_needsShowDemoMenu = false;
}
+
+ if (_needsShowCredits) {
+ _cursor->hideCursor();
+ changeToStack(kCreditsStack, 10000, 0, 0);
+ _needsShowCredits = false;
+ }
break;
default:
break;
@@ -372,6 +355,15 @@ Common::Error MohawkEngine_Myst::run() {
return Common::kNoError;
}
+bool MohawkEngine_Myst::pollEvent(Common::Event &event) {
+ // Saving / Loading is allowed from the GMM only when the main event loop is running
+ _canSafelySaveLoad = true;
+ bool eventReturned = _eventMan->pollEvent(event);
+ _canSafelySaveLoad = false;
+
+ return eventReturned;
+}
+
bool MohawkEngine_Myst::skippableWait(uint32 duration) {
uint32 end = _system->getMillis() + duration;
bool skipped = false;
@@ -413,6 +405,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
// Fill screen with black and empty cursor
_cursor->setCursor(0);
+ _currentCursor = 0;
if (getFeatures() & GF_ME)
_system->fillScreen(_system->getScreenFormat().RGBToColor(0, 0, 0));
@@ -502,7 +495,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
if (getFeatures() & GF_ME) {
// Play Flyby Entry Movie on Masterpiece Edition.
- const char *flyby = 0;
+ const char *flyby = nullptr;
switch (_curStack) {
case kSeleniticStack:
@@ -512,8 +505,9 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
flyby = "stoneship flyby";
break;
// Myst Flyby Movie not used in Original Masterpiece Edition Engine
+ // We play it when first arriving on Myst, and if the user has chosen so.
case kMystStack:
- if (_tweaksEnabled)
+ if (ConfMan.getBool("playmystflyby") && card == 4134)
flyby = "myst flyby";
break;
case kMechanicalStack:
@@ -539,12 +533,12 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
uint16 MohawkEngine_Myst::getCardBackgroundId() {
uint16 imageToDraw = 0;
- if (_view.conditionalImageCount == 0)
+ if (_view.conditionalImages.size() == 0)
imageToDraw = _view.mainImage;
else {
- for (uint16 i = 0; i < _view.conditionalImageCount; i++) {
+ for (uint16 i = 0; i < _view.conditionalImages.size(); i++) {
uint16 varValue = _scriptParser->getVar(_view.conditionalImages[i].var);
- if (varValue < _view.conditionalImages[i].numStates)
+ if (varValue < _view.conditionalImages[i].values.size())
imageToDraw = _view.conditionalImages[i].values[varValue];
}
}
@@ -586,36 +580,7 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
drawCardBackground();
// Handle sound
- int16 soundAction = 0;
- uint16 soundActionVolume = 0;
-
- if (_view.sound == kMystSoundActionConditional) {
- uint16 soundVarValue = _scriptParser->getVar(_view.soundVar);
- if (soundVarValue >= _view.soundCount)
- warning("Conditional sound variable outside range");
- else {
- soundAction = _view.soundList[soundVarValue];
- soundActionVolume = _view.soundListVolume[soundVarValue];
- }
- } else {
- soundAction = _view.sound;
- soundActionVolume = _view.soundVolume;
- }
-
- if (soundAction == kMystSoundActionContinue)
- debug(2, "Continuing with current sound");
- else if (soundAction == kMystSoundActionChangeVolume) {
- debug(2, "Continuing with current sound, changing volume");
- _sound->changeBackgroundVolumeMyst(soundActionVolume);
- } else if (soundAction == kMystSoundActionStop) {
- debug(2, "Stopping sound");
- _sound->stopBackgroundMyst();
- } else if (soundAction > 0) {
- debug(2, "Playing new sound %d", soundAction);
- _sound->replaceBackgroundMyst(soundAction, soundActionVolume);
- } else {
- error("Unknown sound action %d", soundAction);
- }
+ applySoundBlock(_view.soundBlock);
if (_view.flags & kMystZipDestination)
_gameState->addZipDest(_curStack, card);
@@ -637,15 +602,16 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
// Make sure the screen is updated
if (transition != kNoTransition) {
- if (!_gameState->_globals.transitions)
- transition = kTransitionCopy;
-
- _gfx->runTransition(transition, Common::Rect(544, 333), 10, 0);
+ if (_gameState->_globals.transitions) {
+ _gfx->runTransition(transition, Common::Rect(544, 333), 10, 0);
+ } else {
+ _gfx->copyBackBufferToScreen(Common::Rect(544, 333));
+ _needsUpdate = true;
+ }
}
// Make sure we have the right cursor showing
- _dragResource = 0;
- _hoverResource = 0;
+ _hoverResource = nullptr;
_curResource = -1;
checkCurrentResource();
@@ -671,13 +637,13 @@ void MohawkEngine_Myst::checkCurrentResource() {
// Tell previous resource the mouse is no longer hovering it
if (_hoverResource && !_hoverResource->contains(mouse)) {
_hoverResource->handleMouseLeave();
- _hoverResource = 0;
+ _hoverResource = nullptr;
}
for (uint16 i = 0; i < _resources.size(); i++)
if (_resources[i]->contains(mouse)) {
- if (_hoverResource != _resources[i] && _resources[i]->type == kMystHoverArea) {
- _hoverResource = static_cast<MystResourceType13 *>(_resources[i]);
+ if (_hoverResource != _resources[i] && _resources[i]->type == kMystAreaHover) {
+ _hoverResource = static_cast<MystAreaHover *>(_resources[i]);
_hoverResource->handleMouseEnter();
}
@@ -694,17 +660,17 @@ void MohawkEngine_Myst::checkCurrentResource() {
checkCursorHints();
}
-MystResource *MohawkEngine_Myst::updateCurrentResource() {
+MystArea *MohawkEngine_Myst::updateCurrentResource() {
checkCurrentResource();
if (_curResource >= 0)
return _resources[_curResource];
else
- return 0;
+ return nullptr;
}
void MohawkEngine_Myst::loadCard() {
- debugC(kDebugView, "Loading Card View:");
+ debugC(kDebugView, "Loading Card View: %d", _curCard);
Common::SeekableReadStream *viewStream = getResource(ID_VIEW, _curCard);
@@ -713,21 +679,23 @@ void MohawkEngine_Myst::loadCard() {
debugC(kDebugView, "Flags: 0x%04X", _view.flags);
// The Image Block (Reminiscent of Riven PLST resources)
- _view.conditionalImageCount = viewStream->readUint16LE();
- debugC(kDebugView, "Conditional Image Count: %d", _view.conditionalImageCount);
- if (_view.conditionalImageCount != 0) {
- _view.conditionalImages = new MystCondition[_view.conditionalImageCount];
- for (uint16 i = 0; i < _view.conditionalImageCount; i++) {
+ uint16 conditionalImageCount = viewStream->readUint16LE();
+ debugC(kDebugView, "Conditional Image Count: %d", conditionalImageCount);
+ if (conditionalImageCount != 0) {
+ for (uint16 i = 0; i < conditionalImageCount; i++) {
+ MystCondition conditionalImage;
+
debugC(kDebugView, "\tImage %d:", i);
- _view.conditionalImages[i].var = viewStream->readUint16LE();
- debugC(kDebugView, "\t\tVar: %d", _view.conditionalImages[i].var);
- _view.conditionalImages[i].numStates = viewStream->readUint16LE();
- debugC(kDebugView, "\t\tNumber of States: %d", _view.conditionalImages[i].numStates);
- _view.conditionalImages[i].values = new uint16[_view.conditionalImages[i].numStates];
- for (uint16 j = 0; j < _view.conditionalImages[i].numStates; j++) {
- _view.conditionalImages[i].values[j] = viewStream->readUint16LE();
- debugC(kDebugView, "\t\tState %d -> Value %d", j, _view.conditionalImages[i].values[j]);
+ conditionalImage.var = viewStream->readUint16LE();
+ debugC(kDebugView, "\t\tVar: %d", conditionalImage.var);
+ uint16 numStates = viewStream->readUint16LE();
+ debugC(kDebugView, "\t\tNumber of States: %d", numStates);
+ for (uint16 j = 0; j < numStates; j++) {
+ conditionalImage.values.push_back(viewStream->readUint16LE());
+ debugC(kDebugView, "\t\tState %d -> Value %d", j, conditionalImage.values[j]);
}
+
+ _view.conditionalImages.push_back(conditionalImage);
}
_view.mainImage = 0;
} else {
@@ -736,87 +704,58 @@ void MohawkEngine_Myst::loadCard() {
}
// The Sound Block (Reminiscent of Riven SLST resources)
- _view.sound = viewStream->readSint16LE();
- debugCN(kDebugView, "Sound Control: %d = ", _view.sound);
- if (_view.sound > 0) {
- debugC(kDebugView, "Play new Sound, change volume");
- debugC(kDebugView, "\tSound: %d", _view.sound);
- _view.soundVolume = viewStream->readUint16LE();
- debugC(kDebugView, "\tVolume: %d", _view.soundVolume);
- } else if (_view.sound == kMystSoundActionContinue)
- debugC(kDebugView, "Continue current sound");
- else if (_view.sound == kMystSoundActionChangeVolume) {
- debugC(kDebugView, "Continue current sound, change volume");
- _view.soundVolume = viewStream->readUint16LE();
- debugC(kDebugView, "\tVolume: %d", _view.soundVolume);
- } else if (_view.sound == kMystSoundActionStop) {
- debugC(kDebugView, "Stop sound");
- } else if (_view.sound == kMystSoundActionConditional) {
- debugC(kDebugView, "Conditional sound list");
- _view.soundVar = viewStream->readUint16LE();
- debugC(kDebugView, "\tVar: %d", _view.soundVar);
- _view.soundCount = viewStream->readUint16LE();
- debugC(kDebugView, "\tCount: %d", _view.soundCount);
- _view.soundList = new int16[_view.soundCount];
- _view.soundListVolume = new uint16[_view.soundCount];
-
- for (uint16 i = 0; i < _view.soundCount; i++) {
- _view.soundList[i] = viewStream->readSint16LE();
- debugC(kDebugView, "\t\tCondition %d: Action %d", i, _view.soundList[i]);
- if (_view.soundList[i] == kMystSoundActionChangeVolume || _view.soundList[i] >= 0) {
- _view.soundListVolume[i] = viewStream->readUint16LE();
- debugC(kDebugView, "\t\tCondition %d: Volume %d", i, _view.soundListVolume[i]);
- }
- }
- } else {
- debugC(kDebugView, "Unknown");
- warning("Unknown sound control value in card");
- }
+ _view.soundBlock = readSoundBlock(viewStream);
// Resources that scripts can call upon
- _view.scriptResCount = viewStream->readUint16LE();
- debugC(kDebugView, "Script Resource Count: %d", _view.scriptResCount);
- if (_view.scriptResCount != 0) {
- _view.scriptResources = new MystView::ScriptResource[_view.scriptResCount];
- for (uint16 i = 0; i < _view.scriptResCount; i++) {
- debugC(kDebugView, "\tResource %d:", i);
- _view.scriptResources[i].type = viewStream->readUint16LE();
- debugC(kDebugView, "\t\t Type: %d", _view.scriptResources[i].type);
-
- switch (_view.scriptResources[i].type) {
- case 1:
- debugC(kDebugView, "\t\t\t\t= Image");
- break;
- case 2:
- debugC(kDebugView, "\t\t\t\t= Sound");
- break;
- case 3:
- debugC(kDebugView, "\t\t\t\t= Resource List");
- break;
- default:
- debugC(kDebugView, "\t\t\t\t= Unknown");
- break;
- }
+ uint16 scriptResCount = viewStream->readUint16LE();
+ debugC(kDebugView, "Script Resource Count: %d", scriptResCount);
+ for (uint16 i = 0; i < scriptResCount; i++) {
+ MystView::ScriptResource scriptResource;
+
+ debugC(kDebugView, "\tResource %d:", i);
+ scriptResource.type = (MystView::ScriptResourceType) viewStream->readUint16LE();
+ debugC(kDebugView, "\t\t Type: %d", scriptResource.type);
+
+ switch (scriptResource.type) {
+ case MystView::kResourceImage:
+ debugC(kDebugView, "\t\t\t\t= Image");
+ break;
+ case MystView::kResourceSound:
+ debugC(kDebugView, "\t\t\t\t= Sound");
+ break;
+ case MystView::kResourceSwitch:
+ debugC(kDebugView, "\t\t\t\t= Resource Switch");
+ break;
+ case MystView::kResourceImageNoCache:
+ debugC(kDebugView, "\t\t\t\t= Image - Caching disabled");
+ break;
+ case MystView::kResourceSoundNoCache:
+ debugC(kDebugView, "\t\t\t\t= Sound - Caching disabled");
+ break;
+ default:
+ debugC(kDebugView, "\t\t\t\t= Unknown");
+ warning("Unknown script resource type '%d' in card '%d'", scriptResource.type, _curCard);
+ break;
+ }
- if (_view.scriptResources[i].type == 3) {
- _view.scriptResources[i].var = viewStream->readUint16LE();
- debugC(kDebugView, "\t\t Var: %d", _view.scriptResources[i].var);
- _view.scriptResources[i].count = viewStream->readUint16LE();
- debugC(kDebugView, "\t\t Resource List Count: %d", _view.scriptResources[i].count);
- _view.scriptResources[i].u0 = viewStream->readUint16LE();
- debugC(kDebugView, "\t\t u0: %d", _view.scriptResources[i].u0);
- _view.scriptResources[i].resource_list = new int16[_view.scriptResources[i].count];
-
- for (uint16 j = 0; j < _view.scriptResources[i].count; j++) {
- _view.scriptResources[i].resource_list[j] = viewStream->readSint16LE();
- debugC(kDebugView, "\t\t Resource List %d: %d", j, _view.scriptResources[i].resource_list[j]);
- }
- } else {
- _view.scriptResources[i].resource_list = NULL;
- _view.scriptResources[i].id = viewStream->readUint16LE();
- debugC(kDebugView, "\t\t Id: %d", _view.scriptResources[i].id);
+ if (scriptResource.type == MystView::kResourceSwitch) {
+ scriptResource.switchVar = viewStream->readUint16LE();
+ debugC(kDebugView, "\t\t Var: %d", scriptResource.switchVar);
+ uint16 count = viewStream->readUint16LE();
+ debugC(kDebugView, "\t\t Resource List Count: %d", count);
+ scriptResource.switchResourceType = (MystView::ScriptResourceType) viewStream->readUint16LE();
+ debugC(kDebugView, "\t\t u0: %d", scriptResource.switchResourceType);
+
+ for (uint16 j = 0; j < count; j++) {
+ scriptResource.switchResourceIds.push_back(viewStream->readSint16LE());
+ debugC(kDebugView, "\t\t Resource List %d: %d", j, scriptResource.switchResourceIds[j]);
}
+ } else {
+ scriptResource.id = viewStream->readUint16LE();
+ debugC(kDebugView, "\t\t Id: %d", scriptResource.id);
}
+
+ _view.scriptResources.push_back(scriptResource);
}
// Identifiers for other resources. 0 if non existent. There is always an RLST.
@@ -831,7 +770,6 @@ void MohawkEngine_Myst::loadCard() {
delete viewStream;
// Precache Card Resources
- // TODO: Deal with Mac ME External Picture File
uint32 cacheImageType;
if (getFeatures() & GF_ME)
cacheImageType = ID_PICT;
@@ -839,63 +777,58 @@ void MohawkEngine_Myst::loadCard() {
cacheImageType = ID_WDIB;
// Precache Image Block data
- if (_view.conditionalImageCount != 0) {
- for (uint16 i = 0; i < _view.conditionalImageCount; i++)
- for (uint16 j = 0; j < _view.conditionalImages[i].numStates; j++)
- cachePreload(cacheImageType, _view.conditionalImages[i].values[j]);
- } else
+ if (_view.conditionalImages.size() != 0) {
+ for (uint16 i = 0; i < _view.conditionalImages.size(); i++) {
+ uint16 value = _scriptParser->getVar(_view.conditionalImages[i].var);
+ cachePreload(cacheImageType, _view.conditionalImages[i].values[value]);
+ }
+ } else {
cachePreload(cacheImageType, _view.mainImage);
+ }
// Precache Sound Block data
- if (_view.sound > 0)
- cachePreload(ID_MSND, _view.sound);
- else if (_view.sound == kMystSoundActionConditional) {
- for (uint16 i = 0; i < _view.soundCount; i++) {
- if (_view.soundList[i] > 0)
- cachePreload(ID_MSND, _view.soundList[i]);
+ if (_view.soundBlock.sound > 0)
+ cachePreload(ID_MSND, _view.soundBlock.sound);
+ else if (_view.soundBlock.sound == kMystSoundActionConditional) {
+ uint16 value = _scriptParser->getVar(_view.soundBlock.soundVar);
+ if (_view.soundBlock.soundList[value].action > 0) {
+ cachePreload(ID_MSND, _view.soundBlock.soundList[value].action);
}
}
// Precache Script Resources
- if (_view.scriptResCount != 0) {
- for (uint16 i = 0; i < _view.scriptResCount; i++) {
- switch (_view.scriptResources[i].type) {
- case 1:
- cachePreload(cacheImageType, _view.scriptResources[i].id);
- break;
- case 2:
- cachePreload(ID_MSND, _view.scriptResources[i].id);
- break;
- case 3:
- warning("TODO: Precaching of Script Resource List not supported");
- break;
- default:
- warning("Unknown Resource in Script Resource List Precaching");
- break;
- }
+ for (uint16 i = 0; i < _view.scriptResources.size(); i++) {
+ MystView::ScriptResourceType type;
+ int16 id;
+ if (_view.scriptResources[i].type == MystView::kResourceSwitch) {
+ type = _view.scriptResources[i].switchResourceType;
+ uint16 value = _scriptParser->getVar(_view.scriptResources[i].switchVar);
+ id = _view.scriptResources[i].switchResourceIds[value];
+ } else {
+ type = _view.scriptResources[i].type;
+ id = _view.scriptResources[i].id;
+ }
+
+ if (id < 0) continue;
+
+ switch (type) {
+ case MystView::kResourceImage:
+ cachePreload(cacheImageType, id);
+ break;
+ case MystView::kResourceSound:
+ cachePreload(ID_MSND, id);
+ break;
+ default:
+ // The other resource types should not be cached
+ break;
}
}
}
void MohawkEngine_Myst::unloadCard() {
- for (uint16 i = 0; i < _view.conditionalImageCount; i++)
- delete[] _view.conditionalImages[i].values;
-
- delete[] _view.conditionalImages;
- _view.conditionalImageCount = 0;
- _view.conditionalImages = NULL;
-
- delete[] _view.soundList;
- _view.soundList = NULL;
- delete[] _view.soundListVolume;
- _view.soundListVolume = NULL;
-
- for (uint16 i = 0; i < _view.scriptResCount; i++)
- delete[] _view.scriptResources[i].resource_list;
-
- delete[] _view.scriptResources;
- _view.scriptResources = NULL;
- _view.scriptResCount = 0;
+ _view.conditionalImages.clear();
+ _view.soundBlock.soundList.clear();
+ _view.scriptResources.clear();
}
void MohawkEngine_Myst::runInitScript() {
@@ -968,14 +901,12 @@ void MohawkEngine_Myst::loadHelp(uint16 id) {
debugC(kDebugHelp, "\thelpText: \"%s\"", helpText.c_str());
delete[] u0;
+
+ delete helpStream;
}
void MohawkEngine_Myst::loadCursorHints() {
- for (uint16 i = 0; i < _cursorHintCount; i++)
- delete[] _cursorHints[i].variableHint.values;
- _cursorHintCount = 0;
- delete[] _cursorHints;
- _cursorHints = NULL;
+ _cursorHints.clear();
if (!_view.hint) {
debugC(kDebugHint, "No HINT Present");
@@ -985,33 +916,33 @@ void MohawkEngine_Myst::loadCursorHints() {
debugC(kDebugHint, "Loading Cursor Hints:");
Common::SeekableReadStream *hintStream = getResource(ID_HINT, _curCard);
- _cursorHintCount = hintStream->readUint16LE();
- debugC(kDebugHint, "Cursor Hint Count: %d", _cursorHintCount);
- _cursorHints = new MystCursorHint[_cursorHintCount];
+ uint16 cursorHintCount = hintStream->readUint16LE();
+ debugC(kDebugHint, "Cursor Hint Count: %d", cursorHintCount);
+
+ for (uint16 i = 0; i < cursorHintCount; i++) {
+ MystCursorHint hint;
- for (uint16 i = 0; i < _cursorHintCount; i++) {
debugC(kDebugHint, "Cursor Hint %d:", i);
- _cursorHints[i].id = hintStream->readUint16LE();
- debugC(kDebugHint, "\tId: %d", _cursorHints[i].id);
- _cursorHints[i].cursor = hintStream->readSint16LE();
- debugC(kDebugHint, "\tCursor: %d", _cursorHints[i].cursor);
+ hint.id = hintStream->readUint16LE();
+ debugC(kDebugHint, "\tId: %d", hint.id);
+ hint.cursor = hintStream->readSint16LE();
+ debugC(kDebugHint, "\tCursor: %d", hint.cursor);
- if (_cursorHints[i].cursor == -1) {
+ if (hint.cursor == -1) {
debugC(kDebugHint, "\tConditional Cursor Hints:");
- _cursorHints[i].variableHint.var = hintStream->readUint16LE();
- debugC(kDebugHint, "\tVar: %d", _cursorHints[i].variableHint.var);
- _cursorHints[i].variableHint.numStates = hintStream->readUint16LE();
- debugC(kDebugHint, "\tNumber of States: %d", _cursorHints[i].variableHint.numStates);
- _cursorHints[i].variableHint.values = new uint16[_cursorHints[i].variableHint.numStates];
- for (uint16 j = 0; j < _cursorHints[i].variableHint.numStates; j++) {
- _cursorHints[i].variableHint.values[j] = hintStream->readUint16LE();
- debugC(kDebugHint, "\t\t State %d: Cursor %d", j, _cursorHints[i].variableHint.values[j]);
+ hint.variableHint.var = hintStream->readUint16LE();
+ debugC(kDebugHint, "\tVar: %d", hint.variableHint.var);
+ uint16 numStates = hintStream->readUint16LE();
+ debugC(kDebugHint, "\tNumber of States: %d", numStates);
+ for (uint16 j = 0; j < numStates; j++) {
+ hint.variableHint.values.push_back(hintStream->readUint16LE());
+ debugC(kDebugHint, "\t\t State %d: Cursor %d", j, hint.variableHint.values[j]);
}
} else {
- _cursorHints[i].variableHint.var = 0;
- _cursorHints[i].variableHint.numStates = 0;
- _cursorHints[i].variableHint.values = NULL;
+ hint.variableHint.var = 0;
}
+
+ _cursorHints.push_back(hint);
}
delete hintStream;
@@ -1033,12 +964,12 @@ void MohawkEngine_Myst::checkCursorHints() {
}
// Check all the cursor hints to see if we're in a hotspot that contains a hint.
- for (uint16 i = 0; i < _cursorHintCount; i++)
+ for (uint16 i = 0; i < _cursorHints.size(); i++)
if (_cursorHints[i].id == _curResource && _resources[_cursorHints[i].id]->isEnabled()) {
if (_cursorHints[i].cursor == -1) {
uint16 var_value = _scriptParser->getVar(_cursorHints[i].variableHint.var);
- if (var_value >= _cursorHints[i].variableHint.numStates)
+ if (var_value >= _cursorHints[i].variableHint.values.size())
warning("Variable %d Out of Range in variable HINT Resource %d", _cursorHints[i].variableHint.var, i);
else {
_currentCursor = _cursorHints[i].variableHint.values[var_value];
@@ -1076,50 +1007,50 @@ void MohawkEngine_Myst::drawResourceImages() {
_resources[i]->drawDataToScreen();
}
-void MohawkEngine_Myst::redrawResource(MystResourceType8 *resource, bool update) {
- resource->drawConditionalDataToScreen(_scriptParser->getVar(resource->getType8Var()), update);
+void MohawkEngine_Myst::redrawResource(MystAreaImageSwitch *resource, bool update) {
+ resource->drawConditionalDataToScreen(_scriptParser->getVar(resource->getImageSwitchVar()), update);
}
void MohawkEngine_Myst::redrawArea(uint16 var, bool update) {
for (uint16 i = 0; i < _resources.size(); i++)
- if (_resources[i]->type == kMystConditionalImage && _resources[i]->getType8Var() == var)
- redrawResource(static_cast<MystResourceType8 *>(_resources[i]), update);
+ if (_resources[i]->type == kMystAreaImageSwitch && _resources[i]->getImageSwitchVar() == var)
+ redrawResource(static_cast<MystAreaImageSwitch *>(_resources[i]), update);
}
-MystResource *MohawkEngine_Myst::loadResource(Common::SeekableReadStream *rlstStream, MystResource *parent) {
- MystResource *resource = 0;
+MystArea *MohawkEngine_Myst::loadResource(Common::SeekableReadStream *rlstStream, MystArea *parent) {
+ MystArea *resource = nullptr;
ResourceType type = static_cast<ResourceType>(rlstStream->readUint16LE());
debugC(kDebugResource, "\tType: %d", type);
- debugC(kDebugResource, "\tSub_Record: %d", (parent == NULL) ? 0 : 1);
+ debugC(kDebugResource, "\tSub_Record: %d", (parent == nullptr) ? 0 : 1);
switch (type) {
- case kMystAction:
- resource = new MystResourceType5(this, rlstStream, parent);
+ case kMystAreaAction:
+ resource = new MystAreaAction(this, rlstStream, parent);
break;
- case kMystVideo:
- resource = new MystResourceType6(this, rlstStream, parent);
+ case kMystAreaVideo:
+ resource = new MystAreaVideo(this, rlstStream, parent);
break;
- case kMystSwitch:
- resource = new MystResourceType7(this, rlstStream, parent);
+ case kMystAreaActionSwitch:
+ resource = new MystAreaActionSwitch(this, rlstStream, parent);
break;
- case kMystConditionalImage:
- resource = new MystResourceType8(this, rlstStream, parent);
+ case kMystAreaImageSwitch:
+ resource = new MystAreaImageSwitch(this, rlstStream, parent);
break;
- case kMystSlider:
- resource = new MystResourceType10(this, rlstStream, parent);
+ case kMystAreaSlider:
+ resource = new MystAreaSlider(this, rlstStream, parent);
break;
- case kMystDragArea:
- resource = new MystResourceType11(this, rlstStream, parent);
+ case kMystAreaDrag:
+ resource = new MystAreaDrag(this, rlstStream, parent);
break;
case kMystVideoInfo:
- resource = new MystResourceType12(this, rlstStream, parent);
+ resource = new MystVideoInfo(this, rlstStream, parent);
break;
- case kMystHoverArea:
- resource = new MystResourceType13(this, rlstStream, parent);
+ case kMystAreaHover:
+ resource = new MystAreaHover(this, rlstStream, parent);
break;
default:
- resource = new MystResource(this, rlstStream, parent);
+ resource = new MystArea(this, rlstStream, parent);
break;
}
@@ -1145,34 +1076,42 @@ void MohawkEngine_Myst::loadResources() {
for (uint16 i = 0; i < resourceCount; i++) {
debugC(kDebugResource, "Resource #%d:", i);
- _resources.push_back(loadResource(rlstStream, NULL));
+ _resources.push_back(loadResource(rlstStream, nullptr));
}
delete rlstStream;
}
Common::Error MohawkEngine_Myst::loadGameState(int slot) {
- if (_gameState->load(_gameState->generateSaveGameList()[slot]))
+ if (_gameState->load(MystGameState::generateSaveGameList()[slot]))
return Common::kNoError;
return Common::kUnknownError;
}
Common::Error MohawkEngine_Myst::saveGameState(int slot, const Common::String &desc) {
- Common::StringArray saveList = _gameState->generateSaveGameList();
+ Common::StringArray saveList = MystGameState::generateSaveGameList();
if ((uint)slot < saveList.size())
- _gameState->deleteSave(saveList[slot]);
+ MystGameState::deleteSave(saveList[slot]);
+
+ return _gameState->save(desc) ? Common::kNoError : Common::kUnknownError;
+}
- return _gameState->save(Common::String(desc)) ? Common::kNoError : Common::kUnknownError;
+bool MohawkEngine_Myst::hasGameSaveSupport() const {
+ return !(getFeatures() & GF_DEMO) && getGameType() != GType_MAKINGOF;
}
bool MohawkEngine_Myst::canLoadGameStateCurrently() {
// No loading in the demo/makingof
- return !(getFeatures() & GF_DEMO) && getGameType() != GType_MAKINGOF;
+ return _canSafelySaveLoad && hasGameSaveSupport();
}
bool MohawkEngine_Myst::canSaveGameStateCurrently() {
+ if (!_canSafelySaveLoad) {
+ return false;
+ }
+
// There's a limited number of stacks the game can save in
switch (_curStack) {
case kChannelwoodStack:
@@ -1225,4 +1164,82 @@ void MohawkEngine_Myst::dropPage() {
checkCursorHints();
}
+MystSoundBlock MohawkEngine_Myst::readSoundBlock(Common::ReadStream *stream) const {
+ MystSoundBlock soundBlock;
+ soundBlock.sound = stream->readSint16LE();
+ debugCN(kDebugView, "Sound Control: %d = ", soundBlock.sound);
+
+ if (soundBlock.sound > 0) {
+ debugC(kDebugView, "Play new Sound, change volume");
+ debugC(kDebugView, "\tSound: %d", soundBlock.sound);
+ soundBlock.soundVolume = stream->readUint16LE();
+ debugC(kDebugView, "\tVolume: %d", soundBlock.soundVolume);
+ } else if (soundBlock.sound == kMystSoundActionContinue)
+ debugC(kDebugView, "Continue current sound");
+ else if (soundBlock.sound == kMystSoundActionChangeVolume) {
+ debugC(kDebugView, "Continue current sound, change volume");
+ soundBlock.soundVolume = stream->readUint16LE();
+ debugC(kDebugView, "\tVolume: %d", soundBlock.soundVolume);
+ } else if (soundBlock.sound == kMystSoundActionStop) {
+ debugC(kDebugView, "Stop sound");
+ } else if (soundBlock.sound == kMystSoundActionConditional) {
+ debugC(kDebugView, "Conditional sound list");
+ soundBlock.soundVar = stream->readUint16LE();
+ debugC(kDebugView, "\tVar: %d", soundBlock.soundVar);
+ uint16 soundCount = stream->readUint16LE();
+ debugC(kDebugView, "\tCount: %d", soundCount);
+
+ for (uint16 i = 0; i < soundCount; i++) {
+ MystSoundBlock::SoundItem sound;
+
+ sound.action = stream->readSint16LE();
+ debugC(kDebugView, "\t\tCondition %d: Action %d", i, sound.action);
+ if (sound.action == kMystSoundActionChangeVolume || sound.action >= 0) {
+ sound.volume = stream->readUint16LE();
+ debugC(kDebugView, "\t\tCondition %d: Volume %d", i, sound.volume);
+ }
+
+ soundBlock.soundList.push_back(sound);
+ }
+ } else {
+ debugC(kDebugView, "Unknown");
+ warning("Unknown sound control value '%d' in card '%d'", soundBlock.sound, _curCard);
+ }
+
+ return soundBlock;
+}
+
+void MohawkEngine_Myst::applySoundBlock(const MystSoundBlock &block) {
+ int16 soundAction = 0;
+ uint16 soundActionVolume = 0;
+
+ if (block.sound == kMystSoundActionConditional) {
+ uint16 soundVarValue = _scriptParser->getVar(block.soundVar);
+ if (soundVarValue >= block.soundList.size())
+ warning("Conditional sound variable outside range");
+ else {
+ soundAction = block.soundList[soundVarValue].action;
+ soundActionVolume = block.soundList[soundVarValue].volume;
+ }
+ } else {
+ soundAction = block.sound;
+ soundActionVolume = block.soundVolume;
+ }
+
+ if (soundAction == kMystSoundActionContinue)
+ debug(2, "Continuing with current sound");
+ else if (soundAction == kMystSoundActionChangeVolume) {
+ debug(2, "Continuing with current sound, changing volume");
+ _sound->changeBackgroundVolumeMyst(soundActionVolume);
+ } else if (soundAction == kMystSoundActionStop) {
+ debug(2, "Stopping sound");
+ _sound->stopBackgroundMyst();
+ } else if (soundAction > 0) {
+ debug(2, "Playing new sound %d", soundAction);
+ _sound->replaceBackgroundMyst(soundAction, soundActionVolume);
+ } else {
+ error("Unknown sound action %d", soundAction);
+ }
+}
+
} // End of namespace Mohawk