Beispiel #1
0
Common::String DefaultSaveFileManager::concatWithSavesPath(Common::String name) {
	DefaultSaveFileManager *manager = dynamic_cast<DefaultSaveFileManager *>(g_system->getSavefileManager());
	Common::String path = (manager ? manager->getSavePath() : ConfMan.get("savepath"));
	if (path.size() > 0 && (path.lastChar() == '/' || path.lastChar() == '\\'))
		return path + name;

	//simple heuristic to determine which path separator to use
	int backslashes = 0;
	for (uint32 i = 0; i < path.size(); ++i)
		if (path[i] == '/') --backslashes;
		else if (path[i] == '\\') ++backslashes;

	if (backslashes > 0) return path + '\\' + name;
	return path + '/' + name;
}
Beispiel #2
0
void SavesSyncRequest::start() {
	//cleanup
	_ignoreCallback = true;
	if (_workingRequest)
		_workingRequest->finish();
	_currentDownloadingFile = StorageFile();
	_currentUploadingFile = "";
	_filesToDownload.clear();
	_filesToUpload.clear();
	_localFilesTimestamps.clear();
	_totalFilesToHandle = 0;
	_ignoreCallback = false;

	//load timestamps
	_localFilesTimestamps = DefaultSaveFileManager::loadTimestamps();

	//list saves directory
	Common::String dir = _storage->savesDirectoryPath();
	if (dir.lastChar() == '/')
		dir.deleteLastChar();
	_workingRequest = _storage->listDirectory(
		dir,
		new Common::Callback<SavesSyncRequest, Storage::ListDirectoryResponse>(this, &SavesSyncRequest::directoryListedCallback),
		new Common::Callback<SavesSyncRequest, Networking::ErrorResponse>(this, &SavesSyncRequest::directoryListedErrorCallback)
	);
	if (!_workingRequest) finishError(Networking::ErrorResponse(this));
}
Beispiel #3
0
void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse error) {
	_workingRequest = nullptr;
	if (_ignoreCallback)
		return;

	bool irrecoverable = error.interrupted || error.failed;
	if (error.failed) {
		Common::JSONValue *value = Common::JSON::parse(error.response.c_str());
		if (value) {
			if (value->isObject()) {
				Common::JSONObject object = value->asObject();

				//Dropbox-related error:
				if (object.contains("error_summary") && object.getVal("error_summary")->isString()) {
					Common::String summary = object.getVal("error_summary")->asString();
					if (summary.contains("not_found")) {
						irrecoverable = false;
					}
				}

				//OneDrive-related error:
				if (object.contains("error") && object.getVal("error")->isObject()) {
					Common::JSONObject errorNode = object.getVal("error")->asObject();
					if (Networking::CurlJsonRequest::jsonContainsString(errorNode, "code", "SavesSyncRequest")) {
						Common::String code = errorNode.getVal("code")->asString();
						if (code == "itemNotFound") {
							irrecoverable = false;
						}
					}
				}
			}
			delete value;
		}

		//Google Drive and Box-related ScummVM-based error
		if (error.response.contains("subdirectory not found")) {
			irrecoverable = false; //base "/ScummVM/" folder not found
		} else if (error.response.contains("no such file found in its parent directory")) {
			irrecoverable = false; //"Saves" folder within "/ScummVM/" not found
		}
	}

	if (irrecoverable) {
		finishError(error);
		return;
	}

	//we're lucky - user just lacks his "/cloud/" folder - let's create one
	Common::String dir = _storage->savesDirectoryPath();
	if (dir.lastChar() == '/')
		dir.deleteLastChar();
	debug(9, "SavesSyncRequest: creating %s", dir.c_str());
	_workingRequest = _storage->createDirectory(
		dir,
		new Common::Callback<SavesSyncRequest, Storage::BoolResponse>(this, &SavesSyncRequest::directoryCreatedCallback),
		new Common::Callback<SavesSyncRequest, Networking::ErrorResponse>(this, &SavesSyncRequest::directoryCreatedErrorCallback)
	);
	if (!_workingRequest)
		finishError(Networking::ErrorResponse(this));
}
Beispiel #4
0
Ps2FilesystemNode::Ps2FilesystemNode(const Common::String &path) {
	dbg_printf("NEW FSNODE(%s)\n", path.c_str());

	_path = path;

	if (path.empty()) {
		_isHere = true;
		_isDirectory = true; /* root is always a dir */
		_isRoot = true;
		_displayName = Common::String("PlayStation 2");
		_verified = true;
	} else if (path.lastChar() == ':') {
		_isHere = true;
		_isDirectory = true; /* devs are always a dir */
		_isRoot = false;
		_displayName = getDeviceDescription();
		_verified = true;
	} else {
		_verified = false;
		doverify();
		if (!_isHere)
			return;

		_displayName = _lastPathComponent(_path);

		if (_isDirectory && _path.lastChar() != '/')
			_path+= '/';

		_isRoot = false;
	}
}
Beispiel #5
0
bool LabelCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
	if (line.lastChar() != ':') {
		return false;
	}

	Common::String label = line;
	label.deleteLastChar();

	LabelCommand *labelCmd = new LabelCommand(label);
	if (!parseCtx._labels.contains(label)) {
		parseCtx._labels[label] = labelCmd;
	} else {
		warning("Label '%s' already exists", label.c_str());
	}

	if (parseCtx._pendingGotos.contains(label)) {
		GotoCommands &gotos = parseCtx._pendingGotos[label];
		for (GotoCommands::const_iterator it = gotos.begin(); it != gotos.end(); ++it) {
			(*it)->setLabelCommand(labelCmd);
		}
		gotos.clear();
	}

	command = labelCmd;
	return true;
}
Beispiel #6
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();
}
Beispiel #7
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));
}
Beispiel #8
0
Common::InSaveFile *GBAMPSaveFileManager::openForLoading(const Common::String &filename) {
	Common::String fileSpec = getSavePath();
	if (fileSpec.lastChar() != '/')
		fileSpec += '/';
	fileSpec += filename;

//	consolePrintf("Opening the file: %s\n", fileSpec.c_str());

	return DS::DSFileStream::makeFromPath(fileSpec, false);
}
Beispiel #9
0
Common::OutSaveFile *GBAMPSaveFileManager::openForSaving(const Common::String &filename, bool compress) {
	Common::String fileSpec = getSavePath();
	if (fileSpec.lastChar() != '/')
		fileSpec += '/';
	fileSpec += filename;

//	consolePrintf("Opening the file: %s\n", fileSpec.c_str());

	Common::WriteStream *stream = DS::DSFileStream::makeFromPath(fileSpec, true);
	// Use a write buffer
	stream = Common::wrapBufferedWriteStream(stream, SAVE_BUFFER_SIZE);
	return new OutSaveFile(stream);
}
Beispiel #10
0
AbstractFSNode *WindowsFilesystemNode::getChild(const Common::String &n) const {
	assert(_isDirectory);

	// Make sure the string contains no slashes
	assert(!n.contains('/'));

	Common::String newPath(_path);
	if (_path.lastChar() != '\\')
		newPath += '\\';
	newPath += n;

	return new WindowsFilesystemNode(newPath, false);
}
Beispiel #11
0
BadaFilesystemNode::BadaFilesystemNode(const Common::String &root,
																			 const Common::String &nodePath) {
	// Make sure the string contains no slashes
	AppAssert(!nodePath.contains('/'));

	// We assume here that path is already normalized (hence don't bother to
	// call Common::normalizePath on the final path).
	Common::String newPath(root);
	if (root.lastChar() != '/') {
		newPath += '/';
	}
	newPath += nodePath;

	init(newPath);
}
Beispiel #12
0
Common::String ScummEngine_v60he::convertFilePath(const byte *src) {
	debug(2, "convertFilePath in: '%s'", (const char *)src);

	int srcSize = resStrLen(src);
	int start = 0;

	if (srcSize > 2) {
		if (src[0] == ':') { // Game Data Path (Macintosh)
			// The default game data path is set to ':' by ScummVM
			start = 1;
		} else if (src[0] == '.' && src[1] == '\\') { // Game Data Path (Windows)
			// The default game data path is set to '.\\' by ScummVM
			start = 2;
		} else if (src[0] == '*' && src[1] == '\\') { // Save Game Path (Windows HE72 - HE100)
			// The default save game path is set to '*\\' by ScummVM
			start = 2;
		} else if (src[0] == '*' && src[1] == ':') { // Save Game Path (Macintosh HE72 - HE100)
			// The default save game path is set to '*:' by ScummVM
			start = 2;
		} else if (src[0] == 'c' && src[1] == ':') { // Save Game Path (HE60 - HE71)
			// The default save path is game path (DOS) or 'c:\\hegames\\' (Windows)
			for (start = srcSize; start != 0; start--)
				if (src[start - 1] == '\\')
					break;
		} else if (src[0] == 'u' && src[1] == 's') { // Save Game Path (Moonbase Commander)
			// The default save path is 'user\\'
			start = 5;
		}
	}

	Common::String dst;

	for (int i = start; i < srcSize; i++) {
		// Convert path separators
		if (src[i] == '\\' || src[i] == ':')
			dst += '/';
		else
			dst += src[i];
	}

	// Sanity check
	if (dst.lastChar() == '/')
		dst.deleteLastChar();

	debug(2, "convertFilePath out: '%s'", dst.c_str());

	return dst;
}
Beispiel #13
0
Common::String normalizePath(const Common::String &path, const char sep) {
	if (path.empty())
		return path;

	const char *cur = path.c_str();
	Common::String result;

	// If there is a leading slash, preserve that:
	if (*cur == sep) {
		result += sep;
		while (*cur == sep)
			++cur;
	}

	// Scan till the end of the String
	while (*cur != 0) {
		const char *start = cur;

		// Scan till the next path separator resp. the end of the string
		while (*cur != sep && *cur != 0)
			cur++;

		const Common::String component(start, cur);

		// Skip empty components and dot components, add all others
		if (!component.empty() && component != ".") {
			// Add a separator before the component, unless the result
			// string already ends with one (which happens only if the
			// path *starts* with a separator).
			if (!result.empty() && result.lastChar() != sep)
				result += sep;

			// Add the component
			result += component;
		}

		// Skip over separator chars
		while (*cur == sep)
			cur++;
	}

	return result;
}
Beispiel #14
0
static void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles, int depth, const char * const *directoryGlobs) {
    if (depth <= 0)
        return;

    if (fslist.empty())
        return;

    // First we compose a hashmap of all files in fslist.
    // Includes nifty stuff like removing trailing dots and ignoring case.
    for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
        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(files, allFiles, depth - 1, directoryGlobs);
        }

        Common::String tstr = file->getName();

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

        allFiles[tstr] = *file;	// Record the presence of this file
    }
}
Beispiel #15
0
bool ThemeEngine::themeConfigParseHeader(Common::String header, Common::String &themeName) {
	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() != RESIDUAL_THEME_VERSION_STR)
		return false;

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

	return tok.empty();
}
Beispiel #16
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
	}
}
Beispiel #17
0
TextChange TextStyleState::parseStyle(const Common::String &str, int16 len) {
	Common::String buf = Common::String(str.c_str(), len);

	uint retval = TEXT_CHANGE_NONE;

	Common::StringTokenizer tokenizer(buf, " ");
	Common::String token;

	while (!tokenizer.empty()) {
		token = tokenizer.nextToken();

		if (token.matchString("font", true)) {
			token = tokenizer.nextToken();
			if (token[0] == '"') {
				Common::String _tmp = Common::String(token.c_str() + 1);

				while (token.lastChar() != '"' && !tokenizer.empty()) {
					token = tokenizer.nextToken();
					_tmp += " " + token;
				}

				if (_tmp.lastChar() == '"')
					_tmp.deleteLastChar();

				_fontname = _tmp;
			} else {
				if (!tokenizer.empty())
					_fontname = token;
			}
			retval |= TEXT_CHANGE_FONT_TYPE;

		} else if (token.matchString("blue", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				int32 tmp = atoi(token.c_str());
				if (_blue != tmp) {
					_blue = tmp;
					retval |= TEXT_CHANGE_FONT_STYLE;
				}
			}
		} else if (token.matchString("red", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				int32 tmp = atoi(token.c_str());
				if (_red != tmp) {
					_red = tmp;
					retval |= TEXT_CHANGE_FONT_STYLE;
				}
			}
		} else if (token.matchString("green", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				int32 tmp = atoi(token.c_str());
				if (_green != tmp) {
					_green = tmp;
					retval |= TEXT_CHANGE_FONT_STYLE;
				}
			}
		} else if (token.matchString("newline", true)) {
#if 0
			if ((retval & TXT_RET_NEWLN) == 0)
				_newline = 0;

			_newline++;
#endif
			retval |= TEXT_CHANGE_NEWLINE;
		} else if (token.matchString("point", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				int32 tmp = atoi(token.c_str());
				if (_size != tmp) {
					_size = tmp;
					retval |= TEXT_CHANGE_FONT_TYPE;
				}
			}
		} else if (token.matchString("escapement", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
#if 0
				int32 tmp = atoi(token.c_str());
				_escapement = tmp;
#endif
			}
		} else if (token.matchString("italic", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("on", true)) {
					if (_italic != true) {
						_italic = true;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				} else if (token.matchString("off", true)) {
					if (_italic != false) {
						_italic = false;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				}
			}
		} else if (token.matchString("underline", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("on", true)) {
					if (_underline != true) {
						_underline = true;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				} else if (token.matchString("off", true)) {
					if (_underline != false) {
						_underline = false;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				}
			}
		} else if (token.matchString("strikeout", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("on", true)) {
					if (_strikeout != true) {
						_strikeout = true;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				} else if (token.matchString("off", true)) {
					if (_strikeout != false) {
						_strikeout = false;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				}
			}
		} else if (token.matchString("bold", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("on", true)) {
					if (_bold != true) {
						_bold = true;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				} else if (token.matchString("off", true)) {
					if (_bold != false) {
						_bold = false;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				}
			}
		} else if (token.matchString("skipcolor", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
#if 0
				if (token.matchString("on", true)) {
					_skipcolor = true;
				} else if (token.matchString("off", true)) {
					_skipcolor = false;
				}
#endif
			}
		} else if (token.matchString("image", true)) {
			// Not used
		} else if (token.matchString("statebox", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				_statebox = atoi(token.c_str());
				retval |= TEXT_CHANGE_HAS_STATE_BOX;
			}
		} else if (token.matchString("justify", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("center", true))
					_justification = TEXT_JUSTIFY_CENTER;
				else if (token.matchString("left", true))
					_justification = TEXT_JUSTIFY_LEFT;
				else if (token.matchString("right", true))
					_justification = TEXT_JUSTIFY_RIGHT;
			}
		}
	}
	return (TextChange)retval;
}
Beispiel #18
0
void MassAddDialog::handleTickle() {
	if (_scanStack.empty())
		return;	// We have finished scanning

	uint32 t = g_system->getMillis();

	// Perform a breadth-first scan of the filesystem.
	while (!_scanStack.empty() && (g_system->getMillis() - t) < kMaxScanTime) {
		Common::FSNode dir = _scanStack.pop();

		Common::FSList files;
		if (!dir.getChildren(files, Common::FSNode::kListAll)) {
			continue;
		}

		// Run the detector on the dir
		GameList candidates(EngineMan.detectGames(files));

		// Just add all detected games / game variants. If we get more than one,
		// that either means the directory contains multiple games, or the detector
		// could not fully determine which game variant it was seeing. In either
		// case, let the user choose which entries he wants to keep.
		//
		// However, we only add games which are not already in the config file.
		for (GameList::const_iterator cand = candidates.begin(); cand != candidates.end(); ++cand) {
			GameDescriptor result = *cand;
			Common::String path = dir.getPath();

			// Remove trailing slashes
			while (path != "/" && path.lastChar() == '/')
				path.deleteLastChar();

			// Check for existing config entries for this path/gameid/lang/platform combination
			if (_pathToTargets.contains(path)) {
				bool duplicate = false;
				const StringArray &targets = _pathToTargets[path];
				for (StringArray::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) {
					// If the gameid, platform and language match -> skip it
					Common::ConfigManager::Domain *dom = ConfMan.getDomain(*iter);
					assert(dom);

					if ((*dom)["gameid"] == result["gameid"] &&
					    (*dom)["platform"] == result["platform"] &&
					    (*dom)["language"] == result["language"]) {
						duplicate = true;
						break;
					}
				}
				if (duplicate) {
					_oldGamesCount++;
					break;	// Skip duplicates
				}
			}
			result["path"] = path;
			_games.push_back(result);

			_list->append(result.description());
		}


		// Recurse into all subdirs
		for (Common::FSList::const_iterator file = files.begin(); file != files.end(); ++file) {
			if (file->isDirectory()) {
				_scanStack.push(*file);
			}
		}

		_dirsScanned++;
	}


	// Update the dialog
	Common::String buf;

	if (_scanStack.empty()) {
		// Enable the OK button
		_okButton->setEnabled(true);

		buf = _("Scan complete!");
		_dirProgressText->setLabel(buf);

		buf = Common::String::format(_("Discovered %d new games, ignored %d previously added games."), _games.size(), _oldGamesCount);
		_gameProgressText->setLabel(buf);

	} else {
		buf = Common::String::format(_("Scanned %d directories ..."), _dirsScanned);
		_dirProgressText->setLabel(buf);

		buf = Common::String::format(_("Discovered %d new games, ignored %d previously added games ..."), _games.size(), _oldGamesCount);
		_gameProgressText->setLabel(buf);
	}

	if (_games.size() > 0) {
		_list->scrollToEnd();
	}

	drawDialog();
}
Beispiel #19
0
void Menu::createCommandsMenu(MenuItem *menu) {
	Common::String string(_gui->_engine->_world->_commandsMenu);

	Common::String item;

	for (uint i = 0; i < string.size(); i++) {
		while(i < string.size() && string[i] != ';') // Read token
			item += string[i++];

		if (item == "(-") {
			menu->subitems.push_back(new MenuSubItem(NULL, 0));
		} else {
			bool enabled = true;
			int style = 0;
			char shortcut = 0;
			const char *shortPtr = strrchr(item.c_str(), '/');
			if (shortPtr != NULL) {
				if (strlen(shortPtr) >= 2) {
					shortcut = shortPtr[1];
					item.deleteChar(shortPtr - item.c_str());
					item.deleteChar(shortPtr - item.c_str());
				} else {
					error("Unexpected shortcut: '%s', item '%s' in menu '%s'", shortPtr, item.c_str(), string.c_str());
				}
			}

			while (item.size() >= 2 && item[item.size() - 2] == '<') {
				char c = item.lastChar();
				if (c == 'B') {
					style |= kFontStyleBold;
				} else if (c == 'I') {
					style |= kFontStyleItalic;
				} else if (c == 'U') {
					style |= kFontStyleUnderline;
				} else if (c == 'O') {
					style |= kFontStyleOutline;
				} else if (c == 'S') {
					style |= kFontStyleShadow;
				} else if (c == 'C') {
					style |= kFontStyleCondensed;
				} else if (c == 'E') {
					style |= kFontStyleExtended;
				}
				item.deleteLastChar();
				item.deleteLastChar();
			}

			Common::String tmpitem(item);
			tmpitem.trim();
			if (tmpitem[0] == '(') {
				enabled = false;

				for (uint j = 0; j < item.size(); j++)
					if (item[j] == '(') {
						item.deleteChar(j);
						break;
					}
			}

			menu->subitems.push_back(new MenuSubItem(item.c_str(), kMenuActionCommand, style, shortcut, enabled));
		}

		item.clear();
	}
}
Beispiel #20
0
bool DownloadDialog::selectDirectories() {
	if (Networking::Connection::isLimited()) {
		MessageDialog alert(_("It looks like your connection is limited. "
			"Do you really want to download files with it?"), _("Yes"), _("No"));
		if (alert.runModal() != GUI::kMessageOK)
			return false;
	}

	//first user should select remote directory to download
	if (_remoteBrowser->runModal() <= 0)
		return false;

	Cloud::StorageFile remoteDirectory = _remoteBrowser->getResult();

	//now user should select local directory to download into
	if (_browser->runModal() <= 0)
		return false;

	Common::FSNode dir(_browser->getResult());
	Common::FSList files;
	if (!dir.getChildren(files, Common::FSNode::kListAll)) {
		MessageDialog alert(_("ScummVM couldn't open the specified directory!"));
		alert.runModal();
		return false;
	}

	//check that there is no file with the remote directory's name in the local one
	for (Common::FSList::iterator i = files.begin(); i != files.end(); ++i) {
		if (i->getName().equalsIgnoreCase(remoteDirectory.name())) {
			//if there is, ask user whether it's OK
			if (!i->isDirectory()) {
				GUI::MessageDialog alert(_("Cannot create a directory to download - the specified directory has a file with the same name."), _("OK"));
				alert.runModal();
				return false;
			}
			GUI::MessageDialog alert(
				Common::String::format(_("The \"%s\" already exists in the specified directory.\nDo you really want to download files into that directory?"), remoteDirectory.name().c_str()),
				_("Yes"),
				_("No")
				);
			if (alert.runModal() != GUI::kMessageOK)
				return false;
			break;
		}
	}

	//make a local path
	Common::String localPath = dir.getPath();

	//simple heuristic to determine which path separator to use
	if (localPath.size() && localPath.lastChar() != '/' && localPath.lastChar() != '\\') {
		int backslashes = 0;
		for (uint32 i = 0; i < localPath.size(); ++i)
			if (localPath[i] == '/')
				--backslashes;
			else if (localPath[i] == '\\')
				++backslashes;

		if (backslashes > 0)
			localPath += '\\' + remoteDirectory.name();
		else
			localPath += '/' + remoteDirectory.name();
	} else {
		localPath += remoteDirectory.name();
	}

	CloudMan.startDownload(remoteDirectory.path(), localPath);
	CloudMan.setDownloadTarget(this);
	_localDirectory = localPath;
	return true;
}
Beispiel #21
0
bool WintermuteEngine::getGameInfo(const Common::FSList &fslist, Common::String &name, Common::String &caption) {
	bool retVal = false;
	caption = name = "(invalid)";
	Common::SeekableReadStream *stream = NULL;
	// Quick-fix, instead of possibly breaking the persistence-system, let's just roll with it
	BaseFileManager *fileMan = new BaseFileManager(Common::UNK_LANG);
	fileMan->registerPackages(fslist);
	stream = fileMan->openFile("startup.settings", false, false);

	// The process is as follows: Check the "GAME=" tag in startup.settings, to decide where the
	// game-settings are (usually "default.game"), then look into the game-settings to find
	// the NAME = and CAPTION = tags, to use them to generate a gameid and extras-field

	Common::String settingsGameFile = "default.game";
	// If the stream-open failed, lets at least attempt to open the default game file afterwards
	// so, we don't call it a failure yet.
	if (stream) {
		while (!stream->eos() && !stream->err()) {
			Common::String line = stream->readLine();
			line.trim(); // Get rid of indentation
			// Expect "SETTINGS {" or comment, or empty line
			if (line.size() == 0 || line[0] == ';' || (line.contains("{"))) {
				continue;
			} else {
				// We are looking for "GAME ="
				Common::StringTokenizer token(line, "=");
				Common::String key = token.nextToken();
				Common::String value = token.nextToken();
				if (value.size() == 0) {
					continue;
				}
				if (value[0] == '\"') {
					value.deleteChar(0);
				} else {
					continue;
				}
				if (value.lastChar() == '\"') {
					value.deleteLastChar();
				}
				if (key == "GAME") {
					settingsGameFile = value;
					break;
				}
			}
		}
	}

	delete stream;
	stream = fileMan->openFile(settingsGameFile, false, false);
	if (stream) {
		// We do some manual parsing here, as the engine needs gfx to be initalized to do that.
		while (!stream->eos() && !stream->err()) {
			Common::String line = stream->readLine();
			line.trim(); // Get rid of indentation
			// Expect "GAME {" or comment, or empty line
			if (line.size() == 0 || line[0] == ';' || (line.contains("{"))) {
				continue;
			} else {
				Common::StringTokenizer token(line, "=");
				Common::String key = token.nextToken();
				Common::String value = token.nextToken();
				if (value.size() == 0) {
					continue;
				}
				if (value[0] == '\"') {
					value.deleteChar(0);
				} else {
					continue;    // not a string
				}
				if (value.lastChar() == '\"') {
					value.deleteLastChar();
				}
				if (key == "NAME") {
					retVal = true;
					name = value;
				} else if (key == "CAPTION") {
					retVal = true;
					caption = value;
				}
			}
		}
		delete stream;
	}
	delete fileMan;
	BaseEngine::destroy();
	return retVal;
}
Beispiel #22
0
/**
 * Load Sprite Bank
 */
int AnimationManager::loadSpriteBank(int idx, const Common::String &filename) {
	int result = 0;
	Bank[idx]._loadedFl = true;
	Bank[idx]._filename = filename;

	byte *fileDataPtr = _vm->_fileIO->loadFile(filename);

	Bank[idx]._fileHeader = 0;
	if (fileDataPtr[1] == 'L' && fileDataPtr[2] == 'E')
		Bank[idx]._fileHeader = 1;
	else if (fileDataPtr[1] == 'O' && fileDataPtr[2] == 'R')
		Bank[idx]._fileHeader = 2;

	if (!Bank[idx]._fileHeader) {
		_vm->_globals->freeMemory(fileDataPtr);
		Bank[idx]._loadedFl = false;
		result = -1;
	}

	Bank[idx]._data = fileDataPtr;

	int objectDataIdx = 0;
	for(objectDataIdx = 0; objectDataIdx <= 249; objectDataIdx++) {
		int width = _vm->_objectsMan->getWidth(fileDataPtr, objectDataIdx);
		int height = _vm->_objectsMan->getHeight(fileDataPtr, objectDataIdx);
		if (!width && !height)
			break;
	}

	if (objectDataIdx > 249) {
		_vm->_globals->freeMemory(fileDataPtr);
		Bank[idx]._loadedFl = false;
		result = -2;
	}
	Bank[idx]._objDataIdx = objectDataIdx;

	Common::String ofsFilename = Bank[idx]._filename;
	char ch;
	do {
		ch = ofsFilename.lastChar();
		ofsFilename.deleteLastChar();
	} while (ch != '.');
	ofsFilename += ".OFS";

	Common::File f;
	if (f.exists(ofsFilename)) {
		byte *ofsData = _vm->_fileIO->loadFile(ofsFilename);
		byte *curOfsData = ofsData;
		for (int objIdx = 0; objIdx < Bank[idx]._objDataIdx; ++objIdx, curOfsData += 8) {
			int x1 = READ_LE_INT16(curOfsData);
			int y1 = READ_LE_INT16(curOfsData + 2);
			int x2 = READ_LE_INT16(curOfsData + 4);
			int y2 = READ_LE_INT16(curOfsData + 6);

			_vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x1, y1, 0);
			if (Bank[idx]._fileHeader == 2)
				_vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x2, y2, 1);
		}

		_vm->_globals->freeMemory(ofsData);
		result = 0;
	}

	return result;
}