diff options
Diffstat (limited to 'src/core/hle/service')
35 files changed, 349 insertions, 80 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index deeca925d..a17c46121 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -945,7 +945,7 @@ public: {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, {1, &ILibraryAppletAccessor::IsCompleted, "IsCompleted"}, {10, &ILibraryAppletAccessor::Start, "Start"}, - {20, nullptr, "RequestExit"}, + {20, &ILibraryAppletAccessor::RequestExit, "RequestExit"}, {25, nullptr, "Terminate"}, {30, &ILibraryAppletAccessor::GetResult, "GetResult"}, {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, @@ -1010,6 +1010,15 @@ private: rb.Push(ResultSuccess); } + void RequestExit(HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called"); + + ASSERT(applet != nullptr); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(applet->RequestExit()); + } + void PushInData(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); @@ -1265,7 +1274,8 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx) } std::vector<u8> memory(transfer_mem->GetSize()); - system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size()); + system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), + memory.size()); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); @@ -1298,7 +1308,8 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) { } std::vector<u8> memory(transfer_mem->GetSize()); - system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size()); + system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), + memory.size()); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 162687b29..93c9f2a55 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp @@ -174,4 +174,9 @@ void Cabinet::Cancel() { broker.SignalStateChanged(); } +Result Cabinet::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h index 84197a807..edd295a27 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.h +++ b/src/core/hle/service/am/applets/applet_cabinet.h @@ -89,6 +89,7 @@ public: void Execute() override; void DisplayCompleted(bool apply_changes, std::string_view amiibo_name); void Cancel(); + Result RequestExit() override; private: const Core::Frontend::CabinetApplet& frontend; diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp index 58484519b..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); @@ -262,4 +264,9 @@ void Controller::ConfigurationComplete() { broker.SignalStateChanged(); } +Result Controller::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h index 1f9adec65..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."); @@ -129,8 +134,9 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; 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_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp index b013896b4..b46ea840c 100644 --- a/src/core/hle/service/am/applets/applet_error.cpp +++ b/src/core/hle/service/am/applets/applet_error.cpp @@ -209,4 +209,9 @@ void Error::DisplayCompleted() { broker.SignalStateChanged(); } +Result Error::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_error.h b/src/core/hle/service/am/applets/applet_error.h index d78d6f1d1..d822a32bb 100644 --- a/src/core/hle/service/am/applets/applet_error.h +++ b/src/core/hle/service/am/applets/applet_error.h @@ -34,6 +34,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; + Result RequestExit() override; void DisplayCompleted(); diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp index 1eefa85e3..8b352020e 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.cpp +++ b/src/core/hle/service/am/applets/applet_general_backend.cpp @@ -150,6 +150,11 @@ void Auth::AuthFinished(bool is_successful) { broker.SignalStateChanged(); } +Result Auth::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, const Core::Frontend::PhotoViewerApplet& frontend_) : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} @@ -202,6 +207,11 @@ void PhotoViewer::ViewFinished() { broker.SignalStateChanged(); } +Result PhotoViewer::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_) : Applet{system_, applet_mode_}, id{id_}, system{system_} {} @@ -250,4 +260,9 @@ void StubApplet::Execute() { broker.SignalStateChanged(); } +Result StubApplet::RequestExit() { + // Nothing to do. + R_SUCCEED(); +} + } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_general_backend.h b/src/core/hle/service/am/applets/applet_general_backend.h index a9f2535a2..34ecaebb9 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.h +++ b/src/core/hle/service/am/applets/applet_general_backend.h @@ -28,6 +28,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; + Result RequestExit() override; void AuthFinished(bool is_successful = true); @@ -59,6 +60,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; + Result RequestExit() override; void ViewFinished(); @@ -80,6 +82,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; + Result RequestExit() override; private: AppletId id; diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index ae80ef506..d1f652c09 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp @@ -135,4 +135,9 @@ void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result, broker.SignalStateChanged(); } +Result MiiEdit::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_mii_edit.h b/src/core/hle/service/am/applets/applet_mii_edit.h index d18dd3cf5..3f46fae1b 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.h +++ b/src/core/hle/service/am/applets/applet_mii_edit.h @@ -25,6 +25,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; + Result RequestExit() override; void MiiEditOutput(MiiEditResult result, s32 index); 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 1d69f5447..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,10 +109,15 @@ 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(); } +Result ProfileSelect::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + } // namespace Service::AM::Applets 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 b77f1d205..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: @@ -42,13 +123,17 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; + Result RequestExit() override; void SelectionComplete(std::optional<Common::UUID> uuid); 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; diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.cpp b/src/core/hle/service/am/applets/applet_software_keyboard.cpp index c18236045..4145bb84f 100644 --- a/src/core/hle/service/am/applets/applet_software_keyboard.cpp +++ b/src/core/hle/service/am/applets/applet_software_keyboard.cpp @@ -770,6 +770,11 @@ void SoftwareKeyboard::ExitKeyboard() { broker.SignalStateChanged(); } +Result SoftwareKeyboard::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + // Inline Software Keyboard Requests void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) { diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.h b/src/core/hle/service/am/applets/applet_software_keyboard.h index b01b31c98..2e919811b 100644 --- a/src/core/hle/service/am/applets/applet_software_keyboard.h +++ b/src/core/hle/service/am/applets/applet_software_keyboard.h @@ -31,6 +31,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; + Result RequestExit() override; /** * Submits the input text to the application. diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp index f061bae80..2accf7898 100644 --- a/src/core/hle/service/am/applets/applet_web_browser.cpp +++ b/src/core/hle/service/am/applets/applet_web_browser.cpp @@ -363,6 +363,11 @@ void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url) broker.SignalStateChanged(); } +Result WebBrowser::RequestExit() { + frontend.Close(); + R_SUCCEED(); +} + bool WebBrowser::InputTLVExistsInMap(WebArgInputTLVType input_tlv_type) const { return web_arg_input_tlv_map.find(input_tlv_type) != web_arg_input_tlv_map.end(); } diff --git a/src/core/hle/service/am/applets/applet_web_browser.h b/src/core/hle/service/am/applets/applet_web_browser.h index fd727fac8..99fe18659 100644 --- a/src/core/hle/service/am/applets/applet_web_browser.h +++ b/src/core/hle/service/am/applets/applet_web_browser.h @@ -35,6 +35,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; + Result RequestExit() override; void ExtractOfflineRomFS(); diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index a22eb62a8..12f374199 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -142,6 +142,7 @@ public: virtual Result GetStatus() const = 0; virtual void ExecuteInteractive() = 0; virtual void Execute() = 0; + virtual Result RequestExit() = 0; AppletDataBroker& GetBroker() { return broker; diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp index 37f2e4405..bcb272eaf 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp +++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp @@ -60,7 +60,8 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti // Update seven six axis transfer memory seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); - system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo)); + system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, + sizeof(seven_sixaxis_lifo)); } void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index ba6f04d8d..b070327ec 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -819,12 +819,12 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode return communication_mode; } -Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, - NpadJoyDeviceType npad_device_type, - NpadJoyAssignmentMode assignment_mode) { +bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, + NpadJoyDeviceType npad_device_type, + NpadJoyAssignmentMode assignment_mode) { if (!IsNpadIdValid(npad_id)) { LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - return InvalidNpadId; + return false; } auto& controller = GetControllerFromNpadIdType(npad_id); @@ -833,7 +833,7 @@ Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, } if (!controller.device->IsConnected()) { - return ResultSuccess; + return false; } if (assignment_mode == NpadJoyAssignmentMode::Dual) { @@ -842,52 +842,52 @@ Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, controller.is_dual_left_connected = true; controller.is_dual_right_connected = false; UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); - return ResultSuccess; + return false; } if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) { DisconnectNpad(npad_id); controller.is_dual_left_connected = false; controller.is_dual_right_connected = true; UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); - return ResultSuccess; + return false; } - return ResultSuccess; + return false; } // This is for NpadJoyAssignmentMode::Single // Only JoyconDual get affected by this function if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) { - return ResultSuccess; + return false; } if (controller.is_dual_left_connected && !controller.is_dual_right_connected) { DisconnectNpad(npad_id); UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); - return ResultSuccess; + return false; } if (!controller.is_dual_left_connected && controller.is_dual_right_connected) { DisconnectNpad(npad_id); UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); - return ResultSuccess; + return false; } // We have two controllers connected to the same npad_id we need to split them - const auto npad_id_2 = hid_core.GetFirstDisconnectedNpadId(); - auto& controller_2 = GetControllerFromNpadIdType(npad_id_2); + new_npad_id = hid_core.GetFirstDisconnectedNpadId(); + auto& controller_2 = GetControllerFromNpadIdType(new_npad_id); DisconnectNpad(npad_id); if (npad_device_type == NpadJoyDeviceType::Left) { UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); controller_2.is_dual_left_connected = false; controller_2.is_dual_right_connected = true; - UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true); + UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true); } else { UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); controller_2.is_dual_left_connected = true; controller_2.is_dual_right_connected = false; - UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true); + UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true); } - return ResultSuccess; + return true; } bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, @@ -1388,7 +1388,8 @@ Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, return NpadIsDualJoycon; } - // Disconnect the joycon at the second id and connect the dual joycon at the first index. + // Disconnect the joycons and connect them as dual joycon at the first index. + DisconnectNpad(npad_id_1); DisconnectNpad(npad_id_2); controller_1.is_dual_left_connected = true; controller_1.is_dual_right_connected = true; diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index a5998c453..9cfe298f1 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -102,8 +102,8 @@ public: void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); NpadCommunicationMode GetNpadCommunicationMode() const; - Result SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, - NpadJoyAssignmentMode assignment_mode); + bool SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, + NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode); bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, const Core::HID::VibrationValue& vibration_value); diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 4529ad643..87e7b864a 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -302,7 +302,7 @@ Hid::Hid(Core::System& system_) {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"}, {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, - {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, + {133, &Hid::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"}, {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"}, {135, &Hid::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"}, {136, &Hid::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"}, @@ -1180,8 +1180,10 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; + Core::HID::NpadIdType new_npad_id{}; auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); - controller.SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left, + controller.SetNpadMode(new_npad_id, parameters.npad_id, + Controller_NPad::NpadJoyDeviceType::Left, Controller_NPad::NpadJoyAssignmentMode::Single); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, @@ -1203,8 +1205,9 @@ void Hid::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; + Core::HID::NpadIdType new_npad_id{}; auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); - controller.SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type, + controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, Controller_NPad::NpadJoyAssignmentMode::Single); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", @@ -1226,8 +1229,10 @@ void Hid::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; + Core::HID::NpadIdType new_npad_id{}; auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); - controller.SetNpadMode(parameters.npad_id, {}, Controller_NPad::NpadJoyAssignmentMode::Dual); + controller.SetNpadMode(new_npad_id, parameters.npad_id, {}, + Controller_NPad::NpadJoyAssignmentMode::Dual); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, parameters.applet_resource_user_id); @@ -1369,6 +1374,34 @@ void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) { rb.Push(result); } +void Hid::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + Core::HID::NpadIdType npad_id; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + Controller_NPad::NpadJoyDeviceType npad_joy_device_type; + }; + static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + Core::HID::NpadIdType new_npad_id{}; + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto is_reassigned = + controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, + Controller_NPad::NpadJoyAssignmentMode::Single); + + LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", + parameters.npad_id, parameters.applet_resource_user_id, + parameters.npad_joy_device_type); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(is_reassigned); + rb.PushEnum(new_npad_id); +} + void Hid::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; struct Parameters { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index c69e5f3fb..f247b83c2 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -151,6 +151,7 @@ private: void SwapNpadAssignment(HLERequestContext& ctx); void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx); void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx); + void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx); void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx); void SetNpadCaptureButtonAssignment(HLERequestContext& ctx); void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx); diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp index 65a2dd521..378108012 100644 --- a/src/core/hle/service/hid/hidbus/ringcon.cpp +++ b/src/core/hle/service/hid/hidbus/ringcon.cpp @@ -64,8 +64,8 @@ void RingController::OnUpdate() { curr_entry.polling_data.out_size = sizeof(ringcon_value); std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value)); - system.Memory().WriteBlock(transfer_memory, &enable_sixaxis_data, - sizeof(enable_sixaxis_data)); + system.ApplicationMemory().WriteBlock(transfer_memory, &enable_sixaxis_data, + sizeof(enable_sixaxis_data)); break; } default: diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp index ca5d067e8..803a6277c 100644 --- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp +++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp @@ -58,16 +58,16 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType if (camera_data.format != current_config.origin_format) { LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format, current_config.origin_format); - system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, - GetDataSize(current_config.trimming_format)); + system.ApplicationMemory().ZeroBlock(transfer_memory, + GetDataSize(current_config.trimming_format)); return; } if (current_config.origin_format > current_config.trimming_format) { LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}", current_config.origin_format, current_config.trimming_format); - system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, - GetDataSize(current_config.trimming_format)); + system.ApplicationMemory().ZeroBlock(transfer_memory, + GetDataSize(current_config.trimming_format)); return; } @@ -84,8 +84,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})", current_config.trimming_start_x, current_config.trimming_start_y, trimming_width, trimming_height, origin_width, origin_height); - system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory, - GetDataSize(current_config.trimming_format)); + system.ApplicationMemory().ZeroBlock(transfer_memory, + GetDataSize(current_config.trimming_format)); return; } @@ -99,8 +99,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType } } - system.Memory().WriteBlock(transfer_memory, window_data.data(), - GetDataSize(current_config.trimming_format)); + system.ApplicationMemory().WriteBlock(transfer_memory, window_data.data(), + GetDataSize(current_config.trimming_format)); if (!IsProcessorActive()) { StartProcessor(); @@ -148,7 +148,7 @@ Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState( std::vector<u8>& data) const { const auto size = GetDataSize(current_config.trimming_format); data.resize(size); - system.Memory().ReadBlock(transfer_memory, data.data(), size); + system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size); return processor_state; } diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp index cca697c64..2290df705 100644 --- a/src/core/hle/service/hle_ipc.cpp +++ b/src/core/hle/service/hle_ipc.cpp @@ -303,8 +303,7 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(Kernel::KThread& requesti } // Copy the translated command buffer back into the thread's command buffer area. - memory.WriteBlock(owner_process, requesting_thread.GetTlsAddress(), cmd_buf.data(), - write_size * sizeof(u32)); + memory.WriteBlock(requesting_thread.GetTlsAddress(), cmd_buf.data(), write_size * sizeof(u32)); return ResultSuccess; } diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp index 607f27b21..be996870f 100644 --- a/src/core/hle/service/jit/jit.cpp +++ b/src/core/hle/service/jit/jit.cpp @@ -24,8 +24,8 @@ class IJitEnvironment final : public ServiceFramework<IJitEnvironment> { public: explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx, CodeRange user_ro) - : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, context{ - system_.Memory()} { + : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, + context{system_.ApplicationMemory()} { // clang-format off static const FunctionInfo functions[] = { {0, &IJitEnvironment::GenerateCode, "GenerateCode"}, diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 437dc2ea5..c42489ff9 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -225,7 +225,7 @@ public: // Read NRR data from memory std::vector<u8> nrr_data(nrr_size); - system.Memory().ReadBlock(nrr_address, nrr_data.data(), nrr_size); + system.ApplicationMemory().ReadBlock(nrr_address, nrr_data.data(), nrr_size); NRRHeader header; std::memcpy(&header, nrr_data.data(), sizeof(NRRHeader)); @@ -314,7 +314,7 @@ public: const auto is_region_available = [&](VAddr addr) { const auto end_addr = addr + size; while (addr < end_addr) { - if (system.Memory().IsValidVirtualAddress(addr)) { + if (system.ApplicationMemory().IsValidVirtualAddress(addr)) { return false; } @@ -427,8 +427,8 @@ public: const VAddr bss_end_addr{ Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)}; - const auto CopyCode = [this, process](VAddr src_addr, VAddr dst_addr, u64 size) { - system.Memory().CopyBlock(*process, dst_addr, src_addr, size); + const auto CopyCode = [this](VAddr src_addr, VAddr dst_addr, u64 size) { + system.ApplicationMemory().CopyBlock(dst_addr, src_addr, size); }; CopyCode(nro_addr + nro_header.segment_headers[TEXT_INDEX].memory_offset, text_start, nro_header.segment_headers[TEXT_INDEX].memory_size); @@ -506,7 +506,7 @@ public: // Read NRO data from memory std::vector<u8> nro_data(nro_size); - system.Memory().ReadBlock(nro_address, nro_data.data(), nro_size); + system.ApplicationMemory().ReadBlock(nro_address, nro_data.data(), nro_size); SHA256Hash hash{}; mbedtls_sha256_ret(nro_data.data(), nro_data.size(), hash.data(), 0); diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp index bba862fb2..a3622e792 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.cpp +++ b/src/core/hle/service/nfp/amiibo_crypto.cpp @@ -70,6 +70,10 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) { return true; } +bool IsAmiiboValid(const NTAG215File& ntag_file) { + return IsAmiiboValid(EncodedDataToNfcData(ntag_file)); +} + NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { NTAG215File encoded_data{}; diff --git a/src/core/hle/service/nfp/amiibo_crypto.h b/src/core/hle/service/nfp/amiibo_crypto.h index c9fd67a39..f6208ee6b 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.h +++ b/src/core/hle/service/nfp/amiibo_crypto.h @@ -60,6 +60,9 @@ static_assert(sizeof(DerivedKeys) == 0x30, "DerivedKeys is an invalid size"); /// Validates that the amiibo file is not corrupted bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file); +/// Validates that the amiibo file is not corrupted +bool IsAmiiboValid(const NTAG215File& ntag_file); + /// Converts from encrypted file format to encoded file format NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data); diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index 5990e1473..607e70968 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp @@ -121,7 +121,16 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) { // TODO: Filter by allowed_protocols here - memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); + memcpy(&tag_data, data.data(), sizeof(EncryptedNTAG215File)); + is_plain_amiibo = AmiiboCrypto::IsAmiiboValid(tag_data); + + if (is_plain_amiibo) { + encrypted_tag_data = AmiiboCrypto::EncodedDataToNfcData(tag_data); + LOG_INFO(Service_NFP, "Using plain amiibo"); + } else { + tag_data = {}; + memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); + } device_state = DeviceState::TagFound; deactivate_event->GetReadableEvent().Clear(); @@ -232,13 +241,17 @@ Result NfpDevice::Flush() { tag_data.write_counter++; - if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { - LOG_ERROR(Service_NFP, "Failed to encode data"); - return WriteAmiiboFailed; - } + std::vector<u8> data(sizeof(EncryptedNTAG215File)); + if (is_plain_amiibo) { + memcpy(data.data(), &tag_data, sizeof(tag_data)); + } else { + if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { + LOG_ERROR(Service_NFP, "Failed to encode data"); + return WriteAmiiboFailed; + } - std::vector<u8> data(sizeof(encrypted_tag_data)); - memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); + memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); + } if (!npad_device->WriteNfc(data)) { LOG_ERROR(Service_NFP, "Error writing to file"); @@ -256,6 +269,13 @@ Result NfpDevice::Mount(MountTarget mount_target_) { return WrongDeviceState; } + // The loaded amiibo is not encrypted + if (is_plain_amiibo) { + device_state = DeviceState::TagMounted; + mount_target = mount_target_; + return ResultSuccess; + } + if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { LOG_ERROR(Service_NFP, "Not an amiibo"); return NotAnAmiibo; diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index 27122e86e..7f963730d 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h @@ -95,6 +95,7 @@ private: bool is_initalized{}; bool is_data_moddified{}; bool is_app_area_open{}; + bool is_plain_amiibo{}; TagProtocol allowed_protocols{}; s64 current_posix_time{}; MountTarget mount_target{MountTarget::None}; diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index b3599a513..70c878552 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h @@ -309,7 +309,8 @@ struct EncryptedNTAG215File { u32 CFG1; // Defines number of verification attempts NTAG215Password password; // Password data }; -static_assert(sizeof(EncryptedNTAG215File) == 0x21C, "EncryptedNTAG215File is an invalid size"); +static_assert(sizeof(EncryptedNTAG215File) == sizeof(NTAG215File), + "EncryptedNTAG215File is an invalid size"); static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>, "EncryptedNTAG215File must be trivially copyable."); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index d2308fffc..453a965dc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -304,8 +304,8 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8> Tegra::CommandList entries(params.num_entries); if (kickoff) { - system.Memory().ReadBlock(params.address, entries.command_lists.data(), - params.num_entries * sizeof(Tegra::CommandListHeader)); + system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(), + params.num_entries * sizeof(Tegra::CommandListHeader)); } else { std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)], params.num_entries * sizeof(Tegra::CommandListHeader)); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 7bcef105b..1ab51f10b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -105,8 +105,8 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, const auto object = nvmap.GetHandle(cmd_buffer.memory_id); ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); - system.Memory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), - cmdlist.size() * sizeof(u32)); + system.ApplicationMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), + cmdlist.size() * sizeof(u32)); gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); } std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); |