Browse Source
applets: Implement ProfileSelect applet
applets: Implement ProfileSelect applet
Allows the player to select an emulated profile.pull/15/merge
2 changed files with 130 additions and 0 deletions
-
76src/core/hle/service/am/applets/profile_select.cpp
-
54src/core/hle/service/am/applets/profile_select.h
@ -0,0 +1,76 @@ |
|||
// 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
|
|||
@ -0,0 +1,54 @@ |
|||
// Copyright 2018 yuzu emulator team |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <string> |
|||
#include <vector> |
|||
|
|||
#include "common/common_funcs.h" |
|||
#include "common/swap.h" |
|||
#include "core/hle/service/acc/profile_manager.h" |
|||
#include "core/hle/service/am/am.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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue