diff --git a/Common/Include/os/os_HomeMenu.hpp b/Common/Include/os/os_HomeMenu.hpp index 3f906aa..780b5d2 100644 --- a/Common/Include/os/os_HomeMenu.hpp +++ b/Common/Include/os/os_HomeMenu.hpp @@ -7,7 +7,7 @@ namespace os enum class GeneralChannelMessage : u32 { Invalid, - HomeButton = 2, // Is this really HOME button? Never fires... + HomeButton = 2, Sleep = 3, Shutdown = 5, Reboot = 6, @@ -20,13 +20,13 @@ namespace os struct SystemAppletMessage { - u32 magic; // "SAMS" -> System Applet message...? + u32 magic; u32 unk; u32 message; - u8 data[0x400 - (sizeof(u32) * 3)]; + u8 data[0x400 - (sizeof(u32) * 3)]; // 1024 bytes are usually sent, so let's read it all. } PACKED; - static constexpr u32 SAMSMagic = 0x534D4153; + static constexpr u32 SAMSMagic = 0x534D4153; // "SAMS" -> System Applet message...? static_assert(sizeof(SystemAppletMessage) == 0x400, "System applet message must be 0x400!"); diff --git a/HOME.md b/HOME.md deleted file mode 100644 index 6fa0162..0000000 --- a/HOME.md +++ /dev/null @@ -1,89 +0,0 @@ -# qlaunch - -qlaunch is the name of the process officially known as **HOME menu**. - -## Official - -- qlaunch uses ~56MB memory from applet pool. - -- qlaunch is a **system applet**, a special and unique type of applet. - - - There are 3 types of applets: **system applet** (qlaunch), **overlay applet** (overlay, another special title), and the rest, which are **library applets** (software keyboard, user selector, web applets...) - - - Development kits or Kiosk units may have different system and overlay titles: for instance, development consoles' overlay is a different one, some can launch DevMenu instead of normal qlaunch, and Kiosk units have special menus instead of qlaunch (known as Retail Interactive Display Menu) - - - Both qlaunch and overlayDisp are special, since they take care of unique and essential functionality, thus they have more access and privileges than any other applet/application. - - - Some of the privileges qlaunch has: title management (is the only one who can directly launch, suspend and close titles), special applet messages (like HOME button press, any other applet or application has these messages but qlaunch has special ones), the general channel (a channel where any applet/application can communicate to qlaunch to request things via storages and "SAMS" messages), foreground control... - -- According to RE and left strings, it is qlaunch who handles periodical play report telemetry, aka **is the one who makes play reports and sends them to Nintendo**. Then, **prepo** system service is the one who queues the reports and uploads them when possible. - - - Those play reports contain **a lot** of information about the console, but it is worth to mention that, among them, there is the list of launched titles. If N detects that there is any kind of irregulatity with that list (custom installed titles, for instance), it will likely result in a guaranteed ban. - - - Note that reports are apparently saved even if there is no connection, so that they will be uploaded to N's servers as soon as connection is established. Thus, blocking connection to N's servers (via 90DNS, for example) is, as long as you did ban-baity stuff, a way to delay one's fate. Plain homebrew, aka not touching games or doing suspicious stuff, should not risk bans, but the actual range those have is still unclear. - -- qlaunch doesn't just contain the main menu, it does also contain: **news**, **console settings**, **lock screen**... (did I forgot any?) - -- Surprisingly, qlaunch's basic functionality (launching titles, detecting HOME press, systems other applets use to interact with it) hasn't (apparently) changed, at least not since 5.1.0 (oldest firmware I did tests related to qlaunch) - -## Custom implementation: uLaunch - -### Homebrew limitations - -Problems arose when starting to work on a proper, serious custom qlaunch reimplementation project, which started by the temporary name **Project Home**, and later got renamed to **eQlipse**. - -Homebrew libraries' base GPU libraries (mesa) require **a lot** of memory. Since normal homebrew is expected to run as a library applet or an application, it has never supposed any issues (by default, homebrew libraries tend to reserve as much mem as they can, which tends to be a few hundreds of MBs). - -Speaking of a custom type of applet which must use ~50-60MB to not leave the applet pool dry, this supposes a problem. - -In fact, this is why the idea of a qlaunch reimplementation was almost abandoned: - -- eQlipse used ~180MB, which was the minimum to make the UI work (still sometimes struggling to render properly). - -- After updating to latest SDL2 and Plutonium, UI wouldn't even work with more than that (and I was already using more than 3 times the memory I should use!) - -- In addition to that, eQlipse's code was really bad organised, and changing a small thing could be really tedious. - -### Workaround and re-start - -I started to work on a new, well organised and optimized reimplementation before memory issues became unbearable, and this rewrite, after finding a workaround for the memory issue, would become the current project. - -The final workaround for the reimplementation was, simply, to **separate the UI from the actual qlaunch functionality** in different processes: - -- The actual qlaunch process would be **a daemon process, a backend**, which would make no use of anything UI-related (thus saving **A LOT** of memory, now using even way less than official qlaunch), and which would -**just perform what it is asked to do**, since it is the one with privileges. - -- The menu the user would interact with would be a **separate library applet**. Instead of having it always opened, the applet is closed when an application or an applet is launched, and reopened when pressing HOME. - -*Result*: using as much memory I want from the applet pool for the UI without being a problem, and the actual qlaunch process wasting ~40MB less memory than usual! - -In fact, the fact that the menu gets closed and re-opened very often is helpful in order to update records, since normal qlaunch would have to listen to an event to see if any new one was added or removed, while this way there is no need to do that. - -This is the list of some remarkable advantages this system has: - -- Application records: when new records are added (new games installed) or removed (games removed) official qlaunch needs to wait for a system event on an extra thread in order to notice when there are changes, and then re-update its display. Since just by returning HOME the menu is always re-opened, if one installed or removed a title from homebrew, just returning (thus reopening) the menu, which always gets all records on startup, would show new ones or lack the removed ones. - -- Communications security: while my first approach was to make the communication system use the **general channel** (storage system where other titles send requests to qlaunch: sleep, HOME press...), but that wouldn't be a good idea since that channel isn't meant for "send-receive" communications, and since the daemon-to-menu part would be handled via **library applet storages** (the system made for an applet and the one who launched it to communicate with each other) it would involve waiting, possible threading... In the end (for what it's worth) this latter system was used for both sides, since in the end it iss made for that purpose. Communications consist on 16KB byte blocks sent and received by and from both. - -- qlaunch's essential threading: a regular qlaunch reimplementation does need threads, since it needs to host its special event handling (the aforementioned general channel, applet messages...) appart from the UI and user input. In uLaunch's case this responsibilities (back-end and front-end functionalities) are split into both the menu and the daemon. Despite being almost invisible, since the daemon (being the system applet in this case) has its unique functionality only it can use, the communication system between the menu library applet and the daemon consists on the menu asking the daemon to perform a certain privileged task (launching titles, detecting HOME menu...) and the response from the daemon with the result and/or the asked data. - -### Homebrew and forwarding - -A common practice to be able to easily launch homebrew, from the main menu and as application, is to take advantage of the *title override* feature most CFWs provide, or as a last resource, to install forwarder NSPs to target homebrew located at the SD card. - -Nevertheless, the latter is ban-baity idea, not to mention the disapproval of a big part of homebrew developers due to its tight relation to piracy. - -Since eQlipse, I've taken advantage of a lost gem in the switch's system memory: **flog**. - -"flog" easter egg was a special application consisting on a NES emulator with a hardcoded ROM of the NES Golf game. Hackers discovered it and people were really impressed of the easter egg (related to Iwata by the way it had to be accessed), but N quickly spoiled the fun of the discovery, leaving it **stubbed** on 4.0.0. - -It is important to note that it was stubbed, not removed. That means that the title is there, in your console's memory (on any version), but no longer launchable via the HOME menu trick, and the code would do nothing if it was launched. - -However, the fact that it is still there means that **every console has an application title built-in in their systems**. In fact, flog is a special title kind: it is a **system application**, which is completely similar to a normal application, but the difference is that these kind of titles come within the system. - -Theorerically, flog isn't the only system application, since **starter** (that special menu shown on the initial configuration of the console) seems to be one too. - -The idea of a custom way to target homebrew started in eQlipse, where there were two custom titles: a library applet and a system application, both wrappers of nx-hbloader, which took advantage of library applets' argument storages to target homebrew. - -For the rewrite I basically ported both, with some minor fixes and improvements, but the idea and functionality was the same. - -Both of them replace certain console titles (eShop applet and flog system application) so launching those with certain input arguments can be used as an improved hbloader. \ No newline at end of file diff --git a/LibraryAppletQMenu/RomFs/LangDefault.json b/LibraryAppletQMenu/RomFs/LangDefault.json index 49c927f..4d10839 100644 --- a/LibraryAppletQMenu/RomFs/LangDefault.json +++ b/LibraryAppletQMenu/RomFs/LangDefault.json @@ -3,6 +3,7 @@ "no": "No", "ok": "Ok", "cancel": "Cancel", + "menu_quick_info": "Tip: to open the quick menu, hold a stick (L or R-stick) and release it after selecting an option by moving it (while being held)", "menu_multiselect": "Multiselect", "menu_multiselect_cancel": "Multiselect was cancelled.", "hb_mode_entries_add": "Would you like to add all selected entries to the main menu?", @@ -32,14 +33,10 @@ "folder_entry_single": "entry", "folder_entry_mult": "entries", "app_launch": "Title launch", - "app_unexpected_error": "A title failed to start, crashed or unexpectedly terminated. (Could it be corrupted? If it is a gamecard title, do you have it inserted?)", + "app_unexpected_error": "A title failed to start, crashed or unexpectedly terminated.\n(Could it be corrupted? If it is a gamecard title, do you have it inserted?)", "ulaunch_about": "About uLaunch", - "ulaunch_desc": "uLaunch is a FOSS, extended and homebrew-oriented HOME menu reimplementation.", - "ulaunch_contribute": "If you would like to contribute, check uLaunch's GitHub repository", + "ulaunch_desc": "uLaunch is a free, open source, extended and homebrew-oriented HOME menu replacement.\nNote that some original HOME menu functionalities aren't implemented yet.\n\nIf you're looking for new uLaunch themes, check r/uLaunchThemes subreddit.\nIf you would like to contribute, check uLaunch's GitHub repository", "control_minus": "Swap the main menu", - "control_x": "Close title if suspended", - "control_y": "Options / multiselect", - "control_zlr": "Open top menus", "suspended_app": "Suspended title", "suspended_close": "Would you like to close this title? All unsaved data will be lost.", "hb_launch": "Homebrew launch", @@ -116,5 +113,13 @@ "lang_active_this": "This is the current language of the console.", "lang_set_conf": "Would you like to set this language as the console's language? The console will reboot after doing so.", "lang_set_ok": "The console's language was changed. Close this dialog to reboot.", - "lang_set_error": "An error ocurred attempting to change the console's language" + "lang_set_error": "An error ocurred attempting to change the console's language", + "help_title": "uLaunch help", + "help_launch": "Press A to launch the selected entry, or to return to it if suspended.", + "help_close": "Press X to close the currently opened title.", + "help_quick": "Hold a stick (L or R-stick) and move it while being held to select an option in the quick menu, then release it to open it.", + "help_multiselect": "Press Y to open the multiselect mode\n(with this mode open, press Y to select/deselect any title, Y to confirm the selection or B to cancel)", + "help_back": "Press B or HOME on any menu (except the startup menu) to return to the main menu.", + "help_minus": "Press Minus (-) on the main menu to swap between the normal menu and the homebrew menu\n(the first swap will take longer due to homebrew scanning!)", + "help_plus": "Press Plus (+) to see uLaunch's information (project version, description...)" } \ No newline at end of file diff --git a/LibraryAppletQMenu/Source/ui/ui_MenuLayout.cpp b/LibraryAppletQMenu/Source/ui/ui_MenuLayout.cpp index 6708a66..16ef7c1 100644 --- a/LibraryAppletQMenu/Source/ui/ui_MenuLayout.cpp +++ b/LibraryAppletQMenu/Source/ui/ui_MenuLayout.cpp @@ -747,8 +747,7 @@ namespace ui void MenuLayout::logo_Click() { - qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "ulaunch_about"), "uLaunch v" + std::string(Q_VERSION) + "\n\n" + cfg::GetLanguageString(config.main_lang, config.default_lang, "ulaunch_desc") + "\n\n" + cfg::GetLanguageString(config.main_lang, config.default_lang, "ulaunch_contribute") + ":\nhttps://github.com/XorTroll/uLaunch", { cfg::GetLanguageString(config.main_lang, config.default_lang, "ok") }, true, "romfs:/LogoLarge.png"); - // qapp->ShowNotification("(-) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_minus") + " | (X) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_x") + " | (Y) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_y") + " | (L), (R), (ZL), (ZR) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_zlr"), 3500); + qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "ulaunch_about"), "uLaunch v" + std::string(Q_VERSION) + "\n\n" + cfg::GetLanguageString(config.main_lang, config.default_lang, "ulaunch_desc") + ":\nhttps://github.com/XorTroll/uLaunch", { cfg::GetLanguageString(config.main_lang, config.default_lang, "ok") }, true, "romfs:/LogoLarge.png"); } void MenuLayout::settings_Click() @@ -1078,7 +1077,16 @@ namespace ui void MenuLayout::HandleShowHelp() { - // ... + std::string msg; + msg += " - " + cfg::GetLanguageString(config.main_lang, config.default_lang, "help_launch") + "\n"; + msg += " - " + cfg::GetLanguageString(config.main_lang, config.default_lang, "help_close") + "\n"; + msg += " - " + cfg::GetLanguageString(config.main_lang, config.default_lang, "help_quick") + "\n"; + msg += " - " + cfg::GetLanguageString(config.main_lang, config.default_lang, "help_multiselect") + "\n"; + msg += " - " + cfg::GetLanguageString(config.main_lang, config.default_lang, "help_back") + "\n"; + msg += " - " + cfg::GetLanguageString(config.main_lang, config.default_lang, "help_minus") + "\n"; + msg += " - " + cfg::GetLanguageString(config.main_lang, config.default_lang, "help_plus") + "\n"; + + qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "help_title"), msg, { cfg::GetLanguageString(config.main_lang, config.default_lang, "ok") }, true); } void MenuLayout::HandleOpenAlbum() diff --git a/LibraryAppletQMenu/Source/ui/ui_QMenuApplication.cpp b/LibraryAppletQMenu/Source/ui/ui_QMenuApplication.cpp index 84af2e7..b2edd3f 100644 --- a/LibraryAppletQMenu/Source/ui/ui_QMenuApplication.cpp +++ b/LibraryAppletQMenu/Source/ui/ui_QMenuApplication.cpp @@ -117,7 +117,9 @@ namespace ui void QMenuApplication::NotifyEndSuspended() { - this->status = {}; + // Blanking the whole status would also blank the selected user... + this->status.input = {}; + this->status.app_id = 0; } bool QMenuApplication::LaunchFailed() diff --git a/LibraryAppletQMenu/Source/ui/ui_StartupLayout.cpp b/LibraryAppletQMenu/Source/ui/ui_StartupLayout.cpp index c69f65f..9e616a8 100644 --- a/LibraryAppletQMenu/Source/ui/ui_StartupLayout.cpp +++ b/LibraryAppletQMenu/Source/ui/ui_StartupLayout.cpp @@ -41,6 +41,7 @@ namespace ui qapp->FadeOut(); qapp->LoadMenu(); qapp->FadeIn(); + qapp->ShowNotification(cfg::GetLanguageString(config.main_lang, config.default_lang, "menu_quick_info"), 3000); // Show for 3s } } diff --git a/Makefile b/Makefile index 13c64c0..50db180 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -export Q_VERSION := 0.1 +export Q_VERSION := 0.2 .PHONY: all dev clean diff --git a/README.md b/README.md index f67abd2..6bf8c47 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -> Custom, open-source replacement/reimplementation for Nintendo Switch's HOME menu (qlaunch), extending it with amazing, homebrew-orienteed functionality! +> Custom, open-source replacement/reimplementation for Nintendo Switch's HOME menu (qlaunch), extending it with amazing, homebrew-oriented functionality! drawing drawing @@ -8,7 +8,7 @@ drawing drawing -uLaunch is a very ambitious project, consisting on two custom library applets, a custom system application and a custom system applet, in order to replace the console's **HOME menu** with a custom, homebrew-orienteed one. +uLaunch is a very ambitious project, consisting on two custom library applets, a custom system application and a custom system applet, in order to replace the console's **HOME menu** with a custom, homebrew-oriented one. - This isn't any kind of HOME menu extension, injection, patch, etc. uLaunch is a **complete** reimplementation, 100% open-source, which also takes over eShop and Parental control applets and flog system title (all of them are pretty much useless with this reimpl) for its extended functionality. @@ -16,7 +16,13 @@ uLaunch is a very ambitious project, consisting on two custom library applets, a - For those who are interested in how the UI was done, this project is, like [Goldleaf](https://github.com/XorTroll/Goldleaf), a good example of how powerful [Plutonium libraries](https://github.com/XorTroll/Plutonium) can be in order to make beautiful UIs. -## For more detailed information about the whole project (themeing too), check its [wiki](/wiki)! +## Get it from [here](https://github.com/XorTroll/uLaunch/releases/latest)! + +### Want to create **custom forwarders** (eg. RetroArch ones)? check **uViewer** tool in [latest releases](https://github.com/XorTroll/uLaunch/releases/latest)! + +### Want to find **themes** for uLaunch? Check [r/uLaunchThemes subreddit](https://www.reddit.com/r/uLaunchThemes/)! + +### For more detailed **information** about the whole project (*themeing* too), check its [wiki](https://github.com/XorTroll/uLaunch/wiki)! ## Features @@ -42,16 +48,6 @@ uLaunch is a very ambitious project, consisting on two custom library applets, a - Show user's page (in order to edit nickname, icon, friends...) -**List of not (yet) implemented HOME menu features**: - -- Controller managing - -- Album - -- ~~Periodical play report sending (so long, telemetry!)~~ - -This is the amount of features uLaunch contains, compared to the original HOME menu: - - *Homebrew support* - Launching as applets (no need of **Album**!) @@ -82,7 +78,7 @@ This is the amount of features uLaunch contains, compared to the original HOME m - Web browsing (via web-applet) directly from the main menu! - - **Foreground capturing** from PC itself (*Windows*-only) via USB-C cable and *uViewer*! + - **Console screen capturing** from PC itself (*Windows*-only) via USB-C cable and *uViewer* tool! ## Disclaimer @@ -102,14 +98,14 @@ Using `make dev` instead of regular `make` will compile uLaunch in debug mode, w ## Credits -- Several scene developers for help with small issues or features. - - SciresM for [libstratosphere](https://github.com/Atmosphere-NX/libstratosphere). -- Switchbrew team for libnx and [hbloader](https://github.com/switchbrew/nx-hbloader), the base of *QHbTarget projects (they're some useful wrappers of hbloader in the end) +- Switchbrew team for libnx and [nx-hbloader](https://github.com/switchbrew/nx-hbloader), the base of *QHbTarget processes (they're just simple wrappers of hbloader in the end) - C4Phoenix for the amazing design of this project's logo. - [Icons8](https://icons8.com/) website for a big part of the icons used by the default style. +- Several scene developers for their help with small issues or features. + - Everyone from Discord or other places whose suggestions made this project a little bit better :) \ No newline at end of file