public void Read(BinaryReaderEx br) { //data that seems to be present in every level header = Instance<SceneHeader>.FromReader(br, 0); if (header.ptrRestartPts != 0) restartPts = InstanceList<Pose>.FromReader(br, header.ptrRestartPts, header.cntRestartPts); if (header.ptrMeshInfo != 0) { meshinfo = Instance<MeshInfo>.FromReader(br, header.ptrMeshInfo); if (meshinfo.ptrVertexArray != 0) verts = InstanceList<Vertex>.FromReader(br, meshinfo.ptrVertexArray, meshinfo.cntVertex); if (meshinfo.ptrVisDataArray != 0) visdata = InstanceList<VisData>.FromReader(br, meshinfo.ptrVisDataArray, meshinfo.cntColData); if (meshinfo.ptrQuadBlockArray != 0) quads = InstanceList<QuadBlock>.FromReader(br, meshinfo.ptrQuadBlockArray, meshinfo.cntQuadBlock); } //optional stuff, can be missing if (header.ptrSkybox != 0) skybox = Instance<SkyBox>.FromReader(br, header.ptrSkybox); if (header.ptrVcolAnim != 0) vertanims = InstanceList<VertexAnim>.FromReader(br, header.ptrVcolAnim, header.cntVcolAnim); if (header.ptrAiNav != 0) nav = Instance<Nav>.FromReader(br, header.ptrAiNav); if (header.ptrTrialData != 0) trial = Instance<TrialData>.FromReader(br, header.ptrTrialData); if (header.cntSpawnPts != 0) { br.Jump(header.ptrSpawnPts); unkadv = new UnkAdv(br, (int)header.cntSpawnPts); } if (header.cntTrialData != 0) { br.Jump(header.ptrTrialData); int cnt = br.ReadInt32(); int ptr = br.ReadInt32(); br.Jump(ptr); for (int i = 0; i < cnt; i++) posu1.Add(new Pose(br)); } if (header.cntu2 != 0) { br.Jump(header.ptru2); int cnt = br.ReadInt32(); int ptr = br.ReadInt32(); br.Jump(ptr); for (int i = 0; i < cnt; i++) posu2.Add(new Vector3s(br)); } //find all water quads in visdata foreach (VisData v in visdata) { if (v.IsLeaf) { if (v.flag.HasFlag(VisDataFlags.Water)) { int z = (int)((v.ptrQuadBlock - meshinfo.ptrQuadBlockArray) / 0x5C); for (int i = z; i < z + v.numQuadBlock; i++) quads[i].isWater = true; } } } /* //texture defs br.Jump(header.ptrTexArray); br.Skip(8); int ptrTexList = br.ReadInt32(); br.Jump(ptrTexList); Console.WriteLine(ptrTexList.ToString("X8")); Console.ReadKey(); texmaps = new List<TexMap>(); TexMap mp; do { mp = new TexMap(br, "none"); Console.WriteLine(mp.name); Console.ReadKey(); if (mp.name != "") { texmaps.Add(mp); } } while (mp.name != ""); */ /* //water texture br.BaseStream.Position = header.ptrWater; List<uint> vptr = new List<uint>(); List<uint> wptr = new List<uint>(); for (int i = 0; i < header.cntWater; i++) { vptr.Add(br.ReadUInt32()); wptr.Add(br.ReadUInt32()); } wptr.Sort(); foreach(uint u in wptr) { Console.WriteLine(u.ToString("X8")); } Console.ReadKey(); */ //read pickups for (int i = 0; i < header.numInstances; i++) { br.Jump(header.ptrInstancesPtr + 4 * i); br.Jump(br.ReadUInt32()); pickups.Add(new PickupHeader(br)); } br.Jump(header.ptrModelsPtr); int x = (int)br.BaseStream.Position; for (int i = 0; i < header.numModels; i++) { br.BaseStream.Position = x + 4 * i; br.BaseStream.Position = br.ReadUInt32(); Models.Add(CtrModel.FromReader(br)); } /* quads = quads.OrderBy(o => o.mosaicPtr1).ToList(); StringBuilder sb = new StringBuilder(); foreach (QuadBlock qb in quads) { sb.AppendLine( $"{qb.id.ToString("X4")}\t" + $"{(qb.mosaicPtr1 & 0xFFFFFFFC).ToString("X8")} ({Helpers.TestPointer(qb.mosaicPtr1)})\t" + $"{(qb.mosaicPtr2 & 0xFFFFFFFC).ToString("X8")} ({Helpers.TestPointer(qb.mosaicPtr2)})\t" + $"{(qb.mosaicPtr3 & 0xFFFFFFFC).ToString("X8")} ({Helpers.TestPointer(qb.mosaicPtr3)})\t" + $"{(qb.mosaicPtr4 & 0xFFFFFFFC).ToString("X8")} ({Helpers.TestPointer(qb.mosaicPtr4)})" ); } Helpers.WriteToFile(".\\mosaic_test.txt", sb.ToString()); */ }
public void ReadScene(BinaryReaderEx br) { header = Instance <SceneHeader> .FromReader(br, 0); if (header == null) { throw new Exception("Scene header is null. Halt parsing."); } if (header.ptrMeshInfo != UIntPtr.Zero) { mesh = new PtrWrap <MeshInfo>(header.ptrMeshInfo).Get(br); quads = mesh.QuadBlocks; verts = mesh.Vertices; visdata = mesh.VisData; } restartPts = new PtrWrap <Pose>(header.ptrRestartPts).GetList(br, header.numRestartPts); vertanims = new PtrWrap <VertexAnim>(header.ptrVcolAnim).GetList(br, header.numVcolAnim); skybox = new PtrWrap <SkyBox>(header.ptrSkybox).Get(br); nav = new PtrWrap <Nav>(header.ptrAiNav).Get(br); iconpack = new PtrWrap <IconPack>(header.ptrIcons).Get(br); trial = new PtrWrap <TrialData>(header.ptrTrialData).Get(br); if (header.numSpawnPts > 0) { br.Jump(header.ptrSpawnPts); unkadv = new UnkAdv(br, (int)header.numSpawnPts); } if (header.cntTrialData > 0) { br.Jump(header.ptrTrialData); int cnt = br.ReadInt32(); int ptr = br.ReadInt32(); br.Jump(ptr); for (int i = 0; i < cnt; i++) { posu1.Add(new Pose(br)); } } if (header.cntu2 > 0) { br.Jump(header.ptru2); int cnt = br.ReadInt32(); int ptr = br.ReadInt32(); br.Jump(ptr); for (int i = 0; i < cnt; i++) { posu2.Add(new Vector3s(br)); } } //find all water quads in visdata foreach (var node in visdata) { if (node.IsLeaf) { if (node.flag.HasFlag(VisDataFlags.Water)) { int z = (int)((node.ptrQuadBlock - mesh.ptrQuadBlocks.ToUInt32()) / 0x5C); for (int i = z; i < z + node.numQuadBlock; i++) { quads[i].isWater = true; } } } } //assign anim color target to vertex foreach (var va in vertanims) { verts[(int)((va.ptrVertex - mesh.ptrVertices.ToUInt32()) / 16)].color_target = va.color; } /* * //water texture * br.BaseStream.Position = header.ptrWater; * * List<uint> vptr = new List<uint>(); * List<uint> wptr = new List<uint>(); * * for (int i = 0; i < header.cntWater; i++) * { * vptr.Add(br.ReadUInt32()); * wptr.Add(br.ReadUInt32()); * } * * wptr.Sort(); * * foreach(uint u in wptr) * { * Console.WriteLine(u.ToString("X8")); * } * * Console.ReadKey(); */ //read pickups for (int i = 0; i < header.numInstances; i++) { br.Jump(header.ptrInstancesPtr + 4 * i); br.Jump(br.ReadUInt32()); pickups.Add(PickupHeader.FromReader(br)); } br.Jump(header.ptrModelsPtr); List <uint> modelPtr = br.ReadListUInt32(header.numModels); foreach (var ptr in modelPtr) { br.Jump(ptr); try { CtrModel ctr = CtrModel.FromReader(br); if (ctr != null) { Models.Add(ctr); } } catch { Helpers.Panic(this, PanicType.Error, "Unexpected CtrModel crash."); } } foreach (VertexAnim va in vertanims) { Helpers.Panic(this, PanicType.Info, va.ToString()); } /* * quads = quads.OrderBy(o => o.mosaicPtr1).ToList(); * * StringBuilder sb = new StringBuilder(); * * foreach (QuadBlock qb in quads) * { * sb.AppendLine( * $"{qb.id.ToString("X4")}\t" + * $"{(qb.mosaicPtr1 & 0xFFFFFFFC).ToString("X8")} ({Helpers.TestPointer(qb.mosaicPtr1)})\t" + * $"{(qb.mosaicPtr2 & 0xFFFFFFFC).ToString("X8")} ({Helpers.TestPointer(qb.mosaicPtr2)})\t" + * $"{(qb.mosaicPtr3 & 0xFFFFFFFC).ToString("X8")} ({Helpers.TestPointer(qb.mosaicPtr3)})\t" + * $"{(qb.mosaicPtr4 & 0xFFFFFFFC).ToString("X8")} ({Helpers.TestPointer(qb.mosaicPtr4)})" * ); * } * * Helpers.WriteToFile(".\\mosaic_test.txt", sb.ToString()); * */ }