예제 #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();
}
예제 #2
0
Common::UString GFFStruct::readLabel(Common::SeekableReadStream &gff, uint32 index) const {
	gff.seek(_parent->_header.labelOffset + index * 16);

	Common::UString label;
	label.readFixedASCII(gff, 16);

	return label;
}
예제 #3
0
파일: ndsrom.cpp 프로젝트: DeejStar/xoreos
bool NDSFile::isNDS(Common::SeekableReadStream &stream) {
	if (!stream.seek(0))
		return false;

	Common::UString gameName;
	gameName.readFixedASCII(stream, 12);
	if (gameName != "SONICCHRON") // Should be the only game we will accept.
		return false;

	if (!stream.seek(0x40))
		return false;

	return true;
}
예제 #4
0
bool ModelNode_NWN2::loadSkin(Model_NWN2::ParserContext &ctx) {
	if (ctx.mdb->readUint32BE() != kSkinID)
		throw Common::Exception("Packet signatures do not match");

	uint32 packetSize = ctx.mdb->readUint32LE();

	_name.readFixedASCII(*ctx.mdb, 32);

	// Skipping lower level of detail models
	if (_name.endsWith("_L01") || _name.endsWith("_L02"))
		return false;

	Common::UString skeletonName;
	skeletonName.readFixedASCII(*ctx.mdb, 32);

	Common::UString diffuseMap, normalMap, tintMap, glowMap;
	diffuseMap.readFixedASCII(*ctx.mdb, 32);
	 normalMap.readFixedASCII(*ctx.mdb, 32);
	   tintMap.readFixedASCII(*ctx.mdb, 32);
	   glowMap.readFixedASCII(*ctx.mdb, 32);

	_diffuse [0] = ctx.mdb->readIEEEFloatLE();
	_diffuse [1] = ctx.mdb->readIEEEFloatLE();
	_diffuse [2] = ctx.mdb->readIEEEFloatLE();
	_specular[0] = ctx.mdb->readIEEEFloatLE();
	_specular[1] = ctx.mdb->readIEEEFloatLE();
	_specular[2] = ctx.mdb->readIEEEFloatLE();

	float  specularPower = ctx.mdb->readIEEEFloatLE();
	float  specularValue = ctx.mdb->readIEEEFloatLE();
	uint32 textureFlags  = ctx.mdb->readUint32LE();

	uint32 vertexCount = ctx.mdb->readUint32LE();
	uint32 faceCount   = ctx.mdb->readUint32LE();

	if ((vertexCount == 0) || (faceCount == 0))
		return false;

	std::vector<Common::UString> textures;
	textures.push_back(diffuseMap);

	uint32 textureCount = textures.size();

	loadTextures(textures);
	if (!createFaces(faceCount))
		return false;


	// Read vertex coordinates

	std::vector<float> vX, vY, vZ;
	vX.resize(vertexCount);
	vY.resize(vertexCount);
	vZ.resize(vertexCount);

	std::vector<float> tX, tY, tZ;
	tX.resize(vertexCount);
	tY.resize(vertexCount);
	tZ.resize(vertexCount);

	for (uint32 i = 0; i < vertexCount; i++) {
		vX[i] = ctx.mdb->readIEEEFloatLE();
		vY[i] = ctx.mdb->readIEEEFloatLE();
		vZ[i] = ctx.mdb->readIEEEFloatLE();

		ctx.mdb->skip(3 * 4); // Normals

		ctx.mdb->skip(4 * 4); // Bone weights
		ctx.mdb->skip(4 * 1); // Bone indices

		ctx.mdb->skip(3 * 4); // Tangents
		ctx.mdb->skip(3 * 4); // Binormals

		tX[i] = ctx.mdb->readIEEEFloatLE();
		tY[i] = ctx.mdb->readIEEEFloatLE();
		tZ[i] = ctx.mdb->readIEEEFloatLE();

		ctx.mdb->skip(4); // Bone count
	}


	// Read faces

	for (uint32 i = 0; i < faceCount; i++) {
		const uint16 v1 = ctx.mdb->readUint16LE();
		const uint16 v2 = ctx.mdb->readUint16LE();
		const uint16 v3 = ctx.mdb->readUint16LE();

		// Vertex coordinates
		_vX[3 * i + 0] = v1 < vX.size() ? vX[v1] : 0.0;
		_vY[3 * i + 0] = v1 < vY.size() ? vY[v1] : 0.0;
		_vZ[3 * i + 0] = v1 < vZ.size() ? vZ[v1] : 0.0;
		_boundBox.add(_vX[3 * i + 0], _vY[3 * i + 0], _vZ[3 * i + 0]);

		_vX[3 * i + 1] = v2 < vX.size() ? vX[v2] : 0.0;
		_vY[3 * i + 1] = v2 < vY.size() ? vY[v2] : 0.0;
		_vZ[3 * i + 1] = v2 < vZ.size() ? vZ[v2] : 0.0;
		_boundBox.add(_vX[3 * i + 1], _vY[3 * i + 1], _vZ[3 * i + 1]);

		_vX[3 * i + 2] = v3 < vX.size() ? vX[v3] : 0.0;
		_vY[3 * i + 2] = v3 < vY.size() ? vY[v3] : 0.0;
		_vZ[3 * i + 2] = v3 < vZ.size() ? vZ[v3] : 0.0;
		_boundBox.add(_vX[3 * i + 2], _vY[3 * i + 2], _vZ[3 * i + 2]);

		// Texture coordinates
		for (uint32 t = 0; t < textureCount; t++) {
			_tX[3 * textureCount * i + 3 * t + 0] = v1 < tX.size() ? tX[v1] : 0.0;
			_tY[3 * textureCount * i + 3 * t + 0] = v1 < tY.size() ? tY[v1] : 0.0;

			_tX[3 * textureCount * i + 3 * t + 1] = v2 < tX.size() ? tX[v2] : 0.0;
			_tY[3 * textureCount * i + 3 * t + 1] = v2 < tY.size() ? tY[v2] : 0.0;

			_tX[3 * textureCount * i + 3 * t + 2] = v3 < tX.size() ? tX[v3] : 0.0;
			_tY[3 * textureCount * i + 3 * t + 2] = v3 < tY.size() ? tY[v3] : 0.0;
		}

	}

	createCenter();

	_render = true;

	return true;
}
예제 #5
0
Common::UString GFFStruct::getString(const Common::UString &field,
                                        const Common::UString &def) const {
	load();

	const Field *f = getField(field);
	if (!f)
		return def;

	if (f->type == kFieldTypeExoString) {
		Common::SeekableReadStream &data = getData(*f);

		uint32 length = data.readUint32LE();

		Common::UString str;
		str.readFixedASCII(data, length);
		return str;
	}

	if (f->type == kFieldTypeResRef) {
		Common::SeekableReadStream &data = getData(*f);

		uint32 length = data.readByte();

		Common::UString str;
		str.readFixedASCII(data, length);
		return str;
	}

	if ((f->type == kFieldTypeByte  ) ||
	    (f->type == kFieldTypeUint16) ||
	    (f->type == kFieldTypeUint32) ||
	    (f->type == kFieldTypeUint64)) {

		return Common::UString::sprintf("%lu", getUint(field));
	}

	if ((f->type == kFieldTypeChar  ) ||
	    (f->type == kFieldTypeSint16) ||
	    (f->type == kFieldTypeSint32) ||
	    (f->type == kFieldTypeSint64)) {

		return Common::UString::sprintf("%ld", getSint(field));
	}

	if ((f->type == kFieldTypeFloat) ||
	    (f->type == kFieldTypeDouble)) {

		return Common::UString::sprintf("%lf", getDouble(field));
	}

	if (f->type == kFieldTypeVector) {
		float x, y, z;

		getVector(field, x, y, z);
		return Common::UString::sprintf("%f/%f/%f", x, y, z);
	}

	if (f->type == kFieldTypeOrientation) {
		float a, b, c, d;

		getOrientation(field, a, b, c, d);
		return Common::UString::sprintf("%f/%f/%f/%f", a, b, c, d);
	}

	throw Common::Exception("Field is not a string(able) type");
}
예제 #6
0
void Model_Witcher::load(ParserContext &ctx) {
	if (ctx.mdb->readByte() != 0) {
		ctx.mdb->seek(0);

		Common::UString type;
		type.readASCII(*ctx.mdb);
		if (type.beginsWith("binarycompositemodel"))
			throw Common::Exception("TODO: binarycompositemodel");

		throw Common::Exception("Not a The Witcher MDB file");
	}

	ctx.mdb->seek(4);

	ctx.fileVersion = ctx.mdb->readUint16LE();

	ctx.mdb->skip(10);

	ctx.modelDataSize = ctx.mdb->readUint32LE();

	ctx.mdb->skip(4);

	ctx.offModelData = 32;

	if (ctx.fileVersion == 133) {
		ctx.offRawData  = ctx.mdb->readUint32LE() + ctx.offModelData;
		ctx.rawDataSize = ctx.mdb->readUint32LE();
		ctx.offTexData  = ctx.offModelData;
		ctx.texDatasize = 0;
	} else {
		ctx.offRawData  = ctx.offModelData;
		ctx.rawDataSize = 0;
		ctx.offTexData  = ctx.mdb->readUint32LE() + ctx.offModelData;
		ctx.texDatasize = ctx.mdb->readUint32LE();
	}

	ctx.mdb->skip(8);

	_name.readFixedASCII(*ctx.mdb, 64);

	uint32 offsetRootNode = ctx.mdb->readUint32LE();

	ctx.mdb->skip(32);

	byte type = ctx.mdb->readByte();

	ctx.mdb->skip(3);

	ctx.mdb->skip(48);

	float firstLOD = ctx.mdb->readIEEEFloatLE();
	float lastLOD  = ctx.mdb->readIEEEFloatLE();

	ctx.mdb->skip(16);

	Common::UString detailMap;
	detailMap.readFixedASCII(*ctx.mdb, 64);

	ctx.mdb->skip(4);

	float scale = ctx.mdb->readIEEEFloatLE();

	Common::UString superModel;
	superModel.readFixedASCII(*ctx.mdb, 64);

	ctx.mdb->skip(16);

	newState(ctx);

	ModelNode_Witcher *rootNode = new ModelNode_Witcher(*this);
	ctx.nodes.push_back(rootNode);

	ctx.mdb->seek(ctx.offModelData + offsetRootNode);
	rootNode->load(ctx);

	addState(ctx);
}