Example #1
0
        public Level5_Resource(byte[] data)
        {
            data = Decompress.Level5Decom(data);
            using (DataReader r = new DataReader(new System.IO.MemoryStream(data)))
            {
                var magic = new string(r.ReadChars(6));
                if (magic != "CHRC00" && magic != "CHRN01")
                {
                    throw new FormatException("RES file is corrupt");
                }

                // -----------------------
                var unknown0                  = r.ReadInt16();
                var stringTableOffset         = r.ReadInt16() << 2;
                var unknown1                  = r.ReadInt16();
                var materialTableOffset       = r.ReadInt16() << 2;
                var materialTableSectionCount = r.ReadInt16();
                var resourceNodeOffsets       = r.ReadInt16() << 2;
                var resourceNodeCount         = r.ReadInt16();

                r.Seek((uint)stringTableOffset);
                while (r.Position < r.BaseStream.Length)
                {
                    string mname = r.ReadString();
                    if (mname == "")
                    {
                        break;
                    }
                    if (!ResourceNames.ContainsKey(CRC32.Crc32C(mname)))
                    {
                        ResourceNames.Add(CRC32.Crc32C(mname), mname);
                    }
                }

                r.Seek((uint)materialTableOffset);
                for (int i = 0; i < materialTableSectionCount; i++)
                {
                    var offset  = r.ReadInt16() << 2;
                    var count   = r.ReadInt16();
                    var unknown = r.ReadInt16();
                    var size    = r.ReadInt16();

                    if (unknown == 0x270F)
                    {
                        continue;
                    }

                    var temp = r.Position;
                    for (int j = 0; j < count; j++)
                    {
                        r.Position = (uint)(offset + j * size);
                        var    key          = r.ReadUInt32();
                        string resourceName = (ResourceNames.ContainsKey(key) ? ResourceNames[key] : key.ToString("X"));
                        //Console.WriteLine(resourceName + " " + unknown.ToString("X") + " " + size.ToString("X"));

                        if (unknown == 0xF0)
                        {
                            TextureNames.Add(resourceName);
                        }
                        if (unknown == 0x122)
                        {
                            Level5_Material mat = new Level5_Material();
                            mat.Name = resourceName;
                            r.Skip(12);
                            key          = r.ReadUInt32();
                            resourceName = (ResourceNames.ContainsKey(key) ? ResourceNames[key] : key.ToString("X"));
                            mat.TexName  = resourceName;
                            Console.WriteLine(resourceName + " " + unknown.ToString("X") + " " + size.ToString("X"));
                            Materials.Add(mat);
                        }
                    }

                    r.Seek(temp);
                }

                r.Seek((uint)resourceNodeOffsets);
                for (int i = 0; i < resourceNodeCount; i++)
                {
                    var offset  = r.ReadInt16() << 2;
                    var count   = r.ReadInt16();
                    var unknown = r.ReadInt16();
                    var size    = r.ReadInt16();

                    if (unknown == 0x270F)
                    {
                        continue;
                    }

                    var temp = r.Position;
                    r.Seek((uint)offset);
                    for (int j = 0; j < count; j++)
                    {
                        var key = r.ReadUInt32();
                        //Console.WriteLine((ResourceNames.ContainsKey(key) ? ResourceNames[key] : key.ToString("X")) + " " + unknown.ToString("X") + " " + size.ToString("X"));
                        r.Position += (uint)(size - 4);
                    }

                    r.Seek(temp);
                }
            }
        }
Example #2
0
        public void Open(FileItem File)
        {
            using (DataReader r = new DataReader(new MemoryStream(File.GetFileBinary())))
            {
                if (!new string(r.ReadChars(4)).Equals("XPCK"))
                {
                    throw new Exception("File header error");
                }

                uint fileCount = (uint)(r.ReadUInt16() & 0xFFF);

                var fileInfoOffset  = r.ReadUInt16() * 4;
                var fileTableOffset = r.ReadUInt16() * 4;
                var dataOffset      = r.ReadUInt16() * 4;

                r.ReadUInt16();
                var filenameTableSize = r.ReadUInt16() * 4;

                var hashToData = new Dictionary <uint, byte[]>();
                r.Seek((uint)fileInfoOffset);
                for (int i = 0; i < fileCount; i++)
                {
                    var nameCRC = r.ReadUInt32();
                    r.ReadInt16();
                    var offset    = (uint)r.ReadUInt16();
                    var size      = (uint)r.ReadUInt16();
                    var offsetExt = (uint)r.ReadByte();
                    var sizeExt   = (uint)r.ReadByte();

                    offset |= offsetExt << 16;
                    size   |= sizeExt << 16;
                    offset  = (uint)(offset * 4 + dataOffset);

                    var data = r.GetSection(offset, (int)size);
                    //Decompress.CheckLevel5Zlib(data, out data);

                    hashToData.Add(nameCRC, data);
                }

                byte[] nameTable = r.GetSection((uint)fileTableOffset, filenameTableSize);
                if (!Decompress.CheckLevel5Zlib(nameTable, out nameTable))
                {
                    nameTable = Decompress.lzss_Decompress(nameTable);
                }
                using (DataReader nt = new DataReader(new MemoryStream(nameTable)))
                {
                    for (int i = 0; i < fileCount; i++)
                    {
                        var name = nt.ReadString();

                        if (hashToData.ContainsKey(CRC32.Crc32C(name)))
                        {
                            Files.Add(name, hashToData[CRC32.Crc32C(name)]);
                        }
                        else
                        {
                            Console.WriteLine("Couldn't find " + name + " " + CRC32.Crc32C(name).ToString("X"));
                        }
                    }
                }
            }
        }