summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/am/applets
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/am/applets')
-rw-r--r--src/core/hle/service/am/applets/applet_controller.cpp12
-rw-r--r--src/core/hle/service/am/applets/applet_controller.h9
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.cpp52
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.h102
4 files changed, 154 insertions, 21 deletions
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp
index 2d1d115d7..9840d2547 100644
--- a/src/core/hle/service/am/applets/applet_controller.cpp
+++ b/src/core/hle/service/am/applets/applet_controller.cpp
@@ -224,7 +224,8 @@ void Controller::Execute() {
parameters.allow_dual_joycons, parameters.allow_left_joycon,
parameters.allow_right_joycon);
- frontend.ReconfigureControllers([this] { ConfigurationComplete(); }, parameters);
+ frontend.ReconfigureControllers(
+ [this](bool is_success) { ConfigurationComplete(is_success); }, parameters);
break;
}
case ControllerSupportMode::ShowControllerStrapGuide:
@@ -232,16 +233,16 @@ void Controller::Execute() {
case ControllerSupportMode::ShowControllerKeyRemappingForSystem:
UNIMPLEMENTED_MSG("ControllerSupportMode={} is not implemented",
controller_private_arg.mode);
- ConfigurationComplete();
+ ConfigurationComplete(true);
break;
default: {
- ConfigurationComplete();
+ ConfigurationComplete(true);
break;
}
}
}
-void Controller::ConfigurationComplete() {
+void Controller::ConfigurationComplete(bool is_success) {
ControllerSupportResultInfo result_info{};
// If enable_single_mode is enabled, player_count is 1 regardless of any other parameters.
@@ -250,7 +251,8 @@ void Controller::ConfigurationComplete() {
result_info.selected_id = static_cast<u32>(system.HIDCore().GetFirstNpadId());
- result_info.result = 0;
+ result_info.result =
+ is_success ? ControllerSupportResult::Success : ControllerSupportResult::Cancel;
LOG_DEBUG(Service_HID, "Result Info: player_count={}, selected_id={}, result={}",
result_info.player_count, result_info.selected_id, result_info.result);
diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h
index 1fbabee11..f6c64f633 100644
--- a/src/core/hle/service/am/applets/applet_controller.h
+++ b/src/core/hle/service/am/applets/applet_controller.h
@@ -48,6 +48,11 @@ enum class ControllerSupportCaller : u8 {
MaxControllerSupportCaller,
};
+enum class ControllerSupportResult : u32 {
+ Success = 0,
+ Cancel = 2,
+};
+
struct ControllerSupportArgPrivate {
u32 arg_private_size{};
u32 arg_size{};
@@ -112,7 +117,7 @@ struct ControllerSupportResultInfo {
s8 player_count{};
INSERT_PADDING_BYTES(3);
u32 selected_id{};
- u32 result{};
+ ControllerSupportResult result{};
};
static_assert(sizeof(ControllerSupportResultInfo) == 0xC,
"ControllerSupportResultInfo has incorrect size.");
@@ -131,7 +136,7 @@ public:
void Execute() override;
Result RequestExit() override;
- void ConfigurationComplete();
+ void ConfigurationComplete(bool is_success);
private:
const Core::Frontend::ControllerApplet& frontend;
diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp
index 07abc2563..89cb323e9 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.cpp
+++ b/src/core/hle/service/am/applets/applet_profile_select.cpp
@@ -25,13 +25,29 @@ void ProfileSelect::Initialize() {
final_data.clear();
Applet::Initialize();
+ profile_select_version = ProfileSelectAppletVersion{common_args.library_version};
const auto user_config_storage = broker.PopNormalDataToApplet();
ASSERT(user_config_storage != nullptr);
const auto& user_config = user_config_storage->GetData();
- ASSERT(user_config.size() >= sizeof(UserSelectionConfig));
- std::memcpy(&config, user_config.data(), sizeof(UserSelectionConfig));
+ LOG_INFO(Service_AM, "Initializing Profile Select Applet with version={}",
+ profile_select_version);
+
+ switch (profile_select_version) {
+ case ProfileSelectAppletVersion::Version1:
+ ASSERT(user_config.size() == sizeof(UiSettingsV1));
+ std::memcpy(&config_old, user_config.data(), sizeof(UiSettingsV1));
+ break;
+ case ProfileSelectAppletVersion::Version2:
+ case ProfileSelectAppletVersion::Version3:
+ ASSERT(user_config.size() == sizeof(UiSettings));
+ std::memcpy(&config, user_config.data(), sizeof(UiSettings));
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version);
+ break;
+ }
}
bool ProfileSelect::TransactionComplete() const {
@@ -52,11 +68,37 @@ void ProfileSelect::Execute() {
return;
}
- frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); });
+ Core::Frontend::ProfileSelectParameters parameters{};
+
+ switch (profile_select_version) {
+ case ProfileSelectAppletVersion::Version1:
+ parameters = {
+ .mode = config_old.mode,
+ .invalid_uid_list = config_old.invalid_uid_list,
+ .display_options = config_old.display_options,
+ .purpose = UserSelectionPurpose::General,
+ };
+ break;
+ case ProfileSelectAppletVersion::Version2:
+ case ProfileSelectAppletVersion::Version3:
+ parameters = {
+ .mode = config.mode,
+ .invalid_uid_list = config.invalid_uid_list,
+ .display_options = config.display_options,
+ .purpose = config.purpose,
+ };
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version);
+ break;
+ }
+
+ frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); },
+ parameters);
}
void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
- UserSelectionOutput output{};
+ UiReturnArg output{};
if (uuid.has_value() && uuid->IsValid()) {
output.result = 0;
@@ -67,7 +109,7 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
output.uuid_selected = Common::InvalidUUID;
}
- final_data = std::vector<u8>(sizeof(UserSelectionOutput));
+ final_data = std::vector<u8>(sizeof(UiReturnArg));
std::memcpy(final_data.data(), &output, final_data.size());
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
broker.SignalStateChanged();
diff --git a/src/core/hle/service/am/applets/applet_profile_select.h b/src/core/hle/service/am/applets/applet_profile_select.h
index 85705c216..369f9250f 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.h
+++ b/src/core/hle/service/am/applets/applet_profile_select.h
@@ -16,19 +16,100 @@ class System;
namespace Service::AM::Applets {
-struct UserSelectionConfig {
- // TODO(DarkLordZach): RE this structure
- // It seems to be flags and the like that determine the UI of the applet on the switch... from
- // my research this is safe to ignore for now.
- INSERT_PADDING_BYTES(0xA0);
+enum class ProfileSelectAppletVersion : u32 {
+ Version1 = 0x1, // 1.0.0+
+ Version2 = 0x10000, // 2.0.0+
+ Version3 = 0x20000, // 6.0.0+
};
-static_assert(sizeof(UserSelectionConfig) == 0xA0, "UserSelectionConfig has incorrect size.");
-struct UserSelectionOutput {
+// This is nn::account::UiMode
+enum class UiMode {
+ UserSelector,
+ UserCreator,
+ EnsureNetworkServiceAccountAvailable,
+ UserIconEditor,
+ UserNicknameEditor,
+ UserCreatorForStarter,
+ NintendoAccountAuthorizationRequestContext,
+ IntroduceExternalNetworkServiceAccount,
+ IntroduceExternalNetworkServiceAccountForRegistration,
+ NintendoAccountNnidLinker,
+ LicenseRequirementsForNetworkService,
+ LicenseRequirementsForNetworkServiceWithUserContextImpl,
+ UserCreatorForImmediateNaLoginTest,
+ UserQualificationPromoter,
+};
+
+// This is nn::account::UserSelectionPurpose
+enum class UserSelectionPurpose {
+ General,
+ GameCardRegistration,
+ EShopLaunch,
+ EShopItemShow,
+ PicturePost,
+ NintendoAccountLinkage,
+ SettingsUpdate,
+ SaveDataDeletion,
+ UserMigration,
+ SaveDataTransfer,
+};
+
+// This is nn::account::NintendoAccountStartupDialogType
+enum class NintendoAccountStartupDialogType {
+ LoginAndCreate,
+ Login,
+ Create,
+};
+
+// This is nn::account::UserSelectionSettingsForSystemService
+struct UserSelectionSettingsForSystemService {
+ UserSelectionPurpose purpose;
+ bool enable_user_creation;
+ INSERT_PADDING_BYTES(0x3);
+};
+static_assert(sizeof(UserSelectionSettingsForSystemService) == 0x8,
+ "UserSelectionSettingsForSystemService has incorrect size.");
+
+struct UiSettingsDisplayOptions {
+ bool is_network_service_account_required;
+ bool is_skip_enabled;
+ bool is_system_or_launcher;
+ bool is_registration_permitted;
+ bool show_skip_button;
+ bool aditional_select;
+ bool show_user_selector;
+ bool is_unqualified_user_selectable;
+};
+static_assert(sizeof(UiSettingsDisplayOptions) == 0x8,
+ "UiSettingsDisplayOptions has incorrect size.");
+
+struct UiSettingsV1 {
+ UiMode mode;
+ INSERT_PADDING_BYTES(0x4);
+ std::array<Common::UUID, 8> invalid_uid_list;
+ u64 application_id;
+ UiSettingsDisplayOptions display_options;
+};
+static_assert(sizeof(UiSettingsV1) == 0x98, "UiSettings has incorrect size.");
+
+// This is nn::account::UiSettings
+struct UiSettings {
+ UiMode mode;
+ INSERT_PADDING_BYTES(0x4);
+ std::array<Common::UUID, 8> invalid_uid_list;
+ u64 application_id;
+ UiSettingsDisplayOptions display_options;
+ UserSelectionPurpose purpose;
+ INSERT_PADDING_BYTES(0x4);
+};
+static_assert(sizeof(UiSettings) == 0xA0, "UiSettings has incorrect size.");
+
+// This is nn::account::UiReturnArg
+struct UiReturnArg {
u64 result;
Common::UUID uuid_selected;
};
-static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has incorrect size.");
+static_assert(sizeof(UiReturnArg) == 0x18, "UiReturnArg has incorrect size.");
class ProfileSelect final : public Applet {
public:
@@ -49,7 +130,10 @@ public:
private:
const Core::Frontend::ProfileSelectApplet& frontend;
- UserSelectionConfig config;
+ UiSettings config;
+ UiSettingsV1 config_old;
+ ProfileSelectAppletVersion profile_select_version;
+
bool complete = false;
Result status = ResultSuccess;
std::vector<u8> final_data;