Example #1
0
Common::String Win32TaskbarManager::getIconPath(Common::String target) {
	// We first try to look for a iconspath configuration variable then
	// fallback to the extra path
	//
	// Icons can be either in a subfolder named "icons" or directly in the path

	Common::String iconsPath = ConfMan.get("iconspath");
	Common::String extraPath = ConfMan.get("extrapath");

#define TRY_ICON_PATH(path) { \
	Common::FSNode node((path)); \
	if (node.exists()) \
		return (path); \
}

	if (!iconsPath.empty()) {
		TRY_ICON_PATH(iconsPath + "/" + target + ".ico");
		TRY_ICON_PATH(iconsPath + "/" + ConfMan.get("gameid") + ".ico");
		TRY_ICON_PATH(iconsPath + "/icons/" + target + ".ico");
		TRY_ICON_PATH(iconsPath + "/icons/" + ConfMan.get("gameid") + ".ico");
	}

	if (!extraPath.empty()) {
		TRY_ICON_PATH(extraPath + "/" + target + ".ico");
		TRY_ICON_PATH(extraPath + "/" + ConfMan.get("gameid") + ".ico");
		TRY_ICON_PATH(extraPath + "/icons/" + target + ".ico");
		TRY_ICON_PATH(extraPath + "/icons/" + ConfMan.get("gameid") + ".ico");
	}

	return "";
}
Example #2
0
void Win32TaskbarManager::setOverlayIcon(const Common::String &name, const Common::String &description) {
	//warning("[Win32TaskbarManager::setOverlayIcon] Setting overlay icon to: %s (%s)", name.c_str(), description.c_str());

	if (_taskbar == NULL)
		return;

	if (name.empty()) {
		_taskbar->SetOverlayIcon(getHwnd(), NULL, L"");
		return;
	}

	// Compute full icon path
	Common::String path = getIconPath(name);
	if (path.empty())
		return;

	HICON pIcon = (HICON)::LoadImage(NULL, path.c_str(), IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
	if (!pIcon) {
		warning("[Win32TaskbarManager::setOverlayIcon] Cannot load icon!");
		return;
	}

	// Sets the overlay icon
	LPWSTR desc = ansiToUnicode(description.c_str());
	_taskbar->SetOverlayIcon(getHwnd(), pIcon, desc);

	DestroyIcon(pIcon);

	delete[] desc;
}
Example #3
0
bool MohawkEngine_Riven::checkDatafiles() {
	Common::String missingFiles;

	const char **datafiles = listExpectedDatafiles();
	for (int i = 0; datafiles[i] != nullptr; i++) {
		if (!SearchMan.hasFile(datafiles[i])) {
			if (strcmp(datafiles[i], "j_Data3.mhk") == 0
					|| strcmp(datafiles[i], "b_Data1.mhk") == 0) {
				// j_Data3.mhk and b_Data1.mhk come from the 1.02 patch. They are not required to play.
				continue;
			}

			if (!missingFiles.empty()) {
				missingFiles += ", ";
			}
			missingFiles += datafiles[i];
		}
	}

	if (missingFiles.empty()) {
		return true;
	}

	Common::String message = _("You are missing the following required Riven data files:\n") + missingFiles;
	warning("%s", message.c_str());
	GUIErrorMessage(message);

	return false;
}
Example #4
0
Common::String OSystem_POSIX::getDefaultConfigFileName() {
	Common::String configFile;

	Common::String prefix;
#ifdef MACOSX
	prefix = getenv("HOME");
#elif !defined(SAMSUNGTV)
	const char *envVar;
	// Our old configuration file path for POSIX systems was ~/.scummvmrc.
	// If that file exists, we still use it.
	envVar = getenv("HOME");
	if (envVar && *envVar) {
		configFile = envVar;
		configFile += '/';
		configFile += ".scummvmrc";

		if (configFile.size() < MAXPATHLEN) {
			struct stat sb;
			if (stat(configFile.c_str(), &sb) == 0) {
				return configFile;
			}
		}
	}

	// On POSIX systems we follow the XDG Base Directory Specification for
	// where to store files. The version we based our code upon can be found
	// over here: http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
	envVar = getenv("XDG_CONFIG_HOME");
	if (!envVar || !*envVar) {
		envVar = getenv("HOME");
		if (!envVar) {
			return 0;
		}

		if (Posix::assureDirectoryExists(".config", envVar)) {
			prefix = envVar;
			prefix += "/.config";
		}
	} else {
		prefix = envVar;
	}

	if (!prefix.empty() && Posix::assureDirectoryExists("scummvm", prefix.c_str())) {
		prefix += "/scummvm";
	}
#endif

	if (!prefix.empty() && (prefix.size() + 1 + _baseConfigName.size()) < MAXPATHLEN) {
		configFile = prefix;
		configFile += '/';
		configFile += _baseConfigName;
	} else {
		configFile = _baseConfigName;
	}

	return configFile;
}
Example #5
0
const ExtraGuiOptions AdvancedMetaEngine::getExtraGuiOptions(const Common::String &target) const {
	if (!_extraGuiOptions)
		return ExtraGuiOptions();

	ExtraGuiOptions options;

	// If there isn't any target specified, return all available GUI options.
	// Only used when an engine starts in order to set option defaults.
	if (target.empty()) {
		for (const ADExtraGuiOptionsMap *entry = _extraGuiOptions; entry->guioFlag; ++entry)
			options.push_back(entry->option);

		return options;
	}

	// Query the GUI options
	const Common::String guiOptionsString = ConfMan.get("guioptions", target);
	const Common::String guiOptions = parseGameGUIOptions(guiOptionsString);

	// Add all the applying extra GUI options.
	for (const ADExtraGuiOptionsMap *entry = _extraGuiOptions; entry->guioFlag; ++entry) {
		if (guiOptions.contains(entry->guioFlag))
			options.push_back(entry->option);
	}

	return options;
}
Example #6
0
void SciEngine::loadMacExecutable() {
	if (getPlatform() != Common::kPlatformMacintosh || getSciVersion() < SCI_VERSION_1_EARLY || getSciVersion() > SCI_VERSION_1_1)
		return;

	Common::String filename;

	switch (getGameId()) {
	case GID_KQ6:
		filename = "King's Quest VI";
		break;
	case GID_FREDDYPHARKAS:
		filename = "Freddy Pharkas";
		break;
	default:
		break;
	}

	if (filename.empty())
		return;

	if (!_macExecutable.open(filename) || !_macExecutable.hasResFork()) {
		// KQ6/Freddy require the executable to load their icon bar palettes
		if (hasMacIconBar())
			error("Could not load Mac resource fork '%s'", filename.c_str());

		// TODO: Show some sort of warning dialog saying they can't get any
		// high-res Mac fonts, when we get to that point ;)
	}
}
Example #7
0
bool LabEngine::saveRestoreGame() {
	bool isOK = false;

	// The original had one screen for saving/loading. We have two.
	// Ask the user which screen to use.
	GUI::MessageDialog saveOrLoad(_("Would you like to save or restore a game?"), _("Save"), _("Restore"));

	int choice = saveOrLoad.runModal();
	if (choice == GUI::kMessageOK) {
		// Save
		GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
		int slot = dialog->runModalWithCurrentTarget();
		if (slot >= 0) {
			Common::String desc = dialog->getResultString();

			if (desc.empty()) {
				// create our own description for the saved game, the user didn't enter it
				desc = dialog->createDefaultSaveDescription(slot);
			}

			isOK = saveGame(slot, desc);
		}
		delete dialog;
	} else {
		// Restore
		GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
		int slot = dialog->runModalWithCurrentTarget();
		if (slot >= 0) {
			isOK = loadGame(slot);
		}
		delete dialog;
	}

	return isOK;
}
Example #8
0
bool ThemeEngine::themeConfigParseHeader(Common::String header, Common::String &themeName) {
	// Check that header is not corrupted
	if ((byte)header[0] > 127) {
		warning("Corrupted theme header found");
		return false;
	}

	header.trim();

	if (header.empty())
		return false;

	if (header[0] != '[' || header.lastChar() != ']')
		return false;

	header.deleteChar(0);
	header.deleteLastChar();

	Common::StringTokenizer tok(header, ":");

	if (tok.nextToken() != SCUMMVM_THEME_VERSION_STR)
		return false;

	themeName = tok.nextToken();
	Common::String author = tok.nextToken();

	return tok.empty();
}
Example #9
0
Common::String BuriedEngine::getFilePath(uint32 stringID) {
	Common::String path = getString(stringID);
	Common::String output;

	if (path.empty())
		return output;

	uint i = 0;

	// The non-demo paths have CD info followed by a backslash.
	// We ignore this.
	// In the demo, we remove the "BITDATA" prefix because the
	// binaries are in the same directory.
	if (isDemo())
		i += 8;
	else
		i += 2;

	for (; i < path.size(); i++) {
		if (path[i] == '\\')
			output += '/';
		else
			output += path[i];
	}

	return output;
}
Example #10
0
void RemoteBrowserDialog::updateListing() {
	// Update the path display
	Common::String path = _node.path();
	if (path.empty())
		path = "/"; //root
	if (_navigationLocked)
		path = "Loading... " + path;
	_currentPath->setLabel(path);

	if (!_navigationLocked) {
		// Populate the ListWidget
		ListWidget::StringArray list;
		ListWidget::ColorList colors;
		for (Common::Array<Cloud::StorageFile>::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) {
			if (i->isDirectory()) {
				list.push_back(i->name() + "/");
				colors.push_back(ThemeEngine::kFontColorNormal);
			} else {
				list.push_back(i->name());
				colors.push_back(ThemeEngine::kFontColorAlternate);
			}
		}

		_fileList->setList(list, &colors);
		_fileList->scrollTo(0);
	}

	_fileList->setEnabled(!_navigationLocked);

	// Finally, redraw
	g_gui.scheduleTopDialogRedraw();
}
Example #11
0
bool StarTrekEngine::showSaveMenu() {
	GUI::SaveLoadChooser *dialog;
	Common::String desc;
	int slot;

	dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);

	slot = dialog->runModalWithCurrentTarget();
	desc = dialog->getResultString();

	if (desc.empty()) {
		// create our own description for the saved game, the user didnt enter it
		desc = dialog->createDefaultSaveDescription(slot);
	}

	if (desc.size() > 28)
		desc = Common::String(desc.c_str(), 28);

	delete dialog;

	if (slot < 0)
		return true;

	return saveGame(slot, desc);
}
Example #12
0
void Parallaction_br::setFollower(const Common::String &name) {
	if (name.empty()) {
		_followerName.clear();
		_follower.reset();
	} else {
		_followerName = name;
		_follower = _location.findAnimation(name.c_str());
	}
}
Example #13
0
void MohawkEngine_Riven::addZipVisitedCard(uint16 cardId, uint16 cardNameId) {
	Common::String cardName = getStack()->getName(kCardNames, cardNameId);
	if (cardName.empty())
		return;
	ZipMode zip;
	zip.name = cardName;
	zip.id = cardId;
	if (Common::find(_zipModeData.begin(), _zipModeData.end(), zip) == _zipModeData.end())
		_zipModeData.push_back(zip);
}
Example #14
0
void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
	//warning("[Win32TaskbarManager::addRecent] Adding recent list entry: %s (%s)", name.c_str(), description.c_str());

	if (_taskbar == NULL)
		return;

	// ANSI version doesn't seem to work correctly with Win7 jump lists, so explicitly use Unicode interface.
	IShellLinkW *link;

	// Get the ScummVM executable path.
	WCHAR path[MAX_PATH];
	GetModuleFileNameW(NULL, path, MAX_PATH);

	// Create a shell link.
	if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC, IID_IShellLinkW, reinterpret_cast<void**> (&link)))) {
		// Convert game name and description to Unicode.
		LPWSTR game = ansiToUnicode(name.c_str());
		LPWSTR desc = ansiToUnicode(description.c_str());

		// Set link properties.
		link->SetPath(path);
		link->SetArguments(game);

		Common::String iconPath = getIconPath(name);
		if (iconPath.empty()) {
			link->SetIconLocation(path, 0); // No game-specific icon available
		} else {
			LPWSTR icon = ansiToUnicode(iconPath.c_str());

			link->SetIconLocation(icon, 0);

			delete[] icon;
		}

		// The link's display name must be set via property store.
		IPropertyStore* propStore;
		HRESULT hr = link->QueryInterface(IID_IPropertyStore, reinterpret_cast<void**> (&(propStore)));
		if (SUCCEEDED(hr)) {
			PROPVARIANT pv;
			pv.vt = VT_LPWSTR;
			pv.pwszVal = desc;

			hr = propStore->SetValue(PKEY_Title, pv);

			propStore->Commit();
			propStore->Release();
		}

		// SHAddToRecentDocs will cause the games to be added to the Recent list, allowing the user to pin them.
		SHAddToRecentDocs(SHARD_LINK, link);
		link->Release();
		delete[] game;
		delete[] desc;
	}
}
Example #15
0
Common::String OSystem_SDL::getSystemLanguage() const {
#if defined(USE_DETECTLANG) && !defined(_WIN32_WCE)
#ifdef WIN32
	// We can not use "setlocale" (at least not for MSVC builds), since it
	// will return locales like: "English_USA.1252", thus we need a special
	// way to determine the locale string for Win32.
	char langName[9];
	char ctryName[9];

	const LCID languageIdentifier = GetThreadLocale();

	if (GetLocaleInfo(languageIdentifier, LOCALE_SISO639LANGNAME, langName, sizeof(langName)) != 0 &&
		GetLocaleInfo(languageIdentifier, LOCALE_SISO3166CTRYNAME, ctryName, sizeof(ctryName)) != 0) {
		Common::String localeName = langName;
		localeName += "_";
		localeName += ctryName;

		return localeName;
	} else {
		return ModularBackend::getSystemLanguage();
	}
#else // WIN32
	// Activating current locale settings
	const Common::String locale = setlocale(LC_ALL, "");

	// Restore default C locale to prevent issues with
	// portability of sscanf(), atof(), etc.
	// See bug #3615148
	setlocale(LC_ALL, "C");

	// Detect the language from the locale
	if (locale.empty()) {
		return ModularBackend::getSystemLanguage();
	} else {
		int length = 0;

		// Strip out additional information, like
		// ".UTF-8" or the like. We do this, since
		// our translation languages are usually
		// specified without any charset information.
		for (int size = locale.size(); length < size; ++length) {
			// TODO: Check whether "@" should really be checked
			// here.
			if (locale[length] == '.' || locale[length] == ' ' || locale[length] == '@')
				break;
		}

		return Common::String(locale.c_str(), length);
	}
#endif // WIN32
#else // USE_DETECTLANG
	return ModularBackend::getSystemLanguage();
#endif // USE_DETECTLANG
}
Example #16
0
uint16 Archive::findResourceID(uint32 tag, const Common::String &resName) const {
	if (!_types.contains(tag) || resName.empty())
		return 0xFFFF;

	const ResourceMap &resMap = _types[tag];

	for (ResourceMap::const_iterator it = resMap.begin(); it != resMap.end(); it++)
		if (it->_value.name.matchString(resName))
			return it->_key;

	return 0xFFFF;
}
Example #17
0
bool MohawkEngine_Riven::isZipVisitedCard(const Common::String &hotspotName) const {
	bool foundMatch = false;

	if (!hotspotName.empty())
		for (uint16 j = 0; j < _zipModeData.size(); j++)
			if (_zipModeData[j].name == hotspotName) {
				foundMatch = true;
				break;
			}

	return foundMatch;
}
Example #18
0
bool Archive::hasResource(uint32 tag, const Common::String &resName) const {
	if (!_types.contains(tag) || resName.empty())
		return false;

	const ResourceMap &resMap = _types[tag];

	for (ResourceMap::const_iterator it = resMap.begin(); it != resMap.end(); it++)
		if (it->_value.name.matchString(resName))
			return true;

	return false;
}
Example #19
0
MacCursorManager::MacCursorManager(const Common::String &appName) {
	if (!appName.empty()) {
		_resFork = new Common::MacResManager();

		if (!_resFork->open(appName)) {
			// Not all have cursors anyway, so this is not a problem
			delete _resFork;
			_resFork = 0;
		}
	} else {
		_resFork = 0;
	}
}
Example #20
0
bool ThemeParser::resolutionCheck(const Common::String &resolution) {
	if (resolution.empty())
		return true;

	Common::StringTokenizer globTokenizer(resolution, ", ");
	Common::String cur;

	while (!globTokenizer.empty()) {
		cur = globTokenizer.nextToken();

		bool lt;
		int val;

		if (cur.size() < 5) {
			warning("Invalid theme 'resolution' token '%s'", resolution.c_str());
			return false;
		}

		if (cur[0] == 'x') {
			val = g_system->getOverlayWidth();
		} else if (cur[0] == 'y') {
			val = g_system->getOverlayHeight();
		} else {
			warning("Error parsing theme 'resolution' token '%s'", resolution.c_str());
			return false;
		}

		if (cur[1] == '<') {
			lt = true;
		} else if (cur[1] == '>') {
			lt = false;
		} else {
			warning("Error parsing theme 'resolution' token '%s'", resolution.c_str());
			return false;
		}

		int token = atoi(cur.c_str() + 2);

		// check inverse for unfulfilled requirements
		if (lt) {
			if (val >= token)
				return false;
		} else {
			if (val <= token)
				return false;
		}
	}

	return true;
}
Example #21
0
const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename) {
	const Graphics::Font *font = 0;
	Common::String cacheFilename = genCacheFilename(filename);
	Common::File fontFile;

	if (!cacheFilename.empty()) {
		if (fontFile.open(cacheFilename)) {
			font = Graphics::BdfFont::loadFromCache(fontFile);
		}

		if (font)
			return font;

		if ((font = loadCachedFontFromArchive(cacheFilename)))
			return font;
	}

	// normal open
	if (fontFile.open(filename)) {
		font = Graphics::BdfFont::loadFont(fontFile);
	}

	if (!font) {
		font = loadFontFromArchive(filename);
	}

	if (font) {
		if (!cacheFilename.empty()) {
			if (!Graphics::BdfFont::cacheFontData(*(const Graphics::BdfFont *)font, cacheFilename)) {
				warning("Couldn't create cache file for font '%s'", filename.c_str());
			}
		}
	}

	return font;
}
Example #22
0
void RemoteBrowserDialog::goUp() {
	if (_rememberedNodeContents.contains(_node.path()))
		_rememberedNodeContents.erase(_node.path());

	Common::String path = _node.path();
	if (path.size() && (path.lastChar() == '/' || path.lastChar() == '\\'))
		path.deleteLastChar();
	if (path.empty()) {
		_rememberedNodeContents.erase("");
	} else {
		for (int i = path.size() - 1; i >= 0; --i)
			if (i == 0 || path[i] == '/' || path[i] == '\\') {
				path.erase(i);
				break;
			}
	}

	listDirectory(Cloud::StorageFile(path, 0, 0, true));
}
Example #23
0
Common::String ThemeEngine::getThemeId(const Common::String &filename) {
	// If no filename has been given we will initialize the builtin theme
	if (filename.empty())
		return "builtin";

	Common::FSNode node(filename);
	if (!node.exists())
		return "builtin";

	if (node.getName().matchString("*.zip", true)) {
		Common::String id = node.getName();

		for (int i = 0; i < 4; ++i)
			id.deleteLastChar();

		return id;
	} else {
		return node.getName();
	}
}
Example #24
0
void ThemeEngine::drawPopUpWidget(const Common::Rect &r, const Common::String &sel, int deltax, WidgetStateInfo state, Graphics::TextAlign align) {
	if (!ready())
		return;

	DrawData dd = kDDPopUpIdle;

	if (state == kStateEnabled)
		dd = kDDPopUpIdle;
	else if (state == kStateHighlight)
		dd = kDDPopUpHover;
	else if (state == kStateDisabled)
		dd = kDDPopUpDisabled;

	queueDD(dd, r);

	if (!sel.empty()) {
		Common::Rect text(r.left + 3, r.top + 1, r.right - 10, r.bottom);
		queueDDText(getTextData(dd), getTextColor(dd), text, sel, true, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax);
	}
}
Example #25
0
bool DumpFile::open(const String &filename, bool createPath) {
	assert(!filename.empty());
	assert(!_handle);

	if (createPath) {
		for (uint32 i = 0; i < filename.size(); ++i) {
			if (filename[i] == '/' || filename[i] == '\\') {
				Common::String subpath = filename;
				subpath.erase(i);
				if (subpath.empty()) continue;
				AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(subpath);
				if (node->exists()) continue;
				if (!node->create(true)) warning("DumpFile: unable to create directories from path prefix");
			}
		}
	}

	FSNode node(filename);
	return open(node);
}
Example #26
0
Common::String DefaultSaveFileManager::getSavePath() const {

	Common::String dir;

	// Try to use game specific savepath from config
	dir = ConfMan.get("savepath");

	// Work around a bug (#999122) in the original 0.6.1 release of
	// ScummVM, which would insert a bad savepath value into config files.
	if (dir == "None") {
		ConfMan.removeKey("savepath", ConfMan.getActiveDomainName());
		ConfMan.flushToDisk();
		dir = ConfMan.get("savepath");
	}

#ifdef _WIN32_WCE
	if (dir.empty())
		dir = ConfMan.get("path");
#endif

	return dir;
}
Example #27
0
void AdvancedMetaEngine::composeFileHashMap(FileMap &allFiles, const Common::FSList &fslist, int depth, const Common::String &parentName) const {
	if (depth <= 0)
		return;

	if (fslist.empty())
		return;

	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
		Common::String tstr = (_matchFullPaths && !parentName.empty() ? parentName + "/" : "") + file->getName();

		if (file->isDirectory()) {
			Common::FSList files;

			if (!_directoryGlobs)
				continue;

			bool matched = false;
			for (const char * const *glob = _directoryGlobs; *glob; glob++)
				if (file->getName().matchString(*glob, true)) {
					matched = true;
					break;
				}

			if (!matched)
				continue;

			if (!file->getChildren(files, Common::FSNode::kListAll))
				continue;

			composeFileHashMap(allFiles, files, depth - 1, tstr);
		}

		// Strip any trailing dot
		if (tstr.lastChar() == '.')
			tstr.deleteLastChar();

		allFiles[tstr] = *file;	// Record the presence of this file
	}
}
Example #28
0
Common::SeekableReadStream *LangFilter::createReadStreamForMember(const Common::String &name) const {
	if (!_arc)
		return 0;

	//Search the right file
	Common::String fullName;
	Common::List<Common::String> namesToTry;
	namesToTry.push_front(kLanguages1[_lang] + name);
	namesToTry.push_front(kLanguages1[kCommon] + name);
	namesToTry.push_front(kLanguages2[_lang] + name);
	namesToTry.push_front(kLanguages2[kCommon] + name);
	for (Common::List<Common::String>::const_iterator it = namesToTry.begin(); it != namesToTry.end(); it++)
		if (_arc->hasFile(*it)) {
			fullName = *it;
			break;
		}

	if (fullName.empty())
		return 0;

	return _arc->createReadStreamForMember(fullName);
}
Example #29
0
void ResourceManager::addNewGMPatch(SciGameId gameId) {
    Common::String gmPatchFile;

    switch (gameId) {
    case GID_ECOQUEST:
        gmPatchFile = "ECO1GM.PAT";
        break;
    case GID_HOYLE3:
        gmPatchFile = "HOY3GM.PAT";
        break;
    case GID_LSL1:
        gmPatchFile = "LL1_GM.PAT";
        break;
    case GID_LSL5:
        gmPatchFile = "LL5_GM.PAT";
        break;
    case GID_LONGBOW:
        gmPatchFile = "ROBNGM.PAT";
        break;
    case GID_SQ1:
        gmPatchFile = "SQ1_GM.PAT";
        break;
    case GID_SQ4:
        gmPatchFile = "SQ4_GM.PAT";
        break;
    case GID_FAIRYTALES:
        gmPatchFile = "TALEGM.PAT";
        break;
    default:
        break;
    }

    if (!gmPatchFile.empty() && Common::File::exists(gmPatchFile)) {
        ResourceSource *psrcPatch = new PatchResourceSource(gmPatchFile);
        processPatch(psrcPatch, kResourceTypePatch, 4);
    }
}
Example #30
0
bool StarTrekEngine::saveOrLoadGameData(Common::SeekableReadStream *in, Common::WriteStream *out, SavegameMetadata *meta) {
	Common::Serializer ser(in, out);

	if (ser.isLoading()) {
		if (_lastGameMode == GAMEMODE_BRIDGE)
			cleanupBridge();
		else // Assume GAMEMODE_AWAYMISSION
			unloadRoom();
	}

	ser.syncAsUint16LE(_gameMode);
	// TODO: sub_1d8eb (save) / sub_1d958 (load) (probably bridge / space combat state)

	Common::String midiFilename = _sound->_loadedMidiFilename;
	ser.syncString(midiFilename);
	ser.syncAsSint16LE(_sound->_loopingMidiTrack);

	if (ser.isLoading()) {
		if (midiFilename.empty())
			_sound->clearAllMidiSlots();
		else {
			_sound->loadMusicFile(midiFilename);
			_sound->playMidiMusicTracks(_sound->_loopingMidiTrack, _sound->_loopingMidiTrack);
		}
	}

	ser.syncAsUint16LE(_frameIndex);
	ser.syncAsUint16LE(_mouseControllingShip);
	// TODO: word_45aa8
	// TODO: word_45aaa
	// TODO: word_45aac
	// TODO: word_5082e
	// TODO: dword_519b0
	// TODO: word_45ab2
	// TODO: word_45ab4
	// TODO: word_45ab8

	ser.syncString(_missionToLoad);
	// TODO: word_4b032
	// TODO: word_519bc
	// TODO: word_45c5c
	// TODO: unk_52afe
	ser.syncString(_sound->_loopingAudioName);

	if (ser.isLoading()) {
		if (!_sound->_loopingAudioName.empty())
			_sound->playVoc(_sound->_loopingAudioName);
	}

	// TODO: word_45a50

	for (int i = 0; i < NUM_OBJECTS; i++) {
		ser.syncAsByte(_itemList[i].have);
	}

	if (_gameMode == GAMEMODE_AWAYMISSION) {
		ser.syncString(_missionName);
		ser.syncAsSint16LE(_roomIndex);

		if (ser.isLoading()) {
			_gfx->fadeoutScreen();
			_txtFilename = "ground";

			// This must be done before loading the actor variables, since this clears
			// them.
			loadRoom(_missionName, _roomIndex);
		}

		ser.syncAsUint32LE(_roomFrameCounter);
		ser.syncAsUint32LE(_frameIndex); // FIXME: redundant

		// Serialize the "actor" class
		for (int i = 0; i < NUM_ACTORS; i++) {
			Actor *a = &_actorList[i];
			ser.syncAsUint16LE(a->spriteDrawn);
			ser.syncBytes((byte *)a->animFilename, 16);
			ser.syncAsUint16LE(a->animType);

			a->sprite.saveLoadWithSerializer(ser);

			ser.syncBytes((byte *)a->bitmapFilename, 10);
			a->scale.saveLoadWithSerializer(ser);
			// Can't save "animFile" (will be reloaded)
			ser.syncAsUint16LE(a->numAnimFrames);
			ser.syncAsUint16LE(a->animFrame);
			ser.syncAsUint32LE(a->frameToStartNextAnim);
			ser.syncAsSint16LE(a->pos.x);
			ser.syncAsSint16LE(a->pos.y);
			ser.syncAsUint16LE(a->field60);
			ser.syncAsUint16LE(a->field62);
			ser.syncAsUint16LE(a->triggerActionWhenAnimFinished);
			ser.syncAsUint16LE(a->finishedAnimActionParam);
			ser.syncBytes((byte *)a->animationString2, 8);
			ser.syncAsUint16LE(a->field70);
			ser.syncAsUint16LE(a->field72);
			ser.syncAsUint16LE(a->field74);
			ser.syncAsUint16LE(a->field76);
			ser.syncAsSint16LE(a->iwSrcPosition);
			ser.syncAsSint16LE(a->iwDestPosition);
			a->granularPosX.saveLoadWithSerializer(ser);
			a->granularPosY.saveLoadWithSerializer(ser);
			a->speedX.saveLoadWithSerializer(ser);
			a->speedY.saveLoadWithSerializer(ser);
			ser.syncAsSint16LE(a->dest.x);
			ser.syncAsSint16LE(a->dest.y);
			ser.syncAsUint16LE(a->field90);
			ser.syncAsByte(a->field92);
			ser.syncAsByte(a->direction);
			ser.syncAsUint16LE(a->field94);
			ser.syncAsUint16LE(a->field96);
			ser.syncBytes((byte *)a->animationString, 10);
			ser.syncAsUint16LE(a->fielda2);
			ser.syncAsUint16LE(a->fielda4);
			ser.syncAsUint16LE(a->fielda6);
		}

		ser.syncString(_mapFilename);

		// Away mission struct
		for (int i = 0; i < 8; i++)
			ser.syncAsSint16LE(_awayMission.timers[i]);
		ser.syncAsSint16LE(_awayMission.mouseX);
		ser.syncAsSint16LE(_awayMission.mouseY);
		for (int i = 0; i < 4; i++)
			ser.syncAsSint16LE(_awayMission.crewGetupTimers[i]);
		ser.syncAsByte(_awayMission.disableWalking);
		ser.syncAsByte(_awayMission.disableInput);
		ser.syncAsByte(_awayMission.redshirtDead);
		ser.syncAsByte(_awayMission.activeAction);
		ser.syncAsByte(_awayMission.activeObject);
		ser.syncAsByte(_awayMission.passiveObject);
		ser.syncAsByte(_awayMission.rdfStillDoDefaultAction);
		ser.syncAsByte(_awayMission.crewDownBitset);
		for (int i = 0; i < 4; i++)
			ser.syncAsByte(_awayMission.crewDirectionsAfterWalk[i]);

		if (_missionName == "DEMON") {
			_awayMission.demon.saveLoadWithSerializer(ser);
			_room->_roomVar.demon.saveLoadWithSerializer(ser);
		} else if (_missionName == "TUG") {
			_awayMission.tug.saveLoadWithSerializer(ser);
			_room->_roomVar.tug.saveLoadWithSerializer(ser);
		} else if (_missionName == "LOVE") {
			_awayMission.love.saveLoadWithSerializer(ser);
			_room->_roomVar.love.saveLoadWithSerializer(ser);
		} else if (_missionName == "MUDD") {
			_awayMission.mudd.saveLoadWithSerializer(ser);
			_room->_roomVar.mudd.saveLoadWithSerializer(ser);
		} else if (_missionName == "FEATHER") {
			_awayMission.feather.saveLoadWithSerializer(ser);
			_room->_roomVar.feather.saveLoadWithSerializer(ser);
		} else if (_missionName == "TRIAL") {
			_awayMission.trial.saveLoadWithSerializer(ser);
			_room->_roomVar.trial.saveLoadWithSerializer(ser);
		} else if (_missionName == "SINS") {
			_awayMission.sins.saveLoadWithSerializer(ser);
			_room->_roomVar.sins.saveLoadWithSerializer(ser);
		}

		// The action queue
		if (ser.isLoading()) {
			_actionQueue = Common::Queue<Action>();
			int16 n = 0;
			ser.syncAsSint16LE(n);
			for (int i = 0; i < n; i++) {
				Action a;
				a.saveLoadWithSerializer(ser);
				_actionQueue.push(a);
			}
		} else { // Saving
			int16 n = _actionQueue.size();
			ser.syncAsSint16LE(n);
			for (int i = 0; i < n; i++) {
				Action a = _actionQueue.pop();
				a.saveLoadWithSerializer(ser);
				_actionQueue.push(a);
			}
		}

		// Original game located changes in RDF files and saved them. Since RDF files
		// aren't modified directly here, that's skipped.

		ser.syncAsSint16LE(_objectHasWalkPosition);
		ser.syncAsSint16LE(_objectWalkPosition.x);
		ser.syncAsSint16LE(_objectWalkPosition.y);

		for (int i = 0; i < MAX_BUFFERED_WALK_ACTIONS; i++) {
			_actionOnWalkCompletion[i].saveLoadWithSerializer(ser);
			ser.syncAsByte(_actionOnWalkCompletionInUse[i]);
		}

		ser.syncAsSint16LE(_warpHotspotsActive);
	}

	return true;
}