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.
This commit is contained in:
parent
1d5f6b173d
commit
c50401903f
|
@ -20,15 +20,44 @@ MiiEdit::MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_,
|
||||||
MiiEdit::~MiiEdit() = default;
|
MiiEdit::~MiiEdit() = default;
|
||||||
|
|
||||||
void MiiEdit::Initialize() {
|
void MiiEdit::Initialize() {
|
||||||
is_complete = false;
|
// 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();
|
const auto storage = broker.PopNormalDataToApplet();
|
||||||
ASSERT(storage != nullptr);
|
ASSERT(storage != nullptr);
|
||||||
|
|
||||||
const auto data = storage->GetData();
|
const auto applet_input_data = storage->GetData();
|
||||||
ASSERT(data.size() == sizeof(MiiAppletInput));
|
ASSERT(applet_input_data.size() >= sizeof(MiiEditAppletInputCommon));
|
||||||
|
|
||||||
std::memcpy(&input_data, data.data(), sizeof(MiiAppletInput));
|
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 {
|
bool MiiEdit::TransactionComplete() const {
|
||||||
|
@ -40,7 +69,7 @@ ResultCode MiiEdit::GetStatus() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiiEdit::ExecuteInteractive() {
|
void MiiEdit::ExecuteInteractive() {
|
||||||
UNREACHABLE_MSG("Unexpected interactive applet data!");
|
UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiiEdit::Execute() {
|
void MiiEdit::Execute() {
|
||||||
|
@ -48,54 +77,63 @@ void MiiEdit::Execute() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto callback = [this](const Core::Frontend::MiiParameters& parameters) {
|
// This is a default stub for each of the MiiEdit applet modes.
|
||||||
DisplayCompleted(parameters);
|
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)},
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (input_data.applet_mode) {
|
MiiEditOutputForCharInfoEditing(MiiEditResult::Success, char_info);
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
UNIMPLEMENTED_MSG("Unimplemented LibAppletMiiEdit mode={:02X}!", input_data.applet_mode);
|
UNIMPLEMENTED_MSG("Unknown MiiEditAppletMode={}", applet_input_common.applet_mode);
|
||||||
|
|
||||||
|
MiiEditOutput(MiiEditResult::Success, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiiEdit::DisplayCompleted(const Core::Frontend::MiiParameters& parameters) {
|
void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) {
|
||||||
is_complete = true;
|
const MiiEditAppletOutput applet_output{
|
||||||
|
.result{result},
|
||||||
std::vector<u8> reply(sizeof(AppletOutputForCharInfoEditing));
|
.index{index},
|
||||||
output_data = {
|
|
||||||
.result = 0,
|
|
||||||
.mii_data = parameters.mii_data,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::memcpy(reply.data(), &output_data, sizeof(AppletOutputForCharInfoEditing));
|
std::vector<u8> out_data(sizeof(MiiEditAppletOutput));
|
||||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
|
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();
|
broker.SignalStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,14 +27,17 @@ public:
|
||||||
void ExecuteInteractive() override;
|
void ExecuteInteractive() override;
|
||||||
void Execute() override;
|
void Execute() override;
|
||||||
|
|
||||||
void DisplayCompleted(const Core::Frontend::MiiParameters& parameters);
|
void MiiEditOutput(MiiEditResult result, s32 index);
|
||||||
|
|
||||||
|
void MiiEditOutputForCharInfoEditing(MiiEditResult result, const MiiEditCharInfo& char_info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Core::Frontend::MiiEditApplet& frontend;
|
const Core::Frontend::MiiEditApplet& frontend;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
MiiAppletInput input_data{};
|
MiiEditAppletInputCommon applet_input_common{};
|
||||||
AppletOutputForCharInfoEditing output_data{};
|
MiiEditAppletInputV3 applet_input_v3{};
|
||||||
|
MiiEditAppletInputV4 applet_input_v4{};
|
||||||
|
|
||||||
bool is_complete{false};
|
bool is_complete{false};
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue