void Geometry::readVcNative(ifstream &dff)
{
	HeaderInfo header;

	READ_HEADER(CHUNK_STRUCT); /* wrong size */
	dff.seekg(4, ios::cur); /* platform */

	uint32 index = 0;
	for (uint32 i = 0; i < splits.size(); i++) {
		uint32 splitSize = ReadUInt32(dff);
		bool isNotActor = ReadInt32(dff);
		uint32 nextSplit = splitSize + dff.tellg();
		if (isNotActor)
			dff.seekg(16, ios::cur);
		bool isLast = false;
		while (!isLast) {
			if (!isNotActor)
				dff.seekg(48, ios::cur);

			/* vertices */
			dff.seekg(14, ios::cur);
			uint32 numVertices = ReadUInt8(dff);
			dff.seekg(1, ios::cur);
			for (uint32 j = 0; j < numVertices; j++) {
				vertices.push_back(ReadFloat32(dff));
				vertices.push_back(ReadFloat32(dff));
				vertices.push_back(ReadFloat32(dff));
				splits[i].indices.push_back(index++);
			}
			uint32 padding;
			if ((padding = numVertices*3*sizeof(float32) % 16))
				dff.seekg(16-padding, ios::cur);

			/* texture coordinates */
			dff.seekg(16, ios::cur);
			if (flags & FLAGS_TEXTURED) {
				for (uint32 j = 0; j < numVertices; j++) {
					texCoords1.push_back(ReadFloat32(dff));
					texCoords1.push_back(ReadFloat32(dff));
				}
			} else {
				dff.seekg(numVertices*2*sizeof(float32),
				          ios::cur);
			}
			if ((padding = numVertices*2*sizeof(float32) % 16))
				dff.seekg(16-padding, ios::cur);

			/* vertex colors */
			dff.seekg(16, ios::cur);
			if (flags & FLAGS_PRELIT) {
				for (uint32 j = 0; j < numVertices; j++) {
					vertexColors.push_back(ReadUInt8(dff));
					vertexColors.push_back(ReadUInt8(dff));
					vertexColors.push_back(ReadUInt8(dff));
					vertexColors.push_back(ReadUInt8(dff));
				}
			} else {
				dff.seekg(numVertices*4*sizeof(uint8),
				          ios::cur);
			}
			if ((padding = numVertices*4*sizeof(uint8) % 16))
				dff.seekg(16-padding, ios::cur);

			/* normals */
			dff.seekg(16, ios::cur);
			if (flags & FLAGS_NORMALS) {
				int8 normal[3];
				for (uint32 j = 0; j < numVertices; j++) {
					dff.read(reinterpret_cast <char *>
						 (normal), 3*sizeof(int8));
					normals.push_back(normal[0] *
					                  NORMALSCALE);
					normals.push_back(normal[1] *
					                  NORMALSCALE);
					normals.push_back(normal[2] *
					                  NORMALSCALE);
				}
			} else {
				dff.seekg(numVertices*3*sizeof(int8),
				          ios::cur);
			}
			if ((padding = numVertices*3*sizeof(int8) % 16))
				dff.seekg(16-padding, ios::cur);

			dff.seekg(11, ios::cur);
			isLast = (ReadInt8(dff) == 0x11);
			/* remove last to vertices if not last block */
			if (!isLast) {
				uint32 size = vertices.size();
				vertices.resize(size-2*3);
				size = splits[i].indices.size();
				splits[i].indices.resize(size-2);
				index -= 2;
				if (flags & FLAGS_TEXTURED) {
					size = texCoords1.size();
					texCoords1.resize(size-2*2);
				}
				if (flags & FLAGS_PRELIT) {
					size = vertexColors.size();
					vertexColors.resize(size-2*4);
				}
				if (flags & FLAGS_NORMALS) {
					size = normals.size();
					normals.resize(size-2*3);
				}
			}
			dff.seekg(4, ios::cur);
		}
		dff.seekg(nextSplit, ios::beg);
	}
}

void Geometry::readSaNative(ifstream &dff)
{
	HeaderInfo header;

	READ_HEADER(CHUNK_STRUCT); /* wrong size */
	dff.seekg(4, ios::cur); /* platform */

	/* TODO: find out correct scale */
	float32 vertScale = 1.0f/128.0f;

	uint32 index = 0;
	for (uint32 i = 0; i < splits.size(); i++) {
		uint32 splitSize = ReadUInt32(dff);
		dff.seekg(4, ios::cur);
		uint32 nextSplit = splitSize + dff.tellg();

		uint32 start = dff.tellg();
		dff.seekg(4, ios::cur);
		uint32 vertexPos = ReadUInt32(dff);
		uint32 texCoordPos, vertexColorPos, normalPos;
		vertexPos = (vertexPos << 4) + start;
		if ((flags & FLAGS_TEXTURED) ||
		    (flags & FLAGS_TEXTURED2)) {
			dff.seekg(28, ios::cur);
			texCoordPos = ReadUInt32(dff);
			texCoordPos = (texCoordPos << 4) + start;
		}
		if (flags & FLAGS_PRELIT) {
			dff.seekg(28, ios::cur);
			vertexColorPos = ReadUInt32(dff);
			vertexColorPos = (vertexColorPos << 4) + start;
		}
		if (flags & FLAGS_NORMALS) {
			dff.seekg(28, ios::cur);
			normalPos = ReadUInt32(dff);
			normalPos = (normalPos << 4) + start;
		}

		uint32 numVertices = splits[i].indices.size();
		splits[i].indices.resize(0);

		/* TODO: read larger blocks */
		dff.seekg(vertexPos, ios::beg);
		int16 vertex[4];
		for (uint32 j = 0; j < numVertices; j++) {
			dff.read(reinterpret_cast <char *>
				 (vertex), 4*sizeof(int16));
			vertices.push_back(vertex[0] * vertScale);
			vertices.push_back(vertex[1] * vertScale);
			vertices.push_back(vertex[2] * vertScale);
			int32 flag = vertex[3] & 0xffff; /* sign trouble */
			if (flag == 0x8000)
				splits[i].indices.push_back(index-1);
			splits[i].indices.push_back(index++);
		}
		if (flags & FLAGS_TEXTURED) {
			dff.seekg(texCoordPos, ios::beg);
			int16 texCoord[2];
			for (uint32 j = 0; j < numVertices; j++) {
				dff.read(reinterpret_cast <char *>
					 (texCoord), 2*sizeof(int16));
				texCoords1.push_back(texCoord[0] * UVSCALE);
				texCoords1.push_back(texCoord[1] * UVSCALE);
			}
		/* TODO: probably incorrect */
		} else if (flags & FLAGS_TEXTURED2) {
			dff.seekg(texCoordPos, ios::beg);
			int16 texCoord[4];
			for (uint32 j = 0; j < numVertices; j++) {
				dff.read(reinterpret_cast <char *>
					 (texCoord), 4*sizeof(int16));
				texCoords1.push_back(texCoord[0] * UVSCALE);
				texCoords1.push_back(texCoord[1] * UVSCALE);
				texCoords2.push_back(texCoord[2] * UVSCALE);
				texCoords2.push_back(texCoord[3] * UVSCALE);
			}
		}
		if (flags & FLAGS_PRELIT) {
			dff.seekg(vertexColorPos, ios::beg);
			int8 color[8];
			for (uint32 j = 0; j < numVertices; j++) {
				dff.read(reinterpret_cast <char *>
					 (color), 4*sizeof(int8));
				vertexColors.push_back(color[0]);
				vertexColors.push_back(color[2]);
				vertexColors.push_back(color[4]);
				vertexColors.push_back(color[6]);
				nightColors.push_back(color[1]);
				nightColors.push_back(color[3]);
				nightColors.push_back(color[5]);
				nightColors.push_back(color[7]);
			}
		}
		if (flags & FLAGS_NORMALS) {
			dff.seekg(normalPos, ios::beg);
			int8 normal[4];
			for (uint32 j = 0; j < numVertices; j++) {
				dff.read(reinterpret_cast <char *>
					 (normal), 4*sizeof(int8));
				normals.push_back(normal[0] * NORMALSCALE);
				normals.push_back(normal[1] * NORMALSCALE);
				normals.push_back(normal[2] * NORMALSCALE);
			}
		}

		dff.seekg(nextSplit);
	}
}

bool Geometry::isSaCompression(ifstream &dff)
{
	HeaderInfo header;

	header.read(dff);
	dff.seekg(8, ios::cur);
	uint32 isNotActor = ReadUInt32(dff);
	dff.seekg(-24, ios::cur);
	/* this seems to be right; update: it's not */
	return (header.version == SA && !isNotActor);
}

