Skip to content

Commit

Permalink
Add basic lockscreen, verify support, fix several bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
XorTroll committed Aug 11, 2024
1 parent 940b7d2 commit 73a2202
Show file tree
Hide file tree
Showing 63 changed files with 2,974 additions and 886 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
</a>
</p>

### Want to find **themes** for uLaunch? Check the [r/uLaunchThemes subreddit](https://www.reddit.com/r/uLaunchThemes/) or the [Discord server](https://discord.gg/3KpFyaH)!
### Want to find **themes** for uLaunch? Check the `ulaunch-themes` channel on our [Discord server](https://discord.gg/3KpFyaH)!

### Want to make your own uLaunch **themes**? Check our [web theme editor](https://xortroll.github.io/uLaunch/) or the [wiki](https://github.com/XorTroll/uLaunch/wiki)!

Expand All @@ -56,6 +56,7 @@
- [Installing uLaunch](#installing-ulaunch)
- [Removing uLaunch](#removing-ulaunch)
- [FAQ](#faq)
- [Translating](#translating)
- [Components](#components)
- [uSystem](#usystem)
- [uMenu](#umenu)
Expand Down Expand Up @@ -240,6 +241,18 @@ List of not implemented official HOME menu features:

- Aside from the two excuses above, there is always room for further optimizations in uLaunch's code. Feel free to submit any issues of excessive lag/slowdowns, I'll do my best to improve it :)

## Translating

Translations for uLaunch are always welcome!

The files to be translated are [uMenu translations](https://github.com/XorTroll/uLaunch/blob/unew/projects/uMenu/romfs/lang/en.json) and [uManager translations](https://github.com/XorTroll/uLaunch/blob/unew/projects/uManager/romfs/lang/en.json). They are pretty straightforward to understand, just JSON files with English sentences meant to be translated to **any language officially supported by the Nintendo Switch**.

Character `\n` is a new-line escape (indicates a new line) and must remain unchanged. Punctuation marks (mainly dots at the end of sentences, questions, double dots) must be respected, with perhaphs the exception of commas in the middle of sentences.

Feel free to open pull requests for translations, but it's better to keep contact with me through [Discord](https://discord.gg/3KpFyaH).

As I work on new features and new strings are needed, I will manually add them as English on other language files to keep support.

## Components

### uSystem
Expand Down Expand Up @@ -354,6 +367,6 @@ In order to only build a certain subproject, you can run `make` plus the subproj

- Several scene developers for their help with small issues or features.

- uMenu/uManager translations: [DDinghoya](https://github.com/DDinghoya) for Korean, [NedcloarBR](https://github.com/NedcloarBR) for Brazilian Portuguese
- uMenu/uManager translations: [DDinghoya](https://github.com/DDinghoya) for Korean, [NedcloarBR](https://github.com/NedcloarBR) for Brazilian Portuguese, [Gabriele73](https://github.com/Gabriele73) for Italian

- Everyone from my Discord and other places whose suggestions made this project a little bit better! Specially all the testers for being essential in reporting bugs and helping a lot with the project's development <3
Binary file added assets/default-theme/Main/EntryIcon/Amiibo.xcf
Binary file not shown.
Binary file added assets/default-theme/Main/OverIcon/Corrupted.xcf
Binary file not shown.
Binary file added assets/default-theme/Main/OverIcon/Gamecard.xcf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added assets/orig/Empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/orig/Update.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added default-theme/ui/Main/EntryIcon/Amiibo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added default-theme/ui/Main/OverIcon/Corrupted.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added default-theme/ui/Main/OverIcon/Gamecard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added default-theme/ui/Main/OverIcon/NeedsUpdate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added default-theme/ui/Main/OverIcon/NotLaunchable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 39 additions & 3 deletions default-theme/ui/UI.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,51 @@
}
},
"settings_menu": {
"info_text": {
"menu_text": {
"x": 0,
"y": 37,
"y": 25,
"h_align": "center",
"font_size": "large"
},
"submenu_text": {
"x": 0,
"y": 70,
"h_align": "center",
"font_size": "medium"
},
"settings_menu": {
"x": 75,
"y": 120
"y": 180
}
},
"lockscreen_menu": {
"info_text": {
"h_align": "center",
"v_align": "center",
"font_size": "large"
},
"connection_top_icon": {
"x": 120,
"y": 52
},
"time_text": {
"x": 262,
"y": 105,
"font_size": "medium"
},
"date_text": {
"x": 262,
"y": 68,
"font_size": "small"
},
"battery_text": {
"x": 1612,
"y": 60,
"font_size": "small"
},
"battery_top_icon": {
"x": 1590,
"y": 65
}
}
}
Binary file modified docs/udesigner.data
Binary file not shown.
14 changes: 7 additions & 7 deletions docs/udesigner.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ if (ENVIRONMENT_IS_NODE) {

// --pre-jses are emitted after the Module integration code, so that they can
// refer to Module (if they choose; they can also define Module)
// include: /tmp/tmp1069syv8.js
// include: /tmp/tmp_90qdbgt.js

if (!Module.expectedDataFileDownloads) {
Module.expectedDataFileDownloads = 0;
Expand Down Expand Up @@ -216,25 +216,25 @@ Module['FS_createPath']("/", "assets", true, true);
}

}
loadPackage({"files": [{"filename": "/assets/FontExtended.ttf", "start": 0, "end": 102428}, {"filename": "/assets/FontStandard.ttf", "start": 102428, "end": 2193280}, {"filename": "/assets/Logo.png", "start": 2193280, "end": 2210489}, {"filename": "/assets/default-theme.zip", "start": 2210489, "end": 2603524}], "remote_package_size": 2603524});
loadPackage({"files": [{"filename": "/assets/FontExtended.ttf", "start": 0, "end": 102428}, {"filename": "/assets/FontStandard.ttf", "start": 102428, "end": 2193280}, {"filename": "/assets/Logo.png", "start": 2193280, "end": 2210489}, {"filename": "/assets/default-theme.zip", "start": 2210489, "end": 2626318}], "remote_package_size": 2626318});

})();

// end include: /tmp/tmp1069syv8.js
// include: /tmp/tmpoa2hxxve.js
// end include: /tmp/tmp_90qdbgt.js
// include: /tmp/tmpg0ofgdo3.js

// All the pre-js content up to here must remain later on, we need to run
// it.
if (Module['$ww'] || (typeof ENVIRONMENT_IS_PTHREAD != 'undefined' && ENVIRONMENT_IS_PTHREAD)) Module['preRun'] = [];
var necessaryPreJSTasks = Module['preRun'].slice();
// end include: /tmp/tmpoa2hxxve.js
// include: /tmp/tmpx50pwn30.js
// end include: /tmp/tmpg0ofgdo3.js
// include: /tmp/tmpiu8r_zac.js

if (!Module['preRun']) throw 'Module.preRun should exist because file support used it; did a pre-js delete it?';
necessaryPreJSTasks.forEach((task) => {
if (Module['preRun'].indexOf(task) < 0) throw 'All preRun tasks that exist before user pre-js code should remain after; did you replace Module or modify Module.preRun?';
});
// end include: /tmp/tmpx50pwn30.js
// end include: /tmp/tmpiu8r_zac.js


// Sometimes an existing Module object exists with properties
Expand Down
Binary file modified docs/udesigner.wasm
Binary file not shown.
31 changes: 26 additions & 5 deletions libs/uCommon/include/ul/cfg/cfg_Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ namespace ul::cfg {
MenuTakeoverProgramId,
HomebrewAppletTakeoverProgramId,
HomebrewApplicationTakeoverApplicationId,
ViewerUsbEnabled,
UsbScreenCaptureEnabled,
ActiveThemeName,
MenuEntryHeightCount
MenuEntryHeightCount,
LockscreenEnabled
};

enum class ConfigEntryType : u8 {
Expand Down Expand Up @@ -165,7 +166,7 @@ namespace ul::cfg {
return false;
}
}
case ConfigEntryId::ViewerUsbEnabled: {
case ConfigEntryId::UsbScreenCaptureEnabled: {
if constexpr(std::is_same_v<T, bool>) {
new_entry.header.type = ConfigEntryType::Bool;
new_entry.header.size = sizeof(t);
Expand Down Expand Up @@ -198,6 +199,17 @@ namespace ul::cfg {
return false;
}
}
case ConfigEntryId::LockscreenEnabled: {
if constexpr(std::is_same_v<T, bool>) {
new_entry.header.type = ConfigEntryType::Bool;
new_entry.header.size = sizeof(t);
new_entry.bool_value = t;
break;
}
else {
return false;
}
}
}
this->entries.push_back(std::move(new_entry));
return true;
Expand Down Expand Up @@ -243,7 +255,7 @@ namespace ul::cfg {
return false;
}
}
case ConfigEntryId::ViewerUsbEnabled: {
case ConfigEntryId::UsbScreenCaptureEnabled: {
if constexpr(std::is_same_v<T, bool>) {
// Disabled by default, it might interfer with other homebrews
out_t = false;
Expand All @@ -255,7 +267,7 @@ namespace ul::cfg {
}
case ConfigEntryId::ActiveThemeName: {
if constexpr(std::is_same_v<T, std::string>) {
// Empty by default
// None (empty) by default
out_t = "";
return true;
}
Expand All @@ -272,6 +284,15 @@ namespace ul::cfg {
return false;
}
}
case ConfigEntryId::LockscreenEnabled: {
if constexpr(std::is_same_v<T, bool>) {
out_t = false;
return true;
}
else {
return false;
}
}
}
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion libs/uCommon/include/ul/menu/menu_Cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace ul::menu {

void CacheHomebrew(const std::string &hb_base_path = RootHomebrewPath);
void CacheApplications(const std::vector<NsApplicationRecord> &records);
void CacheSingleApplication(const u64 app_id);
bool CacheSingleApplication(const u64 app_id);

inline std::string GetApplicationCacheIconPath(const u64 app_id) {
return fs::JoinPath(ApplicationCachePath, util::FormatProgramId(app_id) + ".jpg");
Expand Down
50 changes: 23 additions & 27 deletions libs/uCommon/include/ul/menu/menu_Entries.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

#pragma once
#include <ul/loader/loader_TargetTypes.hpp>
#include <ul/os/os_Applications.hpp>
#include <ul/fs/fs_Stdio.hpp>
#include <ul/ul_Include.hpp>
#include <vector>
Expand All @@ -18,35 +19,25 @@ namespace ul::menu {
SpecialEntrySettings,
SpecialEntryThemes,
SpecialEntryControllers,
SpecialEntryAlbum
SpecialEntryAlbum,
SpecialEntryAmiibo
};

struct EntryApplicationInfo {
u64 app_id;
NsApplicationRecord record;
NsApplicationContentMetaStatus meta_status;
NsApplicationView view;
u32 version;
u32 launch_required_version;

inline bool IsInstalledNew() const {
return this->record.type == 0x03;
template<os::ApplicationViewFlag Flag>
inline constexpr bool HasViewFlag() const {
return (view.flags & static_cast<u32>(Flag)) != 0;
}

inline bool IsInstalled() const {
return this->record.type == 0x10;
inline bool NeedsUpdate() const {
return this->launch_required_version > this->version;
}

inline bool IsRunning() const {
return this->record.type == 0x0; // Not really an ideal state, might be after a uLaunch crash, but whatever
}

inline bool IsLaunchable() const {
return this->IsInstalled() || this->IsInstalledNew() || this->IsRunning();
}

/* TODO (new)
inline bool IsGamecard() const {
return this->meta_status.storageID == NcmStorageId_GameCard;
}
*/
};

struct EntryHomebrewInfo {
Expand Down Expand Up @@ -97,7 +88,8 @@ namespace ul::menu {
|| this->Is<EntryType::SpecialEntrySettings>()
|| this->Is<EntryType::SpecialEntryThemes>()
|| this->Is<EntryType::SpecialEntryControllers>()
|| this->Is<EntryType::SpecialEntryAlbum>();
|| this->Is<EntryType::SpecialEntryAlbum>()
|| this->Is<EntryType::SpecialEntryAmiibo>();
}

inline bool operator<(const Entry &other) const {
Expand All @@ -109,7 +101,7 @@ namespace ul::menu {
}

void TryLoadControlData();
void ReloadApplicationInfo();
void ReloadApplicationInfo(const bool force_reload_records_views = true);

void MoveTo(const std::string &new_folder_path);
bool MoveToIndex(const u32 new_index);
Expand All @@ -128,13 +120,17 @@ namespace ul::menu {
std::vector<Entry> Remove();
};

void InitializeEntries();
void EnsureApplicationEntry(const NsApplicationRecord &app_record);
void SetLoadApplicationEntryVersions(const bool load);

void InitializeEntries();
std::vector<Entry> LoadEntries(const std::string &path);

Entry CreateFolderEntry(const std::string &base_path, const std::string &folder_name, const u32 index);
Entry CreateHomebrewEntry(const std::string &base_path, const std::string &nro_path, const std::string &nro_argv, const u32 index);
void DeleteApplicationEntry(const u64 app_id, const std::string &path);
void EnsureApplicationEntry(const NsApplicationRecord &app_record);
Entry CreateFolderEntry(const std::string &base_path, const std::string &folder_name, const s32 index = -1);
Entry CreateHomebrewEntry(const std::string &base_path, const std::string &nro_path, const std::string &nro_argv, const s32 index = -1);
Entry CreateSpecialEntry(const std::string &base_path, const EntryType type, const s32 index = -1);
void DeleteApplicationEntryRecursively(const u64 app_id, const std::string &path);

void ReloadApplicationEntryInfos(std::vector<Entry> &entries);

}
10 changes: 8 additions & 2 deletions libs/uCommon/include/ul/os/os_Applications.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@

namespace ul::os {

constexpr u32 MaxApplicationCount = 64000;
enum class ApplicationViewFlag : u32 {
Valid = BIT(0),
GameCardApplication = BIT(6),
GameCardApplicationAccessible = BIT(7),
Launchable = BIT(8),
NeedsVerify = BIT(13)
};

std::vector<NsApplicationRecord> ListApplicationRecords();
Result GetApplicationContentMetaStatus(const u64 app_id, NsApplicationContentMetaStatus &out_status);
std::vector<NsApplicationView> ListApplicationViews(const std::vector<NsApplicationRecord> &base_records);

}
Loading

0 comments on commit 73a2202

Please sign in to comment.