diff options
| author | 2022-03-17 05:18:48 -0400 | |
|---|---|---|
| committer | 2022-03-21 23:57:31 -0400 | |
| commit | c50401903f593dbc3fa83cef333e2e957fe18e85 (patch) | |
| tree | 6787bee6f98199da9578dd1d1903805c75955d11 /src | |
| parent | applets/mii: Cleanup MiiEdit applet types (diff) | |
| download | yuzu-c50401903f593dbc3fa83cef333e2e957fe18e85.tar.gz yuzu-c50401903f593dbc3fa83cef333e2e957fe18e85.tar.xz yuzu-c50401903f593dbc3fa83cef333e2e957fe18e85.zip | |
applets/mii: Cleanup MiiEdit applet implementation
This also enables proper support for MiiEdit applets which are used in games with firmware versions prior to 10.2.0 by handling the 2 different versions of applet inputs and outputs.
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/am/applets/applet_mii_edit.cpp | 120 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/applet_mii_edit.h | 9 |
2 files changed, 85 insertions, 44 deletions
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index 769c3c3eb..a97a3295e 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp | |||
| @@ -20,15 +20,44 @@ MiiEdit::MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, | |||
| 20 | MiiEdit::~MiiEdit() = default; | 20 | MiiEdit::~MiiEdit() = default; |
| 21 | 21 | ||
| 22 | void MiiEdit::Initialize() { | 22 | void MiiEdit::Initialize() { |
| 23 | is_complete = false; | 23 | // Note: MiiEdit is not initialized with common arguments. |
| 24 | // Instead, it is initialized by an AppletInput storage with size 0x100 bytes. | ||
| 25 | // Do NOT call Applet::Initialize() here. | ||
| 24 | 26 | ||
| 25 | const auto storage = broker.PopNormalDataToApplet(); | 27 | const auto storage = broker.PopNormalDataToApplet(); |
| 26 | ASSERT(storage != nullptr); | 28 | ASSERT(storage != nullptr); |
| 27 | 29 | ||
| 28 | const auto data = storage->GetData(); | 30 | const auto applet_input_data = storage->GetData(); |
| 29 | ASSERT(data.size() == sizeof(MiiAppletInput)); | 31 | ASSERT(applet_input_data.size() >= sizeof(MiiEditAppletInputCommon)); |
| 30 | 32 | ||
| 31 | std::memcpy(&input_data, data.data(), sizeof(MiiAppletInput)); | 33 | std::memcpy(&applet_input_common, applet_input_data.data(), sizeof(MiiEditAppletInputCommon)); |
| 34 | |||
| 35 | LOG_INFO(Service_AM, | ||
| 36 | "Initializing MiiEdit Applet with MiiEditAppletVersion={} and MiiEditAppletMode={}", | ||
| 37 | applet_input_common.version, applet_input_common.applet_mode); | ||
| 38 | |||
| 39 | switch (applet_input_common.version) { | ||
| 40 | case MiiEditAppletVersion::Version3: | ||
| 41 | ASSERT(applet_input_data.size() == | ||
| 42 | sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV3)); | ||
| 43 | std::memcpy(&applet_input_v3, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), | ||
| 44 | sizeof(MiiEditAppletInputV3)); | ||
| 45 | break; | ||
| 46 | case MiiEditAppletVersion::Version4: | ||
| 47 | ASSERT(applet_input_data.size() == | ||
| 48 | sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV4)); | ||
| 49 | std::memcpy(&applet_input_v4, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), | ||
| 50 | sizeof(MiiEditAppletInputV4)); | ||
| 51 | break; | ||
| 52 | default: | ||
| 53 | UNIMPLEMENTED_MSG("Unknown MiiEditAppletVersion={} with size={}", | ||
| 54 | applet_input_common.version, applet_input_data.size()); | ||
| 55 | ASSERT(applet_input_data.size() >= | ||
| 56 | sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV4)); | ||
| 57 | std::memcpy(&applet_input_v4, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), | ||
| 58 | sizeof(MiiEditAppletInputV4)); | ||
| 59 | break; | ||
| 60 | } | ||
| 32 | } | 61 | } |
| 33 | 62 | ||
| 34 | bool MiiEdit::TransactionComplete() const { | 63 | bool MiiEdit::TransactionComplete() const { |
| @@ -40,7 +69,7 @@ ResultCode MiiEdit::GetStatus() const { | |||
| 40 | } | 69 | } |
| 41 | 70 | ||
| 42 | void MiiEdit::ExecuteInteractive() { | 71 | void MiiEdit::ExecuteInteractive() { |
| 43 | UNREACHABLE_MSG("Unexpected interactive applet data!"); | 72 | UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); |
| 44 | } | 73 | } |
| 45 | 74 | ||
| 46 | void MiiEdit::Execute() { | 75 | void MiiEdit::Execute() { |
| @@ -48,54 +77,63 @@ void MiiEdit::Execute() { | |||
| 48 | return; | 77 | return; |
| 49 | } | 78 | } |
| 50 | 79 | ||
| 51 | const auto callback = [this](const Core::Frontend::MiiParameters& parameters) { | 80 | // This is a default stub for each of the MiiEdit applet modes. |
| 52 | DisplayCompleted(parameters); | 81 | switch (applet_input_common.applet_mode) { |
| 53 | }; | 82 | case MiiEditAppletMode::ShowMiiEdit: |
| 54 | 83 | case MiiEditAppletMode::AppendMii: | |
| 55 | switch (input_data.applet_mode) { | 84 | case MiiEditAppletMode::AppendMiiImage: |
| 56 | case MiiAppletMode::ShowMiiEdit: { | 85 | case MiiEditAppletMode::UpdateMiiImage: |
| 57 | Service::Mii::MiiManager manager; | 86 | MiiEditOutput(MiiEditResult::Success, 0); |
| 58 | Core::Frontend::MiiParameters params{ | ||
| 59 | .is_editable = false, | ||
| 60 | .mii_data = input_data.mii_char_info.mii_data, | ||
| 61 | }; | ||
| 62 | frontend.ShowMii(params, callback); | ||
| 63 | break; | ||
| 64 | } | ||
| 65 | case MiiAppletMode::EditMii: { | ||
| 66 | Service::Mii::MiiManager manager; | ||
| 67 | Core::Frontend::MiiParameters params{ | ||
| 68 | .is_editable = true, | ||
| 69 | .mii_data = input_data.mii_char_info.mii_data, | ||
| 70 | }; | ||
| 71 | frontend.ShowMii(params, callback); | ||
| 72 | break; | 87 | break; |
| 73 | } | 88 | case MiiEditAppletMode::CreateMii: |
| 74 | case MiiAppletMode::CreateMii: { | 89 | case MiiEditAppletMode::EditMii: { |
| 75 | Service::Mii::MiiManager manager; | 90 | Service::Mii::MiiManager mii_manager; |
| 76 | Core::Frontend::MiiParameters params{ | 91 | |
| 77 | .is_editable = true, | 92 | const MiiEditCharInfo char_info{ |
| 78 | .mii_data = manager.BuildDefault(0), | 93 | .mii_info{applet_input_common.applet_mode == MiiEditAppletMode::EditMii |
| 94 | ? applet_input_v4.char_info.mii_info | ||
| 95 | : mii_manager.BuildDefault(0)}, | ||
| 79 | }; | 96 | }; |
| 80 | frontend.ShowMii(params, callback); | 97 | |
| 98 | MiiEditOutputForCharInfoEditing(MiiEditResult::Success, char_info); | ||
| 81 | break; | 99 | break; |
| 82 | } | 100 | } |
| 83 | default: | 101 | default: |
| 84 | UNIMPLEMENTED_MSG("Unimplemented LibAppletMiiEdit mode={:02X}!", input_data.applet_mode); | 102 | UNIMPLEMENTED_MSG("Unknown MiiEditAppletMode={}", applet_input_common.applet_mode); |
| 103 | |||
| 104 | MiiEditOutput(MiiEditResult::Success, 0); | ||
| 105 | break; | ||
| 85 | } | 106 | } |
| 86 | } | 107 | } |
| 87 | 108 | ||
| 88 | void MiiEdit::DisplayCompleted(const Core::Frontend::MiiParameters& parameters) { | 109 | void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) { |
| 110 | const MiiEditAppletOutput applet_output{ | ||
| 111 | .result{result}, | ||
| 112 | .index{index}, | ||
| 113 | }; | ||
| 114 | |||
| 115 | std::vector<u8> out_data(sizeof(MiiEditAppletOutput)); | ||
| 116 | std::memcpy(out_data.data(), &applet_output, sizeof(MiiEditAppletOutput)); | ||
| 117 | |||
| 89 | is_complete = true; | 118 | is_complete = true; |
| 90 | 119 | ||
| 91 | std::vector<u8> reply(sizeof(AppletOutputForCharInfoEditing)); | 120 | broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); |
| 92 | output_data = { | 121 | broker.SignalStateChanged(); |
| 93 | .result = 0, | 122 | } |
| 94 | .mii_data = parameters.mii_data, | 123 | |
| 124 | void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result, | ||
| 125 | const MiiEditCharInfo& char_info) { | ||
| 126 | const MiiEditAppletOutputForCharInfoEditing applet_output{ | ||
| 127 | .result{result}, | ||
| 128 | .char_info{char_info}, | ||
| 95 | }; | 129 | }; |
| 96 | 130 | ||
| 97 | std::memcpy(reply.data(), &output_data, sizeof(AppletOutputForCharInfoEditing)); | 131 | std::vector<u8> out_data(sizeof(MiiEditAppletOutputForCharInfoEditing)); |
| 98 | broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); | 132 | std::memcpy(out_data.data(), &applet_output, sizeof(MiiEditAppletOutputForCharInfoEditing)); |
| 133 | |||
| 134 | is_complete = true; | ||
| 135 | |||
| 136 | broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); | ||
| 99 | broker.SignalStateChanged(); | 137 | broker.SignalStateChanged(); |
| 100 | } | 138 | } |
| 101 | 139 | ||
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.h b/src/core/hle/service/am/applets/applet_mii_edit.h index 2b4b27c8f..e9ca0e2af 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.h +++ b/src/core/hle/service/am/applets/applet_mii_edit.h | |||
| @@ -27,14 +27,17 @@ public: | |||
| 27 | void ExecuteInteractive() override; | 27 | void ExecuteInteractive() override; |
| 28 | void Execute() override; | 28 | void Execute() override; |
| 29 | 29 | ||
| 30 | void DisplayCompleted(const Core::Frontend::MiiParameters& parameters); | 30 | void MiiEditOutput(MiiEditResult result, s32 index); |
| 31 | |||
| 32 | void MiiEditOutputForCharInfoEditing(MiiEditResult result, const MiiEditCharInfo& char_info); | ||
| 31 | 33 | ||
| 32 | private: | 34 | private: |
| 33 | const Core::Frontend::MiiEditApplet& frontend; | 35 | const Core::Frontend::MiiEditApplet& frontend; |
| 34 | Core::System& system; | 36 | Core::System& system; |
| 35 | 37 | ||
| 36 | MiiAppletInput input_data{}; | 38 | MiiEditAppletInputCommon applet_input_common{}; |
| 37 | AppletOutputForCharInfoEditing output_data{}; | 39 | MiiEditAppletInputV3 applet_input_v3{}; |
| 40 | MiiEditAppletInputV4 applet_input_v4{}; | ||
| 38 | 41 | ||
| 39 | bool is_complete{false}; | 42 | bool is_complete{false}; |
| 40 | }; | 43 | }; |