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