public void Read(BinaryReaderEx br) { int texOff = br.ReadInt32(); //so here's what's going on, instead of reading all pointers in a loop, we assume the 1st pointer is smallest, which is also where pointermap ends. //we get number of models and just read the array. this will shamelessly fail, if pointers are not sorted or models don't come after pointer map. int numModels = (br.ReadInt32() - 4) / 4 - 1; br.Seek(-4); //go back List <uint> modelPtrs = br.ReadListUInt32(numModels); br.Jump(texOff); iconPack = new IconPack(br); foreach (var ptr in modelPtrs) { br.Jump(ptr); try { Models.Add(CtrModel.FromReader(br)); } catch { Console.WriteLine($"Model failed: {ptr.ToString("X8")}"); } } }
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()); * */ }