Beispiel #1
0
 /// <summary>
 /// Make a clone
 /// </summary>
 public VMS_DLC(VMS_DLC original)
 {
     Title           = original.Title;
     Description     = original.Description;
     AppName         = original.AppName;
     Icon            = original.Icon;
     Identifier      = original.Identifier;
     EnableSonic     = original.EnableSonic;
     EnableTails     = original.EnableTails;
     EnableKnuckles  = original.EnableKnuckles;
     EnableGamma     = original.EnableGamma;
     EnableBig       = original.EnableBig;
     EnableAmy       = original.EnableAmy;
     EnableWhatever1 = original.EnableWhatever1;
     EnableWhatever2 = original.EnableWhatever2;
     Region          = original.Region;
     JapaneseStrings = new string[16];
     EnglishStrings  = new string[16];
     FrenchStrings   = new string[16];
     GermanStrings   = new string[16];
     SpanishStrings  = new string[16];
     for (int i = 0; i < 16; i++)
     {
         JapaneseStrings[i] = original.JapaneseStrings[i];
         EnglishStrings[i]  = original.EnglishStrings[i];
         FrenchStrings[i]   = original.FrenchStrings[i];
         GermanStrings[i]   = original.GermanStrings[i];
         SpanishStrings[i]  = original.SpanishStrings[i];
     }
     Items = new List <DLCObjectData>();
     if (original.Items != null && original.Items.Count > 0)
     {
         foreach (DLCObjectData objdata in original.Items)
         {
             Items.Add(new DLCObjectData(objdata));
         }
     }
     if (original.TextureData != null)
     {
         TextureData = new byte[original.TextureData.Length];
         Array.Copy(original.TextureData, TextureData, TextureData.Length);
     }
     if (original.SoundData != null)
     {
         SoundData = new byte[original.SoundData.Length];
         Array.Copy(original.SoundData, SoundData, SoundData.Length);
     }
     if (original.ModelData != null)
     {
         ModelData = new byte[original.ModelData.Length];
         Array.Copy(original.ModelData, ModelData, ModelData.Length);
     }
 }
Beispiel #2
0
            /// <summary>
            /// Load from a byte array (VMS file)
            /// </summary>
            public VMS_DLC(byte[] file)
            {
                // Decrypt if encrypted
                if (BitConverter.ToUInt32(file, 0x280) != 0x2C0)
                {
                    int    aniFrames = file[0x40] + (file[0x41] << 8);
                    int    dataStart = 0x80 + (aniFrames * 0x200);
                    byte[] encrypted = new byte[file.Length - dataStart];
                    Array.Copy(file, dataStart, encrypted, 0, encrypted.Length);
                    VMSFile.DecryptData(ref encrypted);
                    Array.Copy(encrypted, 0, file, dataStart, encrypted.Length);
                }
                // Get title and other stuff
                byte[] title_b       = GetTextItem(ref file, 0, 16);
                byte[] description_b = GetTextItem(ref file, 0x10, 32);
                byte[] appname_b     = GetTextItem(ref file, 0x30, 16);
                Description = System.Text.Encoding.GetEncoding(932).GetString(description_b);
                Title       = System.Text.Encoding.GetEncoding(932).GetString(title_b);
                AppName     = System.Text.Encoding.GetEncoding(932).GetString(appname_b);
                Icon        = GetIconFromFile(file);
                // Get items
                int item_pointer = BitConverter.ToInt32(file, 0x280);

                if (item_pointer != 0x2C0)
                {
                    System.Windows.Forms.MessageBox.Show("Unable to find SA1 DLC data.", "DLC Tool Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                    Items           = new List <DLCObjectData>();
                    JapaneseStrings = new string[16];
                    EnglishStrings  = new string[16];
                    FrenchStrings   = new string[16];
                    GermanStrings   = new string[16];
                    SpanishStrings  = new string[16];
                    TextureData     = new byte[0];
                    SoundData       = new byte[0];
                    ModelData       = new byte[0];
                    return;
                }
                Identifier = BitConverter.ToUInt32(file, item_pointer);
                if ((file[item_pointer + 4] & 0xF) > 0)
                {
                    EnableSonic = true;
                }
                if ((file[item_pointer + 4] >> 4) > 0)
                {
                    EnableTails = true;
                }
                if ((file[item_pointer + 5] & 0xF) > 0)
                {
                    EnableKnuckles = true;
                }
                if ((file[item_pointer + 5] >> 4) > 0)
                {
                    EnableGamma = true;
                }
                if ((file[item_pointer + 6] & 0xF) > 0)
                {
                    EnableAmy = true;
                }
                if ((file[item_pointer + 6] >> 4) > 0)
                {
                    EnableBig = true;
                }
                if ((file[item_pointer + 7] & 0xF) > 0)
                {
                    EnableWhatever1 = true;
                }
                if ((file[item_pointer + 7] >> 4) > 0)
                {
                    EnableWhatever2 = true;
                }
                Region = (DLCRegionLocks)BitConverter.ToInt32(file, item_pointer + 8);
                // Item table
                int item_count = BitConverter.ToInt32(file, 0x284);

                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.ScaleX               = file[item_pointer + u * 30 + 2];
                    dlcitem.ScaleY               = file[item_pointer + u * 30 + 3];
                    dlcitem.ScaleZ               = file[item_pointer + u * 30 + 4];
                    dlcitem.RotSpeedX            = (sbyte)file[item_pointer + u * 30 + 5];
                    dlcitem.RotSpeedY            = (sbyte)file[item_pointer + u * 30 + 6];
                    dlcitem.RotSpeedX            = (sbyte)file[item_pointer + u * 30 + 7];
                    dlcitem.ObjectType           = (DLCObjectTypes)file[item_pointer + u * 30 + 8];
                    dlcitem.Texture              = file[item_pointer + u * 30 + 9];
                    dlcitem.Flags                = (DLCObjectFlags)(BitConverter.ToUInt16(file, item_pointer + u * 30 + 10));
                    dlcitem.InternalID           = file[item_pointer + u * 30 + 12];
                    dlcitem.Unknown3             = file[item_pointer + u * 30 + 13];
                    dlcitem.Message              = file[item_pointer + u * 30 + 14];
                    dlcitem.TriggerDistance      = file[item_pointer + u * 30 + 15];
                    dlcitem.WarpLevelOrSoundbank = file[item_pointer + u * 30 + 16];
                    dlcitem.WarpActOrSoundID     = file[item_pointer + u * 30 + 17];
                    dlcitem.RotationX            = BitConverter.ToUInt16(file, item_pointer + u * 30 + 18);
                    dlcitem.RotationY            = BitConverter.ToUInt16(file, item_pointer + u * 30 + 20);
                    dlcitem.RotationZ            = 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);
                    Items.Add(dlcitem);
                }
                // Get strings
                JapaneseStrings = new string[16];
                EnglishStrings  = new string[16];
                FrenchStrings   = new string[16];
                SpanishStrings  = new string[16];
                GermanStrings   = new string[16];
                int           text_pointer = BitConverter.ToInt32(file, 0x288);
                int           text_count   = BitConverter.ToInt32(file, 0x28C);
                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;
                    }
                    JapaneseStrings[u] = stringarr[u];
                    if (text_count <= 16)
                    {
                        continue;
                    }
                    EnglishStrings[u] = stringarr[u + 16];
                    if (text_count <= 32)
                    {
                        continue;
                    }
                    FrenchStrings[u] = stringarr[u + 32];
                    if (text_count <= 48)
                    {
                        continue;
                    }
                    SpanishStrings[u] = stringarr[u + 48];
                    if (text_count <= 64)
                    {
                        continue;
                    }
                    GermanStrings[u] = stringarr[u + 64];
                }
                TextureData = new byte[0];
                SoundData   = new byte[0];
                ModelData   = new byte[0];
                // Get PVM pointer
                uint pvm_pointer = BitConverter.ToUInt32(file, 0x290); // Number of PVMs at 0x294, number of textures at 0x298
                // Get MLT pointer
                uint mlt_pointer = BitConverter.ToUInt32(file, 0x29C);
                int  nummlt      = BitConverter.ToInt32(file, 0x2A0);

                if (nummlt != 0)
                {
                    ContainsSound = true;
                }
                // Get PRS pointer
                uint prs_pointer = BitConverter.ToUInt32(file, 0x2A4); // Number of PRSes at 0x2A8
                // Get PVM data
                int pvm_size = (int)mlt_pointer - (int)pvm_pointer;

                if (pvm_size > 0)
                {
                    TextureData = new byte[pvm_size];
                    Array.Copy(file, pvm_pointer, TextureData, 0, pvm_size);
                }
                // Get MLT data
                int mlt_size = (int)prs_pointer - (int)mlt_pointer;

                if (mlt_size > 0)
                {
                    SoundData = new byte[mlt_size];
                    Array.Copy(file, mlt_pointer, SoundData, 0, mlt_size);
                }
                int item_size = (item_count * 30 + 12); // 12-byte header, headerless section size at 0x48

                do
                {
                    item_size++;
                }while (item_size % 16 != 0);
                // The size of the PRS cannot be determined reliably because the file might be padded to have a size divisible by 512
                // To get the correct size, the PRS chunk is read until the end of file or a sequence of 16 empty bytes
                int prs_size = 0;

                for (int indx = (int)prs_pointer; indx < file.Length; indx += 16)
                {
                    bool valid = false;
                    for (int u = 0; u < 16; u++)
                    {
                        if (file[indx + u] != 0)
                        {
                            valid = true;
                            break;
                        }
                    }
                    if (valid)
                    {
                        prs_size += 16;
                    }
                    else
                    {
                        break;
                    }
                }
                // Get PRS data
                if (prs_size > 0)
                {
                    ModelData = new byte[prs_size];
                    Array.Copy(file, prs_pointer, ModelData, 0, prs_size);
                }
            }