Beispiel #1
0
        private static List<Texture2D> LoadTEX1FromFile(EndianBinaryReader reader, long chunkStart)
        {
            ushort textureCount = reader.ReadUInt16();
            ushort padding = reader.ReadUInt16(); // Usually 0xFFFF?
            uint textureHeaderOffset = reader.ReadUInt32(); // textureCount # bti image headers are stored here, relative to chunkStart.
            uint stringTableOffset = reader.ReadUInt32(); // One filename per texture. relative to chunkStart.
            List<Texture2D> textureList = new List<Texture2D>();

            // Get all Texture Names
            reader.BaseStream.Position = chunkStart + stringTableOffset;
            StringTable stringTable = StringTable.FromStream(reader);

            for (int t = 0; t < textureCount; t++)
            {
                // 0x20 is the length of the BinaryTextureImage header which all come in a row, but then the stream gets jumped around while loading the BTI file.
                reader.BaseStream.Position = chunkStart + textureHeaderOffset + (t * 0x20);
                BinaryTextureImage texture = new BinaryTextureImage();
                texture.Load(reader, chunkStart + 0x20, t);

                Texture2D texture2D = new Texture2D(texture.Width, texture.Height);
                texture2D.Name = stringTable[t];
                texture2D.PixelData = texture.GetData();
                textureList.Add(texture2D);

                string executionPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                texture.SaveImageToDisk(executionPath + "/TextureDump/" + string.Format("{0}_({1}-{2}).png", stringTable[t], texture.Format, t));
            }

            return textureList;
        }
Beispiel #2
0
        private static List <Texture2D> LoadTEX1FromFile(EndianBinaryReader reader, long chunkStart)
        {
            ushort           textureCount        = reader.ReadUInt16();
            ushort           padding             = reader.ReadUInt16(); // Usually 0xFFFF?
            uint             textureHeaderOffset = reader.ReadUInt32(); // textureCount # bti image headers are stored here, relative to chunkStart.
            uint             stringTableOffset   = reader.ReadUInt32(); // One filename per texture. relative to chunkStart.
            List <Texture2D> textureList         = new List <Texture2D>();

            // Get all Texture Names
            reader.BaseStream.Position = chunkStart + stringTableOffset;
            StringTable stringTable = StringTable.FromStream(reader);

            for (int t = 0; t < textureCount; t++)
            {
                // 0x20 is the length of the BinaryTextureImage header which all come in a row, but then the stream gets jumped around while loading the BTI file.
                reader.BaseStream.Position = chunkStart + textureHeaderOffset + (t * 0x20);
                BinaryTextureImage texture = new BinaryTextureImage();
                texture.Load(reader, chunkStart + 0x20, t);

                Texture2D texture2D = new Texture2D(texture.Width, texture.Height);
                texture2D.Name      = stringTable[t];
                texture2D.PixelData = texture.GetData();
                textureList.Add(texture2D);


                string executionPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                texture.SaveImageToDisk(executionPath + "/TextureDump/" + string.Format("{0}_({1}-{2}).png", stringTable[t], texture.Format, t));
            }

            return(textureList);
        }
Beispiel #3
0
        public void LoadTEX1FromStream(EndianBinaryReader reader, long tagStart, bool dumpTextures)
        {
            ushort numTextures = reader.ReadUInt16();

            Trace.Assert(reader.ReadUInt16() == 0xFFFF); // Padding

            int textureHeaderDataOffset = reader.ReadInt32();
            int stringTableOffset       = reader.ReadInt32();

            // Texture Names
            reader.BaseStream.Position = tagStart + stringTableOffset;
            StringTable nameTable = StringTable.FromStream(reader);

            Textures = new BindingList <Texture>();
            for (int t = 0; t < numTextures; t++)
            {
                // Reset the stream position to the start of this header as loading the actual data of the texture
                // moves the stream head around.
                reader.BaseStream.Position = tagStart + textureHeaderDataOffset + (t * 0x20);

                BinaryTextureImage compressedTex = new BinaryTextureImage();
                string             tempFileName  = string.Format("TextureDump/{1}_{0}.png", nameTable[t], t);
                if (!m_allowTextureCache || !File.Exists(tempFileName))
                {
                    compressedTex.Load(reader, tagStart + 0x20 /* Size of TEX1 header?*/, t);
                }
                else
                {
                    compressedTex.LoadImageFromDisk(tempFileName);
                }

                Texture texture = new Texture(nameTable[t], compressedTex);
                Textures.Add(texture);

                if (dumpTextures)
                {
                    compressedTex.SaveImageToDisk(string.Format("TextureDump/{2}__{0}_{1}_{3}.png", texture.Name, compressedTex.Format, t, compressedTex.PaletteFormat));
                }
            }
        }
Beispiel #4
0
        public void WriteObj(string f)
        {
            //string dirPath = Path.GetDirectoryName(f);
            string fileName = $"{ AppContext.BaseDirectory }\\{ Path.GetFileNameWithoutExtension(f) }";

            StringWriter objWriter = new StringWriter();
            StringWriter mtlWriter = new StringWriter();

            objWriter.WriteLine("# dumped with booldozer");
            objWriter.WriteLine($"mtllib { fileName }.mtl");

            foreach (var vert in verticies)
            {
                objWriter.WriteLine($"v {vert.X} {vert.Y} {vert.Z}");
            }

            if (normals.Count != 0)
            {
                foreach (var vert in normals)
                {
                    objWriter.WriteLine($"vn { vert.X } { vert.Y } { vert.Z }");
                }
            }

            if (uvs.Count != 0)
            {
                foreach (var vert in uvs)
                {
                    objWriter.WriteLine($"vt { vert.X } { 1 - vert.Y }");
                }
            }

            objWriter.WriteLine();

            int index = 0;

            foreach (DrawElement drw in drawelements)
            {
                Material mat = materials[drw.matIndex];
                GXBatch  shp = shapes[drw.shapeIndex];

                mtlWriter.WriteLine($"newmtl { index }");
                mtlWriter.WriteLine($"Kd { ((mat.color & 0xFF000000) >> 24) / 255 } { ((mat.color & 0x00FF0000) >> 16) / 255 } { ((mat.color & 0x0000FF00) >> 8) / 255 }");
                mtlWriter.WriteLine($"d { (mat.color & 0x000000FF) / 255 }");

                if (mat.num_tev_stages > 0)
                {
                    TexObj texObj = texobjs[mat.stages[0].texobj_index];
                    mtlWriter.WriteLine($"map_Kd { index }.png");
                    BinaryTextureImage tex = textures[texObj.textureIndex];
                    tex.SaveImageToDisk($"{ AppContext.BaseDirectory }\\{ index }.png", tex.GetData(), tex.Width, tex.Height);
                }

                objWriter.WriteLine($"o { index }");
                objWriter.WriteLine($"usemtl { index }");

                for (int i = 0; i < shp.RawVertices.Count; i += 3)
                {
                    string[] verts = new string[3] {
                        "", "", ""
                    };

                    for (int j = 0; j < 3; j++)
                    {
                        string pos  = "";
                        string uv   = "";
                        string norm = "";

                        if (shp.ActiveAttributes.Contains(GXAttribute.Position))
                        {
                            pos = $"{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Position)] + 1) }/";
                        }
                        if (shp.ActiveAttributes.Contains(GXAttribute.Tex0))
                        {
                            uv = $"{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Tex0)] + 1) }";
                        }
                        if (shp.ActiveAttributes.Contains(GXAttribute.Normal))
                        {
                            norm = $"/{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Normal)] + 1) }/";
                        }

                        verts[j] = $"{ pos }{ uv }{ norm }";
                    }

                    objWriter.WriteLine($"f { verts[0] } { verts[1] } { verts[2] }");
                }

                index++;
            }

            using (FileStream s = new FileStream($"{ fileName }.obj", FileMode.Create, FileAccess.Write))
            {
                EndianBinaryWriter w = new EndianBinaryWriter(s, Endian.Big);
                w.Write(objWriter.ToString().ToCharArray());
            }

            using (FileStream s = new FileStream($"{ fileName }.mtl", FileMode.Create, FileAccess.Write))
            {
                EndianBinaryWriter w = new EndianBinaryWriter(s, Endian.Big);
                w.Write(mtlWriter.ToString().ToCharArray());
            }
        }