Пример #1
0
        public static void PatchAndSave()
        {
            if (CommonSzs == null)
            {
                Window.Alert("Open an szs first !");
                return;
            }
            if (LoadedDDS == null)
            {
                Window.Alert("Open a DDS first !");
                return;
            }
            DoActionWithloading(() =>
            {
                LayoutPatch targetLayout = null;
                if (LayoutsComboBox.SelectedIndex > 0)
                {
                    targetLayout = layoutPatches[int.Parse(
                                                     ((HTMLOptionElement)LayoutsComboBox.Children[LayoutsComboBox.SelectedIndex]).Value)];
                }

                var yaz0 = Theme.Make(CommonSzs, DDSEncoder.LoadDDS(LoadedDDS), targetPatch, targetLayout);
                if (yaz0 == null)
                {
                    return;
                }
                Uint8Array dwn       = new Uint8Array(yaz0);
                string DownloadFname = targetPatch.szsName;
                Script.Write("downloadBlob(dwn,DownloadFname,'application/octet-stream');");
            });
        }
Пример #2
0
        bool BgImageCheck(bool IsLegacyTarget)
        {
            if (tbBntxFile.Text.Trim() == "")
            {
                return(true);
            }
            if (!tbBntxFile.Text.EndsWith(".dds"))
            {
                var res = ImageToDDS(tbBntxFile.Text, Path.GetTempPath());
                if (res)
                {
                    tbBntxFile.Text  = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(tbBntxFile.Text) + ".dds");
                    tbBntxFile2.Text = tbBntxFile.Text;
                }
                else
                {
                    return(false);
                }
            }

            if (IsLegacyTarget)             //This is checked at a later stage for nxtheme
            {
                var dds = DDSEncoder.LoadDDS(File.ReadAllBytes(tbBntxFile.Text));
                if (dds.Format != "DXT1")
                {
                    MessageBox.Show("WARNING: the encoding of the selected DDS is not DXT1, it may crash on the switch");
                }
                if (dds.width != 1280 || dds.height != 720)
                {
                    MessageBox.Show("WARNING: the selected image is not 720p (1280x720), it may crash on the swtich");
                }
            }

            return(true);
        }
        public void AddMainBg(byte[] data)
        {
            if (data == null)
            {
                return;
            }
            string ext = "";

            if (data.Matches("DDS "))
            {
                ext = "dds";
                var img = DDSEncoder.LoadDDS(data);
                if (img.width != 1280 || img.height != 720 || img.Format != "DXT1")
                {
                    throw new Exception("The background image must be 1280x720 and (if you're using a DDS) DXT1 encoded.");
                }
            }
            else if (data.Matches(0, new byte[] { 0xFF, 0xD8, 0xFF }))
            {
                ext = "jpg";
                (UInt32 w, UInt32 h) = GetJpgSize(data);
                if (w != 1280 || h != 720)
                {
                    throw new Exception("The background image must be 1280x720.");
                }
            }
            else
            {
                throw new Exception("Invalid image format");
            }
            AddFile("image." + ext, data);
        }
Пример #4
0
 public static void UploadDDS(Uint8Array arr, string fileName)         //called from file uploader
 {
     DoActionWithloading(() =>
     {
         lblDDSPath.TextContent = fileName;
         LoadedDDS = DDSEncoder.LoadDDS(arr.ToArray());
     });
 }
        public void AddAppletIcon(string name, byte[] data)
        {
            if (!TextureReplacement.NxNameToList.ContainsKey(info.Target))
            {
                throw new Exception("Not supported for this target");
            }

            var item = TextureReplacement.NxNameToList[info.Target].Where(x => x.NxThemeName == name).FirstOrDefault();

            if (item == null)
            {
                throw new Exception($"{name} not supported for this target");
            }

            string ext = "";

            if (data.Matches("DDS "))
            {
                ext = ".dds";
                var img = DDSEncoder.LoadDDS(data);
                if (img.width != item.W || img.height != item.H || (img.Format != "DXT1" && img.Format != "DXT4" && img.Format != "DXT5" && img.Format != "DXT3"))
                {
                    throw new Exception("The applet image must be 64x56 and (if you're using a DDS) DXT1/3/4/5 encoded.");
                }
            }
            else if (data.Matches(1, "PNG"))
            {
                ext = ".png";
                (UInt32 w, UInt32 h) = GetPngSize(data);
                if (w != item.W || h != item.H)
                {
                    throw new Exception("The applet image must be 64x56.");
                }
            }
            else
            {
                throw new Exception("Invalid image format: Applet icons can only be DDS or PNG images");
            }
            AddFile(name + ext, data);
        }
        public void AddMainBg(byte[] data)
        {
            if (data == null)
            {
                return;
            }
            string ext = "";

            if (data.Matches("DDS "))
            {
                ext = "dds";
                var img = DDSEncoder.LoadDDS(data);
                if (img.width != 1280 || img.height != 720 || img.Format != "DXT1")
                {
                    throw new Exception("The background image must be 1280x720 and (if you're using a DDS) DXT1 encoded.");
                }
            }
            else if (data.Matches(0, new byte[] { 0xFF, 0xD8, 0xFF }))
            {
                ext = "jpg";
                (UInt32 w, UInt32 h, bool IsProgressive) = GetJpgInfo(data);

                if (IsProgressive)
                {
                    throw new Exception("Progressive JPG images are not currently supported for the background image, check the encoding settings in your image editor");
                }

                if (w != 1280 || h != 720)
                {
                    throw new Exception("The background image must be 1280x720.");
                }
            }
            else
            {
                throw new Exception("Invalid image format: The background image can only be a DDS or JPG image");
            }
            AddFile("image." + ext, data);
        }
Пример #7
0
        static void MakeNxTheme(string partName, string name, string author, LayoutPatch targetLayout)
        {
            if (LoadedDDS == null)
            {
                Window.Alert("Open a DDS first !");
                return;
            }
            if (!ValidAutoThemeParts.Contains(partName))
            {
                Window.Alert("select a valid Home menu part");
                return;
            }
            if (name.Trim() == "")
            {
                Window.Alert("Enter a valid name");
                return;
            }
            DoActionWithloading(() =>
            {
                var dds = DDSEncoder.LoadDDS(LoadedDDS);                 //this will crash if the dds type is wrong

                var meta = new ThemeFileManifest()
                {
                    Version    = 1,
                    Author     = author,
                    LayoutInfo = targetLayout != null ? targetLayout.ToString() : "",
                    ThemeName  = name,
                    Target     = partName,
                };

                var res              = SwitchThemesCommon.GenerateNXTheme(meta, LoadedDDS, targetLayout == null ? null : System.Text.Encoding.UTF8.GetBytes(targetLayout.AsJson()));
                Uint8Array dwn       = new Uint8Array(res);
                string DownloadFname = name + ".nxtheme";
                Script.Write("downloadBlob(dwn,DownloadFname,'application/octet-stream');");
            });
        }
 public bool PatchMainBG(byte[] DDS)
 {
     return(PatchMainBG(DDSEncoder.LoadDDS(DDS)));
 }
Пример #9
0
        static void DoAutoTheme(string type, string url, string layout)
        {
            cardLoad = Document.GetElementById <HTMLDivElement>("CardLoad");
            Document.GetElementById <HTMLDivElement>("CardTutorial").Hidden = true;
            string themeTarget = "<br/><br/>This theme is for " + Window.LocalStorage.GetItem(type + "Name") as string + "<br/>To change the target version upload another szs for Auto-Theme on the <a href=\"index.html\">Home page</a>";

            cardLoad.InnerHTML = "Wait while your theme is being generated.... " + themeTarget;
            cardLoad.Hidden    = false;
            StartLoading();

            DDSEncoder.DDSLoadResult LoadedDDS;
            SarcData      CommonSzs;
            PatchTemplate targetPatch;
            LayoutPatch   targetLayout = null;

            void BuildTheme()
            {
                var yaz0 = Theme.Make(CommonSzs, LoadedDDS, targetPatch, targetLayout);

                if (yaz0 == null)
                {
                    endWithError("Theme.Make() failed :(");
                    return;
                }
                Uint8Array dwn           = new Uint8Array(yaz0);
                string     DownloadFname = targetPatch.szsName;

                Script.Write("downloadBlob(dwn,DownloadFname,'application/octet-stream');");
                Document.GetElementById <HTMLDivElement>("CardLoad").InnerHTML = "Your theme has been generated !" + themeTarget;
                EndLoading();
            }

            void DDSDownloaded(Uint8Array arr)
            {
                LoadedDDS = DDSEncoder.LoadDDS(arr.ToArray());
                arr       = null;
                CommonSzs = SARC.UnpackRamN(
                    ManagedYaz0.Decompress(
                        Convert.FromBase64String(
                            Window.LocalStorage.GetItem(type) as string)));

                targetPatch = SwitchThemesCommon.DetectSarc(CommonSzs, DefaultTemplates.templates);

                if (layout == null)
                {
                    BuildTheme();
                }
                else
                {
                    HttpRequest(layout, LayoutDownloaded, "Layout");
                }
            }

            void LayoutDownloaded(string req)
            {
                targetLayout = LayoutPatch.LoadTemplate(req);
                BuildTheme();
            }

            HttpRequest(url, DDSDownloaded, "DDS");
        }
Пример #10
0
        static bool SZSFromArgs(string[] args)
        {
            string GetArg(string start)
            {
                var a = args.Where(x => x.StartsWith(start + "=")).FirstOrDefault();

                if (a == null)
                {
                    return(null);
                }
                else
                {
                    return(a.Split('=')[1]);
                }
            }

            if (args.Length < 2)
            {
                return(false);
            }

            string Target      = args[1];
            var    CommonSzs   = SARCExt.SARC.UnpackRamN(ManagedYaz0.Decompress(File.ReadAllBytes(Target)));
            var    targetPatch = SzsPatcher.DetectSarc(CommonSzs, DefaultTemplates.templates);

            if (targetPatch == null)
            {
                Console.WriteLine("Unknown szs file");
                return(false);
            }

            string Image = args.Where(x => x.ToLower().EndsWith(".dds")).FirstOrDefault();

            if (Image == null || !File.Exists(Image))
            {
                Console.WriteLine("No image file !\r\nNote that only dds files are supported for szs themes.");
                return(false);
            }
            string Layout = args.Where(x => x.EndsWith(".json")).FirstOrDefault();

            string Output = GetArg("out");

            if (Output == null || Output == "")
            {
                return(false);
            }

            {
                var dds = DDSEncoder.LoadDDS(File.ReadAllBytes(Image));
                if (dds.Format != "DXT1")
                {
                    Console.WriteLine("WARNING: the encoding of the selected DDS is not DXT1, it may crash on the switch");
                }
                if (dds.width != 1280 || dds.height != 720)
                {
                    Console.WriteLine("WARNING: the selected image is not 720p (1280x720), it may crash on the swtich");
                }
            }

            try
            {
                var res     = true;
                var Patcher = new SzsPatcher(CommonSzs, DefaultTemplates.templates);

                if (Image != null)
                {
                    res = Patcher.PatchMainBG(File.ReadAllBytes(Image));
                    if (!res)
                    {
                        Console.WriteLine("Couldn't patch this file, it might have been already modified or it's from an unsupported system version.");
                        return(false);
                    }
                }

                void ProcessAppletIcons(List <TextureReplacement> l)
                {
                    foreach (var a in l)
                    {
                        string path = GetArg(a.NxThemeName);
                        if (!path.EndsWith(".dds"))
                        {
                            Console.WriteLine($"{path} is not supported, only dds files can be used for szs themes");
                            path = null;
                        }
                        if (path != null)
                        {
                            if (!Patcher.PatchAppletIcon(File.ReadAllBytes(path), a.NxThemeName))
                            {
                                Console.WriteLine($"Applet icon patch for {a.NxThemeName} failed");
                            }
                        }
                    }
                }

                if (TextureReplacement.NxNameToList.ContainsKey(targetPatch.NXThemeName))
                {
                    ProcessAppletIcons(TextureReplacement.NxNameToList[targetPatch.NXThemeName]);
                }

                if (Layout != null)
                {
                    Patcher.EnableAnimations = true;
                    var l         = LayoutPatch.LoadTemplate(File.ReadAllText(Layout));
                    var layoutres = Patcher.PatchLayouts(l, targetPatch);
                    if (!layoutres)
                    {
                        Console.WriteLine("One of the target files for the selected layout patch is missing in the SZS, you are probably using an already patched SZS");
                        return(false);
                    }
                    layoutres = Patcher.PatchAnimations(l.Anims);
                }

                CommonSzs = Patcher.GetFinalSarc();
                var sarc = SARC.PackN(CommonSzs);

                File.WriteAllBytes(Output, ManagedYaz0.Compress(sarc.Item2, 3, (int)sarc.Item1));
                GC.Collect();

                if (Patcher.PatchTemplate.RequiresCodePatch)
                {
                    Console.WriteLine("The file has been patched successfully but due to memory limitations this szs requires an extra code patch to be applied to the home menu, if you use NXThemesInstaller to install this it will be done automatically, otherwise you need to manually copy the patches from https://github.com/exelix11/SwitchThemeInjector/tree/master/SwitchThemesNX/romfs to the exefs patches directory of your cfw");
                }
                else
                {
                    Console.WriteLine("Done");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }

            return(true);
        }
Пример #11
0
        static bool NXThemeFromArgs(string[] args)
        {
            if (args.Length < 4)
            {
                return(false);
            }
            string Target = args[1];

            if (!Form1.HomeMenuParts.Values.Contains(Target))
            {
                return(false);
            }

            string Image = args.Where(x => x.EndsWith(".dds") || x.EndsWith(".jpg") || x.EndsWith(".png") || x.EndsWith("jpeg")).FirstOrDefault();

            if (Image == null || !File.Exists(Image))
            {
                Console.WriteLine("No image file !");
                return(false);
            }
            string Layout = args.Where(x => x.EndsWith(".json")).FirstOrDefault();

            string GetArg(string start)
            {
                var a = args.Where(x => x.StartsWith(start + "=")).FirstOrDefault();

                if (a == null)
                {
                    return(null);
                }
                else
                {
                    return(a.Split('=')[1]);
                }
            }

            bool?GetArgBool(string start)
            {
                var a = GetArg(start);

                if (a == null)
                {
                    return(null);
                }
                else
                {
                    return(bool.Parse(a));
                }
            }

            string Name        = GetArg("name");
            string Author      = GetArg("author");
            string Output      = GetArg("out");
            string ExtraCommon = GetArg("commonlyt");
            string album       = GetArg("album");

            if (Output == null || Output == "")
            {
                return(false);
            }

            bool preview = GetArgBool("preview") ?? true;

            if (Name == null || Name.Trim() == "")
            {
                var info = ThemeInputInfo.Ask();
                Name    = info.Item1;
                Author  = info.Item2;
                preview = info.Item3;
            }

            LayoutPatch layout = null;

            if (Layout != null && File.Exists(Layout))
            {
                layout = LayoutPatch.LoadTemplate(File.ReadAllText(Layout));
            }

            if (!Image.EndsWith(".dds"))
            {
                if (Form1.ImageToDDS(Image, Path.GetTempPath()))
                {
                    Image = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Image) + ".dds");
                }
                else
                {
                    return(false);
                }
            }

            var dds = DDSEncoder.LoadDDS(File.ReadAllBytes(Image));

            if (dds.Format != "DXT1")
            {
                MessageBox.Show("WARNING: the encoding of the selected DDS is not DXT1, it may crash on the switch");
            }
            if (dds.width != 1280 || dds.height != 720)
            {
                MessageBox.Show("WARNING: the selected image is not 720p (1280x720), it may crash on the swtich");
            }

            if (album != null && !album.EndsWith(".dds"))
            {
                if (Form1.ImageToDDS(album, Path.GetTempPath()))
                {
                    album = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(album) + ".dds");
                }
                else
                {
                    return(false);
                }
            }

            var res = SwitchThemesCommon.GenerateNXTheme(
                new ThemeFileManifest()
            {
                Version    = 4,
                ThemeName  = Name,
                Author     = Author,
                Target     = Target,
                LayoutInfo = layout == null ? "" : layout.PatchName + " by " + layout.AuthorName,
            },
                File.ReadAllBytes(Image),
                layout?.AsByteArray(),
                new Tuple <string, byte[]>("preview.png", preview ? Form1.GenerateDDSPreview(Image) : null),
                new Tuple <string, byte[]>("album.dds", album != null ? File.ReadAllBytes(album) : null));

            File.WriteAllBytes(Output, res);

            return(true);
        }
 public BflytFile.PatchResult PatchMainBG(byte[] DDS)
 {
     return(PatchMainBG(DDSEncoder.LoadDDS(DDS)));
 }
Пример #13
0
        public static byte[] GenerateNXTheme(ThemeFileManifest info, byte[] image, byte[] layout = null, params Tuple <string, byte[]>[] _ExtraFiles)
        {
            Dictionary <string, byte[]> ExtFiles = new Dictionary <string, byte[]>();

            foreach (var f in _ExtraFiles)
            {
                if (f != null && f.Item1 != null && f.Item2 != null)
                {
                    ExtFiles.Add(f.Item1, f.Item2);
                }
            }

            if (image == null && layout == null)
            {
                throw new Exception("You need at least an image or a layout to make a theme");
            }

            if (image != null)
            {
                var img = DDSEncoder.LoadDDS(image);
                if (img.width != 1280 || img.height != 720 || img.Format != "DXT1")
                {
                    throw new Exception("The background image must be 1280x720 and (if you're using a DDS) DXT1 encoded ");
                }
            }

            if (info.Target != "home")
            {
                if (ExtFiles.ContainsKey("album.dds"))
                {
                    ExtFiles.Remove("album.dds");
                }
                if (ExtFiles.ContainsKey("common.json"))
                {
                    ExtFiles.Remove("common.json");
                }
            }

            {
                byte[] album_img = null;
                ExtFiles.TryGetValue("album.dds", out album_img);
                if (album_img != null)
                {
                    var img = DDSEncoder.LoadDDS(album_img);
                    if (img.width != 64 || img.height != 56)
                    {
                        throw new Exception("The custom album image must be 64x56");
                    }
                }
            }

            Dictionary <string, byte[]> Files = new Dictionary <string, byte[]>();

            Files.Add("info.json", Encoding.UTF8.GetBytes(info.Serialize()));
            if (image != null)
            {
                Files.Add("image.dds", image);
            }
            if (layout != null)
            {
                Files.Add("layout.json", layout);
            }

            foreach (var f in ExtFiles)
            {
                Files.Add(f.Key, f.Value);
            }

            var sarc = SARCExt.SARC.PackN(new SARCExt.SarcData()
            {
                endianness = ByteOrder.LittleEndian, Files = Files, HashOnly = false
            });

            return(ManagedYaz0.Compress(sarc.Item2, 1, (int)sarc.Item1));
        }
Пример #14
0
        private void PatchButtonClick(object sender, EventArgs e)
        {
            if (CommonSzs == null || targetPatch == null)
            {
                MessageBox.Show("Open a valid SZS first");
                return;
            }

            bool HasImage = tbImageFile.Text.Trim() != "";

            if (!HasImage)
            {
                if (LayoutPatchList.SelectedIndex <= 0)
                {
                    MessageBox.Show("There is nothing to patch");
                    return;
                }

                if (MessageBox.Show("Are you sure you want to continue without selecting a background image ?", "", MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    return;
                }
            }
            else if (!File.Exists(tbImageFile.Text))
            {
                MessageBox.Show($"{tbImageFile.Text} not found!");
                return;
            }
            else if (!tbImageFile.Text.ToLower().EndsWith("dds"))
            {
                MessageBox.Show($"For szs patching only dds images are supported");
                return;
            }

            if (HasImage)
            {
                var dds = DDSEncoder.LoadDDS(File.ReadAllBytes(tbImageFile.Text));
                if (dds.Format != "DXT1")
                {
                    MessageBox.Show("WARNING: the encoding of the selected DDS is not DXT1, it may crash on the switch");
                }
                if (dds.width != 1280 || dds.height != 720)
                {
                    MessageBox.Show("WARNING: the selected image is not 720p (1280x720), it may crash on the swtich");
                }
            }

            SaveFileDialog sav = new SaveFileDialog()
            {
                Filter   = "SZS file|*.szs",
                FileName = targetPatch.szsName
            };

            if (sav.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            SzsPatcher Patcher = new SzsPatcher(CommonSzs, Templates);

            var res = true;

            if (HasImage)
            {
                res = Patcher.PatchMainBG(File.ReadAllBytes(tbImageFile.Text));
                if (!res)
                {
                    MessageBox.Show("Couldn't patch this file, it might have been already modified or it's from an unsupported system version.");
                    return;
                }
            }

            if (targetPatch.NXThemeName == "home")
            {
                foreach (var n in TextureReplacement.NxNameToList[targetPatch.NXThemeName])
                {
                    if (HomeAppletIcons[n.NxThemeName] == null)
                    {
                        continue;
                    }
                    string path = HomeAppletIcons[n.NxThemeName].ToLower();
                    if (!path.EndsWith(".dds"))
                    {
                        MessageBox.Show($"For szs patching only dds images are supported");
                        return;
                    }
                    HomeAppletIcons[n.NxThemeName] = path;
                    if (!Patcher.PatchAppletIcon(File.ReadAllBytes(path), n.NxThemeName))
                    {
                        MessageBox.Show($"Failed applet icon patch for {n.NxThemeName}");
                        return;
                    }
                }
            }
            else if (targetPatch.NXThemeName == "lock" && LockCustomIcon != null)
            {
                if (!LockCustomIcon.ToLower().EndsWith(".dds"))
                {
                    MessageBox.Show($"For szs patching only dds images are supported");
                    return;
                }
                Patcher.PatchAppletIcon(File.ReadAllBytes(LockCustomIcon), TextureReplacement.Entrance[0].NxThemeName);
            }

            if (LayoutPatchList.SelectedIndex != 0)
            {
                Patcher.EnableAnimations = !UseAnim.Checked;
                var layoutres = Patcher.PatchLayouts(LayoutPatchList.SelectedItem as LayoutPatch, targetPatch);
                if (!layoutres)
                {
                    MessageBox.Show("One of the target files for the selected layout patch is missing in the SZS, you are probably using an already patched SZS");
                    return;
                }
                layoutres = Patcher.PatchAnimations((LayoutPatchList.SelectedItem as LayoutPatch).Anims);
                if (!layoutres)
                {
                    MessageBox.Show("Error while patching the animations !");
                    return;
                }
            }

            CommonSzs = Patcher.GetFinalSarc();
            var sarc = SARC.PackN(CommonSzs);

            File.WriteAllBytes(sav.FileName, ManagedYaz0.Compress(sarc.Item2, 3, (int)sarc.Item1));
            GC.Collect();

            if (Patcher.PatchTemplate.RequiresCodePatch)
            {
                MessageBox.Show("The file has been patched successfully but due to memory limitations this szs requires an extra code patch to be applied to the home menu, if you use NXThemesInstaller to install this it will be done automatically, otherwise you need to manually copy the patches from https://github.com/exelix11/SwitchThemeInjector/tree/master/SwitchThemesNX/romfs to the exefs patches directory of your cfw");
            }
            else
            {
                MessageBox.Show("Done");
            }
        }