mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 23:49:01 -05:00 
			
		
		
		
	Merge pull request #1781 from DarkLordZach/applet-profile-select
am: Implement HLE profile selector applet
This commit is contained in:
		| @@ -19,6 +19,7 @@ | ||||
| #include "core/hle/service/am/applet_ae.h" | ||||
| #include "core/hle/service/am/applet_oe.h" | ||||
| #include "core/hle/service/am/applets/applets.h" | ||||
| #include "core/hle/service/am/applets/profile_select.h" | ||||
| #include "core/hle/service/am/applets/software_keyboard.h" | ||||
| #include "core/hle/service/am/applets/stub_applet.h" | ||||
| #include "core/hle/service/am/idle.h" | ||||
| @@ -39,6 +40,7 @@ constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 0x2}; | ||||
| constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7}; | ||||
|  | ||||
| enum class AppletId : u32 { | ||||
|     ProfileSelect = 0x10, | ||||
|     SoftwareKeyboard = 0x11, | ||||
| }; | ||||
|  | ||||
| @@ -775,6 +777,8 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default; | ||||
|  | ||||
| static std::shared_ptr<Applets::Applet> GetAppletFromId(AppletId id) { | ||||
|     switch (id) { | ||||
|     case AppletId::ProfileSelect: | ||||
|         return std::make_shared<Applets::ProfileSelect>(); | ||||
|     case AppletId::SoftwareKeyboard: | ||||
|         return std::make_shared<Applets::SoftwareKeyboard>(); | ||||
|     default: | ||||
|   | ||||
							
								
								
									
										77
									
								
								src/core/hle/service/am/applets/profile_select.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/core/hle/service/am/applets/profile_select.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| // Copyright 2018 yuzu emulator team | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <cstring> | ||||
|  | ||||
| #include "common/assert.h" | ||||
| #include "common/string_util.h" | ||||
| #include "core/core.h" | ||||
| #include "core/frontend/applets/software_keyboard.h" | ||||
| #include "core/hle/service/am/am.h" | ||||
| #include "core/hle/service/am/applets/profile_select.h" | ||||
|  | ||||
| namespace Service::AM::Applets { | ||||
|  | ||||
| constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; | ||||
|  | ||||
| ProfileSelect::ProfileSelect() = default; | ||||
| ProfileSelect::~ProfileSelect() = default; | ||||
|  | ||||
| void ProfileSelect::Initialize() { | ||||
|     complete = false; | ||||
|     status = RESULT_SUCCESS; | ||||
|     final_data.clear(); | ||||
|  | ||||
|     Applet::Initialize(); | ||||
|  | ||||
|     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)); | ||||
| } | ||||
|  | ||||
| bool ProfileSelect::TransactionComplete() const { | ||||
|     return complete; | ||||
| } | ||||
|  | ||||
| ResultCode ProfileSelect::GetStatus() const { | ||||
|     return status; | ||||
| } | ||||
|  | ||||
| void ProfileSelect::ExecuteInteractive() { | ||||
|     UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); | ||||
| } | ||||
|  | ||||
| void ProfileSelect::Execute() { | ||||
|     if (complete) { | ||||
|         broker.PushNormalDataFromApplet(IStorage{final_data}); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const auto& frontend{Core::System::GetInstance().GetProfileSelector()}; | ||||
|  | ||||
|     frontend.SelectProfile([this](std::optional<Account::UUID> uuid) { SelectionComplete(uuid); }); | ||||
| } | ||||
|  | ||||
| void ProfileSelect::SelectionComplete(std::optional<Account::UUID> uuid) { | ||||
|     UserSelectionOutput output{}; | ||||
|  | ||||
|     if (uuid.has_value() && uuid->uuid != Account::INVALID_UUID) { | ||||
|         output.result = 0; | ||||
|         output.uuid_selected = uuid->uuid; | ||||
|     } else { | ||||
|         status = ERR_USER_CANCELLED_SELECTION; | ||||
|         output.result = ERR_USER_CANCELLED_SELECTION.raw; | ||||
|         output.uuid_selected = Account::INVALID_UUID; | ||||
|     } | ||||
|  | ||||
|     final_data = std::vector<u8>(sizeof(UserSelectionOutput)); | ||||
|     std::memcpy(final_data.data(), &output, final_data.size()); | ||||
|     broker.PushNormalDataFromApplet(IStorage{final_data}); | ||||
|     broker.SignalStateChanged(); | ||||
| } | ||||
|  | ||||
| } // namespace Service::AM::Applets | ||||
							
								
								
									
										50
									
								
								src/core/hle/service/am/applets/profile_select.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/core/hle/service/am/applets/profile_select.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // Copyright 2018 yuzu emulator team | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| #include "common/common_funcs.h" | ||||
| #include "core/hle/service/acc/profile_manager.h" | ||||
| #include "core/hle/service/am/applets/applets.h" | ||||
|  | ||||
| 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); | ||||
| }; | ||||
| static_assert(sizeof(UserSelectionConfig) == 0xA0, "UserSelectionConfig has incorrect size."); | ||||
|  | ||||
| struct UserSelectionOutput { | ||||
|     u64 result; | ||||
|     u128 uuid_selected; | ||||
| }; | ||||
| static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has incorrect size."); | ||||
|  | ||||
| class ProfileSelect final : public Applet { | ||||
| public: | ||||
|     ProfileSelect(); | ||||
|     ~ProfileSelect() override; | ||||
|  | ||||
|     void Initialize() override; | ||||
|  | ||||
|     bool TransactionComplete() const override; | ||||
|     ResultCode GetStatus() const override; | ||||
|     void ExecuteInteractive() override; | ||||
|     void Execute() override; | ||||
|  | ||||
|     void SelectionComplete(std::optional<Account::UUID> uuid); | ||||
|  | ||||
| private: | ||||
|     UserSelectionConfig config; | ||||
|     bool complete = false; | ||||
|     ResultCode status = RESULT_SUCCESS; | ||||
|     std::vector<u8> final_data; | ||||
| }; | ||||
|  | ||||
| } // namespace Service::AM::Applets | ||||
		Reference in New Issue
	
	Block a user
	 bunnei
					bunnei