public void ExportTex(string filename) { FileOutput o = new FileOutput(); o.endian = Endianness.Little; o.WriteInt(pictureBox1.Image.Width); o.WriteInt(pictureBox1.Image.Height); o.WriteByte(formatSelector.SelectedIndex); o.WriteByte(1); o.WriteShort(0); o.WriteString(nameBox.Text); for (int i = 0; i < 0x74 - nameBox.Text.Length; i++) { o.WriteByte(0); } pictureBox1.Image.RotateFlip(RotateFlipType.RotateNoneFlipY); o.WriteBytes(_3DS.EncodeImage(new Bitmap(pictureBox1.Image), (_3DS.Tex_Formats)formatSelector.SelectedIndex)); pictureBox1.Image.RotateFlip(RotateFlipType.RotateNoneFlipY); o.Save(filename); }
public override byte[] Rebuild() { FileOutput buf = new FileOutput(); buf.endian = Endianness.Little; var flagsOffset = 0x10; var entriesOffset = flagsOffset + (atlases.Count * 4); var stringsOffset = entriesOffset + (textures.Count * 0x20); buf.WriteInt(0x544C5354); // TLST buf.WriteShort(0); // idk buf.WriteShort((short)atlases.Count); buf.WriteShort((short)textures.Count); buf.WriteShort((short)flagsOffset); buf.WriteShort((short)entriesOffset); buf.WriteShort((short)stringsOffset); // flags foreach (var flag in atlases) { buf.WriteInt((int)flag); } // entries int namePtr = 0; foreach (var texture in textures) { buf.WriteInt(namePtr); buf.WriteInt(namePtr); namePtr += texture.name.Length + 1; buf.WriteFloat(texture.topLeft.X); buf.WriteFloat(texture.topLeft.Y); buf.WriteFloat(texture.botRight.X); buf.WriteFloat(texture.botRight.Y); buf.WriteShort(texture.width); buf.WriteShort(texture.height); buf.WriteShort(texture.atlasId); buf.WriteShort(0); // pad } //strings foreach (var texture in textures) { buf.WriteString(texture.name); buf.WriteByte(0); } buf.WriteByte(0); return(buf.GetBytes()); }
public int Rebuild(FileOutput o) { int size = o.Size(); o.WriteInt(hash); o.WriteInt(unk1); o.WriteByte(name.Length + 1); o.WriteString(name); o.WriteByte(0); o.Align(4); o.WriteInt(0); o.WriteInt(8); o.WriteInt(offset); o.WriteInt(this.size); // write data foreach (float f in param) { o.WriteFloat(f); } o.WriteInt(offsets.Length); foreach (int f in offsets) { o.WriteInt(f); } o.WriteInt(unkvalues.Length); int v = 0; foreach (float f in unkvalues) { o.WriteInt(v++); o.WriteFloat(f); } foreach (int f in unkending) { o.WriteInt(f); } foreach (int f in end) { o.WriteInt(f); } return(o.Size() - size); }
} // Read() #region serialization void writeSymbols(FileOutput o) { FileOutput tag = new FileOutput(); tag.WriteInt(Strings.Count); Console.WriteLine($"Strings = [ // offset=0x{o.Size():X2}"); for (int i = 0; i < Strings.Count; i++) { var str = Strings[i]; Console.WriteLine($"\t0x{i:X3}: \"{str}\""); var strBytes = Encoding.UTF8.GetBytes(str); tag.WriteInt(strBytes.Length); tag.WriteBytes(strBytes); int padSize = 4 - (tag.Size() % 4); for (int j = 0; j < padSize; j++) { tag.WriteByte(0); } } Console.WriteLine("]\n"); o.WriteInt((int)TagType.Symbols); o.WriteInt(tag.Size() / 4); o.WriteOutput(tag); }
public int Rebuild(FileOutput o) { o.WriteString("GRP "); int sizeoff = o.Size(); o.WriteInt(0); int size = o.Size(); o.WriteInt(names.Count); int start = names.Count * 8 + 4; FileOutput name = new FileOutput(); name.endian = Endianness.Little; int c = 0; foreach (string na in names) { o.WriteInt(start + name.Size()); int ns = name.Pos(); name.WriteInt(1); name.WriteByte(na.Length == 0 ? 0xFF : na.Length + 1); name.WriteString(na); name.WriteByte(0); name.Align(4); if (c != names.Count - 1) { name.WriteInt(0); // padding } else { ns -= 4; } c++; o.WriteInt(name.Pos() - ns); } o.WriteInt(0); o.WriteOutput(name); size = o.Size() - size; o.WriteIntAt(size, sizeoff); return(size); }
public void WriteVertex(FileOutput f, ref Vertex v) { switch (type) { case (int)_3DSGPU.VertexAttribute.pos: WriteType(f, v.pos.X); WriteType(f, v.pos.Y); WriteType(f, v.pos.Z); break; case (int)_3DSGPU.VertexAttribute.nrm: WriteType(f, v.nrm.X); WriteType(f, v.nrm.Y); WriteType(f, v.nrm.Z); WriteType(f, 1f); break; case (int)_3DSGPU.VertexAttribute.tx0: WriteType(f, v.tx.X); WriteType(f, v.tx.Y); break; case (int)_3DSGPU.VertexAttribute.col: WriteType(f, v.col.X); WriteType(f, v.col.Y); WriteType(f, v.col.Z); WriteType(f, v.col.W); break; case (int)_3DSGPU.VertexAttribute.bone: f.WriteByte((int)v.bone.X); f.WriteByte((int)v.bone.Y); break; case (int)_3DSGPU.VertexAttribute.weight: WriteType(f, v.weight.X); WriteType(f, v.weight.Y); break; default: Console.WriteLine("Error"); break; } }
public int Rebuild(FileOutput o) { int size = o.Size(); o.WriteInt(hash); o.WriteInt(unk1); o.WriteByte(name.Length + 1); o.WriteString(name); o.WriteByte(0); o.Align(4); // write data foreach (float f in data) { o.WriteFloat(f); } return(o.Size() - size); }
public int Rebuild(FileOutput o) { o.WriteString("BINF"); int sizeoff = o.Size(); o.WriteInt(0); int size = o.Size(); o.WriteInt(0); o.WriteInt(unk1); o.WriteByte(name.Length + 1); o.WriteString(name); o.WriteByte(0); o.Align(4); o.WriteInt(flag); size = o.Size() - size; o.WriteIntAt(size, sizeoff); return(size); }
private void WriteType(FileOutput d, float data) { switch (format) { case 0: d.WriteFloat(data / scale); break; case 1: d.WriteByte((byte)(data / scale)); break; case 2: d.WriteByte((byte)(data / scale)); break; case 3: d.WriteShort((short)(data / scale)); break; } }
private static void writeType(FileOutput d, float value, int format, float scale) { switch (format) { case 0: d.WriteFloat(value / scale); break; case 1: d.WriteByte((byte)(value / scale)); break; case 2: d.WriteByte((byte)(value / scale)); break; case 3: d.WriteShort((short)(value / scale)); break; } }
public byte[] Rebuild(int pos) { FileOutput f = new FileOutput(); f.endian = Endianness.Big; f.WriteInt(pos + f.Pos() + 0x20); f.WriteInt(Convert.ToInt32(unk1)); int offset = pos + f.Pos() + 0x18; offset += name.Length + 1; while (offset % 16 != 0) { offset++; } offset += 0x10; f.WriteInt(offset); f.WriteBytes(new byte[0x14]); f.WriteString(name); f.WriteByte(0); while ((pos + f.Pos()) % 16 != 0) { f.WriteByte(0); } f.WriteBytes(new byte[0x10]); f.WriteInt(frameCount); f.WriteShort(Convert.ToInt32(unk2)); f.WriteShort(frames.Count); f.WriteInt(pos + f.Pos() + 0x18); f.WriteBytes(new byte[0x14]); foreach (frame keyframe in frames) { f.WriteShort(keyframe.frameNum); f.WriteByte(keyframe.state); f.WriteByte(keyframe.unknown); } return(f.GetBytes()); }
public byte[] Rebuild(int pos) { FileOutput f = new FileOutput(); f.endian = Endianness.Big; f.WriteInt(pos + f.Pos() + 0x20); f.WriteInt(unknown); f.WriteInt(valueCount); f.WriteInt(frames.Count); f.WriteShort(unknown2); f.WriteShort(animType); int position = pos + f.Pos() + 0xC + name.Length + 1; while (position % 0x10 != 0) { position++; } f.WriteInt(position); f.WriteBytes(new byte[8]); f.WriteString(name); f.WriteByte(0); while ((pos + f.Pos()) % 0x10 != 0) { f.WriteByte(0); } foreach (frame fr in frames) { for (int i = 0; i < valueCount; i++) { f.WriteFloat(fr.values[i]); } } f.WriteBytes(new byte[0x10]); return(f.GetBytes()); }
public int Rebuild(FileOutput o) { o.WriteString("PROP"); int sizeoff = o.Size(); o.WriteInt(0); int size = o.Size(); o.WriteInt(0); o.WriteInt(unk1); o.WriteShort(0); o.WriteShort(unk2); o.WriteByte(project.Length + 1); o.WriteString(project); o.WriteByte(0); o.WriteByte(0); o.WriteByte(0); o.WriteByte(0); o.Align(4); o.WriteShort(unk3); o.Align(4); o.WriteByte(timestamp.Length + 1); o.WriteString(timestamp); o.WriteByte(0); o.WriteByte(0); o.WriteByte(0); o.WriteByte(0); o.Align(4); size = o.Size() - size; o.WriteIntAt(size, sizeoff); return(size); }
public byte[] RebuildEntries(FileOutput f) { List <int> nameOffsets = new List <int>(); int nameTableOffset = 0x30 + (0x20 * entries.Count); FileOutput nameTable = new FileOutput() { endian = Endianness.Big }; foreach (Entry entry in entries) { nameOffsets.Add(nameTableOffset + nameTable.Pos()); nameTable.WriteString(entry.name); nameTable.WriteBytes(new byte[4 - (entry.name.Length % 4)]); //Pad to next word } while (nameTable.Pos() % 0x10 != 0) { nameTable.WriteByte(0); } for (int i = 0; i < entries.Count; i++) { entries[i].values[0] = nameOffsets[i]; } foreach (Entry entry in entries) { foreach (int value in entry.values) { f.WriteInt(value); } } f.WriteBytes(nameTable.GetBytes()); return(f.GetBytes()); }
private void extractRom(object sender, EventArgs e) { using (OpenFileDialog ofd = new OpenFileDialog()) { ofd.Title = "Select NES ROM"; if (ofd.ShowDialog() == DialogResult.OK) { using (SaveFileDialog sfd = new SaveFileDialog()) { sfd.Title = "Select Save Location"; if (sfd.ShowDialog() == DialogResult.OK) { byte[] rom = File.ReadAllBytes(ofd.FileName); FileOutput f = new FileOutput(); for (int i = 0x30; i < rom.Length - 0x20; i++) { f.WriteByte(rom[i]); } f.Save(sfd.FileName); } } } } }
public static byte[] encodeETCa4(Bitmap b) { int width = b.Width; int height = b.Height; int[] pixels = new int[width * height]; int i, j; FileOutput o = new FileOutput(); o.endian = System.IO.Endianness.Little; for (i = 0; i < height; i += 8) { for (j = 0; j < width; j += 8) { int x, y; Color[] temp = new Color[16]; int pi = 0; for (x = i; x < i + 4; x++) { for (y = j; y < j + 4; y++) { temp[pi++] = b.GetPixel(y, x); } } for (int ax = 0; ax < 4; ax++) { for (int ay = 0; ay < 4; ay++) { int a = (temp[ax + ay * 4].A >> 4); ay++; a |= (temp[ax + ay * 4].A >> 4) << 4; o.WriteByte(a); } } ulong g = GenETC1(temp); o.WriteInt((int)(g & 0xFFFFFFFF)); o.WriteInt((int)((g >> 32) & 0xFFFFFFFF)); temp = new Color[16]; pi = 0; for (x = i; x < i + 4; x++) { for (y = j + 4; y < j + 8; y++) { temp[pi++] = b.GetPixel(y, x); } } for (int ax = 0; ax < 4; ax++) { for (int ay = 0; ay < 4; ay++) { int a = (temp[ax + ay * 4].A >> 4); ay++; a |= (temp[ax + ay * 4].A >> 4) << 4; o.WriteByte(a); } } g = GenETC1(temp); o.WriteInt((int)(g & 0xFFFFFFFF)); o.WriteInt((int)((g >> 32) & 0xFFFFFFFF)); temp = new Color[16]; pi = 0; for (x = i + 4; x < i + 8; x++) { for (y = j; y < j + 4; y++) { temp[pi++] = b.GetPixel(y, x); } } for (int ax = 0; ax < 4; ax++) { for (int ay = 0; ay < 4; ay++) { int a = (temp[ax + ay * 4].A >> 4); ay++; a |= (temp[ax + ay * 4].A >> 4) << 4; o.WriteByte(a); } } g = GenETC1(temp); o.WriteInt((int)(g & 0xFFFFFFFF)); o.WriteInt((int)((g >> 32) & 0xFFFFFFFF)); temp = new Color[16]; pi = 0; for (x = i + 4; x < i + 8; x++) { for (y = j + 4; y < j + 8; y++) { temp[pi++] = b.GetPixel(y, x); } } for (int ax = 0; ax < 4; ax++) { for (int ay = 0; ay < 4; ay++) { int a = (temp[ax + ay * 4].A >> 4); ay++; a |= (temp[ax + ay * 4].A >> 4) << 4; o.WriteByte(a); } } g = GenETC1(temp); o.WriteInt((int)(g & 0xFFFFFFFF)); o.WriteInt((int)((g >> 32) & 0xFFFFFFFF)); } } return(o.GetBytes()); }
public override byte[] Rebuild() { FileOutput file = new FileOutput(); if (file != null) { if (Endian == Endianness.Little) { file.endian = Endianness.Little; file.WriteString(" NBV"); file.WriteShort(0x02); file.WriteShort(0x01); } else if (Endian == Endianness.Big) { file.endian = Endianness.Big; file.WriteString("VBN "); file.WriteShort(0x01); file.WriteShort(0x02); } file.WriteInt(bones.Count); if (boneCountPerType[0] == 0) { boneCountPerType[0] = (uint)bones.Count; } List <Bone> Normal = new List <Bone>(); List <Bone> Unk = new List <Bone>(); List <Bone> Helper = new List <Bone>(); List <Bone> Swing = new List <Bone>(); string[] SpecialBones = new string[] { "TransN", "RotN", "HipN", "LLegJ", "LKneeJ", "LFootJ", "LToeN", "RLegJ", "RKneeJ", "RFootJ", "RToeN", "WaistN", "BustN", "LShoulderN", "LShoulderJ", "LArmJ", "LHandN", "RShoulderN", "RShoulderJ", "RArmJ", "RHandN", "NeckN", "HeadN", "RHaveN", "LHaveN", "ThrowN" }; Bone[] Special = new Bone[SpecialBones.Length]; int specialCount = 0; // OrderPass foreach (Bone b in bones) { for (int i = 0; i < SpecialBones.Length; i++) { if (b.Text.Equals(SpecialBones[i]) || (SpecialBones[i].Equals("RotN") && b.Text.Equals("XRotN"))) { specialCount++; Special[i] = b; break; } } } Console.WriteLine(SpecialBones.Length + " " + specialCount); if (specialCount == SpecialBones.Length) { Normal.AddRange(Special); } //Gather Each Bone Type foreach (Bone b in bones) { switch (b.boneType) { case 0: if (!Normal.Contains(b)) { Normal.Add(b); } break; case 2: Helper.Add(b); break; case 3: Swing.Add(b); break; default: Unk.Add(b); break; } } file.WriteInt(Normal.Count); file.WriteInt(Unk.Count); file.WriteInt(Helper.Count); file.WriteInt(Swing.Count); List <Bone> NewBoneOrder = new List <Bone>(); NewBoneOrder.AddRange(Normal); NewBoneOrder.AddRange(Unk); NewBoneOrder.AddRange(Helper); NewBoneOrder.AddRange(Swing); bones.Clear(); bones = NewBoneOrder; for (int i = 0; i < bones.Count; i++) { file.WriteString(bones[i].Text); for (int j = 0; j < 64 - bones[i].Text.Length; j++) { file.WriteByte(0); } file.WriteInt((int)bones[i].boneType); if (bones[i].parentIndex == -1) { file.WriteInt(0x0FFFFFFF); } else { file.WriteInt(bones[i].parentIndex); } file.WriteInt((int)bones[i].boneId); } for (int i = 0; i < bones.Count; i++) { file.WriteFloat(bones[i].position[0]); file.WriteFloat(bones[i].position[1]); file.WriteFloat(bones[i].position[2]); file.WriteFloat(bones[i].rotation[0]); file.WriteFloat(bones[i].rotation[1]); file.WriteFloat(bones[i].rotation[2]); file.WriteFloat(bones[i].scale[0]); file.WriteFloat(bones[i].scale[1]); file.WriteFloat(bones[i].scale[2]); } } return(file.GetBytes()); }
public override byte[] Rebuild() { FileOutput f = new FileOutput(); f.endian = Endianness.Little; FileOutput fv = new FileOutput(); fv.endian = Endianness.Little; f.WriteShort(format); f.WriteShort(unknown); f.WriteInt(flags); f.WriteInt(mode); bool hasNameTable = (flags & 2) > 0; f.WriteInt(mesh.Count); int vertSize = 0; // Vertex Bank for (int i = 0; i < 1; i++) { if (mode == 0 || i == 0) { Descriptor des = descript[i]; if (format != 4) { foreach (Vertex v in vertices) { for (int k = 0; k < des.type.Length; k++) { fv.Align(2, 0x00); switch (des.type[k]) { case 0: //Position writeType(fv, v.pos.X, des.format[k], des.scale[k]); writeType(fv, v.pos.Y, des.format[k], des.scale[k]); writeType(fv, v.pos.Z, des.format[k], des.scale[k]); break; case 1: //Normal writeType(fv, v.nrm.X, des.format[k], des.scale[k]); writeType(fv, v.nrm.Y, des.format[k], des.scale[k]); writeType(fv, v.nrm.Z, des.format[k], des.scale[k]); break; case 2: //Color writeType(fv, v.col.X, des.format[k], des.scale[k]); writeType(fv, v.col.Y, des.format[k], des.scale[k]); writeType(fv, v.col.Z, des.format[k], des.scale[k]); writeType(fv, v.col.W, des.format[k], des.scale[k]); break; case 3: //Tex0 writeType(fv, v.tx[0].X, des.format[k], des.scale[k]); writeType(fv, v.tx[0].Y, des.format[k], des.scale[k]); break; case 4: //Tex1 writeType(fv, v.tx[1].X, des.format[k], des.scale[k]); writeType(fv, v.tx[1].Y, des.format[k], des.scale[k]); break; case 5: //Bone Index fv.WriteByte(v.node[0]); fv.WriteByte(v.node[1]); break; case 6: //Bone Weight writeType(fv, v.weight[0], des.format[k], des.scale[k]); writeType(fv, v.weight[1], des.format[k], des.scale[k]); break; //default: // Console.WriteLine("WTF is this"); } } } vertSize = fv.Size(); fv.Align(32, 0xFF); } } for (int j = 0; j < mesh.Count; j++) { foreach (List <int> l in mesh[j].faces) { foreach (int index in l) { fv.WriteShort(index); } fv.Align(32, 0xFF); } } } for (int i = 0; i < mesh.Count; i++) { if (i == 0 && mode == 1) { descript[0].WriteDescription(f); f.WriteInt(vertSize); } f.WriteInt(mesh[i].nodeList.Count); //Console.WriteLine(mesh[i].faces.Count + " " + mesh[i].nodeList.Count); for (int j = 0; j < mesh[i].nodeList.Count; j++) { f.WriteInt(mesh[i].nodeList[j].Count); for (int k = 0; k < mesh[i].nodeList[j].Count; k++) { f.WriteInt(mesh[i].nodeList[j][k]); } f.WriteInt(mesh[i].faces[j].Count); // TODO: This stuff 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); * } * * }*/ } } // TODO: STRING TABLE /*if (hasNameTable) * { * for (int i = 0; i < mesh.Count; i++) * { * int index = d.readByte(); * nameTable.Add(d.readString()); * } * }*/ if (format != 4) { f.Align(32, 0xFF); } f.WriteOutput(fv); return(f.GetBytes()); }
public static void Rebuild(string fname, List <Animation> animations) { // poopity doo da // headery deadery FileOutput o = new FileOutput(); o.WriteString("BCH"); o.Align(4); o.WriteByte(0x21); // version stuffs o.WriteByte(0x21); // version stuffs o.endian = System.IO.Endianness.Little; o.WriteShort(0xA755); // version FileOutput d_Main = new FileOutput(); d_Main.endian = System.IO.Endianness.Little; FileOutput d_Main2 = new FileOutput(); d_Main2.endian = System.IO.Endianness.Little; FileOutput d_Main3 = new FileOutput(); d_Main3.endian = System.IO.Endianness.Little; FileOutput d_String = new FileOutput(); d_String.endian = System.IO.Endianness.Little; FileOutput d_GPU = new FileOutput(); d_GPU.endian = System.IO.Endianness.Little; FileOutput d_Data = new FileOutput(); d_Data.endian = System.IO.Endianness.Little; FileOutput Reloc = new FileOutput(); Reloc.endian = System.IO.Endianness.Little; //Offsets o.WriteInt(0); //main o.WriteInt(0); //string o.WriteInt(0); //gpu o.WriteInt(0); //data o.WriteInt(0); //dataext o.WriteInt(0); //relocationtable //Length o.WriteInt(0); //main o.WriteInt(0); //string o.WriteInt(0); //gpu o.WriteInt(0); //data o.WriteInt(0); //dataext o.WriteInt(0); //relocationtable o.WriteInt(0); //datasection o.WriteInt(0); // o.WriteShort(1); //flag o.WriteShort(0); //addcount //Contents in the main header...... d_Main.WriteInt(0); // Model d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // Material d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // Shader d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // Texture d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // MaterialLUT d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // Lights d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // Camera d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // Fog d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); // SkeAnim { // Names need to be in patricia tree....... Dictionary <string, int> NameBank = new Dictionary <string, int>(); NameBank.Add("BustN", d_String.Size()); d_String.WriteString("BustN"); d_String.WriteByte(0); List <PatriciaTree.PatriciaTreeNode> Nodes = new List <PatriciaTree.PatriciaTreeNode>(); int maxlength = 0; foreach (Animation a in animations) { maxlength = Math.Max(maxlength, a.Text.Length); } Nodes.Add(new PatriciaTree.PatriciaTreeNode() { ReferenceBit = uint.MaxValue }); foreach (Animation a in animations) { PatriciaTree.Insert(Nodes, new PatriciaTree.PatriciaTreeNode() { Name = a.Text }, maxlength); } int nameOff = 0xb4 + d_Main2.Size(); foreach (PatriciaTree.PatriciaTreeNode node in Nodes) { d_Main2.WriteInt((int)node.ReferenceBit); d_Main2.WriteShort(node.LeftNodeIndex); d_Main2.WriteShort(node.RightNodeIndex); if (node.Name.Equals("")) { d_Main2.WriteInt(0); } else { NameBank.Add(node.Name, d_String.Size()); d_Main2.WriteOffset(d_String.Size(), d_String); d_String.WriteString(node.Name); d_String.WriteByte(0); } } // bones // Okay, first create the animation data then create the table pointng to it side by side int dataOff = 0xb4 + d_Main2.Size(); foreach (Animation a in animations) { d_Main2.WriteOffset(d_Main3.Size(), d_Main2); // now create the actual animation data I guess d_Main3.WriteOffset(NameBank[a.Text], d_String); // name offset d_Main3.WriteInt(0x2); // Flags TODO: What are these d_Main3.WriteFloat(a.frameCount + 1); d_Main3.WriteOffset(d_Main3.Size() + 12, d_Main3); // bone offset d_Main3.WriteInt(a.bones.Count); // bonecount d_Main3.WriteInt(0); // metadata nonsense FileOutput boneHeader = new FileOutput(); boneHeader.endian = System.IO.Endianness.Little; FileOutput keyData = new FileOutput(); keyData.endian = System.IO.Endianness.Little; int start = d_Main3.Size() + (a.bones.Count * 4); int track = 0; foreach (Animation.KeyNode node in a.bones) { d_Main3.WriteOffset(start + boneHeader.Size(), d_Main3); // bone offset // name type and flags if (!NameBank.ContainsKey(node.Text)) { NameBank.Add(node.Text, d_String.Size()); d_String.WriteString(node.Text); d_String.WriteByte(0); } boneHeader.WriteOffset(NameBank[node.Text], d_String); // name offset boneHeader.WriteInt(0x040000); // animation type flags, default is just simply transform // Actual Flags int flags = 0; flags |= (((node.xsca.keys.Count > 0) ? 0 : 1) << (16 + 0)); flags |= (((node.ysca.keys.Count > 0) ? 0 : 1) << (16 + 1)); flags |= (((node.zsca.keys.Count > 0) ? 0 : 1) << (16 + 2)); flags |= (((node.xrot.keys.Count > 0) ? 0 : 1) << (16 + 3)); flags |= (((node.yrot.keys.Count > 0) ? 0 : 1) << (16 + 4)); flags |= (((node.zrot.keys.Count > 0) ? 0 : 1) << (16 + 5)); flags |= (((node.xpos.keys.Count > 0) ? 0 : 1) << (16 + 6)); flags |= (((node.ypos.keys.Count > 0) ? 0 : 1) << (16 + 7)); flags |= (((node.zpos.keys.Count > 0) ? 0 : 1) << (16 + 8)); flags |= (((node.xsca.keys.Count == 1) ? 1 : 0) << (6 + 0)); flags |= (((node.ysca.keys.Count == 1) ? 1 : 0) << (6 + 1)); flags |= (((node.zsca.keys.Count == 1) ? 1 : 0) << (6 + 2)); flags |= (((node.xrot.keys.Count == 1) ? 1 : 0) << (6 + 3)); flags |= (((node.yrot.keys.Count == 1) ? 1 : 0) << (6 + 4)); flags |= (((node.zrot.keys.Count == 1) ? 1 : 0) << (6 + 5)); flags |= (((node.xpos.keys.Count == 1) ? 1 : 0) << (6 + 7)); flags |= (((node.ypos.keys.Count == 1) ? 1 : 0) << (6 + 8)); flags |= (((node.zpos.keys.Count == 1) ? 1 : 0) << (6 + 9)); boneHeader.WriteInt(flags); // Create KeyFrame Data int sta = start + (a.bones.Count * 12 * 4); WriteKeyData(node.xsca, boneHeader, keyData, d_Main3, sta, ref track); WriteKeyData(node.ysca, boneHeader, keyData, d_Main3, sta, ref track); WriteKeyData(node.zsca, boneHeader, keyData, d_Main3, sta, ref track); WriteKeyData(node.xrot, boneHeader, keyData, d_Main3, sta, ref track); WriteKeyData(node.yrot, boneHeader, keyData, d_Main3, sta, ref track); WriteKeyData(node.zrot, boneHeader, keyData, d_Main3, sta, ref track); WriteKeyData(node.xpos, boneHeader, keyData, d_Main3, sta, ref track); WriteKeyData(node.ypos, boneHeader, keyData, d_Main3, sta, ref track); WriteKeyData(node.zpos, boneHeader, keyData, d_Main3, sta, ref track); } d_Main3.WriteOutput(boneHeader); d_Main3.WriteOutput(keyData); } d_Main.WriteOffset(dataOff, d_Main); d_Main.WriteInt(animations.Count); // d_Main.WriteOffset(nameOff, d_Main); // } d_Main.WriteInt(0); // MaterialAnim d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // VisAnim d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // LightAnim d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // CameraAnim d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // FogAnim d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteInt(0); // Scene d_Main.WriteInt(0); // d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); // d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main2.WriteInt(0); d_Main.WriteOutput(d_Main2); d_Main.WriteOutput(d_Main3); int headSize = o.Size(); o.WriteIntAt(headSize, 0x08); o.WriteIntAt(d_Main.Size(), 0x20); o.WriteOutput(d_Main); o.Align(4); int stringSize = o.Size(); o.WriteIntAt(stringSize, 0x0C); o.WriteIntAt(d_String.Size(), 0x24); o.WriteOutput(d_String); o.Align(4); int gpuSize = o.Size(); o.WriteIntAt(d_GPU.Size() > 0 ? gpuSize : 0, 0x10); o.WriteIntAt(d_GPU.Size(), 0x28); o.WriteOutput(d_GPU); o.Align(0x100); int dataSize = o.Size(); o.WriteIntAt(dataSize, 0x14); o.WriteIntAt(dataSize, 0x18); o.WriteIntAt(d_Data.Size(), 0x2C); o.WriteIntAt(d_Data.Size(), 0x30); o.WriteOutput(d_Data); //Create Relocation Table // Flag is 7 bits // 0 - main 1 - string 2 - gpu 3 - data foreach (FileOutput.RelocOffset off in o.offsets) { int size = 0; int code = 0; int div = 4; if (off.output == d_Main || off.output == d_Main2 || off.output == d_Main3) { size = headSize; code = 0; if (off.output == d_Main3) { off.value += headSize; } if (off.output == d_Main2) { off.value += d_Main2.Size() + headSize; } } if (off.output == d_String) { size = stringSize; code = 1; div = 1; } if (off.output == d_GPU) { size = gpuSize; code = 2; } if (off.output == d_Data) { size = dataSize; code = 3; } o.WriteIntAt(off.value - size, off.position); int reloc = (code << 25) | (((off.position - headSize) / div) & 0x1FFFFFF); Reloc.WriteInt(reloc); } int relocSize = o.Size(); o.WriteIntAt(relocSize, 0x1C); o.WriteIntAt(Reloc.Size(), 0x34); o.WriteOutput(Reloc); o.Save(fname); }
public override byte[] Rebuild() { FileOutput f = new FileOutput(); f.endian = Endianness.Big; f.WriteString("MTA4"); f.WriteUInt(unknown); f.WriteUInt(frameCount); f.WriteUInt(startFrame); f.WriteUInt(endFrame); f.WriteUInt(frameRate); f.WriteInt(matEntries.Count); if (matEntries.Count > 0) { f.WriteInt(0x38); } else { f.WriteInt(0); } f.WriteInt(visEntries.Count); if (visEntries.Count > 0) { f.WriteInt(0x38 + 4 * matEntries.Count); } else { f.WriteInt(0); } for (int i = 0; i < 0x10; i++) { f.WriteByte(0); } List <byte[]> matEntriesBuilt = new List <byte[]>(); List <byte[]> visEntriesBuilt = new List <byte[]>(); int position = 0x38 + matEntries.Count + visEntries.Count; while (position % 0x10 != 0) { position++; } foreach (MatEntry m in matEntries) { byte[] b = m.Rebuild(position); matEntriesBuilt.Add(b); f.WriteInt(position); position += b.Length; while (position % 0x10 != 0) { position++; } } foreach (VisEntry v in visEntries) { byte[] b = v.Rebuild(position); matEntriesBuilt.Add(b); f.WriteInt(position); position += b.Length; while (position % 0x10 != 0) { position++; } } while (f.Pos() % 0x10 != 0) { f.WriteByte(0); } foreach (byte[] b in matEntriesBuilt) { f.WriteBytes(b); while (f.Pos() % 0x10 != 0) { f.WriteByte(0); } } foreach (byte[] b in visEntriesBuilt) { f.WriteBytes(b); while (f.Pos() % 0x10 != 0) { f.WriteByte(0); } } return(f.GetBytes()); }
public override byte[] Rebuild() { FileOutput o = new FileOutput(); FileOutput data = new FileOutput(); //We always want BE for the first six bytes o.endian = Endianness.Big; data.endian = Endianness.Big; if (Endian == Endianness.Big) { o.WriteUInt(0x4E545033); //NTP3 } else if (Endian == Endianness.Little) { o.WriteUInt(0x4E545744); //NTWD } //Most NTWU NUTs are 0x020E, which isn't valid for NTP3/NTWD if (Version > 0x0200) { Version = 0x0200; } o.WriteUShort(Version); //After that, endian is used appropriately o.endian = Endian; data.endian = Endian; o.WriteUShort((ushort)Nodes.Count); o.WriteInt(0); o.WriteInt(0); //calculate total header size uint headerLength = 0; foreach (NutTexture texture in Nodes) { byte surfaceCount = (byte)texture.surfaces.Count; bool isCubemap = surfaceCount == 6; if (surfaceCount < 1 || surfaceCount > 6) { throw new NotImplementedException($"Unsupported surface amount {surfaceCount} for texture with hash 0x{texture.HashId:X}. 1 to 6 faces are required."); } else if (surfaceCount > 1 && surfaceCount < 6) { throw new NotImplementedException($"Unsupported cubemap face amount for texture with hash 0x{texture.HashId:X}. Six faces are required."); } byte mipmapCount = (byte)texture.surfaces[0].mipmaps.Count; ushort headerSize = 0x50; if (isCubemap) { headerSize += 0x10; } if (mipmapCount > 1) { headerSize += (ushort)(mipmapCount * 4); while (headerSize % 0x10 != 0) { headerSize += 1; } } headerLength += headerSize; } // write headers+data foreach (NutTexture texture in Nodes) { byte surfaceCount = (byte)texture.surfaces.Count; bool isCubemap = surfaceCount == 6; byte mipmapCount = (byte)texture.surfaces[0].mipmaps.Count; uint dataSize = 0; foreach (var mip in texture.GetAllMipmaps()) { dataSize += (uint)mip.Length; while (dataSize % 0x10 != 0) { dataSize += 1; } } ushort headerSize = 0x50; if (isCubemap) { headerSize += 0x10; } if (mipmapCount > 1) { headerSize += (ushort)(mipmapCount * 4); while (headerSize % 0x10 != 0) { headerSize += 1; } } o.WriteUInt(dataSize + headerSize); o.WriteUInt(0); o.WriteUInt(dataSize); o.WriteUShort(headerSize); o.WriteUShort(0); o.WriteByte(0); o.WriteByte(mipmapCount); o.WriteByte(0); o.WriteByte(texture.getNutFormat()); o.WriteShort(texture.Width); o.WriteShort(texture.Height); o.WriteInt(0); o.WriteUInt(texture.DdsCaps2); if (Version < 0x0200) { o.WriteUInt(0); } else if (Version >= 0x0200) { o.WriteUInt((uint)(headerLength + data.Size())); } headerLength -= headerSize; o.WriteInt(0); o.WriteInt(0); o.WriteInt(0); if (isCubemap) { o.WriteInt(texture.surfaces[0].mipmaps[0].Length); o.WriteInt(texture.surfaces[0].mipmaps[0].Length); o.WriteInt(0); o.WriteInt(0); } if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17) { texture.SwapChannelOrderDown(); } for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel) { for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel) { int ds = data.Size(); data.WriteBytes(texture.surfaces[surfaceLevel].mipmaps[mipLevel]); data.Align(0x10); if (mipmapCount > 1 && surfaceLevel == 0) { o.WriteInt(data.Size() - ds); } } } o.Align(0x10); if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17) { texture.SwapChannelOrderUp(); } o.WriteBytes(new byte[] { 0x65, 0x58, 0x74, 0x00 }); // "eXt\0" o.WriteInt(0x20); o.WriteInt(0x10); o.WriteInt(0x00); o.WriteBytes(new byte[] { 0x47, 0x49, 0x44, 0x58 }); // "GIDX" o.WriteInt(0x10); o.WriteInt(texture.HashId); o.WriteInt(0); if (Version < 0x0200) { o.WriteOutput(data); data = new FileOutput(); } } if (Version >= 0x0200) { o.WriteOutput(data); } return(o.GetBytes()); }
public byte[] Rebuild(bool dump = false) { FileOutput o = new FileOutput(); TextWriter oldOut = Console.Out; MemoryStream ostrm = new MemoryStream(0xA00000); StreamWriter writer = new StreamWriter(ostrm); Console.SetOut(writer); // TODO: write correct filesize in header. // It isn't checked by the game, but what the hell, right? header.Write(o); writeSymbols(o); writeColors(o); writeTransforms(o); writePositions(o); writeBounds(o); Actionscript.Write(o); if (Actionscript2 != null) { Actionscript2.Write(o); } writeAtlases(o); unkF008.Write(o); unkF009.Write(o); unkF00A.Write(o); unk000A.Write(o); unkF00B.Write(o); properties.Write(o); Defines.numShapes = (uint)Shapes.Count; Defines.numSprites = (uint)Sprites.Count; Defines.numTexts = (uint)Texts.Count; Defines.Write(o); writeShapes(o); writeSprites(o); writeTexts(o); o.WriteInt((int)TagType.End); o.WriteInt(0); int padSize = (4 - (o.Size() % 4)) % 4; for (int i = 0; i < padSize; i++) { o.WriteByte(0); } if (dump) { writer.Flush(); using (var filestream = new FileStream("dump.txt", FileMode.Create)) ostrm.WriteTo(filestream); } Console.SetOut(oldOut); o.Save(Filename); return(o.GetBytes()); }
public byte[] Rebuild(int pos) { FileOutput f = new FileOutput(); f.endian = Endianness.Big; f.WriteInt(pos + f.Pos() + 0x20); f.WriteInt(matHash); f.WriteInt(properties.Count); int nameOffset = pos + f.Pos() + 0x15 + name.Length; while (nameOffset % 4 != 0) { nameOffset++; } f.WriteInt(nameOffset); f.WriteFlag(hasPat); f.WriteBytes(new byte[3]); //Write all the mat data into a buffer (g) then write pat offset int pos2 = pos + f.Pos() + 4; FileOutput g = new FileOutput(); g.endian = Endianness.Big; if (matHash2 != 0) { g.WriteInt(pos2 + g.Pos() + 0x8); g.WriteInt(matHash); } else { g.WriteBytes(new byte[8]); } g.WriteString(name); g.WriteByte(0); while ((pos2 + g.Pos()) % 0x10 != 0) { g.WriteByte(0); } int position = pos2 + g.Pos() + properties.Count * 4; while (position % 16 != 0) { position++; } List <byte[]> builtProperties = new List <byte[]>(); foreach (MatData prop in properties) { g.WriteInt(position); byte[] b = prop.Rebuild(position); builtProperties.Add(b); position += b.Length; while (position % 16 != 0) { position++; } } while ((pos2 + g.Pos()) % 16 != 0) { g.WriteByte(0); } foreach (byte[] b in builtProperties) { g.WriteBytes(b); while ((pos2 + g.Pos()) % 16 != 0) { g.WriteByte(0); } } f.WriteInt(pos2 + g.Pos()); f.WriteBytes(g.GetBytes()); if (hasPat) { f.WriteBytes(pat0.Rebuild(f.Pos())); } return(f.GetBytes()); }