diff options
| author | 2018-12-23 14:35:13 -0500 | |
|---|---|---|
| committer | 2018-12-23 14:35:13 -0500 | |
| commit | f95f6c7d86af9857cb737a741fc847bf2c5d8413 (patch) | |
| tree | b5c02a35cdb18b78c648bc3a6f98b87e68d2e651 /src/core/hle | |
| parent | Merge pull request #1780 from DarkLordZach/controller-profiles (diff) | |
| parent | applets: Correct event ResetTypes from OneShot to Sticky (diff) | |
| download | yuzu-f95f6c7d86af9857cb737a741fc847bf2c5d8413.tar.gz yuzu-f95f6c7d86af9857cb737a741fc847bf2c5d8413.tar.xz yuzu-f95f6c7d86af9857cb737a741fc847bf2c5d8413.zip | |
Merge pull request #1781 from DarkLordZach/applet-profile-select
am: Implement HLE profile selector applet
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/profile_select.cpp | 77 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/profile_select.h | 50 |
3 files changed, 131 insertions, 0 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 27c31aad2..5fc02a521 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "core/hle/service/am/applet_ae.h" | 19 | #include "core/hle/service/am/applet_ae.h" |
| 20 | #include "core/hle/service/am/applet_oe.h" | 20 | #include "core/hle/service/am/applet_oe.h" |
| 21 | #include "core/hle/service/am/applets/applets.h" | 21 | #include "core/hle/service/am/applets/applets.h" |
| 22 | #include "core/hle/service/am/applets/profile_select.h" | ||
| 22 | #include "core/hle/service/am/applets/software_keyboard.h" | 23 | #include "core/hle/service/am/applets/software_keyboard.h" |
| 23 | #include "core/hle/service/am/applets/stub_applet.h" | 24 | #include "core/hle/service/am/applets/stub_applet.h" |
| 24 | #include "core/hle/service/am/idle.h" | 25 | #include "core/hle/service/am/idle.h" |
| @@ -39,6 +40,7 @@ constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 0x2}; | |||
| 39 | constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7}; | 40 | constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7}; |
| 40 | 41 | ||
| 41 | enum class AppletId : u32 { | 42 | enum class AppletId : u32 { |
| 43 | ProfileSelect = 0x10, | ||
| 42 | SoftwareKeyboard = 0x11, | 44 | SoftwareKeyboard = 0x11, |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| @@ -775,6 +777,8 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default; | |||
| 775 | 777 | ||
| 776 | static std::shared_ptr<Applets::Applet> GetAppletFromId(AppletId id) { | 778 | static std::shared_ptr<Applets::Applet> GetAppletFromId(AppletId id) { |
| 777 | switch (id) { | 779 | switch (id) { |
| 780 | case AppletId::ProfileSelect: | ||
| 781 | return std::make_shared<Applets::ProfileSelect>(); | ||
| 778 | case AppletId::SoftwareKeyboard: | 782 | case AppletId::SoftwareKeyboard: |
| 779 | return std::make_shared<Applets::SoftwareKeyboard>(); | 783 | return std::make_shared<Applets::SoftwareKeyboard>(); |
| 780 | default: | 784 | default: |
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp new file mode 100644 index 000000000..4c7b45454 --- /dev/null +++ b/src/core/hle/service/am/applets/profile_select.cpp | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <cstring> | ||
| 6 | |||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/string_util.h" | ||
| 9 | #include "core/core.h" | ||
| 10 | #include "core/frontend/applets/software_keyboard.h" | ||
| 11 | #include "core/hle/service/am/am.h" | ||
| 12 | #include "core/hle/service/am/applets/profile_select.h" | ||
| 13 | |||
| 14 | namespace Service::AM::Applets { | ||
| 15 | |||
| 16 | constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; | ||
| 17 | |||
| 18 | ProfileSelect::ProfileSelect() = default; | ||
| 19 | ProfileSelect::~ProfileSelect() = default; | ||
| 20 | |||
| 21 | void ProfileSelect::Initialize() { | ||
| 22 | complete = false; | ||
| 23 | status = RESULT_SUCCESS; | ||
| 24 | final_data.clear(); | ||
| 25 | |||
| 26 | Applet::Initialize(); | ||
| 27 | |||
| 28 | const auto user_config_storage = broker.PopNormalDataToApplet(); | ||
| 29 | ASSERT(user_config_storage != nullptr); | ||
| 30 | const auto& user_config = user_config_storage->GetData(); | ||
| 31 | |||
| 32 | ASSERT(user_config.size() >= sizeof(UserSelectionConfig)); | ||
| 33 | std::memcpy(&config, user_config.data(), sizeof(UserSelectionConfig)); | ||
| 34 | } | ||
| 35 | |||
| 36 | bool ProfileSelect::TransactionComplete() const { | ||
| 37 | return complete; | ||
| 38 | } | ||
| 39 | |||
| 40 | ResultCode ProfileSelect::GetStatus() const { | ||
| 41 | return status; | ||
| 42 | } | ||
| 43 | |||
| 44 | void ProfileSelect::ExecuteInteractive() { | ||
| 45 | UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); | ||
| 46 | } | ||
| 47 | |||
| 48 | void ProfileSelect::Execute() { | ||
| 49 | if (complete) { | ||
| 50 | broker.PushNormalDataFromApplet(IStorage{final_data}); | ||
| 51 | return; | ||
| 52 | } | ||
| 53 | |||
| 54 | const auto& frontend{Core::System::GetInstance().GetProfileSelector()}; | ||
| 55 | |||
| 56 | frontend.SelectProfile([this](std::optional<Account::UUID> uuid) { SelectionComplete(uuid); }); | ||
| 57 | } | ||
| 58 | |||
| 59 | void ProfileSelect::SelectionComplete(std::optional<Account::UUID> uuid) { | ||
| 60 | UserSelectionOutput output{}; | ||
| 61 | |||
| 62 | if (uuid.has_value() && uuid->uuid != Account::INVALID_UUID) { | ||
| 63 | output.result = 0; | ||
| 64 | output.uuid_selected = uuid->uuid; | ||
| 65 | } else { | ||
| 66 | status = ERR_USER_CANCELLED_SELECTION; | ||
| 67 | output.result = ERR_USER_CANCELLED_SELECTION.raw; | ||
| 68 | output.uuid_selected = Account::INVALID_UUID; | ||
| 69 | } | ||
| 70 | |||
| 71 | final_data = std::vector<u8>(sizeof(UserSelectionOutput)); | ||
| 72 | std::memcpy(final_data.data(), &output, final_data.size()); | ||
| 73 | broker.PushNormalDataFromApplet(IStorage{final_data}); | ||
| 74 | broker.SignalStateChanged(); | ||
| 75 | } | ||
| 76 | |||
| 77 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/profile_select.h b/src/core/hle/service/am/applets/profile_select.h new file mode 100644 index 000000000..787485f22 --- /dev/null +++ b/src/core/hle/service/am/applets/profile_select.h | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "common/common_funcs.h" | ||
| 10 | #include "core/hle/service/acc/profile_manager.h" | ||
| 11 | #include "core/hle/service/am/applets/applets.h" | ||
| 12 | |||
| 13 | namespace Service::AM::Applets { | ||
| 14 | |||
| 15 | struct UserSelectionConfig { | ||
| 16 | // TODO(DarkLordZach): RE this structure | ||
| 17 | // It seems to be flags and the like that determine the UI of the applet on the switch... from | ||
| 18 | // my research this is safe to ignore for now. | ||
| 19 | INSERT_PADDING_BYTES(0xA0); | ||
| 20 | }; | ||
| 21 | static_assert(sizeof(UserSelectionConfig) == 0xA0, "UserSelectionConfig has incorrect size."); | ||
| 22 | |||
| 23 | struct UserSelectionOutput { | ||
| 24 | u64 result; | ||
| 25 | u128 uuid_selected; | ||
| 26 | }; | ||
| 27 | static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has incorrect size."); | ||
| 28 | |||
| 29 | class ProfileSelect final : public Applet { | ||
| 30 | public: | ||
| 31 | ProfileSelect(); | ||
| 32 | ~ProfileSelect() override; | ||
| 33 | |||
| 34 | void Initialize() override; | ||
| 35 | |||
| 36 | bool TransactionComplete() const override; | ||
| 37 | ResultCode GetStatus() const override; | ||
| 38 | void ExecuteInteractive() override; | ||
| 39 | void Execute() override; | ||
| 40 | |||
| 41 | void SelectionComplete(std::optional<Account::UUID> uuid); | ||
| 42 | |||
| 43 | private: | ||
| 44 | UserSelectionConfig config; | ||
| 45 | bool complete = false; | ||
| 46 | ResultCode status = RESULT_SUCCESS; | ||
| 47 | std::vector<u8> final_data; | ||
| 48 | }; | ||
| 49 | |||
| 50 | } // namespace Service::AM::Applets | ||