Beispiel #1
0
        static MDBBody ParseMDB(Stream stream)
        {
            byte[] temp4 = new byte[0x4];
            if (stream.Read(temp4, 0, 0x4) != 0x4)
            {
                Console.WriteLine("Head const read fail");
                return(null);
            }
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(temp4, 0, 0x4);
            }

            MDBBody body = new MDBBody();

            if ((body.head = BitConverter.ToInt32(temp4, 0)) != 0x08)
            {
                Console.WriteLine("Head const read mismatch, value {0:X}", body.head);
                return(null);
            }
            if (stream.Read(temp4, 0, 0x4) != 0x4)
            {
                Console.WriteLine("unknown_flag read fail");
                return(null);
            }
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(temp4, 0, 0x4);
            }
            body.unknown_flag = BitConverter.ToBoolean(temp4, 0);

            if (stream.Read(temp4, 0, 0x4) != 0x4)
            {
                Console.WriteLine("num texture entries read fail");
                return(null);
            }
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(temp4, 0, 0x4);
            }
            body.num_texture_entries = BitConverter.ToInt32(temp4, 0);
            body.texture_entries     = new TextureEntry[body.num_texture_entries];
            for (int i = 0; i < body.num_texture_entries; i++)
            {
                TextureEntry te = new TextureEntry {
                    texture_name = AstebreedUtil.StreamNullTermStr(stream),
                    file_name    = AstebreedUtil.StreamNullTermStr(stream)
                };
                body.texture_entries[i] = te;
            }
            if (stream.Read(temp4, 0, 0x4) != 0x4)
            {
                Console.WriteLine("num texture names read fail");
                return(null);
            }
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(temp4, 0, 0x4);
            }
            body.num_texture_names = BitConverter.ToInt32(temp4, 0);
            body.texture_names     = new string[body.num_texture_names];
            for (int i = 0; i < body.num_texture_names; i++)
            {
                body.texture_names[i] = AstebreedUtil.StreamNullTermStr(stream);
            }
            if (stream.Read(temp4, 0, 0x4) != 0x4)
            {
                Console.WriteLine("num mat entries read fail");
                return(null);
            }
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(temp4, 0, 0x4);
            }
            body.num_mat_entries = BitConverter.ToInt32(temp4, 0);
            body.mat_entries     = new MatEntry[body.num_mat_entries];
            for (int i = 0; i < body.num_mat_entries; i++)
            {
                MatEntry me = new MatEntry {
                    mat_name = AstebreedUtil.StreamNullTermStr(stream)
                };
                me._populated = me.mat_name.Length != 0;
                if (stream.Read(temp4, 0, 0x4) != 0x4)
                {
                    Console.WriteLine("num mat kvps read fail");
                    return(null);
                }
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(temp4, 0, 0x4);
                }
                me.num_mat_kvps = BitConverter.ToInt32(temp4, 0);
                me.mat_kvps     = new MatKVP[me.num_mat_kvps];
                for (int j = 0; j < me.num_mat_kvps; j++)
                {
                    MatKVP kvp = new MatKVP();
                    kvp.key = AstebreedUtil.StreamNullTermStr(stream);
                    if (stream.Read(temp4, 0, 0x4) != 0x4)
                    {
                        Console.WriteLine("kvp word count read fail");
                        return(null);
                    }
                    if (!BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(temp4, 0, 0x4);
                    }
                    kvp.wordcount = BitConverter.ToInt32(temp4, 0);
                    kvp.value     = new byte[kvp.wordcount * 4];
                    if (stream.Read(kvp.value, 0, kvp.value.Length) != kvp.value.Length)
                    {
                        Console.WriteLine("kvp value read fail");
                        return(null);
                    }
                    me.mat_kvps[j] = kvp;
                }
                if (stream.Read(temp4, 0, 0x4) != 0x4)
                {
                    Console.WriteLine("num shader tex mappings read fail");
                    return(null);
                }
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(temp4, 0, 0x4);
                }
                me.num_shader_texture_mapping_entries = BitConverter.ToInt32(temp4, 0);
                me.shader_texture_mapping_entries     = new ShaderTextureMappingEntry[me.num_shader_texture_mapping_entries];
                for (int j = 0; j < me.num_shader_texture_mapping_entries; j++)
                {
                    ShaderTextureMappingEntry se = new ShaderTextureMappingEntry {
                        shader_param_name = AstebreedUtil.StreamNullTermStr(stream),
                        texture_name      = AstebreedUtil.StreamNullTermStr(stream)
                    };
                    me.shader_texture_mapping_entries[j] = se;
                }
                me.shader_name = AstebreedUtil.StreamNullTermStr(stream);
                if (stream.Read(temp4, 0, 0x4) != 0x4)
                {
                    Console.WriteLine("unknown val 1 read fail");
                    return(null);
                }
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(temp4, 0, 0x4);
                }
                me.unknown_num_1    = BitConverter.ToInt32(temp4, 0);
                body.mat_entries[i] = me;
            }
            if (stream.Read(temp4, 0, 0x4) != 0x4)
            {
                Console.WriteLine("num node entries read fail");
                return(null);
            }
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(temp4, 0, 0x4);
            }
            body.num_node_entries = BitConverter.ToInt32(temp4, 0);
            body.node_entries     = new NodeEntry[body.num_node_entries];
            for (int i = 0; i < body.num_node_entries; i++)
            {
                NodeEntry ne = new NodeEntry();
                ne.node_name   = AstebreedUtil.StreamNullTermStr(stream);
                ne.parent_node = AstebreedUtil.StreamNullTermStr(stream);
                ne.node_type   = AstebreedUtil.StreamNullTermStr(stream);
                ne.data        = new byte[68];
                if (stream.Read(ne.data, 0, 68) != 68)
                {
                    Console.WriteLine("node data read fail");
                    return(null);
                }
                body.node_entries[i] = ne;
            }
            if (stream.Read(temp4, 0, 0x4) != 0x4)
            {
                Console.WriteLine("num meshes read fail");
                return(null);
            }
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(temp4, 0, 0x4);
            }
            body.num_meshes = BitConverter.ToInt32(temp4);
            body.meshes     = new Mesh[body.num_meshes];
            for (int i = 0; i < body.num_meshes; i++)
            {
                Mesh mesh = new Mesh {
                    mesh_name = AstebreedUtil.StreamNullTermStr(stream)
                };
                if (stream.Read(temp4, 0, 0x4) != 0x4)
                {
                    Console.WriteLine("unknown val 2 read fail");
                    return(null);
                }
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(temp4, 0, 0x4);
                }
                mesh.unknown_num_2 = BitConverter.ToInt32(temp4, 0);
                mesh.data          = new byte[28];
                if (stream.Read(mesh.data, 0, 28) != 28)
                {
                    Console.WriteLine("mesh data read fail");
                    return(null);
                }
                if (stream.Read(temp4, 0, 0x4) != 0x4)
                {
                    Console.WriteLine("num node ids read fail");
                    return(null);
                }
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(temp4, 0, 0x4);
                }
                mesh.num_node_ids = BitConverter.ToInt32(temp4, 0);
                mesh.node_ids     = new NodeID[mesh.num_node_ids];
                for (int j = 0; j < mesh.num_node_ids; j++)
                {
                    NodeID ni = new NodeID();
                    ni._             = (byte)stream.ReadByte();
                    ni.node_name     = AstebreedUtil.StreamNullTermStr(stream);
                    mesh.node_ids[j] = ni;
                }
                if (stream.Read(temp4, 0, 0x4) != 0x4)
                {
                    Console.WriteLine("num vertices read fail");
                    return(null);
                }
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(temp4, 0, 0x4);
                }
                mesh.num_vertices = BitConverter.ToInt32(temp4, 0);
                if (stream.Read(temp4, 0, 0x4) != 0x4)
                {
                    Console.WriteLine("vertex length read fail");
                    return(null);
                }
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(temp4, 0, 0x4);
                }
                mesh.vertex_length = BitConverter.ToInt32(temp4, 0);
                mesh.vertices      = new Vertex[mesh.num_vertices];
                for (int j = 0; j < mesh.num_vertices; j++)
                {
                    Vertex v = new Vertex();
                    v.data = new byte[mesh.vertex_length];
                    if (stream.Read(v.data, 0, v.data.Length) != v.data.Length)
                    {
                        Console.WriteLine("vertex data read fail");
                        return(null);
                    }
                    mesh.vertices[j] = v;
                }
                body.meshes[i] = mesh;
            }
            body.foot = new byte[24];
            if (stream.Read(body.foot, 0, body.foot.Length) != body.foot.Length)
            {
                Console.WriteLine("body foot read fail");
                return(null);
            }
            Console.WriteLine("End read @ {0}", stream.Position);
            return(body);
        }
Beispiel #2
0
        static void MDBFmtParseAttempt()
        {
            Console.WriteLine("Enter file to parse.");
            string  file = Console.ReadLine();
            MDBBody body = ParseMDB(new FileStream(file, FileMode.Open, FileAccess.Read));

            if (body == null)
            {
                return;
            }
            Console.WriteLine("Done parsing.");
            byte[] temp4 = new byte[4];
            foreach (Mesh mesh in body.meshes)
            {
                Console.WriteLine("Mesh {0}", mesh.mesh_name);
                byte[]  mins      = new byte[mesh.vertex_length];
                byte[]  maxes     = new byte[mesh.vertex_length];
                float[] minFloats = new float[mesh.vertex_length / 4];
                float[] maxFloats = new float[mesh.vertex_length / 4];
                //byte[] temp = new byte[0x14];
                for (int i = 0; i < mesh.vertex_length; i++)
                {
                    byte val = mesh.vertices[0].data[i];
                    mins[i]  = val;
                    maxes[i] = val;
                }
                for (int i = 0; i < mesh.vertex_length / 4; i++)
                {
                    Array.Copy(mesh.vertices[0].data, i * 4, temp4, 0, 4);
                    float val = BitConverter.ToSingle(temp4);
                    minFloats[i] = val;
                    maxFloats[i] = val;
                }
                foreach (Vertex v in mesh.vertices)
                {
                    //AstebreedUtil.PrintHexArray(v.data, 0x20, 0x20, false);

                    /*
                     * AstebreedUtil.JustPrintFloat(v.data, 0x0, true);
                     * Console.Write(' ');
                     * AstebreedUtil.JustPrintFloat(v.data, 0x4, true);
                     * Console.Write(' ');
                     * AstebreedUtil.JustPrintFloat(v.data, 0x8, true);
                     * Console.WriteLine();
                     */

                    /*Array.Copy(v.data, 0xC, temp, 0, 0x14);
                     * if (!BitConverter.IsLittleEndian) {
                     *  Array.Reverse(temp, 0x0, 0x4);
                     *  Array.Reverse(temp, 0x4, 0x4);
                     * }
                     * float f1 = BitConverter.ToSingle(temp, 0x0), f2 = BitConverter.ToSingle(temp, 0x4);
                     * if (f1 < 0.99f) {
                     *  AstebreedUtil.PrintHexArray(v.data, 0xC, 0x14, false);
                     *  Console.Write("\t");
                     *  Console.Write("{0} {1}", f1, f2);
                     *  Console.WriteLine();
                     * }*/
                    for (int i = 0; i < mesh.vertex_length; i++)
                    {
                        byte val = v.data[i];
                        mins[i]  = Math.Min(val, mins[i]);
                        maxes[i] = Math.Max(val, maxes[i]);
                    }
                    for (int i = 0; i < mesh.vertex_length / 4; i++)
                    {
                        Array.Copy(v.data, i * 4, temp4, 0, 4);
                        float val = BitConverter.ToSingle(temp4);
                        minFloats[i] = Math.Min(val, minFloats[i]);
                        maxFloats[i] = Math.Max(val, maxFloats[i]);
                    }
                }
                Console.WriteLine("     Min | Max");
                for (int i = 0; i < mesh.vertex_length; i++)
                {
                    Console.WriteLine("{0,4:X4} {1,2:X2}    {2,2:X2}", i, mins[i], maxes[i]);
                }
                Console.WriteLine("     FMin | FMax");
                for (int i = 0; i < mesh.vertex_length / 4; i++)
                {
                    Console.WriteLine("{0} {1} {2}", i, minFloats[i], maxFloats[i]);
                }

                /*AstebreedUtil.PrintHexArray(mins, 0, mins.Length, true);
                 * Console.WriteLine();
                 * AstebreedUtil.PrintHexArray(maxes, 0, maxes.Length, true);
                 * Console.WriteLine();*/
            }
        }