private byte[] Decrypt(FileData d) { int[] filedata = null; filedata = new int[d.size() / 4]; int size = (int)d.size(); int words = size >> 2; int xorval = 0; d.seek(0x1C); d.Endian = Endianness.Big; int SEED = d.readInt(); RandomXS _rand = new RandomXS(SEED); d.Endian = Endianness.Big; d.seek(0); if (size % 8 == 0) { goto Dword_loop; } else if (size == 0) { return(null); } else if (size / 8 <= 0) { goto BYTE_loop; } else { ;//goto default_loop } #region DWORD Loop Dword_loop: if (words == 0) { goto loops_end; } else if (words / 8 <= 0) { goto Word_Loop; } else { for (int i = 0; i < (words >> 3); i++) { for (int x = 0; x < 8; x++) { var randInt = _rand.GetInt(); var XOR = d.readInt() ^ randInt; var val = XOR ^ xorval; xorval = (randInt << 13) & unchecked ((int)0x80000000); filedata[x + (i * 8)] = val.Reverse(); } } } #endregion #region Word Loop Word_Loop: if ((words & 7) <= 0) { goto loops_end; } int offset = (size >> 2 >> 3 << 3 << 2); d.seek(offset); for (int i = 0; i < (words & 7); i++) { var randInt = _rand.GetInt(); var XOR = d.readInt() ^ randInt; var val = XOR ^ xorval; xorval = (randInt << 13) & unchecked ((int)0x80000000); filedata[offset / 4 + i] = val.Reverse(); } goto loops_end; #endregion #region BYTE Loop BYTE_loop: if ((size & 7) == 0) { goto func_end; } d.seek(4); for (int i = 4; i < (size & 7); i++) { byte[] data = BitConverter.GetBytes(filedata[i.RoundDown(4)]); var b = d.readByte(); var shifted = (b >> 3) | (b << 32 - 3); var val = b ^ shifted; data[i] = (byte)val; } #endregion loops_end: filedata[7] = SEED.Reverse(); func_end: byte[] result = new byte[filedata.Length * sizeof(int)]; Buffer.BlockCopy(filedata, 0, result, 0, result.Length); return(result); }
public static Animation read(FileData d) { d.Endian = Endianness.Big; d.skip(4); // header OMO d.skip(4); // two shorts, idk d.skip(4); //flags? d.skip(2); int boneCount = d.readShort(); int frameCount = d.readShort(); int frameSize = d.readShort(); int offset1 = d.readInt(); // nodeOffset int offset2 = d.readInt(); // interOffset int offset3 = d.readInt(); // keyOffset SkelAnimation anim = new SkelAnimation(); anim.Tag = d; if (boneCount > offset2 / 0x10) { boneCount = offset2 / 0x10; anim.Tag = null; } // base frames // These are linked to bones via hashes d.seek(offset1); // int[] framekey = new int[boneCount]; KeyNode[] baseNode = new KeyNode[boneCount]; // Start positions for bones/nodes for (int i = 0; i < boneCount; i++) { flagsused = flagsused | d.readInt(); d.seek(d.pos() - 4); //Console.WriteLine(flagsused.ToString("x")); int flags = d.readByte(); int tFlag = d.readByte(); int rFlag = d.readByte(); int sFlag = d.readByte(); int hash = d.readInt(); // used to find the identifying bone int off1 = d.readInt() + offset2; framekey[i] = d.readInt(); bool hasTrans = (flags & 0x01) == 0x01; bool hasScale = (flags & 0x04) == 0x04; bool hasRot = (flags & 0x02) == 0x02; KeyNode node = new KeyNode(); baseNode[i] = node; node.hash = (uint)hash; int temp = d.pos(); d.seek(off1); if (hasTrans) { if (tFlag == 0x8) { // interpolated node.t_type = KeyNode.INTERPOLATED; node.t = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); node.t2 = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } else if (tFlag == 0x20) { node.t_type = KeyNode.CONSTANT; node.t = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } else if (tFlag == 0x4) { // entire Vector3 provided in keyframe data i.e. KEYFRAME type node.t_type = KeyNode.KEYFRAME; } } if (hasRot) { if ((rFlag & 0xF0) != 0x50 && (rFlag & 0xF0) != 0x70 && (rFlag & 0xF0) != 0x60 && (rFlag & 0xF0) != 0xA0) { //Console.WriteLine(rFlag); } if ((rFlag & 0xF0) == 0xA0) { // All data is in the keyframe for this type node.r_type = KeyNode.COMPRESSED; } if ((rFlag & 0xF0) == 0x50) { // interpolated node.r_type = KeyNode.INTERPOLATED; node.rv = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); node.rv2 = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } if ((rFlag & 0xF0) == 0x60) { node.r_type = KeyNode.KEYFRAME; node.rv = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); node.r_extra = d.readFloat() / 65535; } if ((rFlag & 0xF0) == 0x70) { node.r_type = KeyNode.CONSTANT; node.rv = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } } if (hasScale) { if ((sFlag & 0xF0) == 0x80) { // interpolated node.s_type = KeyNode.INTERPOLATED; node.s = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); node.s2 = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } // TODO: investigate the difference between these if ((rFlag & 0x0F) == 0x02 || (rFlag & 0x0F) == 0x03) { // constant node.s_type = KeyNode.CONSTANT; node.s = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } } d.seek(temp); } // Interpolated type below here is always a set translation/rotation/scale // from the coords specified with the bone node above Animation a = new Animation("Anim"); a.Tag = anim.Tag; a.FrameCount = frameCount; d.seek(offset3); for (int j = 0; j < boneCount; j++) { string bid = ""; int hash = -1; if (!MainForm.Hashes.ids.TryGetValue(baseNode[j].hash, out bid)) { hash = (int)baseNode[j].hash; } Animation.KeyNode n = new Animation.KeyNode(bid); n.Hash = hash; a.Bones.Add(n); n.Type = Animation.BoneType.NORMAL; /*foreach (ModelContainer con in Runtime.ModelContainers) * if (con.VBN != null) * bid = con.VBN.getBone(baseNode[j].hash) == null ? "" : con.VBN.getBone(baseNode[j].hash).Text;*/ for (int i = 0; i < a.FrameCount; i++) { d.seek(offset3 + frameSize * i + framekey[j]); if (baseNode[j].t_type == KeyNode.INTERPOLATED) { float i1 = ((float)d.readShort() / 0xffff); float i2 = ((float)d.readShort() / 0xffff); float i3 = ((float)d.readShort() / 0xffff); float x = baseNode[j].t.X + (baseNode[j].t2.X * (i1)); float y = baseNode[j].t.Y + (baseNode[j].t2.Y * (i2)); float z = baseNode[j].t.Z + (baseNode[j].t2.Z * (i3)); //node.t = new Vector3(x, y, z); // Translation n.XPOS.Keys.Add(new Animation.KeyFrame(x, i)); n.YPOS.Keys.Add(new Animation.KeyFrame(y, i)); n.ZPOS.Keys.Add(new Animation.KeyFrame(z, i)); } else if (baseNode[j].t_type == KeyNode.CONSTANT) { //node.t = baseNode[j].t; n.XPOS.Keys.Add(new Animation.KeyFrame(baseNode[j].t.X, i)); n.YPOS.Keys.Add(new Animation.KeyFrame(baseNode[j].t.Y, i)); n.ZPOS.Keys.Add(new Animation.KeyFrame(baseNode[j].t.Z, i)); } else if (baseNode[j].t_type == 2) { float x = d.readFloat(); float y = d.readFloat(); float z = d.readFloat(); //node.t = new Vector3(x, y, z); n.XPOS.Keys.Add(new Animation.KeyFrame(x, i)); n.YPOS.Keys.Add(new Animation.KeyFrame(y, i)); n.ZPOS.Keys.Add(new Animation.KeyFrame(z, i)); } if (baseNode[j].r_type == KeyNode.COMPRESSED) { // There are 64 bits present for each node of this rot type // The format is: 20bits * 3 of encoded floats, and 4 bits of flags // The flags describe which 3 components of the quaternion are being presented int b1 = d.readByte(); int b2 = d.readByte(); int b3 = d.readByte(); int b4 = d.readByte(); int b5 = d.readByte(); int b6 = d.readByte(); int b7 = d.readByte(); int b8 = d.readByte(); // Capture 20 bits at a time of the raw data int f1 = (b1 << 12) | (b2 << 4) | ((b3 & 0xF0) >> 4); int f2 = ((b3 & 0xF) << 16) | (b4 << 8) | b5; int f3 = (b6 << 12) | (b7 << 4) | ((b8 & 0xF0) >> 4); int flags = b8 & 0xF; Quaternion r = new Quaternion(); switch (flags) { case 0: // y, z, w provided r.Y = encodedRot10ToQuaternionComponent(f1); r.Z = encodedRot10ToQuaternionComponent(f2); r.W = encodedRot10ToQuaternionComponent(f3); r.X = (float)Math.Sqrt(Math.Abs(1 - (r.Y * r.Y + r.Z * r.Z + r.W * r.W))); break; case 1: // x, z, w provided r.X = encodedRot10ToQuaternionComponent(f1); r.Z = encodedRot10ToQuaternionComponent(f2); r.W = encodedRot10ToQuaternionComponent(f3); r.Y = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Z * r.Z + r.W * r.W))); break; case 2: // x, y, w provided r.X = encodedRot10ToQuaternionComponent(f1); r.Y = encodedRot10ToQuaternionComponent(f2); r.W = encodedRot10ToQuaternionComponent(f3); r.Z = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Y * r.Y + r.W * r.W))); break; case 3: // x, y, z, provided r.X = encodedRot10ToQuaternionComponent(f1); r.Y = encodedRot10ToQuaternionComponent(f2); r.Z = encodedRot10ToQuaternionComponent(f3); r.W = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Y * r.Y + r.Z * r.Z))); break; default: Console.WriteLine("Unknown rotation type3 flags: " + flags); break; } n.RotType = Animation.RotationType.QUATERNION; n.XROT.Keys.Add(new Animation.KeyFrame(r.X, i)); n.YROT.Keys.Add(new Animation.KeyFrame(r.Y, i)); n.ZROT.Keys.Add(new Animation.KeyFrame(r.Z, i)); n.WROT.Keys.Add(new Animation.KeyFrame(r.W, i)); } else if (baseNode[j].r_type == KeyNode.INTERPOLATED) { float i1 = ((float)d.readShort() / (0xffff)); float i2 = ((float)d.readShort() / (0xffff)); float i3 = ((float)d.readShort() / (0xffff)); float x = baseNode[j].rv.X + (baseNode[j].rv2.X * (i1)); float y = baseNode[j].rv.Y + (baseNode[j].rv2.Y * (i2)); float z = baseNode[j].rv.Z + (baseNode[j].rv2.Z * (i3)); float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z))); Quaternion r = new Quaternion(new Vector3(x, y, z), w); r.Normalize(); n.RotType = Animation.RotationType.QUATERNION; n.XROT.Keys.Add(new Animation.KeyFrame(r.X, i)); n.YROT.Keys.Add(new Animation.KeyFrame(r.Y, i)); n.ZROT.Keys.Add(new Animation.KeyFrame(r.Z, i)); n.WROT.Keys.Add(new Animation.KeyFrame(r.W, i)); } else if (baseNode[j].r_type == KeyNode.KEYFRAME) { float scale = d.readShort() * baseNode[j].r_extra; float x = baseNode[j].rv.X; float y = baseNode[j].rv.Y; float z = baseNode[j].rv.Z + scale; float w = rot6CalculateW(x, y, z); Quaternion r = new Quaternion(x, y, z, w); n.RotType = Animation.RotationType.QUATERNION; n.XROT.Keys.Add(new Animation.KeyFrame(r.X, i)); n.YROT.Keys.Add(new Animation.KeyFrame(r.Y, i)); n.ZROT.Keys.Add(new Animation.KeyFrame(r.Z, i)); n.WROT.Keys.Add(new Animation.KeyFrame(r.W, i)); } else { float x = baseNode[j].rv.X; float y = baseNode[j].rv.Y; float z = baseNode[j].rv.Z; float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z))); Quaternion r = new Quaternion(baseNode[j].rv, w); r.Normalize(); n.RotType = Animation.RotationType.QUATERNION; n.XROT.Keys.Add(new Animation.KeyFrame(r.X, i)); n.YROT.Keys.Add(new Animation.KeyFrame(r.Y, i)); n.ZROT.Keys.Add(new Animation.KeyFrame(r.Z, i)); n.WROT.Keys.Add(new Animation.KeyFrame(r.W, i)); } if (baseNode[j].s_type == KeyNode.INTERPOLATED) { float i1 = ((float)d.readShort() / (0xffff)); float i2 = ((float)d.readShort() / (0xffff)); float i3 = ((float)d.readShort() / (0xffff)); float x = baseNode[j].s.X + (baseNode[j].s2.X * (i1)); float y = baseNode[j].s.Y + (baseNode[j].s2.Y * (i2)); float z = baseNode[j].s.Z + (baseNode[j].s2.Z * (i3)); //node.s = new Vector3(x, y, z); n.XSCA.Keys.Add(new Animation.KeyFrame(x, i)); n.YSCA.Keys.Add(new Animation.KeyFrame(y, i)); n.ZSCA.Keys.Add(new Animation.KeyFrame(z, i)); } else { //node.s = baseNode[j].s; n.XSCA.Keys.Add(new Animation.KeyFrame(baseNode[j].s.X, i)); n.YSCA.Keys.Add(new Animation.KeyFrame(baseNode[j].s.Y, i)); n.ZSCA.Keys.Add(new Animation.KeyFrame(baseNode[j].s.Z, i)); } } } return(a); }
/*public void readStageAnim() * { * FileData d = new FileData("C:\\Users\\ploaj_000\\Desktop\\Melee\\GrIz.dat"); * d.Endian = System.IO.Endianness.Big; * Debug = true; * readKeyFrame(d, 8, 0x107300, 0x04, 0x00, 0x08, 0, 0x06); * }*/ public void readKeyFrame(FileData d, int length, int dataoff, int valueFormat, int tanFormat, int keyframeCount, int boneId, int trackType) { int temp = d.pos(); d.seek(dataoff); if (Debug) { Console.WriteLine("Start 0x" + d.pos() + " " + keyframeCount); } DATAnimTrack track = new DATAnimTrack(); track.type = (AnimType)trackType; nodes[boneId].Add(track); while (d.pos() < dataoff + length) { int type = readExtendedByte(d); int interpolation = ((type) & 0x0F); int numOfKey = ((type >> 4) & 0xFF) + 1; if (Debug) { Console.WriteLine("Interpolation type: " + (InterpolationType)interpolation + "\tnumofkey: " + numOfKey); } for (int i = 0; i < numOfKey; i++) { double value = -99, tan = -99; int time = 0; if (interpolation == 1) { // step value = readVal(d, valueFormat); time = readExtendedByte(d); if (Debug) { Console.WriteLine("\t" + value + "\t" + time); } } if (interpolation == 2) { // linear value = readVal(d, valueFormat); time = readExtendedByte(d); //Console.WriteLine("\t" + value + "\t" + time); } if (interpolation == 3) { // hermite value = readVal(d, valueFormat); tan = 0; time = readExtendedByte(d); if (Debug) { Console.WriteLine("\t" + value + "\t" + time); } } if (interpolation == 4) { // hermite value = readVal(d, valueFormat); tan = readVal(d, tanFormat); time = readExtendedByte(d); if (Debug) { Console.WriteLine("\t" + value + "\t" + tan + "\t" + time); } } if (interpolation == 5) { // hermite tan = readVal(d, tanFormat); if (Debug) { Console.WriteLine("\t" + "Tan" + tan); } } if (interpolation == 6) { // constant value = readVal(d, valueFormat); time = readExtendedByte(d); //Console.WriteLine("\t" + value + "\t" + time); } KeyNode node = new KeyNode(); node.value = (float)value; node.frame = time; node.tan = (float)tan; node.interpolationType = (InterpolationType)interpolation; track.keys.Add(node); //node.boneID = boneId; } d.Endian = System.IO.Endianness.Big; } //Console.WriteLine("Ends at: " + (d.pos() + 8 - (d.pos() % 8)).ToString("x")); d.seek(temp); }
public static SkelAnimation read(FileData d) { d.Endian = Endianness.Big; d.skip(4); // header OMO d.skip(4); // two shorts, idk d.skip(4); //flags? d.skip(2); int numOfBones = d.readShort(); int frameSize = d.readShort(); int frameStart = d.readShort(); int offset1 = d.readInt(); int offset2 = d.readInt(); int offset3 = d.readInt(); SkelAnimation anim = new SkelAnimation(); anim.Tag = d; //anim.setModel(m); // base frames // These are linked to bones somehow, hash?? d.seek(offset1); // int[] framekey = new int[numOfBones]; KeyNode[] baseNode = new KeyNode[numOfBones]; for (int i = 0; i < numOfBones; i++) { int flags = d.readByte(); int tFlag = d.readByte(); int rFlag = d.readByte(); int sFlag = d.readByte(); int hash = d.readInt(); // used to find the identifying bone int off1 = d.readInt() + offset2; framekey[i] = d.readInt(); bool hasTrans = (flags & 0x01) == 0x01; bool hasScale = (flags & 0x04) == 0x04; bool hasRot = (flags & 0x02) == 0x02; KeyNode node = new KeyNode(); baseNode[i] = node; node.hash = (uint)hash; int temp = d.pos(); d.seek(off1); if (hasTrans) { if (tFlag == 0x8) { // interpolated node.t_type = KeyNode.INTERPOLATED; node.t = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); node.t2 = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } else if (tFlag == 0x20) { node.t_type = KeyNode.CONSTANT; node.t = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } } if (hasRot) { if ((rFlag & 0xF) != 0x50 && (rFlag & 0xF0) != 0x70 && (rFlag & 0xF0) != 0x60 && (rFlag & 0xF0) != 0xA0) { //Console.WriteLine(rFlag); } if ((rFlag & 0xF0) == 0xA0) { node.r_type = 3; } if ((rFlag & 0xF0) == 0x50) { // interpolated node.r_type = KeyNode.INTERPOLATED; node.rv = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); node.rv2 = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } if ((rFlag & 0xF0) == 0x70 || (rFlag & 0xF0) == 0x60) { // constant node.r_type = KeyNode.CONSTANT; node.rv = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); if ((rFlag & 0xF0) == 0x60) { d.skip(4); } } } if (hasScale) { if ((sFlag & 0xF0) == 0x80) { // interpolated node.s_type = KeyNode.INTERPOLATED; node.s = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); node.s2 = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } if ((rFlag & 0x0F) == 0x02 || (rFlag & 0x0F) == 0x03) { // constant node.s_type = KeyNode.CONSTANT; node.s = new Vector3(d.readFloat(), d.readFloat(), d.readFloat()); } } d.seek(temp); } d.seek(offset3); for (int i = 0; i < frameSize; i++) { KeyFrame key = new KeyFrame(); key.frame = i; int off = d.pos(); for (int j = 0; j < numOfBones; j++) { KeyNode node = new KeyNode(); node.t_type = baseNode[j].t_type; node.r_type = baseNode[j].r_type; node.s_type = baseNode[j].s_type; node.id = baseNode[j].id; node.hash = baseNode[j].hash; d.seek(off + framekey[j]); if (baseNode[j].t_type == KeyNode.INTERPOLATED) { float i1 = ((float)d.readShort() / 0xffff); float i2 = ((float)d.readShort() / 0xffff); float i3 = ((float)d.readShort() / 0xffff); float x = baseNode[j].t.X + (baseNode[j].t2.X * (i1)); float y = baseNode[j].t.Y + (baseNode[j].t2.Y * (i2)); float z = baseNode[j].t.Z + (baseNode[j].t2.Z * (i3)); node.t = new Vector3(x, y, z); } else { node.t = baseNode[j].t; } if (baseNode[j].r_type == 3) { float i4 = ((float)d.readShort() / (0xffff)); float i1 = ((float)d.readShort() / (0xffff)); float i2 = ((float)d.readShort() / (0xffff)); float i3 = ((float)d.readShort() / (0xffff)); node.r = new Quaternion(new Vector3(i1, i2, i3), i4); node.r = VBN.FromEulerAngles(i4 * i1, i4 * i2, i4 * i3); node.r_type = KeyNode.INTERPOLATED; //node.r.Normalize(); } else if (baseNode[j].r_type == KeyNode.INTERPOLATED) { float i1 = ((float)d.readShort() / (0xffff)); float i2 = ((float)d.readShort() / (0xffff)); float i3 = ((float)d.readShort() / (0xffff)); float x = baseNode[j].rv.X + (baseNode[j].rv2.X * (i1)); float y = baseNode[j].rv.Y + (baseNode[j].rv2.Y * (i2)); float z = baseNode[j].rv.Z + (baseNode[j].rv2.Z * (i3)); float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z))); node.r = new Quaternion(new Vector3(x, y, z), w); node.r.Normalize(); } else { float x = baseNode[j].rv.X; float y = baseNode[j].rv.Y; float z = baseNode[j].rv.Z; float w = (float)Math.Sqrt(1 - (x * x + y * y + z * z)); node.r = new Quaternion(baseNode[j].rv, w); } if (baseNode[j].s_type == KeyNode.INTERPOLATED) { float i1 = ((float)d.readShort() / (0xffff)); float i2 = ((float)d.readShort() / (0xffff)); float i3 = ((float)d.readShort() / (0xffff)); float x = baseNode[j].s.X + (baseNode[j].s2.X * (i1)); float y = baseNode[j].s.Y + (baseNode[j].s2.Y * (i2)); float z = baseNode[j].s.Z + (baseNode[j].s2.Z * (i3)); node.s = new Vector3(x, y, z); } else { node.s = baseNode[j].s; } key.addNode(node); } d.seek(off + frameStart); anim.addKeyframe(key); } return(anim); }
/** * Reading and saving -------------------- **/ public override void Read(string filename) { FileData d = new FileData(filename); d.seek(0); d.Endian = Endianness.Little; format = d.readShort(); unkown = (ushort)d.readShort(); flags = d.readInt(); mode = d.readInt(); bool hasNameTable = (flags & 2) > 0; int polyCount = d.readInt(); mesh = new List <Mesh>(); descript = new List <Descriptor>(); List <List <int> > prim = new List <List <int> >(); for (int i = 0; i < polyCount; i++) { if (i == 0 && mode == 1) { Descriptor des = new Descriptor(); des.ReadDescription(d); descript.Add(des); } Mesh m = new Mesh(); mesh.Add(m); int faceCount = d.readInt(); List <int> prims = new List <int>(); prim.Add(prims); for (int j = 0; j < faceCount; j++) { int nodeCount = d.readInt(); List <int> nodeList = new List <int>(); m.nodeList.Add(nodeList); for (int k = 0; k < nodeCount; k++) { nodeList.Add(d.readInt()); // for a node list? } int primitiveCount = d.readInt(); prims.Add(primitiveCount); if (hasNameTable) { int nameId = d.readInt(); } if (mode == 0) { if (format == 4) { int[] buffer = new int[primitiveCount]; for (int k = 0; k < primitiveCount; k++) { buffer[k] = d.readShort(); } d.align(4); List <int> buf = new List <int>(); buf.AddRange(buffer); m.faces.Add(buf); } else { Descriptor des = new Descriptor(); des.ReadDescription(d); descript.Add(des); } } } } if (mode == 0) { //Console.WriteLine("Extra!"); } // TODO: STRING TABLE if (hasNameTable) { for (int i = 0; i < mesh.Count; i++) { int index = d.readByte(); nameTable.Add(d.readString()); } } if (format != 4) { d.align(32); } // Vertex Bank int start = d.pos(); for (int i = 0; i < 1; i++) { if (mode == 0 || i == 0) { Descriptor des = descript[i]; if (format != 4) { while (d.pos() < start + des.length) { Vertex v = new Vertex(); vertices.Add(v); for (int k = 0; k < des.type.Length; k++) { d.align(2); switch (des.type[k]) { case 0: //Position v.pos.X = readType(d, des.format[k], des.scale[k]); v.pos.Y = readType(d, des.format[k], des.scale[k]); v.pos.Z = readType(d, des.format[k], des.scale[k]); break; case 1: //Normal v.nrm.X = readType(d, des.format[k], des.scale[k]); v.nrm.Y = readType(d, des.format[k], des.scale[k]); v.nrm.Z = readType(d, des.format[k], des.scale[k]); break; case 2: //Color v.col.X = (int)(readType(d, des.format[k], des.scale[k])); v.col.Y = (int)(readType(d, des.format[k], des.scale[k])); v.col.Z = (int)(readType(d, des.format[k], des.scale[k])); v.col.W = (int)(readType(d, des.format[k], des.scale[k])); break; case 3: //Tex0 v.tx.Add(new Vector2(readType(d, des.format[k], des.scale[k]), readType(d, des.format[k], des.scale[k]))); break; case 4: //Tex1 v.tx.Add(new Vector2(readType(d, des.format[k], des.scale[k]), readType(d, des.format[k], des.scale[k]))); break; case 5: //Bone Index v.node.Add(d.readByte()); v.node.Add(d.readByte()); break; case 6: //Bone Weight v.weight.Add(readType(d, des.format[k], des.scale[k])); v.weight.Add(readType(d, des.format[k], des.scale[k])); break; //default: // Console.WriteLine("WTF is this"); } } } d.align(32); } } for (int j = 0; j < mesh.Count; j++) { foreach (int l in prim[j]) { List <int> face = new List <int>(); mesh[j].faces.Add(face); for (int k = 0; k < l; k++) { face.Add(d.readShort()); } d.align(32); } } } PreRender(); }
public void Read(FileData d) { d.Endian = System.IO.Endianness.Big; d.seek(4); // skip filesize int dataSize = d.readInt(); int offsetTableCount = d.readInt(); int rootA = d.readInt(); int headerSize = 0x20; int rootOffset = headerSize + dataSize + offsetTableCount * 4; d.seek(rootOffset); int figtree = d.readInt() + headerSize; d.skip(4); String name = d.readString(d.pos(), -1); this.Name = name; d.seek(figtree); d.skip(8); float frameCount = d.readFloat(); int keyOffset = d.readInt(); if (Debug) { Console.WriteLine(name + "\tCount: " + frameCount); } this.frameCount = (int)frameCount; int temp = d.pos(); d.seek(keyOffset + 0x20); //int boneCount = 0x2E; // TODO: Use actual bone count 0x35 List <int> keyFrameCount = new List <int>(); int bid = d.readByte(); while (bid != 0xFF) { keyFrameCount.Add(bid); bid = d.readByte(); nodes.Add(new List <DATAnimTrack>()); } int boneCount = keyFrameCount.Count; if (Debug) { Console.WriteLine(boneCount); } d.seek(temp); int animDataOffset = 0; int[] trackcount = new int[offsetTableCount]; for (int i = 0; i < offsetTableCount; i++) { trackcount[i] = d.readInt(); if (i == 0) { animDataOffset = trackcount[i]; } } d.seek(animDataOffset + 0x20); for (int i = 0; i < boneCount; i++) { // bonecount if (Debug) { Console.WriteLine("Bone " + i + ": " + keyFrameCount[i] + "\t" + d.pos().ToString("x")); } for (int j = 0; j < keyFrameCount[i]; j++) { int length = d.readShort(); d.skip(2); int trackType = d.readByte(); int valueFormat = d.readByte(); int tanFormat = d.readByte(); d.skip(1); int dataoff = d.readInt() + 0x20; if (Debug) { Console.WriteLine((AnimType)trackType + "\tLength: " + length + "\tOffset: " + dataoff.ToString("x") + " " + valueFormat.ToString("x") + " " + tanFormat.ToString("x")); } // System.out.println(valueFormat + " " + tanFormat); readKeyFrame(d, length, dataoff, valueFormat, tanFormat, keyFrameCount[i], i, trackType); } } }
/*type 1 - collisions * type 2 - spawns * type 3 - respawns * type 4 - camera bounds * type 5 - death boundaries * type 6 - enemy generator * type 7 - ITEMPT_transform * type 8 - ??? * type 9 - ITEMPT * type 10 - fsAreaCam (and other fsArea's ? ) * type 11 - fsCamLimit * type 12 - damageShapes (damage sphere and damage capsule are the only ones I've seen, type 2 and 3 respectively) * type 13 - item spawners * type 14 - general shapes (general rect, general path, etc.) * type 15 - general points * type 16 - ??? * type 17 - FsStartPoint * type 18 - ??? * type 19 - ???*/ public override void Read(string filename) { FileData f = new FileData(filename); f.skip(0xA);//It's magic f.skip(1); int collisionCount = f.readInt(); for (int i = 0; i < collisionCount; i++) { Collision temp = new Collision(); temp.read(f); collisions.Add(temp); } f.skip(1); int spawnCount = f.readInt(); for (int i = 0; i < spawnCount; i++) { Spawn temp = new Spawn(); temp.read(f); spawns.Add(temp); } f.skip(1); int respawnCount = f.readInt(); for (int i = 0; i < respawnCount; i++) { Spawn temp = new Spawn(); temp.read(f); respawns.Add(temp); } f.skip(1); int cameraCount = f.readInt(); for (int i = 0; i < cameraCount; i++) { Bounds temp = new Bounds(); temp.read(f); cameraBounds.Add(temp); } f.skip(1); int blastzoneCount = f.readInt(); for (int i = 0; i < blastzoneCount; i++) { Bounds temp = new Bounds(); temp.read(f); blastzones.Add(temp); } f.skip(1); int enemyGeneratorCount = f.readInt(); for (int i = 0; i < enemyGeneratorCount; i++) { EnemyGenerator temp = new EnemyGenerator(); temp.read(f); enemySpawns.Add(temp); } f.skip(1); if (f.readInt() != 0) //7 { return; } f.skip(1); if (f.readInt() != 0) //8 { return; } f.skip(1); if (f.readInt() != 0) //9 { return; } f.skip(1); int fsAreaCamCount = f.readInt(); if (fsAreaCamCount != 0) { return; } f.skip(1); int fsCamLimitCount = f.readInt(); if (fsCamLimitCount != 0) { return; } f.skip(1); int damageShapeCount = f.readInt(); for (int i = 0; i < damageShapeCount; i++) { DamageShape temp = new DamageShape(); temp.read(f); damageShapes.Add(temp); } f.skip(1); int itemCount = f.readInt(); for (int i = 0; i < itemCount; i++) { ItemSpawner temp = new ItemSpawner(); temp.read(f); itemSpawns.Add(temp); } f.skip(1); int generalShapeCount = f.readInt(); for (int i = 0; i < generalShapeCount; i++) { GeneralShape temp = new GeneralShape(); temp.read(f); generalShapes.Add(temp); } f.skip(1); int generalPointCount = f.readInt(); for (int i = 0; i < generalPointCount; i++) { GeneralPoint temp = new GeneralPoint(); temp.read(f); generalPoints.Add(temp); } f.skip(1); if (f.readInt() != 0) //16 { return; //no clue how to be consistent in reading these so... } f.skip(1); if (f.readInt() != 0) //17 { return; //no clue how to be consistent in reading these so... } f.skip(1); if (f.readInt() != 0) //18 { return; //no clue how to be consistent in reading these so... } f.skip(1); if (f.readInt() != 0) //19 { return; //no clue how to be consistent in reading these so... } //LVD doesn't end here and neither does my confusion, will update this part later }
public void writeHalfFloat(float f) { writeShort(FileData.fromFloat(f)); }
public void ReadNTP3(FileData d) { d.skip(0x2); int count = d.readShort(); d.skip(0x8); int dataPtr = 0; for (int i = 0; i < count; i++) { Debug.WriteLine(d.pos().ToString("x")); NUD_Texture tex = new NUD_Texture(); tex.type = PixelInternalFormat.Rgba32ui; int totalSize = d.readInt(); d.skip(4); // padding int dataSize = d.readInt(); int headerSize = d.readShort(); d.skip(3); int numMips = d.readByte(); Debug.WriteLine(numMips); d.skip(1); tex.setPixelFormatFromNutFormat(d.readByte()); tex.width = d.readShort(); tex.height = d.readShort(); d.skip(8); // padding? int dataOffset = d.readInt() + dataPtr + 0x10; d.skip(0x0C); int[] mipSizes = new int[numMips]; if (numMips == 1) { mipSizes[0] = dataSize; } else { for (int j = 0; j < numMips; j++) { mipSizes[j] = d.readInt(); } } d.align(16); d.skip(0x18); tex.id = d.readInt(); d.skip(4); // padding align 8 // add mipmap data for (int miplevel = 0; miplevel < numMips; miplevel++) { byte[] texArray = d.getSection(dataOffset, mipSizes[miplevel]); tex.mipmaps.Add(texArray); dataOffset += mipSizes[miplevel]; } dataPtr += headerSize; if (tex.getNutFormat() == 14 || tex.getNutFormat() == 17) { Console.WriteLine("Endian swap"); // swap foreach (byte[] mip in tex.mipmaps) { for (int t = 0; t < mip.Length; t += 4) { byte t1 = mip[t]; mip[t] = mip[t + 1]; mip[t + 1] = mip[t + 2]; mip[t + 2] = mip[t + 3]; mip[t + 3] = t1; /*byte t1 = mip[t]; * byte t2 = mip[t+1]; * mip[t] = mip[t + 3]; * mip[t + 1] = mip[t + 2]; * mip[t + 2] = t2; * mip[t + 3] = t1;*/ } } } textures.Add(tex); /*for (int miplevel = 0; miplevel < numMips; miplevel++) * { * byte[] texArray = d.getSection(dataOffset, mipSizes[miplevel]); * * if (tex.getNutFormat() == 14) * { * byte[] oldArray = texArray; * for (int pos = 0; pos < mipSizes[miplevel]; pos+=4) * { * * for (int p = 0; p < 4; p++) * { * if (p == 0) * texArray[pos + 3] = oldArray[pos]; * else * texArray[pos + p - 1] = oldArray[pos + p]; * } * * } * } * tex.mipmaps.Add(texArray); * dataOffset += mipSizes[miplevel]; * }*/ } foreach (var tex in textures) { if (!draw.ContainsKey(tex.id)) { draw.Add(tex.id, loadImage(tex, true)); } } }
public void ReadNTWU(FileData d) { d.skip(0x02); int count = d.readShort(); d.skip(0x10); int headerPtr = d.pos(); int dataPtr = 0; int gtxHeaderOffset = 0; for (int i = 0; i < count; i++) { NUD_Texture tex = new NUD_Texture(); tex.type = PixelInternalFormat.Rgba32ui; d.seek(headerPtr); int totalSize = d.readInt(); int headerSize = d.readShort(); int numMips = d.readInt(); tex.setPixelFormatFromNutFormat(d.readShort()); tex.width = d.readShort(); tex.height = d.readShort(); d.skip(8); // mipmaps and padding int dataOffset = d.readInt() + dataPtr + 0x10; headerPtr += headerSize; dataPtr += headerSize; d.skip(0x04); if (i == 0) { gtxHeaderOffset = d.readInt() + 0x10; } else { gtxHeaderOffset += 0x80; d.skip(0x04); } d.skip(0x04); // check for cubemap bool cmap = (d.readInt() == d.readInt()); d.seek(d.pos() - 8); if (cmap) { Console.WriteLine("cubemap detected"); } d.skip(headerSize - 0x50); d.skip(0x18); tex.id = d.readInt(); Console.WriteLine(gtxHeaderOffset.ToString("x")); d.seek(gtxHeaderOffset); d.skip(0x04); // dim d.skip(0x04); // width d.skip(0x04); // height d.skip(0x04); // depth d.skip(0x04); // numMips int format = d.readInt(); d.skip(0x04); // aa d.skip(0x04); // use int imageSize = d.readInt(); d.skip(0x04); // imagePtr int maxSize = d.readInt(); // mipSize d.skip(0x04); // mipPtr int tileMode = d.readInt(); int swizzle = d.readInt(); d.skip(0x04); // alignment int pitch = d.readInt(); int ds = dataOffset; int s1 = 0; int size = 0; Console.WriteLine(totalSize.ToString("x")); for (int mipLevel = 0; mipLevel < numMips; mipLevel++) { // Maybe this is the problem? int mipSize = imageSize >> (mipLevel * 2); int p = pitch >> mipLevel; size = d.readInt(); //Console.WriteLine("\tMIP: " + size.ToString("x") + " " + dataOffset.ToString("x") + " " + mipSize.ToString("x") + " " + p + " " + (size == 0 ? ds + totalSize - dataOffset : size)); //Console.WriteLine(tex.id.ToString("x") + " " + dataOffset.ToString("x") + " " + mipSize.ToString("x") + " " + p + " " + swizzle); //Console.WriteLine((tex.width >> mipLevel) + " " + (tex.height >> mipLevel)); //if (cmap) tex.height *= 2; int w = (tex.width >> mipLevel); int h = (tex.height >> mipLevel); { byte[] deswiz = GTX.swizzleBC( d.getSection(dataOffset, d.size() - dataOffset), w, h, format, tileMode, p, swizzle ); tex.mipmaps.Add(new FileData(deswiz).getSection(0, mipSize)); } if (mipLevel == 0) { s1 = size; dataOffset = ds + size; } else { dataOffset = ds + s1 + size; } //dataOffset += mipSize; /*if (cmap) * { * for(int k = 0; k < 5; k++) * { * p = pitch >> (mipLevel + k + 1); * tex.mipmaps.Add(GTX.swizzleBC( * d.getSection(dataOffset, mipSize), * w, * h, * format, * tileMode, * p, * swizzle * )); * * dataOffset += mipSize; * } * }*/ //while (dataOffset % 1024 != 0) dataOffset++; //if (mipSize == 0x4000) dataOffset += 0x400; } textures.Add(tex); } foreach (var tex in textures) { if (!draw.ContainsKey(tex.id)) { draw.Add(tex.id, loadImage(tex, false)); } // redo mipmaps /*GL.BindTexture(TextureTarget.Texture2D, draw[tex.id]); * for (int k = 1; k < tex.mipmaps.Count; k++) * { * tex.mipmaps[k] = new byte[tex.mipmaps[k].Length]; * GCHandle pinnedArray = GCHandle.Alloc(tex.mipmaps[k], GCHandleType.Pinned); * IntPtr pointer = pinnedArray.AddrOfPinnedObject(); * GL.GetCompressedTexImage(TextureTarget.Texture2D, 0, pointer); * pinnedArray.Free(); * }*/ } //File.WriteAllBytes("C:\\s\\Smash\\extract\\data\\fighter\\duckhunt\\model\\body\\mip1.bin", bytearray); //Console.WriteLine(GL.GetError()); /*int j = 0; * foreach(byte[] b in textures[0].mipmaps) * { * if (j == 3) * { * for(int w = 3; w < 8; w++) * { * for (int p = 3; p < 6; p++) * { * byte[] deswiz = GTX.swizzleBC( * b, * (int)Math.Pow(2, w), * 64, * 51, * 4, * (int)Math.Pow(2, p), * 197632 * ); * File.WriteAllBytes("C:\\s\\Smash\\extract\\data\\fighter\\duckhunt\\model\\body\\chunk_" + (int)Math.Pow(2, p) + "_" + (int)Math.Pow(2, w), deswiz); * } * } * * } * j++; * }*/ }
public NUT(FileData d) { Read(d); }
public override void Read(string filename) { FileData d = new FileData(filename); d.Endian = Endianness.Little; // characters are little d.seek(8); // skip magic and version? int count = d.readInt(); // entry count for (int i = 0; i < count; i++) { SBEntry sb = new SBEntry() { hash = (uint)d.readInt(), param1_1 = d.readFloat(), param1_2 = d.readInt(), param1_3 = d.readInt(), param2_1 = d.readFloat(), param2_2 = d.readInt(), param2_3 = d.readInt(), rx1 = d.readFloat(), rx2 = d.readFloat(), ry1 = d.readFloat(), ry2 = d.readFloat(), rz1 = d.readFloat(), rz2 = d.readFloat() }; for (int j = 0; j < 8; j++) { sb.boneHashes[j] = (uint)d.readInt(); } for (int j = 0; j < 4; j++) { sb.unks1[j] = d.readFloat(); } for (int j = 0; j < 5; j++) { sb.unks2[j] = d.readFloat(); } sb.factor = d.readFloat(); for (int j = 0; j < 4; j++) { sb.ints[j] = d.readInt(); } bones.Add(sb); /*Console.WriteLine(sb.hash.ToString("x")); * Console.WriteLine(d.readFloat() + " " + d.readInt() + " " + d.readInt()); * Console.WriteLine(d.readFloat() + " " + d.readInt() + " " + d.readInt()); * * //28 floats? * Console.WriteLine(d.readFloat() + " " + d.readFloat()); * Console.WriteLine(d.readFloat() + " " + d.readFloat()); * Console.WriteLine(d.readFloat() + " " + d.readFloat()); * Console.WriteLine(d.readFloat() + " " + d.readFloat() + " " + d.readFloat() + " " + d.readFloat()); * Console.WriteLine(d.readFloat() + " " + d.readFloat() + " " + d.readFloat() + " " + d.readFloat()); * * Console.WriteLine(d.readFloat() + " " + d.readFloat() + " " + d.readFloat() + " " + d.readFloat()); * Console.WriteLine(d.readFloat() + " " + d.readFloat() + " " + d.readFloat() + " " + d.readFloat()); * * Console.WriteLine(d.readFloat() + " " + d.readFloat()); * Console.WriteLine(d.readInt() + " " + d.readInt()); * Console.WriteLine(d.readInt() + " " + d.readInt()); * Console.WriteLine();*/ } }
public override void Read(string filename) { FileData file = new FileData(filename); if (file != null) { file.Endian = Endianness.Little; Endian = Endianness.Little; string magic = file.readString(0, 4); if (magic == "VBN ") { file.Endian = Endianness.Big; Endian = Endianness.Big; } file.seek(4); unk_1 = (short)file.readShort(); unk_2 = (short)file.readShort(); totalBoneCount = (UInt32)file.readInt(); boneCountPerType[0] = (UInt32)file.readInt(); boneCountPerType[1] = (UInt32)file.readInt(); boneCountPerType[2] = (UInt32)file.readInt(); boneCountPerType[3] = (UInt32)file.readInt(); int[] pi = new int[totalBoneCount]; for (int i = 0; i < totalBoneCount; i++) { Bone temp = new Bone(this); temp.Text = file.readString(file.pos(), -1); file.skip(64); temp.boneType = (UInt32)file.readInt(); pi[i] = file.readInt(); temp.boneId = (UInt32)file.readInt(); temp.position = new float[3]; temp.rotation = new float[3]; temp.scale = new float[3]; bones.Add(temp); } for (int i = 0; i < bones.Count; i++) { bones[i].position[0] = file.readFloat(); bones[i].position[1] = file.readFloat(); bones[i].position[2] = file.readFloat(); bones[i].rotation[0] = file.readFloat(); bones[i].rotation[1] = file.readFloat(); bones[i].rotation[2] = file.readFloat(); bones[i].scale[0] = file.readFloat(); bones[i].scale[1] = file.readFloat(); bones[i].scale[2] = file.readFloat(); Bone temp = bones[i]; temp.parentIndex = pi[i]; //Debug.Write(temp.parentIndex); //if (temp.parentIndex != 0x0FFFFFFF && temp.parentIndex > -1) // bones[temp.parentIndex].children.Add(i); bones[i] = temp; } reset(); } }
public void Read(FileData f) { f.Endian = Endianness.Little; f.seek(4); int count = f.readInt(); f.skip(12); int dataCount = f.readInt(); int boneCount = f.readInt(); int hashCount = f.readInt(); int hashOffset = f.readInt() + 0x28; f.skip(4); int pos = f.pos(); f.seek(hashOffset); csvHashes csv = new csvHashes(Path.Combine(MainForm.executableDir, "hashTable.csv")); List <string> bonename = new List <string>(); for (int i = 0; i < hashCount; i++) { uint hash = (uint)f.readInt(); for (int j = 0; j < csv.ids.Count; j++) { if (csv.ids[j] == hash) { Console.WriteLine(csv.names[j]); bonename.Add(csv.names[j]); break; } } } f.seek(pos); Console.WriteLine("Count " + count); for (int i = 0; i < dataCount; i++) { Console.WriteLine("Bone " + i + " start at " + f.pos().ToString("x")); // 3 sections int secLength = f.readInt(); int someCount = f.readInt(); // usually 2? for (int sec = 0; sec < 5; sec++) { int size = f.readInt(); int id = f.readInt(); Console.WriteLine(id + ":\t" + size.ToString("x")); for (int j = 0; j < ((size - 1) / 4) - 1; j++) { Console.Write("\t" + f.readShort() + " " + f.readShort() + "\t"); } Console.WriteLine(); } f.skip(8); } Console.WriteLine("0x" + f.pos().ToString("X")); f.skip(8); int hashSize = f.readInt(); int unk = f.readInt(); }
public NUT.NUD_Texture toNUT_Texture() { NUT.NUD_Texture tex = new NUT.NUD_Texture(); tex.id = 0x48415348; tex.height = header.height; tex.width = header.width; float size = 1; int mips = header.mipmapCount; /*if (mips > header.mipmapCount) * { * mips = header.mipmapCount; * MessageBox.Show("Possible texture error: Only one mipmap"); * }*/ switch (header.dwFourCC) { case 0x0: size = 4f; tex.type = PixelInternalFormat.SrgbAlpha; tex.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; break; case 0x31545844: size = 1 / 2f; tex.type = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext; break; case 0x35545844: size = 1f; tex.type = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext; break; case 0x32495441: size = 1 / 2f; tex.type = PixelInternalFormat.CompressedRedRgtc1; break; case 0x31495441: size = 1f; tex.type = PixelInternalFormat.CompressedRgRgtc2; break; default: MessageBox.Show("Unsupported DDS format - 0x" + header.dwFourCC.ToString("x")); break; } // now for mipmap data... FileData d = new FileData(data); int off = 0, w = header.width, h = header.height; if (header.mipmapCount == 0) { header.mipmapCount = 1; } for (int i = 0; i < header.mipmapCount; i++) { int s = (int)((w * h) * size); if (s < 0x8) { s = 0x8; } //Console.WriteLine(off.ToString("x") + " " + s.ToString("x")); w /= 2; h /= 2; tex.mipmaps.Add(d.getSection(off, s)); off += s; } Console.WriteLine(off.ToString("x")); return(tex); }