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.pull/15/head
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 New Issue