applets/controller: Introduce additional checks for mode and caller

Some games like Cave Story+ set invalid values in the ControllerPrivateArg's mode and caller fields.
Use other fields to determine the appropriate mode and caller should either or both fields be invalid.
This commit is contained in:
Morph 2020-11-04 11:21:17 -05:00
parent 88192af8ac
commit af1183a993
2 changed files with 39 additions and 5 deletions

View file

@ -75,6 +75,36 @@ void Controller::Initialize() {
"Unknown ControllerSupportArgPrivate revision={} with size={}", "Unknown ControllerSupportArgPrivate revision={} with size={}",
library_applet_version, controller_private_arg.arg_private_size); library_applet_version, controller_private_arg.arg_private_size);
// Some games such as Cave Story+ set invalid values for the ControllerSupportMode.
// Defer to arg_size to set the ControllerSupportMode.
if (controller_private_arg.mode >= ControllerSupportMode::MaxControllerSupportMode) {
switch (controller_private_arg.arg_size) {
case sizeof(ControllerSupportArgOld):
case sizeof(ControllerSupportArgNew):
controller_private_arg.mode = ControllerSupportMode::ShowControllerSupport;
break;
case sizeof(ControllerUpdateFirmwareArg):
controller_private_arg.mode = ControllerSupportMode::ShowControllerFirmwareUpdate;
break;
default:
UNIMPLEMENTED_MSG("Unknown ControllerPrivateArg mode={} with arg_size={}",
controller_private_arg.mode, controller_private_arg.arg_size);
controller_private_arg.mode = ControllerSupportMode::ShowControllerSupport;
break;
}
}
// Some games such as Cave Story+ set invalid values for the ControllerSupportCaller.
// This is always 0 (Application) except with ShowControllerFirmwareUpdateForSystem.
if (controller_private_arg.caller >= ControllerSupportCaller::MaxControllerSupportCaller) {
if (controller_private_arg.flag_1 &&
controller_private_arg.mode == ControllerSupportMode::ShowControllerFirmwareUpdate) {
controller_private_arg.caller = ControllerSupportCaller::System;
} else {
controller_private_arg.caller = ControllerSupportCaller::Application;
}
}
switch (controller_private_arg.mode) { switch (controller_private_arg.mode) {
case ControllerSupportMode::ShowControllerSupport: { case ControllerSupportMode::ShowControllerSupport: {
const auto user_arg_storage = broker.PopNormalDataToApplet(); const auto user_arg_storage = broker.PopNormalDataToApplet();

View file

@ -29,14 +29,18 @@ enum class LibraryAppletVersion : u32_le {
}; };
enum class ControllerSupportMode : u8 { enum class ControllerSupportMode : u8 {
ShowControllerSupport = 0, ShowControllerSupport,
ShowControllerStrapGuide = 1, ShowControllerStrapGuide,
ShowControllerFirmwareUpdate = 2, ShowControllerFirmwareUpdate,
MaxControllerSupportMode,
}; };
enum class ControllerSupportCaller : u8 { enum class ControllerSupportCaller : u8 {
Application = 0, Application,
System = 1, System,
MaxControllerSupportCaller,
}; };
struct ControllerSupportArgPrivate { struct ControllerSupportArgPrivate {