public void Read(BinaryReaderEx br) { pos = br.BaseStream.Position; for (int i = 0; i < 9; i++) { ind[i] = br.ReadInt16(); } quadFlags = (QuadFlags)br.ReadUInt16(); bitvalue = br.ReadUInt32(); //big endian or little?? { drawOrderLow = (byte)(bitvalue & 0xFF); for (int i = 0; i < 4; i++) { byte val = (byte)((bitvalue >> 8 + 5 * i) & 0x1F); faceFlags[i] = new FaceFlags(val); } //extradata = (byte)(bitvalue & 0xF0000000 >> 28); extradata = (bitvalue & 0xFFF); } drawOrderHigh = br.ReadBytes(4); for (int i = 0; i < 4; i++) { ptrTexMid[i] = br.ReadUInt32(); if (Helpers.TestPointer(ptrTexMid[i]) != 0) { Console.WriteLine("mid " + Helpers.TestPointer(ptrTexMid[i]).ToString("x2")); // Console.ReadKey(); } } bb = new BoundingBox(br); byte tf = br.ReadByte(); if (tf > 20) { Helpers.Panic(this, "unexpected terrain flag value -> " + tf); } terrainFlag = (TerrainFlags)tf; WeatherIntensity = br.ReadByte(); WeatherType = br.ReadByte(); TerrainFlagUnknown = br.ReadByte(); id = br.ReadInt16(); trackPos = br.ReadByte(); midunk = br.ReadByte(); //midflags = br.ReadBytes(2); ptrTexLow = br.ReadUInt32(); if (Helpers.TestPointer(ptrTexLow) != 0) { Console.WriteLine("ptrTexLow " + Helpers.TestPointer(ptrTexLow).ToString("x2")); //Console.ReadKey(); } mosaicStruct = br.ReadUInt32(); if (Helpers.TestPointer(mosaicStruct) != 0) { Console.WriteLine("offset2 " + Helpers.TestPointer(mosaicStruct).ToString("x2")); //Console.ReadKey(); } for (int i = 0; i < 5; i++) { unk3.Add(new Vector2s(br)); } /* * //this is some value per tirangle * foreach(var val in unk3) * { * Console.WriteLine(val.X / 4096f + " " + val.Y / 4096f); * } */ //struct done //read texture layouts int texpos = (int)br.BaseStream.Position; br.Jump(ptrTexLow); texlow = TextureLayout.FromStream(br); foreach (uint u in ptrTexMid) { if (u != 0) { br.Jump(u); tex.Add(new CtrTex(br, (int)mosaicStruct)); } else { if (ptrTexLow != 0) { Console.WriteLine("!"); } } } if (mosaicStruct != 0) { br.BaseStream.Position = mosaicStruct; mosaicPtr1 = br.ReadUInt32(); mosaicPtr2 = br.ReadUInt32(); mosaicPtr3 = br.ReadUInt32(); mosaicPtr4 = br.ReadUInt32(); } br.BaseStream.Position = texpos; }
public void Read(BinaryReaderEx br) { int pos = (int)br.BaseStream.Position; if ((pos & 2) > 0) { Console.WriteLine("!!!"); Console.ReadKey(); } //this apparently defines animated texture, really if ((pos & 1) == 1) { isAnimated = true; br.BaseStream.Position -= 1; texpos = br.ReadUInt32(); numFrames = br.ReadInt16(); whatsthat = br.ReadInt16(); if (br.ReadUInt32() != 0) { Helpers.Panic(this, "not 0!"); } ptrs = br.ReadArrayUInt32(numFrames); foreach (uint ptr in ptrs) { if (ptr < br.BaseStream.Length) { br.Jump(ptr); animframes.Add(TextureLayout.FromStream(br)); } else { Debug.LogWarning("CtrTex -- Animation Frame Overflow"); } } br.Jump(texpos); } for (int i = 0; i < 3; i++) { midlods[i] = TextureLayout.FromStream(br); } //Console.WriteLine(br.BaseStream.Position.ToString("X8")); //Console.ReadKey(); ptrHi = br.ReadUInt32(); //loosely assume we got a valid pointer if (ptrHi > 0x30000 && ptrHi < 0xB0000) { br.Jump(ptrHi); for (int i = 0; i < 16; i++) { hi[i] = TextureLayout.FromStream(br); } } }
public void Read(BinaryReaderEx br) { name = br.ReadStringFixed(16); unk0 = br.ReadInt32(); lodDistance = br.ReadInt16(); billboard = br.ReadInt16(); Console.WriteLine($"CtrHeader: {name}"); if (unk0 != 0) { Helpers.Panic(this, $"check unusual unk0 value = {unk0}"); } if (billboard > 1) { Helpers.Panic(this, $"check unusual billboard value = {billboard}"); } scale = new Vector4s(br); ptrCmd = br.ReadInt32(); ptrVerts = br.ReadInt32(); ptrTex = br.ReadInt32(); ptrClut = br.ReadInt32(); unk3 = br.ReadInt32(); numAnims = br.ReadInt32(); ptrAnims = br.ReadInt32(); unk4 = br.ReadInt32(); if (unk3 != 0) { Helpers.Panic(this, $"check unusual unk3 value = {unk3}"); } if (unk4 != 0) { Helpers.Panic(this, $"check unusual unk4 value = {unk4}"); } long pos = br.BaseStream.Position; //read all drawing commands br.Jump(ptrCmd); cmdNum = br.ReadInt32(); uint x; do { x = br.ReadUInt32Big(); if (x != 0xFFFFFFFF) { drawList.Add(new CtrDraw(x)); } }while (x != 0xFFFFFFFF); //should read anims here /* * if (numAnims > 0) * { * for (int f = 0; f < numAnims; f++) * { * br.Jump(ptrAnims + f * 4); * br.Jump(br.ReadInt32()); * anims.Add(new CTRAnim(br)); * } * } */ //define temporary arrays Vector4b[] clr = new Vector4b[3]; //color buffer Vector3s[] crd = new Vector3s[4]; //face buffer Vector3s[] stack = new Vector3s[256]; //vertex buffer int maxv = 0; int maxc = 0; int maxt = 0; //one pass through all draw commands to get the array lengths foreach (var draw in drawList) { //only increase vertex count for commands that don't take vertex from stack if (!draw.flags.HasFlag(CtrDrawFlags.v)) { maxv++; } //simply find max color index if (draw.colorIndex > maxc) { maxc = draw.colorIndex; } //find max index, but 0 means no texture. if (draw.texIndex > 0) { if (draw.texIndex - 1 > maxt) { maxt = draw.texIndex; } } Console.WriteLine(draw.ToString()); } Console.WriteLine("maxv: " + maxv); Console.WriteLine("maxc: " + maxc); Console.WriteLine("maxt: " + maxt); //int ppos = (int)br.BaseStream.Position; br.Jump(ptrClut); for (int k = 0; k <= maxc; k++) { cols.Add(new Vector4b(br)); } //if static model if (!IsAnimated) { br.Jump(ptrVerts); posOffset = new Vector4s(br); Console.WriteLine(posOffset); br.Skip(16); vrenderMode = br.ReadInt32(); if (!(new List <int> { 0x1C, 0x22 }).Contains(vrenderMode)) { Helpers.Panic(this, $"check vrender {vrenderMode.ToString("X8")}"); } } else { //jump to first animation, read header and jump to vertex garbage br.Jump(ptrAnims); int ptr = br.ReadInt32(); br.Jump(ptr); CtrAnim anim = CtrAnim.FromReader(br); Console.WriteLine(anim.name + " " + anim.numFrames); br.Skip(0x1C); Console.WriteLine(br.HexPos()); posOffset = new Vector4s(0, 0, 0, 0); } //read vertices for (int k = 0; k < maxv; k++) { vtx.Add(new Vector3b(br)); } foreach (var v in vtx) { Console.WriteLine(v.ToString(VecFormat.Hex)); } List <Vector3s> vfixed = new List <Vector3s>(); foreach (var v in vtx) { vfixed.Add(new Vector3s(v.X, v.Y, v.Z)); } foreach (Vector3s v in vfixed) { //scale vertices v.X = (short)((((float)v.X / 255.0f - 0.5) * scale.X)); v.Y = (short)((((float)v.Y / 255.0f - 0.5) * scale.Z)); v.Z = (short)((((float)v.Z / 255.0f) * scale.Y)); //flip axis short zz = v.Z; v.Z = (short)-v.Y; v.Y = zz; } int vertexIndex = 0; int stripLength = 0; //process all commands foreach (CtrDraw d in drawList) { //if we got no stack vertex flag if (!d.flags.HasFlag(CtrDrawFlags.v)) { //push vertex from the array to the buffer stack[d.stackIndex] = vfixed[vertexIndex]; vertexIndex++; } //push new vertex from stack crd[0] = crd[1]; crd[1] = crd[2]; crd[2] = crd[3]; crd[3] = stack[d.stackIndex]; if (d.flags.HasFlag(CtrDrawFlags.l)) { crd[1] = crd[0]; } //push new color clr[0] = clr[1]; clr[1] = clr[2]; clr[2] = cols[d.colorIndex]; //if got reset flag, reset tristrip vertex counter if (d.flags.HasFlag(CtrDrawFlags.s)) { stripLength = 0; } //if we got 3 indices in tristrip (0,1,2) if (stripLength >= 2) { //read 3 vertices and push to the array for (int z = 1; z < 4; z++) { Vertex v = new Vertex(); v.coord = new Vector4s(crd[z].X, crd[z].Y, crd[z].Z, 0); v.color = clr[z - 1]; v.color_morph = v.color; verts.Add(v); } //ig got normal flag, change vertex order to flip normals if (!d.flags.HasFlag(CtrDrawFlags.n)) { Vertex v = verts[verts.Count - 1]; verts[verts.Count - 1] = verts[verts.Count - 3]; verts[verts.Count - 3] = v; } } stripLength++; } //read texture layouts br.Jump(ptrTex); uint[] texptrs = br.ReadArrayUInt32(maxt); Console.WriteLine("texptrs: " + texptrs.Length); foreach (uint t in texptrs) { Console.WriteLine(t.ToString("X8")); br.Jump(t); TextureLayout tx = TextureLayout.FromStream(br); tl.Add(tx); Console.WriteLine(tx.ToString()); } Console.WriteLine("tlcnt: " + tl.Count); br.BaseStream.Position = pos; }
public void Read(BinaryReaderEx br) { name = br.ReadStringFixed(16); id = br.ReadUInt32(); tl = TextureLayout.FromStream(br); }
public void Read(BinaryReaderEx br) { long pos = br.BaseStream.Position; for (int i = 0; i < 9; i++) { ind[i] = br.ReadInt16(); } quadFlags = (QuadFlags)br.ReadUInt16(); bitvalue = br.ReadUInt32Big(); { drawOrderLow = (byte)(bitvalue & 0xFF); for (int i = 0; i < 4; i++) { byte val = (byte)(bitvalue >> 8 + 5 * i & 0x1F); faceFlags[i] = new FaceFlags(val); } extradata = (byte)(bitvalue & 0xF0000000 >> 28); } drawOrderHigh = br.ReadBytes(4); for (int i = 0; i < 4; i++) { ptrTexMid[i] = br.ReadUInt32(); } bb = new BoundingBox(br); byte tf = br.ReadByte(); if (tf > 20) { Helpers.Panic(this, "unexpected terrain flag value -> " + tf); } terrainFlag = (TerrainFlags)tf; WeatherIntensity = br.ReadByte(); WeatherType = br.ReadByte(); TerrainFlagUnknown = br.ReadByte(); id = br.ReadInt16(); trackPos = br.ReadByte(); midunk = br.ReadByte(); //midflags = br.ReadBytes(2); ptrTexLow = br.ReadInt32(); offset2 = br.ReadInt32(); for (int i = 0; i < 10; i++) { unk3[i] = br.ReadUInt16(); } //struct done //read texture layouts int texpos = (int)br.BaseStream.Position; br.Jump(ptrTexLow); texlow = TextureLayout.FromStream(br); foreach (uint u in ptrTexMid) { if (u != 0) { br.Jump(u); tex.Add(new CtrTex(br)); } else { if (ptrTexLow != 0) { Console.WriteLine("!"); } } } br.BaseStream.Position = texpos; }
public void Read(BinaryReaderEx br) { name = br.ReadStringFixed(16); Console.WriteLine(name); //Console.ReadKey(); unk0 = br.ReadInt32(); //0? lodDistance = br.ReadInt16(); billboard = br.ReadInt16(); //probably flags scale = new Vector4s(br); //ptr ptrCmd = br.ReadInt32(); ptrVerts = br.ReadInt32(); ptrTex = br.ReadInt32(); ptrClut = br.ReadInt32(); unk3 = br.ReadInt32(); //? numAnims = br.ReadInt32(); ptrAnims = br.ReadInt32(); unk4 = br.ReadInt32(); //? long pos = br.BaseStream.Position; br.Jump(ptrCmd); cmdNum = br.ReadInt32(); uint x; do { x = br.ReadUInt32Big(); if (x != 0xFFFFFFFF) { defs.Add(new CtrDraw(x)); } }while (x != 0xFFFFFFFF); /* * if (numAnims > 0) * { * for (int f = 0; f < numAnims; f++) * { * br.Jump(ptrAnims + f * 4); * br.Jump(br.ReadInt32()); * anims.Add(new CTRAnim(br)); * } * } */ StringBuilder sb = new StringBuilder(); sb.AppendFormat("o {0}\r\n", name); Vector4b[] clr = new Vector4b[3]; Vector3s[] crd = new Vector3s[4]; Vector3s[] stack = new Vector3s[256]; Vector3s curvert; int i = 0; int cur_i = 0; int maxv = 0; int maxc = 0; int maxt = 0; foreach (CtrDraw d in defs) { if (!d.flags.HasFlag(Flags.v)) { maxv++; } if (d.colorIndex > maxc) { maxc = d.colorIndex; } if (d.texIndex > 0) { if (d.texIndex - 1 > maxt) { maxt = d.texIndex; } } } Console.WriteLine("maxv: " + maxv); Console.WriteLine("maxc: " + maxc); Console.WriteLine("maxt: " + maxt); //int ppos = (int)br.BaseStream.Position; br.Jump(ptrClut); for (int k = 0; k <= maxc; k++) { cols.Add(new Vector4b(br)); } if (!IsAnimated) { br.Jump(ptrVerts); posOffset = new Vector4s(br); Console.WriteLine(posOffset); br.Skip(16); vrenderMode = br.ReadInt32(); if (vrenderMode != 0x1C) { Helpers.Panic(this, $"{vrenderMode.ToString("X8")}"); // Console.ReadKey(); } } else { br.Jump(ptrAnims); br.Jump(br.ReadInt32() + 0x1C + 0x18); posOffset = new Vector4s(0, 0, 0, 0); } for (int k = 0; k < maxv; k++) { vtx.Add(new Vector3b(br)); } List <Vector3s> vfixed = new List <Vector3s>(); foreach (var v in vtx) { vfixed.Add(new Vector3s(v.X, v.Y, v.Z)); } foreach (Vector3s v in vfixed) { v.X = (short)(((int)v.X / 255.0f - 0.5) * (scale.X / 16f)); v.Y = (short)(((int)v.Y / 255.0f - 0.5) * (scale.Z / 16f)); v.Z = (short)(((int)v.Z / 255.0f) * (scale.Y / 16f)); short zz = v.Z; v.Z = (short)-v.Y; v.Y = zz; } //br.Jump(ppos); foreach (CtrDraw d in defs) { if (d.flags.HasFlag(Flags.s)) { Console.WriteLine(cur_i); cur_i = 0; } if (d.flags.HasFlag(Flags.v)) { curvert = stack[d.value >> 16 & 0xFF]; } else { curvert = vfixed[i];//ReadVertex(br, i); stack[d.value >> 16 & 0xFF] = curvert; i++; } crd[0] = crd[1]; crd[1] = crd[2]; crd[2] = crd[3]; crd[3] = curvert; if (d.flags.HasFlag(Flags.l)) { crd[1] = crd[0]; } clr[0] = clr[1]; clr[1] = clr[2]; clr[2] = cols[d.colorIndex];//ReadColor(br, d.colorIndex); if (cur_i >= 2) { for (int z = 1; z < 4; z++) { Vertex v = new Vertex(); v.coord = new Vector4s(crd[z].X, crd[z].Y, crd[z].Z, 0); v.color = clr[z - 1]; v.color_morph = v.color; verts.Add(v); } } cur_i++; // Console.ReadKey(); } // Directory.CreateDirectory("mpk"); // Helpers.WriteToFile("mpk\\" + name + ".obj", sb.ToString()); br.Jump(ptrTex); uint[] texptrs = br.ReadArrayUInt32(maxt); Console.WriteLine("texptrs: " + texptrs.Length); foreach (uint t in texptrs) { Console.WriteLine(t.ToString("X8")); br.Jump(t); TextureLayout tx = TextureLayout.FromStream(br); tl.Add(tx); Console.WriteLine(tx.ToString()); } Console.WriteLine("tlcnt: " + tl.Count); br.BaseStream.Position = pos; }
public void Read(BinaryReaderEx br) { int pos = (int)br.BaseStream.Position; if ((pos & 2) > 0) { Console.WriteLine("!!!"); Console.ReadKey(); } //this apparently defines animated texture, really if ((pos & 1) == 1) { isAnimated = true; br.BaseStream.Position -= 1; uint texpos = br.ReadUInt32(); int numFrames = br.ReadInt16(); int whatsthat = br.ReadInt16(); if (br.ReadUInt32() != 0) { Helpers.Panic(this, "not 0!"); } uint[] ptrs = br.ReadArrayUInt32(numFrames); foreach (uint ptr in ptrs) { br.Jump(ptr); animframes.Add(TextureLayout.FromStream(br)); } br.Jump(texpos); } for (int i = 0; i < 3; i++) { midlods[i] = TextureLayout.FromStream(br); } //Console.WriteLine(br.BaseStream.Position.ToString("X8")); //Console.ReadKey(); /* * ptrHi = br.ReadUInt32(); * * * if (ptrHi != 0 && ptrHi < br.BaseStream.Position) * { * br.Jump(ptrHi); * * ptrHi = br.ReadUInt32(); * if (ptrHi != 0 && ptrHi < br.BaseStream.Position) * { * * for (int i = 0; i < 4; i++) * { * try * { * hi[i] = TextureLayout.FromStream(br); * } * catch * { * Console.WriteLine("fail"); * Console.ReadKey(); * } * } * } * else * { * ptrHi -= 4; * * for (int i = 0; i < 4; i++) * { * try * { * hi[i] = TextureLayout.FromStream(br); * } * catch * { * Console.WriteLine("fail"); * Console.ReadKey(); * } * } * * } * } * else * { * // Console.WriteLine("not a hi res texture"); * } * */ }