Beispiel #1
0
void NDSFile::readNames(Common::SeekableReadStream &nds, uint32 offset, uint32 length) {
	if (!nds.seek(offset + 8))
		throw Common::Exception(Common::kSeekError);

	uint32 index = 0;
	while (((uint32) nds.pos()) < (offset + length)) {
		Resource res;

		byte nameLength = nds.readByte();

		Common::UString name;

		name.readFixedASCII(nds, nameLength);
		name.tolower();

		res.name  = setFileType(name, kFileTypeNone);
		res.type  = getFileType(name);
		res.index = index++;

		_resources.push_back(res);
	}

	while (!_resources.empty() && _resources.back().name.empty())
		_resources.pop_back();
}
Beispiel #2
0
void ResourceManager::addResource(Resource &resource, Common::UString name, ChangeID &change) {
	name.tolower();
	if (name.empty())
		return;

	// Normalize resource type *sigh*
	if      (resource.type == kFileTypeQST2)
		resource.type = kFileTypeQST;
	else if (resource.type == kFileTypeMDX2)
		resource.type = kFileTypeMDX;
	else if (resource.type == kFileTypeTXB2)
		resource.type = kFileTypeTXB;
	else if (resource.type == kFileTypeCRE)
		resource.type = kFileTypeBTC;

	// Resolve the type aliases
	std::map<FileType, FileType>::const_iterator alias = _typeAliases.find(resource.type);
	if (alias != _typeAliases.end())
		resource.type = alias->second;

	ResourceMap::iterator resTypeMap = _resources.find(name);
	if (resTypeMap == _resources.end()) {
		// We don't yet have a resource with this name, create a new type map for it

		std::pair<ResourceMap::iterator, bool> result;

		result = _resources.insert(std::make_pair(name, ResourceTypeMap()));

		resTypeMap = result.first;
	}

	ResourceTypeMap::iterator resList = resTypeMap->second.find(resource.type);
	if (resList == resTypeMap->second.end()) {
		// We don't yet have a resource with that name and type, create a new resource list for it

		std::pair<ResourceTypeMap::iterator, bool> result;

		result = resTypeMap->second.insert(std::make_pair(resource.type, ResourceList()));

		resList = result.first;
	}

	// Add the resource to the list
	resList->second.push_back(resource);

	// And sort the list by priority
	resList->second.sort();

	// Remember the resource in the change set
	change._change->resources.push_back(ResourceChange());
	change._change->resources.back().nameIt = resTypeMap;
	change._change->resources.back().typeIt = resList;
	change._change->resources.back().resIt  = --resList->second.end();
}
Beispiel #3
0
FileType FileTypeManager::getFileType(const Common::UString &path) {
    buildExtensionLookup();

    Common::UString ext = Common::FilePath::getExtension(path);
    ext.tolower();

    ExtensionLookup::const_iterator t = _extensionLookup.find(ext);
    if (t != _extensionLookup.end())
        return t->second->type;

    return kFileTypeNone;
}
Beispiel #4
0
void ResourceManager::checkHashCollision(const Resource &resource, ResourceMap::const_iterator resList) {
	if (resource.name.empty() || resList->second.empty())
		return;

	Common::UString newName = TypeMan.setFileType(resource.name, resource.type);
	newName.tolower();

	for (ResourceList::const_iterator r = resList->second.begin(); r != resList->second.end(); ++r) {
		if (r->name.empty())
			continue;

		Common::UString oldName = TypeMan.setFileType(r->name, r->type);
		oldName.tolower();

		if (oldName != newName) {
			warning("ResourceManager: Found hash collision: 0x%016llX (\"%s\" and \"%s\")",
					(unsigned long long) getHash(oldName), oldName.c_str(), newName.c_str());
			return;
		}
	}
}
Beispiel #5
0
void VISFile::load(Common::SeekableReadStream &vis) {
	clear();

	Common::StreamTokenizer tokenizer(Common::StreamTokenizer::kRuleIgnoreAll);
	tokenizer.addSeparator(' ');
	tokenizer.addChunkEnd('\n');
	tokenizer.addIgnore('\r');

	for (;;) {
		std::vector<Common::UString> strings;
		tokenizer.getTokens(vis, strings);

		// Make sure we don't get any empty lines
		while (!vis.eos() && !vis.err() && strings.empty()) {
			tokenizer.nextChunk(vis);
			tokenizer.getTokens(vis, strings);
		}

		if (vis.eos() || vis.err())
			break;

		if ((strings.size() == 1) && (strings[0] == "[Adjacent]"))
			// TODO: New in Jade Empire
			break;

		if (strings.size() > 2)
			throw Common::Exception("Malformed VIS file");

		Common::UString room = strings[0];
		std::vector<Common::UString> visibilityArray;

		int roomCount = 0;
		if (strings.size() > 1)
			roomCount = atoi(strings[1].c_str());

		room.tolower();

		int realRoomCount = 0;

		visibilityArray.reserve(roomCount);
		while (!vis.eos() && !vis.err()) {
			uint32 lineStart = vis.pos();

			tokenizer.nextChunk(vis);

			if (((char) vis.readByte()) != ' ') {
				// Not indented => new room

				vis.seek(lineStart);
				break;
			}

			tokenizer.getTokens(vis, strings);

			if (strings.size() != 1) {
				// More than one token => new room

				vis.seek(lineStart);
				break;
			}

			visibilityArray.push_back(strings[0]);
			realRoomCount++;
		}

		if (roomCount != realRoomCount)
			// Thanks, BioWare! -.-
			warning("Malformed VIS file. Wanted %d rooms, got %d?!?", roomCount, realRoomCount);

		if (!visibilityArray.empty())
			_map[room] = visibilityArray;
	}
}
Beispiel #6
0
inline uint64 ResourceManager::getHash(Common::UString name) const {
	name.tolower();

	return Common::hashString(name, _hashAlgo);
}