Example #1
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;
}
Example #2
0
SaveStateList SkyMetaEngine::listSaves(const char *target) const {
	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
	SaveStateList saveList;

	// Load the descriptions
	Common::StringArray savenames;
	savenames.resize(MAX_SAVE_GAMES+1);

	Common::InSaveFile *inf;
	inf = saveFileMan->openForLoading("SKY-VM.SAV");
	if (inf != NULL) {
		char *tmpBuf =  new char[MAX_SAVE_GAMES * MAX_TEXT_LEN];
		char *tmpPtr = tmpBuf;
		inf->read(tmpBuf, MAX_SAVE_GAMES * MAX_TEXT_LEN);
		for (int i = 0; i < MAX_SAVE_GAMES; ++i) {
			savenames[i] = tmpPtr;
			tmpPtr += savenames[i].size() + 1;
		}
		delete inf;
		delete[] tmpBuf;
	}

	// Find all saves
	Common::StringArray filenames;
	filenames = saveFileMan->listSavefiles("SKY-VM.???");
	sort(filenames.begin(), filenames.end());	// Sort (hopefully ensuring we are sorted numerically..)

	// Slot 0 is the autosave, if it exists.
	// TODO: Check for the existence of the autosave -- but this require us
	// to know which SKY variant we are looking at.
	saveList.insert_at(0, SaveStateDescriptor(0, "*AUTOSAVE*"));

	// Prepare the list of savestates by looping over all matching savefiles
	for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
		// Extract the extension
		Common::String ext = file->c_str() + file->size() - 3;
		ext.toUppercase();
		if (Common::isDigit(ext[0]) && Common::isDigit(ext[1]) && Common::isDigit(ext[2])) {
			int slotNum = atoi(ext.c_str());
			Common::InSaveFile *in = saveFileMan->openForLoading(*file);
			if (in) {
				saveList.push_back(SaveStateDescriptor(slotNum+1, savenames[slotNum]));
				delete in;
			}
		}
	}

	return saveList;
}
Example #3
0
void SkyMetaEngine::removeSaveState(const char *target, int slot) const {
	if (slot == 0)	// do not delete the auto save
		return;

	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
	char fName[20];
	sprintf(fName,"SKY-VM.%03d", slot - 1);
	saveFileMan->removeSavefile(fName);

	// Load current save game descriptions
	Common::StringArray savenames;
	savenames.resize(MAX_SAVE_GAMES+1);
	Common::InSaveFile *inf;
	inf = saveFileMan->openForLoading("SKY-VM.SAV");
	if (inf != NULL) {
		char *tmpBuf =  new char[MAX_SAVE_GAMES * MAX_TEXT_LEN];
		char *tmpPtr = tmpBuf;
		inf->read(tmpBuf, MAX_SAVE_GAMES * MAX_TEXT_LEN);
		for (int i = 0; i < MAX_SAVE_GAMES; ++i) {
			savenames[i] = tmpPtr;
			tmpPtr += savenames[i].size() + 1;
		}
		delete inf;
		delete[] tmpBuf;
	}

	// Update the save game description at the given slot
	savenames[slot - 1] = "";

	// Save the updated descriptions
	Common::OutSaveFile *outf;

	outf = saveFileMan->openForSaving("SKY-VM.SAV");
	bool ioFailed = true;
	if (outf) {
		for (uint16 cnt = 0; cnt < MAX_SAVE_GAMES; cnt++) {
			outf->write(savenames[cnt].c_str(), savenames[cnt].size() + 1);
		}
		outf->finalize();
		if (!outf->err())
			ioFailed = false;
		delete outf;
	}
	if (ioFailed)
		warning("Unable to store Savegame names to file SKY-VM.SAV. (%s)", saveFileMan->popErrorDesc().c_str());
}
Example #4
0
Common::Error SkyEngine::saveGameState(int slot, const Common::String &desc) {
	if (slot == 0)
		return Common::kWritePermissionDenied;	// we can't overwrite the auto save

	// Set the save slot and save the game
	_skyControl->_selectedGame = slot - 1;
	if (_skyControl->saveGameToFile(false) != GAME_SAVED)
		return Common::kWritePermissionDenied;

	// Load current save game descriptions
	Common::StringArray saveGameTexts;
	saveGameTexts.resize(MAX_SAVE_GAMES+1);
	_skyControl->loadDescriptions(saveGameTexts);

	// Update the save game description at the given slot
	saveGameTexts[slot - 1] = desc;
	// Save the updated descriptions
	_skyControl->saveDescriptions(saveGameTexts);

	return Common::kNoError;
}
Example #5
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();
}