void SaveLoad_ns::renameOldSavefiles() { Common::StringArray oldFilenames = _saveFileMan->listSavefiles("game.*"); uint numOldSaves = oldFilenames.size(); bool rename = false; uint success = 0, id; Common::String oldName, newName; for (uint i = 0; i < oldFilenames.size(); ++i) { oldName = oldFilenames[i]; int e = sscanf(oldName.c_str(), "game.%u", &id); if (e != 1) { // this wasn't a savefile, so adjust numOldSaves accordingly --numOldSaves; continue; } if (!rename) { rename = askRenameOldSavefiles(); } if (!rename) { // return immediately if the user doesn't want to rename the files return; } newName = genSaveFileName(id); if (_saveFileMan->renameSavefile(oldName, newName)) { success++; } else { warning("Error %i (%s) occurred while renaming %s to %s", _saveFileMan->getError().getCode(), _saveFileMan->getErrorDesc().c_str(), oldName.c_str(), newName.c_str()); } } if (numOldSaves == 0) { // there were no old savefiles: nothing to notify return; } char msg[200]; if (success == numOldSaves) { sprintf(msg, "ScummVM successfully converted all your savefiles."); } else { sprintf(msg, "ScummVM printed some warnings in your console window and can't guarantee all your files have been converted.\n\n" "Please report to the team."); } GUI::MessageDialog dialog1(msg); dialog1.runModal(); }
Common::StringArray Kernel::checkStaticSelectorNames() { Common::StringArray names; const int offset = (getSciVersion() < SCI_VERSION_1_1) ? 3 : 0; #ifdef ENABLE_SCI32 const int count = (getSciVersion() <= SCI_VERSION_1_1) ? ARRAYSIZE(sci0Selectors) + offset : ARRAYSIZE(sci2Selectors); #else const int count = ARRAYSIZE(sci0Selectors) + offset; #endif int countSci1 = ARRAYSIZE(sci1Selectors); int countSci11 = ARRAYSIZE(sci11Selectors); // Resize the list of selector names and fill in the SCI 0 names. names.resize(count); if (getSciVersion() <= SCI_VERSION_1_LATE) { // Fill selectors 0 - 2 for SCI0 - SCI1 late names[0] = "species"; names[1] = "superClass"; names[2] = "-info-"; } if (getSciVersion() <= SCI_VERSION_1_1) { // SCI0 - SCI11 for (int i = offset; i < count; i++) names[i] = sci0Selectors[i - offset]; if (getSciVersion() > SCI_VERSION_01) { // Several new selectors were added in SCI 1 and later. names.resize(count + countSci1); for (int i = count; i < count + countSci1; i++) names[i] = sci1Selectors[i - count]; } if (getSciVersion() >= SCI_VERSION_1_1) { // Several new selectors were added in SCI 1.1 names.resize(count + countSci1 + countSci11); for (int i = count + countSci1; i < count + countSci1 + countSci11; i++) names[i] = sci11Selectors[i - count - countSci1]; } #ifdef ENABLE_SCI32 } else { // SCI2+ for (int i = 0; i < count; i++) names[i] = sci2Selectors[i]; #endif } findSpecificSelectors(names); for (const SelectorRemap *selectorRemap = sciSelectorRemap; selectorRemap->slot; ++selectorRemap) { if (getSciVersion() >= selectorRemap->minVersion && getSciVersion() <= selectorRemap->maxVersion) { const uint32 slot = selectorRemap->slot; if (slot >= names.size()) names.resize(slot + 1); names[slot] = selectorRemap->name; } } return names; }
Common::Error MohawkEngine_Riven::saveGameState(int slot, const Common::String &desc) { Common::StringArray saveList = _saveLoad->generateSaveGameList(); if ((uint)slot < saveList.size()) _saveLoad->deleteSave(saveList[slot]); return _saveLoad->saveGame(desc); }
Common::Error MohawkEngine_Riven::saveGameState(int slot, const char *desc) { Common::StringArray saveList = _saveLoad->generateSaveGameList(); if ((uint)slot < saveList.size()) _saveLoad->deleteSave(saveList[slot]); return _saveLoad->saveGame(Common::String(desc)) ? Common::kNoError : Common::kUnknownError; }
Common::HashMap<Common::String, uint32> DefaultSaveFileManager::loadTimestamps() { Common::HashMap<Common::String, uint32> timestamps; //refresh the files list Common::Array<Common::String> files; g_system->getSavefileManager()->updateSavefilesList(files); //start with listing all the files in saves/ directory and setting invalid timestamp to them Common::StringArray localFiles = g_system->getSavefileManager()->listSavefiles("*"); for (uint32 i = 0; i < localFiles.size(); ++i) timestamps[localFiles[i]] = INVALID_TIMESTAMP; //now actually load timestamps from file Common::InSaveFile *file = g_system->getSavefileManager()->openRawFile(TIMESTAMPS_FILENAME); if (!file) { warning("DefaultSaveFileManager: failed to open '%s' file to load timestamps", TIMESTAMPS_FILENAME); return timestamps; } while (!file->eos()) { //read filename into buffer (reading until the first ' ') Common::String buffer; while (!file->eos()) { byte b = file->readByte(); if (b == ' ') break; buffer += (char)b; } //read timestamp info buffer (reading until ' ' or some line ending char) Common::String filename = buffer; while (true) { bool lineEnded = false; buffer = ""; while (!file->eos()) { byte b = file->readByte(); if (b == ' ' || b == '\n' || b == '\r') { lineEnded = (b == '\n'); break; } buffer += (char)b; } if (buffer == "" && file->eos()) break; if (!lineEnded) filename += " " + buffer; else break; } //parse timestamp uint32 timestamp = buffer.asUint64(); if (buffer == "" || timestamp == 0) break; if (timestamps.contains(filename)) timestamps[filename] = timestamp; } delete file; return timestamps; }
SaveStateList MohawkMetaEngine::listSaves(const char *target) const { Common::StringArray filenames; SaveStateList saveList; // Loading games is only supported in Myst/Riven currently. if (strstr(target, "myst")) { filenames = g_system->getSavefileManager()->listSavefiles("*.mys"); for (uint32 i = 0; i < filenames.size(); i++) saveList.push_back(SaveStateDescriptor(i, filenames[i])); } else if (strstr(target, "riven")) { filenames = g_system->getSavefileManager()->listSavefiles("*.rvn"); for (uint32 i = 0; i < filenames.size(); i++) saveList.push_back(SaveStateDescriptor(i, filenames[i])); } return saveList; }
TestExitStatus SaveGametests::testListingSavefile() { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); saveFileMan->clearError(); // create some savefiles const char *savefileName[] = {"tBedSavefileToList.0", "tBedSavefileToList.1", "tBedSavefileToList.2"}; writeDataToFile("tBedSavefileToList.0", "Save me!"); writeDataToFile("tBedSavefileToList.1", "Save me!"); writeDataToFile("tBedSavefileToList.2", "Save me!"); Common::Error error = saveFileMan->getError(); if (error != Common::kNoError) { // Abort. Some Error in writing files Testsuite::logDetailedPrintf("Error while creating savefiles: %s\n", Common::errorToString(error)); return kTestFailed; } Common::StringArray savefileList = saveFileMan->listSavefiles("tBedSavefileToList.?"); if (savefileList.size() == ARRAYSIZE(savefileName)) { // Match them exactly // As the order of savefileList may be platform specific, match them exhaustively for (uint i = 0; i < ARRAYSIZE(savefileName); i++) { for (uint j = 0; j < savefileList.size(); j++) { if (savefileList[j].equals(savefileName[i])) { break; } if (savefileList.size() == j) { // A match for this name not found Testsuite::logDetailedPrintf("Listed Names don't match\n"); return kTestFailed; } } } return kTestPassed; } else { Testsuite::logDetailedPrintf("listing Savefiles failed!\n"); return kTestFailed; } return kTestFailed; }
Common::Error MohawkEngine_Riven::run() { MohawkEngine::run(); // Let's try to open the installer file (it holds extras.mhk) // Though, we set a low priority to prefer the extracted version if (_installerArchive.open("arcriven.z")) SearchMan.add("arcriven.z", &_installerArchive, 0, false); _gfx = new RivenGraphics(this); _console = new RivenConsole(this); _saveLoad = new RivenSaveLoad(this, _saveFileMan); _externalScriptHandler = new RivenExternal(this); _optionsDialog = new RivenOptionsDialog(this); _scriptMan = new RivenScriptManager(this); _cursor = new RivenCursorManager(); _rnd = new Common::RandomSource(); g_eventRec.registerRandomSource(*_rnd, "riven"); initVars(); // Open extras.mhk for common images _extrasFile = new MohawkArchive(); if (!_extrasFile->open("extras.mhk")) error("Could not open extras.mhk"); // Start at main cursor _cursor->setCursor(kRivenMainCursor); // Let's begin, shall we? if (getFeatures() & GF_DEMO) { // Start the demo off with the videos changeToStack(aspit); changeToCard(6); } else if (ConfMan.hasKey("save_slot")) { // Load game from launcher/command line if requested uint32 gameToLoad = ConfMan.getInt("save_slot"); Common::StringArray savedGamesList = _saveLoad->generateSaveGameList(); if (gameToLoad > savedGamesList.size()) error ("Could not find saved game"); _saveLoad->loadGame(savedGamesList[gameToLoad]); } else { // Otherwise, start us off at aspit's card 1 (the main menu) changeToStack(aspit); changeToCard(1); } while (!_gameOver && !shouldQuit()) handleEvents(); return Common::kNoError; }
void LuaScriptEngine::setCommandLine(const Common::StringArray &commandLineParameters) { lua_newtable(_state); for (size_t i = 0; i < commandLineParameters.size(); ++i) { lua_pushnumber(_state, i + 1); lua_pushstring(_state, commandLineParameters[i].c_str()); lua_settable(_state, -3); } lua_setglobal(_state, "CommandLine"); }
bool Debugger::Cmd_ShowMessage(int argc, const char **argv) { if (argc != 2) { debugPrintf("Usage: %s <message number>\n", argv[0]); } else { int messageId = strToInt(argv[1]); Common::StringArray msg = _vm->_game->getMessage(messageId); for (uint idx = 0; idx < msg.size(); ++idx) { Common::String srcLine = msg[idx]; debugPrintf("%s\n", srcLine.c_str()); } } return true; }
/* bind accept the following input formats: 1 - [S].slide.[L]{.[C]} 2 - [L]{.[C]} where: [S] is the slide to be shown [L] is the location to switch to (immediately in case 2, or right after slide [S] in case 1) [C] is the character to be selected, and is optional The routine tells one form from the other by searching for the '.slide.' NOTE: there exists one script in which [L] is not used in the case 1, but its use is commented out, and would definitely crash the current implementation. */ void LocationName::bind(const char *s) { free(_buf); _buf = strdup(s); _hasSlide = false; _hasCharacter = false; Common::StringArray list; char *tok = strtok(_buf, "."); while (tok) { list.push_back(tok); tok = strtok(NULL, "."); } if (list.size() < 1 || list.size() > 4) error("changeLocation: ill-formed location name '%s'", s); if (list.size() > 1) { if (list[1] == "slide") { _hasSlide = true; _slide = list[0]; list.remove_at(0); // removes slide name list.remove_at(0); // removes 'slide' } if (list.size() == 2) { _hasCharacter = true; _character = list[1]; } } _location = list[0]; strcpy(_buf, s); // kept as reference }
SaveStateDescriptor MohawkMetaEngine::querySaveMetaInfos(const char *target, int slot) const { #ifdef ENABLE_MYST if (strstr(target, "myst")) { Common::StringArray filenames = Mohawk::MystGameState::generateSaveGameList(); if (slot >= (int) filenames.size()) { return SaveStateDescriptor(); } return Mohawk::MystGameState::querySaveMetaInfos(filenames[slot]); } else #endif { return SaveStateDescriptor(); } }
SaveStateList BuriedMetaEngine::listSaves(const char *target) const { // The original had no pattern, so the user must rename theirs // Note that we ignore the target because saves are compatible between // all versions Common::StringArray fileNames = Buried::BuriedEngine::listSaveFiles(); SaveStateList saveList; for (uint32 i = 0; i < fileNames.size(); i++) { // Isolate the description from the file name Common::String desc = fileNames[i].c_str() + 7; for (int j = 0; j < 4; j++) desc.deleteLastChar(); saveList.push_back(SaveStateDescriptor(i, desc)); } return saveList; }
void WidgetText::load(const Common::String &str, int speaker) { Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; Common::StringArray lines; // If bounds for a window have not yet been calculated, figure them out if (_surface.empty()) { int width = SHERLOCK_SCREEN_WIDTH / 3; int height; for (;;) { splitLines(str, lines, width - _surface.widestChar() * 2, 100); height = (screen.fontHeight() + 1) * lines.size() + 9; if ((width - _surface.widestChar() * 2 > height * 3 / 2) || (width - _surface.widestChar() * 2 > SHERLOCK_SCREEN_WIDTH * 3 / 4)) break; width += (width / 4); } // See if it's only a single line long if (height == _surface.fontHeight() + 10) { width = _surface.widestChar() * 2 + 6; const char *strP = str.c_str(); while (*strP && (*strP < talk._opcodes[OP_SWITCH_SPEAKER] || *strP == talk._opcodes[OP_NULL])) width += _surface.charWidth(*strP++); } _bounds = Common::Rect(width, height); if (speaker == -1) { // No speaker specified, so center window on look position _bounds.translate(ui._lookPos.x - width / 2, ui._lookPos.y - height / 2); } else { // Speaker specified, so center the window above them centerWindowOnSpeaker(speaker); } } render(str); }
void Kernel::loadSelectorNames() { Resource *r = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS), 0); bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); // Starting with KQ7, Mac versions have a BE name table. GK1 Mac and earlier (and all // other platforms) always use LE. bool isBE = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2_1 && g_sci->getGameId() != GID_GK1); if (!r) { // No such resource? // Check if we have a table for this game // Some demos do not have a selector table Common::StringArray staticSelectorTable = checkStaticSelectorNames(); if (staticSelectorTable.empty()) error("Kernel: Could not retrieve selector names"); else warning("No selector vocabulary found, using a static one"); for (uint32 i = 0; i < staticSelectorTable.size(); i++) { _selectorNames.push_back(staticSelectorTable[i]); if (oldScriptHeader) _selectorNames.push_back(staticSelectorTable[i]); } return; } int count = (isBE ? READ_BE_UINT16(r->data) : READ_LE_UINT16(r->data)) + 1; // Counter is slightly off for (int i = 0; i < count; i++) { int offset = isBE ? READ_BE_UINT16(r->data + 2 + i * 2) : READ_LE_UINT16(r->data + 2 + i * 2); int len = isBE ? READ_BE_UINT16(r->data + offset) : READ_LE_UINT16(r->data + offset); Common::String tmp((const char *)r->data + offset + 2, len); _selectorNames.push_back(tmp); //debug("%s", tmp.c_str()); // Early SCI versions used the LSB in the selector ID as a read/write // toggle. To compensate for that, we add every selector name twice. if (oldScriptHeader) _selectorNames.push_back(tmp); } }
bool Debugger::cmdSong(int argc, const char **argv) { if (argc != 2) { debugPrintf("Format: song <name>\n"); return true; } Common::StringArray songs; _vm->_music->getSongNames(songs); for (uint i = 0; i < songs.size(); i++) { if (songs[i].equalsIgnoreCase(argv[1])) { _vm->_music->loadSong(songs[i]); return false; } } debugPrintf("Invalid song. Use the 'songs' command to see which ones are available.\n"); return true; }
void Lingo::runTests() { Common::File inFile; Common::ArchiveMemberList fsList; SearchMan.listMatchingMembers(fsList, "*.lingo"); Common::StringArray fileList; int counter = 1; for (Common::ArchiveMemberList::iterator it = fsList.begin(); it != fsList.end(); ++it) fileList.push_back((*it)->getName()); Common::sort(fileList.begin(), fileList.end()); for (uint i = 0; i < fileList.size(); i++) { Common::SeekableReadStream *const stream = SearchMan.createReadStreamForMember(fileList[i]); if (stream) { uint size = stream->size(); char *script = (char *)calloc(size + 1, 1); stream->read(script, size); debugC(2, kDebugLingoCompile, "Compiling file %s of size %d, id: %d", fileList[i].c_str(), size, counter); _hadError = false; addCode(script, kMovieScript, counter); if (!_hadError) executeScript(kMovieScript, counter); else debugC(2, kDebugLingoCompile, "Skipping execution"); free(script); counter++; } inFile.close(); } }
SaveStateList AdlMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##"); SaveStateList saveList; for (uint i = 0; i < files.size(); ++i) { const Common::String &fileName = files[i]; Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName); if (!inFile) { warning("Cannot open save file '%s'", fileName.c_str()); continue; } if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { warning("No header found in '%s'", fileName.c_str()); delete inFile; continue; } byte saveVersion = inFile->readByte(); if (saveVersion != SAVEGAME_VERSION) { warning("Unsupported save game version %i found in '%s'", saveVersion, fileName.c_str()); delete inFile; continue; } char name[SAVEGAME_NAME_LEN] = { }; inFile->read(name, sizeof(name) - 1); delete inFile; int slotNum = atoi(fileName.c_str() + fileName.size() - 2); SaveStateDescriptor sd(slotNum, name); saveList.push_back(sd); } // Sort saves based on slot number. Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); return saveList; }
Common::String WidgetBase::splitLines(const Common::String &str, Common::StringArray &lines, int maxWidth, uint maxLines) { Talk &talk = *_vm->_talk; const char *strP = str.c_str(); // Loop counting up lines lines.clear(); do { int width = 0; const char *spaceP = nullptr; const char *lineStartP = strP; // Find how many characters will fit on the next line while (width < maxWidth && *strP && ((byte)*strP < talk._opcodes[OP_SWITCH_SPEAKER] || (byte)*strP == talk._opcodes[OP_NULL])) { width += _surface.charWidth(*strP); // Keep track of the last space if (*strP == ' ') spaceP = strP; ++strP; } // If the line was too wide to fit on a single line, go back to the last space // if there was one, or otherwise simply break the line at this point if (width >= maxWidth && spaceP != nullptr) strP = spaceP; // Add the line to the output array lines.push_back(Common::String(lineStartP, strP)); // Move the string ahead to the next line if (*strP == ' ' || *strP == 13) ++strP; } while (*strP && (lines.size() < maxLines) && ((byte)*strP < talk._opcodes[OP_SWITCH_SPEAKER] || (byte)*strP == talk._opcodes[OP_NULL])); // Return any remaining text left over return *strP ? Common::String(strP) : Common::String(); }
SaveStateList DreamWebMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::StringArray files = saveFileMan->listSavefiles("DREAMWEB.D??"); Common::sort(files.begin(), files.end()); SaveStateList saveList; for(uint i = 0; i < files.size(); ++i) { const Common::String &file = files[i]; Common::InSaveFile *stream = saveFileMan->openForLoading(file); if (!stream) error("cannot open save file %s", file.c_str()); char name[17] = {}; stream->seek(0x61); stream->read(name, sizeof(name) - 1); delete stream; int slotNum = atoi(file.c_str() + file.size() - 2); SaveStateDescriptor sd(slotNum, name); saveList.push_back(sd); } return saveList; }
SaveStateList MohawkMetaEngine::listSaves(const char *target) const { Common::StringArray filenames; SaveStateList saveList; // Loading games is only supported in Myst/Riven currently. #ifdef ENABLE_MYST if (strstr(target, "myst")) { filenames = g_system->getSavefileManager()->listSavefiles("myst-###.mys"); size_t prefixLen = sizeof("myst") - 1; for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) { // Extract the slot number from the filename char slot[4]; slot[0] = (*filename)[prefixLen + 1]; slot[1] = (*filename)[prefixLen + 2]; slot[2] = (*filename)[prefixLen + 3]; slot[3] = '\0'; int slotNum = atoi(slot); // Read the description from the save Common::String description = Mohawk::MystGameState::querySaveDescription(slotNum); saveList.push_back(SaveStateDescriptor(slotNum, description)); } Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); } else #endif if (strstr(target, "riven")) { filenames = g_system->getSavefileManager()->listSavefiles("*.rvn"); for (uint32 i = 0; i < filenames.size(); i++) saveList.push_back(SaveStateDescriptor(i, filenames[i])); } return saveList; }
void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) { // Now, we need to find out selectors which keep changing place... // We do that by dissecting game objects, and looking for selectors at // specified locations. // We need to initialize script 0 here, to make sure that it's always // located at segment 1. _segMan->instantiateScript(0); // The Actor class contains the init, xLast and yLast selectors, which // we reference directly. It's always in script 998, so we need to // explicitly load it here. if (getSciVersion() >= SCI_VERSION_1_EGA_ONLY) { uint16 actorScript = 998; #ifdef ENABLE_SCI32 if (getSciVersion() >= SCI_VERSION_2) { actorScript += 64000; } #endif if (_resMan->testResource(ResourceId(kResourceTypeScript, actorScript))) { _segMan->instantiateScript(actorScript); const Object *actorClass = _segMan->getObject(_segMan->findObjectByName("Actor")); if (actorClass) { // Find the xLast and yLast selectors, used in kDoBresen int offset = (getSciVersion() < SCI_VERSION_1_1) ? 3 : 0; #ifdef ENABLE_SCI32 if (getSciVersion() >= SCI_VERSION_2) { offset += 12; } #endif // xLast and yLast always come between illegalBits and xStep int illegalBitsSelectorPos = actorClass->locateVarSelector(_segMan, 15 + offset); // illegalBits int xStepSelectorPos = actorClass->locateVarSelector(_segMan, 51 + offset); // xStep if (xStepSelectorPos - illegalBitsSelectorPos != 3) { error("illegalBits and xStep selectors aren't found in " "known locations. illegalBits = %d, xStep = %d", illegalBitsSelectorPos, xStepSelectorPos); } int xLastSelectorPos = actorClass->getVarSelector(illegalBitsSelectorPos + 1); int yLastSelectorPos = actorClass->getVarSelector(illegalBitsSelectorPos + 2); if (selectorNames.size() < (uint32)yLastSelectorPos + 1) selectorNames.resize((uint32)yLastSelectorPos + 1); selectorNames[xLastSelectorPos] = "xLast"; selectorNames[yLastSelectorPos] = "yLast"; } _segMan->uninstantiateScript(actorScript); } } // Find selectors from specific classes for (int i = 0; i < ARRAYSIZE(classReferences); i++) { if (!_resMan->testResource(ResourceId(kResourceTypeScript, classReferences[i].script))) continue; _segMan->instantiateScript(classReferences[i].script); const Object *targetClass = _segMan->getObject(_segMan->findObjectByName(classReferences[i].className)); int targetSelectorPos = 0; uint selectorOffset = classReferences[i].selectorOffset; if (targetClass) { if (classReferences[i].selectorType == kSelectorMethod) { if (targetClass->getMethodCount() < selectorOffset + 1) error("The %s class has less than %d methods (%d)", classReferences[i].className, selectorOffset + 1, targetClass->getMethodCount()); targetSelectorPos = targetClass->getFuncSelector(selectorOffset); } else { // Add the global selectors to the selector ID selectorOffset += (getSciVersion() <= SCI_VERSION_1_LATE) ? 3 : 8; if (targetClass->getVarCount() < selectorOffset + 1) error("The %s class has less than %d variables (%d)", classReferences[i].className, selectorOffset + 1, targetClass->getVarCount()); targetSelectorPos = targetClass->getVarSelector(selectorOffset); } if (selectorNames.size() < (uint32)targetSelectorPos + 1) selectorNames.resize((uint32)targetSelectorPos + 1); selectorNames[targetSelectorPos] = classReferences[i].selectorName; } } _segMan->resetSegMan(); }
Common::Error MohawkEngine_Riven::run() { MohawkEngine::run(); // Let's try to open the installer file (it holds extras.mhk) // Though, we set a low priority to prefer the extracted version if (_installerArchive.open("arcriven.z")) SearchMan.add("arcriven.z", &_installerArchive, 0, false); _gfx = new RivenGraphics(this); _console = new RivenConsole(this); _saveLoad = new RivenSaveLoad(this, _saveFileMan); _externalScriptHandler = new RivenExternal(this); _optionsDialog = new RivenOptionsDialog(this); _scriptMan = new RivenScriptManager(this); _rnd = new Common::RandomSource("riven"); // Create the cursor manager if (Common::File::exists("rivendmo.exe")) _cursor = new PECursorManager("rivendmo.exe"); else if (Common::File::exists("riven.exe")) _cursor = new PECursorManager("riven.exe"); else // last resort: try the Mac executable _cursor = new MacCursorManager("Riven"); initVars(); // We need to have a cursor source, or the game won't work if (!_cursor->hasSource()) { Common::String message = "You're missing a Riven executable. The Windows executable is 'riven.exe' or 'rivendmo.exe'. "; message += "Using the 'arcriven.z' installer file also works. In addition, you can use the Mac 'Riven' executable."; GUIErrorMessage(message); warning("%s", message.c_str()); return Common::kNoGameDataFoundError; } // Open extras.mhk for common images _extrasFile = new MohawkArchive(); // We need extras.mhk for inventory images, marble images, and credits images if (!_extrasFile->openFile("extras.mhk")) { Common::String message = "You're missing 'extras.mhk'. Using the 'arcriven.z' installer file also works."; GUIErrorMessage(message); warning("%s", message.c_str()); return Common::kNoGameDataFoundError; } // Set the transition speed _gfx->setTransitionSpeed(_vars["transitionmode"]); // Start at main cursor _cursor->setCursor(kRivenMainCursor); _cursor->showCursor(); _system->updateScreen(); // Let's begin, shall we? if (getFeatures() & GF_DEMO) { // Start the demo off with the videos changeToStack(kStackAspit); changeToCard(6); } else if (ConfMan.hasKey("save_slot")) { // Load game from launcher/command line if requested uint32 gameToLoad = ConfMan.getInt("save_slot"); Common::StringArray savedGamesList = _saveLoad->generateSaveGameList(); if (gameToLoad > savedGamesList.size()) error ("Could not find saved game"); // Attempt to load the game. On failure, just send us to the main menu. if (_saveLoad->loadGame(savedGamesList[gameToLoad]).getCode() != Common::kNoError) { changeToStack(kStackAspit); changeToCard(1); } } else { // Otherwise, start us off at aspit's card 1 (the main menu) changeToStack(kStackAspit); changeToCard(1); } while (!_gameOver && !shouldQuit()) handleEvents(); return Common::kNoError; }