Exemple #1
0
        static void MetatadaToINI(byte[] file, string filename)
        {
            DLCMetadata header = new DLCMetadata();

            //Get title
            byte[] title_b       = GetTextItem(ref file, 0, 16);
            byte[] description_b = GetTextItem(ref file, 0x10, 32);
            byte[] appname_b     = GetTextItem(ref file, 0x30, 16);
            header.description = System.Text.Encoding.GetEncoding(932).GetString(description_b);
            header.title       = System.Text.Encoding.GetEncoding(932).GetString(title_b);
            header.appname     = System.Text.Encoding.GetEncoding(932).GetString(appname_b);
            //Get items
            int item_pointer = BitConverter.ToInt32(file, 0x280);

            header.dlc_id = BitConverter.ToUInt32(file, item_pointer);
            Console.WriteLine("Identifier: {0}", header.dlc_id);
            if ((file[item_pointer + 4] & 0xF) > 0)
            {
                header.chars_sonic = true;
            }
            if ((file[item_pointer + 4] >> 4) > 0)
            {
                header.chars_tails = true;
            }
            if ((file[item_pointer + 5] & 0xF) > 0)
            {
                header.chars_knuckles = true;
            }
            if ((file[item_pointer + 5] >> 4) > 0)
            {
                header.chars_e102 = true;
            }
            if ((file[item_pointer + 6] & 0xF) > 0)
            {
                header.chars_amy = true;
            }
            if ((file[item_pointer + 6] >> 4) > 0)
            {
                header.chars_big = true;
            }
            Console.Write("Characters: ");
            if (header.chars_sonic)
            {
                Console.Write("Sonic ");
            }
            if (header.chars_tails)
            {
                Console.Write("Tails ");
            }
            if (header.chars_knuckles)
            {
                Console.Write("Knuckles ");
            }
            if (header.chars_amy)
            {
                Console.Write("Amy ");
            }
            if (header.chars_big)
            {
                Console.Write("Big ");
            }
            if (header.chars_e102)
            {
                Console.Write("Gamma");
            }
            Console.Write(System.Environment.NewLine);
            header.whatever = file[item_pointer + 7];
            header.region   = (DLCRegionLocks)BitConverter.ToInt32(file, item_pointer + 8);
            int item_count = BitConverter.ToInt32(file, 0x284);

            Console.WriteLine("Item table at {0}, count {1} (size {2} + 12)", item_pointer.ToString("X"), item_count, item_count * 30);
            header.items  = new List <DLCObjectData>(item_count);
            item_pointer += 12;             //Skip 12-byte item section header
            for (int u = 0; u < item_count; u++)
            {
                DLCObjectData dlcitem = new DLCObjectData();
                dlcitem.level      = file[item_pointer + u * 30];
                dlcitem.act        = file[item_pointer + u * 30 + 1];
                dlcitem.scale_x    = file[item_pointer + u * 30 + 2];
                dlcitem.scale_y    = file[item_pointer + u * 30 + 3];
                dlcitem.scale_z    = file[item_pointer + u * 30 + 4];
                dlcitem.rotspeed_x = (sbyte)file[item_pointer + u * 30 + 5];
                dlcitem.rotspeed_y = (sbyte)file[item_pointer + u * 30 + 6];
                dlcitem.rotspeed_z = (sbyte)file[item_pointer + u * 30 + 7];
                dlcitem.objecttype = (DLCObjectTypes)file[item_pointer + u * 30 + 8];
                dlcitem.textureid  = file[item_pointer + u * 30 + 9];
                dlcitem.flags      = (DLCObjectFlags)(BitConverter.ToUInt16(file, item_pointer + u * 30 + 10));
                dlcitem.objectid   = file[item_pointer + u * 30 + 12];
                dlcitem.unknown3   = file[item_pointer + u * 30 + 13];
                dlcitem.message    = file[item_pointer + u * 30 + 14];
                dlcitem.radius     = file[item_pointer + u * 30 + 15];
                dlcitem.warplevel  = file[item_pointer + u * 30 + 16];
                dlcitem.sound      = file[item_pointer + u * 30 + 17];
                dlcitem.rot_x      = BitConverter.ToUInt16(file, item_pointer + u * 30 + 18);
                dlcitem.rot_y      = BitConverter.ToUInt16(file, item_pointer + u * 30 + 20);
                dlcitem.rot_z      = BitConverter.ToUInt16(file, item_pointer + u * 30 + 22);
                dlcitem.x          = BitConverter.ToInt16(file, item_pointer + u * 30 + 24);
                dlcitem.y          = BitConverter.ToInt16(file, item_pointer + u * 30 + 26);
                dlcitem.z          = BitConverter.ToInt16(file, item_pointer + u * 30 + 28);
                header.items.Add(dlcitem);
            }
            //Get strings
            header.JapaneseStrings = new string[16];
            header.EnglishStrings  = new string[16];
            header.FrenchStrings   = new string[16];
            header.SpanishStrings  = new string[16];
            header.GermanStrings   = new string[16];
            int text_pointer = BitConverter.ToInt32(file, 0x288);
            int text_count   = BitConverter.ToInt32(file, 0x28C);

            Console.WriteLine("String table at {0}, count {1} (size {2})", text_pointer.ToString("X"), text_count, text_count * 64);
            List <string> strings = new List <string>();

            for (int u = 0; u < text_count; u++)
            {
                byte[] arr = new byte[64];
                Array.Copy(file, text_pointer + 64 * u, arr, 0, 64);
                int charcount = 0;
                for (int a = 0; a < arr.Length; a++)
                {
                    if (arr[a] == 0)
                    {
                        break;
                    }
                    charcount++;
                }
                System.Text.Encoding enc = System.Text.Encoding.GetEncoding(932);
                if (u >= 32)
                {
                    enc = System.Text.Encoding.GetEncoding(1252);
                }
                string str = enc.GetString(arr, 0, charcount);
                strings.Add(str);
            }
            //Process special characters
            List <string> strings_new = new List <string>();

            foreach (string str in strings)
            {
                string newstr = System.String.Empty;
                for (int s = 0; s < str.Length; s++)
                {
                    if (s == 0 && (str[s] == '~' || str[s] == 't'))
                    {
                        newstr += ("\t");
                    }
                    else if (str[s] == 't' && str[0] == 't')
                    {
                        newstr += ("\t");
                    }
                    else if (str[s] == '~' && str[0] == '~')
                    {
                        newstr += ("\t");
                    }
                    else if ((str[s] == 'n' && str[0] == 't') || (str[s] == '@' && str[0] == '~'))
                    {
                        newstr += ("\n");
                    }
                    else
                    {
                        newstr += str[s];
                    }
                }
                strings_new.Add(newstr);
            }
            string[] stringarr = strings_new.ToArray();
            for (int u = 0; u < 16; u++)
            {
                if (u >= text_count)
                {
                    break;
                }
                header.JapaneseStrings[u] = stringarr[u];
                if (text_count <= 16)
                {
                    continue;
                }
                header.EnglishStrings[u] = stringarr[u + 16];
                if (text_count <= 32)
                {
                    continue;
                }
                header.FrenchStrings[u] = stringarr[u + 32];
                if (text_count <= 48)
                {
                    continue;
                }
                header.SpanishStrings[u] = stringarr[u + 48];
                if (text_count <= 64)
                {
                    continue;
                }
                header.GermanStrings[u] = stringarr[u + 64];
            }
            //Check if an MLT is present
            int mlt_value = BitConverter.ToInt32(file, 0x2A0);

            if (mlt_value != 0)
            {
                header.has_mlt = true;
            }
            IniSerializer.Serialize(header, filename);
        }
Exemple #2
0
        static byte[] ConvertMetadata(string filename)
        {
            Console.WriteLine("Converting DLC metadata: {0}", filename);
            DLCMetadata header = IniSerializer.Deserialize <DLCMetadata>(filename);

            byte[] mlt = new byte[0];
            byte[] prs;
            byte[] pvm = File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, Path.GetFileNameWithoutExtension(filename), Path.GetFileNameWithoutExtension(filename) + ".pvm"));
            if (File.Exists(Path.Combine(Environment.CurrentDirectory, Path.GetFileNameWithoutExtension(filename), Path.GetFileNameWithoutExtension(filename) + ".bin")))
            {
                prs = FraGag.Compression.Prs.Compress(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, Path.GetFileNameWithoutExtension(filename), Path.GetFileNameWithoutExtension(filename) + ".bin")));
                Console.WriteLine("Using binary data instead of SA1MDL file");
            }
            else
            {
                prs = ConvertModel(Path.Combine(Environment.CurrentDirectory, Path.GetFileNameWithoutExtension(filename), Path.GetFileNameWithoutExtension(filename) + ".sa1mdl"));
            }
            if (header.has_mlt)
            {
                mlt = File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, Path.GetFileNameWithoutExtension(filename), Path.GetFileNameWithoutExtension(filename) + ".mlt"));
            }
            List <byte> result = new List <byte>();
            //Convert item table header
            List <byte> itemtable = new List <byte>();

            itemtable.AddRange(BitConverter.GetBytes(header.dlc_id));
            Console.WriteLine("Identifier: {0}", header.dlc_id);
            byte chars_sonictails = 0;
            byte chars_knuxe102   = 0;
            byte chars_amybig     = 0;

            if (header.chars_sonic)
            {
                chars_sonictails |= 0x1;
            }
            if (header.chars_tails)
            {
                chars_sonictails |= 0x10;
            }
            itemtable.Add(chars_sonictails);
            if (header.chars_knuckles)
            {
                chars_knuxe102 |= 0x1;
            }
            if (header.chars_e102)
            {
                chars_knuxe102 |= 0x10;
            }
            itemtable.Add(chars_knuxe102);
            if (header.chars_amy)
            {
                chars_amybig |= 0x1;
            }
            if (header.chars_big)
            {
                chars_amybig |= 0x10;
            }
            itemtable.Add(chars_amybig);
            itemtable.Add(header.whatever);
            itemtable.AddRange(BitConverter.GetBytes((int)(header.region)));
            Console.Write("Characters: ");
            if (header.chars_sonic)
            {
                Console.Write("Sonic ");
            }
            if (header.chars_tails)
            {
                Console.Write("Tails ");
            }
            if (header.chars_knuckles)
            {
                Console.Write("Knuckles ");
            }
            if (header.chars_amy)
            {
                Console.Write("Amy ");
            }
            if (header.chars_big)
            {
                Console.Write("Big ");
            }
            if (header.chars_e102)
            {
                Console.Write("Gamma");
            }
            Console.Write(System.Environment.NewLine);
            //Convert item table
            foreach (DLCObjectData item in header.items)
            {
                itemtable.Add(item.level);
                itemtable.Add(item.act);
                itemtable.Add(item.scale_x);
                itemtable.Add(item.scale_y);
                itemtable.Add(item.scale_z);
                itemtable.Add((byte)item.rotspeed_x);
                itemtable.Add((byte)item.rotspeed_y);
                itemtable.Add((byte)item.rotspeed_z);
                itemtable.Add((byte)item.objecttype);
                itemtable.Add(item.textureid);
                itemtable.AddRange((BitConverter.GetBytes((ushort)item.flags)));
                itemtable.Add(item.objectid);
                itemtable.Add(item.unknown3);
                itemtable.Add(item.message);
                itemtable.Add(item.radius);
                itemtable.Add(item.warplevel);
                itemtable.Add(item.sound);
                itemtable.AddRange(BitConverter.GetBytes(item.rot_x));
                itemtable.AddRange(BitConverter.GetBytes(item.rot_y));
                itemtable.AddRange(BitConverter.GetBytes(item.rot_z));
                itemtable.AddRange(BitConverter.GetBytes(item.x));
                itemtable.AddRange(BitConverter.GetBytes(item.y));
                itemtable.AddRange(BitConverter.GetBytes(item.z));
            }
            do
            {
                itemtable.Add(0);
            }while (itemtable.Count % 16 != 0);
            //Convert Japanese strings
            List <byte> stringtable = new List <byte>();

            foreach (string str in header.JapaneseStrings)
            {
                for (int s = 0; s < str.Length; s++)
                {
                    if (str[s] == '\t')
                    {
                        stringtable.AddRange(System.Text.Encoding.GetEncoding(932).GetBytes("t"));
                    }
                    else if (str[s] == '\n')
                    {
                        stringtable.AddRange(System.Text.Encoding.GetEncoding(932).GetBytes("n"));
                    }
                    else
                    {
                        stringtable.AddRange(System.Text.Encoding.GetEncoding(932).GetBytes(str[s].ToString()));
                    }
                }
                do
                {
                    stringtable.Add(0);
                }while (stringtable.Count % 64 != 0);
            }
            //Convert European strings
            stringtable.AddRange(ProcessEuropeanStrings(header.EnglishStrings, 932));             //English uses the same character set as Japanese
            stringtable.AddRange(ProcessEuropeanStrings(header.FrenchStrings));
            stringtable.AddRange(ProcessEuropeanStrings(header.SpanishStrings));
            stringtable.AddRange(ProcessEuropeanStrings(header.GermanStrings));
            //Set size
            int fullsize = mlt.Length + prs.Length + pvm.Length + itemtable.Count + stringtable.Count + 64;             //64 is sections table at 0x280 w/checksum + 16 bytes of padding

            if ((fullsize + 640) % 512 != 0)
            {
                do
                {
                    fullsize++;
                }while ((fullsize + 640) % 512 != 0);
            }
            //Convert title
            byte[] title_b = new byte[16];
            byte[] title   = System.Text.Encoding.GetEncoding(932).GetBytes(header.title);
            Array.Copy(title, 0, title_b, 0, title.Length);
            result.AddRange(title_b);
            byte[] desc_b = new byte[32];
            byte[] desc   = System.Text.Encoding.GetEncoding(932).GetBytes(header.description);
            Array.Copy(desc, 0, desc_b, 0, desc.Length);
            result.AddRange(desc_b);
            byte[] app_b = new byte[16];
            byte[] app   = System.Text.Encoding.GetEncoding(932).GetBytes(header.appname);
            Array.Copy(app, 0, app_b, 0, app.Length);
            result.AddRange(app_b);
            result.AddRange(BitConverter.GetBytes((ushort)1));             //Number of icons
            result.AddRange(BitConverter.GetBytes((ushort)1));             //Animation speed
            result.AddRange(BitConverter.GetBytes((ushort)0));             //Eyecatch type
            result.AddRange(BitConverter.GetBytes((ushort)0));             //CRC (unused)
            result.AddRange(BitConverter.GetBytes((uint)fullsize));        //Size of the entire thing without VMS header
            for (int u = 0; u < 20; u++)
            {
                result.Add(0);
            }
            result.AddRange(ConvertIcon(Path.Combine(Environment.CurrentDirectory, Path.GetFileNameWithoutExtension(filename), Path.GetFileNameWithoutExtension(filename) + ".bmp")));
            result.AddRange(BitConverter.GetBytes((uint)0x2C0));             //Item layout table pointer
            Console.WriteLine("Item table at 2C0, count {0} (size {1} + 12)", header.items.Count, header.items.Count * 30);
            result.AddRange(BitConverter.GetBytes((uint)header.items.Count));
            int textpointer = 704 + itemtable.Count;

            result.AddRange(BitConverter.GetBytes((uint)textpointer));             //Text table pointer
            int textcount = header.JapaneseStrings.Length + header.EnglishStrings.Length + header.FrenchStrings.Length + header.GermanStrings.Length + header.SpanishStrings.Length;

            result.AddRange(BitConverter.GetBytes((uint)textcount));
            Console.WriteLine("String table at {0}, count {1} (size {2})", textpointer.ToString("X"), textcount, textcount * 64);
            int pvmpointer = textpointer + 64 * textcount;

            result.AddRange(BitConverter.GetBytes((uint)pvmpointer));
            result.AddRange(BitConverter.GetBytes((uint)1));             //PVM count
            ushort numtextures = BitConverter.ToUInt16(pvm, 0xA);

            result.AddRange(BitConverter.GetBytes((uint)numtextures));
            Console.WriteLine("PVM at {0}, number of textures {1} (size {2})", pvmpointer.ToString("X"), numtextures, pvm.Length);
            int mltpointer = pvmpointer + pvm.Length;

            result.AddRange(BitConverter.GetBytes((uint)mltpointer));
            if (header.has_mlt)
            {
                result.AddRange(BitConverter.GetBytes((uint)1));
                Console.WriteLine("MLT at {0} (size {1})", mltpointer.ToString("X"), mlt.Length);
            }
            else
            {
                result.AddRange(BitConverter.GetBytes((uint)0));
            }
            int prspointer = mltpointer + mlt.Length;

            result.AddRange(BitConverter.GetBytes((uint)prspointer));
            result.AddRange(BitConverter.GetBytes((uint)1));             //PRS count
            List <byte> final = new List <byte>();

            Console.WriteLine("PRS at {0} (size {1})", prspointer.ToString("X"), prs.Length);
            final.AddRange(itemtable.ToArray());
            final.AddRange(stringtable.ToArray());
            final.AddRange(pvm);
            if (header.has_mlt)
            {
                final.AddRange(mlt);
            }
            final.AddRange(prs);
            byte[] finalarr = final.ToArray();
            uint   checksum = CalculateChecksum(ref finalarr, 0, finalarr.Length);

            result.AddRange(BitConverter.GetBytes(checksum));
            Console.WriteLine("Checksum: {0} ({1})", checksum.ToString("X8"), (int)checksum);
            for (int u = 0; u < 16; u++)
            {
                result.Add(0);
            }
            result.AddRange(final);
            if (result.Count % 512 != 0)
            {
                do
                {
                    result.Add(0);
                }while (result.Count % 512 != 0);
            }
            return(result.ToArray());
        }