Ejemplo n.º 1
0
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();
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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");
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
/*
	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
}
Ejemplo n.º 12
0
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();
	}
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
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);
	}
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
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();
	}
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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();
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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();
}
Ejemplo n.º 23
0
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;
}