mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-21 22:32:47 +01:00
suyu_cmd: allow launching of applets by supplying FrontendAppletParameters as an arg
Based off of a patch i saved before I nuked my local copy of the suyu repo from gitlab and replaced it with the one local-hosted
This commit is contained in:
parent
42f3dd309e
commit
1ed34b1e47
3 changed files with 140 additions and 87 deletions
|
@ -47,6 +47,75 @@ bool ShouldCreateGuestApplet(AppletId applet_id) {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
||||
WindowSystem& window_system,
|
||||
std::shared_ptr<Applet> caller_applet,
|
||||
AppletId applet_id,
|
||||
LibraryAppletMode mode) {
|
||||
const auto program_id = static_cast<u64>(Service::AM::AppletIdToProgramId(applet_id));
|
||||
if (program_id == 0) {
|
||||
// Unknown applet
|
||||
return {};
|
||||
}
|
||||
|
||||
// TODO: enable other versions of applets
|
||||
enum : u8 {
|
||||
Firmware1400 = 14,
|
||||
Firmware1500 = 15,
|
||||
Firmware1600 = 16,
|
||||
Firmware1700 = 17,
|
||||
};
|
||||
|
||||
auto process = CreateProcess(system, program_id, Firmware1400, Firmware1700);
|
||||
if (!process) {
|
||||
// Couldn't initialize the guest process
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
||||
applet->program_id = program_id;
|
||||
applet->applet_id = applet_id;
|
||||
applet->type = AppletType::LibraryApplet;
|
||||
applet->library_applet_mode = mode;
|
||||
applet->window_visible = mode != LibraryAppletMode::AllForegroundInitiallyHidden;
|
||||
|
||||
auto broker = std::make_shared<AppletDataBroker>(system);
|
||||
applet->caller_applet = caller_applet;
|
||||
applet->caller_applet_broker = broker;
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
|
||||
window_system.TrackApplet(applet, false);
|
||||
|
||||
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
|
||||
}
|
||||
|
||||
std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system,
|
||||
WindowSystem& window_system,
|
||||
std::shared_ptr<Applet> caller_applet,
|
||||
AppletId applet_id,
|
||||
LibraryAppletMode mode) {
|
||||
const auto program_id = static_cast<u64>(Service::AM::AppletIdToProgramId(applet_id));
|
||||
|
||||
auto process = std::make_unique<Process>(system);
|
||||
auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
||||
applet->program_id = program_id;
|
||||
applet->applet_id = applet_id;
|
||||
applet->type = AppletType::LibraryApplet;
|
||||
applet->library_applet_mode = mode;
|
||||
|
||||
auto storage = std::make_shared<AppletDataBroker>(system);
|
||||
applet->caller_applet = caller_applet;
|
||||
applet->caller_applet_broker = storage;
|
||||
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
|
||||
window_system.TrackApplet(applet, false);
|
||||
|
||||
return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AppletProgramId AppletIdToProgramId(AppletId applet_id) {
|
||||
switch (applet_id) {
|
||||
case AppletId::OverlayDisplay:
|
||||
|
@ -94,79 +163,10 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
||||
WindowSystem& window_system,
|
||||
std::shared_ptr<Applet> caller_applet,
|
||||
AppletId applet_id,
|
||||
LibraryAppletMode mode) {
|
||||
const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
|
||||
if (program_id == 0) {
|
||||
// Unknown applet
|
||||
return {};
|
||||
}
|
||||
|
||||
// TODO: enable other versions of applets
|
||||
enum : u8 {
|
||||
Firmware1400 = 14,
|
||||
Firmware1500 = 15,
|
||||
Firmware1600 = 16,
|
||||
Firmware1700 = 17,
|
||||
};
|
||||
|
||||
auto process = CreateProcess(system, program_id, Firmware1400, Firmware1700);
|
||||
if (!process) {
|
||||
// Couldn't initialize the guest process
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
||||
applet->program_id = program_id;
|
||||
applet->applet_id = applet_id;
|
||||
applet->type = AppletType::LibraryApplet;
|
||||
applet->library_applet_mode = mode;
|
||||
applet->window_visible = mode != LibraryAppletMode::AllForegroundInitiallyHidden;
|
||||
|
||||
auto broker = std::make_shared<AppletDataBroker>(system);
|
||||
applet->caller_applet = caller_applet;
|
||||
applet->caller_applet_broker = broker;
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
|
||||
window_system.TrackApplet(applet, false);
|
||||
|
||||
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
|
||||
}
|
||||
|
||||
std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system,
|
||||
WindowSystem& window_system,
|
||||
std::shared_ptr<Applet> caller_applet,
|
||||
AppletId applet_id,
|
||||
LibraryAppletMode mode) {
|
||||
const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
|
||||
|
||||
auto process = std::make_unique<Process>(system);
|
||||
auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
||||
applet->program_id = program_id;
|
||||
applet->applet_id = applet_id;
|
||||
applet->type = AppletType::LibraryApplet;
|
||||
applet->library_applet_mode = mode;
|
||||
|
||||
auto storage = std::make_shared<AppletDataBroker>(system);
|
||||
applet->caller_applet = caller_applet;
|
||||
applet->caller_applet_broker = storage;
|
||||
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
|
||||
window_system.TrackApplet(applet, false);
|
||||
|
||||
return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "ILibraryAppletCreator"},
|
||||
m_window_system{window_system}, m_applet{std::move(applet)} {
|
||||
: ServiceFramework{system_, "ILibraryAppletCreator"}, m_window_system{window_system},
|
||||
m_applet{std::move(applet)} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"},
|
||||
{1, nullptr, "TerminateAllLibraryApplets"},
|
||||
|
|
|
@ -35,4 +35,6 @@ private:
|
|||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
AppletProgramId AppletIdToProgramId(AppletId applet_id);
|
||||
|
||||
} // namespace Service::AM
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
|
@ -23,9 +24,12 @@
|
|||
#include "core/core_timing.h"
|
||||
#include "core/cpu_manager.h"
|
||||
#include "core/crypto/key_manager.h"
|
||||
#include "core/file_sys/content_archive.h"
|
||||
#include "core/file_sys/nca_metadata.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "core/file_sys/vfs/vfs_real.h"
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/hle/service/am/service/library_applet_creator.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "frontend_common/config.h"
|
||||
|
@ -67,7 +71,8 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
|||
#endif
|
||||
|
||||
static void PrintHelp(const char* argv0) {
|
||||
std::cout << "Usage: " << argv0
|
||||
std::cout
|
||||
<< "Usage: " << argv0
|
||||
<< " [options] <filename>\n"
|
||||
"-c, --config Load the specified configuration file\n"
|
||||
"-f, --fullscreen Start in fullscreen mode\n"
|
||||
|
@ -77,7 +82,12 @@ static void PrintHelp(const char* argv0) {
|
|||
" Nickname, password, address and port for multiplayer\n"
|
||||
"-p, --program Pass following string as arguments to executable\n"
|
||||
"-u, --user Select a specific user profile from 0 to 7\n"
|
||||
"-v, --version Output version information and exit\n";
|
||||
"-v, --version Output version information and exit\n"
|
||||
"-l, "
|
||||
"--applet-params="
|
||||
"\"program_id,applet_id,applet_type,launch_type,prog_index,prev_prog_index\"\n"
|
||||
" Numerical parameters for launching an applet. If applet_id\n"
|
||||
" is 0, then the provided game will launch, if any.\n";
|
||||
}
|
||||
|
||||
static void PrintVersion() {
|
||||
|
@ -212,6 +222,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
bool use_multiplayer = false;
|
||||
bool fullscreen = false;
|
||||
Service::AM::FrontendAppletParameters load_parameters{};
|
||||
std::string nickname{};
|
||||
std::string password{};
|
||||
std::string address{};
|
||||
|
@ -223,6 +234,7 @@ int main(int argc, char** argv) {
|
|||
{"fullscreen", no_argument, 0, 'f'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"game", required_argument, 0, 'g'},
|
||||
{"applet-params", required_argument, 0, 'l'},
|
||||
{"multiplayer", required_argument, 0, 'm'},
|
||||
{"program", optional_argument, 0, 'p'},
|
||||
{"user", required_argument, 0, 'u'},
|
||||
|
@ -232,7 +244,7 @@ int main(int argc, char** argv) {
|
|||
};
|
||||
|
||||
while (optind < argc) {
|
||||
int arg = getopt_long(argc, argv, "g:fhvp::c:u:", long_options, &option_index);
|
||||
int arg = getopt_long(argc, argv, "g:fhvp::c:u:l:", long_options, &option_index);
|
||||
if (arg != -1) {
|
||||
switch (static_cast<char>(arg)) {
|
||||
case 'c':
|
||||
|
@ -250,6 +262,27 @@ int main(int argc, char** argv) {
|
|||
filepath = str_arg;
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
std::string str_arg(optarg);
|
||||
str_arg.append(",0"); // FALLBACK: if string is partially completed ("1234,3")
|
||||
// this will set all those unset to 0. otherwise we get
|
||||
// all 3s.
|
||||
std::stringstream stream(str_arg);
|
||||
std::string sub;
|
||||
std::getline(stream, sub, ',');
|
||||
load_parameters.program_id = std::stoull(sub);
|
||||
std::getline(stream, sub, ',');
|
||||
load_parameters.applet_id = static_cast<Service::AM::AppletId>(std::stoul(sub));
|
||||
std::getline(stream, sub, ',');
|
||||
load_parameters.applet_type = static_cast<Service::AM::AppletType>(std::stoi(sub));
|
||||
std::getline(stream, sub, ',');
|
||||
load_parameters.launch_type = static_cast<Service::AM::LaunchType>(std::stoi(sub));
|
||||
std::getline(stream, sub, ',');
|
||||
load_parameters.program_index = std::stoi(sub);
|
||||
std::getline(stream, sub, ',');
|
||||
load_parameters.previous_program_index = std::stoi(sub);
|
||||
break;
|
||||
}
|
||||
case 'm': {
|
||||
use_multiplayer = true;
|
||||
const std::string str_arg(optarg);
|
||||
|
@ -331,7 +364,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
Common::ConfigureNvidiaEnvironmentFlags();
|
||||
|
||||
if (filepath.empty()) {
|
||||
if (filepath.empty() && !static_cast<u32>(load_parameters.applet_id)) {
|
||||
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
|
||||
return -1;
|
||||
}
|
||||
|
@ -367,9 +400,27 @@ int main(int argc, char** argv) {
|
|||
system.GetFileSystemController().CreateFactories(*system.GetFilesystem());
|
||||
system.GetUserChannel().clear();
|
||||
|
||||
Service::AM::FrontendAppletParameters load_parameters{
|
||||
.applet_id = Service::AM::AppletId::Application,
|
||||
};
|
||||
if (static_cast<u32>(load_parameters.applet_id)) {
|
||||
// code below based off of suyu/main.cpp : GMainWindow::OnHomeMenu()
|
||||
Service::AM::AppletProgramId applet_prog_id =
|
||||
Service::AM::AppletIdToProgramId(load_parameters.applet_id);
|
||||
auto sysnand = system.GetFileSystemController().GetSystemNANDContents();
|
||||
if (!sysnand) {
|
||||
LOG_CRITICAL(Frontend, "Failed to load applet: Firmware not installed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto user_applet_nca = sysnand->GetEntry(static_cast<u64>(applet_prog_id),
|
||||
FileSys::ContentRecordType::Program);
|
||||
if (!user_applet_nca) {
|
||||
LOG_CRITICAL(Frontend, "Failed to load applet: applet cannot be found.");
|
||||
return -1;
|
||||
}
|
||||
if (filepath.empty())
|
||||
filepath = user_applet_nca->GetFullPath();
|
||||
} else {
|
||||
load_parameters.applet_id = Service::AM::AppletId::Application;
|
||||
}
|
||||
const Core::SystemResultStatus load_result{system.Load(*emu_window, filepath, load_parameters)};
|
||||
|
||||
switch (load_result) {
|
||||
|
|
Loading…
Reference in a new issue