summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2020-11-12 21:55:06 -0800
committerGravatar GitHub2020-11-12 21:55:06 -0800
commit87f220efff9970440b7535cbb208d310f8c55a7b (patch)
tree2b87788c581d5a54bc27ee2789b4748bb495e9a8
parentMerge pull request #4901 from bunnei/caps-stub (diff)
parentapplets: Rename LibraryAppletVersion to ControllerAppletVersion (diff)
downloadyuzu-87f220efff9970440b7535cbb208d310f8c55a7b.tar.gz
yuzu-87f220efff9970440b7535cbb208d310f8c55a7b.tar.xz
yuzu-87f220efff9970440b7535cbb208d310f8c55a7b.zip
Merge pull request #4895 from Morph1984/cave-story-plus-applet-fix
applets/controller: Introduce additional checks for mode and caller
-rw-r--r--src/core/hle/service/am/applets/controller.cpp80
-rw-r--r--src/core/hle/service/am/applets/controller.h26
2 files changed, 80 insertions, 26 deletions
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index 2151da783..a0152b4ea 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -62,7 +62,7 @@ void Controller::Initialize() {
62 common_args.play_startup_sound, common_args.size, common_args.system_tick, 62 common_args.play_startup_sound, common_args.size, common_args.system_tick,
63 common_args.theme_color); 63 common_args.theme_color);
64 64
65 library_applet_version = LibraryAppletVersion{common_args.library_version}; 65 controller_applet_version = ControllerAppletVersion{common_args.library_version};
66 66
67 const auto private_arg_storage = broker.PopNormalDataToApplet(); 67 const auto private_arg_storage = broker.PopNormalDataToApplet();
68 ASSERT(private_arg_storage != nullptr); 68 ASSERT(private_arg_storage != nullptr);
@@ -70,39 +70,78 @@ void Controller::Initialize() {
70 const auto& private_arg = private_arg_storage->GetData(); 70 const auto& private_arg = private_arg_storage->GetData();
71 ASSERT(private_arg.size() == sizeof(ControllerSupportArgPrivate)); 71 ASSERT(private_arg.size() == sizeof(ControllerSupportArgPrivate));
72 72
73 std::memcpy(&controller_private_arg, private_arg.data(), sizeof(ControllerSupportArgPrivate)); 73 std::memcpy(&controller_private_arg, private_arg.data(), private_arg.size());
74 ASSERT_MSG(controller_private_arg.arg_private_size == sizeof(ControllerSupportArgPrivate), 74 ASSERT_MSG(controller_private_arg.arg_private_size == sizeof(ControllerSupportArgPrivate),
75 "Unknown ControllerSupportArgPrivate revision={} with size={}", 75 "Unknown ControllerSupportArgPrivate revision={} with size={}",
76 library_applet_version, controller_private_arg.arg_private_size); 76 controller_applet_version, controller_private_arg.arg_private_size);
77
78 // Some games such as Cave Story+ set invalid values for the ControllerSupportMode.
79 // Defer to arg_size to set the ControllerSupportMode.
80 if (controller_private_arg.mode >= ControllerSupportMode::MaxControllerSupportMode) {
81 switch (controller_private_arg.arg_size) {
82 case sizeof(ControllerSupportArgOld):
83 case sizeof(ControllerSupportArgNew):
84 controller_private_arg.mode = ControllerSupportMode::ShowControllerSupport;
85 break;
86 case sizeof(ControllerUpdateFirmwareArg):
87 controller_private_arg.mode = ControllerSupportMode::ShowControllerFirmwareUpdate;
88 break;
89 default:
90 UNIMPLEMENTED_MSG("Unknown ControllerPrivateArg mode={} with arg_size={}",
91 controller_private_arg.mode, controller_private_arg.arg_size);
92 controller_private_arg.mode = ControllerSupportMode::ShowControllerSupport;
93 break;
94 }
95 }
96
97 // Some games such as Cave Story+ set invalid values for the ControllerSupportCaller.
98 // This is always 0 (Application) except with ShowControllerFirmwareUpdateForSystem.
99 if (controller_private_arg.caller >= ControllerSupportCaller::MaxControllerSupportCaller) {
100 if (controller_private_arg.flag_1 &&
101 controller_private_arg.mode == ControllerSupportMode::ShowControllerFirmwareUpdate) {
102 controller_private_arg.caller = ControllerSupportCaller::System;
103 } else {
104 controller_private_arg.caller = ControllerSupportCaller::Application;
105 }
106 }
77 107
78 switch (controller_private_arg.mode) { 108 switch (controller_private_arg.mode) {
79 case ControllerSupportMode::ShowControllerSupport: { 109 case ControllerSupportMode::ShowControllerSupport:
110 case ControllerSupportMode::ShowControllerStrapGuide: {
80 const auto user_arg_storage = broker.PopNormalDataToApplet(); 111 const auto user_arg_storage = broker.PopNormalDataToApplet();
81 ASSERT(user_arg_storage != nullptr); 112 ASSERT(user_arg_storage != nullptr);
82 113
83 const auto& user_arg = user_arg_storage->GetData(); 114 const auto& user_arg = user_arg_storage->GetData();
84 switch (library_applet_version) { 115 switch (controller_applet_version) {
85 case LibraryAppletVersion::Version3: 116 case ControllerAppletVersion::Version3:
86 case LibraryAppletVersion::Version4: 117 case ControllerAppletVersion::Version4:
87 case LibraryAppletVersion::Version5: 118 case ControllerAppletVersion::Version5:
88 ASSERT(user_arg.size() == sizeof(ControllerSupportArgOld)); 119 ASSERT(user_arg.size() == sizeof(ControllerSupportArgOld));
89 std::memcpy(&controller_user_arg_old, user_arg.data(), sizeof(ControllerSupportArgOld)); 120 std::memcpy(&controller_user_arg_old, user_arg.data(), user_arg.size());
90 break; 121 break;
91 case LibraryAppletVersion::Version7: 122 case ControllerAppletVersion::Version7:
92 ASSERT(user_arg.size() == sizeof(ControllerSupportArgNew)); 123 ASSERT(user_arg.size() == sizeof(ControllerSupportArgNew));
93 std::memcpy(&controller_user_arg_new, user_arg.data(), sizeof(ControllerSupportArgNew)); 124 std::memcpy(&controller_user_arg_new, user_arg.data(), user_arg.size());
94 break; 125 break;
95 default: 126 default:
96 UNIMPLEMENTED_MSG("Unknown ControllerSupportArg revision={} with size={}", 127 UNIMPLEMENTED_MSG("Unknown ControllerSupportArg revision={} with size={}",
97 library_applet_version, controller_private_arg.arg_size); 128 controller_applet_version, controller_private_arg.arg_size);
98 ASSERT(user_arg.size() >= sizeof(ControllerSupportArgNew)); 129 ASSERT(user_arg.size() >= sizeof(ControllerSupportArgNew));
99 std::memcpy(&controller_user_arg_new, user_arg.data(), sizeof(ControllerSupportArgNew)); 130 std::memcpy(&controller_user_arg_new, user_arg.data(), sizeof(ControllerSupportArgNew));
100 break; 131 break;
101 } 132 }
102 break; 133 break;
103 } 134 }
104 case ControllerSupportMode::ShowControllerStrapGuide: 135 case ControllerSupportMode::ShowControllerFirmwareUpdate: {
105 case ControllerSupportMode::ShowControllerFirmwareUpdate: 136 const auto update_arg_storage = broker.PopNormalDataToApplet();
137 ASSERT(update_arg_storage != nullptr);
138
139 const auto& update_arg = update_arg_storage->GetData();
140 ASSERT(update_arg.size() == sizeof(ControllerUpdateFirmwareArg));
141
142 std::memcpy(&controller_update_arg, update_arg.data(), update_arg.size());
143 break;
144 }
106 default: { 145 default: {
107 UNIMPLEMENTED_MSG("Unimplemented ControllerSupportMode={}", controller_private_arg.mode); 146 UNIMPLEMENTED_MSG("Unimplemented ControllerSupportMode={}", controller_private_arg.mode);
108 break; 147 break;
@@ -126,10 +165,10 @@ void Controller::Execute() {
126 switch (controller_private_arg.mode) { 165 switch (controller_private_arg.mode) {
127 case ControllerSupportMode::ShowControllerSupport: { 166 case ControllerSupportMode::ShowControllerSupport: {
128 const auto parameters = [this] { 167 const auto parameters = [this] {
129 switch (library_applet_version) { 168 switch (controller_applet_version) {
130 case LibraryAppletVersion::Version3: 169 case ControllerAppletVersion::Version3:
131 case LibraryAppletVersion::Version4: 170 case ControllerAppletVersion::Version4:
132 case LibraryAppletVersion::Version5: 171 case ControllerAppletVersion::Version5:
133 return ConvertToFrontendParameters( 172 return ConvertToFrontendParameters(
134 controller_private_arg, controller_user_arg_old.header, 173 controller_private_arg, controller_user_arg_old.header,
135 controller_user_arg_old.enable_explain_text, 174 controller_user_arg_old.enable_explain_text,
@@ -138,7 +177,7 @@ void Controller::Execute() {
138 controller_user_arg_old.identification_colors.end()), 177 controller_user_arg_old.identification_colors.end()),
139 std::vector<ExplainText>(controller_user_arg_old.explain_text.begin(), 178 std::vector<ExplainText>(controller_user_arg_old.explain_text.begin(),
140 controller_user_arg_old.explain_text.end())); 179 controller_user_arg_old.explain_text.end()));
141 case LibraryAppletVersion::Version7: 180 case ControllerAppletVersion::Version7:
142 default: 181 default:
143 return ConvertToFrontendParameters( 182 return ConvertToFrontendParameters(
144 controller_private_arg, controller_user_arg_new.header, 183 controller_private_arg, controller_user_arg_new.header,
@@ -170,6 +209,9 @@ void Controller::Execute() {
170 } 209 }
171 case ControllerSupportMode::ShowControllerStrapGuide: 210 case ControllerSupportMode::ShowControllerStrapGuide:
172 case ControllerSupportMode::ShowControllerFirmwareUpdate: 211 case ControllerSupportMode::ShowControllerFirmwareUpdate:
212 UNIMPLEMENTED_MSG("ControllerSupportMode={} is not implemented",
213 controller_private_arg.mode);
214 [[fallthrough]];
173 default: { 215 default: {
174 ConfigurationComplete(); 216 ConfigurationComplete();
175 break; 217 break;
diff --git a/src/core/hle/service/am/applets/controller.h b/src/core/hle/service/am/applets/controller.h
index f7bb3fba9..a7a1f2b65 100644
--- a/src/core/hle/service/am/applets/controller.h
+++ b/src/core/hle/service/am/applets/controller.h
@@ -21,7 +21,7 @@ namespace Service::AM::Applets {
21using IdentificationColor = std::array<u8, 4>; 21using IdentificationColor = std::array<u8, 4>;
22using ExplainText = std::array<char, 0x81>; 22using ExplainText = std::array<char, 0x81>;
23 23
24enum class LibraryAppletVersion : u32_le { 24enum class ControllerAppletVersion : u32_le {
25 Version3 = 0x3, // 1.0.0 - 2.3.0 25 Version3 = 0x3, // 1.0.0 - 2.3.0
26 Version4 = 0x4, // 3.0.0 - 5.1.0 26 Version4 = 0x4, // 3.0.0 - 5.1.0
27 Version5 = 0x5, // 6.0.0 - 7.0.1 27 Version5 = 0x5, // 6.0.0 - 7.0.1
@@ -29,14 +29,18 @@ enum class LibraryAppletVersion : u32_le {
29}; 29};
30 30
31enum class ControllerSupportMode : u8 { 31enum class ControllerSupportMode : u8 {
32 ShowControllerSupport = 0, 32 ShowControllerSupport,
33 ShowControllerStrapGuide = 1, 33 ShowControllerStrapGuide,
34 ShowControllerFirmwareUpdate = 2, 34 ShowControllerFirmwareUpdate,
35
36 MaxControllerSupportMode,
35}; 37};
36 38
37enum class ControllerSupportCaller : u8 { 39enum class ControllerSupportCaller : u8 {
38 Application = 0, 40 Application,
39 System = 1, 41 System,
42
43 MaxControllerSupportCaller,
40}; 44};
41 45
42struct ControllerSupportArgPrivate { 46struct ControllerSupportArgPrivate {
@@ -84,6 +88,13 @@ struct ControllerSupportArgNew {
84static_assert(sizeof(ControllerSupportArgNew) == 0x430, 88static_assert(sizeof(ControllerSupportArgNew) == 0x430,
85 "ControllerSupportArgNew has incorrect size."); 89 "ControllerSupportArgNew has incorrect size.");
86 90
91struct ControllerUpdateFirmwareArg {
92 bool enable_force_update{};
93 INSERT_PADDING_BYTES(3);
94};
95static_assert(sizeof(ControllerUpdateFirmwareArg) == 0x4,
96 "ControllerUpdateFirmwareArg has incorrect size.");
97
87struct ControllerSupportResultInfo { 98struct ControllerSupportResultInfo {
88 s8 player_count{}; 99 s8 player_count{};
89 INSERT_PADDING_BYTES(3); 100 INSERT_PADDING_BYTES(3);
@@ -110,10 +121,11 @@ public:
110private: 121private:
111 const Core::Frontend::ControllerApplet& frontend; 122 const Core::Frontend::ControllerApplet& frontend;
112 123
113 LibraryAppletVersion library_applet_version; 124 ControllerAppletVersion controller_applet_version;
114 ControllerSupportArgPrivate controller_private_arg; 125 ControllerSupportArgPrivate controller_private_arg;
115 ControllerSupportArgOld controller_user_arg_old; 126 ControllerSupportArgOld controller_user_arg_old;
116 ControllerSupportArgNew controller_user_arg_new; 127 ControllerSupportArgNew controller_user_arg_new;
128 ControllerUpdateFirmwareArg controller_update_arg;
117 bool complete{false}; 129 bool complete{false};
118 ResultCode status{RESULT_SUCCESS}; 130 ResultCode status{RESULT_SUCCESS};
119 bool is_single_mode{false}; 131 bool is_single_mode{false};