Example #1
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;
}
Example #2
0
Common::StringArray DefaultSaveFileManager::listSavefiles(const Common::String &pattern) {
	// Assure the savefile name cache is up-to-date.
	assureCached(getSavePath());
	if (getError().getCode() != Common::kNoError)
		return Common::StringArray();

	Common::HashMap<Common::String, bool> locked;
	for (Common::StringArray::const_iterator i = _lockedFiles.begin(), end = _lockedFiles.end(); i != end; ++i) {
		locked[*i] = true;
	}

	Common::StringArray results;
	for (SaveFileCache::const_iterator file = _saveFileCache.begin(), end = _saveFileCache.end(); file != end; ++file) {
		if (!locked.contains(file->_key) && file->_key.matchString(pattern, true)) {
			results.push_back(file->_key);
		}
	}
	return results;
}
Example #3
0
bool DefaultSaveFileManager::removeSavefile(const Common::String &filename) {
	// Assure the savefile name cache is up-to-date.
	assureCached(getSavePath());
	if (getError().getCode() != Common::kNoError)
		return false;
	
#ifdef USE_LIBCURL
	// Update file's timestamp
	Common::HashMap<Common::String, uint32> timestamps = loadTimestamps();
	Common::HashMap<Common::String, uint32>::iterator it = timestamps.find(filename);
	if (it != timestamps.end()) {
		timestamps.erase(it);
		saveTimestamps(timestamps);
	}
#endif

	// Obtain node if exists.
	SaveFileCache::const_iterator file = _saveFileCache.find(filename);
	if (file == _saveFileCache.end()) {
		return false;
	} else {
		const Common::FSNode fileNode = file->_value;
		// Remove from cache, this invalidates the 'file' iterator.
		_saveFileCache.erase(file);
		file = _saveFileCache.end();

		// FIXME: remove does not exist on all systems. If your port fails to
		// compile because of this, please let us know (scummvm-devel).
		// There is a nicely portable workaround, too: Make this method overloadable.
		if (remove(fileNode.getPath().c_str()) != 0) {
#ifndef _WIN32_WCE
			if (errno == EACCES)
				setError(Common::kWritePermissionDenied, "Search or write permission denied: "+fileNode.getName());

			if (errno == ENOENT)
				setError(Common::kPathDoesNotExist, "removeSavefile: '"+fileNode.getName()+"' does not exist or path is invalid");
#endif
			return false;
		} else {
			return true;
		}
	}
}
Example #4
0
void DefaultSaveFileManager::saveTimestamps(Common::HashMap<Common::String, uint32> &timestamps) {
	Common::DumpFile f;
	Common::String filename = concatWithSavesPath(TIMESTAMPS_FILENAME);
	if (!f.open(filename, true)) {
		warning("DefaultSaveFileManager: failed to open '%s' file to save timestamps", filename.c_str());
		return;
	}

	for (Common::HashMap<Common::String, uint32>::iterator i = timestamps.begin(); i != timestamps.end(); ++i) {
		Common::String data = i->_key + Common::String::format(" %u\n", i->_value);
		if (f.write(data.c_str(), data.size()) != data.size()) {
			warning("DefaultSaveFileManager: failed to write timestamps data into '%s'", filename.c_str());
			return;
		}
	}

	f.flush();
	f.finalize();
	f.close();
}
Example #5
0
Common::HashMap<Common::String, Score *> *DirectorEngine::scanMovies(const Common::String &folder) {
    Common::FSNode directory(folder);
    Common::FSList movies;
    const char *sharedMMMname;

    if (getPlatform() == Common::kPlatformWindows)
        sharedMMMname = "SHARDCST.MMM";
    else
        sharedMMMname = "Shared Cast*";


    Common::HashMap<Common::String, Score *> *nameMap = new Common::HashMap<Common::String, Score *>();
    if (!directory.getChildren(movies, Common::FSNode::kListFilesOnly))
        return nameMap;

    if (!movies.empty()) {
        for (Common::FSList::const_iterator i = movies.begin(); i != movies.end(); ++i) {
            debugC(2, kDebugLoading, "File: %s", i->getName().c_str());

            if (Common::matchString(i->getName().c_str(), sharedMMMname, true)) {
                _sharedCastFile = i->getName();
                continue;
            }

            Archive *arc = createArchive();

            warning("name: %s", i->getName().c_str());
            arc->openFile(i->getName());
            Score *sc = new Score(this, arc);
            nameMap->setVal(sc->getMacName(), sc);

            debugC(2, kDebugLoading, "Movie name: \"%s\"", sc->getMacName().c_str());
        }
    }

    return nameMap;
}
Example #6
0
bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale) {
	if (!_system->hasFeature(OSystem::kFeatureCursorPalette))
		return true;

	// Try to locate the specified file among all loaded bitmaps
	const Graphics::Surface *cursor = _bitmaps[filename];
	if (!cursor)
		return false;

#ifdef USE_RGB_COLOR
	_cursorFormat.bytesPerPixel = 1;
	_cursorFormat.rLoss = _cursorFormat.gLoss = _cursorFormat.bLoss = _cursorFormat.aLoss = 8;
	_cursorFormat.rShift = _cursorFormat.gShift = _cursorFormat.bShift = _cursorFormat.aShift = 0;
#endif

	// Set up the cursor parameters
	_cursorHotspotX = hotspotX;
	_cursorHotspotY = hotspotY;
	_cursorTargetScale = scale;

	_cursorWidth = cursor->w;
	_cursorHeight = cursor->h;

	// Allocate a new buffer for the cursor
	delete[] _cursor;
	_cursor = new byte[_cursorWidth * _cursorHeight];
	assert(_cursor);
	memset(_cursor, 0xFF, sizeof(byte) * _cursorWidth * _cursorHeight);

	// the transparent color is 0xFF00FF
	const int colTransparent = _overlayFormat.RGBToColor(0xFF, 0, 0xFF);

	// Now, scan the bitmap. We have to convert it from 16 bit color mode
	// to 8 bit mode, and have to create a suitable palette on the fly.
	uint colorsFound = 0;
	Common::HashMap<int, int> colorToIndex;
	const OverlayColor *src = (const OverlayColor *)cursor->pixels;
	for (uint y = 0; y < _cursorHeight; ++y) {
		for (uint x = 0; x < _cursorWidth; ++x) {
			byte r, g, b;

			// Skip transparency
			if (src[x] == colTransparent)
				continue;

			_overlayFormat.colorToRGB(src[x], r, g, b);
			const int col = (r << 16) | (g << 8) | b;

			// If there is no entry yet for this color in the palette: Add one
			if (!colorToIndex.contains(col)) {
				const int index = colorsFound++;
				colorToIndex[col] = index;

				_cursorPal[index * 3 + 0] = r;
				_cursorPal[index * 3 + 1] = g;
				_cursorPal[index * 3 + 2] = b;

				if (colorsFound > MAX_CURS_COLORS) {
					warning("Cursor contains too many colors (%d, but only %d are allowed)", colorsFound, MAX_CURS_COLORS);
					return false;
				}
			}

			// Copy pixel from the 16 bit source surface to the 8bit target surface
			const int index = colorToIndex[col];
			_cursor[y * _cursorWidth + x] = index;
		}
		src += _cursorWidth;
	}

	_useCursor = true;
	_cursorPalSize = colorsFound;

	return true;
}
Example #7
0
void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse response) {
	_workingRequest = nullptr;
	if (_ignoreCallback)
		return;

	if (response.request) _date = response.request->date();

	Common::HashMap<Common::String, bool> localFileNotAvailableInCloud;
	for (Common::HashMap<Common::String, uint32>::iterator i = _localFilesTimestamps.begin(); i != _localFilesTimestamps.end(); ++i) {
		localFileNotAvailableInCloud[i->_key] = true;
	}

	//determine which files to download and which files to upload
	Common::Array<StorageFile> &remoteFiles = response.value;
	uint64 totalSize = 0;
	for (uint32 i = 0; i < remoteFiles.size(); ++i) {
		StorageFile &file = remoteFiles[i];
		if (file.isDirectory())
			continue;
		totalSize += file.size();
		if (file.name() == DefaultSaveFileManager::TIMESTAMPS_FILENAME)
			continue;

		Common::String name = file.name();
		if (!_localFilesTimestamps.contains(name)) {
			_filesToDownload.push_back(file);
		} else {
			localFileNotAvailableInCloud[name] = false;

			if (_localFilesTimestamps[name] == file.timestamp())
				continue;

			//we actually can have some files not only with timestamp < remote
			//but also with timestamp > remote (when we have been using ANOTHER CLOUD and then switched back)
			if (_localFilesTimestamps[name] > file.timestamp() || _localFilesTimestamps[name] == DefaultSaveFileManager::INVALID_TIMESTAMP)
				_filesToUpload.push_back(file.name());
			else
				_filesToDownload.push_back(file);
		}
	}

	CloudMan.setStorageUsedSpace(CloudMan.getStorageIndex(), totalSize);

	//upload files which are unavailable in cloud
	for (Common::HashMap<Common::String, bool>::iterator i = localFileNotAvailableInCloud.begin(); i != localFileNotAvailableInCloud.end(); ++i) {
		if (i->_key == DefaultSaveFileManager::TIMESTAMPS_FILENAME)
			continue;
		if (i->_value)
			_filesToUpload.push_back(i->_key);
	}

	debug(9, "\nSavesSyncRequest: download files:");
	for (uint32 i = 0; i < _filesToDownload.size(); ++i) {
		debug(9, "%s", _filesToDownload[i].name().c_str());
	}
	debug(9, "\nSavesSyncRequest: upload files:");
	for (uint32 i = 0; i < _filesToUpload.size(); ++i) {
		debug(9, "%s", _filesToUpload[i].c_str());
	}
	_totalFilesToHandle = _filesToDownload.size() + _filesToUpload.size();

	//start downloading files
	downloadNextFile();
}
Example #8
0
void dumpEveryResultAction(const Common::String &destFile) {
	Common::HashMap<Common::String, byte> count;
	Common::HashMap<Common::String, bool> fileAlreadyUsed;

	Common::DumpFile output;
	output.open(destFile);

	// Find scr files
	Common::ArchiveMemberList list;
	SearchMan.listMatchingMembers(list, "*.scr");

	for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
		Common::SeekableReadStream *stream = (*iter)->createReadStream();

		Common::String line = stream->readLine();
		trimCommentsAndWhiteSpace(&line);

		while (!stream->eos()) {
			if (line.matchString("*:add*", true)) {
				tryToDumpLine("add", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animplay*", true)) {
				tryToDumpLine("animplay", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animpreload*", true)) {
				tryToDumpLine("animpreload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animunload*", true)) {
				tryToDumpLine("animunload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:attenuate*", true)) {
				tryToDumpLine("attenuate", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:assign*", true)) {
				tryToDumpLine("assign", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:change_location*", true)) {
				tryToDumpLine("change_location", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:crossfade*", true) && !fileAlreadyUsed["add"]) {
				tryToDumpLine("crossfade", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:debug*", true)) {
				tryToDumpLine("debug", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:delay_render*", true)) {
				tryToDumpLine("delay_render", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:disable_control*", true)) {
				tryToDumpLine("disable_control", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:disable_venus*", true)) {
				tryToDumpLine("disable_venus", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:display_message*", true)) {
				tryToDumpLine("display_message", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:dissolve*", true)) {
				tryToDumpLine("dissolve", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:distort*", true)) {
				tryToDumpLine("distort", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:enable_control*", true)) {
				tryToDumpLine("enable_control", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:flush_mouse_events*", true)) {
				tryToDumpLine("flush_mouse_events", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:inventory*", true)) {
				tryToDumpLine("inventory", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:kill*", true)) {
				tryToDumpLine("kill", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:menu_bar_enable*", true)) {
				tryToDumpLine("menu_bar_enable", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:music*", true)) {
				tryToDumpLine("music", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:pan_track*", true)) {
				tryToDumpLine("pan_track", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:playpreload*", true)) {
				tryToDumpLine("playpreload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:preferences*", true)) {
				tryToDumpLine("preferences", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:quit*", true)) {
				tryToDumpLine("quit", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:random*", true)) {
				tryToDumpLine("random", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:region*", true)) {
				tryToDumpLine("region", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:restore_game*", true)) {
				tryToDumpLine("restore_game", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:rotate_to*", true)) {
				tryToDumpLine("rotate_to", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:save_game*", true)) {
				tryToDumpLine("save_game", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_partial_screen*", true)) {
				tryToDumpLine("set_partial_screen", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_screen*", true)) {
				tryToDumpLine("set_screen", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_venus*", true)) {
				tryToDumpLine("set_venus", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:stop*", true)) {
				tryToDumpLine("stop", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:streamvideo*", true)) {
				tryToDumpLine("streamvideo", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:syncsound*", true)) {
				tryToDumpLine("syncsound", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:timer*", true)) {
				tryToDumpLine("timer", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:ttytext*", true)) {
				tryToDumpLine("ttytext", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:universe_music*", true)) {
				tryToDumpLine("universe_music", line, &count, &fileAlreadyUsed, output);
			}

			line = stream->readLine();
			trimCommentsAndWhiteSpace(&line);
		}

		for (Common::HashMap<Common::String, bool>::iterator fileUsedIter = fileAlreadyUsed.begin(); fileUsedIter != fileAlreadyUsed.end(); ++fileUsedIter) {
			fileUsedIter->_value = false;
		}
	}

	output.close();
}