Пример #1
0
        public override void Inject(bool encrypt, string outputPath, string shortName, string longName,
                                    Bitmap menuIconImg, Bitmap bootTvImg, Bitmap bootDrcImg)
        {
            string outPath = GetValidOutputPath(outputPath, shortName);

            if (Directory.Exists(outPath) &&
                (Directory.GetDirectories(outPath).Length != 0 || Directory.GetFiles(outPath).Length != 0))
            {
                throw new Exception("The output path \"" + outPath + "\"exists and is not empty.");
            }

            Base = GetLoadedBase();
            if (!BaseIsLoaded)
            {
                throw new Exception("The base is not ready.");
            }

            InjectImages(menuIconImg, bootTvImg, bootDrcImg);
            if (RomIsValid)
            {
                InjectMeta(shortName, longName);
            }
            InjectRom();

            if (encrypt)
            {
                NusContent.Encrypt(BasePath, outPath);
            }
            else if (!Useful.DirectoryCopy(BasePath, outPath, true))
            {
                throw new Exception("\"" + BasePath + "\" copy failed.");
            }
        }
Пример #2
0
        public void LoadBase(string path)
        {
            NusContent.Format format = NusContent.GetFormat(path);

            if (format == NusContent.Format.Decrypted)
            {
                ValidateBase(path);

                if (Directory.Exists(BasePath))
                {
                    Directory.Delete(BasePath, true);
                    Base = null;
                }

                if (Useful.DirectoryCopy(path, BasePath, true))
                {
                    Base = GetLoadedBase();
                }
                else
                {
                    throw new Exception("Could not load base \"" + path + "\".");
                }
            }
            else if (format == NusContent.Format.Encrypted)
            {
                ValidateEncryptedBase(path);

                if (Directory.Exists(BasePath))
                {
                    Directory.Delete(BasePath, true);
                    Base = null;
                }

                Directory.CreateDirectory(BasePath);
                NusContent.Decrypt(path, BasePath);
                Base = GetLoadedBase();
            }
            else
            {
                StringBuilder strBuilder = new StringBuilder();
                strBuilder.AppendLine("The folder not contains a valid NUS content.");
                strBuilder.AppendLine("If it is an unpackaged (decrypted) NUS content, then:");
                strBuilder.AppendLine("The \"" + path + "\\code\" folder not exist.");
                strBuilder.AppendLine("Or \"" + path + "\\content\" folder not exist.");
                strBuilder.AppendLine("Or \"" + path + "\\meta\" folder not exist.");
                strBuilder.AppendLine("If it is an packaged (encrypted) NUS content, then:");
                strBuilder.AppendLine("The \"" + path + "\\title.tmd\" file not exist.");
                strBuilder.AppendLine("Or \"" + path + "\\title.tik\" file not exist.");
                strBuilder.AppendLine("Or \"" + path + "\\title.cert\" file not exist.");
                throw new Exception(strBuilder.ToString());
            }
        }
Пример #3
0
 //The UTF8 validator is not 100% reliable.
 public static bool UTF8Validator(string filename)
 {
     if (File.Exists(filename))
     {
         FileStream fs   = File.Open(filename, FileMode.Open);
         byte[]     file = new byte[fs.Length];
         fs.Read(file, 0, file.Length);
         fs.Close();
         return(Useful.IsUTF8(file));
     }
     else
     {
         throw new Exception("N64 config file \"" + filename + "\" not exists.");
     }
 }
Пример #4
0
        protected string GetValidOutputPath(string outputPath, string shortName)
        {
            if (!Directory.Exists(outputPath))
            {
                throw new Exception("The output path \"" + outputPath + "\" not exist.");
            }

            if (shortName.Length == 0)
            {
                throw new Exception("The short name is empty.");
            }

            char[] array   = Useful.Windows1252ToASCII(shortName, '_').ToCharArray();
            char[] invalid = Path.GetInvalidFileNameChars();
            for (int i = 0; i < array.Length; i++)
            {
                foreach (char c in invalid)
                {
                    if (array[i] == c)
                    {
                        array[i] = '_';
                    }
                }
            }
            string folderName = new string(array);

            StringBuilder strBuilder = new StringBuilder(outputPath.Length + folderName.Length + 20);

            strBuilder.Append(outputPath);
            strBuilder.Append("\\");
            strBuilder.Append(folderName);
            strBuilder.Append(" [");
            if (RomIsValid)
            {
                strBuilder.Append(TitleId);
                strBuilder.Append("]");
            }
            else
            {
                strBuilder.Append(NusContent.GetTitleID(BasePath));
                strBuilder.Append("] (Edited)");
            }

            return(strBuilder.ToString());
        }
Пример #5
0
 public override string ToString()
 {
     return("Hash: " + Hash.ToString("X8") + ", Release date: " + Release.ToString("yyyy/MM/dd") +
            ", Type: " + Type.ToString() + ", ROM size: " + Useful.ToFileSize(ROMSize) + ", FDS ROM: " + FDSROM.ToString() +
            "\r\nTitle: " + Title);
 }
Пример #6
0
        public RomGBA(string filename)
            : base()
        {
            byte[]     header = new byte[0xC0];
            FileStream fs     = File.OpenRead(filename);

            fs.Read(header, 0, 0xC0);
            fs.Close();

            if (Validate(header))
            {
                byte   uniqueCode;
                byte[] shortTitle = new byte[2];
                byte   region;

                uniqueCode    = header[0xAC];
                shortTitle[0] = header[0xAD];
                shortTitle[1] = header[0xAE];
                region        = header[0xAF];

                if (Useful.IsUpperLetterOrDigit(uniqueCode))
                {
                    FormatCode = (char)uniqueCode;
                }
                if (Useful.IsUpperLetterOrDigit(shortTitle[0]) &&
                    Useful.IsUpperLetterOrDigit(shortTitle[1]))
                {
                    ShortId = Encoding.ASCII.GetString(shortTitle);
                }
                if (Useful.IsUpperLetterOrDigit(region))
                {
                    RegionCode = (char)region;
                }
                if (Useful.IsUpperLetterOrDigit(header[0xBC]))
                {
                    Version = header[0xBC];
                }

                byte[] titleBytes = new byte[0x0C];
                Array.Copy(header, 0xA0, titleBytes, 0, 0x0C);
                int count = 0x0C;
                while (--count >= 0 && titleBytes[count] == 0)
                {
                    ;
                }
                Title = Encoding.ASCII.GetString(titleBytes, 0, count + 1);

                fs        = File.Open(filename, FileMode.Open);
                Size      = (int)fs.Length;
                HashCRC16 = Cll.Security.ComputeCRC16(fs);
                fs.Close();

                if (Size > 33554432)
                {
                    throw new FormatException("The GBA ROM has more than 32 MiB.");
                }

                IsValid = true;
                Console = Format.GBA;
            }
            else
            {
                throw new FormatException("Check bytes in the GBA ROM header are invalid.");
            }
        }
Пример #7
0
        public RomSNES(string filename)
            : base()
        {
            IsSMC = false;
            Mode  = Subformat.Indeterminate;

            FileStream fs            = File.OpenRead(filename);
            int        smcHeaderSize = SMCHeaderSize((int)fs.Length);

            byte[] data = GetData(fs, smcHeaderSize);
            fs.Close();

            if (smcHeaderSize == 0x200)
            {
                IsSMC = true;
            }

            int headerOffset = -1;

            Mode = GetFormat(data, ref headerOffset);

            if (Mode != Subformat.Indeterminate)
            {
                if (data[headerOffset + 0x2A] == 0x33)
                {
                    byte   uniqueCode;
                    byte[] shortTitle = new byte[2];
                    byte   region;

                    uniqueCode    = data[headerOffset + 0x02];
                    shortTitle[0] = data[headerOffset + 0x03];
                    shortTitle[1] = data[headerOffset + 0x04];
                    region        = data[headerOffset + 0x05];

                    if (Useful.IsUpperLetterOrDigit(uniqueCode))
                    {
                        FormatCode = (char)uniqueCode;
                    }
                    if (Useful.IsUpperLetterOrDigit(shortTitle[0]) &&
                        Useful.IsUpperLetterOrDigit(shortTitle[1]))
                    {
                        ShortId = Encoding.ASCII.GetString(shortTitle);
                    }
                    if (Useful.IsUpperLetterOrDigit(region))
                    {
                        RegionCode = (char)region;
                    }
                }

                Version = data[headerOffset + 0x2B];

                byte[] titleBytes = new byte[21];
                Array.Copy(data, headerOffset + 0x10, titleBytes, 0, 21);
                int count = 21;
                while (--count >= 0 && titleBytes[count] == 0x20)
                {
                    ;
                }
                Title     = Encoding.ASCII.GetString(titleBytes, 0, count + 1);
                Size      = data.Length;
                HashCRC16 = Cll.Security.ComputeCRC16_ARC(data, 0, data.Length);

                IsValid = true;
                Console = Format.SNES_USA;
            }
            else
            {
                Size = 0;
                throw new FormatException("It was not possible to determine the SNES ROM format.");
            }
        }
Пример #8
0
 public override string ToString()
 {
     return("Hash: " + Hash.ToString("X8") + ", Release date: " + Release.ToString("yyyy/MM/dd") +
            ", Type: " + Type.ToString() + ", ROM size: " + Useful.ToFileSize(ROMSize) + ", Extended footer: " + ExtendedFooter.ToString() + ", PCM data: " + PCMData.ToString() +
            "\r\nTitle: " + Title);
 }
Пример #9
0
        public RomN64(string filename)
            : base()
        {
            Endianness = Subformat.Indeterminate;

            byte[]     header = new byte[0x40];
            FileStream fs     = File.Open(filename, FileMode.Open);

            Size = (int)fs.Length;
            fs.Read(header, 0, 0x40);
            fs.Close();

            Endianness = GetFormat(header);

            if (Endianness == Subformat.BigEndian ||
                (Endianness != Subformat.Indeterminate && Size % 4 == 0))
            {
                byte   uniqueCode;
                byte[] shortTitle = new byte[2];
                byte   region;

                header = ToBigEndian(header, Endianness);

                uniqueCode    = header[0x3B];
                shortTitle[0] = header[0x3C];
                shortTitle[1] = header[0x3D];
                region        = header[0x3E];

                if (Useful.IsUpperLetterOrDigit(uniqueCode))
                {
                    FormatCode = (char)uniqueCode;
                }
                if (Useful.IsUpperLetterOrDigit(shortTitle[0]) &&
                    Useful.IsUpperLetterOrDigit(shortTitle[1]))
                {
                    ShortId = Encoding.ASCII.GetString(shortTitle);
                }
                if (Useful.IsUpperLetterOrDigit(region))
                {
                    RegionCode = (char)region;
                }
                if (Useful.IsUpperLetterOrDigit(header[0x3F]))
                {
                    Version = header[0x3F];
                }

                byte[] titleBytes = new byte[20];
                Array.Copy(header, 0x20, titleBytes, 0, 20);
                int count = 20;
                while (--count >= 0 && titleBytes[count] == 0x20)
                {
                    ;
                }
                Title = Encoding.ASCII.GetString(titleBytes, 0, count + 1);

                fs        = File.Open(filename, FileMode.Open);
                HashCRC16 = Cll.Security.ComputeCRC16(fs);
                fs.Close();

                IsValid = true;
                Console = Format.N64;
            }
            else
            {
                Size = 0;
                throw new FormatException("It was not possible to determine the N64 ROM format.");
            }
        }
Пример #10
0
        public RomNDS(string filename)
            : base()
        {
            TitleLine1 = "";
            TitleLine2 = "";
            Icon       = null;

            byte[]     header = new byte[0x200];
            FileStream fs     = File.OpenRead(filename);

            fs.Read(header, 0, 0x200);
            fs.Close();

            if (Validate(header))
            {
                byte   uniqueCode;
                byte[] shortTitle = new byte[2];
                byte   region;

                uniqueCode    = header[0x0C];
                shortTitle[0] = header[0x0D];
                shortTitle[1] = header[0x0E];
                region        = header[0x0F];

                if (Useful.IsUpperLetterOrDigit(uniqueCode))
                {
                    FormatCode = (char)uniqueCode;
                }
                if (Useful.IsUpperLetterOrDigit(shortTitle[0]) &&
                    Useful.IsUpperLetterOrDigit(shortTitle[1]))
                {
                    ShortId = Encoding.ASCII.GetString(shortTitle);
                }
                if (Useful.IsUpperLetterOrDigit(region))
                {
                    RegionCode = (char)region;
                }
                if (Useful.IsUpperLetterOrDigit(header[0x1E]))
                {
                    Version = header[0x1E];
                }

                byte[] offsetBytes  = new byte[4];
                byte[] bitmapBytes  = new byte[0x200];
                byte[] paletteBytes = new byte[0x20];
                byte[] titleBytes   = new byte[0x100];

                fs   = File.OpenRead(filename);
                Size = (int)fs.Length;
                fs.Seek(0x68, SeekOrigin.Begin);
                fs.Read(offsetBytes, 0, 4);
                int offset = (offsetBytes[3] << 24) + (offsetBytes[2] << 16) + (offsetBytes[1] << 8) + offsetBytes[0];
                fs.Seek(offset + 0x20, SeekOrigin.Begin);
                fs.Read(bitmapBytes, 0, 0x200);
                fs.Read(paletteBytes, 0, 0x20);
                fs.Read(titleBytes, 0, 0x100);
                fs.Position = 0;
                HashCRC16   = Cll.Security.ComputeCRC16(fs);
                fs.Close();

                string   title = Encoding.Unicode.GetString(titleBytes);
                string[] lines = title.Split(new char[] { '\n' });

                if (lines.Length == 2)
                {
                    Title      = lines[0];
                    TitleLine1 = lines[0];
                }
                else if (lines.Length >= 3)
                {
                    Title      = lines[0] + " " + lines[1];
                    TitleLine1 = lines[0];
                    TitleLine2 = lines[1];
                }

                Color[] palette = new Color[16];
                int     j       = -1;
                for (int i = 0; i < 16; i++)
                {
                    palette[i] = Color.FromArgb(
                        (paletteBytes[++j] & 0x1F) << 3,       //0000 0000 0001 1111
                            ((paletteBytes[j] & 0xE0) >> 2) +  //0000 0000 1110 0000
                            ((paletteBytes[++j] & 0x03) << 6), //0000 0011 0000 0000
                            (paletteBytes[j] & 0x7C) << 1);    //0111 1100 0000 0000
                }
                palette[0] = Color.FromArgb(0, palette[0].R, palette[0].G, palette[0].B);

                byte[] pix = new byte[1024];

                int pixIndex;
                int bytesIndex;
                for (int tileY = 0; tileY < 4; tileY++)
                {
                    for (int tileX = 0; tileX < 4; tileX++)
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            pixIndex          = i * 32 + tileX * 8 + tileY * 256;
                            bytesIndex        = i * 4 + tileX * 32 + tileY * 128;
                            pix[pixIndex]     = (byte)(bitmapBytes[bytesIndex] & 0x0F);
                            pix[pixIndex + 1] = (byte)((bitmapBytes[bytesIndex] & 0xF0) >> 4);
                            pix[pixIndex + 2] = (byte)(bitmapBytes[bytesIndex + 1] & 0x0F);
                            pix[pixIndex + 3] = (byte)((bitmapBytes[bytesIndex + 1] & 0xF0) >> 4);
                            pix[pixIndex + 4] = (byte)(bitmapBytes[bytesIndex + 2] & 0x0F);
                            pix[pixIndex + 5] = (byte)((bitmapBytes[bytesIndex + 2] & 0xF0) >> 4);
                            pix[pixIndex + 6] = (byte)(bitmapBytes[bytesIndex + 3] & 0x0F);
                            pix[pixIndex + 7] = (byte)((bitmapBytes[bytesIndex + 3] & 0xF0) >> 4);
                        }
                    }
                }

                Bitmap    icon = new Bitmap(32, 32);
                Rectangle rect = new Rectangle(0, 0, icon.Width, icon.Height);
                System.Drawing.Imaging.BitmapData data =
                    icon.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                                  icon.PixelFormat);
                int    length    = data.Width * data.Height * 4;
                byte[] iconBytes = new byte[length];
                IntPtr ptr       = data.Scan0;
                System.Runtime.InteropServices.Marshal.Copy(ptr, iconBytes, 0, length);
                Color color;
                for (int i = 0; i < 1024; i++)
                {
                    color                = palette[pix[i]];
                    iconBytes[i * 4]     = color.B;
                    iconBytes[i * 4 + 1] = color.G;
                    iconBytes[i * 4 + 2] = color.R;
                    iconBytes[i * 4 + 3] = color.A;
                }
                System.Runtime.InteropServices.Marshal.Copy(iconBytes, 0, ptr, length);
                icon.UnlockBits(data);

                Icon    = icon;
                IsValid = true;
                Console = Format.NDS;
            }
            else
            {
                throw new FormatException("Checksums in the NDS ROM header are invalid.");
            }
        }
Пример #11
0
        protected void InjectMeta(string shortName, string longName)
        {
            string titleId = TitleId;

            byte[] id = Useful.StrHexToByteArray(titleId, "");

            XmlWriterSettings xmlSettings = new XmlWriterSettings
            {
                Encoding        = new UTF8Encoding(false),
                Indent          = true,
                IndentChars     = "  ",
                NewLineChars    = "\n",
                NewLineHandling = NewLineHandling.Replace
            };

            XmlDocument xmlApp  = new XmlDocument();
            XmlDocument xmlMeta = new XmlDocument();

            xmlApp.Load(BasePath + "\\code\\app.xml");
            xmlMeta.Load(BasePath + "\\meta\\meta.xml");

            XmlNode app_title_id = xmlApp.SelectSingleNode("app/title_id");
            XmlNode app_group_id = xmlApp.SelectSingleNode("app/group_id");

            XmlNode meta_product_code  = xmlMeta.SelectSingleNode("menu/product_code");
            XmlNode meta_title_id      = xmlMeta.SelectSingleNode("menu/title_id");
            XmlNode meta_group_id      = xmlMeta.SelectSingleNode("menu/group_id");
            XmlNode meta_longname_ja   = xmlMeta.SelectSingleNode("menu/longname_ja");
            XmlNode meta_longname_en   = xmlMeta.SelectSingleNode("menu/longname_en");
            XmlNode meta_longname_fr   = xmlMeta.SelectSingleNode("menu/longname_fr");
            XmlNode meta_longname_de   = xmlMeta.SelectSingleNode("menu/longname_de");
            XmlNode meta_longname_it   = xmlMeta.SelectSingleNode("menu/longname_it");
            XmlNode meta_longname_es   = xmlMeta.SelectSingleNode("menu/longname_es");
            XmlNode meta_longname_zhs  = xmlMeta.SelectSingleNode("menu/longname_zhs");
            XmlNode meta_longname_ko   = xmlMeta.SelectSingleNode("menu/longname_ko");
            XmlNode meta_longname_nl   = xmlMeta.SelectSingleNode("menu/longname_nl");
            XmlNode meta_longname_pt   = xmlMeta.SelectSingleNode("menu/longname_pt");
            XmlNode meta_longname_ru   = xmlMeta.SelectSingleNode("menu/longname_ru");
            XmlNode meta_longname_zht  = xmlMeta.SelectSingleNode("menu/longname_zht");
            XmlNode meta_shortname_ja  = xmlMeta.SelectSingleNode("menu/shortname_ja");
            XmlNode meta_shortname_en  = xmlMeta.SelectSingleNode("menu/shortname_en");
            XmlNode meta_shortname_fr  = xmlMeta.SelectSingleNode("menu/shortname_fr");
            XmlNode meta_shortname_de  = xmlMeta.SelectSingleNode("menu/shortname_de");
            XmlNode meta_shortname_it  = xmlMeta.SelectSingleNode("menu/shortname_it");
            XmlNode meta_shortname_es  = xmlMeta.SelectSingleNode("menu/shortname_es");
            XmlNode meta_shortname_zhs = xmlMeta.SelectSingleNode("menu/shortname_zhs");
            XmlNode meta_shortname_ko  = xmlMeta.SelectSingleNode("menu/shortname_ko");
            XmlNode meta_shortname_nl  = xmlMeta.SelectSingleNode("menu/shortname_nl");
            XmlNode meta_shortname_pt  = xmlMeta.SelectSingleNode("menu/shortname_pt");
            XmlNode meta_shortname_ru  = xmlMeta.SelectSingleNode("menu/shortname_ru");
            XmlNode meta_shortname_zht = xmlMeta.SelectSingleNode("menu/shortname_zht");

            app_title_id.InnerText = titleId;
            app_group_id.InnerText = "0000" + id[5].ToString("X2") + id[6].ToString("X2");

            if (!Rom.ProductCode.Contains("?"))
            {
                meta_product_code.InnerText = "WUP-N-" + Rom.ProductCode;
            }

            meta_title_id.InnerText      = titleId;
            meta_group_id.InnerText      = "0000" + id[5].ToString("X2") + id[6].ToString("X2");
            meta_longname_ja.InnerText   = longName;
            meta_longname_en.InnerText   = longName;
            meta_longname_fr.InnerText   = longName;
            meta_longname_de.InnerText   = longName;
            meta_longname_it.InnerText   = longName;
            meta_longname_es.InnerText   = longName;
            meta_longname_zhs.InnerText  = longName;
            meta_longname_ko.InnerText   = longName;
            meta_longname_nl.InnerText   = longName;
            meta_longname_pt.InnerText   = longName;
            meta_longname_ru.InnerText   = longName;
            meta_longname_zht.InnerText  = longName;
            meta_shortname_ja.InnerText  = shortName;
            meta_shortname_en.InnerText  = shortName;
            meta_shortname_fr.InnerText  = shortName;
            meta_shortname_de.InnerText  = shortName;
            meta_shortname_it.InnerText  = shortName;
            meta_shortname_es.InnerText  = shortName;
            meta_shortname_zhs.InnerText = shortName;
            meta_shortname_ko.InnerText  = shortName;
            meta_shortname_nl.InnerText  = shortName;
            meta_shortname_pt.InnerText  = shortName;
            meta_shortname_ru.InnerText  = shortName;
            meta_shortname_zht.InnerText = shortName;

            XmlWriter app  = XmlWriter.Create(BasePath + "\\code\\app.xml", xmlSettings);
            XmlWriter meta = XmlWriter.Create(BasePath + "\\meta\\meta.xml", xmlSettings);

            xmlApp.Save(app);
            xmlMeta.Save(meta);

            app.Close();
            meta.Close();
        }