summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMorph <39850852+Morph1984@users.noreply.github.com>2020-11-04 11:21:17 -0500
committerMorph <39850852+Morph1984@users.noreply.github.com>2020-11-08 09:35:25 -0500
commitaf1183a9938d885a643efaf28397235a4d1bd2ef (patch)
tree6b0b18255c82d58695bfd1b164525098b05af6ac /src
parent88192af8ace632ed37fd1ec0406e84ed083e5301 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/applets/controller.cpp30
-rw-r--r--src/core/hle/service/am/applets/controller.h14
2 files changed, 39 insertions, 5 deletions
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index 2151da783..6b8eeabf4 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -75,6 +75,36 @@ void Controller::Initialize() {
"Unknown ControllerSupportArgPrivate revision={} with 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) {
case ControllerSupportMode::ShowControllerSupport: {
const auto user_arg_storage = broker.PopNormalDataToApplet();
diff --git a/src/core/hle/service/am/applets/controller.h b/src/core/hle/service/am/applets/controller.h
index 86269190b..05788966e 100644
--- a/src/core/hle/service/am/applets/controller.h
+++ b/src/core/hle/service/am/applets/controller.h
@@ -29,14 +29,18 @@ enum class LibraryAppletVersion : u32_le {
};
enum class ControllerSupportMode : u8 {
- ShowControllerSupport = 0,
- ShowControllerStrapGuide = 1,
- ShowControllerFirmwareUpdate = 2,
+ ShowControllerSupport,
+ ShowControllerStrapGuide,
+ ShowControllerFirmwareUpdate,
+
+ MaxControllerSupportMode,
};
enum class ControllerSupportCaller : u8 {
- Application = 0,
- System = 1,
+ Application,
+ System,
+
+ MaxControllerSupportCaller,
};
struct ControllerSupportArgPrivate {