mirror of
https://github.com/XorTroll/uLaunch
synced 2024-11-23 04:13:18 +00:00
Some QoL changes
This commit is contained in:
parent
1dc90d0fe5
commit
6d7b4913e7
17 changed files with 179 additions and 150 deletions
|
@ -4,6 +4,34 @@
|
|||
|
||||
namespace am
|
||||
{
|
||||
namespace controller
|
||||
{
|
||||
struct InitialArg
|
||||
{
|
||||
u32 this_size;
|
||||
u32 unk1;
|
||||
bool unk2; // unk2 (and unk3?) need to be true for controller to launch
|
||||
bool unk3;
|
||||
u8 mode; // Changing this doesn't seem to affect, but this is the mode according to SDK RE...?
|
||||
bool unk4;
|
||||
u64 controller_type;
|
||||
} PACKED;
|
||||
|
||||
struct MainArg
|
||||
{
|
||||
u8 min_player_count;
|
||||
u8 max_player_count;
|
||||
bool take_over_connection;
|
||||
bool left_justify;
|
||||
bool permit_dual_joy;
|
||||
bool single_mode;
|
||||
bool use_colors;
|
||||
u32 colors[4];
|
||||
bool use_controller_names;
|
||||
char controller_names[4][0x80];
|
||||
} PACKED;
|
||||
}
|
||||
|
||||
bool LibraryAppletIsActive();
|
||||
bool LibraryAppletIsQMenu();
|
||||
void LibraryAppletTerminate();
|
||||
|
@ -11,7 +39,21 @@ namespace am
|
|||
Result LibraryAppletSend(void *data, size_t size);
|
||||
Result LibraryAppletRead(void *data, size_t size);
|
||||
Result WebAppletStart(WebCommonConfig *web);
|
||||
Result LibraryAppletQMenuLaunchAnd(AppletId id, u32 la_version, void *in_data, size_t in_size, void *out_data, size_t out_size, std::function<bool()> on_wait);
|
||||
Result LibraryAppletQMenuLaunchWith(AppletId id, u32 la_version, std::function<void(AppletHolder*)> on_prepare, std::function<void(AppletHolder*)> on_finish, std::function<bool()> on_wait);
|
||||
|
||||
inline Result LibraryAppletQMenuLaunchWithSimple(AppletId id, u32 la_version, void *in_data, size_t in_size, void *out_data, size_t out_size, std::function<bool()> on_wait)
|
||||
{
|
||||
return LibraryAppletQMenuLaunchWith(id, la_version,
|
||||
[&](AppletHolder *h)
|
||||
{
|
||||
if(in_size > 0) libappletPushInData(h, in_data, in_size);
|
||||
},
|
||||
[&](AppletHolder *h)
|
||||
{
|
||||
if(out_size > 0) libappletPopOutData(h, out_data, out_size, NULL);
|
||||
}, on_wait);
|
||||
}
|
||||
|
||||
AppletId LibraryAppletGetId();
|
||||
|
||||
static constexpr AppletId QMenuAppletId = AppletId_shop;
|
||||
|
|
|
@ -27,7 +27,6 @@ namespace am
|
|||
LaunchApplication,
|
||||
ResumeApplication,
|
||||
TerminateApplication,
|
||||
GetSuspendedInfo,
|
||||
LaunchHomebrewLibApplet,
|
||||
LaunchHomebrewApplication,
|
||||
OpenWebPage,
|
||||
|
@ -39,15 +38,16 @@ namespace am
|
|||
RemoveUserPassword
|
||||
};
|
||||
|
||||
struct QSuspendedInfo
|
||||
struct QDaemonStatus
|
||||
{
|
||||
u128 selected_user;
|
||||
hb::TargetInput input; // Set if homebrew (via flog takeover) is suspended
|
||||
u64 app_id; // Set if any title (other than flog) is suspended
|
||||
};
|
||||
|
||||
#define AM_QDAEMON_SERVICE_NAME "qdmnsrv"
|
||||
|
||||
Result QDaemon_LaunchQMenu(QMenuStartMode mode);
|
||||
Result QDaemon_LaunchQMenu(QMenuStartMode mode, QDaemonStatus status);
|
||||
Result QDaemon_LaunchQHbTarget(hb::TargetInput input);
|
||||
|
||||
Result QLibraryAppletReadStorage(void *data, size_t size);
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace cfg
|
|||
#define CFG_LANG_DEFAULT "romfs:/LangDefault.json"
|
||||
#define CFG_CONFIG_JSON Q_BASE_SD_DIR "/config.json"
|
||||
|
||||
ResultWith<TitleList> LoadTitleList(bool cache);
|
||||
TitleList LoadTitleList(bool cache);
|
||||
std::vector<TitleRecord> QueryAllHomebrew(std::string base = "sdmc:/switch");
|
||||
std::string GetRecordIconPath(TitleRecord record);
|
||||
RecordInformation GetRecordInformation(TitleRecord record);
|
||||
|
|
|
@ -14,9 +14,43 @@ namespace fs
|
|||
void DeleteDirectory(std::string path);
|
||||
void DeleteFile(std::string path);
|
||||
|
||||
bool WriteFile(std::string path, void *data, size_t size, bool overwrite);
|
||||
bool ReadFile(std::string path, void *data, size_t size);
|
||||
size_t GetFileSize(std::string path);
|
||||
inline bool WriteFile(std::string path, void *data, size_t size, bool overwrite)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), overwrite ? "wb" : "ab+");
|
||||
if(f)
|
||||
{
|
||||
fwrite(data, 1, size, f);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool ReadFile(std::string path, void *data, size_t size)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), "rb");
|
||||
if(f)
|
||||
{
|
||||
fread(data, 1, size, f);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline size_t GetFileSize(std::string path)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), "rb");
|
||||
if(f)
|
||||
{
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t fsz = ftell(f);
|
||||
rewind(f);
|
||||
fclose(f);
|
||||
return fsz;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MoveFile(std::string p1, std::string p2);
|
||||
void CopyFile(std::string p, std::string np);
|
||||
|
|
|
@ -13,5 +13,5 @@ namespace os
|
|||
return (app_id == OS_FLOG_APP_ID);
|
||||
}
|
||||
|
||||
ResultWith<std::vector<cfg::TitleRecord>> QueryInstalledTitles(bool cache);
|
||||
std::vector<cfg::TitleRecord> QueryInstalledTitles(bool cache);
|
||||
}
|
|
@ -57,7 +57,7 @@ namespace am
|
|||
return LibraryAppletStart(AppletId_web, web->version, &web->arg, sizeof(web->arg));
|
||||
}
|
||||
|
||||
Result LibraryAppletQMenuLaunchAnd(AppletId id, u32 la_version, void *in_data, size_t in_size, void *out_data, size_t out_size, std::function<bool()> on_wait)
|
||||
Result LibraryAppletQMenuLaunchWith(AppletId id, u32 la_version, std::function<void(AppletHolder*)> on_prepare, std::function<void(AppletHolder*)> on_finish, std::function<bool()> on_wait)
|
||||
{
|
||||
if(LibraryAppletIsActive()) LibraryAppletTerminate();
|
||||
appletHolderClose(&applet_holder);
|
||||
|
@ -65,10 +65,7 @@ namespace am
|
|||
libappletArgsCreate(&largs, la_version);
|
||||
R_TRY(appletCreateLibraryApplet(&applet_holder, id, LibAppletMode_AllForeground));
|
||||
R_TRY(libappletArgsPush(&largs, &applet_holder));
|
||||
if(in_size > 0)
|
||||
{
|
||||
R_TRY(LibraryAppletSend(in_data, in_size));
|
||||
}
|
||||
on_prepare(&applet_holder);
|
||||
R_TRY(appletHolderStart(&applet_holder));
|
||||
while(true)
|
||||
{
|
||||
|
@ -80,7 +77,7 @@ namespace am
|
|||
}
|
||||
svcSleepThread(10'000'000);
|
||||
}
|
||||
if(out_size > 0) libappletPopOutData(&applet_holder, out_data, out_size, NULL);
|
||||
on_finish(&applet_holder);
|
||||
appletHolderClose(&applet_holder);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace am
|
|||
|
||||
#define Q_AM_WAIT(expr) Q_AM_WAIT_WITH(rc = (expr);)
|
||||
|
||||
Result QDaemon_LaunchQMenu(QMenuStartMode mode)
|
||||
Result QDaemon_LaunchQMenu(QMenuStartMode mode, QDaemonStatus status)
|
||||
{
|
||||
return LibraryAppletStart(QMenuAppletId, (u32)mode, NULL, 0);
|
||||
return LibraryAppletStart(QMenuAppletId, (u32)mode, &status, sizeof(status));
|
||||
}
|
||||
|
||||
Result QDaemon_LaunchQHbTarget(hb::TargetInput input)
|
||||
|
|
|
@ -565,19 +565,19 @@ namespace cfg
|
|||
return title_found;
|
||||
}
|
||||
|
||||
ResultWith<TitleList> LoadTitleList(bool cache)
|
||||
TitleList LoadTitleList(bool cache)
|
||||
{
|
||||
TitleList list = {};
|
||||
|
||||
// Installed titles first
|
||||
auto [rc, titles] = os::QueryInstalledTitles(cache);
|
||||
auto titles = os::QueryInstalledTitles(cache);
|
||||
|
||||
FS_FOR(std::string(Q_ENTRIES_PATH), name, path,
|
||||
{
|
||||
auto [rc, entry] = util::LoadJSONFromFile(path);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
TitleType type = (TitleType)entry.value("type", 0u);
|
||||
TitleType type = (TitleType)entry.value("type", 0);
|
||||
if(type == TitleType::Installed)
|
||||
{
|
||||
std::string appidstr = entry.value("application_id", "");
|
||||
|
@ -632,6 +632,7 @@ namespace cfg
|
|||
rec.author = entry.value("author", "");
|
||||
rec.version = entry.value("version", "");
|
||||
|
||||
// Only cache homebrew added to main menu.
|
||||
CacheHomebrew(nropath);
|
||||
std::string argv = entry.value("nro_argv", "");
|
||||
strcpy(rec.nro_target.nro_path, nropath.c_str());
|
||||
|
@ -639,7 +640,7 @@ namespace cfg
|
|||
std::string folder = entry.value("folder", "");
|
||||
rec.sub_folder = folder;
|
||||
rec.icon = entry.value("icon", "");
|
||||
// Homebrew is cache'd when querying it, so no caching here.
|
||||
|
||||
if(folder.empty()) list.root.titles.push_back(rec);
|
||||
else
|
||||
{
|
||||
|
@ -663,7 +664,7 @@ namespace cfg
|
|||
list.root.titles.push_back(title);
|
||||
}
|
||||
|
||||
return SuccessResultWith(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
std::string GetTitleCacheIconPath(u64 app_id)
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace db
|
|||
if(fs::ExistsFile(filename)) return RES_VALUE(Db, PasswordAlreadyExists);
|
||||
|
||||
if(!fs::WriteFile(filename, &password, sizeof(password), true)) return RES_VALUE(Db, PasswordWriteFail);
|
||||
db::Commit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <fs/fs_Stdio.hpp>
|
||||
#include <util/util_String.hpp>
|
||||
#include <db/db_Save.hpp>
|
||||
|
||||
namespace fs
|
||||
{
|
||||
|
@ -23,77 +22,31 @@ namespace fs
|
|||
void CreateDirectory(std::string path)
|
||||
{
|
||||
mkdir(path.c_str(), 777);
|
||||
db::Commit();
|
||||
}
|
||||
|
||||
void CreateFile(std::string path)
|
||||
{
|
||||
fsdevCreateFile(path.c_str(), 0, 0);
|
||||
db::Commit();
|
||||
}
|
||||
|
||||
void CreateConcatenationFile(std::string path)
|
||||
{
|
||||
fsdevCreateFile(path.c_str(), 0, FS_CREATE_BIG_FILE);
|
||||
db::Commit();
|
||||
}
|
||||
|
||||
void DeleteDirectory(std::string path)
|
||||
{
|
||||
fsdevDeleteDirectoryRecursively(path.c_str());
|
||||
db::Commit();
|
||||
}
|
||||
|
||||
void DeleteFile(std::string path)
|
||||
{
|
||||
remove(path.c_str());
|
||||
db::Commit();
|
||||
}
|
||||
|
||||
bool WriteFile(std::string path, void *data, size_t size, bool overwrite)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), overwrite ? "wb" : "ab+");
|
||||
if(f)
|
||||
{
|
||||
fwrite(data, 1, size, f);
|
||||
fclose(f);
|
||||
db::Commit();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReadFile(std::string path, void *data, size_t size)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), "rb");
|
||||
if(f)
|
||||
{
|
||||
fread(data, 1, size, f);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t GetFileSize(std::string path)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), "rb");
|
||||
if(f)
|
||||
{
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t fsz = ftell(f);
|
||||
rewind(f);
|
||||
fclose(f);
|
||||
return fsz;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MoveFile(std::string p1, std::string p2)
|
||||
{
|
||||
rename(p1.c_str(), p2.c_str());
|
||||
db::Commit();
|
||||
db::Commit();
|
||||
}
|
||||
|
||||
void CopyFile(std::string p, std::string np)
|
||||
|
@ -119,7 +72,6 @@ namespace fs
|
|||
}
|
||||
delete[] tmp;
|
||||
fclose(outf);
|
||||
db::Commit();
|
||||
}
|
||||
fclose(inf);
|
||||
}
|
||||
|
|
|
@ -4,32 +4,35 @@
|
|||
|
||||
namespace os
|
||||
{
|
||||
ResultWith<std::vector<cfg::TitleRecord>> QueryInstalledTitles(bool cache)
|
||||
std::vector<cfg::TitleRecord> QueryInstalledTitles(bool cache)
|
||||
{
|
||||
std::vector<cfg::TitleRecord> titles;
|
||||
NsApplicationRecord *recordbuf = new NsApplicationRecord[OS_MAX_TITLE_COUNT]();
|
||||
size_t record_count = 0;
|
||||
R_TRY_WITH(nsListApplicationRecord(recordbuf, OS_MAX_TITLE_COUNT * sizeof(NsApplicationRecord), 0, &record_count), titles);
|
||||
for(u32 i = 0; i < record_count; i++)
|
||||
auto rc = nsListApplicationRecord(recordbuf, OS_MAX_TITLE_COUNT * sizeof(NsApplicationRecord), 0, &record_count);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
cfg::TitleRecord rec = {};
|
||||
rec.app_id = recordbuf[i].titleID;
|
||||
rec.title_type = (u32)cfg::TitleType::Installed;
|
||||
if(rec.app_id == 0) continue;
|
||||
if(cache)
|
||||
for(u32 i = 0; i < record_count; i++)
|
||||
{
|
||||
NsApplicationControlData control = {};
|
||||
size_t dummy;
|
||||
auto rc = nsGetApplicationControlData(1, rec.app_id, &control, sizeof(NsApplicationControlData), &dummy);
|
||||
if(R_SUCCEEDED(rc))
|
||||
cfg::TitleRecord rec = {};
|
||||
rec.app_id = recordbuf[i].titleID;
|
||||
rec.title_type = (u32)cfg::TitleType::Installed;
|
||||
if(rec.app_id == 0) continue;
|
||||
if(cache)
|
||||
{
|
||||
auto fname = cfg::GetTitleCacheIconPath(rec.app_id);
|
||||
fs::WriteFile(fname, control.icon, sizeof(control.icon), true);
|
||||
NsApplicationControlData control = {};
|
||||
size_t dummy;
|
||||
auto rc = nsGetApplicationControlData(1, rec.app_id, &control, sizeof(NsApplicationControlData), &dummy);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
auto fname = cfg::GetTitleCacheIconPath(rec.app_id);
|
||||
fs::WriteFile(fname, control.icon, sizeof(control.icon), true);
|
||||
}
|
||||
}
|
||||
titles.push_back(rec);
|
||||
}
|
||||
titles.push_back(rec);
|
||||
}
|
||||
delete[] recordbuf;
|
||||
return SuccessResultWith(titles);
|
||||
return titles;
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ namespace ui
|
|||
|
||||
void OnLoad() override;
|
||||
|
||||
void SetStartMode(am::QMenuStartMode mode);
|
||||
void SetInformation(am::QMenuStartMode mode, am::QDaemonStatus status);
|
||||
void LoadMenu();
|
||||
void LoadStartupMenu();
|
||||
void LoadThemeMenu();
|
||||
|
@ -27,7 +27,7 @@ namespace ui
|
|||
bool IsSuspended();
|
||||
bool IsTitleSuspended();
|
||||
bool IsHomebrewSuspended();
|
||||
std::string GetSuspendedHomebrewPath();
|
||||
bool EqualsSuspendedHomebrewPath(std::string path);
|
||||
u64 GetSuspendedApplicationId();
|
||||
void NotifyEndSuspended();
|
||||
bool LaunchFailed();
|
||||
|
@ -86,8 +86,7 @@ namespace ui
|
|||
SettingsMenuLayout::Ref settingsMenuLayout;
|
||||
LanguagesMenuLayout::Ref languagesMenuLayout;
|
||||
pu::ui::extras::Toast::Ref notifToast;
|
||||
am::QSuspendedInfo suspinfo;
|
||||
u128 selected_user;
|
||||
am::QDaemonStatus status;
|
||||
JSON uijson;
|
||||
JSON bgmjson;
|
||||
bool bgm_loop;
|
||||
|
|
|
@ -64,10 +64,14 @@ int main()
|
|||
auto [rc, smode] = am::QMenu_ProcessInput();
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
am::QDaemonStatus status = {};
|
||||
// Information block sent as an extra storage to QMenu.
|
||||
am::QLibraryAppletReadStorage(&status, sizeof(status));
|
||||
|
||||
app_buf = new u8[RawRGBAScreenBufferSize]();
|
||||
qmenu::Initialize();
|
||||
auto [_rc, menulist] = cfg::LoadTitleList(true);
|
||||
list = menulist;
|
||||
|
||||
list = cfg::LoadTitleList(true);
|
||||
|
||||
if(smode != am::QMenuStartMode::Invalid)
|
||||
{
|
||||
|
@ -88,7 +92,7 @@ int main()
|
|||
config.main_lang = ljson;
|
||||
}
|
||||
|
||||
qapp->SetStartMode(smode);
|
||||
qapp->SetInformation(smode, status);
|
||||
qapp->Prepare();
|
||||
|
||||
if(smode == am::QMenuStartMode::MenuApplicationSuspended) qapp->Show();
|
||||
|
|
|
@ -303,7 +303,7 @@ namespace ui
|
|||
bool hblaunch = true;
|
||||
if(qapp->IsHomebrewSuspended())
|
||||
{
|
||||
if(std::string(hb.nro_target.nro_path) == qapp->GetSuspendedHomebrewPath())
|
||||
if(qapp->EqualsSuspendedHomebrewPath(hb.nro_target.nro_path))
|
||||
{
|
||||
if(this->mode == 1) this->mode = 2;
|
||||
hblaunch = false;
|
||||
|
@ -321,7 +321,7 @@ namespace ui
|
|||
{
|
||||
if(qapp->IsSuspended())
|
||||
{
|
||||
if(std::string(hb.nro_target.nro_path) == qapp->GetSuspendedHomebrewPath()) this->HandleCloseSuspended();
|
||||
if(qapp->EqualsSuspendedHomebrewPath(hb.nro_target.nro_path)) this->HandleCloseSuspended();
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
|
@ -361,7 +361,7 @@ namespace ui
|
|||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew)
|
||||
{
|
||||
if(std::string(title.nro_target.nro_path) == qapp->GetSuspendedHomebrewPath())
|
||||
if(qapp->EqualsSuspendedHomebrewPath(title.nro_target.nro_path))
|
||||
{
|
||||
if(this->mode == 1) this->mode = 2;
|
||||
titlelaunch = false;
|
||||
|
@ -414,7 +414,7 @@ namespace ui
|
|||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew)
|
||||
{
|
||||
if(std::string(title.nro_target.nro_path) == qapp->GetSuspendedHomebrewPath()) this->HandleCloseSuspended();
|
||||
if(qapp->EqualsSuspendedHomebrewPath(title.nro_target.nro_path)) this->HandleCloseSuspended();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -575,7 +575,7 @@ namespace ui
|
|||
}
|
||||
else
|
||||
{
|
||||
if(qapp->IsHomebrewSuspended()) if(qapp->GetSuspendedHomebrewPath() == std::string(itm.nro_target.nro_path)) set_susp = true;
|
||||
if(qapp->IsHomebrewSuspended()) if(qapp->EqualsSuspendedHomebrewPath(itm.nro_target.nro_path)) set_susp = true;
|
||||
}
|
||||
this->itemsMenu->AddItem(cfg::GetRecordIconPath(itm));
|
||||
if(set_susp)
|
||||
|
@ -964,7 +964,7 @@ namespace ui
|
|||
*(u32*)in = 7; // Type -> ShowMyProfile
|
||||
memcpy((u128*)(in + 0x8), &uid, sizeof(uid));
|
||||
|
||||
am::LibraryAppletQMenuLaunchAnd(AppletId_myPage, 1, in, sizeof(in), NULL, 0, [&]() -> bool
|
||||
am::LibraryAppletQMenuLaunchWithSimple(AppletId_myPage, 1, in, sizeof(in), NULL, 0, [&]() -> bool
|
||||
{
|
||||
return !am::QMenuIsHomePressed();
|
||||
});
|
||||
|
|
|
@ -15,12 +15,6 @@ namespace ui
|
|||
{
|
||||
pu::ui::render::SetDefaultFont(cfg::ProcessedThemeResource(theme, "ui/Font.ttf"));
|
||||
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::GetSuspendedInfo);
|
||||
writer.FinishWrite();
|
||||
am::QMenuCommandResultReader reader;
|
||||
if(reader) this->suspinfo = reader.Read<am::QSuspendedInfo>();
|
||||
reader.FinishRead();
|
||||
|
||||
if(this->IsSuspended())
|
||||
{
|
||||
bool flag;
|
||||
|
@ -53,13 +47,7 @@ namespace ui
|
|||
case am::QMenuStartMode::MenuApplicationSuspended:
|
||||
case am::QMenuStartMode::MenuLaunchFailure:
|
||||
{
|
||||
// Returned from applet/title, QDaemon has the user but we don't, so...
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::GetSelectedUser);
|
||||
writer.FinishWrite();
|
||||
am::QMenuCommandResultReader res;
|
||||
this->selected_user = res.Read<u128>();
|
||||
res.FinishRead();
|
||||
|
||||
// Returned from applet/title
|
||||
this->StartPlayBGM();
|
||||
this->LoadMenu();
|
||||
break;
|
||||
|
@ -70,14 +58,15 @@ namespace ui
|
|||
}
|
||||
}
|
||||
|
||||
void QMenuApplication::SetStartMode(am::QMenuStartMode mode)
|
||||
void QMenuApplication::SetInformation(am::QMenuStartMode mode, am::QDaemonStatus status)
|
||||
{
|
||||
this->stmode = mode;
|
||||
memcpy(&this->status, &status, sizeof(status));
|
||||
}
|
||||
|
||||
void QMenuApplication::LoadMenu()
|
||||
{
|
||||
this->menuLayout->SetUser(this->selected_user);
|
||||
this->menuLayout->SetUser(this->status.selected_user);
|
||||
this->LoadLayout(this->menuLayout);
|
||||
}
|
||||
|
||||
|
@ -113,27 +102,27 @@ namespace ui
|
|||
|
||||
bool QMenuApplication::IsTitleSuspended()
|
||||
{
|
||||
return (this->suspinfo.app_id != 0);
|
||||
return (this->status.app_id > 0);
|
||||
}
|
||||
|
||||
bool QMenuApplication::IsHomebrewSuspended()
|
||||
{
|
||||
return strlen(this->suspinfo.input.nro_path);
|
||||
return strlen(this->status.input.nro_path);
|
||||
}
|
||||
|
||||
std::string QMenuApplication::GetSuspendedHomebrewPath()
|
||||
bool QMenuApplication::EqualsSuspendedHomebrewPath(std::string path)
|
||||
{
|
||||
return this->suspinfo.input.nro_path;
|
||||
return (strcasecmp(this->status.input.nro_path, path.c_str()) == 0);
|
||||
}
|
||||
|
||||
u64 QMenuApplication::GetSuspendedApplicationId()
|
||||
{
|
||||
return this->suspinfo.app_id;
|
||||
return this->status.app_id;
|
||||
}
|
||||
|
||||
void QMenuApplication::NotifyEndSuspended()
|
||||
{
|
||||
this->suspinfo = {};
|
||||
this->status = {};
|
||||
}
|
||||
|
||||
bool QMenuApplication::LaunchFailed()
|
||||
|
@ -170,11 +159,11 @@ namespace ui
|
|||
writer.Write<u128>(user_id);
|
||||
writer.FinishWrite();
|
||||
|
||||
this->selected_user = user_id;
|
||||
this->status.selected_user = user_id;
|
||||
}
|
||||
|
||||
u128 QMenuApplication::GetSelectedUser()
|
||||
{
|
||||
return this->selected_user;
|
||||
return this->status.selected_user;
|
||||
}
|
||||
}
|
|
@ -177,7 +177,7 @@ namespace ui
|
|||
*(u32*)in = 1; // 0 = normal, 1 = qlaunch, 2 = starter?
|
||||
u8 out[8] = {0};
|
||||
|
||||
am::LibraryAppletQMenuLaunchAnd(AppletId_netConnect, 0, in, sizeof(in), out, sizeof(out), [&]() -> bool
|
||||
am::LibraryAppletQMenuLaunchWithSimple(AppletId_netConnect, 0, in, sizeof(in), out, sizeof(out), [&]() -> bool
|
||||
{
|
||||
return !am::QMenuIsHomePressed();
|
||||
});
|
||||
|
|
|
@ -37,13 +37,32 @@ void CommonSleepHandle()
|
|||
appletStartSleepSequence(true);
|
||||
}
|
||||
|
||||
am::QDaemonStatus CreateStatus()
|
||||
{
|
||||
am::QDaemonStatus status = {};
|
||||
cfg::TitleType tmptype = cfg::TitleType::Invalid;
|
||||
if(am::ApplicationIsActive())
|
||||
{
|
||||
tmptype = cfg::TitleType::Installed;
|
||||
if(am::ApplicationGetId() == OS_FLOG_APP_ID) tmptype = cfg::TitleType::Homebrew;
|
||||
}
|
||||
|
||||
if(tmptype == cfg::TitleType::Installed) status.app_id = am::ApplicationGetId();
|
||||
else if(tmptype == cfg::TitleType::Homebrew) memcpy(&status.input, &hbapplaunch_copy, sizeof(hbapplaunch_copy));
|
||||
|
||||
status.selected_user = selected_uid;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void HandleHomeButton()
|
||||
{
|
||||
bool used_to_reopen_menu = false;
|
||||
if(am::LibraryAppletIsActive() && !am::LibraryAppletIsQMenu())
|
||||
{
|
||||
am::LibraryAppletTerminate();
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::Menu);
|
||||
auto status = CreateStatus();
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::Menu, status);
|
||||
return;
|
||||
}
|
||||
if(am::ApplicationIsActive())
|
||||
|
@ -51,7 +70,8 @@ void HandleHomeButton()
|
|||
if(am::ApplicationHasForeground())
|
||||
{
|
||||
am::HomeMenuSetForeground();
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::MenuApplicationSuspended);
|
||||
auto status = CreateStatus();
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::MenuApplicationSuspended, status);
|
||||
used_to_reopen_menu = true;
|
||||
}
|
||||
}
|
||||
|
@ -208,27 +228,6 @@ void HandleQMenuMessage()
|
|||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::GetSuspendedInfo:
|
||||
{
|
||||
reader.FinishRead();
|
||||
|
||||
am::QSuspendedInfo info = {};
|
||||
cfg::TitleType tmptype = cfg::TitleType::Invalid;
|
||||
if(am::ApplicationIsActive())
|
||||
{
|
||||
tmptype = cfg::TitleType::Installed;
|
||||
if(am::ApplicationGetId() == OS_FLOG_APP_ID) tmptype = cfg::TitleType::Homebrew;
|
||||
}
|
||||
|
||||
if(tmptype == cfg::TitleType::Installed) info.app_id = am::ApplicationGetId();
|
||||
else if(tmptype == cfg::TitleType::Homebrew) memcpy(&info.input, &hbapplaunch_copy, sizeof(hbapplaunch_copy));
|
||||
|
||||
am::QDaemonCommandResultWriter writer(0);
|
||||
writer.Write<am::QSuspendedInfo>(info);
|
||||
writer.FinishWrite();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::LaunchHomebrewLibApplet:
|
||||
{
|
||||
hblaunch_flag = reader.Read<hb::TargetInput>();
|
||||
|
@ -366,10 +365,12 @@ namespace qdaemon
|
|||
|
||||
db::Mount(); // Keep qlaunch's savedata always mounted to avoid others to access it.
|
||||
fs::CreateDirectory(Q_BASE_DB_DIR);
|
||||
db::Commit();
|
||||
fs::CreateDirectory(Q_BASE_SD_DIR);
|
||||
fs::CreateDirectory(Q_ENTRIES_PATH);
|
||||
fs::CreateDirectory(Q_THEMES_PATH);
|
||||
fs::CreateDirectory(Q_BASE_DB_DIR "/user");
|
||||
db::Commit();
|
||||
fs::CreateDirectory(Q_BASE_SD_DIR "/title");
|
||||
fs::CreateDirectory(Q_BASE_SD_DIR "/user");
|
||||
fs::CreateDirectory(Q_BASE_SD_DIR "/nro");
|
||||
|
@ -484,7 +485,8 @@ int main()
|
|||
auto config = cfg::EnsureConfig();
|
||||
if(config.viewer_usb_enabled) qdaemon::LaunchForegroundThread();
|
||||
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::StartupScreen);
|
||||
auto status = CreateStatus();
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::StartupScreen, status);
|
||||
|
||||
while(true)
|
||||
{
|
||||
|
@ -502,7 +504,8 @@ int main()
|
|||
if(!am::LibraryAppletIsActive())
|
||||
{
|
||||
// Web applet failed to launch...
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::MenuLaunchFailure);
|
||||
auto status = CreateStatus();
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::MenuLaunchFailure, status);
|
||||
}
|
||||
sth_done = true;
|
||||
memset(&webapplet_flag, 0, sizeof(webapplet_flag));
|
||||
|
@ -541,9 +544,12 @@ int main()
|
|||
{
|
||||
case am::QHbTargetAppletId:
|
||||
case AppletId_web:
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::Menu);
|
||||
{
|
||||
auto status = CreateStatus();
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::Menu, status);
|
||||
sth_done = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -554,7 +560,8 @@ int main()
|
|||
// No matter what is it, we reopen QMenu in launch-error mode.
|
||||
if(!am::ApplicationIsActive() && !am::LibraryAppletIsActive())
|
||||
{
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::MenuLaunchFailure);
|
||||
auto status = CreateStatus();
|
||||
am::QDaemon_LaunchQMenu(am::QMenuStartMode::MenuLaunchFailure, status);
|
||||
}
|
||||
}
|
||||
svcSleepThread(10'000'000);
|
||||
|
|
Loading…
Reference in a new issue