diff options
Diffstat (limited to 'src/core/hle/service/am/applets')
-rw-r--r-- | src/core/hle/service/am/applets/applet_mii.cpp | 100 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_mii.h | 90 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_mii_edit.cpp | 139 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_mii_edit.h | 45 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_mii_edit_types.h | 83 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applets.cpp | 28 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applets.h | 8 |
7 files changed, 285 insertions, 208 deletions
diff --git a/src/core/hle/service/am/applets/applet_mii.cpp b/src/core/hle/service/am/applets/applet_mii.cpp deleted file mode 100644 index facede97e..000000000 --- a/src/core/hle/service/am/applets/applet_mii.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2022 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/assert.h" -#include "common/logging/log.h" -#include "core/core.h" -#include "core/frontend/applets/mii.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_mii.h" - -namespace Service::AM::Applets { - -Mii::Mii(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::MiiApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} - -Mii::~Mii() = default; - -void Mii::Initialize() { - is_complete = false; - - const auto storage = broker.PopNormalDataToApplet(); - ASSERT(storage != nullptr); - - const auto data = storage->GetData(); - ASSERT(data.size() == sizeof(MiiAppletInput)); - - std::memcpy(&input_data, data.data(), sizeof(MiiAppletInput)); -} - -bool Mii::TransactionComplete() const { - return is_complete; -} - -ResultCode Mii::GetStatus() const { - return ResultSuccess; -} - -void Mii::ExecuteInteractive() { - UNREACHABLE_MSG("Unexpected interactive applet data!"); -} - -void Mii::Execute() { - if (is_complete) { - return; - } - - const auto callback = [this](const Core::Frontend::MiiParameters& parameters) { - DisplayCompleted(parameters); - }; - - switch (input_data.applet_mode) { - case MiiAppletMode::ShowMiiEdit: { - Service::Mii::MiiManager manager; - Core::Frontend::MiiParameters params{ - .is_editable = false, - .mii_data = input_data.mii_char_info.mii_data, - }; - frontend.ShowMii(params, callback); - break; - } - case MiiAppletMode::EditMii: { - Service::Mii::MiiManager manager; - Core::Frontend::MiiParameters params{ - .is_editable = true, - .mii_data = input_data.mii_char_info.mii_data, - }; - frontend.ShowMii(params, callback); - break; - } - case MiiAppletMode::CreateMii: { - Service::Mii::MiiManager manager; - Core::Frontend::MiiParameters params{ - .is_editable = true, - .mii_data = manager.BuildDefault(0), - }; - frontend.ShowMii(params, callback); - break; - } - default: - UNIMPLEMENTED_MSG("Unimplemented LibAppletMiiEdit mode={:02X}!", input_data.applet_mode); - } -} - -void Mii::DisplayCompleted(const Core::Frontend::MiiParameters& parameters) { - is_complete = true; - - std::vector<u8> reply(sizeof(AppletOutputForCharInfoEditing)); - output_data = { - .result = ResultSuccess, - .mii_data = parameters.mii_data, - }; - - std::memcpy(reply.data(), &output_data, sizeof(AppletOutputForCharInfoEditing)); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); - broker.SignalStateChanged(); -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_mii.h b/src/core/hle/service/am/applets/applet_mii.h deleted file mode 100644 index 42326bfc2..000000000 --- a/src/core/hle/service/am/applets/applet_mii.h +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2022 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include <array> - -#include "core/hle/result.h" -#include "core/hle/service/am/applets/applets.h" -#include "core/hle/service/mii/mii_manager.h" - -namespace Core { -class System; -} - -namespace Service::AM::Applets { - -// This is nn::mii::AppletMode -enum class MiiAppletMode : u32 { - ShowMiiEdit = 0, - AppendMii = 1, - AppendMiiImage = 2, - UpdateMiiImage = 3, - CreateMii = 4, - EditMii = 5, -}; - -struct MiiCharInfo { - Service::Mii::MiiInfo mii_data{}; - INSERT_PADDING_BYTES(0x28); -}; -static_assert(sizeof(MiiCharInfo) == 0x80, "MiiCharInfo has incorrect size."); - -// This is nn::mii::AppletInput -struct MiiAppletInput { - s32 version{}; - MiiAppletMode applet_mode{}; - u32 special_mii_key_code{}; - union { - std::array<Common::UUID, 8> valid_uuid; - MiiCharInfo mii_char_info; - }; - Common::UUID used_uuid; - INSERT_PADDING_BYTES(0x64); -}; -static_assert(sizeof(MiiAppletInput) == 0x100, "MiiAppletInput has incorrect size."); - -// This is nn::mii::AppletOutput -struct MiiAppletOutput { - ResultCode result{ResultSuccess}; - s32 index{}; - INSERT_PADDING_BYTES(0x18); -}; -static_assert(sizeof(MiiAppletOutput) == 0x20, "MiiAppletOutput has incorrect size."); - -// This is nn::mii::AppletOutputForCharInfoEditing -struct AppletOutputForCharInfoEditing { - ResultCode result{ResultSuccess}; - Service::Mii::MiiInfo mii_data{}; - INSERT_PADDING_BYTES(0x24); -}; -static_assert(sizeof(AppletOutputForCharInfoEditing) == 0x80, - "AppletOutputForCharInfoEditing has incorrect size."); - -class Mii final : public Applet { -public: - explicit Mii(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::MiiApplet& frontend_); - ~Mii() override; - - void Initialize() override; - - bool TransactionComplete() const override; - ResultCode GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - - void DisplayCompleted(const Core::Frontend::MiiParameters& parameters); - -private: - const Core::Frontend::MiiApplet& frontend; - MiiAppletInput input_data{}; - AppletOutputForCharInfoEditing output_data{}; - - bool is_complete = false; - Core::System& system; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp new file mode 100644 index 000000000..8fbde1be4 --- /dev/null +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp @@ -0,0 +1,139 @@ +// Copyright 2022 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/core.h" +#include "core/frontend/applets/mii_edit.h" +#include "core/hle/service/am/am.h" +#include "core/hle/service/am/applets/applet_mii_edit.h" +#include "core/hle/service/mii/mii_manager.h" + +namespace Service::AM::Applets { + +MiiEdit::MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, + const Core::Frontend::MiiEditApplet& frontend_) + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} + +MiiEdit::~MiiEdit() = default; + +void MiiEdit::Initialize() { + // Note: MiiEdit is not initialized with common arguments. + // Instead, it is initialized by an AppletInput storage with size 0x100 bytes. + // Do NOT call Applet::Initialize() here. + + const auto storage = broker.PopNormalDataToApplet(); + ASSERT(storage != nullptr); + + const auto applet_input_data = storage->GetData(); + ASSERT(applet_input_data.size() >= sizeof(MiiEditAppletInputCommon)); + + std::memcpy(&applet_input_common, applet_input_data.data(), sizeof(MiiEditAppletInputCommon)); + + LOG_INFO(Service_AM, + "Initializing MiiEdit Applet with MiiEditAppletVersion={} and MiiEditAppletMode={}", + applet_input_common.version, applet_input_common.applet_mode); + + switch (applet_input_common.version) { + case MiiEditAppletVersion::Version3: + ASSERT(applet_input_data.size() == + sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV3)); + std::memcpy(&applet_input_v3, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), + sizeof(MiiEditAppletInputV3)); + break; + case MiiEditAppletVersion::Version4: + ASSERT(applet_input_data.size() == + sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV4)); + std::memcpy(&applet_input_v4, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), + sizeof(MiiEditAppletInputV4)); + break; + default: + UNIMPLEMENTED_MSG("Unknown MiiEditAppletVersion={} with size={}", + applet_input_common.version, applet_input_data.size()); + ASSERT(applet_input_data.size() >= + sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV4)); + std::memcpy(&applet_input_v4, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), + sizeof(MiiEditAppletInputV4)); + break; + } +} + +bool MiiEdit::TransactionComplete() const { + return is_complete; +} + +ResultCode MiiEdit::GetStatus() const { + return ResultSuccess; +} + +void MiiEdit::ExecuteInteractive() { + UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); +} + +void MiiEdit::Execute() { + if (is_complete) { + return; + } + + // This is a default stub for each of the MiiEdit applet modes. + switch (applet_input_common.applet_mode) { + case MiiEditAppletMode::ShowMiiEdit: + case MiiEditAppletMode::AppendMii: + case MiiEditAppletMode::AppendMiiImage: + case MiiEditAppletMode::UpdateMiiImage: + MiiEditOutput(MiiEditResult::Success, 0); + break; + case MiiEditAppletMode::CreateMii: + case MiiEditAppletMode::EditMii: { + Service::Mii::MiiManager mii_manager; + + const MiiEditCharInfo char_info{ + .mii_info{applet_input_common.applet_mode == MiiEditAppletMode::EditMii + ? applet_input_v4.char_info.mii_info + : mii_manager.BuildDefault(0)}, + }; + + MiiEditOutputForCharInfoEditing(MiiEditResult::Success, char_info); + break; + } + default: + UNIMPLEMENTED_MSG("Unknown MiiEditAppletMode={}", applet_input_common.applet_mode); + + MiiEditOutput(MiiEditResult::Success, 0); + break; + } +} + +void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) { + const MiiEditAppletOutput applet_output{ + .result{result}, + .index{index}, + }; + + std::vector<u8> out_data(sizeof(MiiEditAppletOutput)); + std::memcpy(out_data.data(), &applet_output, sizeof(MiiEditAppletOutput)); + + is_complete = true; + + broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); + broker.SignalStateChanged(); +} + +void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result, + const MiiEditCharInfo& char_info) { + const MiiEditAppletOutputForCharInfoEditing applet_output{ + .result{result}, + .char_info{char_info}, + }; + + std::vector<u8> out_data(sizeof(MiiEditAppletOutputForCharInfoEditing)); + std::memcpy(out_data.data(), &applet_output, sizeof(MiiEditAppletOutputForCharInfoEditing)); + + is_complete = true; + + broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); + broker.SignalStateChanged(); +} + +} // 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 new file mode 100644 index 000000000..e9ca0e2af --- /dev/null +++ b/src/core/hle/service/am/applets/applet_mii_edit.h @@ -0,0 +1,45 @@ +// Copyright 2022 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/result.h" +#include "core/hle/service/am/applets/applet_mii_edit_types.h" +#include "core/hle/service/am/applets/applets.h" + +namespace Core { +class System; +} // namespace Core + +namespace Service::AM::Applets { + +class MiiEdit final : public Applet { +public: + explicit MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, + const Core::Frontend::MiiEditApplet& frontend_); + ~MiiEdit() override; + + void Initialize() override; + + bool TransactionComplete() const override; + ResultCode GetStatus() const override; + void ExecuteInteractive() override; + void Execute() override; + + void MiiEditOutput(MiiEditResult result, s32 index); + + void MiiEditOutputForCharInfoEditing(MiiEditResult result, const MiiEditCharInfo& char_info); + +private: + const Core::Frontend::MiiEditApplet& frontend; + Core::System& system; + + MiiEditAppletInputCommon applet_input_common{}; + MiiEditAppletInputV3 applet_input_v3{}; + MiiEditAppletInputV4 applet_input_v4{}; + + bool is_complete{false}; +}; + +} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_mii_edit_types.h b/src/core/hle/service/am/applets/applet_mii_edit_types.h new file mode 100644 index 000000000..70dea0007 --- /dev/null +++ b/src/core/hle/service/am/applets/applet_mii_edit_types.h @@ -0,0 +1,83 @@ +// Copyright 2022 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> + +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "core/hle/service/mii/types.h" + +namespace Service::AM::Applets { + +enum class MiiEditAppletVersion : s32 { + Version3 = 0x3, // 1.0.0 - 10.1.1 + Version4 = 0x4, // 10.2.0+ +}; + +// This is nn::mii::AppletMode +enum class MiiEditAppletMode : u32 { + ShowMiiEdit = 0, + AppendMii = 1, + AppendMiiImage = 2, + UpdateMiiImage = 3, + CreateMii = 4, + EditMii = 5, +}; + +enum class MiiEditResult : u32 { + Success, + Cancel, +}; + +struct MiiEditCharInfo { + Service::Mii::MiiInfo mii_info{}; +}; +static_assert(sizeof(MiiEditCharInfo) == 0x58, "MiiEditCharInfo has incorrect size."); + +struct MiiEditAppletInputCommon { + MiiEditAppletVersion version{}; + MiiEditAppletMode applet_mode{}; +}; +static_assert(sizeof(MiiEditAppletInputCommon) == 0x8, + "MiiEditAppletInputCommon has incorrect size."); + +struct MiiEditAppletInputV3 { + u32 special_mii_key_code{}; + std::array<Common::UUID, 8> valid_uuids{}; + Common::UUID used_uuid{}; + INSERT_PADDING_BYTES(0x64); +}; +static_assert(sizeof(MiiEditAppletInputV3) == 0x100 - sizeof(MiiEditAppletInputCommon), + "MiiEditAppletInputV3 has incorrect size."); + +struct MiiEditAppletInputV4 { + u32 special_mii_key_code{}; + MiiEditCharInfo char_info{}; + INSERT_PADDING_BYTES(0x28); + Common::UUID used_uuid{}; + INSERT_PADDING_BYTES(0x64); +}; +static_assert(sizeof(MiiEditAppletInputV4) == 0x100 - sizeof(MiiEditAppletInputCommon), + "MiiEditAppletInputV4 has incorrect size."); + +// This is nn::mii::AppletOutput +struct MiiEditAppletOutput { + MiiEditResult result{}; + s32 index{}; + INSERT_PADDING_BYTES(0x18); +}; +static_assert(sizeof(MiiEditAppletOutput) == 0x20, "MiiEditAppletOutput has incorrect size."); + +// This is nn::mii::AppletOutputForCharInfoEditing +struct MiiEditAppletOutputForCharInfoEditing { + MiiEditResult result{}; + MiiEditCharInfo char_info{}; + INSERT_PADDING_BYTES(0x24); +}; +static_assert(sizeof(MiiEditAppletOutputForCharInfoEditing) == 0x80, + "MiiEditAppletOutputForCharInfoEditing has incorrect size."); + +} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 79e62679d..1f4c9786a 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -9,7 +9,7 @@ #include "core/frontend/applets/controller.h" #include "core/frontend/applets/error.h" #include "core/frontend/applets/general_frontend.h" -#include "core/frontend/applets/mii.h" +#include "core/frontend/applets/mii_edit.h" #include "core/frontend/applets/profile_select.h" #include "core/frontend/applets/software_keyboard.h" #include "core/frontend/applets/web_browser.h" @@ -20,7 +20,7 @@ #include "core/hle/service/am/applets/applet_controller.h" #include "core/hle/service/am/applets/applet_error.h" #include "core/hle/service/am/applets/applet_general_backend.h" -#include "core/hle/service/am/applets/applet_mii.h" +#include "core/hle/service/am/applets/applet_mii_edit.h" #include "core/hle/service/am/applets/applet_profile_select.h" #include "core/hle/service/am/applets/applet_software_keyboard.h" #include "core/hle/service/am/applets/applet_web_browser.h" @@ -173,12 +173,12 @@ void Applet::Initialize() { AppletFrontendSet::AppletFrontendSet() = default; AppletFrontendSet::AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, + MiiEdit mii_edit_, ParentalControlsApplet parental_controls_applet, - MiiApplet mii_applet, PhotoViewer photo_viewer_, - ProfileSelect profile_select_, + PhotoViewer photo_viewer_, ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_, WebBrowser web_browser_) : controller{std::move(controller_applet)}, error{std::move(error_applet)}, - parental_controls{std::move(parental_controls_applet)}, mii{std::move(mii_applet)}, + mii_edit{std::move(mii_edit_)}, parental_controls{std::move(parental_controls_applet)}, photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)}, software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {} @@ -205,12 +205,12 @@ void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { frontend.error = std::move(set.error); } - if (set.parental_controls != nullptr) { - frontend.parental_controls = std::move(set.parental_controls); + if (set.mii_edit != nullptr) { + frontend.mii_edit = std::move(set.mii_edit); } - if (set.mii != nullptr) { - frontend.mii = std::move(set.mii); + if (set.parental_controls != nullptr) { + frontend.parental_controls = std::move(set.parental_controls); } if (set.photo_viewer != nullptr) { @@ -245,15 +245,15 @@ void AppletManager::SetDefaultAppletsIfMissing() { frontend.error = std::make_unique<Core::Frontend::DefaultErrorApplet>(); } + if (frontend.mii_edit == nullptr) { + frontend.mii_edit = std::make_unique<Core::Frontend::DefaultMiiEditApplet>(); + } + if (frontend.parental_controls == nullptr) { frontend.parental_controls = std::make_unique<Core::Frontend::DefaultParentalControlsApplet>(); } - if (frontend.mii == nullptr) { - frontend.mii = std::make_unique<Core::Frontend::DefaultMiiApplet>(); - } - if (frontend.photo_viewer == nullptr) { frontend.photo_viewer = std::make_unique<Core::Frontend::DefaultPhotoViewerApplet>(); } @@ -289,7 +289,7 @@ std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode case AppletId::SoftwareKeyboard: return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard); case AppletId::MiiEdit: - return std::make_shared<Mii>(system, mode, *frontend.mii); + return std::make_shared<MiiEdit>(system, mode, *frontend.mii_edit); case AppletId::Web: case AppletId::Shop: case AppletId::OfflineWeb: diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 0c44aec79..50a7bdceb 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -20,8 +20,8 @@ namespace Core::Frontend { class ControllerApplet; class ECommerceApplet; class ErrorApplet; +class MiiEditApplet; class ParentalControlsApplet; -class MiiApplet; class PhotoViewerApplet; class ProfileSelectApplet; class SoftwareKeyboardApplet; @@ -179,8 +179,8 @@ protected: struct AppletFrontendSet { using ControllerApplet = std::unique_ptr<Core::Frontend::ControllerApplet>; using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>; + using MiiEdit = std::unique_ptr<Core::Frontend::MiiEditApplet>; using ParentalControlsApplet = std::unique_ptr<Core::Frontend::ParentalControlsApplet>; - using MiiApplet = std::unique_ptr<Core::Frontend::MiiApplet>; using PhotoViewer = std::unique_ptr<Core::Frontend::PhotoViewerApplet>; using ProfileSelect = std::unique_ptr<Core::Frontend::ProfileSelectApplet>; using SoftwareKeyboard = std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet>; @@ -188,7 +188,7 @@ struct AppletFrontendSet { AppletFrontendSet(); AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, - ParentalControlsApplet parental_controls_applet, MiiApplet mii_applet, + MiiEdit mii_edit_, ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_, ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_, WebBrowser web_browser_); ~AppletFrontendSet(); @@ -201,8 +201,8 @@ struct AppletFrontendSet { ControllerApplet controller; ErrorApplet error; + MiiEdit mii_edit; ParentalControlsApplet parental_controls; - MiiApplet mii; PhotoViewer photo_viewer; ProfileSelect profile_select; SoftwareKeyboard software_keyboard; |