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:
parent
88192af8ac
commit
af1183a993
|
@ -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();
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue