private static object ReadValue( BinaryReader inputReader, MemoryStream ms, bool isLittleEndian, ushort fieldType, int count, long baseOffset) { switch (fieldType) { case 1: { var valueOrOffset = inputReader.ReadUInt32(isLittleEndian); if (count == 1) { var value = inputReader.ReadByte(); var x = inputReader.ReadBytes(3); return value; } if (count < 4) { var value = inputReader.ReadBytes(count); if (count < 4) { var x = inputReader.ReadBytes(4 - count); } return value; } ms.Position = baseOffset + valueOrOffset; return inputReader.ReadBytes(count); } case 2: { if (count <= 4) { var value = inputReader.ReadString(count).Trim('\0'); if (count < 4) { inputReader.ReadBytes(4 - count); } return value; } var valueOrOffset = inputReader.ReadUInt32(isLittleEndian); ms.Position = baseOffset + valueOrOffset; return inputReader.ReadString(count).Trim('\0'); } case 3: { if (count == 1) { var value = inputReader.ReadUInt16(isLittleEndian); var x = inputReader.ReadUInt16(isLittleEndian); return value; } if (count == 2) { return inputReader.ReadUInt16Array(count, isLittleEndian); } var valueOrOffset = inputReader.ReadUInt32(isLittleEndian); ms.Position = baseOffset + valueOrOffset; return inputReader.ReadUInt16Array(count, isLittleEndian); } case 4: { if (count == 1) { return inputReader.ReadUInt32(isLittleEndian); } var valueOrOffset = inputReader.ReadUInt32(isLittleEndian); ms.Position = baseOffset + valueOrOffset; return inputReader.ReadUInt32Array(count, isLittleEndian); } case 5: { var valueOrOffset = inputReader.ReadUInt32(isLittleEndian); ms.Position = baseOffset + valueOrOffset; if (count == 1) { var nominator = inputReader.ReadUInt32(isLittleEndian); var denominator = inputReader.ReadUInt32(isLittleEndian); return (double)nominator / denominator; } throw new NotImplementedException(); } case 10: { var valueOrOffset = inputReader.ReadInt32(isLittleEndian); ms.Position = baseOffset + valueOrOffset; if (count == 1) { var nominator = inputReader.ReadInt32(isLittleEndian); var denominator = inputReader.ReadInt32(isLittleEndian); return (double)nominator / denominator; } throw new NotImplementedException(); } } throw new NotImplementedException(); }
/// <summary> /// Reads a <see cref="WordTexture"/> /// </summary> /// <param name="br">The <see cref="BinaryReader"/> used to read the <see cref="WordTexture"/></param> /// <returns>A <see cref="WordTexture"/></returns> public static WordTexture Read(BinaryReader br) { var ret = new WordTexture { Pixels = new ushort[256][] }; for (var i = 0; i < 256; i++) { ret.Pixels[i] = br.ReadUInt16Array(256); } return ret; }
// Private Methods private void Read(BinaryReader reader) { _id = reader.ReadUInt32(); _flags = reader.ReadUInt32(); for (int i = 16; i < 31; i++) { if (BitHelper.IsBitSet(_flags, i)) { switch (i) { case 16: _color1 = Color.FromArgb(reader.ReadInt32()); break; case 17: _color2 = Color.FromArgb(reader.ReadInt32()); break; case 18: _textureID = reader.ReadUInt32(); break; case 19: _floatArray1 = reader.ReadFloatArray(5); break; case 20: _color3 = Color.FromArgb(reader.ReadInt32()); break; case 21: _shortArray1 = reader.ReadUInt16Array(2); break; case 22: _floatArray2 = reader.ReadFloatArray(5); break; case 23: _color4 = Color.FromArgb(reader.ReadInt32()); break; case 25: _float1 = reader.ReadSingle(); break; case 26: _floatArray3 = reader.ReadFloatArray(2); break; default: throw new NotImplementedException("Unknown material flag bit set"); } } } }
/// <summary> /// Reads a <see cref="Zone"/> /// </summary> /// <param name="br">The <see cref="BinaryReader"/> used to read the <see cref="Zone"/></param> /// <param name="ver">The game version</param> /// <returns>A <see cref="Zone"/></returns> public static Zone Read(BinaryReader br, Engine ver = Engine.Unknown) { var ret = new Zone(); var arrSize = ver < Engine.TR2 ? 2 : 4; ret.FlyZoneNormal = br.ReadUInt16(); ret.GroundZonesNormal = br.ReadUInt16Array(arrSize); ret.GroundZonesAlternate = br.ReadUInt16Array(arrSize); ret.FlyZoneAlternate = br.ReadUInt16(); return ret; }
/// <summary> /// Reads a <see cref="QuadFace"/> /// </summary> /// <param name="br">The <see cref="BinaryReader"/> used to read the <see cref="QuadFace"/></param> /// <param name="ver">The game version</param> /// <returns>A <see cref="QuadFace"/></returns> public static QuadFace Read(BinaryReader br, Engine ver = Engine.Unknown) { var ret = new QuadFace { Vertices = br.ReadUInt16Array(4), Texture = br.ReadUInt16() }; if (ver >= Engine.TR4) ret.Lighting = br.ReadUInt16(); return ret; }
public static TOMBPCFile Parse(BinaryReader br, bool psx = false) { try { var lvl = new TOMBPCFile(); lvl.IsPSX = psx; lvl.GameVersion = (TOMBPCGameVersion) br.ReadUInt32(); lvl.CopyrightInfo = br.ParseString(256); var gameflowSize = br.ReadUInt16(); if (gameflowSize != 128) { throw new ArgumentOutOfRangeException("gameflowSize [UInt16]", gameflowSize, "Should be 128"); } #region First options lvl.FirstOption = br.ReadInt32(); lvl.TitleReplace = br.ReadInt32(); lvl.OnDeathDemoMode = br.ReadInt32(); lvl.OnDeathInGame = br.ReadInt32(); lvl.DemoTime = br.ReadInt32(); lvl.OnDemoInterrupt = br.ReadInt32(); lvl.OnDemoEnd = br.ReadInt32(); br.ReadBytes(36); // Unknown2 lvl.NumLevels = br.ReadInt16(); lvl.NumChapterScreens = br.ReadInt16(); lvl.NumTitles = br.ReadInt16(); lvl.NumFMVs = br.ReadInt16(); lvl.NumCutscenes = br.ReadInt16(); lvl.NumDemoLevels = br.ReadInt16(); lvl.TitleSoundID = br.ReadInt16(); lvl.SingleLevel = br.ReadInt16(); br.ReadBytes(32); // Unknown3 lvl.Flags = (TOMBPCFlags) br.ReadUInt16(); br.ReadBytes(6); // Unknown4 lvl.XORbyte = br.ReadByte(); lvl.Language = (TOMBPCLanguage) br.ReadByte(); lvl.SecretSoundID = br.ReadInt16(); br.ReadBytes(4); // Unknown5 #endregion #region Strings var xor = lvl.Flags.HasFlag(TOMBPCFlags.UseEncryption) ? lvl.XORbyte : (byte)0; lvl.LevelDisplayNames = br.ReadStringArray(lvl.NumLevels, xor); lvl.ChapterScreens = br.ReadStringArray(lvl.NumChapterScreens, xor); lvl.TitleFileNames = br.ReadStringArray(lvl.NumTitles, xor); lvl.FMVFileNames = br.ReadStringArray(lvl.NumFMVs, xor); lvl.LevelFileNames = br.ReadStringArray(lvl.NumLevels, xor); lvl.CutSceneFileNames = br.ReadStringArray(lvl.NumCutscenes, xor); #endregion #region Script // This code is partially from Script.cpp of OpenRaider project var v = new List<List<ushort>>(); var n = lvl.NumLevels + 1; var offset = br.ReadUInt16Array(n); var numBytes = br.ReadUInt16(); var list = new ushort[(numBytes + 6) / 2]; for (ushort i = 0; i < numBytes / 2; i++) { list[i] = br.ReadUInt16(); } lvl.DemoLevelIDs = br.ReadUInt16Array(lvl.NumDemoLevels); br.BaseStream.Position -= lvl.NumDemoLevels * 2; var hack = br.ReadUInt16Array(3); if (hack[0] == 19 && hack[1] == 20 && hack[2] == 21 || hack[0] == 21 && hack[1] == 22 && hack[2] == 23) { list[numBytes / 2] = hack[0]; list[numBytes / 2 + 1] = hack[1]; list[numBytes / 2 + 2] = hack[2]; } else { br.BaseStream.Position -= 6; } var numPCStrings = 0; hack = br.ReadUInt16Array(3); if ((hack[0] == 1) && (hack[1] == 0) && (hack[2] == 864)) { br.BaseStream.Position += 58; numPCStrings = 80; // TR2 has 80 PSX Strings } else if ((hack[0] == 1) && (hack[1] == 0) && (hack[2] == 817)) { br.BaseStream.Position += 34; numPCStrings = 80; // TR3 also has 80 PSX Strings } else { br.BaseStream.Position -= 6; numPCStrings = 41; } for (uint i = 0; i < n; i++) { uint end = (uint) (offset[i] / 2); var readingOp = false; while (readingOp || (list[end] != (ushort) ScriptOpCode.OP_ENDSEQUENCE)) { if (readingOp) { readingOp = false; end++; } else { if (OpcodeHasOperand[list[end]]) readingOp = true; end++; } } end++; var tmp = new List<ushort>(); for (uint a = (uint) (offset[i] / 2); a < end; a++) { tmp.Add(list[a]); } v.Add(tmp); } lvl.Script = v.Select(x => x.ToArray()).ToArray(); #endregion if (psx) { lvl.PSXFMVInfo = br.ReadArray(lvl.NumFMVs, () => Loader.PSXFMVInfo.Read(br)); } var numGameStrings = br.ReadUInt16(); lvl.GameStrings1 = br.ReadStringArray(numGameStrings, lvl.XORbyte); lvl.GameStrings2 = br.ReadStringArray(numPCStrings, lvl.XORbyte); lvl.Puzzles = new[] { br.ReadStringArray(lvl.NumLevels, lvl.XORbyte), br.ReadStringArray(lvl.NumLevels, lvl.XORbyte), br.ReadStringArray(lvl.NumLevels, lvl.XORbyte), br.ReadStringArray(lvl.NumLevels, lvl.XORbyte) }; lvl.Pickups = new[] { br.ReadStringArray(lvl.NumLevels, lvl.XORbyte), br.ReadStringArray(lvl.NumLevels, lvl.XORbyte) }; lvl.Keys = new[] { br.ReadStringArray(lvl.NumLevels, lvl.XORbyte), br.ReadStringArray(lvl.NumLevels, lvl.XORbyte), br.ReadStringArray(lvl.NumLevels, lvl.XORbyte), br.ReadStringArray(lvl.NumLevels, lvl.XORbyte) }; return lvl; } catch (Exception e) { throw new ScriptParseException(e, br.BaseStream.Position); } }
public static TR4LanguageFile Read(BinaryReader br) { var ret = new TR4LanguageFile(); ret.NumGenericStrings = br.ReadUInt16(); ret.NumPSXStrings = br.ReadUInt16(); ret.NumPCStrings = br.ReadUInt16(); var genericStringsLen = br.ReadUInt16(); var psxStringsLen = br.ReadUInt16(); var pcStringsLen = br.ReadUInt16(); var stringOffsetTable = br.ReadUInt16Array(ret.NumGenericStrings + ret.NumPSXStrings + ret.NumPCStrings); ret.StringTable = br.ReadStringArray(stringOffsetTable, ret.XORbyte); if (br.BaseStream.Position < br.BaseStream.Length) { Cerr.Write("Warning: " + (br.BaseStream.Length - br.BaseStream.Position) + " bytes of data after end of language file"); } return ret; }
public void LoadFrom(Stream stream) { BinaryReader reader = new BinaryReader(stream); texture = new PPtr<Texture2D>(stream, file); int numVertices = reader.ReadInt32(); vertices = new SpriteVertex[numVertices]; for (int i = 0; i < numVertices; i++) { vertices[i] = new SpriteVertex(stream); } int numIndices = reader.ReadInt32(); indices = reader.ReadUInt16Array(numIndices); if ((numIndices & 1) > 0) { reader.ReadBytes(2); } textureRect = new Rectf(stream); textureRectOffset = reader.ReadVector2(); settingsRaw = reader.ReadUInt32(); uvTransform = reader.ReadVector4(); }
/// <summary> /// Initializes a new instance of the <see cref="SkinPartition"/> class. /// </summary> /// <param name="file">The file.</param> /// <param name="reader">The reader.</param> public SkinPartition(NiFile file, BinaryReader reader) { this.NumVertices = reader.ReadUInt16(); this.NumTriangles = reader.ReadUInt16(); this.NumBones = reader.ReadUInt16(); this.NumStrips = reader.ReadUInt16(); this.NumWeightsPerVertex = reader.ReadUInt16(); this.Bones = reader.ReadUInt16Array((int)this.NumBones); this.HasVertexMap = true; this.HasVertexWeights = true; this.HasFaces = true; if (file.Version >= eNifVersion.VER_10_1_0_0) { this.HasVertexMap = reader.ReadBoolean(file.Version); } if (this.HasVertexMap) { this.VertexMap = reader.ReadUInt16Array((int)this.NumVertices); } if (file.Version >= eNifVersion.VER_10_1_0_0) { this.HasVertexWeights = reader.ReadBoolean(file.Version); } if (this.HasVertexWeights) { this.VertexWeights = new float[(int)this.NumVertices][]; for (int i = 0; i < (int)this.NumVertices; i++) { this.VertexWeights[i] = reader.ReadFloatArray((int)this.NumWeightsPerVertex); } } this.StripLengths = reader.ReadUInt16Array((int)this.NumStrips); if (file.Version >= eNifVersion.VER_10_1_0_0) { this.HasFaces = reader.ReadBoolean(file.Version); } if (this.HasFaces && this.NumStrips != 0) { this.Strips = new ushort[(int)this.NumStrips][]; for (int j = 0; j < (int)this.NumStrips; j++) { this.Strips[j] = reader.ReadUInt16Array((int)this.StripLengths[j]); } } else if (this.HasFaces && this.NumStrips == 0) { this.Triangles = new Triangle[(int)this.NumTriangles]; for (int k = 0; k < this.Triangles.Length; k++) { this.Triangles[k] = new Triangle(reader); } } this.HasBoneIndicies = reader.ReadBoolean(file.Version); if (this.HasBoneIndicies) { this.BoneIndicies = new byte[(int)this.NumVertices][]; for (int l = 0; l < this.BoneIndicies.Length; l++) { this.BoneIndicies[l] = new byte[(int)this.NumWeightsPerVertex]; for (int m = 0; m < (int)this.NumWeightsPerVertex; m++) { this.BoneIndicies[l][m] = reader.ReadByte(); } } } if (file.Header.UserVersion >= 12u) { this.UnkownShort = reader.ReadUInt16(); } if (file.Version == eNifVersion.VER_10_2_0_0 && file.Header.UserVersion == 1u) { this.UnkownShort2 = reader.ReadUInt16(); this.UnkownShort3 = reader.ReadUInt16(); this.NumVertices2 = reader.ReadUInt16(); this.UnkownShort4 = reader.ReadUInt16(); this.UnkownShort5 = reader.ReadUInt16(); this.UnkownShort6 = reader.ReadUInt16(); this.UnkownArr = new SkinPartitionUnkownItem1[(int)this.NumVertices2]; for (int n = 0; n < (int)this.NumVertices2; n++) { this.UnkownArr[n] = new SkinPartitionUnkownItem1(file, reader); } } }
private void InternalRead(BinaryReader reader) { int size = reader.ReadInt32(); _numAssignedFrames = reader.ReadUInt16(); _type = reader.ReadUInt16(); _assignedFrameIndices = reader.ReadUInt16Array(_numAssignedFrames); // Align to 4 bytes reader.AlignPosition(4); _boneKeyData = new float[_numAssignedFrames][]; for (int i = 0; i < _numAssignedFrames; i++) { switch (_type) { case 0x04: { _boneKeyData[i] = new float[2]; for (int j = 0; j < 2; j++) { _boneKeyData[i][j] = (float)reader.ReadInt16() / FIXED_POINT; } } break; case 0x08: { _boneKeyData[i] = new float[4]; for (int j = 0; j < 4; j++) { _boneKeyData[i][j] = (float)reader.ReadInt16() / FIXED_POINT; } } break; case 0x0C: { _boneKeyData[i] = new float[3]; for (int j = 0; j < 3; j++) { _boneKeyData[i][j] = reader.ReadSingle(); } } break; default: break; } } }
// Methods internal void InternalRead(MDChunk model, BinaryReader reader) { _batchSize = reader.ReadUInt16(); _materialID = reader.ReadUInt16(); _batchOffset = reader.ReadInt32(); _numUsedNodes = reader.ReadInt32(); _usedNodeIndices = reader.ReadUInt16Array(_numUsedNodes); _usedNodes = new MDNode[_numUsedNodes]; for (int i = 0; i < _numUsedNodes; i++) { _usedNodes[i] = model.Nodes[_usedNodeIndices[i]]; } reader.BaseStream.Seek((int)model.offset + MDChunk.DATA_START_ADDRESS + _batchOffset, SeekOrigin.Begin); _vifPackets = VIFCodeEvaluator.EvaluateBlock(reader, _batchSize); _batches = MDSubMeshVifBatch.ParseBatches(_vifPackets, _numUsedNodes); foreach (MDSubMeshVifBatch batch in _batches) { batch.TransformedPositions = new Vector3[batch.VertexCount]; batch.TransformedNormals = new Vector3[batch.VertexCount]; for (int i = 0; i < batch.VertexCount; i++) { if (batch.Weights[i] != 0) { batch.TransformedPositions[i] = Vector3.Transform(batch.Positions[i], UsedNodes[batch.UsedNodeArrayIndex].WorldMatrix * batch.Weights[i]); } else { batch.TransformedPositions[i] = Vector3.Zero; } if (batch.Weights[i] != 0) { batch.TransformedNormals[i] = Vector3.TransformNormal(batch.Normals[i], UsedNodes[batch.UsedNodeArrayIndex].WorldMatrix * batch.Weights[i]); } else { batch.TransformedNormals[i] = Vector3.Zero; } } } List<MDSubMeshVifBatch> fixedBatches = new List<MDSubMeshVifBatch>(); for (int i = 0; i < _batches.Count; i+=(int)_numUsedNodes) { Vector3[] pos = new Vector3[_batches[i].VertexCount]; Vector3[] nrm = new Vector3[_batches[i].VertexCount]; for (int k = 0; k < _batches[i].VertexCount; k++) { for (int j = 0; j < _numUsedNodes; j++) { pos[k] += _batches[i + j].TransformedPositions[k]; nrm[k] += _batches[i + j].TransformedNormals[k]; } } for (int k = 0; k < _batches[i].VertexCount; k++) { nrm[k].Normalize(); } /* SubMeshVifBatch finalBatch = _batches[(int)_numUsedNodes - 1]; finalBatch.TransformedPositions = pos; finalBatch.TransformedNormals = pos; finalBatch.NodeIndices = fixedBatches.Add(finalBatch); */ for (int j = 0; j < _numUsedNodes; j++) { _batches[i + j].TransformedPositions = pos; _batches[i + j].TransformedNormals = nrm; _batches[i + j].Colors = _batches[(int)_numUsedNodes - 1].Colors; _batches[i + j].TextureCoords = _batches[(int)_numUsedNodes - 1].TextureCoords; } } }
public sviParser(Stream stream) { BinaryReader reader = new BinaryReader(stream); version = reader.ReadInt32(); if (version != 100) { throw new Exception("SVI bad beginning: 0x" + version.ToString("X")); } meshName = reader.ReadName(); submeshIdx = reader.ReadInt32(); int numIndices = reader.ReadInt32(); indices = reader.ReadUInt16Array(numIndices); positionsPresent = reader.ReadByte(); if (positionsPresent == 1) { positions = reader.ReadVector3Array(numIndices); } bonesPresent = reader.ReadByte(); if (bonesPresent == 1) { boneWeights3 = new float[numIndices][]; for (ushort i = 0; i < numIndices; i++) { boneWeights3[i] = reader.ReadSingleArray(3); } boneIndices = new byte[numIndices][]; for (ushort i = 0; i < numIndices; i++) { boneIndices[i] = reader.ReadBytes(4); } int numBones = reader.ReadInt32(); bones = new sviBone[numBones]; for (int i = 0; i < numBones; i++) { bones[i] = new sviBone(); bones[i].name = reader.ReadName(); bones[i].boneIdx = reader.ReadInt32(); bones[i].matrix = reader.ReadMatrix(); } } normalsPresent = reader.ReadByte(); if (normalsPresent == 1) { normals = reader.ReadVector3Array(numIndices); } uvsPresent = reader.ReadByte(); if (uvsPresent == 1) { uvs = reader.ReadVector2Array(numIndices); } futureSectionPresent = reader.ReadByte(); if (futureSectionPresent != 0) { throw new Exception("SVI future section present"); } }