├── SwitchThemesOnline ├── wwwroot │ ├── .nojekyll │ ├── layout │ │ ├── builtin │ │ │ └── put layouts here │ │ └── index.json │ ├── Utils.js │ ├── index.html │ └── css │ │ └── custom_styles2.css ├── Pages │ ├── _Imports.razor │ ├── EditorComponents │ │ ├── PropertiesInput.razor │ │ ├── BGSelect.razor │ │ ├── StateHolder.cs │ │ └── FileUploader.razor │ └── Index.razor ├── App.razor ├── _Imports.razor ├── readme.md ├── Program.cs ├── Startup.cs ├── Shared │ ├── UtilsWrapper.cs │ └── MainLayout.razor └── SwitchThemesOnline.csproj ├── Tests ├── Cases │ ├── ParsedLayouts │ │ ├── .gitkeep │ │ └── .gitignore │ ├── bg.dds │ └── Synthetic │ │ ├── bginjection.bflyt │ │ └── bflan.json ├── SwitchThemesCommonTests │ ├── Layouts.cs │ ├── SwitchThemesCommonTests.csproj │ ├── Util.cs │ ├── SyntheticTests.cs │ ├── Compression.cs │ └── RealTests.cs ├── readme.md └── SwitchThemesNXTests │ ├── Compression.cpp │ ├── Layouts.cpp │ ├── SyntheticTests.cpp │ ├── RealTests.cpp │ └── Util.hpp ├── icon.ico ├── ThemeScreenshot.jpg ├── SwitchThemes ├── icon.ico ├── layouts │ ├── ZnHm.jpg │ ├── DogeFl.png │ ├── GleLk.jpg │ ├── SuchHm.jpg │ ├── SuchLk.jpg │ ├── Side Lock.jpg │ ├── Flow Layout.jpg │ ├── JAG Layout.jpg │ ├── CarefulLayout.jpg │ ├── FlaunchRounded.jpg │ ├── DogeLayoutRounded.jpg │ ├── RoundedSmallCompact.jpg │ ├── SimpleLockscreenLayout.jpg │ ├── SmallCompactHomescreen.jpg │ ├── DiamondLayoutHomescreen.jpg │ ├── Transparant Playerselect.jpg │ ├── Transparant Playerselect top.jpg │ ├── Transparant Playerselect 90% Scale.jpg │ ├── Transparant Playerselect centered.jpg │ ├── Transparant Playerselect 90% Scale top.jpg │ ├── Transparant Playerselect 90% Scale centered.jpg │ ├── DogeFl.json │ ├── CommonNoFooter.json │ ├── Transparant Playerselect.json │ ├── Transparant Playerselect top.json │ ├── Transparant Playerselect centered.json │ ├── Transparant Playerselect 90% Scale.json │ ├── Transparant Playerselect 90% Scale top.json │ ├── Transparant Playerselect 90% Scale centered.json │ ├── FlaunchRounded.json │ ├── SuchLk.json │ └── SimpleLockscreenLayout.json ├── packages.config ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ └── AssemblyInfo.cs ├── ThemeInputInfo.cs ├── App.config └── RemoteInstallForm.cs ├── SwitchThemesNX ├── scripts │ ├── cibuild.sh │ └── build.sh ├── Libs │ ├── hactool │ │ ├── .gitignore │ │ ├── source │ │ │ ├── version.h │ │ │ ├── types.h │ │ │ ├── rsa.h │ │ │ ├── extkeys.h │ │ │ ├── LICENSE │ │ │ ├── sha.h │ │ │ ├── nax0.h │ │ │ ├── filepath.h │ │ │ ├── aes.h │ │ │ ├── nso.h │ │ │ ├── nca0_romfs.h │ │ │ ├── hfs0.h │ │ │ ├── pfs0.h │ │ │ ├── kip.h │ │ │ ├── bktr.h │ │ │ ├── utils.h │ │ │ └── sha.c │ │ ├── README.md │ │ └── include │ │ │ └── hactool.h │ ├── mbedtls │ │ ├── LICENSE │ │ ├── include │ │ │ ├── CMakeLists.txt │ │ │ └── mbedtls │ │ │ │ ├── net.h │ │ │ │ ├── gf128mul.h │ │ │ │ ├── havege.h │ │ │ │ ├── platform_time.h │ │ │ │ └── platform_util.h │ │ └── source │ │ │ └── version.c │ ├── Makefile │ └── SOIL │ │ ├── stbi_DDS_aug.h │ │ └── image_helper.h ├── SwitchThemesNX.jpg ├── romfs │ ├── opensans.ttf │ └── patches │ │ ├── 1839199F6CB331EF1B0E7925E67E397943456A05000000000000000000000000.ips │ │ ├── 27DDD9385FA9C7DBE72F05574F01ADAE3DCC130F000000000000000000000000.ips │ │ ├── 54868A4E20B10356F63304D68F6A2FEA0CF882DC000000000000000000000000.ips │ │ ├── 5937834AA1D0D40A4216C0A7503A83423E0E0D3A000000000000000000000000.ips │ │ ├── 5F7AEBA415D54291D58E7498B2DD1A777758C731000000000000000000000000.ips │ │ ├── 9DE0F08CB5F8A2B25B097484293324CD259B1D72000000000000000000000000.ips │ │ ├── A53014944694070011B321ED00CC14009FC65F35000000000000000000000000.ips │ │ ├── A694C828C2D6D053249E84587535B9AE02B724A8000000000000000000000000.ips │ │ ├── A87DBF733AE09A49DF1288F53CD2DEB81F57083A000000000000000000000000.ips │ │ ├── B2A05B062DA03FC5E3A310E80EE16A64935A8335000000000000000000000000.ips │ │ ├── BA0E686820294763CD12DEFDF44E7DE14BB4DCE8000000000000000000000000.ips │ │ └── BD3C95E4BDEA827F40F07AAC39893223E91FE5D0000000000000000000000000.ips └── source │ ├── Version.hpp │ ├── SwitchThemesCommon │ ├── MyTypes.h │ ├── SarcLib │ │ ├── Yaz0.hpp │ │ └── Sarc.hpp │ ├── Fonts │ │ └── TTF.hpp │ ├── Bntx │ │ ├── QuickBntx.hpp │ │ ├── DDSConv │ │ │ └── DDSConv.hpp │ │ ├── DDS.hpp │ │ └── BRTI.hpp │ ├── Layouts │ │ ├── Bflyt │ │ │ ├── BflytPatcher.hpp │ │ │ ├── Txt1Pane.hpp │ │ │ ├── RGBAColor.hpp │ │ │ ├── Grp1Pane.hpp │ │ │ ├── Pic1Pane.hpp │ │ │ ├── BasePane.hpp │ │ │ └── Pan1Pane.hpp │ │ ├── Base64.hpp │ │ └── LayoutCompatibility.hpp │ └── NXTheme.cpp │ ├── Pages │ ├── RemoteInstall │ │ ├── ApiUtil.hpp │ │ ├── RemoteInstall.hpp │ │ ├── Detail.hpp │ │ ├── List.hpp │ │ └── RemoteInstall.cpp │ ├── UninstallPage.hpp │ ├── NcaDumpPage.hpp │ ├── QlaunchPatchPage.hpp │ ├── CfwSelectPage.hpp │ ├── SettingsPage.hpp │ ├── ThemeEntry │ │ ├── ImagePreview.hpp │ │ ├── ThemeEntry.hpp │ │ ├── FontEntry.hpp │ │ └── LegacyEntry.hpp │ ├── TextPage.hpp │ ├── ExternalInstallPage.hpp │ ├── RebootPage.cpp │ ├── RemoteInstallPage.hpp │ ├── CfwSelectPage.cpp │ ├── ThemePage.hpp │ ├── UninstallPage.cpp │ ├── TextPage.cpp │ └── SettingsPage.cpp │ ├── UI │ ├── UIManagement.hpp │ ├── DialogPages.hpp │ ├── UI.hpp │ └── imgui │ │ └── imgui_impl_opengl3.h │ ├── SwitchTools │ ├── PatchMng.hpp │ ├── hactool.hpp │ └── InjectorInstall.hpp │ ├── Version.cpp │ ├── Dialogs.hpp │ └── Platform │ ├── PlatformFs.hpp │ ├── Windows │ └── dirent.h │ └── Platform.hpp ├── .gitattributes ├── DumpingFiles.md ├── .github ├── FUNDING.yml └── workflows │ ├── InjectorBuild.yml │ └── InstallerBuild.yml └── SwitchThemesCommon ├── Syroot.BinaryData ├── Meta │ ├── BinaryObjectAttribute.cs │ ├── BinaryConverterCache.cs │ ├── IBinaryConverter.cs │ └── MemberData.cs ├── Core │ └── EncodingExtensions.cs ├── ByteOrder.cs ├── SeekTask.cs ├── Offset.cs └── BinaryDataFormats.cs ├── SwitchThemesCommon.shproj ├── Bntx └── BntxxFormats.cs ├── Bflyt ├── Prt1Pane.cs └── Grp1Pane.cs └── Exten.cs /SwitchThemesOnline/wwwroot/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Tests/Cases/ParsedLayouts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Tests/Cases/ParsedLayouts/.gitignore: -------------------------------------------------------------------------------- 1 | *.json -------------------------------------------------------------------------------- /SwitchThemesOnline/wwwroot/layout/builtin/put layouts here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SwitchThemesOnline/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout MainLayout 2 | -------------------------------------------------------------------------------- /icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/icon.ico -------------------------------------------------------------------------------- /Tests/Cases/bg.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/Tests/Cases/bg.dds -------------------------------------------------------------------------------- /ThemeScreenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/ThemeScreenshot.jpg -------------------------------------------------------------------------------- /SwitchThemes/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/icon.ico -------------------------------------------------------------------------------- /SwitchThemesNX/scripts/cibuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | ver=$GITHUB_SHA 5 | make all "GITVER=CI-${ver}" $@ -------------------------------------------------------------------------------- /SwitchThemes/layouts/ZnHm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/ZnHm.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/DogeFl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/DogeFl.png -------------------------------------------------------------------------------- /SwitchThemes/layouts/GleLk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/GleLk.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/SuchHm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/SuchHm.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/SuchLk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/SuchLk.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/Side Lock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/Side Lock.jpg -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/.gitignore: -------------------------------------------------------------------------------- 1 | /config.mk 2 | /hactool 3 | /hactool.exe 4 | /*.o 5 | /*.dll 6 | /bin 7 | /test 8 | /test/* -------------------------------------------------------------------------------- /SwitchThemesNX/SwitchThemesNX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/SwitchThemesNX.jpg -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/opensans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/opensans.ttf -------------------------------------------------------------------------------- /SwitchThemes/layouts/Flow Layout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/Flow Layout.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/JAG Layout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/JAG Layout.jpg -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Shell scripts should use LF 2 | *.sh text eol=lf 3 | 4 | # Auto detect text files and perform LF normalization 5 | * text=auto -------------------------------------------------------------------------------- /SwitchThemes/layouts/CarefulLayout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/CarefulLayout.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/FlaunchRounded.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/FlaunchRounded.jpg -------------------------------------------------------------------------------- /Tests/Cases/Synthetic/bginjection.bflyt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/Tests/Cases/Synthetic/bginjection.bflyt -------------------------------------------------------------------------------- /SwitchThemes/layouts/DogeLayoutRounded.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/DogeLayoutRounded.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/RoundedSmallCompact.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/RoundedSmallCompact.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/SimpleLockscreenLayout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/SimpleLockscreenLayout.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/SmallCompactHomescreen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/SmallCompactHomescreen.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/DiamondLayoutHomescreen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/DiamondLayoutHomescreen.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/Transparant Playerselect.jpg -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/version.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_VERSION_H 2 | #define HACTOOL_VERSION_H 3 | 4 | #define HACTOOL_VERSION "1.4.0" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /SwitchThemesNX/scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | make clean 5 | 6 | ver=$(git describe --always --abbrev=40 --dirty) 7 | make all "GITVER=${ver}" $@ 8 | -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/Transparant Playerselect top.jpg -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/mbedtls/LICENSE: -------------------------------------------------------------------------------- 1 | Unless specifically indicated otherwise in a file, files are licensed 2 | under the Apache 2.0 license, as can be found in: apache-2.0.txt -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect 90% Scale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/Transparant Playerselect 90% Scale.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect centered.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/Transparant Playerselect centered.jpg -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean all 2 | 3 | all: 4 | $(MAKE) -C hactool 5 | $(MAKE) -C mbedtls 6 | 7 | clean: 8 | $(MAKE) -C hactool clean 9 | $(MAKE) -C mbedtls clean -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect 90% Scale top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/Transparant Playerselect 90% Scale top.jpg -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect 90% Scale centered.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemes/layouts/Transparant Playerselect 90% Scale centered.jpg -------------------------------------------------------------------------------- /SwitchThemesOnline/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Sorry, there's nothing at this address.

4 |
5 |
6 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Version.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Version { 5 | extern const std::string Name; 6 | extern const std::string Commit; 7 | extern const std::string UserAgent; 8 | } -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/1839199F6CB331EF1B0E7925E67E397943456A05000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/1839199F6CB331EF1B0E7925E67E397943456A05000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/27DDD9385FA9C7DBE72F05574F01ADAE3DCC130F000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/27DDD9385FA9C7DBE72F05574F01ADAE3DCC130F000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/54868A4E20B10356F63304D68F6A2FEA0CF882DC000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/54868A4E20B10356F63304D68F6A2FEA0CF882DC000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/5937834AA1D0D40A4216C0A7503A83423E0E0D3A000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/5937834AA1D0D40A4216C0A7503A83423E0E0D3A000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/5F7AEBA415D54291D58E7498B2DD1A777758C731000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/5F7AEBA415D54291D58E7498B2DD1A777758C731000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/9DE0F08CB5F8A2B25B097484293324CD259B1D72000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/9DE0F08CB5F8A2B25B097484293324CD259B1D72000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/A53014944694070011B321ED00CC14009FC65F35000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/A53014944694070011B321ED00CC14009FC65F35000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/A694C828C2D6D053249E84587535B9AE02B724A8000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/A694C828C2D6D053249E84587535B9AE02B724A8000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/A87DBF733AE09A49DF1288F53CD2DEB81F57083A000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/A87DBF733AE09A49DF1288F53CD2DEB81F57083A000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/B2A05B062DA03FC5E3A310E80EE16A64935A8335000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/B2A05B062DA03FC5E3A310E80EE16A64935A8335000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/BA0E686820294763CD12DEFDF44E7DE14BB4DCE8000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/BA0E686820294763CD12DEFDF44E7DE14BB4DCE8000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesNX/romfs/patches/BD3C95E4BDEA827F40F07AAC39893223E91FE5D0000000000000000000000000.ips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exelix11/SwitchThemeInjector/HEAD/SwitchThemesNX/romfs/patches/BD3C95E4BDEA827F40F07AAC39893223E91FE5D0000000000000000000000000.ips -------------------------------------------------------------------------------- /SwitchThemesOnline/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Routing 4 | @using Microsoft.JSInterop 5 | @using SwitchThemesOnline 6 | @using SwitchThemesOnline.Shared 7 | -------------------------------------------------------------------------------- /DumpingFiles.md: -------------------------------------------------------------------------------- 1 | # Dumping Files 2 | Manually extracting the home menu is not needed anymore as the latest NXThemes Installer (Ver 1.3) automatically does it without any manual setup. If you need the szs files for layout editing they're in the `/themes/systemData` folder on your sd card. 3 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/MyTypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef int8_t s8; 5 | typedef int16_t s16; 6 | typedef int32_t s32; 7 | typedef int64_t s64; 8 | typedef uint8_t u8; 9 | typedef uint16_t u16; 10 | typedef uint32_t u32; 11 | typedef uint64_t u64; -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/SarcLib/Yaz0.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../MyTypes.h" 4 | 5 | namespace Yaz0 6 | { 7 | std::vector Decompress(const std::vector &Data); 8 | std::vector Compress(const std::vector &Data, int level = 3, int reserved1 = 0, int reserved2 = 0); 9 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/RemoteInstall/ApiUtil.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "../../SwitchThemesCommon/MyTypes.h" 6 | 7 | namespace RemoteInstall::API::Util 8 | { 9 | CURL* EasyGET(const std::string& url, std::vector& out, intptr_t priv = 0); 10 | } -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/README.md: -------------------------------------------------------------------------------- 1 | # hactool 2 | Original repo: https://github.com/SciresM/hactool 3 | 4 | Changes: 5 | - Makefile to compile as a switch lib 6 | - Use spl services to decrypt the key area of an nca 7 | - Extract exefs files to a buffer 8 | 9 | Portlibs mbedtls won't work for building as it's compiled without cmac support. -------------------------------------------------------------------------------- /SwitchThemes/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Fonts/TTF.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../BinaryReadWrite/Buffer.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../MyTypes.h" 8 | 9 | namespace SwitchThemesCommon::TTF 10 | { 11 | std::string GetFontName(const std::vector &Data); 12 | std::vector ConvertToBFTTF(const std::vector &Data); 13 | } -------------------------------------------------------------------------------- /SwitchThemesOnline/readme.md: -------------------------------------------------------------------------------- 1 | This is a new version of the web injector built entirely from scratch, the old code is available till [commit c8d77a4](https://github.com/exelix11/SwitchThemeInjector/commit/c8d77a48235eb18bb93343617a969c57b55ccd6f) 2 | 3 | # Building 4 | Building the new web injector requires visual studio 2019 preview and .net core 3 preview 6. 5 | It's recommended to unload the repo if you're using non-preview visual studio -------------------------------------------------------------------------------- /SwitchThemesNX/source/UI/UIManagement.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define GLFW_INCLUDE_NONE 4 | #include 5 | #include "glad.h" 6 | 7 | #include "imgui/imgui.h" 8 | 9 | namespace GFX { 10 | extern float WRatio, HRatio; 11 | 12 | extern GLFWwindow* mainWindow; 13 | 14 | bool Init(); 15 | void Exit(); 16 | 17 | void StartFrame(); 18 | void EndFrame(); 19 | } 20 | 21 | namespace App { 22 | bool MainLoop(); 23 | void Quit(); 24 | } -------------------------------------------------------------------------------- /SwitchThemesOnline/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Blazor.Hosting; 2 | 3 | namespace SwitchThemesOnline 4 | { 5 | public class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | CreateHostBuilder(args).Build().Run(); 10 | } 11 | 12 | public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) => 13 | BlazorWebAssemblyHost.CreateDefaultBuilder() 14 | .UseBlazorStartup(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SwitchThemes/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/types.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_TYPES_H 2 | #define HACTOOL_TYPES_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | typedef uint8_t byte; 10 | 11 | typedef enum { 12 | VALIDITY_UNCHECKED = 0, 13 | VALIDITY_INVALID, 14 | VALIDITY_VALID 15 | } validity_t; 16 | 17 | #define GET_VALIDITY_STR(validity) ((validity == VALIDITY_VALID) ? "GOOD" : "FAIL") 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/UninstallPage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../UI/UI.hpp" 8 | #include "../fs.hpp" 9 | 10 | class UninstallPage : public IPage 11 | { 12 | private: 13 | ImGuiID firstBtn = 0; 14 | public: 15 | UninstallPage(); 16 | 17 | void Render(int X, int Y) override; 18 | void Update() override; 19 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchTools/PatchMng.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace PatchMng 5 | { 6 | bool Init(); 7 | 8 | const std::string& QlaunchBuildId(); 9 | 10 | enum class InstallResult { 11 | Ok, 12 | MissingIps, 13 | SDError, 14 | UnsupportedCFW 15 | }; 16 | 17 | InstallResult EnsureInstalled(); 18 | void RemoveAll(); 19 | 20 | bool CanInstallTheme(const std::string& FileName); 21 | bool ExefsCompatAsk(const std::string& SzsName); 22 | }; -------------------------------------------------------------------------------- /SwitchThemes/layouts/DogeFl.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "All Apps 90% Scale", 3 | "AuthorName": "Such Meme, Many Skill", 4 | "TargetName": "Flaunch.szs", 5 | "ID": "builtin_AllApps90S", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/FlcBtnIconGame.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "N_Delete", 12 | "Scale": { 13 | "X": 0.9, 14 | "Y": 0.9 15 | } 16 | } 17 | ] 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Version.cpp: -------------------------------------------------------------------------------- 1 | #include "Version.hpp" 2 | 3 | #define VER_NUM "2.8.3" 4 | #define VER_NAME "Ver. " VER_NUM 5 | 6 | #ifndef GITVER 7 | #define GITVER "Unknown version" 8 | #endif 9 | 10 | #ifdef DEVBUILD 11 | const std::string Version::Name = VER_NAME " - DEV BUILD"; 12 | #else 13 | const std::string Version::Name = VER_NAME; 14 | #endif 15 | 16 | const std::string Version::Commit = "Commit: " GITVER; 17 | const std::string Version::UserAgent = "NXThemes/" VER_NUM; -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/include/hactool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include "../source/types.h" 8 | #include "../source/utils.h" 9 | #include "../source/settings.h" 10 | #include "../source/pki.h" 11 | #include "../source/nca.h" 12 | #include "../source/xci.h" 13 | #include "../source/nax0.h" 14 | #include "../source/extkeys.h" 15 | #include "../source/packages.h" 16 | #include "../source/nso.h" 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/NcaDumpPage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../UI/UI.hpp" 8 | #include "../fs.hpp" 9 | 10 | class NcaDumpPage : public IPage 11 | { 12 | public: 13 | NcaDumpPage(); 14 | 15 | void Render(int X, int Y) override; 16 | void Update() override; 17 | 18 | static void CheckHomeMenuVer(); 19 | static void WriteHomeNcaVersion(); 20 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/QlaunchPatchPage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../UI/UI.hpp" 3 | #include 4 | #include "../SwitchTools/PatchMng.hpp" 5 | 6 | class QlaunchPatchPage : public IPage 7 | { 8 | public: 9 | QlaunchPatchPage(); 10 | 11 | void Render(int X, int Y) override; 12 | void Update() override; 13 | 14 | bool ShouldShow(); 15 | private: 16 | void CheckForUpdates(); 17 | 18 | PatchMng::InstallResult patchStatus = PatchMng::InstallResult::Ok; 19 | std::string updateMessageString = ""; 20 | bool updateMessageIsError = false; 21 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/source/Dialogs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | void Dialog(const std::string &msg); 7 | 8 | //executes a function after the drawing loop is terminated 9 | void PushFunction(const std::function& fun); 10 | 11 | //These functions can only be called during the update function as they need to draw outside of the main loop 12 | void DialogBlocking(const std::string &msg); 13 | void DisplayLoading(const std::string &msg); 14 | void DisplayLoading(std::initializer_list lines); -------------------------------------------------------------------------------- /SwitchThemes/layouts/CommonNoFooter.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "Common.szs no footer", 3 | "AuthorName": "SvenDaHacker64", 4 | "TargetName": "common.szs", 5 | "ID": "builtin_CommonNoFooter", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/FooterAll.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "N_Root_00" 12 | }, 13 | { 14 | "PaneName": "N_Pos_00", 15 | "Position": { 16 | "X": 0.0, 17 | "Y": 1000.0, 18 | "Z": 0.0 19 | } 20 | } 21 | ] 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/mbedtls/include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | option(INSTALL_MBEDTLS_HEADERS "Install mbed TLS headers." ON) 2 | 3 | if(INSTALL_MBEDTLS_HEADERS) 4 | 5 | file(GLOB headers "mbedtls/*.h") 6 | 7 | install(FILES ${headers} 8 | DESTINATION include/mbedtls 9 | PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) 10 | 11 | endif(INSTALL_MBEDTLS_HEADERS) 12 | 13 | # Make config.h available in an out-of-source build. ssl-opt.sh requires it. 14 | if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) 15 | link_to_source(mbedtls) 16 | endif() 17 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/CfwSelectPage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../UI/UI.hpp" 8 | #include "../fs.hpp" 9 | #include 10 | 11 | class CfwSelectPage : public IUIControlObj 12 | { 13 | public: 14 | CfwSelectPage(const std::vector &folders); 15 | ~CfwSelectPage(); 16 | 17 | void Render(int X, int Y) override; 18 | void Update() override; 19 | private: 20 | std::vector Folders; 21 | }; -------------------------------------------------------------------------------- /SwitchThemesOnline/Startup.cs: -------------------------------------------------------------------------------- 1 | using Blazor.FileReader; 2 | using Microsoft.AspNetCore.Components.Builder; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Mono.WebAssembly.Interop; 5 | 6 | namespace SwitchThemesOnline 7 | { 8 | public class Startup 9 | { 10 | public void ConfigureServices(IServiceCollection services) 11 | { 12 | services.AddFileReaderService(); 13 | services.AddSingleton(); 14 | } 15 | 16 | public void Configure(IComponentsApplicationBuilder app) 17 | { 18 | app.AddComponent("app"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/rsa.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_RSA_H 2 | #define HACTOOL_RSA_H 3 | 4 | #include 5 | 6 | int rsa2048_pss_verify(const void *data, size_t len, const unsigned char *signature, const unsigned char *modulus); 7 | int rsa2048_pkcs1_verify(const void *data, size_t len, const unsigned char *signature, const unsigned char *modulus); 8 | int rsa2048_oaep_decrypt_verify(void *out, size_t max_out_len, const unsigned char *signature, const unsigned char *modulus, const unsigned char *exponent, size_t exponent_len, const unsigned char *label_hash, size_t *out_len); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/SettingsPage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../UI/UI.hpp" 8 | #include "../fs.hpp" 9 | 10 | namespace Settings { 11 | extern bool UseIcons; 12 | extern bool UseCommon; 13 | extern SwitchThemesCommon::LayoutCompatibilityOption HomeMenuCompat; 14 | }; 15 | 16 | class SettingsPage : public IPage 17 | { 18 | public: 19 | SettingsPage(); 20 | 21 | void Render(int X, int Y) override; 22 | void Update() override; 23 | }; 24 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Platform/PlatformFs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef __SWITCH__ 4 | #define ASSET(_str) "./romfs/" _str 5 | #define SD_PREFIX "F:" 6 | #else 7 | #include 8 | #define ASSET(_str) "romfs:/" _str 9 | #define SD_PREFIX "sdmc:" 10 | #endif 11 | 12 | #if WIN32 13 | #include 14 | #include 15 | #include "Windows\dirent.h" 16 | #define mkdir(x,y) _mkdir(x) 17 | #define rmdir(x) _rmdir(x) 18 | #define unlink(x) _unlink(x) 19 | #undef CreateDirectory 20 | #undef max 21 | #else 22 | #include 23 | #include 24 | #endif 25 | 26 | #define LOGf(...) printf(__VA_ARGS__) -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Bntx/QuickBntx.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "../MyTypes.h" 6 | #include "../BinaryReadWrite/Buffer.hpp" 7 | #include "BRTI.hpp" 8 | #include "DDS.hpp" 9 | 10 | class QuickBntx 11 | { 12 | public: 13 | std::vector Textures; 14 | std::vector Rlt; 15 | 16 | QuickBntx(Buffer &Reader); 17 | 18 | std::vector Write(); 19 | void ReplaceTex(const std::string &name, const DDSEncoder::DDSLoadResult &tex); 20 | Bntxx::BRTI* FindTex(const std::string &name); 21 | private: 22 | std::vector Head; 23 | }; -------------------------------------------------------------------------------- /SwitchThemesOnline/Pages/EditorComponents/PropertiesInput.razor: -------------------------------------------------------------------------------- 1 |
Select the theme target and choose a name
2 | 3 |
4 |

Theme target:

5 | 11 |
12 | 13 |

Theme name:

14 | 15 |

Theme author:

16 | 17 | 18 | @code { 19 | [Parameter] public StateHolder State { get; set; } 20 | } 21 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchTools/hactool.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../fs.hpp" 3 | #include 4 | #include 5 | 6 | namespace hactool { 7 | constexpr u64 QlaunchID = 0x0100000000001000; 8 | constexpr u64 PslID = 0x0100000000001007; 9 | constexpr u64 UserPageID = 0x0100000000001013; 10 | 11 | void ExtractPlayerSelectMenu(); 12 | void ExtractUserPage(); 13 | void ExtractHomeMenu(); 14 | void ExtractTitle(u64 contentID, const std::string& Path); 15 | 16 | void ExtractHomeExefs(); 17 | 18 | std::array GetTitleBuildID(u64 contentID); 19 | std::string BuildIDToString(std::array data); 20 | 21 | std::string QlaunchBuildID(); 22 | } -------------------------------------------------------------------------------- /Tests/Cases/Synthetic/bflan.json: -------------------------------------------------------------------------------- 1 | {"LittleEndian":true,"Version":2000000,"pat1":{"AnimationOrder":0,"Name":"test","ChildBinding":1,"Groups":["SomeGroup"],"Unk_StartOfFile":0,"Unk_EndOfFile":0,"Unk_EndOfHeader":""},"pai1":{"FrameSize":50,"Flags":0,"Textures":[],"Entries":[{"Name":"FirstEntry","Target":0,"Tags":[{"Unknown":0,"TagType":"FLVC","Entries":[{"Index":0,"AnimationTarget":10,"DataType":2,"KeyFrames":[{"Frame":1.0,"Value":2.0,"Blend":3.0},{"Frame":50.0,"Value":100.0,"Blend":0.0}],"FLEUUnknownInt":0,"FLEUEntryName":""}]}],"UnkwnownData":""},{"Name":"Second","Target":0,"Tags":[{"Unknown":0,"TagType":"FLEU","Entries":[{"KeyFrames":[],"FLEUEntryName":"name"}]}],"UnkwnownData":""}]}} -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/ThemeEntry/ImagePreview.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../UI/UI.hpp" 3 | #include "../../ViewFunctions.hpp" 4 | 5 | class ImagePreview : public IUIControlObj 6 | { 7 | public: 8 | ImagePreview(LoadedImage img) : img(img) {} 9 | 10 | void Render(int X, int Y) override 11 | { 12 | Utils::ImGuiNextFullScreen(); 13 | ImGui::Begin("ImagePreview", nullptr, DefaultWinFlags); 14 | 15 | ImGui::Image((ImTextureID)(uintptr_t)img, { SCR_W, SCR_H }); 16 | 17 | if (ImGui::IsItemClicked() || Utils::PageLeaveFocusInput()) 18 | PopPage(this); 19 | 20 | ImGui::End(); 21 | } 22 | 23 | void Update() override {}; 24 | private: 25 | LoadedImage img; 26 | }; 27 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchTools/InjectorInstall.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "../SwitchThemesCommon/MyTypes.h" 5 | 6 | namespace InjectorInstall{ 7 | class Server 8 | { 9 | public: 10 | ~Server() { StopHosting(); } 11 | 12 | void StartHosting(); 13 | void StopHosting(); 14 | void Clear(); 15 | 16 | bool IsHosting() { return hostSock > 0; } 17 | void HostUpdate(); 18 | std::string GetHostname(); 19 | 20 | const std::vector& Buffer(); 21 | bool HasFinished() { return Finished; } 22 | private: 23 | bool Finished = false; 24 | std::vector Data; 25 | 26 | u32 PayloadSize = 0; 27 | int hostSock = -1; 28 | int clientSock = -1; 29 | }; 30 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Bntx/DDSConv/DDSConv.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef SWITCHTHEMESCOMMON_TESTS 3 | //This is not properly part of SwitchThemesCommon but it's needed for installing since support for png background instead of dds 4 | //The image must be converted to DDS so it can go through the already existing lib 5 | 6 | #include 7 | #include 8 | 9 | #define GLFW_INCLUDE_NONE 10 | #include 11 | #include "../../../UI/glad.h" 12 | #include "../../MyTypes.h" 13 | 14 | namespace DDSConv 15 | { 16 | std::vector ImageToDDS(const std::vector& imgData, bool DXT5 = false, int ExpectedW = 1280, int ExpectedH = 720); 17 | const std::string& GetError(); 18 | } 19 | #endif -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: exelix11 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "Transparent Playerselect", 3 | "AuthorName": "Migush", 4 | "TargetName": "Psl.szs", 5 | "ID": "builtin_TransparentPSL", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/DBtmHeaderNml.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "T_00", 12 | "Visible": false 13 | }, 14 | { 15 | "PaneName": "P_Line", 16 | "Visible": false 17 | } 18 | ] 19 | }, 20 | { 21 | "FileName": "blyt/PslSelectSinglePlayer.bflyt", 22 | "Patches": [ 23 | { 24 | "PaneName": "P_Bg", 25 | "Visible": false 26 | } 27 | ] 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/RemoteInstall/RemoteInstall.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace RemoteInstall 6 | { 7 | struct Provider 8 | { 9 | std::string Name; 10 | std::string UrlTemplate; 11 | bool Static; 12 | }; 13 | 14 | enum class FixedTypes 15 | { 16 | Random, 17 | Recent 18 | }; 19 | 20 | void Initialize(); 21 | void Finalize(); 22 | bool IsInitialized(); 23 | 24 | void Begin(const RemoteInstall::Provider& provider, const std::string& ID); 25 | void BeginType(const RemoteInstall::Provider& provider, FixedTypes type); 26 | void BeginRandom(const RemoteInstall::Provider& provider); 27 | void BeginRecent(const RemoteInstall::Provider& provider); 28 | 29 | const std::vector& GetProviders(); 30 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/RemoteInstall/Detail.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../UI/UI.hpp" 3 | #include "API.hpp" 4 | #include 5 | 6 | namespace RemoteInstall 7 | { 8 | class DetailPage : public IUIControlObj 9 | { 10 | public: 11 | DetailPage(const RemoteInstall::API::Entry& entry, LoadedImage img); 12 | 13 | const RemoteInstall::API::Entry entry; 14 | 15 | void Update(); 16 | void Render(int X, int Y); 17 | ~DetailPage(); 18 | private: 19 | std::string PartName; 20 | LoadedImage img; 21 | 22 | enum class Action : int 23 | { 24 | Download = 1, 25 | Install = 2, 26 | DownloadInstall = 3 27 | }; 28 | 29 | void UserDownload(Action act); 30 | 31 | std::vector DownloadData(); 32 | std::vector DownloadedTheme; 33 | }; 34 | } -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/extkeys.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_EXTKEYS_H 2 | #define HACTOOL_EXTKEYS_H 3 | 4 | #include 5 | #include "types.h" 6 | #include "utils.h" 7 | #include "settings.h" 8 | 9 | void parse_hex_key(unsigned char *key, const char *hex, unsigned int len); 10 | void extkeys_initialize_settings(hactool_settings_t *settings, FILE *f); 11 | 12 | void extkeys_parse_titlekeys(hactool_settings_t *settings, FILE *f); 13 | 14 | int settings_has_titlekey(hactool_settings_t *settings, const unsigned char *rights_id); 15 | void settings_add_titlekey(hactool_settings_t *settings, const unsigned char *rights_id, const unsigned char *titlekey); 16 | titlekey_entry_t *settings_get_titlekey(hactool_settings_t *settings, const unsigned char *rights_id); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /SwitchThemesOnline/Pages/EditorComponents/BGSelect.razor: -------------------------------------------------------------------------------- 1 | @using System.IO; 2 | 3 |
Select a background image:
4 | 5 | 6 |

7 | Upload a 1280x720 image, only JPG files are supported. Who needs DDS files anyway ? 8 |

9 | 10 | 11 | 12 | @functions { 13 | [Parameter] 14 | public StateHolder state { get; set; } 15 | 16 | string imageAsString { get; set; } = ""; 17 | 18 | public void LoadImage(MemoryStream file) 19 | { 20 | state.MainBG = new byte[file.Length]; 21 | file.Read(state.MainBG, 0, state.MainBG.Length); 22 | imageAsString = $"data:image/jpeg;base64,{Convert.ToBase64String(state.MainBG)}"; 23 | StateHasChanged(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SwitchThemesOnline/wwwroot/Utils.js: -------------------------------------------------------------------------------- 1 | window.DomUtil = { 2 | Click: function (element) { 3 | element.click(); 4 | } 5 | }; 6 | 7 | function DownloadUrl (filename, url) { 8 | var link = document.createElement('a'); 9 | link.download = filename; 10 | link.href = url; 11 | document.body.appendChild(link); 12 | link.click(); 13 | document.body.removeChild(link); 14 | } 15 | 16 | function DownloadBlob (fileName, data) { 17 | var blob, url; 18 | console.log(typeof data); 19 | var dataArr = Blazor.platform.toUint8Array(data); 20 | blob = new Blob([dataArr], { 21 | type: "application/octet-stream" 22 | }); 23 | url = window.URL.createObjectURL(blob); 24 | DownloadUrl(Blazor.platform.toJavaScriptString(fileName), url); 25 | setTimeout(function () { 26 | return window.URL.revokeObjectURL(url); 27 | }, 1000); 28 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/TextPage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../UI/UI.hpp" 8 | #include "../fs.hpp" 9 | 10 | class TextPage : public IPage 11 | { 12 | public: 13 | TextPage(const std::string &title, const std::string &text); 14 | TextPage(const char* title, const char* text); 15 | 16 | void Render(int X, int Y) override; 17 | void Update() override; 18 | private: 19 | 20 | std::string Text; 21 | const char* c_str; 22 | }; 23 | 24 | class CreditsPage : public IPage 25 | { 26 | public: 27 | CreditsPage(); 28 | 29 | void Render(int X, int Y) override; 30 | void Update() override; 31 | private: 32 | const std::string creditsText; 33 | }; 34 | -------------------------------------------------------------------------------- /Tests/SwitchThemesCommonTests/Layouts.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SwitchThemes.Common; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | 9 | namespace SwitchThemesCommonTests 10 | { 11 | [TestClass] 12 | public class Layouts 13 | { 14 | [TestMethod] 15 | public void LoadAndOptimizeAll() 16 | { 17 | // This generates layouts to load for SwitchThemesNXTests::Layouts::LayoutLoading 18 | foreach (var f in Directory.EnumerateFiles("../../../../../SwitchThemes/layouts").Where(x => x.EndsWith(".json"))) 19 | File.WriteAllText( 20 | Path.Combine(Util.GetPath("ParsedLayouts"), Path.GetFileName(f)), 21 | LayoutPatch.Load(File.ReadAllText(f)).AsJson() 22 | ); 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2018, SciresM 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /Tests/SwitchThemesCommonTests/SwitchThemesCommonTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/sha.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_SHA_H 2 | #define HACTOOL_SHA_H 3 | 4 | #include 5 | 6 | /* Enumerations. */ 7 | typedef enum { 8 | HASH_TYPE_SHA1 = MBEDTLS_MD_SHA1, 9 | HASH_TYPE_SHA256 = MBEDTLS_MD_SHA256, 10 | } hash_type_t; 11 | 12 | /* Define structs. */ 13 | typedef struct { 14 | mbedtls_md_context_t digest; 15 | } sha_ctx_t; 16 | 17 | /* Function prototypes. */ 18 | sha_ctx_t *new_sha_ctx(hash_type_t type, int hmac); 19 | void sha_update(sha_ctx_t *ctx, const void *data, size_t l); 20 | void sha_get_hash(sha_ctx_t *ctx, unsigned char *hash); 21 | void free_sha_ctx(sha_ctx_t *ctx); 22 | 23 | void sha256_hash_buffer(unsigned char *digest, const void *data, size_t l); 24 | 25 | void sha256_get_buffer_hmac(void *digest, const void *secret, size_t s_l, const void *data, size_t d_l); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/ExternalInstallPage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../UI/UI.hpp" 8 | #include "../fs.hpp" 9 | #include "ThemeEntry/ThemeEntry.hpp" 10 | #include 11 | 12 | class ExternalInstallPage : public IUIControlObj 13 | { 14 | public: 15 | ExternalInstallPage(const std::vector &paths); 16 | ~ExternalInstallPage(); 17 | 18 | void Render(int X, int Y) override; 19 | void Update() override; 20 | private: 21 | bool tooManyItems = false; 22 | int RenderStartIndex = 0; 23 | int SelectedIndex = 0; 24 | 25 | bool isInstalled = false; 26 | bool installSuccess = true; 27 | std::vector > ArgEntries; 28 | const u32 GRAY = 0x808080FF; 29 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/SOIL/stbi_DDS_aug.h: -------------------------------------------------------------------------------- 1 | /* 2 | adding DDS loading support to stbi 3 | */ 4 | 5 | #ifndef HEADER_STB_IMAGE_DDS_AUGMENTATION 6 | #define HEADER_STB_IMAGE_DDS_AUGMENTATION 7 | 8 | // is it a DDS file? 9 | extern int stbi_dds_test_memory (stbi_uc const *buffer, int len); 10 | 11 | extern stbi_uc *stbi_dds_load (char *filename, int *x, int *y, int *comp, int req_comp); 12 | extern stbi_uc *stbi_dds_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); 13 | #ifndef STBI_NO_STDIO 14 | extern int stbi_dds_test_file (FILE *f); 15 | extern stbi_uc *stbi_dds_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); 16 | #endif 17 | 18 | // 19 | // 20 | //// end header file ///////////////////////////////////////////////////// 21 | #endif // HEADER_STB_IMAGE_DDS_AUGMENTATION 22 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/nax0.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_NAX0_H 2 | #define HACTOOL_NAX0_H 3 | 4 | #include 5 | #include "types.h" 6 | #include "utils.h" 7 | #include "settings.h" 8 | #include "aes.h" 9 | 10 | #define MAGIC_NAX0 0x3058414E 11 | 12 | typedef struct { 13 | uint8_t hmac_header[0x20]; 14 | uint32_t magic; 15 | uint32_t _0x24; 16 | uint8_t keys[2][0x10]; 17 | uint64_t size; 18 | uint8_t _0x50[0x30]; 19 | } nax0_header_t; 20 | 21 | typedef struct { 22 | filepath_t base_path; 23 | hactool_ctx_t *tool_ctx; 24 | aes_ctx_t *aes_ctx; 25 | FILE **files; 26 | unsigned int num_files; 27 | unsigned int k; 28 | unsigned char encrypted_keys[2][0x10]; 29 | nax0_header_t header; 30 | } nax0_ctx_t; 31 | 32 | void nax0_process(nax0_ctx_t *ctx); 33 | void nax0_save(nax0_ctx_t *ctx); 34 | void nax0_print(nax0_ctx_t *ctx); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect top.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "Transparent Playerselect top", 3 | "AuthorName": "Migush", 4 | "TargetName": "Psl.szs", 5 | "ID": "builtin_TransparentPSLTop", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/DBtmHeaderNml.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "T_00", 12 | "Visible": false 13 | }, 14 | { 15 | "PaneName": "P_Line", 16 | "Visible": false 17 | } 18 | ] 19 | }, 20 | { 21 | "FileName": "blyt/PslSelectSinglePlayer.bflyt", 22 | "Patches": [ 23 | { 24 | "PaneName": "N_Cnt", 25 | "Position": { 26 | "X": 0.0, 27 | "Y": 230.0, 28 | "Z": 0.0 29 | } 30 | }, 31 | { 32 | "PaneName": "P_Bg", 33 | "Visible": false 34 | } 35 | ] 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect centered.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "Transparent Playerselect centered", 3 | "AuthorName": "Migush", 4 | "TargetName": "Psl.szs", 5 | "ID": "builtin_TransparentPSLCenter", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/DBtmHeaderNml.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "T_00", 12 | "Visible": false 13 | }, 14 | { 15 | "PaneName": "P_Line", 16 | "Visible": false 17 | } 18 | ] 19 | }, 20 | { 21 | "FileName": "blyt/PslSelectSinglePlayer.bflyt", 22 | "Patches": [ 23 | { 24 | "PaneName": "N_Cnt", 25 | "Position": { 26 | "X": 0.0, 27 | "Y": 0.0, 28 | "Z": 0.0 29 | } 30 | }, 31 | { 32 | "PaneName": "P_Bg", 33 | "Visible": false 34 | } 35 | ] 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /Tests/readme.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | The most challenging part of the project is to make sure nothing breaks after changes in the code. This is quite hard as we treat qlaunch as a black-box that may or may not accept our edits to the system files. 3 | So most tests are about ensuring that the output is consistent with previous versions. 4 | 5 | Unfortunately it means that we need original szs files to test this, i can't include them in the repo so for the time being you will have to obtain them by yourself. 6 | 7 | My reference currently are files from 10.0 qlaunch. The ResidentMenu.szs file SHA256 starts with `199FA9B627EDF`. 8 | 9 | Put original files in `Cases/Source `and expected results in `Cases/Expected`. 10 | 11 | Synthetic tests are files not actually from the home menu that can be used as a baseline for testing certain features, I plan to expand on them as using non-copyrighted files would mean having tests that can be automated with github actions or equivalent. -------------------------------------------------------------------------------- /SwitchThemesOnline/Shared/UtilsWrapper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | using Microsoft.JSInterop; 3 | using Mono.WebAssembly.Interop; 4 | using System; 5 | using System.Threading.Tasks; 6 | 7 | public static class Exten 8 | { 9 | public static async Task Click(this IJSRuntime runtime, ElementReference element) => 10 | await runtime.InvokeAsync("DomUtil.Click", element); 11 | 12 | public static async Task Alert(this IJSRuntime runtime, string message) => 13 | await runtime.InvokeAsync("alert", message); 14 | 15 | public static void DownloadFile(this MonoWebAssemblyJSRuntime js, string fileName, byte[] Data) => 16 | js.InvokeUnmarshalled("DownloadBlob", fileName, Data); 17 | 18 | public static async Task LegacyDownloadFile(this IJSRuntime js, string fileName, byte[] Data) => 19 | await js.InvokeAsync("DownloadUrl", fileName, "data:application/octet-stream;base64," + Convert.ToBase64String(Data)); 20 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/SarcLib/Sarc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../BinaryReadWrite/Buffer.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../MyTypes.h" 8 | 9 | class SARC 10 | { 11 | public: 12 | struct PackedSarc 13 | { 14 | std::vector data; 15 | u32 align; 16 | }; 17 | 18 | struct SarcData 19 | { 20 | std::unordered_map> files; 21 | Endianness endianness; 22 | bool HashOnly; 23 | }; 24 | 25 | static PackedSarc Pack(SarcData &data, s32 _align = -1); 26 | static SarcData Unpack(const std::vector &data); 27 | 28 | private: 29 | static u32 NameHash(const std::string &name); 30 | static u32 StringHashToUint(const std::string &name); 31 | static std::string GuessFileExtension(const std::vector &file); 32 | static u32 GuessAlignment(const std::unordered_map> &files); 33 | static u32 GuessFileAlignment(const std::vector &file); 34 | }; -------------------------------------------------------------------------------- /SwitchThemes/ThemeInputInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace SwitchThemes 5 | { 6 | public partial class ThemeInputInfo : Form 7 | { 8 | public (string, string) result { get; set; } = (null, null); 9 | 10 | public ThemeInputInfo() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | public static (string, string) Ask() 16 | { 17 | var f = new ThemeInputInfo(); 18 | f.ShowDialog(); 19 | return f.result; 20 | } 21 | 22 | private void button1_Click(object sender, EventArgs e) 23 | { 24 | if (tbThemeName.Text.Trim() == "") 25 | { 26 | MessageBox.Show("Insert a valid theme name to continue"); 27 | return; 28 | } 29 | result = (tbThemeName.Text, tbAuthorName.Text); 30 | this.Close(); 31 | } 32 | 33 | private void button2_Click(object sender, EventArgs e) 34 | { 35 | result = (null, null); 36 | this.Close(); 37 | } 38 | 39 | private void ThemeInputInfo_Load(object sender, EventArgs e) 40 | { 41 | 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SwitchThemesOnline/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | WebInjector 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |

15 | Loading the Switch theme injector....
16 | This build requires support for WebAssembly.
17 | If the page doesn't load for you try enabling javascript, disabling adblockers or upgrading to a proper browser 18 |

19 |

20 | In case of issues you can go back to the old version 21 |

22 |
23 |
24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/Meta/BinaryObjectAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Syroot.BinaryData 4 | { 5 | /// 6 | /// Represents a class or struct configuration for reading and writing it as binary data. 7 | /// 8 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] 9 | public class BinaryObjectAttribute : Attribute 10 | { 11 | // ---- PROPERTIES --------------------------------------------------------------------------------------------- 12 | 13 | /// 14 | /// Gets or sets a value indicating whether inherited members are read and written first. Defaults to 15 | /// false. 16 | /// 17 | public bool Inherit { get; set; } 18 | 19 | /// 20 | /// Gets or sets a value indicating whether public members are not automatically read and written. Defaults to 21 | /// false. 22 | /// 23 | public bool Explicit { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SwitchThemesOnline/Pages/EditorComponents/StateHolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using SwitchThemes.Common; 6 | 7 | namespace SwitchThemesOnline.Pages 8 | { 9 | public class StateHolder 10 | { 11 | private string _Target = "home"; 12 | public string Target { get => _Target; set { _Target = value; TargetHasChanged?.Invoke(); } } 13 | public byte[] MainBG; 14 | public LayoutPatch MainLayout; 15 | public string Name; 16 | public string Author; 17 | 18 | public delegate void SimpleHandler(); 19 | public event SimpleHandler TargetHasChanged; 20 | } 21 | 22 | public static class Constants 23 | { 24 | public static Dictionary NXPartToName = new Dictionary() { 25 | {"home","Home menu"}, 26 | {"lock","Lockscreen"}, 27 | {"user","User page"}, 28 | {"apps","All apps page"}, 29 | {"set","Settings applet"}, 30 | {"news","News applet"}, 31 | { "psl","Player select applet" }, 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Bntx/DDS.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../MyTypes.h" 7 | #include "../BinaryReadWrite/Buffer.hpp" 8 | 9 | namespace DDSEncoder 10 | { 11 | struct DDSLoadResult 12 | { 13 | s32 width; 14 | s32 height; 15 | std::string Format; 16 | s32 size; 17 | s32 numMips; 18 | std::vector data; 19 | }; 20 | 21 | struct EncoderInfo 22 | { 23 | s32 blkHeight; 24 | s32 blkWidth; 25 | s32 bpp; 26 | s32 formatCode; 27 | }; 28 | 29 | struct DDSEncoderResult 30 | { 31 | std::vector Data; 32 | EncoderInfo format; 33 | s32 blockHeightLog2; 34 | }; 35 | 36 | const std::unordered_map EncoderTable = 37 | { 38 | { "DXT1",{ 4,4,8 ,0x1a01 } }, 39 | { "DXT3",{ 4,4,16,0x1b01 } }, 40 | { "DXT4",{ 4,4,16,0x1c01 } }, 41 | { "DXT5",{ 4,4,16,0x1c01 } }, 42 | }; 43 | 44 | DDSEncoderResult EncodeTex(const DDSLoadResult &img); 45 | DDSLoadResult LoadDDS(const std::vector &inb); 46 | } -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/Core/EncodingExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace Syroot.BinaryData.Core 4 | { 5 | /// 6 | /// Represents a set of extension methods for the class. 7 | /// 8 | internal static class EncodingExtensions 9 | { 10 | /// 11 | /// When overridden in a derived class, decodes all the bytes in the specified byte array into a string. 12 | /// 13 | /// The extended instance. 14 | /// The byte array containing the sequence of bytes to decode. 15 | /// A string that contains the results of decoding the specified sequence of bytes. 16 | /// Required as this shortcut method is not included in .NET Standard 1.1. 17 | internal static string GetString(this Encoding encoding, byte[] bytes) 18 | { 19 | return encoding.GetString(bytes, 0, bytes.Length); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /SwitchThemesCommon/SwitchThemesCommon.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11174f92-402d-4064-b278-f52842a48251 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/workflows/InjectorBuild.yml: -------------------------------------------------------------------------------- 1 | name: SwitchThemes 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: [ master, githubCI ] 6 | paths: 7 | - SwitchThemesCommon/** 8 | - SwitchThemes/** 9 | pull_request: 10 | branches: [ master ] 11 | paths: 12 | - SwitchThemesCommon/** 13 | - SwitchThemes/** 14 | jobs: 15 | Build: 16 | runs-on: windows-latest 17 | steps: 18 | - name: Setup msbuild 19 | uses: microsoft/setup-msbuild@v1.0.2 20 | - uses: actions/checkout@v2 21 | - name: Restore packages 22 | run: | 23 | cd %GITHUB_WORKSPACE% 24 | mkdir packages 25 | cd packages 26 | nuget install %GITHUB_WORKSPACE%\SwitchThemes\packages.config 27 | shell: cmd 28 | - name: Build project 29 | run: | 30 | cd %GITHUB_WORKSPACE%\SwitchThemes\ 31 | msbuild -p:Configuration=CIRelease 32 | del bin\CIRelease\*.xml 33 | shell: cmd 34 | - uses: actions/upload-artifact@v4 35 | with: 36 | name: InjectorBuild 37 | path: ${{ github.workspace }}/SwitchThemes/bin/CIRelease/ 38 | -------------------------------------------------------------------------------- /Tests/SwitchThemesNXTests/Compression.cpp: -------------------------------------------------------------------------------- 1 | #include "CppUnitTest.h" 2 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/SwitchThemesCommon.hpp" 3 | #include "Util.hpp" 4 | 5 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 6 | 7 | namespace SwitchThemesNXTests 8 | { 9 | TEST_CLASS(Compression) 10 | { 11 | public: 12 | TEST_METHOD(ConsistentCompression) 13 | { 14 | auto c = Yaz0::Compress(MakeData(), 9); 15 | auto h = Util::StringHash(c); 16 | 17 | if (h != "7865BE4B54FBFE3ED21DEA9CB1E184F0F305404251203AD9EFDFA264280CD0FD") 18 | throw std::runtime_error(""); 19 | } 20 | 21 | TEST_METHOD(CompressionDecompression) 22 | { 23 | auto d = MakeData(); 24 | auto c = Yaz0::Compress(d, 9); 25 | auto u = Yaz0::Decompress(c); 26 | 27 | if (u != d) 28 | throw std::runtime_error(""); 29 | } 30 | 31 | private: 32 | std::vector MakeData() 33 | { 34 | Buffer b; 35 | b.Write("Hello word, here's some data", Buffer::BinaryString::NoPrefixOrTermination); 36 | for (int i = 0; i < 100; i++) 37 | b.Write(i); 38 | return b.getBuffer(); 39 | } 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /SwitchThemesOnline/SwitchThemesOnline.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 7.3 6 | 3.0 7 | 2.0.0 8 | 9 | 10 | 11 | TRACE 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/BflytPatcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "../../BinaryReadWrite/Buffer.hpp" 6 | #include "../../MyTypes.h" 7 | #include "../Patches.hpp" 8 | #include "Bflyt.hpp" 9 | 10 | class BflytPatcher 11 | { 12 | public: 13 | BflytPatcher(BflytFile& layout) : lyt(layout) {} 14 | 15 | bool ClearUVData(const std::string& name); 16 | 17 | bool ApplyLayoutPatch(const std::vector& Patches); 18 | 19 | bool ApplyMaterialsPatch(const std::vector& Patches); 20 | 21 | bool AddGroupNames(const std::vector& Groups); 22 | 23 | bool PatchTextureName(const std::string& original, const std::string& _new); 24 | 25 | u16 AddBgMat(const std::string& texName); 26 | 27 | bool AddBgPanel(Panes::PanePtr target, const std::string &TexName, const std::string &Pic1Name); 28 | 29 | bool PatchBgLayout(const PatchTemplate& patch); 30 | 31 | bool PanePullToFront(const std::string& paneName); 32 | 33 | bool PanePushBack(const std::string& paneName); 34 | 35 | private: 36 | BflytFile& lyt; 37 | }; 38 | -------------------------------------------------------------------------------- /SwitchThemesOnline/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | @using SwitchThemes.Common 3 | 4 |
5 |
6 | @if (ShowDebug) 7 | { 8 |
9 | This is a debug build: Stuff will break and generated themes may not install with the public installer, you've been warned. 10 |
11 | } 12 |

Switch theme injector 🌐

13 |

Version @WebVersion - Core @SwitchThemesCommon.CoreVer

14 |

by exelix - Github repo

15 |
16 | 17 |
18 | @Body 19 |
20 | 21 |
22 | 23 | 24 | @code 25 | { 26 | public static readonly string WebVersion = "2.2.1 BETA"; 27 | 28 | #if DEBUG 29 | bool ShowDebug = false; 30 | #else 31 | bool ShowDebug = false; 32 | #endif 33 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/RemoteInstall/List.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "API.hpp" 3 | #include "../../UI/UI.hpp" 4 | #include 5 | #include "../../SwitchThemesCommon/Layouts/Base64.hpp" 6 | #include "Worker.hpp" 7 | 8 | namespace RemoteInstall 9 | { 10 | class ListPage : public IUIControlObj 11 | { 12 | public: 13 | ListPage(API::APIResponse&& response, Worker::ImageFetch::Result&& img); 14 | 15 | void Update() override; 16 | void Render(int X, int Y) override; 17 | ~ListPage(); 18 | private: 19 | enum class Result 20 | { 21 | None, 22 | Clicked, 23 | Preview 24 | }; 25 | 26 | Result RenderWidget(size_t index); 27 | 28 | API::APIResponse response; 29 | Worker::ImageFetch::Result images; 30 | 31 | std::vector Selection; 32 | size_t SelectedCount() const; 33 | void ApplySelection(bool all); 34 | void ToggleSelected(size_t i); 35 | bool IsSelected(size_t i); 36 | std::vector GetSelectedUrls(); 37 | 38 | std::string DownloadBtnText = "Download"; 39 | void SelectionChanged(); 40 | 41 | void DownloadClicked(); 42 | 43 | void PopulateScrollIDs(); 44 | std::vector ScrollIDs; 45 | }; 46 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/RebootPage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 6 | #include "../UI/UI.hpp" 7 | #include "../fs.hpp" 8 | 9 | #include "../Platform/Platform.hpp" 10 | #include "../ViewFunctions.hpp" 11 | 12 | class RebootPage : public IPage 13 | { 14 | public: 15 | RebootPage() 16 | { 17 | Name = "Reboot"; 18 | } 19 | 20 | void Render(int X, int Y) 21 | { 22 | Utils::ImGuiSetupPage(this, X, Y); 23 | ImGui::PushFont(font30); 24 | ImGui::SetCursorPos({ 5, 10 }); 25 | 26 | ImGui::TextUnformatted("Rebooting your console will apply the changes you made."); 27 | ImGui::TextWrapped("This is a shortcut to the system's reboot button. If your CFW doesn't provide reboot to payload you will need a way to inject a payload from RCM."); 28 | if (ImGui::Button("Reboot")) 29 | { 30 | PlatformReboot(); 31 | } 32 | PAGE_RESET_FOCUS; 33 | 34 | ImGui::PopFont(); 35 | Utils::ImGuiCloseWin(); 36 | } 37 | 38 | void Update() override 39 | { 40 | if (Utils::PageLeaveFocusInput()) 41 | Parent->PageLeaveFocus(this); 42 | } 43 | }; -------------------------------------------------------------------------------- /SwitchThemesOnline/Pages/EditorComponents/FileUploader.razor: -------------------------------------------------------------------------------- 1 | @using System.IO; 2 | @inject Blazor.FileReader.IFileReaderService fileReaderService; 3 | @inject IJSRuntime js; 4 | 5 | @code { 6 | [Parameter] public string Text { get; set; } 7 | [Parameter] public string Filter { get; set; } 8 | [Parameter] public Action OnUpload { get; set; } 9 | [Parameter] public int FileCount { get; set; } = 1; 10 | 11 | ElementReference inputTypeFileElement; 12 | 13 | public async Task ReadFile() 14 | { 15 | int c = 0; 16 | foreach (var file in await fileReaderService.CreateReference(inputTypeFileElement).EnumerateFilesAsync()) 17 | { 18 | var info = await file.ReadFileInfoAsync(); 19 | 20 | if (Filter != null) 21 | if (info.Type != Filter) 22 | { 23 | await js.Alert("This file format is not supported"); 24 | continue; 25 | } 26 | 27 | OnUpload(await file.CreateMemoryStreamAsync()); 28 | if (++c >= FileCount) break; 29 | } 30 | } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /Tests/SwitchThemesCommonTests/Util.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | 7 | namespace SwitchThemesCommonTests 8 | { 9 | static class Util 10 | { 11 | public static string GetPath(string relativePath) => 12 | $"../../../../Cases/{relativePath}"; 13 | 14 | public static byte[] ReadData(string relativePath) => 15 | File.ReadAllBytes(GetPath(relativePath)); 16 | 17 | public static string ReadString(string relativePath) => 18 | File.ReadAllText(GetPath(relativePath)); 19 | 20 | public static bool Exists(string relativePath) => 21 | File.Exists(GetPath(relativePath)); 22 | } 23 | 24 | class HashUtil : IDisposable 25 | { 26 | SHA256 sha = SHA256.Create(); 27 | 28 | public void Dispose() 29 | { 30 | sha.Dispose(); 31 | } 32 | 33 | public byte[] Hash(byte[] data) => 34 | sha.ComputeHash(data); 35 | 36 | public string StringHash(byte[] data) 37 | { 38 | var hash = sha.ComputeHash(data); 39 | StringBuilder sb = new StringBuilder(); 40 | 41 | foreach (var b in hash) 42 | sb.Append(b.ToString("X2")); 43 | 44 | return sb.ToString(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Tests/SwitchThemesNXTests/Layouts.cpp: -------------------------------------------------------------------------------- 1 | #include "CppUnitTest.h" 2 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/SwitchThemesCommon.hpp" 3 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/Layouts/Patches.hpp" 4 | #include "Util.hpp" 5 | 6 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 7 | 8 | namespace SwitchThemesNXTests 9 | { 10 | TEST_CLASS(Layouts) 11 | { 12 | public: 13 | TEST_METHOD(LayoutLoading) 14 | { 15 | // The theme injector will remove useless fields from jsons to save space, this test ensures the jsons keep the same meaning for the C++ parser 16 | // The ParsedLayouts folder is populated by SwitchThemesCommonTests.Layouts.LoadAndOptimizeAll 17 | for (const auto& f : std::filesystem::directory_iterator("../SwitchThemes/layouts/")) 18 | { 19 | if (f.is_regular_file() && f.path().extension() == ".json") 20 | { 21 | auto a = Patches::LoadLayout(Util::ReadAllText(f.path().string())); 22 | auto b = Patches::LoadLayout(Util::ReadTestString("ParsedLayouts/" + f.path().filename().string())); 23 | 24 | if (a != b) 25 | throw std::runtime_error("Files don't match: " + f.path().filename().string()); 26 | } 27 | } 28 | } 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Platform/Windows/dirent.h: -------------------------------------------------------------------------------- 1 | #ifndef DIRENT_INCLUDED 2 | #define DIRENT_INCLUDED 3 | 4 | /* 5 | 6 | Declaration of POSIX directory browsing functions and types for Win32. 7 | 8 | Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) 9 | History: Created March 1997. Updated June 2003. 10 | Rights: See end of file. 11 | 12 | */ 13 | 14 | #ifdef __cplusplus 15 | extern "C" 16 | { 17 | #endif 18 | 19 | typedef struct DIR DIR; 20 | 21 | struct dirent 22 | { 23 | char *d_name; 24 | }; 25 | 26 | DIR *opendir(const char *); 27 | int closedir(DIR *); 28 | struct dirent *readdir(DIR *); 29 | void rewinddir(DIR *); 30 | 31 | /* 32 | 33 | Copyright Kevlin Henney, 1997, 2003. All rights reserved. 34 | 35 | Permission to use, copy, modify, and distribute this software and its 36 | documentation for any purpose is hereby granted without fee, provided 37 | that this copyright and permissions notice appear in all copies and 38 | derivatives. 39 | 40 | This software is supplied "as is" without express or implied warranty. 41 | 42 | But that said, if there are any problems please get in touch. 43 | 44 | */ 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/Txt1Pane.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "BasePane.hpp" 3 | #include "Pan1Pane.hpp" 4 | #include "RGBAColor.hpp" 5 | 6 | namespace Panes 7 | { 8 | // TODO: Implement all properties 9 | class Txt1Pane : public Pan1Pane 10 | { 11 | public: 12 | RGBAColor FontTopColor; 13 | RGBAColor ShadowTopColor; 14 | RGBAColor FontBottomColor; 15 | RGBAColor ShadowBottomColor; 16 | 17 | Txt1Pane(Buffer& reader, Endianness e) : Pan1Pane(reader, e, "txt1") 18 | { 19 | LoadProperties(e); 20 | } 21 | 22 | void ApplyChanges(Buffer& bin) override 23 | { 24 | Pan1Pane::ApplyChanges(bin); 25 | bin.Position = 0x54 - 8 + 20; 26 | FontTopColor.Write(bin); 27 | FontBottomColor.Write(bin); 28 | bin.Position = 0x54 - 8 + 64; 29 | ShadowTopColor.Write(bin); 30 | ShadowBottomColor.Write(bin); 31 | } 32 | 33 | private: 34 | void LoadProperties(Endianness e) 35 | { 36 | Buffer buf(data); 37 | buf.ByteOrder = e; 38 | buf.Position = 0x54 - 8 + 20; 39 | FontTopColor = RGBAColor::Read(buf); 40 | FontBottomColor = RGBAColor::Read(buf); 41 | buf.Position = 0x54 - 8 + 64; 42 | ShadowTopColor = RGBAColor::Read(buf); 43 | ShadowBottomColor = RGBAColor::Read(buf); 44 | } 45 | }; 46 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/Base64.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "../MyTypes.h" 5 | //FROM 6 | //https://gist.github.com/williamdes/308b95ac9ef1ee89ae0143529c361d37 7 | 8 | namespace Base64 { 9 | static const std::string b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//= 10 | inline std::string Encode(const std::vector& in) { 11 | std::string out; 12 | 13 | int val = 0, valb = -6; 14 | for (u8 c : in) { 15 | val = (val << 8) + c; 16 | valb += 8; 17 | while (valb >= 0) { 18 | out.push_back(b[(val >> valb) & 0x3F]); 19 | valb -= 6; 20 | } 21 | } 22 | if (valb > -6) out.push_back(b[((val << 8) >> (valb + 8)) & 0x3F]); 23 | while (out.size() % 4) out.push_back('='); 24 | return out; 25 | } 26 | 27 | inline std::vector Decode(const std::string & in) { 28 | 29 | std::vector out; 30 | 31 | std::vector T(256, -1); 32 | for (int i = 0; i < 64; i++) T[b[i]] = i; 33 | 34 | int val = 0, valb = -8; 35 | for (u8 c : in) { 36 | if (T[c] == -1) break; 37 | val = (val << 6) + T[c]; 38 | valb += 6; 39 | if (valb >= 0) { 40 | out.push_back(u8((val >> valb) & 0xFF)); 41 | valb -= 8; 42 | } 43 | } 44 | return out; 45 | } 46 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/RGBAColor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../../MyTypes.h" 7 | #include 8 | #include "../../BinaryReadWrite/Buffer.hpp" 9 | 10 | class RGBAColor 11 | { 12 | public: 13 | u8 R = 0, G = 0, B = 0, A = 0; 14 | 15 | RGBAColor() {}; 16 | RGBAColor(u8 r, u8 g, u8 b, u8 a = 255) : R(r), G(g), B(b), A(a) {} 17 | RGBAColor(const std::string& LeByteString) 18 | { 19 | u32 Col = std::stoull(LeByteString, nullptr, 16); 20 | R = (Col & 0xFF); 21 | G = ((Col >> 8) & 0xFF); 22 | B = ((Col >> 16) & 0xFF); 23 | A = ((Col >> 24) & 0xFF); 24 | } 25 | 26 | //colors are encoded as 0xAABBGGRR 27 | std::string AsString() 28 | { 29 | std::stringstream str; 30 | str << std::hex << std::setw(8) << ((u32)(R | G << 8 | B << 16 | A << 24)); 31 | return str.str(); 32 | } 33 | 34 | static RGBAColor Read(Buffer& buf) 35 | { 36 | RGBAColor col; 37 | col.R = buf.readUInt8(); 38 | col.G = buf.readUInt8(); 39 | col.B = buf.readUInt8(); 40 | col.A = buf.readUInt8(); 41 | return col; 42 | } 43 | 44 | void Write(Buffer& buf) 45 | { 46 | buf.Write(R); 47 | buf.Write(G); 48 | buf.Write(B); 49 | buf.Write(A); 50 | } 51 | }; -------------------------------------------------------------------------------- /.github/workflows/InstallerBuild.yml: -------------------------------------------------------------------------------- 1 | name: NXThemesInstaller 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: [ master, githubCI ] 6 | paths: 7 | - SwitchThemesNX/** 8 | # This file is included in the c++ codebase to load the json fixes 9 | - SwitchThemesCommon/NewFirmFixesJsons.cs 10 | pull_request: 11 | branches: [ master ] 12 | paths: 13 | - SwitchThemesNX/** 14 | - SwitchThemesCommon/NewFirmFixesJsons.cs 15 | jobs: 16 | Build: 17 | runs-on: ubuntu-latest 18 | container: devkitpro/devkita64:latest 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Launch build script 22 | run: | 23 | sudo apt-get update 24 | sudo apt-get install -y p7zip-full 25 | cd $GITHUB_WORKSPACE/SwitchThemesNX/ 26 | chmod +x scripts/cibuild.sh 27 | scripts/cibuild.sh -j4 28 | - name: Package artifacts 29 | run: | 30 | cd $GITHUB_WORKSPACE/SwitchThemesNX/ 31 | 7z a -y -mx=7 SwitchThemesNX.elf.7z SwitchThemesNX.elf 32 | mkdir artifacts 33 | mv SwitchThemesNX.nro SwitchThemesNX.elf.7z artifacts/ 34 | - uses: actions/upload-artifact@v4 35 | with: 36 | name: InstallerBuild 37 | path: ${{ github.workspace }}/SwitchThemesNX/artifacts/ 38 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/mbedtls/include/mbedtls/net.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file net.h 3 | * 4 | * \brief Deprecated header file that includes mbedtls/net_sockets.h 5 | * 6 | * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | * 23 | * \deprecated Superseded by mbedtls/net_sockets.h 24 | */ 25 | 26 | #if !defined(MBEDTLS_DEPRECATED_REMOVED) 27 | #include "mbedtls/net_sockets.h" 28 | #if defined(MBEDTLS_DEPRECATED_WARNING) 29 | #warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" 30 | #endif /* MBEDTLS_DEPRECATED_WARNING */ 31 | #endif /* !MBEDTLS_DEPRECATED_REMOVED */ 32 | -------------------------------------------------------------------------------- /SwitchThemesCommon/Bntx/BntxxFormats.cs: -------------------------------------------------------------------------------- 1 | namespace SwitchThemes.Common.Bntxx 2 | { 3 | public enum TextureFormatType 4 | { 5 | R5G6B5 = 0x07, 6 | R8G8 = 0x09, 7 | R16 = 0x0a, 8 | R8G8B8A8 = 0x0b, 9 | R11G11B10 = 0x0f, 10 | R32 = 0x14, 11 | BC1 = 0x1a, 12 | BC2 = 0x1b, 13 | BC3 = 0x1c, 14 | BC4 = 0x1d, 15 | BC5 = 0x1e, 16 | ASTC4x4 = 0x2d, 17 | ASTC5x4 = 0x2e, 18 | ASTC5x5 = 0x2f, 19 | ASTC6x5 = 0x30, 20 | ASTC6x6 = 0x31, 21 | ASTC8x5 = 0x32, 22 | ASTC8x6 = 0x33, 23 | ASTC8x8 = 0x34, 24 | ASTC10x5 = 0x35, 25 | ASTC10x6 = 0x36, 26 | ASTC10x8 = 0x37, 27 | ASTC10x10 = 0x38, 28 | ASTC12x10 = 0x39, 29 | ASTC12x12 = 0x3a 30 | } 31 | 32 | public enum TextureFormatVar 33 | { 34 | UNorm = 1, 35 | SNorm = 2, 36 | UInt = 3, 37 | SInt = 4, 38 | Single = 5, 39 | SRGB = 6, 40 | UHalf = 10 41 | } 42 | 43 | public enum TextureType 44 | { 45 | Image1D = 0, 46 | Image2D = 1, 47 | Image3D = 2, 48 | Cube = 3, 49 | CubeFar = 8 50 | } 51 | 52 | public enum ChannelType 53 | { 54 | Zero, 55 | One, 56 | Red, 57 | Green, 58 | Blue, 59 | Alpha 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Tests/SwitchThemesCommonTests/SyntheticTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SwitchThemes.Common; 3 | using SwitchThemes.Common.Bflyt; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | 11 | namespace SwitchThemesCommonTests 12 | { 13 | // These tests use data manually generated to test patching 14 | 15 | [TestClass] 16 | public class SyntheticTests 17 | { 18 | HashUtil hash = new HashUtil(); 19 | 20 | [TestMethod] 21 | public void BflanDeserialize() 22 | { 23 | var bflan = SwitchThemes.Common.Serializers.BflanSerializer.FromJson(Util.ReadString("Synthetic/bflan.json")); 24 | Assert.AreEqual(hash.StringHash(bflan.WriteFile()), "43CE2CDE8B2638E36CA1723328CD571DB350D3BC011B6389944FAD69260BC748"); 25 | } 26 | 27 | [TestMethod] 28 | public void BgPaneInjection() 29 | { 30 | var bflyt = new BflytFile(Util.ReadData("Synthetic/bginjection.bflyt")); 31 | var t = DefaultTemplates.Templates.Where(x => x.szsName == "ResidentMenu.szs" && x.targetPanels.Contains("P_Bg_00")).First(); 32 | 33 | Assert.IsTrue(bflyt.PatchBgLayout(t)); 34 | 35 | Assert.AreEqual(hash.StringHash(bflyt.SaveFile()), "C4F98DF5F9227E122076DA31BEA351523E2780C2287EC7F604FBC86D59703C21"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/NXTheme.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "NXTheme.hpp" 4 | #include "BinaryReadWrite/Buffer.hpp" 5 | #include "Layouts/json.hpp" 6 | #include "SwitchThemesCommon.hpp" 7 | 8 | SystemVersion HOSVer = { 0,0,0 }; 9 | 10 | std::unordered_map ThemeTargetToName = ThemeTargetToName6X; 11 | std::unordered_map ThemeTargetToFileName = ThemeTargetToFileName6X; 12 | 13 | using namespace std; 14 | using json = nlohmann::json; 15 | 16 | ThemeFileManifest ParseNXThemeFile(SARC::SarcData &Archive) 17 | { 18 | if (!Archive.files.count("info.json")) 19 | { 20 | return {-1,"","",""}; 21 | } 22 | string jsn(reinterpret_cast((Archive.files["info.json"]).data()),(Archive.files["info.json"]).size()); 23 | auto j = json::parse(jsn); 24 | 25 | ThemeFileManifest res = {0}; 26 | if (j.count("Version") && j.count("Target")) 27 | { 28 | res.Version = j["Version"].get(); 29 | res.Target = j["Target"].get(); 30 | } 31 | else 32 | { 33 | res.Version = -1; 34 | return res; 35 | } 36 | if (j.count("Author")) 37 | res.Author = j["Author"].get(); 38 | if (j.count("ThemeName")) 39 | res.ThemeName = j["ThemeName"].get(); 40 | if (j.count("LayoutInfo")) 41 | res.LayoutInfo = j["LayoutInfo"].get(); 42 | 43 | return res; 44 | } -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect 90% Scale.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "Transparent Playerselect 90% Scale", 3 | "AuthorName": "Migush", 4 | "TargetName": "Psl.szs", 5 | "ID": "builtin_TransparentPSL90S", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/DBtmHeaderNml.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "T_00", 12 | "Visible": false 13 | }, 14 | { 15 | "PaneName": "P_Line", 16 | "Visible": false 17 | } 18 | ] 19 | }, 20 | { 21 | "FileName": "blyt/PslSelectSinglePlayer.bflyt", 22 | "Patches": [ 23 | { 24 | "PaneName": "N_Cnt", 25 | "Position": { 26 | "X": 0.0, 27 | "Y": -200.0, 28 | "Z": 0.0 29 | } 30 | }, 31 | { 32 | "PaneName": "P_Bg", 33 | "Visible": false, 34 | "Scale": { 35 | "X": 1.1111111, 36 | "Y": 1.1111111 37 | } 38 | }, 39 | { 40 | "PaneName": "exelixPSL", 41 | "Scale": { 42 | "X": 1.1111111, 43 | "Y": 1.1111111 44 | } 45 | }, 46 | { 47 | "PaneName": "RootPane", 48 | "Scale": { 49 | "X": 0.9, 50 | "Y": 0.9 51 | } 52 | } 53 | ] 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect 90% Scale top.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "Transparent Playerselect 90% Scale top", 3 | "AuthorName": "Migush", 4 | "TargetName": "Psl.szs", 5 | "ID": "builtin_TransparentPSL90ST", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/DBtmHeaderNml.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "T_00", 12 | "Visible": false 13 | }, 14 | { 15 | "PaneName": "P_Line", 16 | "Visible": false 17 | } 18 | ] 19 | }, 20 | { 21 | "FileName": "blyt/PslSelectSinglePlayer.bflyt", 22 | "Patches": [ 23 | { 24 | "PaneName": "N_Cnt", 25 | "Position": { 26 | "X": 0.0, 27 | "Y": 230.0, 28 | "Z": 0.0 29 | } 30 | }, 31 | { 32 | "PaneName": "P_Bg", 33 | "Visible": false, 34 | "Scale": { 35 | "X": 1.1111111, 36 | "Y": 1.1111111 37 | } 38 | }, 39 | { 40 | "PaneName": "exelixPSL", 41 | "Scale": { 42 | "X": 1.1111111, 43 | "Y": 1.1111111 44 | } 45 | }, 46 | { 47 | "PaneName": "RootPane", 48 | "Scale": { 49 | "X": 0.9, 50 | "Y": 0.9 51 | } 52 | } 53 | ] 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /SwitchThemes/layouts/Transparant Playerselect 90% Scale centered.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "Transparent Playerselect 90% Scale centered", 3 | "AuthorName": "Migush", 4 | "TargetName": "Psl.szs", 5 | "ID": "builtin_TransparentPSL90SC", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/DBtmHeaderNml.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "T_00", 12 | "Visible": false 13 | }, 14 | { 15 | "PaneName": "P_Line", 16 | "Visible": false 17 | } 18 | ] 19 | }, 20 | { 21 | "FileName": "blyt/PslSelectSinglePlayer.bflyt", 22 | "Patches": [ 23 | { 24 | "PaneName": "N_Cnt", 25 | "Position": { 26 | "X": 0.0, 27 | "Y": 0.0, 28 | "Z": 0.0 29 | } 30 | }, 31 | { 32 | "PaneName": "P_Bg", 33 | "Visible": false, 34 | "Scale": { 35 | "X": 1.1111111, 36 | "Y": 1.1111111 37 | } 38 | }, 39 | { 40 | "PaneName": "exelixPSL", 41 | "Scale": { 42 | "X": 1.1111111, 43 | "Y": 1.1111111 44 | } 45 | }, 46 | { 47 | "PaneName": "RootPane", 48 | "Scale": { 49 | "X": 0.9, 50 | "Y": 0.9 51 | } 52 | } 53 | ] 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/filepath.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_FILEPATH_H 2 | #define HACTOOL_FILEPATH_H 3 | 4 | #include "types.h" 5 | #include "utils.h" 6 | 7 | typedef uint16_t utf16char_t; 8 | 9 | #ifdef _WIN32 10 | typedef wchar_t oschar_t; /* utf-16 */ 11 | 12 | #define os_fopen _wfopen 13 | #define OS_MODE_READ L"rb" 14 | #define OS_MODE_WRITE L"wb" 15 | #define OS_MODE_EDIT L"rb+" 16 | #define OS_PATH_SEPARATOR "\\" 17 | #else 18 | typedef char oschar_t; /* utf-8 */ 19 | 20 | #define os_fopen fopen 21 | #define OS_MODE_READ "rb" 22 | #define OS_MODE_WRITE "wb" 23 | #define OS_MODE_EDIT "rb+" 24 | #define OS_PATH_SEPARATOR "/" 25 | #endif 26 | 27 | typedef struct filepath { 28 | char char_path[MAX_PATH]; 29 | oschar_t os_path[MAX_PATH]; 30 | validity_t valid; 31 | } filepath_t; 32 | 33 | void os_strcpy(oschar_t *dst, const char *src); 34 | int os_makedir(const oschar_t *dir); 35 | int os_rmdir(const oschar_t *dir); 36 | 37 | void filepath_init(filepath_t *fpath); 38 | void filepath_copy(filepath_t *fpath, filepath_t *copy); 39 | void filepath_append(filepath_t *fpath, const char *format, ...); 40 | void filepath_append_n(filepath_t *fpath, uint32_t n, const char *format, ...); 41 | void filepath_set(filepath_t *fpath, const char *path); 42 | void filepath_set_format(filepath_t *fpath, const char *format, ...); 43 | oschar_t *filepath_get(filepath_t *fpath); 44 | 45 | 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/aes.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_AES_H 2 | #define HACTOOL_AES_H 3 | 4 | #include 5 | #include 6 | 7 | /* Enumerations. */ 8 | typedef enum { 9 | AES_MODE_ECB = MBEDTLS_CIPHER_AES_128_ECB, 10 | AES_MODE_CTR = MBEDTLS_CIPHER_AES_128_CTR, 11 | AES_MODE_XTS = MBEDTLS_CIPHER_AES_128_XTS, 12 | AES_MODE_CBC = MBEDTLS_CIPHER_AES_128_CBC 13 | } aes_mode_t; 14 | 15 | typedef enum { 16 | AES_DECRYPT = MBEDTLS_DECRYPT, 17 | AES_ENCRYPT = MBEDTLS_ENCRYPT, 18 | } aes_operation_t; 19 | 20 | /* Define structs. */ 21 | typedef struct { 22 | mbedtls_cipher_context_t cipher_enc; 23 | mbedtls_cipher_context_t cipher_dec; 24 | } aes_ctx_t; 25 | 26 | /* Function prototypes. */ 27 | aes_ctx_t *new_aes_ctx(const void *key, unsigned int key_size, aes_mode_t mode); 28 | void free_aes_ctx(aes_ctx_t *ctx); 29 | 30 | void aes_setiv(aes_ctx_t *ctx, const void *iv, size_t l); 31 | 32 | void aes_encrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l); 33 | void aes_decrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l); 34 | 35 | void aes_calculate_cmac(void *dst, void *src, size_t size, const void *key); 36 | 37 | void aes_xts_encrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l, size_t sector, size_t sector_size); 38 | void aes_xts_decrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l, size_t sector, size_t sector_size); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/RemoteInstallPage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../UI/UI.hpp" 8 | #include "../fs.hpp" 9 | #include "ThemeEntry/ThemeEntry.hpp" 10 | #include "RemoteInstall/RemoteInstall.hpp" 11 | #include "../SwitchTools/InjectorInstall.hpp" 12 | 13 | class RemoteInstallPage : public IPage 14 | { 15 | public: 16 | RemoteInstallPage(); 17 | ~RemoteInstallPage(); 18 | 19 | void Render(int X, int Y) override; 20 | void Update() override; 21 | private: 22 | void DialogError(const std::string &msg); 23 | 24 | // Download install 25 | int ProviderIndex = 0; 26 | bool SelectedProviderStatic = false; 27 | const RemoteInstall::Provider& SelectedProvider(); 28 | std::string RemoteInstallCode; 29 | std::string RemoteInstallBtnText; 30 | void SetRemoteInstallCode(const char* input); 31 | void StartRemoteInstallByCode(); 32 | void StartRemoteInstallFixed(RemoteInstall::FixedTypes type); 33 | 34 | // Injector install 35 | InjectorInstall::Server server; 36 | void StartServer(); 37 | void StopServer(); 38 | void UpdateServer(); 39 | std::unique_ptr RemoteInstallFile = 0; 40 | std::string BtnStart; 41 | bool AutoInstall = false; 42 | 43 | // Layout stuff 44 | void CurItemBlockLeft(); 45 | bool AllowLeft = true; 46 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/source/Platform/Platform.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PlatformFs.hpp" 3 | 4 | #define GLFW_INCLUDE_NONE 5 | #include 6 | 7 | extern GLFWgamepadstate gamepad; 8 | extern GLFWgamepadstate OldGamepad; 9 | 10 | //imgui navbuttons are cleared after end of the frame 11 | //these are needed for getting the pressed directions either from dpad or sticks in Update or out of the drawing loop 12 | extern bool NAV_UP; 13 | extern bool NAV_DOWN; 14 | extern bool NAV_LEFT; 15 | extern bool NAV_RIGHT; 16 | 17 | //Used when running in applet mode on switch 18 | extern bool UseLowMemory; 19 | 20 | static inline bool KeyPressed(int glfwKey) 21 | { 22 | return gamepad.buttons[glfwKey] && !OldGamepad.buttons[glfwKey]; 23 | } 24 | 25 | static inline float StickAsButton(int index) 26 | { 27 | #define ABS(x) (x < 0 ? -x : x) 28 | #define STICK_BTN(x) (ABS(x) > .3f) 29 | if (STICK_BTN(gamepad.axes[index]) && !STICK_BTN(OldGamepad.axes[index])) 30 | return gamepad.axes[index]; 31 | else return 0; 32 | #undef STICK_BTN 33 | #undef ABS 34 | } 35 | 36 | void PlatformInit(); 37 | void PlatformExit(); 38 | 39 | void PlatformReboot(); 40 | 41 | void PlatformAfterInit(); 42 | void PlatformGetInputs(); 43 | void PlatformImguiBinds(); 44 | void PlatformSleep(float time); 45 | 46 | const char* PlatformTextInput(const char* current = nullptr); 47 | 48 | #ifndef __SWITCH__ 49 | static constexpr bool envHasArgv() { return true; } 50 | #endif -------------------------------------------------------------------------------- /SwitchThemesNX/source/UI/DialogPages.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/MyTypes.h" 7 | #include "UI.hpp" 8 | #include "../fs.hpp" 9 | #include 10 | 11 | class LoadingOverlay : public IUIControlObj 12 | { 13 | public: 14 | LoadingOverlay(std::initializer_list lines) : _lines(lines) 15 | { 16 | 17 | } 18 | 19 | LoadingOverlay(const std::string& line) 20 | { 21 | _lines.push_back(line); 22 | } 23 | 24 | ~LoadingOverlay() override {}; 25 | 26 | void Render(int X, int Y) override; 27 | void Update() override {} 28 | private: 29 | std::vector _lines; 30 | }; 31 | 32 | class DialogPage : public IUIControlObj 33 | { 34 | public: 35 | DialogPage(const std::string &msg); 36 | DialogPage(const std::string &msg, const std::string &buttonMsg); 37 | ~DialogPage() override {}; 38 | 39 | void Render(int X, int Y) override; 40 | void Update() override; 41 | private: 42 | std::string text; 43 | std::string btn; 44 | }; 45 | 46 | class YesNoPage : public IUIControlObj 47 | { 48 | public: 49 | static bool Ask(const std::string &msg); 50 | 51 | YesNoPage(const std::string &msg, bool *outRes); 52 | ~YesNoPage() override {}; 53 | 54 | void Render(int X, int Y) override; 55 | void Update() override; 56 | 57 | private: 58 | bool *result; 59 | std::string text; 60 | }; -------------------------------------------------------------------------------- /Tests/SwitchThemesCommonTests/Compression.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using NUnit.Framework.Internal; 3 | using SwitchThemes.Common; 4 | using SwitchThemes.Common.Bflyt; 5 | using System; 6 | using System.Collections; 7 | using System.Diagnostics; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Security.Cryptography; 11 | using System.Text; 12 | 13 | namespace SwitchThemesCommonTests 14 | { 15 | [TestClass] 16 | public class Compression 17 | { 18 | HashUtil hash = new HashUtil(); 19 | 20 | private static byte[] MakeData() 21 | { 22 | MemoryStream mem = new MemoryStream(); 23 | BinaryWriter bin = new BinaryWriter(mem); 24 | 25 | foreach (char c in "Hello word, here's some data") 26 | bin.Write(c); 27 | 28 | foreach (int a in Enumerable.Range(0, 100)) 29 | bin.Write(a); 30 | 31 | return mem.ToArray(); 32 | } 33 | 34 | [TestMethod] 35 | // Not an important test, just to detect changes in the behavior 36 | public void ConsistentCompression() 37 | { 38 | Assert.AreEqual(hash.StringHash(ManagedYaz0.Compress(MakeData(), 9)), "7865BE4B54FBFE3ED21DEA9CB1E184F0F305404251203AD9EFDFA264280CD0FD"); 39 | } 40 | 41 | [TestMethod] 42 | public void CompressionDecompression() 43 | { 44 | var data = MakeData(); 45 | var dec = ManagedYaz0.Decompress(ManagedYaz0.Compress(data, 9)); 46 | 47 | if (!data.SequenceEqual(dec)) 48 | throw new Exception(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/Grp1Pane.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "BasePane.hpp" 3 | 4 | namespace Panes 5 | { 6 | class Grp1Pane : public BasePane 7 | { 8 | public: 9 | u32 Version; 10 | std::string GroupName; 11 | std::vector Panes; 12 | 13 | Grp1Pane(Buffer& buf, u32 version) : BasePane("grp1", buf), Version{ version } 14 | { 15 | LoadProperties(); 16 | } 17 | 18 | Grp1Pane(u32 version) : BasePane("grp1", 8), Version{ version } {}; 19 | private: 20 | void LoadProperties() 21 | { 22 | Buffer bin{ data }; 23 | bin.ByteOrder = Endianness::LittleEndian; 24 | if (Version > 0x05020000) 25 | GroupName = bin.readStr_Fixed(34); 26 | else 27 | GroupName = bin.readStr_Fixed(24); 28 | auto NodeCount = bin.readUInt16(); 29 | if (Version <= 0x05020000) 30 | bin.readUInt16(); 31 | auto pos = bin.Position; 32 | for (size_t i = 0; i < NodeCount; i++) 33 | { 34 | bin.Position = pos + i * 24; 35 | Panes.push_back(bin.readStr_Fixed(24)); 36 | } 37 | } 38 | 39 | void ApplyChanges(Buffer &bin) override 40 | { 41 | if (Version > 0x05020000) 42 | bin.WriteFixedLengthString(GroupName, 34); 43 | else 44 | bin.WriteFixedLengthString(GroupName, 24); 45 | bin.Write((u16)Panes.size()); 46 | if (Version <= 0x05020000) 47 | bin.Write((u16)0); 48 | for (const auto& s : Panes) 49 | bin.WriteFixedLengthString(s, 24); 50 | data = bin.getBuffer(); 51 | } 52 | }; 53 | } -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/Meta/BinaryConverterCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Syroot.BinaryData 5 | { 6 | /// 7 | /// Represents a cache for instances. 8 | /// 9 | internal static class BinaryConverterCache 10 | { 11 | // ---- FIELDS ------------------------------------------------------------------------------------------------- 12 | 13 | private static readonly Dictionary _cache = new Dictionary(); 14 | 15 | // ---- METHODS (INTERNAL) ------------------------------------------------------------------------------------- 16 | 17 | /// 18 | /// Gets a possibly cached instance of a of the given . 19 | /// 20 | /// The of the to return. 21 | /// An instance of the . 22 | internal static IBinaryConverter GetConverter(Type type) 23 | { 24 | if (!_cache.TryGetValue(type, out IBinaryConverter converter)) 25 | { 26 | converter = (IBinaryConverter)Activator.CreateInstance(type); 27 | _cache.Add(type, converter); 28 | } 29 | return converter; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/mbedtls/include/mbedtls/gf128mul.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file gf128mul.h 3 | * 4 | * \brief Fast multiplication in GF(128) 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_GF128MUL_H 24 | #define MBEDTLS_GF128MUL_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /** 31 | * \brief Big-Endian definition for 128 bits elements 32 | */ 33 | typedef unsigned char mbedtls_be128[16]; 34 | 35 | /** 36 | * \brief Multiplication in GF(128): 37 | * r = x times x^4 times x^8 in GF(2^128) 38 | * 39 | * \param x the 128-bits number you want to multiply 40 | * \param r result 41 | */ 42 | void mbedtls_gf128mul_x_ble(mbedtls_be128 r, const mbedtls_be128 x); 43 | 44 | 45 | 46 | #endif /* gf128mul.h */ -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/nso.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_NSO_H 2 | #define HACTOOL_NSO_H 3 | #include "types.h" 4 | #include "utils.h" 5 | #include "settings.h" 6 | 7 | #define MAGIC_NSO0 0x304F534E 8 | 9 | typedef struct { 10 | uint32_t file_off; 11 | uint32_t dst_off; 12 | uint32_t decomp_size; 13 | uint32_t align_or_total_size; 14 | } nso0_segment_t; 15 | 16 | typedef struct { 17 | uint32_t magic; 18 | uint32_t _0x4; 19 | uint32_t _0x8; 20 | uint32_t flags; 21 | nso0_segment_t segments[3]; 22 | uint8_t build_id[0x20]; 23 | uint32_t compressed_sizes[3]; 24 | uint8_t _0x6C[0x24]; 25 | uint64_t dynstr_extents; 26 | uint64_t dynsym_extents; 27 | uint8_t section_hashes[3][0x20]; 28 | unsigned char data[]; 29 | } nso0_header_t; 30 | 31 | typedef struct { 32 | FILE *file; 33 | hactool_ctx_t *tool_ctx; 34 | nso0_header_t *header; 35 | nso0_header_t *uncompressed_header; 36 | validity_t segment_validities[3]; 37 | } nso0_ctx_t; 38 | 39 | void nso0_process(nso0_ctx_t *ctx); 40 | void nso0_print(nso0_ctx_t *ctx); 41 | void nso0_save(nso0_ctx_t *ctx); 42 | 43 | static inline uint64_t nso_get_section_size(nso0_header_t *header, unsigned int segment) { 44 | int is_compressed = (header->flags >> segment) & 1; 45 | return is_compressed ? header->compressed_sizes[segment] : header->segments[segment].decomp_size; 46 | } 47 | 48 | static inline uint64_t nso_get_size(nso0_header_t *header) { 49 | return header->segments[2].file_off + nso_get_section_size(header, 2); 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/ByteOrder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Syroot.BinaryData 4 | { 5 | /// 6 | /// Represents the possible endianness of binary data. 7 | /// 8 | public enum ByteOrder : ushort 9 | { 10 | /// 11 | /// The binary data is present in big endian. 12 | /// 13 | BigEndian = 0xFEFF, 14 | 15 | /// 16 | /// The binary data is present in little endian. 17 | /// 18 | LittleEndian = 0xFFFE 19 | } 20 | 21 | /// 22 | /// Represents helper methods to handle data byte order. 23 | /// 24 | public static class ByteOrderHelper 25 | { 26 | // ---- FIELDS ------------------------------------------------------------------------------------------------- 27 | 28 | private static ByteOrder _systemByteOrder; 29 | 30 | // ---- PROPERTIES --------------------------------------------------------------------------------------------- 31 | 32 | /// 33 | /// Gets the of the system executing the assembly. 34 | /// 35 | public static ByteOrder SystemByteOrder 36 | { 37 | get 38 | { 39 | if (_systemByteOrder == 0) 40 | { 41 | _systemByteOrder = BitConverter.IsLittleEndian ? ByteOrder.LittleEndian : ByteOrder.BigEndian; 42 | } 43 | return _systemByteOrder; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/mbedtls/source/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Version information 3 | * 4 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5 | * SPDX-License-Identifier: Apache-2.0 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | * not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * This file is part of mbed TLS (https://tls.mbed.org) 20 | */ 21 | 22 | #if !defined(MBEDTLS_CONFIG_FILE) 23 | #include "mbedtls/config.h" 24 | #else 25 | #include MBEDTLS_CONFIG_FILE 26 | #endif 27 | 28 | #if defined(MBEDTLS_VERSION_C) 29 | 30 | #include "mbedtls/version.h" 31 | #include 32 | 33 | unsigned int mbedtls_version_get_number() 34 | { 35 | return( MBEDTLS_VERSION_NUMBER ); 36 | } 37 | 38 | void mbedtls_version_get_string( char *string ) 39 | { 40 | memcpy( string, MBEDTLS_VERSION_STRING, 41 | sizeof( MBEDTLS_VERSION_STRING ) ); 42 | } 43 | 44 | void mbedtls_version_get_string_full( char *string ) 45 | { 46 | memcpy( string, MBEDTLS_VERSION_STRING_FULL, 47 | sizeof( MBEDTLS_VERSION_STRING_FULL ) ); 48 | } 49 | 50 | #endif /* MBEDTLS_VERSION_C */ 51 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/nca0_romfs.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_NCA0_ROMFS_H 2 | #define HACTOOL_NCA0_ROMFS_H 3 | 4 | #include "types.h" 5 | #include "utils.h" 6 | #include "ivfc.h" 7 | #include "settings.h" 8 | 9 | /* RomFS structs. */ 10 | #define NCA0_ROMFS_HEADER_SIZE 0x00000028 11 | 12 | typedef struct { 13 | uint32_t header_size; 14 | uint32_t dir_hash_table_offset; 15 | uint32_t dir_hash_table_size; 16 | uint32_t dir_meta_table_offset; 17 | uint32_t dir_meta_table_size; 18 | uint32_t file_hash_table_offset; 19 | uint32_t file_hash_table_size; 20 | uint32_t file_meta_table_offset; 21 | uint32_t file_meta_table_size; 22 | uint32_t data_offset; 23 | } nca0_romfs_hdr_t; 24 | 25 | typedef struct { 26 | uint8_t master_hash[0x20]; /* SHA-256 hash of the hash table. */ 27 | uint32_t block_size; /* In bytes. */ 28 | uint32_t always_2; 29 | uint64_t hash_table_offset; /* Normally zero. */ 30 | uint64_t hash_table_size; 31 | uint64_t romfs_offset; 32 | uint64_t romfs_size; 33 | uint8_t _0x48[0xF0]; 34 | } nca0_romfs_superblock_t; 35 | 36 | typedef struct { 37 | nca0_romfs_superblock_t *superblock; 38 | FILE *file; 39 | hactool_ctx_t *tool_ctx; 40 | validity_t superblock_hash_validity; 41 | validity_t hash_table_validity; 42 | uint64_t romfs_offset; 43 | nca0_romfs_hdr_t header; 44 | romfs_direntry_t *directories; 45 | romfs_fentry_t *files; 46 | } nca0_romfs_ctx_t; 47 | 48 | void nca0_romfs_process(nca0_romfs_ctx_t *ctx); 49 | void nca0_romfs_save(nca0_romfs_ctx_t *ctx); 50 | void nca0_romfs_print(nca0_romfs_ctx_t *ctx); 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/ThemeEntry/ThemeEntry.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../SwitchThemesCommon/MyTypes.h" 3 | #include "../../SwitchThemesCommon/SarcLib/Sarc.hpp" 4 | #include "../../UI/UI.hpp" 5 | #include 6 | 7 | class ThemeEntry 8 | { 9 | public: 10 | static void DisplayInstallDialog(const std::string& path); 11 | 12 | enum class UserAction 13 | { 14 | None, 15 | Enter, 16 | Preview 17 | }; 18 | 19 | static std::unique_ptr FromFile(const std::string& fileName); 20 | static std::unique_ptr FromSZS(const std::vector& RawData); 21 | 22 | virtual ~ThemeEntry(); 23 | 24 | static constexpr int EntryW = 860; 25 | 26 | virtual bool IsFolder() = 0; 27 | virtual bool CanInstall() = 0; 28 | bool Install(bool ShowDialogs = true); 29 | virtual bool HasPreview() = 0; 30 | 31 | bool IsHighlighted(); 32 | std::string GetPath() {return FileName;} 33 | 34 | virtual UserAction Render(bool OverrideColor = false); 35 | 36 | std::string InstallLog; 37 | protected: 38 | virtual bool DoInstall(bool ShowDialogs = true) = 0; 39 | virtual LoadedImage GetPreview() = 0; 40 | 41 | void AppendInstallMessage(const std::string& msg) 42 | { 43 | if (InstallLog.empty()) 44 | InstallLog = msg; 45 | else 46 | InstallLog += "\n" + msg; 47 | } 48 | 49 | std::vector file; 50 | 51 | std::string FileName; 52 | std::string lblFname; 53 | std::string lblLine1; 54 | std::string lblLine2; 55 | 56 | std::string CannotInstallReason; 57 | 58 | //Used to return by reference for the background image 59 | const static std::vector _emtptyVec; 60 | }; -------------------------------------------------------------------------------- /SwitchThemes/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SwitchThemes.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.12.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 29 | public bool Adv { 30 | get { 31 | return ((bool)(this["Adv"])); 32 | } 33 | set { 34 | this["Adv"] = value; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Tests/SwitchThemesNXTests/SyntheticTests.cpp: -------------------------------------------------------------------------------- 1 | #include "CppUnitTest.h" 2 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/SwitchThemesCommon.hpp" 3 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflan.hpp" 4 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/Bflyt.hpp" 5 | #include "picosha2.h" 6 | #include "Util.hpp" 7 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/BflytPatcher.hpp" 8 | 9 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 10 | 11 | namespace SwitchThemesNXTests 12 | { 13 | TEST_CLASS(SyntheticTests) 14 | { 15 | public: 16 | TEST_METHOD(BflanDeserialize) 17 | { 18 | auto bflan = BflanDeserializer::FromJson(Util::ReadTestString("Synthetic/bflan.json")); 19 | auto hash = Util::StringHash(bflan->WriteFile()); 20 | 21 | if (hash != "43CE2CDE8B2638E36CA1723328CD571DB350D3BC011B6389944FAD69260BC748") 22 | throw std::runtime_error(""); 23 | } 24 | 25 | TEST_METHOD(BgPaneInjection) 26 | { 27 | auto bflyt = BflytFile(Util::ReadTestData("Synthetic/bginjection.bflyt")); 28 | 29 | BflytPatcher p(bflyt); 30 | 31 | auto t = *std::find_if(Patches::DefaultTemplates.begin(), Patches::DefaultTemplates.end(), 32 | [](const PatchTemplate& t) { 33 | return t.szsName == "ResidentMenu.szs" && t.targetPanels[0] == "P_Bg_00"; 34 | }); 35 | 36 | if (!p.PatchBgLayout(t)) 37 | throw std::runtime_error(""); 38 | 39 | auto d = bflyt.SaveFile(); 40 | 41 | auto hash = Util::StringHash(d); 42 | 43 | if (hash != "C4F98DF5F9227E122076DA31BEA351523E2780C2287EC7F604FBC86D59703C21") 44 | throw std::runtime_error(""); 45 | } 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /SwitchThemes/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Le informazioni generali relative a un assembly sono controllate dal seguente 6 | // set di attributi. Modificare i valori di questi attributi per modificare le informazioni 7 | // associate a un assembly. 8 | [assembly: AssemblyTitle("Switch theme injector")] 9 | [assembly: AssemblyDescription("Switch custom themes !")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Exelix")] 12 | [assembly: AssemblyProduct("SwitchThemes")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili 18 | // ai componenti COM. Se è necessario accedere a un tipo in questo assembly da 19 | // COM, impostare su true l'attributo ComVisible per tale tipo. 20 | [assembly: ComVisible(false)] 21 | 22 | // Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi 23 | [assembly: Guid("cfbf6ef0-8237-442a-8997-a30072f0b9f8")] 24 | 25 | // Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: 26 | // 27 | // Versione principale 28 | // Versione secondaria 29 | // Numero di build 30 | // Revisione 31 | // 32 | // È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build 33 | // usando l'asterisco '*' come illustrato di seguito: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("4.8.3")] 36 | [assembly: AssemblyFileVersion("4.8.3")] 37 | -------------------------------------------------------------------------------- /SwitchThemes/layouts/FlaunchRounded.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "All Apps 90% scale rounded icons", 3 | "AuthorName": "Such Meme, Many Skill", 4 | "TargetName": "Flaunch.szs", 5 | "ID": "builtin_AllApps90Round", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/FlcBtnIconGame.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "N_Delete", 12 | "Scale": { 13 | "X": 0.9, 14 | "Y": 0.9 15 | } 16 | }, 17 | { 18 | "PaneName": "P_BtnBase", 19 | "UsdPatches": [ 20 | { 21 | "PropName": "S_RoundRadius", 22 | "PropValues": [ 23 | "40" 24 | ], 25 | "type": 2 26 | } 27 | ] 28 | }, 29 | { 30 | "PaneName": "P_IconGame", 31 | "UsdPatches": [ 32 | { 33 | "PropName": "S_RoundRadius", 34 | "PropValues": [ 35 | "38" 36 | ], 37 | "type": 2 38 | } 39 | ] 40 | }, 41 | { 42 | "PaneName": "P_InnerCursor", 43 | "UsdPatches": [ 44 | { 45 | "PropName": "S_RoundRadius", 46 | "PropValues": [ 47 | "40" 48 | ], 49 | "type": 2 50 | } 51 | ] 52 | }, 53 | { 54 | "PaneName": "N_BtnFocusKey", 55 | "UsdPatches": [ 56 | { 57 | "PropName": "S_RoundRadius", 58 | "PropValues": [ 59 | "40" 60 | ], 61 | "type": 2 62 | } 63 | ] 64 | } 65 | ] 66 | } 67 | ] 68 | } -------------------------------------------------------------------------------- /SwitchThemesOnline/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @using SwitchThemes.Common; 3 | @inject Mono.WebAssembly.Interop.MonoWebAssemblyJSRuntime js; 4 | 5 |

Welcome to the new WebInjector, this version can only build .nxtheme files. (You can still go to the old version)

6 |
What is .nxtheme ?
7 |

8 | .nxtheme is a custom file format for themes, it's legal to share and works on most firmwares.
9 | To install nxtheme files you need to download NXThemes Installer on your console.
10 | All the cumbersome parts of the process have been automated, now all you need to do is to launch the installer and select a theme ! 11 |

12 | 13 |

Enough ! Let's make a theme:

14 | 15 | 16 | 17 | 18 | 19 |


20 | 21 | 22 | @if (PrintAlert != null) 23 | { 24 |

@PrintAlert

25 | } 26 | 27 | @code 28 | { 29 | StateHolder holder = new StateHolder(); 30 | 31 | string PrintAlert = null; 32 | 33 | async Task BuildNxtheme() 34 | { 35 | try 36 | { 37 | NXThemeBuilder nx = new NXThemeBuilder(holder.Target, holder.Name, holder.Author); 38 | nx.AddMainBg(holder.MainBG); 39 | nx.AddMainLayout(holder.MainLayout); 40 | 41 | js.DownloadFile($"{holder.Name}.nxtheme", nx.GetNxtheme()); 42 | } 43 | catch (Exception ex) 44 | { 45 | await js.Alert("Error: " + ex.Message); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/Meta/IBinaryConverter.cs: -------------------------------------------------------------------------------- 1 | namespace Syroot.BinaryData 2 | { 3 | /// 4 | /// Represents a converter for reading and writing custom binary values. 5 | /// 6 | public interface IBinaryConverter 7 | { 8 | // ---- METHODS ------------------------------------------------------------------------------------------------ 9 | 10 | /// 11 | /// Reads the value from the given and returns it to set the corresponding member. 12 | /// 13 | /// The to read the value from. 14 | /// The instance to which the value belongs. 15 | /// The containing configuration which can be 16 | /// used to modify the behavior of the converter. 17 | /// The read value. 18 | object Read(BinaryDataReader reader, object instance, BinaryMemberAttribute memberAttribute); 19 | 20 | /// 21 | /// Writes the value with the given . 22 | /// 23 | /// The to write the value with. 24 | /// The instance to which the value belongs. 25 | /// The containing configuration which can be 26 | /// used to modify the behavior of the converter. 27 | /// The value to write. 28 | void Write(BinaryDataWriter writer, object instance, BinaryMemberAttribute memberAttribute, object value); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/ThemeEntry/FontEntry.hpp: -------------------------------------------------------------------------------- 1 | #include "ThemeEntry.hpp" 2 | #include "../../fs.hpp" 3 | #include "../../SwitchThemesCommon/Fonts/TTF.hpp" 4 | #include "../../ViewFunctions.hpp" 5 | #include "../ThemePage.hpp" 6 | 7 | class FontEntry : public ThemeEntry 8 | { 9 | public: 10 | FontEntry(const std::string& fileName, std::vector&& RawData) 11 | { 12 | FileName = fileName; 13 | file = RawData; 14 | ParseFont(); 15 | } 16 | 17 | bool IsFolder() override { return false; } 18 | bool CanInstall() override { return _CanInstall; } 19 | bool HasPreview() override { return false; } 20 | protected: 21 | bool DoInstall(bool ShowDialogs = true) override 22 | { 23 | if (ShowDialogs) 24 | ThemeEntry::DisplayInstallDialog(FileName); 25 | 26 | fs::theme::CreateMitmStructure("0100000000000811"); 27 | fs::theme::CreateRomfsDir("0100000000000811"); 28 | fs::WriteFile(fs::path::RomfsFolder("0100000000000811") + "nintendo_udsg-r_std_003.bfttf", SwitchThemesCommon::TTF::ConvertToBFTTF(file)); 29 | fs::theme::CreateMitmStructure("0100000000000039"); 30 | fs::theme::CreateRomfsDir("0100000000000039"); 31 | fs::WriteFile(fs::path::RomfsFolder("0100000000000039") + "dummy.bin", { 0x70,0x61,0x70,0x65,0x20,0x53,0x61,0x74,0x61,0x6E,0x20,0x41,0x6C,0x65,0x70,0x70,0x65,0x21 }); 32 | return true; 33 | } 34 | private: 35 | bool _CanInstall = true; 36 | 37 | LoadedImage GetPreview() override 38 | { 39 | throw std::runtime_error("Preview is not implemented for fonts"); 40 | } 41 | 42 | void ParseFont() 43 | { 44 | lblLine2 = ("Custom font"); 45 | auto fontName = SwitchThemesCommon::TTF::GetFontName(file); 46 | _CanInstall = fontName != ""; 47 | CannotInstallReason = "Invalid font file"; 48 | lblFname = (CanInstall() ? fontName : "Invalid font :("); 49 | lblLine1 = (fs::GetFileName(FileName)); 50 | } 51 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/hfs0.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_hfs0_H 2 | #define HACTOOL_hfs0_H 3 | 4 | #include "types.h" 5 | #include "utils.h" 6 | #include "settings.h" 7 | 8 | #define MAGIC_HFS0 0x30534648 9 | 10 | typedef struct { 11 | uint32_t magic; 12 | uint32_t num_files; 13 | uint32_t string_table_size; 14 | uint32_t reserved; 15 | } hfs0_header_t; 16 | 17 | typedef struct { 18 | uint64_t offset; 19 | uint64_t size; 20 | uint32_t string_table_offset; 21 | uint32_t hashed_size; 22 | uint64_t reserved; 23 | unsigned char hash[0x20]; 24 | } hfs0_file_entry_t; 25 | 26 | typedef struct { 27 | FILE *file; 28 | uint64_t offset; 29 | uint64_t size; 30 | hactool_ctx_t *tool_ctx; 31 | hfs0_header_t *header; 32 | const char *name; 33 | const uint8_t *hash_suffix; 34 | } hfs0_ctx_t; 35 | 36 | static inline hfs0_file_entry_t *hfs0_get_file_entry(hfs0_header_t *hdr, uint32_t i) { 37 | if (i >= hdr->num_files) return NULL; 38 | return (hfs0_file_entry_t *)((char *)(hdr) + sizeof(*hdr) + i * sizeof(hfs0_file_entry_t)); 39 | } 40 | 41 | static inline char *hfs0_get_string_table(hfs0_header_t *hdr) { 42 | return (char *)(hdr) + sizeof(*hdr) + hdr->num_files * sizeof(hfs0_file_entry_t); 43 | } 44 | 45 | static inline uint64_t hfs0_get_header_size(hfs0_header_t *hdr) { 46 | return sizeof(*hdr) + hdr->num_files * sizeof(hfs0_file_entry_t) + hdr->string_table_size; 47 | } 48 | 49 | static inline char *hfs0_get_file_name(hfs0_header_t *hdr, uint32_t i) { 50 | return hfs0_get_string_table(hdr) + hfs0_get_file_entry(hdr, i)->string_table_offset; 51 | } 52 | 53 | void hfs0_process(hfs0_ctx_t *ctx); 54 | void hfs0_save(hfs0_ctx_t *ctx); 55 | void hfs0_print(hfs0_ctx_t *ctx); 56 | 57 | void hfs0_save_file(hfs0_ctx_t *ctx, uint32_t i, filepath_t *dirpath); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/CfwSelectPage.cpp: -------------------------------------------------------------------------------- 1 | #include "CfwSelectPage.hpp" 2 | #include "../ViewFunctions.hpp" 3 | #include "../UI/UIManagement.hpp" 4 | 5 | using namespace std; 6 | 7 | CfwSelectPage::CfwSelectPage(const vector& folders) : Folders(folders) {} 8 | 9 | CfwSelectPage::~CfwSelectPage() 10 | { 11 | 12 | } 13 | 14 | static const int BtnWidth = 500; 15 | static const int XCursorBtn = SCR_W / 2 - BtnWidth / 2; 16 | 17 | void CfwSelectPage::Render(int X, int Y) 18 | { 19 | Utils::ImGuiSetupPageFullscreen("CfwSelectPage", 10, 10); 20 | ImGui::SetWindowFocus(); 21 | 22 | if (Folders.size() == 0) 23 | { 24 | ImGui::PushFont(font30); 25 | Utils::ImGuiCenterString("Couldn't find the Atmosphere folder."); 26 | ImGui::PopFont(); 27 | ImGui::NewLine(); 28 | ImGui::TextWrapped( 29 | "Make sure you have the \"atmosphere\" folder in the root of your sd card.\n\n" 30 | "If the folder is there there is probably something wrong with your sd card.\n"); 31 | } 32 | else { 33 | Utils::ImGuiCenterString("Multiple cfw folders detected, which one do you want to use ?"); 34 | 35 | ImGui::PushFont(font30); 36 | ImGui::SetCursorPos({ (float)XCursorBtn, ImGui::GetCursorPosY() + 30 }); 37 | 38 | int count = 0; 39 | for (const auto& e : Folders) 40 | { 41 | ImGui::SetCursorPosX((float)XCursorBtn); 42 | if (ImGui::Button(e.c_str(), { BtnWidth, 50 })) 43 | { 44 | fs::cfw::SetFolder(e); 45 | PopPage(this); 46 | } 47 | count++; 48 | } 49 | 50 | ImGui::PopFont(); 51 | } 52 | 53 | ImGui::NewLine(); 54 | if (Utils::ImGuiCenterButton("Close this application")) 55 | App::Quit(); 56 | 57 | Utils::ImGuiSetWindowScrollable(); 58 | Utils::ImGuiCloseWin(); 59 | } 60 | 61 | void CfwSelectPage::Update() 62 | { 63 | if (gamepad.buttons[GLFW_GAMEPAD_BUTTON_START]) 64 | App::Quit(); 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/ThemePage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../UI/UI.hpp" 8 | #include "../fs.hpp" 9 | #include "ThemeEntry/ThemeEntry.hpp" 10 | 11 | class ThemesPage : public IPage 12 | { 13 | public: 14 | static ThemesPage* Instance; 15 | 16 | ThemesPage(); 17 | ~ThemesPage(); 18 | 19 | void Render(int X, int Y) override; 20 | void Update() override; 21 | 22 | void SelectElementOnRescan(const std::string& path); 23 | private: 24 | void RefreshThemesList(); 25 | void SelectElementByPath(const std::string& path); 26 | 27 | void SetDir(const std::string &dir); 28 | void SetPage(int num, int index = 0); 29 | void SelectCurrent(); 30 | 31 | int PageItemsCount(); 32 | 33 | std::vector ThemeFiles; 34 | bool IsSelected(const std::string &fname); 35 | void ClearSelection(); 36 | void UpdateBottomText(); 37 | 38 | std::string CurrentDir; 39 | std::vector DirectoryFiles; 40 | 41 | std::vector> DisplayEntries; 42 | std::string lblPage; 43 | std::string lblCommands; 44 | int pageNum = -1; 45 | int pageCount = -1; 46 | 47 | //Will reset the scroll and force the selected item on the ui 48 | bool ResetScroll = false; 49 | int menuIndex = 0; 50 | 51 | std::vector SelectedFiles; 52 | 53 | const std::string CommandsTextNormal = "A: Install theme Y: Multiselect L/R: Previous/Next page"; 54 | const std::string CommandsTextSelected = "A: Add/Remove to selection Y: Clear selection `+`: Install selected"; 55 | 56 | int LimitLoad = 25; 57 | 58 | std::unordered_map> CursorMemory; 59 | 60 | std::string SelectOnRescanTarget; 61 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/UninstallPage.cpp: -------------------------------------------------------------------------------- 1 | #include "UninstallPage.hpp" 2 | #include "../ViewFunctions.hpp" 3 | #include "../SwitchTools/PatchMng.hpp" 4 | 5 | using namespace std; 6 | 7 | UninstallPage::UninstallPage() 8 | { 9 | Name = "Uninstall theme"; 10 | } 11 | 12 | void UninstallPage::Render(int X, int Y) 13 | { 14 | Utils::ImGuiSetupPage(this, X, Y); 15 | ImGui::PushFont(font30); 16 | 17 | ImGui::TextWrapped("Use this to uninstall the currently installed themes.\nIf you have issues, you can try removing the whole LayeredFS folder and code patches."); 18 | 19 | ImGui::PushStyleColor(ImGuiCol_Button, u32(0x6B70000ff)); 20 | 21 | auto i = Utils::ImGuiCenterButtons({ "Uninstall the current theme", "Uninstall everything" } , &firstBtn); 22 | if (i != -1) 23 | { 24 | PushFunction([i]() { 25 | if (!YesNoPage::Ask("Are you sure ?")) return; 26 | if (i == 1) 27 | { 28 | DisplayLoading("Clearing LayeredFS dir..."); 29 | fs::theme::UninstallTheme(true); 30 | PatchMng::RemoveAll(); 31 | Dialog( 32 | "Done, everything theme-related has been removed, restart your console to apply the changes.\n" 33 | "As this removed the home menu patches as well you should restart this app before installing any theme." 34 | ); 35 | } 36 | else 37 | { 38 | DisplayLoading("Loading..."); 39 | fs::theme::UninstallTheme(false); 40 | Dialog("Done, all the installed themes have been removed, restart your console to apply the changes"); 41 | } 42 | }); 43 | } 44 | 45 | PAGE_RESET_FOCUS_FOR(firstBtn); 46 | ImGui::PopStyleColor(); 47 | 48 | ImGui::PopFont(); 49 | Utils::ImGuiSetWindowScrollable(); 50 | Utils::ImGuiCloseWin(); 51 | } 52 | 53 | void UninstallPage::Update() 54 | { 55 | if (Utils::PageLeaveFocusInput() && ImGui::GetFocusID() == firstBtn){ 56 | Parent->PageLeaveFocus(this); 57 | } 58 | } 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /SwitchThemes/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | False 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/Pic1Pane.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "BasePane.hpp" 3 | #include "Pan1Pane.hpp" 4 | #include "RGBAColor.hpp" 5 | 6 | namespace Panes 7 | { 8 | class Pic1Pane : public Pan1Pane 9 | { 10 | public: 11 | RGBAColor ColorTopRight; 12 | RGBAColor ColorTopLeft; 13 | RGBAColor ColorBottomRight; 14 | RGBAColor ColorBottomLeft; 15 | 16 | u16 MaterialIndex; 17 | 18 | struct UVCoord 19 | { 20 | Vector2 TopLeft; 21 | Vector2 TopRight; 22 | Vector2 BottomLeft; 23 | Vector2 BottomRight; 24 | }; 25 | std::vector UvCoords; 26 | 27 | Pic1Pane(Buffer& reader, Endianness e) : Pan1Pane(reader, e, "pic1") 28 | { 29 | LoadProperties(e); 30 | } 31 | 32 | void ApplyChanges(Buffer& bin) override 33 | { 34 | Pan1Pane::ApplyChanges(bin); 35 | bin.Position = 0x54 - 8; 36 | ColorTopLeft.Write(bin); 37 | ColorTopRight.Write(bin); 38 | ColorBottomLeft.Write(bin); 39 | ColorBottomRight.Write(bin); 40 | bin.Write(MaterialIndex); 41 | bin.Write((u8)UvCoords.size()); 42 | bin.Write((u8)0); 43 | for (const auto& uv : UvCoords) 44 | { 45 | WriteVec2(bin, uv.TopLeft); 46 | WriteVec2(bin, uv.TopRight); 47 | WriteVec2(bin, uv.BottomLeft); 48 | WriteVec2(bin, uv.BottomRight); 49 | } 50 | } 51 | 52 | private: 53 | void LoadProperties(Endianness e) 54 | { 55 | Buffer buf(data); 56 | buf.ByteOrder = e; 57 | buf.Position = 0x54 - 8; 58 | ColorTopLeft = RGBAColor::Read(buf); 59 | ColorTopRight = RGBAColor::Read(buf); 60 | ColorBottomLeft = RGBAColor::Read(buf); 61 | ColorBottomRight = RGBAColor::Read(buf); 62 | MaterialIndex = buf.readUInt16(); //material index 63 | int uvCount = buf.readUInt8(); 64 | buf.readUInt8(); //padding 65 | for (int i = 0; i < uvCount; i++) 66 | UvCoords.push_back( 67 | UVCoord { 68 | ReadVec2(buf), 69 | ReadVec2(buf), 70 | ReadVec2(buf), 71 | ReadVec2(buf) 72 | }); 73 | } 74 | }; 75 | }; -------------------------------------------------------------------------------- /SwitchThemesCommon/Bflyt/Prt1Pane.cs: -------------------------------------------------------------------------------- 1 | using ExtensionMethods; 2 | using Syroot.BinaryData; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Text; 7 | 8 | namespace SwitchThemes.Common.Bflyt 9 | { 10 | public class Prt1Pane : Pan1Pane 11 | { 12 | public class Prt1Section 13 | { 14 | public string Name { get; set; } 15 | public byte Unknown { get; set; } 16 | public byte Flags { get; set; } 17 | public UInt16 Padding { get; set; } 18 | public UInt32 SubpaneOffset { get; set; } 19 | public UInt32 ComplementOffset { get; set; } 20 | public UInt32 ExtraOffset { get; set; } 21 | } 22 | 23 | uint Version; 24 | 25 | public Prt1Pane(byte[] data, ByteOrder b, uint version) : base(data, "prt1", b) 26 | { 27 | Version = version; 28 | ParseData(); 29 | } 30 | 31 | public Prt1Pane(BinaryDataReader bin, uint version) : base(bin, "prt1") 32 | { 33 | Version = version; 34 | ParseData(); 35 | } 36 | 37 | public Vector2 SectionsSacle { get; set; } 38 | public Prt1Section[] Entries { get; set; } 39 | public string PartName { get; set; } 40 | 41 | private void ParseData() 42 | { 43 | BinaryDataReader bin = new BinaryDataReader(new MemoryStream(data)); 44 | bin.ByteOrder = order; 45 | bin.Position = 0x54 - 8; 46 | 47 | UInt32 entriesCount = bin.ReadUInt32(); 48 | SectionsSacle = bin.ReadVector2(); 49 | 50 | Entries = new Prt1Section[entriesCount]; 51 | for (UInt32 i = 0; i < entriesCount; i++) 52 | { 53 | Entries[i] = new Prt1Section(); 54 | Entries[i].Name = bin.ReadFixedLenString(24); 55 | Entries[i].Unknown = bin.ReadByte(); 56 | Entries[i].Flags = bin.ReadByte(); 57 | Entries[i].Padding = bin.ReadUInt16(); 58 | Entries[i].SubpaneOffset = bin.ReadUInt32(); 59 | Entries[i].ComplementOffset = bin.ReadUInt32(); 60 | Entries[i].ExtraOffset = bin.ReadUInt32(); 61 | } 62 | 63 | if (Version >= 0x08000000) 64 | PartName = bin.ReadFixedLenString(24); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/BasePane.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include 4 | #include 5 | #include 6 | #include "../../BinaryReadWrite/Buffer.hpp" 7 | #include "../../MyTypes.h" 8 | #include 9 | 10 | namespace Panes 11 | { 12 | static inline Vector3 ReadVec3(Buffer& buf) 13 | { 14 | Vector3 res; 15 | res.X = buf.readFloat(); 16 | res.Y = buf.readFloat(); 17 | res.Z = buf.readFloat(); 18 | return res; 19 | } 20 | 21 | static inline Vector2 ReadVec2(Buffer& buf) 22 | { 23 | Vector2 res; 24 | res.X = buf.readFloat(); 25 | res.Y = buf.readFloat(); 26 | return res; 27 | } 28 | 29 | static inline void WriteVec3(Buffer& bin, Vector3 _x) 30 | { 31 | bin.Write(_x.X); bin.Write(_x.Y); bin.Write(_x.Z); 32 | } 33 | 34 | static inline void WriteVec2(Buffer& bin, Vector2 _x) 35 | { 36 | bin.Write(_x.X); bin.Write(_x.Y); 37 | } 38 | 39 | class BasePane 40 | { 41 | public: 42 | std::unique_ptr UserData; 43 | std::weak_ptr Parent; 44 | std::vector> Children; 45 | 46 | const std::string name; 47 | std::vector data; 48 | 49 | std::string PaneName = ""; //This is optional 50 | 51 | BasePane(const std::string& _name, u32 len) : name(_name), data(len - 8) 52 | { 53 | } 54 | 55 | //BasePane(const BasePane& ref); 56 | BasePane(const std::string& _name, Buffer& reader) : name(_name) 57 | { 58 | auto length = reader.readUInt32(); 59 | data = reader.readBytes(length - 8); 60 | } 61 | 62 | virtual ~BasePane() {} 63 | virtual void ApplyChanges(Buffer& writer) {} 64 | void WritePane(Buffer& writer) 65 | { 66 | Buffer bin; 67 | bin.ByteOrder = writer.ByteOrder; 68 | ApplyChanges(bin); 69 | if (bin.Length() != 0) 70 | { 71 | data = bin.getBuffer(); 72 | } 73 | 74 | writer.WriteFixedLengthString(name, 4); 75 | writer.Write(u32(data.size() + 8)); 76 | writer.Write(data); 77 | if (UserData) 78 | UserData->WritePane(writer); 79 | } 80 | }; 81 | } -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/Meta/MemberData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Reflection; 4 | 5 | namespace Syroot.BinaryData 6 | { 7 | /// 8 | /// Represents information on a member of a type cached as . 9 | /// 10 | [DebuggerDisplay(nameof(MemberData) + " " + nameof(MemberInfo) + "={" + nameof(MemberInfo) + "}")] 11 | internal class MemberData 12 | { 13 | // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------ 14 | 15 | /// 16 | /// Initializes a new instance of the class for the given 17 | /// with the specified configuration. 18 | /// 19 | /// The to represent. 20 | /// The type of the value stored by the member. 21 | /// The configuration. 22 | internal MemberData(MemberInfo memberInfo, Type type, BinaryMemberAttribute attribute) 23 | { 24 | MemberInfo = memberInfo; 25 | Type = type; 26 | Attribute = attribute; 27 | } 28 | 29 | // ---- PROPERTIES --------------------------------------------------------------------------------------------- 30 | 31 | /// 32 | /// Gets the represented. 33 | /// 34 | internal MemberInfo MemberInfo { get; } 35 | 36 | /// 37 | /// Gets the of the value stored by the member. 38 | /// 39 | internal Type Type { get; } 40 | 41 | /// 42 | /// Gets the configuration. 43 | /// 44 | internal BinaryMemberAttribute Attribute { get; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/pfs0.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_PFS0_H 2 | #define HACTOOL_PFS0_H 3 | 4 | #include "types.h" 5 | #include "utils.h" 6 | #include "npdm.h" 7 | 8 | #define MAGIC_PFS0 0x30534650 9 | 10 | typedef struct { 11 | uint32_t magic; 12 | uint32_t num_files; 13 | uint32_t string_table_size; 14 | uint32_t reserved; 15 | } pfs0_header_t; 16 | 17 | typedef struct { 18 | uint64_t offset; 19 | uint64_t size; 20 | uint32_t string_table_offset; 21 | uint32_t reserved; 22 | } pfs0_file_entry_t; 23 | 24 | typedef struct { 25 | uint8_t master_hash[0x20]; /* SHA-256 hash of the hash table. */ 26 | uint32_t block_size; /* In bytes. */ 27 | uint32_t always_2; 28 | uint64_t hash_table_offset; /* Normally zero. */ 29 | uint64_t hash_table_size; 30 | uint64_t pfs0_offset; 31 | uint64_t pfs0_size; 32 | uint8_t _0x48[0xF0]; 33 | } pfs0_superblock_t; 34 | 35 | typedef struct { 36 | pfs0_superblock_t *superblock; 37 | FILE *file; 38 | hactool_ctx_t *tool_ctx; 39 | validity_t superblock_hash_validity; 40 | validity_t hash_table_validity; 41 | int is_exefs; 42 | npdm_t *npdm; 43 | pfs0_header_t *header; 44 | } pfs0_ctx_t; 45 | 46 | static inline pfs0_file_entry_t *pfs0_get_file_entry(pfs0_header_t *hdr, uint32_t i) { 47 | if (i >= hdr->num_files) return NULL; 48 | return (pfs0_file_entry_t *)((char *)(hdr) + sizeof(*hdr) + i * sizeof(pfs0_file_entry_t)); 49 | } 50 | 51 | static inline char *pfs0_get_string_table(pfs0_header_t *hdr) { 52 | return (char *)(hdr) + sizeof(*hdr) + hdr->num_files * sizeof(pfs0_file_entry_t); 53 | } 54 | 55 | static inline uint64_t pfs0_get_header_size(pfs0_header_t *hdr) { 56 | return sizeof(*hdr) + hdr->num_files * sizeof(pfs0_file_entry_t) + hdr->string_table_size; 57 | } 58 | 59 | static inline char *pfs0_get_file_name(pfs0_header_t *hdr, uint32_t i) { 60 | return pfs0_get_string_table(hdr) + pfs0_get_file_entry(hdr, i)->string_table_offset; 61 | } 62 | 63 | void pfs0_process(pfs0_ctx_t *ctx); 64 | void pfs0_save(pfs0_ctx_t *ctx); 65 | void pfs0_print(pfs0_ctx_t *ctx); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/mbedtls/include/mbedtls/havege.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file havege.h 3 | * 4 | * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion 5 | * 6 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_HAVEGE_H 24 | #define MBEDTLS_HAVEGE_H 25 | 26 | #include 27 | 28 | #define MBEDTLS_HAVEGE_COLLECT_SIZE 1024 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /** 35 | * \brief HAVEGE state structure 36 | */ 37 | typedef struct 38 | { 39 | int PT1, PT2, offset[2]; 40 | int pool[MBEDTLS_HAVEGE_COLLECT_SIZE]; 41 | int WALK[8192]; 42 | } 43 | mbedtls_havege_state; 44 | 45 | /** 46 | * \brief HAVEGE initialization 47 | * 48 | * \param hs HAVEGE state to be initialized 49 | */ 50 | void mbedtls_havege_init( mbedtls_havege_state *hs ); 51 | 52 | /** 53 | * \brief Clear HAVEGE state 54 | * 55 | * \param hs HAVEGE state to be cleared 56 | */ 57 | void mbedtls_havege_free( mbedtls_havege_state *hs ); 58 | 59 | /** 60 | * \brief HAVEGE rand function 61 | * 62 | * \param p_rng A HAVEGE state 63 | * \param output Buffer to fill 64 | * \param len Length of buffer 65 | * 66 | * \return 0 67 | */ 68 | int mbedtls_havege_random( void *p_rng, unsigned char *output, size_t len ); 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif /* havege.h */ 75 | -------------------------------------------------------------------------------- /SwitchThemesOnline/wwwroot/layout/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "home":[ 3 | { 4 | "Prev":"CarefulLayout.jpg", 5 | "File":"CarefulLayout.json" 6 | }, 7 | { 8 | "Prev":"DiamondLayoutHomescreen.jpg", 9 | "File":"DiamondLayoutHomescreen.json" 10 | }, 11 | { 12 | "Prev":"DogeLayoutRounded.jpg", 13 | "File":"DogeLayoutRounded.json" 14 | }, 15 | { 16 | "Prev":"Flow Layout.jpg", 17 | "File":"Flow Layout.json" 18 | }, 19 | { 20 | "Prev":"RoundedSmallCompact.jpg", 21 | "File":"RoundedSmallCompact.json" 22 | }, 23 | { 24 | "Prev":"SmallCompactHomescreen.jpg", 25 | "File":"SmallCompactHomescreen.json" 26 | }, 27 | { 28 | "Prev":"SuchHm.jpg", 29 | "File":"SuchHm.json" 30 | }, 31 | { 32 | "Prev":"ZnHm.jpg", 33 | "File":"ZnHm.json" 34 | } 35 | ], 36 | "lock":[ 37 | { 38 | "Prev":"SimpleLockscreenLayout.jpg", 39 | "File":"SimpleLockscreenLayout.json" 40 | }, 41 | { 42 | "Prev":"SuchLk.jpg", 43 | "File":"SuchLk.json" 44 | }, 45 | { 46 | "Prev":"GleLk.jpg", 47 | "File":"GleLk.json" 48 | } 49 | ], 50 | "psl":[ 51 | { 52 | "Prev":"Transparant Playerselect 90% Scale centered.jpg", 53 | "File":"Transparant Playerselect 90% Scale centered.json" 54 | }, 55 | { 56 | "Prev":"Transparant Playerselect 90% Scale.jpg", 57 | "File":"Transparant Playerselect 90% Scale.json" 58 | }, 59 | { 60 | "Prev":"Transparant Playerselect centered.jpg", 61 | "File":"Transparant Playerselect centered.json" 62 | }, 63 | { 64 | "Prev":"Transparant Playerselect.jpg", 65 | "File":"Transparant Playerselect.json" 66 | } 67 | ], 68 | "apps":[ 69 | { 70 | "Prev":"FlaunchRounded.jpg", 71 | "File":"FlaunchRounded.json" 72 | }, 73 | { 74 | "Prev":"DogeFl.png", 75 | "File":"DogeFl.json" 76 | } 77 | ] 78 | } -------------------------------------------------------------------------------- /Tests/SwitchThemesNXTests/RealTests.cpp: -------------------------------------------------------------------------------- 1 | #include "CppUnitTest.h" 2 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/SwitchThemesCommon.hpp" 3 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflan.hpp" 4 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/Bflyt.hpp" 5 | #include "picosha2.h" 6 | #include "Util.hpp" 7 | #include "../../SwitchThemesNX/source/SwitchThemesCommon/SarcLib/Sarc.hpp" 8 | 9 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 10 | 11 | namespace SwitchThemesNXTests 12 | { 13 | TEST_CLASS(RealTests) 14 | { 15 | public: 16 | #define MAKE_TEST_SZS(x) TEST_METHOD(x) { ProcessSzs(#x); } 17 | 18 | MAKE_TEST_SZS(ResidentMenu) 19 | 20 | MAKE_TEST_SZS(Entrance) 21 | 22 | MAKE_TEST_SZS(Notification) 23 | 24 | MAKE_TEST_SZS(Flaunch) 25 | 26 | MAKE_TEST_SZS(Set) 27 | 28 | private: 29 | void CompareSarc(const SARC::SarcData& a, const SARC::SarcData& b) 30 | { 31 | if (a.files.size() != b.files.size()) 32 | throw std::runtime_error(""); 33 | 34 | for (const auto &[key, value] : a.files) 35 | { 36 | if (!b.files.count(key)) 37 | throw std::runtime_error("file missing: " + key); 38 | 39 | if (b.files.at(key) != value) 40 | throw std::runtime_error("file different: " + key); 41 | } 42 | } 43 | 44 | void ProcessSzs(const std::string& name) 45 | { 46 | auto src = SARC::Unpack(Yaz0::Decompress(Util::ReadTestData("Source/" + name + ".szs"))); 47 | auto exp = SARC::Unpack(Yaz0::Decompress(Util::ReadTestData("Expected/" + name + ".szs"))); 48 | 49 | std::string lyt = Util::ExistsTest("Source/" + name + ".json") ? 50 | Util::ReadTestString("Source/" + name + ".json") : ""; 51 | 52 | SwitchThemesCommon::SzsPatcher p(std::move(src)); 53 | if (!p.PatchMainBG(DDS)) 54 | throw std::runtime_error(""); 55 | 56 | if (lyt != "") 57 | { 58 | auto l = Patches::LoadLayout(lyt); 59 | if (!p.PatchLayouts(l)) 60 | throw std::runtime_error(""); 61 | } 62 | 63 | auto fin = p.GetFinalSarc(); 64 | CompareSarc(exp, fin); 65 | } 66 | 67 | std::vector DDS = Util::ReadTestData("bg.dds"); 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/kip.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_KIP_H 2 | #define HACTOOL_KIP_H 3 | #include "types.h" 4 | #include "utils.h" 5 | #include "settings.h" 6 | 7 | #define MAGIC_INI1 0x31494E49 8 | #define MAGIC_KIP1 0x3150494B 9 | #define INI1_MAX_KIPS 0x50 10 | 11 | typedef struct { 12 | uint32_t magic; 13 | uint32_t size; 14 | uint32_t num_processes; 15 | uint32_t _0xC; 16 | char kip_data[]; 17 | } ini1_header_t; 18 | 19 | typedef struct { 20 | uint32_t out_offset; 21 | uint32_t out_size; 22 | uint32_t compressed_size; 23 | uint32_t attribute; 24 | } kip_section_header_t; 25 | 26 | typedef struct { 27 | uint32_t magic; 28 | char name[0xC]; 29 | uint64_t title_id; 30 | uint32_t process_category; 31 | uint8_t main_thread_priority; 32 | uint8_t default_core; 33 | uint8_t _0x1E; 34 | uint8_t flags; 35 | kip_section_header_t section_headers[6]; 36 | uint32_t capabilities[0x20]; 37 | unsigned char data[]; 38 | } kip1_header_t; 39 | 40 | typedef struct { 41 | FILE *file; 42 | hactool_ctx_t *tool_ctx; 43 | kip1_header_t *header; 44 | } kip1_ctx_t; 45 | 46 | typedef struct { 47 | FILE *file; 48 | hactool_ctx_t *tool_ctx; 49 | ini1_header_t *header; 50 | kip1_ctx_t kips[INI1_MAX_KIPS]; 51 | } ini1_ctx_t; 52 | 53 | void ini1_process(ini1_ctx_t *ctx); 54 | void ini1_print(ini1_ctx_t *ctx); 55 | void ini1_save(ini1_ctx_t *ctx); 56 | 57 | char *kip1_get_json(kip1_ctx_t *ctx); 58 | void kip1_process(kip1_ctx_t *ctx); 59 | void kip1_print(kip1_ctx_t *ctx, int suppress); 60 | void kip1_save(kip1_ctx_t *ctx); 61 | 62 | static inline uint64_t kip1_get_size(kip1_ctx_t *ctx) { 63 | /* Header + .text + .rodata + .rwdata */ 64 | return 0x100 + ctx->header->section_headers[0].compressed_size + ctx->header->section_headers[1].compressed_size + ctx->header->section_headers[2].compressed_size; 65 | } 66 | 67 | static inline uint64_t kip1_get_size_from_header(kip1_header_t *header) { 68 | /* Header + .text + .rodata + .rwdata */ 69 | return 0x100 + header->section_headers[0].compressed_size + header->section_headers[1].compressed_size + header->section_headers[2].compressed_size; 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/RemoteInstall/RemoteInstall.cpp: -------------------------------------------------------------------------------- 1 | #include "RemoteInstall.hpp" 2 | 3 | #include "Worker.hpp" 4 | #include "../../ViewFunctions.hpp" 5 | #include "Detail.hpp" 6 | #include "List.hpp" 7 | #include "API.hpp" 8 | 9 | void RemoteInstall::Initialize() 10 | { 11 | API::Initialize(); 12 | API::ReloadProviders(); 13 | } 14 | 15 | void RemoteInstall::Finalize() 16 | { 17 | API::Finalize(); 18 | } 19 | 20 | bool RemoteInstall::IsInitialized() 21 | { 22 | return API::IsInitialized(); 23 | } 24 | 25 | const std::vector& RemoteInstall::GetProviders() 26 | { 27 | return API::GetProviders(); 28 | } 29 | 30 | void RemoteInstall::Begin(const Provider& provider, const std::string& ID) 31 | { 32 | auto URL = API::MakeUrl(provider.UrlTemplate, ID); 33 | 34 | auto res = API::GetManifest(URL); 35 | if (res.Entries.size() == 0) return; 36 | 37 | std::vector imageUrls; 38 | 39 | if (res.Entries.size() == 1) 40 | imageUrls.push_back(res.Entries[0].PreviewUrl()); 41 | else { 42 | for (const auto& res : res.Entries) 43 | imageUrls.push_back(res.ThumbUrl()); 44 | } 45 | 46 | Worker::ImageFetch::Result ImageLoadResult; 47 | PushPageBlocking(new Worker::ImageFetch(imageUrls, ImageLoadResult)); 48 | 49 | if (res.Entries.size() == 1) 50 | { 51 | PushPage(new DetailPage(res.Entries[0], ImageLoadResult.List[0])); 52 | } 53 | else 54 | { 55 | PushPage(new ListPage(std::move(res), std::move(ImageLoadResult))); 56 | } 57 | } 58 | 59 | void RemoteInstall::BeginType(const RemoteInstall::Provider& provider, FixedTypes type) 60 | { 61 | if (type == FixedTypes::Random) 62 | BeginRandom(provider); 63 | else if (type == FixedTypes::Recent) 64 | BeginRecent(provider); 65 | else 66 | throw std::runtime_error("Unsupported remote install type"); 67 | } 68 | 69 | void RemoteInstall::BeginRandom(const RemoteInstall::Provider& provider) 70 | { 71 | Begin(provider, "__special_random"); 72 | } 73 | 74 | void RemoteInstall::BeginRecent(const RemoteInstall::Provider& provider) 75 | { 76 | Begin(provider, "__special_recent"); 77 | } 78 | -------------------------------------------------------------------------------- /SwitchThemesOnline/wwwroot/css/custom_styles2.css: -------------------------------------------------------------------------------- 1 | .header { 2 | background-color: rgb(38,50,56) !important; 3 | margin: 0; 4 | padding: 0; 5 | overflow: hidden; 6 | } 7 | 8 | .tabColor { 9 | background-color: rgb(55,71,79) !important; 10 | border-radius: 0 !important; 11 | } 12 | 13 | body { 14 | background-color: #333; 15 | float: left; 16 | } 17 | 18 | .tab-content { 19 | background-color: #333333; 20 | position: absolute !important; 21 | left: 0px !important; 22 | padding: 5px !important; 23 | width: 100% !important; 24 | color: white; 25 | } 26 | 27 | p { 28 | color: white; 29 | margin: 1%; 30 | } 31 | 32 | .HeaderTextBig { 33 | font-size: 8vw; 34 | margin-bottom: 2vw; 35 | } 36 | 37 | .HeaderTextSmall { 38 | font-size: 3vw; 39 | margin-top: 2vw; 40 | margin-bottom: 10px; 41 | } 42 | 43 | .BigScreenContent { 44 | width: 100%; 45 | margin: auto; 46 | } 47 | 48 | @media screen and (min-width: 600px) { 49 | .HeaderTextBig { 50 | font-size: 40px; 51 | } 52 | 53 | .HeaderTextSmall { 54 | font-size: 20px; 55 | } 56 | 57 | .BigScreenContent { 58 | max-width: 600px; 59 | margin: auto; 60 | } 61 | } 62 | 63 | .buttonCenter { 64 | margin: auto; 65 | display: block; 66 | } 67 | 68 | b { 69 | font-weight: bold !important; 70 | } 71 | 72 | .PathLabel { 73 | margin-bottom: 15px; 74 | margin-top: 5px; 75 | text-align: center; 76 | } 77 | 78 | .BaseCard { 79 | padding: 10px !important; 80 | background: #37474f !important; 81 | margin: 15px !important; 82 | color: #fff !important; 83 | } 84 | 85 | .WarnCard { 86 | padding: 10px !important; 87 | background: #ff5c5c !important; 88 | margin: 15px !important; 89 | } 90 | 91 | h1 { 92 | color: white; 93 | text-align: center; 94 | } 95 | 96 | h2, h3, h4, h5 { 97 | color: white; 98 | margin-top: 5%; 99 | margin-bottom: 2% 100 | } 101 | 102 | .TextBox { 103 | margin-bottom: 1% !important; 104 | width: 100% !important; 105 | background-color: #DDD !important; 106 | height: 1vw !important; 107 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/TextPage.cpp: -------------------------------------------------------------------------------- 1 | #include "TextPage.hpp" 2 | #include "../Version.hpp" 3 | #include "../ViewFunctions.hpp" 4 | #include "../UI/imgui/imgui_internal.h" 5 | 6 | using namespace std; 7 | 8 | TextPage::TextPage(const std::string& title, const std::string& text) : 9 | Text(text) 10 | { 11 | Name = title; 12 | c_str = Text.c_str(); 13 | } 14 | 15 | TextPage::TextPage(const char* title, const char* text) 16 | { 17 | Name = title; 18 | c_str = text; 19 | } 20 | 21 | void TextPage::Render(int X, int Y) 22 | { 23 | Utils::ImGuiSetupPage(this, X, Y); 24 | ImGui::PushFont(font25); 25 | ImGui::TextWrapped(c_str); 26 | ImGui::PopFont(); 27 | Utils::ImGuiSetWindowScrollable(); 28 | Utils::ImGuiCloseWin(); 29 | } 30 | 31 | void TextPage::Update() 32 | { 33 | Parent->PageLeaveFocus(this); 34 | } 35 | 36 | CreditsPage::CreditsPage() : 37 | creditsText("NXThemes installer by exelix - " + Version::Name + " - Core Ver." + SwitchThemesCommon::CoreVer + 38 | '\n' + Version::Commit + 39 | "\nSource: github.com/exelix11/SwitchThemeInjector"+ 40 | "\nDonations: ko-fi.com/exelix11\n\n") 41 | { 42 | Name = "Credits"; 43 | } 44 | 45 | extern void ShowFirstTimeHelp(bool WelcomeScr); //from main.cpp 46 | void CreditsPage::Render(int X, int Y) 47 | { 48 | Utils::ImGuiSetupPage(this, X, Y); 49 | ImGui::SetCursorPosY(20); 50 | ImGui::PushFont(font30); 51 | ImGui::TextWrapped(creditsText.c_str()); 52 | ImGui::PopFont(); 53 | 54 | ImGui::PushFont(font25); 55 | ImGui::TextWrapped( 56 | "Thanks to:\n" 57 | "Syroot for BinaryData lib\n" 58 | "AboodXD for Bntx editor and sarc lib\n" 59 | "shchmue for Lockpick\n" 60 | "SciresM for hactool\n" 61 | "Everyone from Atmosphere and libnx\n" 62 | "switch-stuff on github for the font converter\n" 63 | "Fincs for the hybrid_app template\n" 64 | "Everyone from the DearImgui github repo" 65 | ); 66 | 67 | if (ImGui::Button("Show first startup info")) 68 | PushFunction([]() {ShowFirstTimeHelp(false); }); 69 | PAGE_RESET_FOCUS; 70 | 71 | ImGui::PopFont(); 72 | Utils::ImGuiSetWindowScrollable(); 73 | Utils::ImGuiCloseWin(); 74 | } 75 | 76 | void CreditsPage::Update() 77 | { 78 | if (Utils::PageLeaveFocusInput()) 79 | Parent->PageLeaveFocus(this); 80 | } 81 | 82 | -------------------------------------------------------------------------------- /Tests/SwitchThemesNXTests/Util.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "picosha2.h" 8 | 9 | namespace Util 10 | { 11 | static inline std::string StringHash(const std::vector& data) 12 | { 13 | auto h = picosha2::hash256_hex_string(data); 14 | 15 | for (char& c : h) 16 | c = std::toupper(c); 17 | 18 | return h; 19 | } 20 | 21 | //static inline void WriteFile(const std::string& name, const std::vector& data) 22 | //{ 23 | // FILE* f = fopen(name.c_str(), "wb"); 24 | // if (!f) 25 | // throw std::runtime_error("Saving file " + name + "failed !"); 26 | // 27 | // fwrite(data.data(), 1, data.size(), f); 28 | // fflush(f); 29 | // fclose(f); 30 | //} 31 | 32 | static inline std::vector ReadFile(const std::string& name) 33 | { 34 | FILE* f = fopen(name.c_str(), "rb"); 35 | if (!f) 36 | throw std::runtime_error("Opening file " + name + " failed !\n"); 37 | 38 | fseek(f, 0, SEEK_END); 39 | size_t len = 0; 40 | { 41 | auto fsz = ftell(f); 42 | if (fsz < 0) 43 | throw std::runtime_error("Reading file size for " + name + " failed !\n"); 44 | len = fsz; 45 | } 46 | rewind(f); 47 | 48 | std::vector coll(len); 49 | if (fread(coll.data(), 1, len, f) != len) 50 | throw std::runtime_error("Reading from file " + name + " failed !\n"); 51 | 52 | fclose(f); 53 | return coll; 54 | } 55 | 56 | static inline std::string ReadAllText(const std::string& name) 57 | { 58 | std::ifstream t(name); 59 | if (!t.good()) 60 | throw std::runtime_error(""); 61 | 62 | std::string str((std::istreambuf_iterator(t)), 63 | std::istreambuf_iterator()); 64 | return str; 65 | } 66 | 67 | static inline std::vector ReadTestData(const std::string& name) 68 | { 69 | return ReadFile("../Tests/Cases/" + name); 70 | } 71 | 72 | static inline std::string ReadTestString(const std::string& name) 73 | { 74 | return ReadAllText("../Tests/Cases/" + name); 75 | } 76 | 77 | static inline bool ExistsTest(const std::string& name) 78 | { 79 | return std::filesystem::exists("../Tests/Cases/" + name); 80 | } 81 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/SettingsPage.cpp: -------------------------------------------------------------------------------- 1 | #include "SettingsPage.hpp" 2 | #include "../ViewFunctions.hpp" 3 | #include "../Platform/Platform.hpp" 4 | 5 | using namespace std; 6 | 7 | namespace Settings { 8 | bool UseIcons = true; 9 | bool UseCommon = true; 10 | SwitchThemesCommon::LayoutCompatibilityOption HomeMenuCompat = SwitchThemesCommon::LayoutCompatibilityOption::Default; 11 | }; 12 | 13 | SettingsPage::SettingsPage() 14 | { 15 | Name = "Settings"; 16 | } 17 | 18 | void SettingsPage::Render(int X, int Y) 19 | { 20 | Utils::ImGuiSetupWin(Name.c_str(), X, Y, DefaultWinFlags); 21 | ImGui::SetWindowSize(ImVec2(SCR_W - (float)X - 30, SCR_H - (float)Y - 70)); 22 | ImGui::PushFont(font25); 23 | 24 | ImGui::PushFont(font30); 25 | ImGui::TextUnformatted("NXTheme settings"); 26 | ImGui::PopFont(); 27 | ImGui::TextWrapped("These settings only apply for installing nxthemes and are not saved, you have to switch them back every time you launch this app"); 28 | ImGui::Checkbox("Enable custom icons", &Settings::UseIcons); 29 | PAGE_RESET_FOCUS; 30 | ImGui::Checkbox("Enable extra layouts (eg. common.szs)", &Settings::UseCommon); 31 | 32 | ImGui::NewLine(); 33 | ImGui::Text("Home menu compatibility options."); 34 | ImGui::TextWrapped("Changing this could help solve install issues with old themes on latest firmware."); 35 | ImGui::RadioButton("Decide automatically (default)", (int*)&Settings::HomeMenuCompat, (int)SwitchThemesCommon::LayoutCompatibilityOption::Default); 36 | ImGui::RadioButton("Force original home menu applet icons (firmware <= 10.0)", (int*)&Settings::HomeMenuCompat, (int)SwitchThemesCommon::LayoutCompatibilityOption::Firmware10); 37 | ImGui::RadioButton("Force home menu layout with the NS online icon (firmware 11.0)", (int*)&Settings::HomeMenuCompat, (int)SwitchThemesCommon::LayoutCompatibilityOption::Firmware11); 38 | ImGui::RadioButton("Do not apply compatibility fixes", (int*)&Settings::HomeMenuCompat, (int)SwitchThemesCommon::LayoutCompatibilityOption::DisableFixes); 39 | 40 | ImGui::NewLine(); 41 | 42 | ImGui::PopFont(); 43 | Utils::ImGuiCloseWin(); 44 | } 45 | 46 | void SettingsPage::Update() 47 | { 48 | if (Utils::PageLeaveFocusInput(true)) 49 | { 50 | Parent->PageLeaveFocus(this); 51 | return; 52 | } 53 | } 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /SwitchThemesCommon/Bflyt/Grp1Pane.cs: -------------------------------------------------------------------------------- 1 | using ExtensionMethods; 2 | using SwitchThemes.Common; 3 | using Syroot.BinaryData; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.ComponentModel; 7 | using System.IO; 8 | using System.Text; 9 | using static SwitchThemes.Common.Bflyt.BflytFile; 10 | 11 | namespace SwitchThemes.Common.Bflyt 12 | { 13 | public class Grp1Pane : BasePane, INamedPane 14 | { 15 | public string GroupName { get; set; } 16 | public string PaneName => GroupName; 17 | 18 | #if LYTEDITOR 19 | [Editor(@"System.Windows.Forms.Design.StringCollectionEditor," + 20 | "System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", 21 | typeof(System.Drawing.Design.UITypeEditor))] 22 | #endif 23 | public List Panes { get; set; } = new List(); 24 | 25 | public uint Version; 26 | 27 | public override string ToString() => GroupName + " [Group]"; 28 | 29 | public Grp1Pane(uint ver) : base("grp1", 8) 30 | { 31 | Version = ver; 32 | } 33 | 34 | public Grp1Pane(BinaryDataReader src, uint version) : base("grp1", src) 35 | { 36 | BinaryDataReader bin = new BinaryDataReader(new MemoryStream(data)); 37 | bin.ByteOrder = src.ByteOrder; 38 | Version = version; 39 | UInt16 NodeCount = 0; 40 | if (version >= 0x05020000) //3dskit docs say this should be > but files from mario maker for wii u use 34 bytes for names with version 5.2 41 | { 42 | GroupName = bin.ReadFixedLenString(34); 43 | NodeCount = bin.ReadUInt16(); 44 | } 45 | else 46 | { 47 | GroupName = bin.ReadFixedLenString(24); 48 | NodeCount = bin.ReadUInt16(); 49 | bin.ReadUInt16(); //padding 50 | } 51 | var pos = bin.Position; 52 | for (int i = 0; i < NodeCount; i++) 53 | { 54 | bin.Position = pos + i * 24; 55 | Panes.Add(bin.ReadFixedLenString(24)); 56 | } 57 | } 58 | 59 | protected override void ApplyChanges(BinaryDataWriter bin) 60 | { 61 | if (Version >= 0x05020000) 62 | { 63 | bin.WriteFixedLenString(GroupName, 34); 64 | bin.Write((UInt16)Panes.Count); 65 | } 66 | else 67 | { 68 | bin.WriteFixedLenString(GroupName, 24); 69 | bin.Write((UInt16)Panes.Count); 70 | bin.Write((UInt16)0); 71 | } 72 | foreach (var s in Panes) 73 | bin.WriteFixedLenString(s, 24); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /SwitchThemes/layouts/SuchLk.json: -------------------------------------------------------------------------------- 1 | { 2 | "TargetName": "Entrance.szs", 3 | "PatchName": "Clear lockscreen", 4 | "AuthorName": "Such Meme, Many Skill", 5 | "ID": "builtin_ClearLock", 6 | "Files": [{ 7 | "FileName": "blyt/EntMain.bflyt", 8 | "Patches": [{ 9 | "PaneName": "N_CntRMain", 10 | "Position": { 11 | "X": -180, 12 | "Y": 0, 13 | "Z": 0 14 | } 15 | }, { 16 | "PaneName": "L_BtnSystemApplet", 17 | "Position": { 18 | "X": 1000, 19 | "Y": 0, 20 | "Z": 0 21 | } 22 | }, { 23 | "PaneName": "L_BtnSystemAppletLock", 24 | "Position": { 25 | "X": -180, 26 | "Y": 0, 27 | "Z": 0 28 | } 29 | }, { 30 | "PaneName": "L_BtnResume", 31 | "Position": { 32 | "X": -180, 33 | "Y": -300, 34 | "Z": 0 35 | } 36 | }, { 37 | "PaneName": "N_CntHud", 38 | "Position": { 39 | "X": -180, 40 | "Y": -14, 41 | "Z": 0 42 | } 43 | }, { 44 | "PaneName": "N_CntL", 45 | "Position": { 46 | "X": -1000, 47 | "Y": 10000, 48 | "Z": 0 49 | } 50 | }, { 51 | "PaneName": "N_News", 52 | "Position": { 53 | "X": -1000, 54 | "Y": 36, 55 | "Z": 0 56 | } 57 | }, { 58 | "PaneName": "L_BtnNtf", 59 | "Position": { 60 | "X": 0, 61 | "Y": -1000, 62 | "Z": 0 63 | } 64 | } 65 | ] 66 | } 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/bktr.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_BKTR_H 2 | #define HACTOOL_BKTR_H 3 | 4 | #include "types.h" 5 | 6 | #define MAGIC_BKTR 0x52544B42 7 | 8 | typedef struct { 9 | uint64_t offset; 10 | uint64_t size; 11 | uint32_t magic; /* "BKTR" */ 12 | uint32_t _0x14; /* Version? */ 13 | uint32_t num_entries; 14 | uint32_t _0x1C; /* Reserved? */ 15 | } bktr_header_t; 16 | 17 | #pragma pack(push, 1) 18 | typedef struct { 19 | uint64_t virt_offset; 20 | uint64_t phys_offset; 21 | uint32_t is_patch; 22 | } bktr_relocation_entry_t; 23 | #pragma pack(pop) 24 | 25 | #pragma pack(push, 1) 26 | typedef struct { 27 | uint32_t _0x0; 28 | uint32_t num_entries; 29 | uint64_t virtual_offset_end; 30 | bktr_relocation_entry_t entries[0x3FF0/sizeof(bktr_relocation_entry_t)]; 31 | uint8_t padding[0x3FF0 % sizeof(bktr_relocation_entry_t)]; 32 | } bktr_relocation_bucket_t; 33 | #pragma pack(pop) 34 | 35 | #pragma pack(push, 1) 36 | typedef struct { 37 | uint32_t _0x0; 38 | uint32_t num_buckets; 39 | uint64_t total_size; 40 | uint64_t bucket_virtual_offsets[0x3FF0/sizeof(uint64_t)]; 41 | bktr_relocation_bucket_t buckets[]; 42 | } bktr_relocation_block_t; 43 | #pragma pack(pop) 44 | 45 | #pragma pack(push, 1) 46 | typedef struct { 47 | uint64_t offset; 48 | uint32_t _0x8; 49 | uint32_t ctr_val; 50 | } bktr_subsection_entry_t; 51 | #pragma pack(pop) 52 | 53 | #pragma pack(push, 1) 54 | typedef struct { 55 | uint32_t _0x0; 56 | uint32_t num_entries; 57 | uint64_t physical_offset_end; 58 | bktr_subsection_entry_t entries[0x3FF]; 59 | } bktr_subsection_bucket_t; 60 | #pragma pack(pop) 61 | 62 | #pragma pack(push, 1) 63 | typedef struct { 64 | uint32_t _0x0; 65 | uint32_t num_buckets; 66 | uint64_t total_size; 67 | uint64_t bucket_physical_offsets[0x3FF0/sizeof(uint64_t)]; 68 | bktr_subsection_bucket_t buckets[]; 69 | } bktr_subsection_block_t; 70 | #pragma pack(pop) 71 | 72 | bktr_relocation_bucket_t *bktr_get_relocation_bucket(bktr_relocation_block_t *block, uint32_t i); 73 | bktr_relocation_entry_t *bktr_get_relocation(bktr_relocation_block_t *block, uint64_t offset); 74 | 75 | bktr_subsection_bucket_t *bktr_get_subsection_bucket(bktr_subsection_block_t *block, uint32_t i); 76 | bktr_subsection_entry_t *bktr_get_subsection(bktr_subsection_block_t *block, uint64_t offset); 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/LayoutCompatibility.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../SarcLib/Sarc.hpp" 8 | #include "Bflan.hpp" 9 | #include "Patches.hpp" 10 | 11 | namespace SwitchThemesCommon::Compatibility 12 | { 13 | enum class ProblemType 14 | { 15 | // The layout references a file that does not exist anymore 16 | MissingFile, 17 | // The layout or animation references a pane that does not exist anymore 18 | MissingPane, 19 | // The animation references a group that does not exist anymore 20 | MissingGroup, 21 | // The animation references a texture that does not exist anymore 22 | MissingTexture, 23 | // The heuristic failed to determine the severity of the issue 24 | Uncertain 25 | }; 26 | 27 | enum class ProblemSeverity 28 | { 29 | // This issue won't crash the theme, it will be automatically ignored by the theme installer 30 | // it is the case for layout patches that refer to non-existing panes 31 | AutoIgnored, 32 | // This issue will crash the console if the theme is installed 33 | // It is the case for custom animations that refer to non-existing panes or groups 34 | // To prevent crashes during the installation process any file that has a Critical issue will be dropped 35 | Critical 36 | }; 37 | 38 | struct CompatIssue 39 | { 40 | std::string FileName; 41 | std::string ItemName; 42 | std::string AdditionalInfo; 43 | ProblemType Type; 44 | ProblemSeverity Severity; 45 | 46 | static CompatIssue MissingPane(std::string_view fileName, std::string_view paneName, std::string_view additional = "", bool critical = false); 47 | static CompatIssue Uncertain(std::string_view fileName, std::string_view itemName, std::string_view additional); 48 | static CompatIssue MissingGroup(std::string_view fileName, std::string_view groupName); 49 | }; 50 | 51 | std::string LayoutNameForAnimation(std::string_view animationName); 52 | void CheckAnimationCompatibility(std::vector& res, const LayoutPatch& layout, const SARC::SarcData& szs, std::string_view animName, const Bflan& bflan); 53 | 54 | // TODO: The c++ implementation is not complete. We do not implement bflyt checks since those are not currently used in the install process 55 | } -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef HACTOOL_UTILS_H 2 | #define HACTOOL_UTILS_H 3 | 4 | #include 5 | #include 6 | #include "types.h" 7 | 8 | struct filepath; 9 | 10 | #ifdef _WIN32 11 | #define PATH_SEPERATOR '\\' 12 | #else 13 | #define PATH_SEPERATOR '/' 14 | #endif 15 | 16 | #define MEDIA_SIZE 0x200 17 | 18 | /* On the switch, paths are limited to 0x300. Limit them to 0x400 - 1 on PC. */ 19 | /* MAX_PATH is previously defined in "windef.h" on WIN32. */ 20 | #ifndef MAX_PATH 21 | #define MAX_PATH 1023 22 | #endif 23 | 24 | #define FATAL_ERROR(msg) do {\ 25 | fprintf(stderr, "Error: %s\n", msg);\ 26 | exit(EXIT_FAILURE);\ 27 | } while (0) 28 | 29 | uint32_t align(uint32_t offset, uint32_t alignment); 30 | uint64_t align64(uint64_t offset, uint64_t alignment); 31 | 32 | void print_magic(const char *prefix, uint32_t magic); 33 | 34 | void memdump(FILE *f, const char *prefix, const void *data, size_t size); 35 | 36 | uint64_t _fsize(const char *filename); 37 | 38 | void save_file_section(FILE *f_in, uint64_t ofs, uint64_t total_size, struct filepath *filepath); 39 | 40 | void save_buffer_to_file(void *buf, uint64_t size, struct filepath *filepath); 41 | void save_buffer_to_directory_file(void *buf, uint64_t size, struct filepath *dirpath, const char *filename); 42 | 43 | const char *get_key_revision_summary(uint8_t key_rev); 44 | 45 | FILE *open_key_file(const char *prefix); 46 | 47 | validity_t check_memory_hash_table(FILE *f_in, unsigned char *hash_table, uint64_t data_ofs, uint64_t data_len, uint64_t block_size, int full_block); 48 | validity_t check_file_hash_table(FILE *f_in, uint64_t hash_ofs, uint64_t data_ofs, uint64_t data_len, uint64_t block_size, int full_block); 49 | 50 | validity_t check_memory_hash_table_with_suffix(FILE *f_in, unsigned char *hash_table, uint64_t data_ofs, uint64_t data_len, uint64_t block_size, const uint8_t *suffix, int full_block); 51 | 52 | #ifdef _MSC_VER 53 | inline int fseeko64(FILE *__stream, long long __off, int __whence) 54 | { 55 | return _fseeki64(__stream, __off, __whence); 56 | } 57 | #elif __MINGW32__ 58 | /* MINGW32 does not have 64-bit offsets even with large file support. */ 59 | extern int fseeko64 (FILE *__stream, _off64_t __off, int __whence); 60 | #else 61 | /* off_t is 64-bit with large file support */ 62 | #define fseeko64 fseek 63 | #endif 64 | 65 | static inline uint64_t media_to_real(uint64_t media) { 66 | return MEDIA_SIZE * media; 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/SeekTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Syroot.BinaryData 5 | { 6 | /// 7 | /// Represents a temporary seek to another position which is undone after the task has been disposed. 8 | /// 9 | public class SeekTask : IDisposable 10 | { 11 | // ---- CONSTRUCTORS ------------------------------------------------------------------------------------------- 12 | 13 | /// 14 | /// Initializes a new instance of the class to temporarily seek the given 15 | /// to the specified position. The is rewound to its 16 | /// previous position after the task is disposed. 17 | /// 18 | /// A to temporarily seek. 19 | /// A byte offset relative to the origin parameter. 20 | /// A value of type indicating the reference point used to obtain 21 | /// the new position. 22 | public SeekTask(Stream stream, long offset, SeekOrigin origin) 23 | { 24 | Stream = stream; 25 | PreviousPosition = stream.Position; 26 | Stream.Seek(offset, origin); 27 | } 28 | 29 | // ---- PROPERTIES --------------------------------------------------------------------------------------------- 30 | 31 | /// 32 | /// Gets the which is temporarily sought to another position. 33 | /// 34 | public Stream Stream 35 | { 36 | get; 37 | private set; 38 | } 39 | 40 | /// 41 | /// Gets the absolute position to which the will be rewound after this task is disposed. 42 | /// 43 | public long PreviousPosition 44 | { 45 | get; 46 | private set; 47 | } 48 | 49 | // ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- 50 | 51 | /// 52 | /// Rewinds the to its previous position. 53 | /// 54 | public void Dispose() 55 | { 56 | Stream.Seek(PreviousPosition, SeekOrigin.Begin); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/mbedtls/include/mbedtls/platform_time.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file platform_time.h 3 | * 4 | * \brief mbed TLS Platform time abstraction 5 | * 6 | * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 7 | * SPDX-License-Identifier: Apache-2.0 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 | * not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * This file is part of mbed TLS (https://tls.mbed.org) 22 | */ 23 | #ifndef MBEDTLS_PLATFORM_TIME_H 24 | #define MBEDTLS_PLATFORM_TIME_H 25 | 26 | #if !defined(MBEDTLS_CONFIG_FILE) 27 | #include "config.h" 28 | #else 29 | #include MBEDTLS_CONFIG_FILE 30 | #endif 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /** 37 | * \name SECTION: Module settings 38 | * 39 | * The configuration options you can set for this module are in this section. 40 | * Either change them in config.h or define them on the compiler command line. 41 | * \{ 42 | */ 43 | 44 | /* 45 | * The time_t datatype 46 | */ 47 | #if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) 48 | typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; 49 | #else 50 | /* For time_t */ 51 | #include 52 | typedef time_t mbedtls_time_t; 53 | #endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ 54 | 55 | /* 56 | * The function pointers for time 57 | */ 58 | #if defined(MBEDTLS_PLATFORM_TIME_ALT) 59 | extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); 60 | 61 | /** 62 | * \brief Set your own time function pointer 63 | * 64 | * \param time_func the time function implementation 65 | * 66 | * \return 0 67 | */ 68 | int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); 69 | #else 70 | #if defined(MBEDTLS_PLATFORM_TIME_MACRO) 71 | #define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO 72 | #else 73 | #define mbedtls_time time 74 | #endif /* MBEDTLS_PLATFORM_TIME_MACRO */ 75 | #endif /* MBEDTLS_PLATFORM_TIME_ALT */ 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* platform_time.h */ 82 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/Pages/ThemeEntry/LegacyEntry.hpp: -------------------------------------------------------------------------------- 1 | #include "ThemeEntry.hpp" 2 | #include "../../fs.hpp" 3 | #include "../../SwitchTools/PatchMng.hpp" 4 | #include "../../SwitchThemesCommon/SarcLib/Yaz0.hpp" 5 | #include "../../ViewFunctions.hpp" 6 | #include "../../SwitchThemesCommon/SwitchThemesCommon.hpp" 7 | #include "../ThemePage.hpp" 8 | 9 | class LegacyEntry : public ThemeEntry 10 | { 11 | public: 12 | LegacyEntry(const std::string& fileName, std::vector&& RawData) 13 | { 14 | FileName = fileName; 15 | file = RawData; 16 | auto DecompressedFile = Yaz0::Decompress(file); 17 | ParseLegacyTheme(SARC::Unpack(DecompressedFile)); 18 | } 19 | 20 | LegacyEntry(const std::string& fileName, SARC::SarcData&& _SData) 21 | { 22 | FileName = fileName; 23 | 24 | auto packed = SARC::Pack(_SData); 25 | file = move(Yaz0::Compress(packed.data)); 26 | 27 | ParseLegacyTheme(std::move(_SData)); 28 | } 29 | 30 | bool IsFolder() override { return false; } 31 | bool CanInstall() override { return _CanInstall; } 32 | bool HasPreview() override { return false; } 33 | protected: 34 | bool DoInstall(bool ShowDialogs = true) override 35 | { 36 | if (ShowDialogs) 37 | ThemeEntry::DisplayInstallDialog(FileName); 38 | 39 | auto patch = SwitchThemesCommon::SzsPatcher::DetectSarc(SData); 40 | 41 | if (!patch) 42 | throw std::runtime_error("Couldn't find a compatible patch template"); 43 | 44 | if (!PatchMng::ExefsCompatAsk(patch->szsName)) 45 | return false; 46 | 47 | fs::theme::CreateStructure(patch->TitleId); 48 | fs::WriteFile(fs::path::RomfsFolder(patch->TitleId) + "lyt/" + patch->szsName, file); 49 | 50 | return true; 51 | } 52 | 53 | private: 54 | bool _CanInstall = true; 55 | SARC::SarcData SData; 56 | 57 | LoadedImage GetPreview() override 58 | { 59 | throw std::runtime_error("Preview is not implemented for szs themes"); 60 | } 61 | 62 | void ParseLegacyTheme(SARC::SarcData&& _Sdata) 63 | { 64 | SData = _Sdata; 65 | if (FileName == "") 66 | { 67 | lblFname = "Unknown.szs"; 68 | lblLine1 = "Remote install"; 69 | } 70 | else 71 | { 72 | lblFname = fs::GetFileName(FileName); 73 | lblLine1 = FileName; 74 | } 75 | auto patch = SwitchThemesCommon::SzsPatcher::DetectSarc(SData); 76 | if (!patch) 77 | { 78 | lblLine2 = "Invalid theme"; 79 | CannotInstallReason = "Couldn't find a compatible patch template"; 80 | _CanInstall = false; 81 | } 82 | 83 | else lblLine2 = (patch->TemplateName + " for " + patch->FirmName); 84 | } 85 | }; -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Layouts/Bflyt/Pan1Pane.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "BasePane.hpp" 3 | #include "../Patches.hpp" 4 | 5 | namespace Panes 6 | { 7 | enum class OriginX : u8 8 | { 9 | Center = 0, 10 | Left = 1, 11 | Right = 2 12 | }; 13 | 14 | enum class OriginY : u8 15 | { 16 | Center = 0, 17 | Top = 1, 18 | Bottom = 2 19 | }; 20 | 21 | class Pan1Pane : public BasePane 22 | { 23 | public: 24 | Vector3 Position, Rotation; 25 | Vector2 Scale, Size; 26 | 27 | bool GetVisible() { return (_flag1 & 0x1) == 0x1; } 28 | void SetVisible(bool value) { 29 | if (value) 30 | _flag1 |= 0x1; 31 | else 32 | _flag1 &= 0xFE; 33 | } 34 | 35 | OriginX GetOriginX() { 36 | return (OriginX)((_flag2 & 0xC0) >> 6);; 37 | } 38 | 39 | void SetOriginX(OriginX val) { 40 | _flag2 &= ((u8)(~0xC0)); 41 | _flag2 |= (u8)((u8)val << 6); 42 | } 43 | 44 | OriginY GetOriginY() { 45 | return (OriginY)((_flag2 & 0x30) >> 4); 46 | } 47 | 48 | void SetOriginY(OriginY val) { 49 | _flag2 &= ((u8)(~0x30)); 50 | _flag2 |= (u8)((u8)val << 4); 51 | } 52 | 53 | OriginX GetParentOriginX() { 54 | return (OriginX)((_flag2 & 0xC) >> 2); 55 | } 56 | 57 | void SetParentOriginX(OriginX val) { 58 | _flag2 &= ((u8)(~0xC)); 59 | _flag2 |= (u8)((u8)val << 2); 60 | } 61 | 62 | OriginY GetParentOriginY() { 63 | return (OriginY)((_flag2 & 0x3)); 64 | } 65 | 66 | void SetParentOriginY(OriginY val) { 67 | _flag2 &= ((u8)(~0x3)); 68 | _flag2 |= (u8)val; 69 | } 70 | 71 | Pan1Pane(Buffer& b, Endianness e, const std::string &name = "pan1") : BasePane(name, b) 72 | { 73 | LoadProperties(e); 74 | } 75 | 76 | void ApplyChanges(Buffer &bin) override 77 | { 78 | bin.Write(data); 79 | bin.Position = 0; 80 | bin.Write(_flag1); 81 | bin.Write(_flag2); 82 | bin.Position = 0x2C - 8; 83 | WriteVec3(bin,Position); 84 | WriteVec3(bin, Rotation); 85 | WriteVec2(bin, Scale); 86 | WriteVec2(bin, Size); 87 | } 88 | 89 | private: 90 | void LoadProperties(Endianness e) 91 | { 92 | Buffer buf(data); 93 | buf.ByteOrder = e; 94 | _flag1 = buf.readUInt8(); 95 | _flag2 = buf.readUInt8(); 96 | buf.Position += 2; 97 | PaneName = buf.readStr_NullTerm(0x18); 98 | buf.Position = 0x2c - 8; 99 | Position = ReadVec3(buf); 100 | Rotation = ReadVec3(buf); 101 | Scale = ReadVec2(buf); 102 | Size = ReadVec2(buf); 103 | } 104 | 105 | u8 _flag1; 106 | u8 _flag2; 107 | }; 108 | }; -------------------------------------------------------------------------------- /SwitchThemes/RemoteInstallForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using System.Windows.Forms; 5 | using System.IO; 6 | using Syroot.BinaryData; 7 | using System.Net.Sockets; 8 | 9 | namespace SwitchThemes 10 | { 11 | public partial class RemoteInstallForm : Form 12 | { 13 | public string DefaultFileName; 14 | 15 | public RemoteInstallForm(string DefaultName = "") 16 | { 17 | InitializeComponent(); 18 | DefaultFileName = DefaultName; 19 | } 20 | 21 | public static string DoRemoteInstall(string Ip, byte[] theme) 22 | { 23 | var mem = new MemoryStream(); 24 | BinaryDataWriter bin = new BinaryDataWriter(mem, UTF8Encoding.ASCII); 25 | bin.Write("theme", BinaryStringFormat.NoPrefixOrTermination); 26 | bin.Write(new byte[3]); 27 | bin.Write((Int32)theme.Length); 28 | bin.Write(theme); 29 | try 30 | { 31 | Socket sock = 32 | new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 33 | 34 | var arr = mem.ToArray(); 35 | 36 | sock.Connect(Ip, 5000); 37 | 38 | if (sock.Connected) 39 | { 40 | sock.Send(arr, SocketFlags.None); 41 | 42 | byte[] by = new byte[2]; 43 | if (sock.Receive(by, SocketFlags.None) != 2) 44 | return "Didn't receive confirmation from switch :("; 45 | 46 | sock.Close(); 47 | 48 | } 49 | else 50 | return "Socket didn't connect"; 51 | } 52 | catch (Exception ex) 53 | { 54 | return "There was an error: " + ex.ToString(); 55 | } 56 | return null; 57 | } 58 | 59 | private void button1_Click(object sender, EventArgs e) 60 | { 61 | if (textBox1.Text.Trim() == "") 62 | { 63 | MessageBox.Show("Enter a valid address"); 64 | return; 65 | } 66 | OpenFileDialog opn = new OpenFileDialog() { Filter = "theme files (*.nxtheme,*.szs)|*.nxtheme;*.szs", FileName = DefaultFileName }; 67 | if (opn.ShowDialog() != DialogResult.OK) return; 68 | byte[] theme = System.IO.File.ReadAllBytes(opn.FileName); 69 | 70 | string res = DoRemoteInstall(textBox1.Text, theme); 71 | if (res != null) 72 | MessageBox.Show(res); 73 | } 74 | 75 | private void RemoteInstallForm_DragEnter(object sender, DragEventArgs e) 76 | { 77 | if (e.GetFiles()?.Length == 1) 78 | e.Effect = DragDropEffects.Copy; 79 | } 80 | 81 | private void RemoteInstallForm_DragDrop(object sender, DragEventArgs e) 82 | { 83 | byte[] theme = System.IO.File.ReadAllBytes(e.GetFiles().First()); 84 | string res = DoRemoteInstall(textBox1.Text, theme); 85 | if (res != null) 86 | MessageBox.Show(res); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/hactool/source/sha.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "sha.h" 4 | #include "types.h" 5 | #include "utils.h" 6 | 7 | /* Allocate new context. */ 8 | sha_ctx_t *new_sha_ctx(hash_type_t type, int hmac) { 9 | sha_ctx_t *ctx; 10 | 11 | if ((ctx = malloc(sizeof(*ctx))) == NULL) { 12 | FATAL_ERROR("Failed to allocate sha_ctx_t!"); 13 | } 14 | 15 | mbedtls_md_init(&ctx->digest); 16 | 17 | if (mbedtls_md_setup(&ctx->digest, mbedtls_md_info_from_type(type), hmac)) { 18 | FATAL_ERROR("Failed to set up hash context!"); 19 | } 20 | 21 | if (mbedtls_md_starts(&ctx->digest)) { 22 | FATAL_ERROR("Failed to start hash context!"); 23 | } 24 | 25 | return ctx; 26 | } 27 | 28 | /* Free an allocated context. */ 29 | void free_sha_ctx(sha_ctx_t *ctx) { 30 | /* Explicitly allow NULL. */ 31 | if (ctx == NULL) { 32 | return; 33 | } 34 | 35 | mbedtls_md_free(&ctx->digest); 36 | free(ctx); 37 | } 38 | 39 | /* Update digest with new data. */ 40 | void sha_update(sha_ctx_t *ctx, const void *data, size_t l) { 41 | mbedtls_md_update(&ctx->digest, data, l); 42 | } 43 | 44 | /* Read hash from context. */ 45 | void sha_get_hash(sha_ctx_t *ctx, unsigned char *hash) { 46 | mbedtls_md_finish(&ctx->digest, hash); 47 | } 48 | 49 | /* SHA256 digest. */ 50 | void sha256_hash_buffer(unsigned char *digest, const void *data, size_t l) { 51 | sha_ctx_t *sha_ctx = new_sha_ctx(HASH_TYPE_SHA256, 0); 52 | sha_update(sha_ctx, data, l); 53 | sha_get_hash(sha_ctx, digest); 54 | free_sha_ctx(sha_ctx); 55 | } 56 | 57 | /* SHA256-HMAC digest. */ 58 | void sha256_get_buffer_hmac(void *digest, const void *secret, size_t s_l, const void *data, size_t d_l) { 59 | sha_ctx_t *ctx; 60 | 61 | if ((ctx = malloc(sizeof(*ctx))) == NULL) { 62 | FATAL_ERROR("Failed to allocate sha_ctx_t!"); 63 | } 64 | 65 | mbedtls_md_init(&ctx->digest); 66 | 67 | if (mbedtls_md_setup(&ctx->digest, mbedtls_md_info_from_type(HASH_TYPE_SHA256), 1)) { 68 | FATAL_ERROR("Failed to set up hash context!"); 69 | } 70 | 71 | if (mbedtls_md_hmac_starts(&ctx->digest, secret, s_l)) { 72 | FATAL_ERROR("Failed to set up HMAC secret context!"); 73 | } 74 | 75 | if (mbedtls_md_hmac_update(&ctx->digest, data, d_l)) { 76 | FATAL_ERROR("Failed processing HMAC input!"); 77 | } 78 | 79 | if (mbedtls_md_hmac_finish(&ctx->digest, digest)) { 80 | FATAL_ERROR("Failed getting HMAC output!"); 81 | } 82 | 83 | mbedtls_md_free(&ctx->digest); 84 | free(ctx); 85 | } 86 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/mbedtls/include/mbedtls/platform_util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file platform_util.h 3 | * 4 | * \brief Common and shared functions used by multiple modules in the Mbed TLS 5 | * library. 6 | */ 7 | /* 8 | * Copyright (C) 2018, Arm Limited, All Rights Reserved 9 | * SPDX-License-Identifier: GPL-2.0 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | * 25 | * This file is part of Mbed TLS (https://tls.mbed.org) 26 | */ 27 | #ifndef MBEDTLS_PLATFORM_UTIL_H 28 | #define MBEDTLS_PLATFORM_UTIL_H 29 | 30 | #include 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /** 37 | * \brief Securely zeroize a buffer 38 | * 39 | * The function is meant to wipe the data contained in a buffer so 40 | * that it can no longer be recovered even if the program memory 41 | * is later compromised. Call this function on sensitive data 42 | * stored on the stack before returning from a function, and on 43 | * sensitive data stored on the heap before freeing the heap 44 | * object. 45 | * 46 | * It is extremely difficult to guarantee that calls to 47 | * mbedtls_platform_zeroize() are not removed by aggressive 48 | * compiler optimizations in a portable way. For this reason, Mbed 49 | * TLS provides the configuration option 50 | * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure 51 | * mbedtls_platform_zeroize() to use a suitable implementation for 52 | * their platform and needs 53 | * 54 | * \param buf Buffer to be zeroized 55 | * \param len Length of the buffer in bytes 56 | * 57 | */ 58 | void mbedtls_platform_zeroize( void *buf, size_t len ); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | #endif /* MBEDTLS_PLATFORM_UTIL_H */ 65 | -------------------------------------------------------------------------------- /SwitchThemesCommon/Exten.cs: -------------------------------------------------------------------------------- 1 | using SwitchThemes.Common; 2 | using Syroot.BinaryData; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace ExtensionMethods 8 | { 9 | public static class Extensions 10 | { 11 | public static RGBAColor ReadColorRGBA(this BinaryDataReader bin) 12 | { 13 | byte[] values = bin.ReadBytes(4); 14 | return new RGBAColor(values[0], values[1], values[2], values[3]); 15 | } 16 | 17 | public static void Write(this BinaryDataWriter bin, RGBAColor c) 18 | { 19 | bin.Write(c.R); 20 | bin.Write(c.G); 21 | bin.Write(c.B); 22 | bin.Write(c.A); 23 | } 24 | 25 | public static Vector3 ReadVector3(this BinaryDataReader bin) => 26 | new Vector3 { X = bin.ReadSingle(), Y = bin.ReadSingle(), Z = bin.ReadSingle() }; 27 | 28 | public static void Write(this BinaryDataWriter bin, Vector3 vec) 29 | { 30 | bin.Write((float)vec.X); 31 | bin.Write((float)vec.Y); 32 | bin.Write((float)vec.Z); 33 | } 34 | 35 | public static Vector2 ReadVector2(this BinaryDataReader bin) => 36 | new Vector2 { X = bin.ReadSingle(), Y = bin.ReadSingle() }; 37 | 38 | public static void Write(this BinaryDataWriter bin, Vector2 vec) 39 | { 40 | bin.Write((float)vec.X); 41 | bin.Write((float)vec.Y); 42 | } 43 | 44 | public static bool Matches(this byte[] arr, string magic) => 45 | arr.Matches(0, Encoding.ASCII.GetBytes(magic)); 46 | public static bool Matches(this byte[] arr, uint startIndex, string magic) => 47 | arr.Matches(startIndex, Encoding.ASCII.GetBytes(magic)); 48 | 49 | public static bool Matches(this byte[] arr, uint startIndex, params byte[] magic) 50 | { 51 | if (arr.Length < magic.Length + startIndex) return false; 52 | for (uint i = 0; i < magic.Length; i++) 53 | { 54 | if (arr[i + startIndex] != magic[i]) return false; 55 | } 56 | return true; 57 | } 58 | 59 | public static void WriteFixedLenString(this BinaryDataWriter bin, string s, int max) 60 | { 61 | if (s.Length > max) throw new Exception("The string is longer than the field"); 62 | bin.Write(s, BinaryStringFormat.NoPrefixOrTermination); 63 | for (int i = s.Length; i < max; i++) 64 | bin.Write((byte)0); 65 | } 66 | 67 | public static string ReadFixedLenString(this BinaryDataReader bin, int max) => 68 | bin.ReadFixedLenString(max, Encoding.UTF8); 69 | 70 | public static string ReadFixedLenString(this BinaryDataReader bin, int max, Encoding encoding) 71 | { 72 | var data = bin.ReadBytes(max); 73 | int count = 0; 74 | for (; count < max && data[count] != 0; count++) ; 75 | return encoding.GetString(data, 0, count); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/SwitchThemesCommon/Bntx/BRTI.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "../MyTypes.h" 5 | #include "../BinaryReadWrite/Buffer.hpp" 6 | 7 | namespace Bntxx 8 | { 9 | enum class TextureFormatType : u32 10 | { 11 | R5G6B5 = 0x07, 12 | R8G8 = 0x09, 13 | R16 = 0x0a, 14 | R8G8B8A8 = 0x0b, 15 | R11G11B10 = 0x0f, 16 | R32 = 0x14, 17 | BC1 = 0x1a, 18 | BC2 = 0x1b, 19 | BC3 = 0x1c, 20 | BC4 = 0x1d, 21 | BC5 = 0x1e, 22 | ASTC4x4 = 0x2d, 23 | ASTC5x4 = 0x2e, 24 | ASTC5x5 = 0x2f, 25 | ASTC6x5 = 0x30, 26 | ASTC6x6 = 0x31, 27 | ASTC8x5 = 0x32, 28 | ASTC8x6 = 0x33, 29 | ASTC8x8 = 0x34, 30 | ASTC10x5 = 0x35, 31 | ASTC10x6 = 0x36, 32 | ASTC10x8 = 0x37, 33 | ASTC10x10 = 0x38, 34 | ASTC12x10 = 0x39, 35 | ASTC12x12 = 0x3a 36 | }; 37 | 38 | enum class TextureFormatVar : u32 39 | { 40 | UNorm = 1, 41 | SNorm = 2, 42 | UInt = 3, 43 | SInt = 4, 44 | Single = 5, 45 | SRGB = 6, 46 | UHalf = 10 47 | }; 48 | 49 | enum class TextureType : u32 50 | { 51 | Image1D = 0, 52 | Image2D = 1, 53 | Image3D = 2, 54 | Cube = 3, 55 | CubeFar = 8 56 | }; 57 | 58 | enum class ChannelType 59 | { 60 | Zero, 61 | One, 62 | Red, 63 | Green, 64 | Blue, 65 | Alpha 66 | }; 67 | 68 | class BRTI 69 | { 70 | public: 71 | //Header 72 | s32 BRTILength0; 73 | long long int BRTILength1; 74 | u8 Flags; 75 | u8 Dimensions; 76 | u16 TileMode; 77 | u16 SwizzleSize; 78 | u16 MipmapCount; 79 | u16 MultiSampleCount; 80 | u16 Reversed1A; 81 | u32 Format; 82 | u32 AccessFlags; 83 | s32 Width; 84 | s32 Height; 85 | s32 Depth; 86 | s32 ArrayCount; 87 | s32 BlockHeightLog2; 88 | s32 Reserved38; 89 | s32 Reserved3C; 90 | s32 Reserved40; 91 | s32 Reserved44; 92 | s32 Reserved48; 93 | s32 Reserved4C; 94 | s32 DataLength; 95 | s32 Alignment; 96 | s32 ChannelTypes; 97 | s32 TextureType; 98 | long long int NameAddress; 99 | long long int ParentAddress; 100 | long long int PtrsAddress; 101 | 102 | std::vector Data; 103 | std::vector ExtraBrtiData; 104 | 105 | const std::string& Name() const; 106 | 107 | ChannelType Channel0Type() const; 108 | ChannelType Channel3Type() const; 109 | ChannelType Channel1Type() const; 110 | ChannelType Channel2Type() const; 111 | 112 | Bntxx::TextureType Type() const; 113 | TextureFormatType FormatType() const; 114 | TextureFormatVar FormatVariant() const; 115 | 116 | std::vector Write(); 117 | BRTI(Buffer &Reader); 118 | 119 | private: 120 | std::string _readonly_name; 121 | }; 122 | } -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/Offset.cs: -------------------------------------------------------------------------------- 1 | namespace Syroot.BinaryData 2 | { 3 | /// 4 | /// Represents a space of 4 bytes reserved in the underlying stream of a which can 5 | /// be comfortably satisfied later on. 6 | /// 7 | public class Offset 8 | { 9 | // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------ 10 | 11 | /// 12 | /// Initializes a new instance of the class reserving an offset with the specified 13 | /// at the current position. 14 | /// 15 | /// The holding the stream in which the offset will be 16 | /// reserved. 17 | public Offset(BinaryDataWriter writer) 18 | { 19 | Writer = writer; 20 | Position = (uint)Writer.Position; 21 | Writer.Position += 4; 22 | } 23 | 24 | // ---- PROPERTIES --------------------------------------------------------------------------------------------- 25 | 26 | /// 27 | /// Gets the in which underlying stream the allocation is made. 28 | /// 29 | public BinaryDataWriter Writer { get; private set; } 30 | 31 | /// 32 | /// Gets the address at which the allocation is made. 33 | /// 34 | public uint Position { get; private set; } 35 | 36 | // ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- 37 | 38 | /// 39 | /// Satisfies the offset by writing the current position of the underlying stream at the reserved 40 | /// , then seeking back to the current position. 41 | /// 42 | public void Satisfy() 43 | { 44 | Satisfy((int)Writer.Position); 45 | } 46 | 47 | /// 48 | /// Satisfies the offset by writing the given value of the underlying stream at the reserved 49 | /// , then seeking back to the current position. 50 | /// 51 | public void Satisfy(int value) 52 | { 53 | // Temporarily seek back to the allocation offset and write the given value there, then seek back. 54 | uint oldPosition = (uint)Writer.Position; 55 | Writer.Position = Position; 56 | Writer.Write(value); 57 | Writer.Position = oldPosition; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /SwitchThemesNX/source/UI/UI.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../SwitchThemesCommon/MyTypes.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "imgui/imgui.h" 8 | 9 | #ifdef __SWITCH__ 10 | #include 11 | #endif 12 | 13 | constexpr ImGuiWindowFlags DefaultWinFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove; 14 | const ImVec2 TabPageSize = { 900, 552 }; 15 | 16 | extern ImFont* font25; 17 | extern ImFont* font30; 18 | extern ImFont* font40; 19 | 20 | constexpr uint32_t SCR_W = 1280; 21 | constexpr uint32_t SCR_H = 720; 22 | 23 | typedef unsigned int LoadedImage; 24 | 25 | namespace Colors { 26 | const ImVec4 Highlight = { 0,1,0.788f,1 }; 27 | const ImVec4 Red = { 1,0,0,1 }; 28 | } 29 | 30 | namespace Image 31 | { 32 | void Free(LoadedImage img); 33 | LoadedImage Load(const std::vector& data); 34 | //TODO: LoadedImage Load(const std::string path); 35 | namespace Internal { 36 | void AssertOnLeaks(); 37 | } 38 | } 39 | 40 | namespace ImageCache { 41 | void Clear(); 42 | void FreeImage(const std::string& img); 43 | //Cache automatically frees old images, no need to do it manually 44 | LoadedImage LoadDDS(const std::vector& data, const std::string& name); 45 | }; 46 | 47 | struct PageEvent 48 | { 49 | bool Reset() { if (Fired) { Fired = false; return true; } return false; } 50 | void Set() { Fired = true; } 51 | bool Peek() { return Fired; } 52 | private: 53 | bool Fired = true; 54 | }; 55 | 56 | class IUIControlObj 57 | { 58 | public: 59 | //Execute commands out of the drawing code,eg manually check inputs or call UI blocking functions 60 | virtual void Update() = 0; 61 | //Draw the control in the existing Imgui frame 62 | virtual void Render(int X, int Y) = 0; 63 | virtual ~IUIControlObj(); 64 | }; 65 | 66 | class TabRenderer; 67 | class IPage : public IUIControlObj 68 | { 69 | public: 70 | IPage() = default; 71 | IPage(std::string_view name) : Name(name) {} 72 | 73 | TabRenderer* Parent; 74 | std::string Name; 75 | virtual ~IPage(); 76 | 77 | PageEvent FocusEvent; 78 | }; 79 | 80 | class TabRenderer : public IUIControlObj 81 | { 82 | public: 83 | TabRenderer(); 84 | 85 | //TabRenderer ignores the position 86 | void Render(int X, int Y) override; 87 | 88 | void PageLeaveFocus(IPage *page); 89 | void AddPage(IPage* page); 90 | void RemoveAt(int id); 91 | IPage* At(int id); 92 | 93 | void Update() override; 94 | private: 95 | void SetFocused(int id); 96 | IPage* CurrentControl = nullptr; 97 | bool ControlHasFocus = false; 98 | std::vector Pages; 99 | std::string Title; 100 | }; -------------------------------------------------------------------------------- /SwitchThemes/layouts/SimpleLockscreenLayout.json: -------------------------------------------------------------------------------- 1 | { 2 | "PatchName": "Simple Layout Lockscreen", 3 | "AuthorName": "Akai", 4 | "TargetName": "Entrance.szs", 5 | "ID": "builtin_SimpleLayoutLockscreen", 6 | "Files": [ 7 | { 8 | "FileName": "blyt/EntMain.bflyt", 9 | "Patches": [ 10 | { 11 | "PaneName": "N_CntRMain", 12 | "Position": { 13 | "X": 300.0, 14 | "Y": -299.0, 15 | "Z": 0.0 16 | }, 17 | "Scale": { 18 | "X": 0.4, 19 | "Y": 0.4 20 | } 21 | }, 22 | { 23 | "PaneName": "L_BtnResume", 24 | "Position": { 25 | "X": 1000.0, 26 | "Y": 0.0, 27 | "Z": 0.0 28 | } 29 | }, 30 | { 31 | "PaneName": "N_ChildLock", 32 | "Visible": false 33 | }, 34 | { 35 | "PaneName": "N_MarginChildLockHud", 36 | "Visible": false 37 | }, 38 | { 39 | "PaneName": "N_CntL", 40 | "Visible": false 41 | }, 42 | { 43 | "PaneName": "N_News", 44 | "Position": { 45 | "X": -100.0, 46 | "Y": 36.0, 47 | "Z": 0.0 48 | }, 49 | "Visible": false 50 | }, 51 | { 52 | "PaneName": "L_BtnNtf", 53 | "Scale": { 54 | "X": 0.8, 55 | "Y": 0.8 56 | }, 57 | "Visible": false 58 | }, 59 | { 60 | "PaneName": "L_Lock", 61 | "Position": { 62 | "X": -200.0, 63 | "Y": -290.0, 64 | "Z": 0.0 65 | }, 66 | "Scale": { 67 | "X": 0.8, 68 | "Y": 0.8 69 | } 70 | }, 71 | { 72 | "PaneName": "L_BtnBack", 73 | "Position": { 74 | "X": -362.0, 75 | "Y": -285.0, 76 | "Z": 0.0 77 | } 78 | } 79 | ] 80 | }, 81 | { 82 | "FileName": "blyt/EntBtnChildLock.bflyt", 83 | "Patches": [ 84 | { 85 | "PaneName": "RootPane", 86 | "Visible": false 87 | }, 88 | { 89 | "PaneName": "N_Root", 90 | "Visible": false 91 | } 92 | ] 93 | }, 94 | { 95 | "FileName": "blyt/Hud.bflyt", 96 | "Patches": [ 97 | { 98 | "PaneName": "N_Root", 99 | "Position": { 100 | "X": -900.0, 101 | "Y": -580.0, 102 | "Z": 0.0 103 | } 104 | } 105 | ] 106 | } 107 | ] 108 | } -------------------------------------------------------------------------------- /SwitchThemesNX/source/UI/imgui/imgui_impl_opengl3.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline 2 | // - Desktop GL: 3.x 4.x 3 | // - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) 4 | // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) 5 | 6 | // Implemented features: 7 | // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. 8 | 9 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 10 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 11 | // https://github.com/ocornut/imgui 12 | 13 | // About Desktop OpenGL function loaders: 14 | // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. 15 | // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). 16 | // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. 17 | 18 | // About GLSL version: 19 | // The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string. 20 | // On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es" 21 | // Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp. 22 | 23 | #pragma once 24 | 25 | // Specific OpenGL versions 26 | //#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten 27 | //#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android 28 | 29 | #define IMGUI_IMPL_OPENGL_LOADER_CUSTOM "../glad.h" 30 | 31 | // Set default OpenGL3 loader to be gl3w 32 | #if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \ 33 | && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \ 34 | && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \ 35 | && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) 36 | #define IMGUI_IMPL_OPENGL_LOADER_GL3W 37 | #endif 38 | 39 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL); 40 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); 41 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); 42 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data); 43 | 44 | // Called by Init/NewFrame/Shutdown 45 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture(); 46 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture(); 47 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); 48 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); 49 | -------------------------------------------------------------------------------- /SwitchThemesCommon/Syroot.BinaryData/BinaryDataFormats.cs: -------------------------------------------------------------------------------- 1 | namespace Syroot.BinaryData 2 | { 3 | /// 4 | /// Represents the set of formats of binary boolean encodings. 5 | /// 6 | public enum BinaryBooleanFormat 7 | { 8 | /// 9 | /// The boolean is stored in 1 byte and is true when the value is not 0. This is the .NET default. 10 | /// 11 | NonZeroByte, 12 | 13 | /// 14 | /// The boolean is stored in 2 bytes and is true when the value is not 0. 15 | /// 16 | NonZeroWord, 17 | 18 | /// 19 | /// The boolean is stored in 4 bytes and is true when the value is not 0. 20 | /// 21 | NonZeroDword 22 | } 23 | 24 | /// 25 | /// Represents the set of formats of binary date and time encodings. 26 | /// 27 | public enum BinaryDateTimeFormat 28 | { 29 | /// 30 | /// The is stored as the ticks of a .NET instance. 31 | /// 32 | NetTicks, 33 | 34 | /// 35 | /// The has the time_t format of the C library. 36 | /// 37 | CTime 38 | } 39 | 40 | /// 41 | /// Represents the set of formats of binary string encodings. 42 | /// 43 | public enum BinaryStringFormat 44 | { 45 | /// 46 | /// The string has a prefix of variable size determining the length of the string and no postfix. This is the 47 | /// .NET default. 48 | /// 49 | VariableLengthPrefix, 50 | 51 | /// 52 | /// The string has a prefix of 1 byte determining the length of the string and no postfix. 53 | /// 54 | ByteLengthPrefix, 55 | 56 | /// 57 | /// The string has a prefix of 2 bytes determining the length of the string and no postfix. 58 | /// 59 | WordLengthPrefix, 60 | 61 | /// 62 | /// The string has a prefix of 4 bytes determining the length of the string and no postfix. 63 | /// 64 | DwordLengthPrefix, 65 | 66 | /// 67 | /// The string has no prefix and is terminated with a byte of the value 0. 68 | /// 69 | ZeroTerminated, 70 | 71 | /// 72 | /// The string has neither prefix nor postfix. This format is only valid for writing strings. For reading 73 | /// strings, the length has to be specified manually. 74 | /// 75 | NoPrefixOrTermination 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Tests/SwitchThemesCommonTests/RealTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SARCExt; 3 | using SwitchThemes.Common; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Text; 9 | 10 | namespace SwitchThemesCommonTests 11 | { 12 | [TestClass] 13 | public class RealTests 14 | { 15 | byte[] DDS = Util.ReadData("bg.dds"); 16 | 17 | private void CompareSarc(SARCExt.SarcData a, SARCExt.SarcData b) 18 | { 19 | Assert.AreEqual(a.Files.Count, b.Files.Count); 20 | 21 | foreach (var f in a.Files) 22 | { 23 | if (!b.Files.ContainsKey(f.Key)) 24 | throw new Exception($"{f.Key} is missing in B"); 25 | 26 | if (!b.Files[f.Key].SequenceEqual(f.Value)) 27 | throw new Exception($"file {f.Key} is different in B"); 28 | } 29 | } 30 | 31 | private void ProcessSzs(string name) 32 | { 33 | SarcData src = SARC.Unpack(ManagedYaz0.Decompress(Util.ReadData($"Source/{name}.szs"))); 34 | SarcData exp = SARC.Unpack(ManagedYaz0.Decompress(Util.ReadData($"Expected/{name}.szs"))); 35 | 36 | string lyt = Util.Exists($"Source/{name}.json") ? Util.ReadString($"Source/{name}.json") : null; 37 | 38 | SzsPatcher patcher = new SzsPatcher(src); 39 | Assert.IsTrue(patcher.PatchMainBG(DDS)); 40 | 41 | if (lyt != null) 42 | { 43 | var l = LayoutPatch.Load(lyt); 44 | patcher.PatchLayouts(l); 45 | } 46 | 47 | var final = patcher.GetFinalSarc(); 48 | CompareSarc(final, exp); 49 | } 50 | 51 | [TestMethod] 52 | public void ResidentMenu() => 53 | ProcessSzs("ResidentMenu"); 54 | 55 | [TestMethod] 56 | public void Entrance() => 57 | ProcessSzs("Entrance"); 58 | 59 | [TestMethod] 60 | public void Notification() => 61 | ProcessSzs("Notification"); 62 | 63 | [TestMethod] 64 | public void Flaunch() => 65 | ProcessSzs("Flaunch"); 66 | 67 | [TestMethod] 68 | public void Set() => 69 | ProcessSzs("Set"); 70 | 71 | 72 | private void MaterialTexturesAssumption(string name) 73 | { 74 | SarcData src = SARC.Unpack(ManagedYaz0.Decompress(System.IO.File.ReadAllBytes(name))); 75 | 76 | foreach (var val in src.Files.Where(x => x.Key.EndsWith(".bflyt"))) 77 | { 78 | var (n, f) = val; 79 | 80 | SwitchThemes.Common.Bflyt.BflytFile ff = new SwitchThemes.Common.Bflyt.BflytFile(f); 81 | 82 | if (ff.Mat1 != null) 83 | { 84 | foreach (var m in ff.Mat1.Materials) 85 | Assert.AreEqual(m.Textures.Length, m.TextureTransformations.Length); 86 | } 87 | } 88 | } 89 | 90 | [TestMethod] 91 | public void CheckMaterialTexturesAssumption() 92 | { 93 | foreach (var f in System.IO.Directory.GetFiles(Util.GetPath("Source/")).Where(x => x.EndsWith(".szs"))) 94 | MaterialTexturesAssumption(f); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /SwitchThemesNX/Libs/SOIL/image_helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | Jonathan Dummer 3 | 4 | Image helper functions 5 | 6 | MIT license 7 | */ 8 | 9 | #ifndef HEADER_IMAGE_HELPER 10 | #define HEADER_IMAGE_HELPER 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /** 17 | This function upscales an image. 18 | Not to be used to create MIPmaps, 19 | but to make it square, 20 | or to make it a power-of-two sized. 21 | **/ 22 | int 23 | up_scale_image 24 | ( 25 | const unsigned char* const orig, 26 | int width, int height, int channels, 27 | unsigned char* resampled, 28 | int resampled_width, int resampled_height 29 | ); 30 | 31 | /** 32 | This function downscales an image. 33 | Used for creating MIPmaps, 34 | the incoming image should be a 35 | power-of-two sized. 36 | **/ 37 | int 38 | mipmap_image 39 | ( 40 | const unsigned char* const orig, 41 | int width, int height, int channels, 42 | unsigned char* resampled, 43 | int block_size_x, int block_size_y 44 | ); 45 | 46 | /** 47 | This function takes the RGB components of the image 48 | and scales each channel from [0,255] to [16,235]. 49 | This makes the colors "Safe" for display on NTSC 50 | displays. Note that this is _NOT_ a good idea for 51 | loading images like normal- or height-maps! 52 | **/ 53 | int 54 | scale_image_RGB_to_NTSC_safe 55 | ( 56 | unsigned char* orig, 57 | int width, int height, int channels 58 | ); 59 | 60 | /** 61 | This function takes the RGB components of the image 62 | and converts them into YCoCg. 3 components will be 63 | re-ordered to CoYCg (for optimum DXT1 compression), 64 | while 4 components will be ordered CoCgAY (for DXT5 65 | compression). 66 | **/ 67 | int 68 | convert_RGB_to_YCoCg 69 | ( 70 | unsigned char* orig, 71 | int width, int height, int channels 72 | ); 73 | 74 | /** 75 | This function takes the YCoCg components of the image 76 | and converts them into RGB. See above. 77 | **/ 78 | int 79 | convert_YCoCg_to_RGB 80 | ( 81 | unsigned char* orig, 82 | int width, int height, int channels 83 | ); 84 | 85 | /** 86 | Converts an HDR image from an array 87 | of unsigned chars (RGBE) to RGBdivA 88 | \return 0 if failed, otherwise returns 1 89 | **/ 90 | int 91 | RGBE_to_RGBdivA 92 | ( 93 | unsigned char *image, 94 | int width, int height, 95 | int rescale_to_max 96 | ); 97 | 98 | /** 99 | Converts an HDR image from an array 100 | of unsigned chars (RGBE) to RGBdivA2 101 | \return 0 if failed, otherwise returns 1 102 | **/ 103 | int 104 | RGBE_to_RGBdivA2 105 | ( 106 | unsigned char *image, 107 | int width, int height, 108 | int rescale_to_max 109 | ); 110 | 111 | #ifdef __cplusplus 112 | } 113 | #endif 114 | 115 | #endif /* HEADER_IMAGE_HELPER */ 116 | --------------------------------------------------------------------------------