summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/android-merge.js49
-rw-r--r--.github/workflows/android-publish.yml4
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt9
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt17
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt28
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt3
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt219
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt5
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt3
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt12
-rw-r--r--src/android/app/src/main/jni/android_config.cpp6
-rw-r--r--src/android/app/src/main/jni/android_config.h1
-rw-r--r--src/android/app/src/main/jni/native.cpp22
-rw-r--r--src/android/app/src/main/res/values/arrays.xml12
-rw-r--r--src/android/app/src/main/res/values/strings.xml16
-rw-r--r--src/core/CMakeLists.txt92
-rw-r--r--src/core/core.cpp2
-rw-r--r--src/core/file_sys/savedata_factory.cpp9
-rw-r--r--src/core/file_sys/savedata_factory.h1
-rw-r--r--src/core/frontend/applets/controller.cpp6
-rw-r--r--src/core/hle/kernel/k_thread.cpp8
-rw-r--r--src/core/hle/service/am/am.cpp4
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.cpp2
-rw-r--r--src/core/hle/service/am/applets/applet_controller.cpp8
-rw-r--r--src/core/hle/service/hid/controllers/npad.h197
-rw-r--r--src/core/hle/service/hid/errors.h39
-rw-r--r--src/core/hle/service/hid/hid.cpp5
-rw-r--r--src/core/hle/service/hid/hid_debug_server.cpp2
-rw-r--r--src/core/hle/service/hid/hid_server.cpp257
-rw-r--r--src/core/hle/service/hid/hid_system_server.cpp113
-rw-r--r--src/core/hle/service/hid/hid_system_server.h6
-rw-r--r--src/core/hle/service/hid/hidbus.cpp8
-rw-r--r--src/core/hle/service/hid/hidbus.h2
-rw-r--r--src/core/hle/service/hid/irs.cpp22
-rw-r--r--src/core/hle/service/hid/irs.h6
-rw-r--r--src/core/hle/service/nfc/common/device.cpp6
-rw-r--r--src/core/hle/service/nfc/common/device_manager.cpp4
-rw-r--r--src/core/hle/service/nfc/common/device_manager.h2
-rw-r--r--src/core/hle/service/nfc/nfc_interface.cpp2
-rw-r--r--src/core/hle/service/nfp/nfp_interface.cpp2
-rw-r--r--src/core/memory/cheat_engine.cpp4
-rw-r--r--src/frontend_common/config.cpp18
-rw-r--r--src/frontend_common/config.h16
-rw-r--r--src/hid_core/CMakeLists.txt126
-rw-r--r--src/hid_core/frontend/emulated_console.cpp (renamed from src/core/hid/emulated_console.cpp)4
-rw-r--r--src/hid_core/frontend/emulated_console.h (renamed from src/core/hid/emulated_console.h)4
-rw-r--r--src/hid_core/frontend/emulated_controller.cpp (renamed from src/core/hid/emulated_controller.cpp)6
-rw-r--r--src/hid_core/frontend/emulated_controller.h (renamed from src/core/hid/emulated_controller.h)6
-rw-r--r--src/hid_core/frontend/emulated_devices.cpp (renamed from src/core/hid/emulated_devices.cpp)4
-rw-r--r--src/hid_core/frontend/emulated_devices.h (renamed from src/core/hid/emulated_devices.h)2
-rw-r--r--src/hid_core/frontend/input_converter.cpp (renamed from src/core/hid/input_converter.cpp)2
-rw-r--r--src/hid_core/frontend/input_converter.h (renamed from src/core/hid/input_converter.h)0
-rw-r--r--src/hid_core/frontend/input_interpreter.cpp (renamed from src/core/hid/input_interpreter.cpp)8
-rw-r--r--src/hid_core/frontend/input_interpreter.h (renamed from src/core/hid/input_interpreter.h)0
-rw-r--r--src/hid_core/frontend/motion_input.cpp (renamed from src/core/hid/motion_input.cpp)2
-rw-r--r--src/hid_core/frontend/motion_input.h (renamed from src/core/hid/motion_input.h)0
-rw-r--r--src/hid_core/hid_core.cpp (renamed from src/core/hid/hid_core.cpp)10
-rw-r--r--src/hid_core/hid_core.h (renamed from src/core/hid/hid_core.h)2
-rw-r--r--src/hid_core/hid_result.h59
-rw-r--r--src/hid_core/hid_types.h (renamed from src/core/hid/hid_types.h)1
-rw-r--r--src/hid_core/hid_util.h (renamed from src/core/hle/service/hid/hid_util.h)12
-rw-r--r--src/hid_core/hidbus/hidbus_base.cpp (renamed from src/core/hle/service/hid/hidbus/hidbus_base.cpp)4
-rw-r--r--src/hid_core/hidbus/hidbus_base.h (renamed from src/core/hle/service/hid/hidbus/hidbus_base.h)0
-rw-r--r--src/hid_core/hidbus/ringcon.cpp (renamed from src/core/hle/service/hid/hidbus/ringcon.cpp)6
-rw-r--r--src/hid_core/hidbus/ringcon.h (renamed from src/core/hle/service/hid/hidbus/ringcon.h)2
-rw-r--r--src/hid_core/hidbus/starlink.cpp (renamed from src/core/hle/service/hid/hidbus/starlink.cpp)6
-rw-r--r--src/hid_core/hidbus/starlink.h (renamed from src/core/hle/service/hid/hidbus/starlink.h)2
-rw-r--r--src/hid_core/hidbus/stubbed.cpp (renamed from src/core/hle/service/hid/hidbus/stubbed.cpp)6
-rw-r--r--src/hid_core/hidbus/stubbed.h (renamed from src/core/hle/service/hid/hidbus/stubbed.h)2
-rw-r--r--src/hid_core/irsensor/clustering_processor.cpp (renamed from src/core/hle/service/hid/irsensor/clustering_processor.cpp)6
-rw-r--r--src/hid_core/irsensor/clustering_processor.h (renamed from src/core/hle/service/hid/irsensor/clustering_processor.h)6
-rw-r--r--src/hid_core/irsensor/image_transfer_processor.cpp (renamed from src/core/hle/service/hid/irsensor/image_transfer_processor.cpp)6
-rw-r--r--src/hid_core/irsensor/image_transfer_processor.h (renamed from src/core/hle/service/hid/irsensor/image_transfer_processor.h)4
-rw-r--r--src/hid_core/irsensor/ir_led_processor.cpp (renamed from src/core/hle/service/hid/irsensor/ir_led_processor.cpp)2
-rw-r--r--src/hid_core/irsensor/ir_led_processor.h (renamed from src/core/hle/service/hid/irsensor/ir_led_processor.h)4
-rw-r--r--src/hid_core/irsensor/irs_types.h (renamed from src/core/hid/irs_types.h)2
-rw-r--r--src/hid_core/irsensor/moment_processor.cpp (renamed from src/core/hle/service/hid/irsensor/moment_processor.cpp)6
-rw-r--r--src/hid_core/irsensor/moment_processor.h (renamed from src/core/hle/service/hid/irsensor/moment_processor.h)6
-rw-r--r--src/hid_core/irsensor/pointing_processor.cpp (renamed from src/core/hle/service/hid/irsensor/pointing_processor.cpp)2
-rw-r--r--src/hid_core/irsensor/pointing_processor.h (renamed from src/core/hle/service/hid/irsensor/pointing_processor.h)4
-rw-r--r--src/hid_core/irsensor/processor_base.cpp (renamed from src/core/hle/service/hid/irsensor/processor_base.cpp)2
-rw-r--r--src/hid_core/irsensor/processor_base.h (renamed from src/core/hle/service/hid/irsensor/processor_base.h)2
-rw-r--r--src/hid_core/irsensor/tera_plugin_processor.cpp (renamed from src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp)2
-rw-r--r--src/hid_core/irsensor/tera_plugin_processor.h (renamed from src/core/hle/service/hid/irsensor/tera_plugin_processor.h)4
-rw-r--r--src/hid_core/precompiled_headers.h6
-rw-r--r--src/hid_core/resource_manager.cpp (renamed from src/core/hle/service/hid/resource_manager.cpp)81
-rw-r--r--src/hid_core/resource_manager.h (renamed from src/core/hle/service/hid/resource_manager.h)2
-rw-r--r--src/hid_core/resources/applet_resource.cpp (renamed from src/core/hle/service/hid/controllers/applet_resource.cpp)40
-rw-r--r--src/hid_core/resources/applet_resource.h (renamed from src/core/hle/service/hid/controllers/applet_resource.h)3
-rw-r--r--src/hid_core/resources/controller_base.cpp (renamed from src/core/hle/service/hid/controllers/controller_base.cpp)6
-rw-r--r--src/hid_core/resources/controller_base.h (renamed from src/core/hle/service/hid/controllers/controller_base.h)6
-rw-r--r--src/hid_core/resources/debug_pad/debug_pad.cpp (renamed from src/core/hle/service/hid/controllers/debug_pad.cpp)15
-rw-r--r--src/hid_core/resources/debug_pad/debug_pad.h (renamed from src/core/hle/service/hid/controllers/debug_pad.h)7
-rw-r--r--src/hid_core/resources/debug_pad/debug_pad_types.h (renamed from src/core/hle/service/hid/controllers/types/debug_pad_types.h)2
-rw-r--r--src/hid_core/resources/digitizer/digitizer.cpp (renamed from src/core/hle/service/hid/controllers/digitizer.cpp)9
-rw-r--r--src/hid_core/resources/digitizer/digitizer.h (renamed from src/core/hle/service/hid/controllers/digitizer.h)2
-rw-r--r--src/hid_core/resources/hid_firmware_settings.cpp (renamed from src/core/hle/service/hid/hid_firmware_settings.cpp)2
-rw-r--r--src/hid_core/resources/hid_firmware_settings.h (renamed from src/core/hle/service/hid/hid_firmware_settings.h)0
-rw-r--r--src/hid_core/resources/irs_ring_lifo.h (renamed from src/core/hle/service/hid/irs_ring_lifo.h)0
-rw-r--r--src/hid_core/resources/keyboard/keyboard.cpp (renamed from src/core/hle/service/hid/controllers/keyboard.cpp)13
-rw-r--r--src/hid_core/resources/keyboard/keyboard.h (renamed from src/core/hle/service/hid/controllers/keyboard.h)9
-rw-r--r--src/hid_core/resources/keyboard/keyboard_types.h (renamed from src/core/hle/service/hid/controllers/types/keyboard_types.h)2
-rw-r--r--src/hid_core/resources/mouse/debug_mouse.cpp (renamed from src/core/hle/service/hid/controllers/debug_mouse.cpp)13
-rw-r--r--src/hid_core/resources/mouse/debug_mouse.h (renamed from src/core/hle/service/hid/controllers/debug_mouse.h)6
-rw-r--r--src/hid_core/resources/mouse/mouse.cpp (renamed from src/core/hle/service/hid/controllers/mouse.cpp)13
-rw-r--r--src/hid_core/resources/mouse/mouse.h (renamed from src/core/hle/service/hid/controllers/mouse.h)6
-rw-r--r--src/hid_core/resources/mouse/mouse_types.h (renamed from src/core/hle/service/hid/controllers/types/mouse_types.h)0
-rw-r--r--src/hid_core/resources/npad/npad.cpp (renamed from src/core/hle/service/hid/controllers/npad.cpp)1007
-rw-r--r--src/hid_core/resources/npad/npad.h214
-rw-r--r--src/hid_core/resources/npad/npad_data.cpp228
-rw-r--r--src/hid_core/resources/npad/npad_data.h88
-rw-r--r--src/hid_core/resources/npad/npad_resource.cpp687
-rw-r--r--src/hid_core/resources/npad/npad_resource.h132
-rw-r--r--src/hid_core/resources/npad/npad_types.h (renamed from src/core/hle/service/hid/controllers/types/npad_types.h)5
-rw-r--r--src/hid_core/resources/palma/palma.cpp (renamed from src/core/hle/service/hid/controllers/palma.cpp)7
-rw-r--r--src/hid_core/resources/palma/palma.h (renamed from src/core/hle/service/hid/controllers/palma.h)5
-rw-r--r--src/hid_core/resources/ring_lifo.h (renamed from src/core/hle/service/hid/ring_lifo.h)0
-rw-r--r--src/hid_core/resources/shared_memory_format.h (renamed from src/core/hle/service/hid/controllers/types/shared_memory_format.h)16
-rw-r--r--src/hid_core/resources/shared_memory_holder.cpp (renamed from src/core/hle/service/hid/controllers/shared_memory_holder.cpp)8
-rw-r--r--src/hid_core/resources/shared_memory_holder.h (renamed from src/core/hle/service/hid/controllers/shared_memory_holder.h)0
-rw-r--r--src/hid_core/resources/six_axis/console_six_axis.cpp (renamed from src/core/hle/service/hid/controllers/console_six_axis.cpp)11
-rw-r--r--src/hid_core/resources/six_axis/console_six_axis.h (renamed from src/core/hle/service/hid/controllers/console_six_axis.h)2
-rw-r--r--src/hid_core/resources/six_axis/seven_six_axis.cpp (renamed from src/core/hle/service/hid/controllers/seven_six_axis.cpp)8
-rw-r--r--src/hid_core/resources/six_axis/seven_six_axis.h (renamed from src/core/hle/service/hid/controllers/seven_six_axis.h)4
-rw-r--r--src/hid_core/resources/six_axis/six_axis.cpp (renamed from src/core/hle/service/hid/controllers/six_axis.cpp)17
-rw-r--r--src/hid_core/resources/six_axis/six_axis.h (renamed from src/core/hle/service/hid/controllers/six_axis.h)6
-rw-r--r--src/hid_core/resources/system_buttons/capture_button.cpp (renamed from src/core/hle/service/hid/controllers/capture_button.cpp)9
-rw-r--r--src/hid_core/resources/system_buttons/capture_button.h (renamed from src/core/hle/service/hid/controllers/capture_button.h)2
-rw-r--r--src/hid_core/resources/system_buttons/home_button.cpp (renamed from src/core/hle/service/hid/controllers/home_button.cpp)9
-rw-r--r--src/hid_core/resources/system_buttons/home_button.h (renamed from src/core/hle/service/hid/controllers/home_button.h)2
-rw-r--r--src/hid_core/resources/system_buttons/sleep_button.cpp (renamed from src/core/hle/service/hid/controllers/sleep_button.cpp)9
-rw-r--r--src/hid_core/resources/system_buttons/sleep_button.h (renamed from src/core/hle/service/hid/controllers/sleep_button.h)2
-rw-r--r--src/hid_core/resources/touch_screen/gesture.cpp (renamed from src/core/hle/service/hid/controllers/gesture.cpp)16
-rw-r--r--src/hid_core/resources/touch_screen/gesture.h (renamed from src/core/hle/service/hid/controllers/gesture.h)4
-rw-r--r--src/hid_core/resources/touch_screen/gesture_types.h (renamed from src/core/hle/service/hid/controllers/types/gesture_types.h)0
-rw-r--r--src/hid_core/resources/touch_screen/touch_screen.cpp (renamed from src/core/hle/service/hid/controllers/touchscreen.cpp)12
-rw-r--r--src/hid_core/resources/touch_screen/touch_screen.h (renamed from src/core/hle/service/hid/controllers/touchscreen.h)6
-rw-r--r--src/hid_core/resources/touch_screen/touch_types.h (renamed from src/core/hle/service/hid/controllers/types/touch_types.h)2
-rw-r--r--src/hid_core/resources/unique_pad/unique_pad.cpp (renamed from src/core/hle/service/hid/controllers/unique_pad.cpp)8
-rw-r--r--src/hid_core/resources/unique_pad/unique_pad.h (renamed from src/core/hle/service/hid/controllers/unique_pad.h)2
-rw-r--r--src/input_common/CMakeLists.txt2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_image.cpp12
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_instructions.h2
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp11
-rw-r--r--src/yuzu/applets/qt_controller.cpp8
-rw-r--r--src/yuzu/applets/qt_software_keyboard.cpp8
-rw-r--r--src/yuzu/applets/qt_web_browser.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug_controller.cpp2
-rw-r--r--src/yuzu/configuration/configure_hotkeys.cpp4
-rw-r--r--src/yuzu/configuration/configure_input.cpp4
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp4
-rw-r--r--src/yuzu/configuration/configure_input_per_game.cpp4
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp6
-rw-r--r--src/yuzu/configuration/configure_input_player_widget.cpp2
-rw-r--r--src/yuzu/configuration/configure_input_player_widget.h4
-rw-r--r--src/yuzu/configuration/configure_ringcon.cpp4
-rw-r--r--src/yuzu/configuration/configure_vibration.cpp6
-rw-r--r--src/yuzu/configuration/shared_translation.cpp2
-rw-r--r--src/yuzu/debugger/controller.cpp4
-rw-r--r--src/yuzu/hotkeys.cpp2
-rw-r--r--src/yuzu/hotkeys.h2
-rw-r--r--src/yuzu/main.cpp4
-rw-r--r--src/yuzu/util/controller_navigation.cpp4
-rw-r--r--src/yuzu/util/overlay_dialog.cpp4
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp2
167 files changed, 3080 insertions, 1386 deletions
diff --git a/.github/workflows/android-merge.js b/.github/workflows/android-merge.js
index 7e02dc9e5..44ab56e44 100644
--- a/.github/workflows/android-merge.js
+++ b/.github/workflows/android-merge.js
@@ -10,7 +10,7 @@ const CHANGE_LABEL = 'android-merge';
10// how far back in time should we consider the changes are "recent"? (default: 24 hours) 10// how far back in time should we consider the changes are "recent"? (default: 24 hours)
11const DETECTION_TIME_FRAME = (parseInt(process.env.DETECTION_TIME_FRAME)) || (24 * 3600 * 1000); 11const DETECTION_TIME_FRAME = (parseInt(process.env.DETECTION_TIME_FRAME)) || (24 * 3600 * 1000);
12 12
13async function checkBaseChanges(github, context) { 13async function checkBaseChanges(github) {
14 // query the commit date of the latest commit on this branch 14 // query the commit date of the latest commit on this branch
15 const query = `query($owner:String!, $name:String!, $ref:String!) { 15 const query = `query($owner:String!, $name:String!, $ref:String!) {
16 repository(name:$name, owner:$owner) { 16 repository(name:$name, owner:$owner) {
@@ -22,8 +22,8 @@ async function checkBaseChanges(github, context) {
22 } 22 }
23 }`; 23 }`;
24 const variables = { 24 const variables = {
25 owner: context.repo.owner, 25 owner: 'yuzu-emu',
26 name: context.repo.repo, 26 name: 'yuzu',
27 ref: 'refs/heads/master', 27 ref: 'refs/heads/master',
28 }; 28 };
29 const result = await github.graphql(query, variables); 29 const result = await github.graphql(query, variables);
@@ -38,8 +38,8 @@ async function checkBaseChanges(github, context) {
38 return false; 38 return false;
39} 39}
40 40
41async function checkAndroidChanges(github, context) { 41async function checkAndroidChanges(github) {
42 if (checkBaseChanges(github, context)) return true; 42 if (checkBaseChanges(github)) return true;
43 const query = `query($owner:String!, $name:String!, $label:String!) { 43 const query = `query($owner:String!, $name:String!, $label:String!) {
44 repository(name:$name, owner:$owner) { 44 repository(name:$name, owner:$owner) {
45 pullRequests(labels: [$label], states: OPEN, first: 100) { 45 pullRequests(labels: [$label], states: OPEN, first: 100) {
@@ -48,8 +48,8 @@ async function checkAndroidChanges(github, context) {
48 } 48 }
49 }`; 49 }`;
50 const variables = { 50 const variables = {
51 owner: context.repo.owner, 51 owner: 'yuzu-emu',
52 name: context.repo.repo, 52 name: 'yuzu',
53 label: CHANGE_LABEL, 53 label: CHANGE_LABEL,
54 }; 54 };
55 const result = await github.graphql(query, variables); 55 const result = await github.graphql(query, variables);
@@ -90,8 +90,8 @@ async function tagAndPush(github, owner, repo, execa, commit=false) {
90 console.log(`New tag: ${newTag}`); 90 console.log(`New tag: ${newTag}`);
91 if (commit) { 91 if (commit) {
92 let channelName = channel[0].toUpperCase() + channel.slice(1); 92 let channelName = channel[0].toUpperCase() + channel.slice(1);
93 console.info(`Committing pending commit as ${channelName} #${tagNumber + 1}`); 93 console.info(`Committing pending commit as ${channelName} ${tagNumber + 1}`);
94 await execa("git", ['commit', '-m', `${channelName} #${tagNumber + 1}`]); 94 await execa("git", ['commit', '-m', `${channelName} ${tagNumber + 1}`]);
95 } 95 }
96 console.info('Pushing tags to GitHub ...'); 96 console.info('Pushing tags to GitHub ...');
97 await execa("git", ['tag', newTag]); 97 await execa("git", ['tag', newTag]);
@@ -157,7 +157,7 @@ async function mergePullRequests(pulls, execa) {
157 process1.stdout.pipe(process.stdout); 157 process1.stdout.pipe(process.stdout);
158 await process1; 158 await process1;
159 159
160 const process2 = execa("git", ["commit", "-m", `Merge PR ${pr}`]); 160 const process2 = execa("git", ["commit", "-m", `Merge yuzu-emu#${pr}`]);
161 process2.stdout.pipe(process.stdout); 161 process2.stdout.pipe(process.stdout);
162 await process2; 162 await process2;
163 163
@@ -182,7 +182,30 @@ async function mergePullRequests(pulls, execa) {
182 return mergeResults; 182 return mergeResults;
183} 183}
184 184
185async function resetBranch(execa) {
186 console.log("::group::Reset master branch");
187 let hasFailed = false;
188 try {
189 await execa("git", ["remote", "add", "source", "https://github.com/yuzu-emu/yuzu.git"]);
190 await execa("git", ["fetch", "source"]);
191 const process1 = await execa("git", ["rev-parse", "source/master"]);
192 const headCommit = process1.stdout;
193
194 await execa("git", ["reset", "--hard", headCommit]);
195 } catch (err) {
196 console.log(`::error title=Failed to reset master branch`);
197 hasFailed = true;
198 }
199 console.log("::endgroup::");
200 if (hasFailed) {
201 throw 'Failed to reset the master branch. Aborting!';
202 }
203}
204
185async function mergebot(github, context, execa) { 205async function mergebot(github, context, execa) {
206 // Reset our local copy of master to what appears on yuzu-emu/yuzu - master
207 await resetBranch(execa);
208
186 const query = `query ($owner:String!, $name:String!, $label:String!) { 209 const query = `query ($owner:String!, $name:String!, $label:String!) {
187 repository(name:$name, owner:$owner) { 210 repository(name:$name, owner:$owner) {
188 pullRequests(labels: [$label], states: OPEN, first: 100) { 211 pullRequests(labels: [$label], states: OPEN, first: 100) {
@@ -193,8 +216,8 @@ async function mergebot(github, context, execa) {
193 } 216 }
194 }`; 217 }`;
195 const variables = { 218 const variables = {
196 owner: context.repo.owner, 219 owner: 'yuzu-emu',
197 name: context.repo.repo, 220 name: 'yuzu',
198 label: CHANGE_LABEL, 221 label: CHANGE_LABEL,
199 }; 222 };
200 const result = await github.graphql(query, variables); 223 const result = await github.graphql(query, variables);
@@ -209,7 +232,7 @@ async function mergebot(github, context, execa) {
209 await fetchPullRequests(pulls, "https://github.com/yuzu-emu/yuzu", execa); 232 await fetchPullRequests(pulls, "https://github.com/yuzu-emu/yuzu", execa);
210 const mergeResults = await mergePullRequests(pulls, execa); 233 const mergeResults = await mergePullRequests(pulls, execa);
211 await generateReadme(pulls, context, mergeResults, execa); 234 await generateReadme(pulls, context, mergeResults, execa);
212 await tagAndPush(github, context.repo.owner, `${context.repo.repo}-android`, execa, true); 235 await tagAndPush(github, 'yuzu-emu', `yuzu-android`, execa, true);
213} 236}
214 237
215module.exports.mergebot = mergebot; 238module.exports.mergebot = mergebot;
diff --git a/.github/workflows/android-publish.yml b/.github/workflows/android-publish.yml
index 8f46fcf74..68e21c2f2 100644
--- a/.github/workflows/android-publish.yml
+++ b/.github/workflows/android-publish.yml
@@ -16,7 +16,7 @@ on:
16jobs: 16jobs:
17 android: 17 android:
18 runs-on: ubuntu-latest 18 runs-on: ubuntu-latest
19 if: ${{ github.event.inputs.android != 'false' && github.repository == 'yuzu-emu/yuzu' }} 19 if: ${{ github.event.inputs.android != 'false' && github.repository == 'yuzu-emu/yuzu-android' }}
20 steps: 20 steps:
21 # this checkout is required to make sure the GitHub Actions scripts are available 21 # this checkout is required to make sure the GitHub Actions scripts are available
22 - uses: actions/checkout@v3 22 - uses: actions/checkout@v3
@@ -33,7 +33,7 @@ jobs:
33 script: | 33 script: |
34 if (context.payload.inputs && context.payload.inputs.android === 'true') return true; 34 if (context.payload.inputs && context.payload.inputs.android === 'true') return true;
35 const checkAndroidChanges = require('./.github/workflows/android-merge.js').checkAndroidChanges; 35 const checkAndroidChanges = require('./.github/workflows/android-merge.js').checkAndroidChanges;
36 return checkAndroidChanges(github, context); 36 return checkAndroidChanges(github);
37 - run: npm install execa@5 37 - run: npm install execa@5
38 if: ${{ steps.check-changes.outputs.result == 'true' }} 38 if: ${{ steps.check-changes.outputs.result == 'true' }}
39 - uses: actions/checkout@v3 39 - uses: actions/checkout@v3
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e04d2418b..edca221b1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -185,6 +185,7 @@ add_subdirectory(common)
185add_subdirectory(core) 185add_subdirectory(core)
186add_subdirectory(audio_core) 186add_subdirectory(audio_core)
187add_subdirectory(video_core) 187add_subdirectory(video_core)
188add_subdirectory(hid_core)
188add_subdirectory(network) 189add_subdirectory(network)
189add_subdirectory(input_common) 190add_subdirectory(input_common)
190add_subdirectory(frontend_common) 191add_subdirectory(frontend_common)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
index 010c44951..b7556e353 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
@@ -548,6 +548,15 @@ object NativeLibrary {
548 external fun getSavePath(programId: String): String 548 external fun getSavePath(programId: String): String
549 549
550 /** 550 /**
551 * Gets the root save directory for the default profile as either
552 * /user/save/account/<user id raw string> or /user/save/000...000/<user id>
553 *
554 * @param future If true, returns the /user/save/account/... directory
555 * @return Save data path that may not exist yet
556 */
557 external fun getDefaultProfileSaveDataRoot(future: Boolean): String
558
559 /**
551 * Adds a file to the manual filesystem provider in our EmulationSession instance 560 * Adds a file to the manual filesystem provider in our EmulationSession instance
552 * @param path Path to the file we're adding. Can be a string representation of a [Uri] or 561 * @param path Path to the file we're adding. Can be a string representation of a [Uri] or
553 * a normal path 562 * a normal path
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
index 43caac989..fee80bb21 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
@@ -79,7 +79,18 @@ object Settings {
79 const val PREF_THEME_MODE = "ThemeMode" 79 const val PREF_THEME_MODE = "ThemeMode"
80 const val PREF_BLACK_BACKGROUNDS = "BlackBackgrounds" 80 const val PREF_BLACK_BACKGROUNDS = "BlackBackgrounds"
81 81
82 const val LayoutOption_Unspecified = 0 82 enum class EmulationOrientation(val int: Int) {
83 const val LayoutOption_MobilePortrait = 4 83 Unspecified(0),
84 const val LayoutOption_MobileLandscape = 5 84 SensorLandscape(5),
85 Landscape(1),
86 ReverseLandscape(2),
87 SensorPortrait(6),
88 Portrait(4),
89 ReversePortrait(3);
90
91 companion object {
92 fun from(int: Int): EmulationOrientation =
93 entries.firstOrNull { it.int == int } ?: Unspecified
94 }
95 }
85} 96}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index 510b2b5eb..9efc1705d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -50,6 +50,7 @@ import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding
50import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting 50import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
51import org.yuzu.yuzu_emu.features.settings.model.IntSetting 51import org.yuzu.yuzu_emu.features.settings.model.IntSetting
52import org.yuzu.yuzu_emu.features.settings.model.Settings 52import org.yuzu.yuzu_emu.features.settings.model.Settings
53import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationOrientation
53import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile 54import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
54import org.yuzu.yuzu_emu.model.DriverViewModel 55import org.yuzu.yuzu_emu.model.DriverViewModel
55import org.yuzu.yuzu_emu.model.Game 56import org.yuzu.yuzu_emu.model.Game
@@ -99,6 +100,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
99 */ 100 */
100 override fun onCreate(savedInstanceState: Bundle?) { 101 override fun onCreate(savedInstanceState: Bundle?) {
101 super.onCreate(savedInstanceState) 102 super.onCreate(savedInstanceState)
103 updateOrientation()
102 104
103 val intentUri: Uri? = requireActivity().intent.data 105 val intentUri: Uri? = requireActivity().intent.data
104 var intentGame: Game? = null 106 var intentGame: Game? = null
@@ -458,13 +460,23 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
458 @SuppressLint("SourceLockedOrientationActivity") 460 @SuppressLint("SourceLockedOrientationActivity")
459 private fun updateOrientation() { 461 private fun updateOrientation() {
460 emulationActivity?.let { 462 emulationActivity?.let {
461 it.requestedOrientation = when (IntSetting.RENDERER_SCREEN_LAYOUT.getInt()) { 463 val orientationSetting =
462 Settings.LayoutOption_MobileLandscape -> 464 EmulationOrientation.from(IntSetting.RENDERER_SCREEN_LAYOUT.getInt())
465 it.requestedOrientation = when (orientationSetting) {
466 EmulationOrientation.Unspecified -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
467 EmulationOrientation.SensorLandscape ->
463 ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE 468 ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
464 Settings.LayoutOption_MobilePortrait -> 469
465 ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT 470 EmulationOrientation.Landscape -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
466 Settings.LayoutOption_Unspecified -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 471 EmulationOrientation.ReverseLandscape ->
467 else -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE 472 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
473
474 EmulationOrientation.SensorPortrait ->
475 ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
476
477 EmulationOrientation.Portrait -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
478 EmulationOrientation.ReversePortrait ->
479 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
468 } 480 }
469 } 481 }
470 } 482 }
@@ -651,7 +663,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
651 @SuppressLint("SourceLockedOrientationActivity") 663 @SuppressLint("SourceLockedOrientationActivity")
652 private fun startConfiguringControls() { 664 private fun startConfiguringControls() {
653 // Lock the current orientation to prevent editing inconsistencies 665 // Lock the current orientation to prevent editing inconsistencies
654 if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == Settings.LayoutOption_Unspecified) { 666 if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == EmulationOrientation.Unspecified.int) {
655 emulationActivity?.let { 667 emulationActivity?.let {
656 it.requestedOrientation = 668 it.requestedOrientation =
657 if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { 669 if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
@@ -669,7 +681,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
669 binding.doneControlConfig.visibility = View.GONE 681 binding.doneControlConfig.visibility = View.GONE
670 binding.surfaceInputOverlay.setIsInEditMode(false) 682 binding.surfaceInputOverlay.setIsInEditMode(false)
671 // Unlock the orientation if it was locked for editing 683 // Unlock the orientation if it was locked for editing
672 if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == Settings.LayoutOption_Unspecified) { 684 if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == EmulationOrientation.Unspecified.int) {
673 emulationActivity?.let { 685 emulationActivity?.let {
674 it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 686 it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
675 } 687 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt
index b1d3c0040..b04d1208f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt
@@ -445,7 +445,8 @@ class GamePropertiesFragment : Fragment() {
445 val zipResult = FileUtil.zipFromInternalStorage( 445 val zipResult = FileUtil.zipFromInternalStorage(
446 File(saveLocation), 446 File(saveLocation),
447 saveLocation.replaceAfterLast("/", ""), 447 saveLocation.replaceAfterLast("/", ""),
448 BufferedOutputStream(requireContext().contentResolver.openOutputStream(result)) 448 BufferedOutputStream(requireContext().contentResolver.openOutputStream(result)),
449 compression = false
449 ) 450 )
450 return@newInstance when (zipResult) { 451 return@newInstance when (zipResult) {
451 TaskState.Completed -> getString(R.string.export_success) 452 TaskState.Completed -> getString(R.string.export_success)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt
index 569727b90..5b4bf2c9f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt
@@ -7,20 +7,39 @@ import android.os.Bundle
7import android.view.LayoutInflater 7import android.view.LayoutInflater
8import android.view.View 8import android.view.View
9import android.view.ViewGroup 9import android.view.ViewGroup
10import android.widget.Toast
11import androidx.activity.result.contract.ActivityResultContracts
10import androidx.core.view.ViewCompat 12import androidx.core.view.ViewCompat
11import androidx.core.view.WindowInsetsCompat 13import androidx.core.view.WindowInsetsCompat
12import androidx.core.view.updatePadding 14import androidx.core.view.updatePadding
13import androidx.fragment.app.Fragment 15import androidx.fragment.app.Fragment
14import androidx.fragment.app.activityViewModels 16import androidx.fragment.app.activityViewModels
17import androidx.lifecycle.Lifecycle
18import androidx.lifecycle.lifecycleScope
19import androidx.lifecycle.repeatOnLifecycle
15import androidx.navigation.findNavController 20import androidx.navigation.findNavController
16import androidx.recyclerview.widget.GridLayoutManager 21import androidx.recyclerview.widget.GridLayoutManager
17import com.google.android.material.transition.MaterialSharedAxis 22import com.google.android.material.transition.MaterialSharedAxis
23import kotlinx.coroutines.Dispatchers
24import kotlinx.coroutines.launch
25import kotlinx.coroutines.withContext
26import org.yuzu.yuzu_emu.NativeLibrary
18import org.yuzu.yuzu_emu.R 27import org.yuzu.yuzu_emu.R
28import org.yuzu.yuzu_emu.YuzuApplication
19import org.yuzu.yuzu_emu.adapters.InstallableAdapter 29import org.yuzu.yuzu_emu.adapters.InstallableAdapter
20import org.yuzu.yuzu_emu.databinding.FragmentInstallablesBinding 30import org.yuzu.yuzu_emu.databinding.FragmentInstallablesBinding
21import org.yuzu.yuzu_emu.model.HomeViewModel 31import org.yuzu.yuzu_emu.model.HomeViewModel
22import org.yuzu.yuzu_emu.model.Installable 32import org.yuzu.yuzu_emu.model.Installable
33import org.yuzu.yuzu_emu.model.TaskState
23import org.yuzu.yuzu_emu.ui.main.MainActivity 34import org.yuzu.yuzu_emu.ui.main.MainActivity
35import org.yuzu.yuzu_emu.utils.DirectoryInitialization
36import org.yuzu.yuzu_emu.utils.FileUtil
37import java.io.BufferedInputStream
38import java.io.BufferedOutputStream
39import java.io.File
40import java.math.BigInteger
41import java.time.LocalDateTime
42import java.time.format.DateTimeFormatter
24 43
25class InstallableFragment : Fragment() { 44class InstallableFragment : Fragment() {
26 private var _binding: FragmentInstallablesBinding? = null 45 private var _binding: FragmentInstallablesBinding? = null
@@ -56,6 +75,17 @@ class InstallableFragment : Fragment() {
56 binding.root.findNavController().popBackStack() 75 binding.root.findNavController().popBackStack()
57 } 76 }
58 77
78 viewLifecycleOwner.lifecycleScope.launch {
79 repeatOnLifecycle(Lifecycle.State.CREATED) {
80 homeViewModel.openImportSaves.collect {
81 if (it) {
82 importSaves.launch(arrayOf("application/zip"))
83 homeViewModel.setOpenImportSaves(false)
84 }
85 }
86 }
87 }
88
59 val installables = listOf( 89 val installables = listOf(
60 Installable( 90 Installable(
61 R.string.user_data, 91 R.string.user_data,
@@ -64,6 +94,43 @@ class InstallableFragment : Fragment() {
64 export = { mainActivity.exportUserData.launch("export.zip") } 94 export = { mainActivity.exportUserData.launch("export.zip") }
65 ), 95 ),
66 Installable( 96 Installable(
97 R.string.manage_save_data,
98 R.string.manage_save_data_description,
99 install = {
100 MessageDialogFragment.newInstance(
101 requireActivity(),
102 titleId = R.string.import_save_warning,
103 descriptionId = R.string.import_save_warning_description,
104 positiveAction = { homeViewModel.setOpenImportSaves(true) }
105 ).show(parentFragmentManager, MessageDialogFragment.TAG)
106 },
107 export = {
108 val oldSaveDataFolder = File(
109 "${DirectoryInitialization.userDirectory}/nand" +
110 NativeLibrary.getDefaultProfileSaveDataRoot(false)
111 )
112 val futureSaveDataFolder = File(
113 "${DirectoryInitialization.userDirectory}/nand" +
114 NativeLibrary.getDefaultProfileSaveDataRoot(true)
115 )
116 if (!oldSaveDataFolder.exists() && !futureSaveDataFolder.exists()) {
117 Toast.makeText(
118 YuzuApplication.appContext,
119 R.string.no_save_data_found,
120 Toast.LENGTH_SHORT
121 ).show()
122 return@Installable
123 } else {
124 exportSaves.launch(
125 "${getString(R.string.save_data)} " +
126 LocalDateTime.now().format(
127 DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
128 )
129 )
130 }
131 }
132 ),
133 Installable(
67 R.string.install_game_content, 134 R.string.install_game_content,
68 R.string.install_game_content_description, 135 R.string.install_game_content_description,
69 install = { mainActivity.installGameUpdate.launch(arrayOf("*/*")) } 136 install = { mainActivity.installGameUpdate.launch(arrayOf("*/*")) }
@@ -121,4 +188,156 @@ class InstallableFragment : Fragment() {
121 188
122 windowInsets 189 windowInsets
123 } 190 }
191
192 private val importSaves =
193 registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
194 if (result == null) {
195 return@registerForActivityResult
196 }
197
198 val inputZip = requireContext().contentResolver.openInputStream(result)
199 val cacheSaveDir = File("${requireContext().cacheDir.path}/saves/")
200 cacheSaveDir.mkdir()
201
202 if (inputZip == null) {
203 Toast.makeText(
204 YuzuApplication.appContext,
205 getString(R.string.fatal_error),
206 Toast.LENGTH_LONG
207 ).show()
208 return@registerForActivityResult
209 }
210
211 IndeterminateProgressDialogFragment.newInstance(
212 requireActivity(),
213 R.string.save_files_importing,
214 false
215 ) {
216 try {
217 FileUtil.unzipToInternalStorage(BufferedInputStream(inputZip), cacheSaveDir)
218 val files = cacheSaveDir.listFiles()
219 var successfulImports = 0
220 var failedImports = 0
221 if (files != null) {
222 for (file in files) {
223 if (file.isDirectory) {
224 val baseSaveDir =
225 NativeLibrary.getSavePath(BigInteger(file.name, 16).toString())
226 if (baseSaveDir.isEmpty()) {
227 failedImports++
228 continue
229 }
230
231 val internalSaveFolder = File(
232 "${DirectoryInitialization.userDirectory}/nand$baseSaveDir"
233 )
234 internalSaveFolder.deleteRecursively()
235 internalSaveFolder.mkdir()
236 file.copyRecursively(target = internalSaveFolder, overwrite = true)
237 successfulImports++
238 }
239 }
240 }
241
242 withContext(Dispatchers.Main) {
243 if (successfulImports == 0) {
244 MessageDialogFragment.newInstance(
245 requireActivity(),
246 titleId = R.string.save_file_invalid_zip_structure,
247 descriptionId = R.string.save_file_invalid_zip_structure_description
248 ).show(parentFragmentManager, MessageDialogFragment.TAG)
249 return@withContext
250 }
251 val successString = if (failedImports > 0) {
252 """
253 ${
254 requireContext().resources.getQuantityString(
255 R.plurals.saves_import_success,
256 successfulImports,
257 successfulImports
258 )
259 }
260 ${
261 requireContext().resources.getQuantityString(
262 R.plurals.saves_import_failed,
263 failedImports,
264 failedImports
265 )
266 }
267 """
268 } else {
269 requireContext().resources.getQuantityString(
270 R.plurals.saves_import_success,
271 successfulImports,
272 successfulImports
273 )
274 }
275 MessageDialogFragment.newInstance(
276 requireActivity(),
277 titleId = R.string.import_complete,
278 descriptionString = successString
279 ).show(parentFragmentManager, MessageDialogFragment.TAG)
280 }
281
282 cacheSaveDir.deleteRecursively()
283 } catch (e: Exception) {
284 Toast.makeText(
285 YuzuApplication.appContext,
286 getString(R.string.fatal_error),
287 Toast.LENGTH_LONG
288 ).show()
289 }
290 }.show(parentFragmentManager, IndeterminateProgressDialogFragment.TAG)
291 }
292
293 private val exportSaves = registerForActivityResult(
294 ActivityResultContracts.CreateDocument("application/zip")
295 ) { result ->
296 if (result == null) {
297 return@registerForActivityResult
298 }
299
300 IndeterminateProgressDialogFragment.newInstance(
301 requireActivity(),
302 R.string.save_files_exporting,
303 false
304 ) {
305 val cacheSaveDir = File("${requireContext().cacheDir.path}/saves/")
306 cacheSaveDir.mkdir()
307
308 val oldSaveDataFolder = File(
309 "${DirectoryInitialization.userDirectory}/nand" +
310 NativeLibrary.getDefaultProfileSaveDataRoot(false)
311 )
312 if (oldSaveDataFolder.exists()) {
313 oldSaveDataFolder.copyRecursively(cacheSaveDir)
314 }
315
316 val futureSaveDataFolder = File(
317 "${DirectoryInitialization.userDirectory}/nand" +
318 NativeLibrary.getDefaultProfileSaveDataRoot(true)
319 )
320 if (futureSaveDataFolder.exists()) {
321 futureSaveDataFolder.copyRecursively(cacheSaveDir)
322 }
323
324 val saveFilesTotal = cacheSaveDir.listFiles()?.size ?: 0
325 if (saveFilesTotal == 0) {
326 cacheSaveDir.deleteRecursively()
327 return@newInstance getString(R.string.no_save_data_found)
328 }
329
330 val zipResult = FileUtil.zipFromInternalStorage(
331 cacheSaveDir,
332 cacheSaveDir.path,
333 BufferedOutputStream(requireContext().contentResolver.openOutputStream(result))
334 )
335 cacheSaveDir.deleteRecursively()
336
337 return@newInstance when (zipResult) {
338 TaskState.Completed -> getString(R.string.export_success)
339 TaskState.Cancelled, TaskState.Failed -> getString(R.string.export_failed)
340 }
341 }.show(parentFragmentManager, IndeterminateProgressDialogFragment.TAG)
342 }
124} 343}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
index d19f20dc2..5ae05b5cc 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
@@ -167,13 +167,14 @@ class GamesViewModel : ViewModel() {
167 } 167 }
168 } 168 }
169 169
170 fun onCloseGameFoldersFragment() = 170 fun onCloseGameFoldersFragment() {
171 NativeConfig.saveGlobalConfig()
171 viewModelScope.launch { 172 viewModelScope.launch {
172 withContext(Dispatchers.IO) { 173 withContext(Dispatchers.IO) {
173 NativeConfig.saveGlobalConfig()
174 getGameDirs(true) 174 getGameDirs(true)
175 } 175 }
176 } 176 }
177 }
177 178
178 private fun getGameDirs(reloadList: Boolean = false) { 179 private fun getGameDirs(reloadList: Boolean = false) {
179 val gameDirs = NativeConfig.getGameDirs() 180 val gameDirs = NativeConfig.getGameDirs()
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
index b4117d761..622ae996e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -625,7 +625,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
625 File(DirectoryInitialization.userDirectory!!), 625 File(DirectoryInitialization.userDirectory!!),
626 DirectoryInitialization.userDirectory!!, 626 DirectoryInitialization.userDirectory!!,
627 BufferedOutputStream(contentResolver.openOutputStream(result)), 627 BufferedOutputStream(contentResolver.openOutputStream(result)),
628 taskViewModel.cancelled 628 taskViewModel.cancelled,
629 compression = false
629 ) 630 )
630 return@newInstance when (zipResult) { 631 return@newInstance when (zipResult) {
631 TaskState.Completed -> getString(R.string.user_data_export_success) 632 TaskState.Completed -> getString(R.string.user_data_export_success)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
index 00c6bf90e..132f002fb 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
@@ -21,6 +21,7 @@ import org.yuzu.yuzu_emu.model.TaskState
21import java.io.BufferedOutputStream 21import java.io.BufferedOutputStream
22import java.lang.NullPointerException 22import java.lang.NullPointerException
23import java.nio.charset.StandardCharsets 23import java.nio.charset.StandardCharsets
24import java.util.zip.Deflater
24import java.util.zip.ZipOutputStream 25import java.util.zip.ZipOutputStream
25import kotlin.IllegalStateException 26import kotlin.IllegalStateException
26 27
@@ -312,15 +313,23 @@ object FileUtil {
312 * @param inputFile File representation of the item that will be zipped 313 * @param inputFile File representation of the item that will be zipped
313 * @param rootDir Directory containing the inputFile 314 * @param rootDir Directory containing the inputFile
314 * @param outputStream Stream where the zip file will be output 315 * @param outputStream Stream where the zip file will be output
316 * @param cancelled [StateFlow] that reports whether this process has been cancelled
317 * @param compression Disables compression if true
315 */ 318 */
316 fun zipFromInternalStorage( 319 fun zipFromInternalStorage(
317 inputFile: File, 320 inputFile: File,
318 rootDir: String, 321 rootDir: String,
319 outputStream: BufferedOutputStream, 322 outputStream: BufferedOutputStream,
320 cancelled: StateFlow<Boolean>? = null 323 cancelled: StateFlow<Boolean>? = null,
324 compression: Boolean = true
321 ): TaskState { 325 ): TaskState {
322 try { 326 try {
323 ZipOutputStream(outputStream).use { zos -> 327 ZipOutputStream(outputStream).use { zos ->
328 if (!compression) {
329 zos.setMethod(ZipOutputStream.DEFLATED)
330 zos.setLevel(Deflater.NO_COMPRESSION)
331 }
332
324 inputFile.walkTopDown().forEach { file -> 333 inputFile.walkTopDown().forEach { file ->
325 if (cancelled?.value == true) { 334 if (cancelled?.value == true) {
326 return TaskState.Cancelled 335 return TaskState.Cancelled
@@ -338,6 +347,7 @@ object FileUtil {
338 } 347 }
339 } 348 }
340 } catch (e: Exception) { 349 } catch (e: Exception) {
350 Log.error("[FileUtil] Failed creating zip file - ${e.message}")
341 return TaskState.Failed 351 return TaskState.Failed
342 } 352 }
343 return TaskState.Completed 353 return TaskState.Completed
diff --git a/src/android/app/src/main/jni/android_config.cpp b/src/android/app/src/main/jni/android_config.cpp
index c86aa1c39..08aed3216 100644
--- a/src/android/app/src/main/jni/android_config.cpp
+++ b/src/android/app/src/main/jni/android_config.cpp
@@ -14,12 +14,6 @@ AndroidConfig::AndroidConfig(const std::string& config_name, ConfigType config_t
14 } 14 }
15} 15}
16 16
17AndroidConfig::~AndroidConfig() {
18 if (global) {
19 AndroidConfig::SaveAllValues();
20 }
21}
22
23void AndroidConfig::ReloadAllValues() { 17void AndroidConfig::ReloadAllValues() {
24 Reload(); 18 Reload();
25 ReadAndroidValues(); 19 ReadAndroidValues();
diff --git a/src/android/app/src/main/jni/android_config.h b/src/android/app/src/main/jni/android_config.h
index d83852de9..693e1e3f0 100644
--- a/src/android/app/src/main/jni/android_config.h
+++ b/src/android/app/src/main/jni/android_config.h
@@ -9,7 +9,6 @@ class AndroidConfig final : public Config {
9public: 9public:
10 explicit AndroidConfig(const std::string& config_name = "config", 10 explicit AndroidConfig(const std::string& config_name = "config",
11 ConfigType config_type = ConfigType::GlobalConfig); 11 ConfigType config_type = ConfigType::GlobalConfig);
12 ~AndroidConfig() override;
13 12
14 void ReloadAllValues() override; 13 void ReloadAllValues() override;
15 void SaveAllValues() override; 14 void SaveAllValues() override;
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 0c1db7d46..136c8dee6 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -45,15 +45,15 @@
45#include "core/frontend/applets/profile_select.h" 45#include "core/frontend/applets/profile_select.h"
46#include "core/frontend/applets/software_keyboard.h" 46#include "core/frontend/applets/software_keyboard.h"
47#include "core/frontend/applets/web_browser.h" 47#include "core/frontend/applets/web_browser.h"
48#include "core/hid/emulated_controller.h"
49#include "core/hid/hid_core.h"
50#include "core/hid/hid_types.h"
51#include "core/hle/service/am/applet_ae.h" 48#include "core/hle/service/am/applet_ae.h"
52#include "core/hle/service/am/applet_oe.h" 49#include "core/hle/service/am/applet_oe.h"
53#include "core/hle/service/am/applets/applets.h" 50#include "core/hle/service/am/applets/applets.h"
54#include "core/hle/service/filesystem/filesystem.h" 51#include "core/hle/service/filesystem/filesystem.h"
55#include "core/loader/loader.h" 52#include "core/loader/loader.h"
56#include "frontend_common/config.h" 53#include "frontend_common/config.h"
54#include "hid_core/frontend/emulated_controller.h"
55#include "hid_core/hid_core.h"
56#include "hid_core/hid_types.h"
57#include "jni/android_common/android_common.h" 57#include "jni/android_common/android_common.h"
58#include "jni/id_cache.h" 58#include "jni/id_cache.h"
59#include "jni/native.h" 59#include "jni/native.h"
@@ -862,6 +862,9 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getAddonsForFile(JNIEnv* env,
862jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj, 862jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj,
863 jstring jprogramId) { 863 jstring jprogramId) {
864 auto program_id = EmulationSession::GetProgramId(env, jprogramId); 864 auto program_id = EmulationSession::GetProgramId(env, jprogramId);
865 if (program_id == 0) {
866 return ToJString(env, "");
867 }
865 868
866 auto& system = EmulationSession::GetInstance().System(); 869 auto& system = EmulationSession::GetInstance().System();
867 870
@@ -880,6 +883,19 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j
880 return ToJString(env, user_save_data_path); 883 return ToJString(env, user_save_data_path);
881} 884}
882 885
886jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDefaultProfileSaveDataRoot(JNIEnv* env,
887 jobject jobj,
888 jboolean jfuture) {
889 Service::Account::ProfileManager manager;
890 // TODO: Pass in a selected user once we get the relevant UI working
891 const auto user_id = manager.GetUser(static_cast<std::size_t>(0));
892 ASSERT(user_id);
893
894 const auto user_save_data_root =
895 FileSys::SaveDataFactory::GetUserGameSaveDataRoot(user_id->AsU128(), jfuture);
896 return ToJString(env, user_save_data_root);
897}
898
883void Java_org_yuzu_yuzu_1emu_NativeLibrary_addFileToFilesystemProvider(JNIEnv* env, jobject jobj, 899void Java_org_yuzu_yuzu_1emu_NativeLibrary_addFileToFilesystemProvider(JNIEnv* env, jobject jobj,
884 jstring jpath) { 900 jstring jpath) {
885 EmulationSession::GetInstance().ConfigureFilesystemProvider(GetJString(env, jpath)); 901 EmulationSession::GetInstance().ConfigureFilesystemProvider(GetJString(env, jpath));
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml
index 45d57c3ea..0363ff3b6 100644
--- a/src/android/app/src/main/res/values/arrays.xml
+++ b/src/android/app/src/main/res/values/arrays.xml
@@ -118,15 +118,23 @@
118 </integer-array> 118 </integer-array>
119 119
120 <string-array name="rendererScreenLayoutNames"> 120 <string-array name="rendererScreenLayoutNames">
121 <item>@string/screen_layout_auto</item>
122 <item>@string/screen_layout_sensor_landscape</item>
121 <item>@string/screen_layout_landscape</item> 123 <item>@string/screen_layout_landscape</item>
124 <item>@string/screen_layout_reverse_landscape</item>
125 <item>@string/screen_layout_sensor_portrait</item>
122 <item>@string/screen_layout_portrait</item> 126 <item>@string/screen_layout_portrait</item>
123 <item>@string/screen_layout_auto</item> 127 <item>@string/screen_layout_reverse_portrait</item>
124 </string-array> 128 </string-array>
125 129
126 <integer-array name="rendererScreenLayoutValues"> 130 <integer-array name="rendererScreenLayoutValues">
131 <item>0</item>
127 <item>5</item> 132 <item>5</item>
133 <item>1</item>
134 <item>2</item>
135 <item>6</item>
128 <item>4</item> 136 <item>4</item>
129 <item>0</item> 137 <item>3</item>
130 </integer-array> 138 </integer-array>
131 139
132 <string-array name="rendererAspectRatioNames"> 140 <string-array name="rendererAspectRatioNames">
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 1bedcb1ef..3bb92ad67 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -133,6 +133,15 @@
133 <string name="add_game_folder">Add game folder</string> 133 <string name="add_game_folder">Add game folder</string>
134 <string name="folder_already_added">This folder was already added!</string> 134 <string name="folder_already_added">This folder was already added!</string>
135 <string name="game_folder_properties">Game folder properties</string> 135 <string name="game_folder_properties">Game folder properties</string>
136 <plurals name="saves_import_failed">
137 <item quantity="one">Failed to import %d save</item>
138 <item quantity="other">Failed to import %d saves</item>
139 </plurals>
140 <plurals name="saves_import_success">
141 <item quantity="one">Successfully imported %d save</item>
142 <item quantity="other">Successfully imported %d saves</item>
143 </plurals>
144 <string name="no_save_data_found">No save data found</string>
136 145
137 <!-- Applet launcher strings --> 146 <!-- Applet launcher strings -->
138 <string name="applets">Applet launcher</string> 147 <string name="applets">Applet launcher</string>
@@ -276,6 +285,7 @@
276 <string name="global">Global</string> 285 <string name="global">Global</string>
277 <string name="custom">Custom</string> 286 <string name="custom">Custom</string>
278 <string name="notice">Notice</string> 287 <string name="notice">Notice</string>
288 <string name="import_complete">Import complete</string>
279 289
280 <!-- GPU driver installation --> 290 <!-- GPU driver installation -->
281 <string name="select_gpu_driver">Select GPU driver</string> 291 <string name="select_gpu_driver">Select GPU driver</string>
@@ -463,9 +473,13 @@
463 <string name="anti_aliasing_smaa">SMAA</string> 473 <string name="anti_aliasing_smaa">SMAA</string>
464 474
465 <!-- Screen Layouts --> 475 <!-- Screen Layouts -->
476 <string name="screen_layout_auto">Auto</string>
477 <string name="screen_layout_sensor_landscape">Sensor landscape</string>
466 <string name="screen_layout_landscape">Landscape</string> 478 <string name="screen_layout_landscape">Landscape</string>
479 <string name="screen_layout_reverse_landscape">Reverse landscape</string>
480 <string name="screen_layout_sensor_portrait">Sensor portrait</string>
467 <string name="screen_layout_portrait">Portrait</string> 481 <string name="screen_layout_portrait">Portrait</string>
468 <string name="screen_layout_auto">Auto</string> 482 <string name="screen_layout_reverse_portrait">Reverse portrait</string>
469 483
470 <!-- Aspect Ratios --> 484 <!-- Aspect Ratios -->
471 <string name="ratio_default">Default (16:9)</string> 485 <string name="ratio_default">Default (16:9)</string>
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index dfba79267..adcc23c18 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -183,22 +183,6 @@ add_library(core STATIC
183 frontend/framebuffer_layout.cpp 183 frontend/framebuffer_layout.cpp
184 frontend/framebuffer_layout.h 184 frontend/framebuffer_layout.h
185 frontend/graphics_context.h 185 frontend/graphics_context.h
186 hid/emulated_console.cpp
187 hid/emulated_console.h
188 hid/emulated_controller.cpp
189 hid/emulated_controller.h
190 hid/emulated_devices.cpp
191 hid/emulated_devices.h
192 hid/hid_core.cpp
193 hid/hid_core.h
194 hid/hid_types.h
195 hid/input_converter.cpp
196 hid/input_converter.h
197 hid/input_interpreter.cpp
198 hid/input_interpreter.h
199 hid/irs_types.h
200 hid/motion_input.cpp
201 hid/motion_input.h
202 hle/api_version.h 186 hle/api_version.h
203 hle/ipc.h 187 hle/ipc.h
204 hle/kernel/board/nintendo/nx/k_memory_layout.cpp 188 hle/kernel/board/nintendo/nx/k_memory_layout.cpp
@@ -531,90 +515,16 @@ add_library(core STATIC
531 hle/service/hid/hid.h 515 hle/service/hid/hid.h
532 hle/service/hid/hid_debug_server.cpp 516 hle/service/hid/hid_debug_server.cpp
533 hle/service/hid/hid_debug_server.h 517 hle/service/hid/hid_debug_server.h
534 hle/service/hid/hid_firmware_settings.cpp
535 hle/service/hid/hid_firmware_settings.h
536 hle/service/hid/hid_server.cpp 518 hle/service/hid/hid_server.cpp
537 hle/service/hid/hid_server.h 519 hle/service/hid/hid_server.h
538 hle/service/hid/hid_system_server.cpp 520 hle/service/hid/hid_system_server.cpp
539 hle/service/hid/hid_system_server.h 521 hle/service/hid/hid_system_server.h
540 hle/service/hid/hid_util.h
541 hle/service/hid/hidbus.cpp 522 hle/service/hid/hidbus.cpp
542 hle/service/hid/hidbus.h 523 hle/service/hid/hidbus.h
543 hle/service/hid/irs.cpp 524 hle/service/hid/irs.cpp
544 hle/service/hid/irs.h 525 hle/service/hid/irs.h
545 hle/service/hid/irs_ring_lifo.h
546 hle/service/hid/resource_manager.cpp
547 hle/service/hid/resource_manager.h
548 hle/service/hid/ring_lifo.h
549 hle/service/hid/xcd.cpp 526 hle/service/hid/xcd.cpp
550 hle/service/hid/xcd.h 527 hle/service/hid/xcd.h
551 hle/service/hid/errors.h
552 hle/service/hid/controllers/types/debug_pad_types.h
553 hle/service/hid/controllers/types/keyboard_types.h
554 hle/service/hid/controllers/types/mouse_types.h
555 hle/service/hid/controllers/types/npad_types.h
556 hle/service/hid/controllers/types/shared_memory_format.h
557 hle/service/hid/controllers/types/touch_types.h
558 hle/service/hid/controllers/applet_resource.cpp
559 hle/service/hid/controllers/applet_resource.h
560 hle/service/hid/controllers/capture_button.cpp
561 hle/service/hid/controllers/capture_button.h
562 hle/service/hid/controllers/console_six_axis.cpp
563 hle/service/hid/controllers/console_six_axis.h
564 hle/service/hid/controllers/controller_base.cpp
565 hle/service/hid/controllers/controller_base.h
566 hle/service/hid/controllers/debug_mouse.cpp
567 hle/service/hid/controllers/debug_mouse.h
568 hle/service/hid/controllers/debug_pad.cpp
569 hle/service/hid/controllers/debug_pad.h
570 hle/service/hid/controllers/digitizer.cpp
571 hle/service/hid/controllers/digitizer.h
572 hle/service/hid/controllers/gesture.cpp
573 hle/service/hid/controllers/gesture.h
574 hle/service/hid/controllers/home_button.cpp
575 hle/service/hid/controllers/home_button.h
576 hle/service/hid/controllers/keyboard.cpp
577 hle/service/hid/controllers/keyboard.h
578 hle/service/hid/controllers/mouse.cpp
579 hle/service/hid/controllers/mouse.h
580 hle/service/hid/controllers/npad.cpp
581 hle/service/hid/controllers/npad.h
582 hle/service/hid/controllers/palma.cpp
583 hle/service/hid/controllers/palma.h
584 hle/service/hid/controllers/seven_six_axis.cpp
585 hle/service/hid/controllers/seven_six_axis.h
586 hle/service/hid/controllers/shared_memory_holder.cpp
587 hle/service/hid/controllers/shared_memory_holder.h
588 hle/service/hid/controllers/six_axis.cpp
589 hle/service/hid/controllers/six_axis.h
590 hle/service/hid/controllers/sleep_button.cpp
591 hle/service/hid/controllers/sleep_button.h
592 hle/service/hid/controllers/touchscreen.cpp
593 hle/service/hid/controllers/touchscreen.h
594 hle/service/hid/controllers/unique_pad.cpp
595 hle/service/hid/controllers/unique_pad.h
596 hle/service/hid/hidbus/hidbus_base.cpp
597 hle/service/hid/hidbus/hidbus_base.h
598 hle/service/hid/hidbus/ringcon.cpp
599 hle/service/hid/hidbus/ringcon.h
600 hle/service/hid/hidbus/starlink.cpp
601 hle/service/hid/hidbus/starlink.h
602 hle/service/hid/hidbus/stubbed.cpp
603 hle/service/hid/hidbus/stubbed.h
604 hle/service/hid/irsensor/clustering_processor.cpp
605 hle/service/hid/irsensor/clustering_processor.h
606 hle/service/hid/irsensor/image_transfer_processor.cpp
607 hle/service/hid/irsensor/image_transfer_processor.h
608 hle/service/hid/irsensor/ir_led_processor.cpp
609 hle/service/hid/irsensor/ir_led_processor.h
610 hle/service/hid/irsensor/moment_processor.cpp
611 hle/service/hid/irsensor/moment_processor.h
612 hle/service/hid/irsensor/pointing_processor.cpp
613 hle/service/hid/irsensor/pointing_processor.h
614 hle/service/hid/irsensor/processor_base.cpp
615 hle/service/hid/irsensor/processor_base.h
616 hle/service/hid/irsensor/tera_plugin_processor.cpp
617 hle/service/hid/irsensor/tera_plugin_processor.h
618 hle/service/lbl/lbl.cpp 528 hle/service/lbl/lbl.cpp
619 hle/service/lbl/lbl.h 529 hle/service/lbl/lbl.h
620 hle/service/ldn/lan_discovery.cpp 530 hle/service/ldn/lan_discovery.cpp
@@ -955,7 +865,7 @@ endif()
955 865
956create_target_directory_groups(core) 866create_target_directory_groups(core)
957 867
958target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core nx_tzdb) 868target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb)
959target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API) 869target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API)
960if (MINGW) 870if (MINGW)
961 target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY}) 871 target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 66f444d39..c063f7719 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -28,7 +28,6 @@
28#include "core/file_sys/savedata_factory.h" 28#include "core/file_sys/savedata_factory.h"
29#include "core/file_sys/vfs_concat.h" 29#include "core/file_sys/vfs_concat.h"
30#include "core/file_sys/vfs_real.h" 30#include "core/file_sys/vfs_real.h"
31#include "core/hid/hid_core.h"
32#include "core/hle/kernel/k_memory_manager.h" 31#include "core/hle/kernel/k_memory_manager.h"
33#include "core/hle/kernel/k_process.h" 32#include "core/hle/kernel/k_process.h"
34#include "core/hle/kernel/k_resource_limit.h" 33#include "core/hle/kernel/k_resource_limit.h"
@@ -52,6 +51,7 @@
52#include "core/telemetry_session.h" 51#include "core/telemetry_session.h"
53#include "core/tools/freezer.h" 52#include "core/tools/freezer.h"
54#include "core/tools/renderdoc.h" 53#include "core/tools/renderdoc.h"
54#include "hid_core/hid_core.h"
55#include "network/network.h" 55#include "network/network.h"
56#include "video_core/host1x/host1x.h" 56#include "video_core/host1x/host1x.h"
57#include "video_core/renderer_base.h" 57#include "video_core/renderer_base.h"
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index 8d5d593e8..12b3bd797 100644
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -189,6 +189,15 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
189 } 189 }
190} 190}
191 191
192std::string SaveDataFactory::GetUserGameSaveDataRoot(u128 user_id, bool future) {
193 if (future) {
194 Common::UUID uuid;
195 std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
196 return fmt::format("/user/save/account/{}", uuid.RawString());
197 }
198 return fmt::format("/user/save/{:016X}/{:016X}{:016X}", 0, user_id[1], user_id[0]);
199}
200
192SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, 201SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
193 u128 user_id) const { 202 u128 user_id) const {
194 const auto path = 203 const auto path =
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h
index e3a0f8cef..fd4887e99 100644
--- a/src/core/file_sys/savedata_factory.h
+++ b/src/core/file_sys/savedata_factory.h
@@ -101,6 +101,7 @@ public:
101 static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space); 101 static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
102 static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space, 102 static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space,
103 SaveDataType type, u64 title_id, u128 user_id, u64 save_id); 103 SaveDataType type, u64 title_id, u128 user_id, u64 save_id);
104 static std::string GetUserGameSaveDataRoot(u128 user_id, bool future);
104 105
105 SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const; 106 SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
106 void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, 107 void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 27755cb58..34fe23b6a 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -6,9 +6,9 @@
6#include "common/settings.h" 6#include "common/settings.h"
7#include "common/settings_enums.h" 7#include "common/settings_enums.h"
8#include "core/frontend/applets/controller.h" 8#include "core/frontend/applets/controller.h"
9#include "core/hid/emulated_controller.h" 9#include "hid_core/frontend/emulated_controller.h"
10#include "core/hid/hid_core.h" 10#include "hid_core/hid_core.h"
11#include "core/hid/hid_types.h" 11#include "hid_core/hid_types.h"
12 12
13namespace Core::Frontend { 13namespace Core::Frontend {
14 14
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 24394d222..7d3421929 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -1258,11 +1258,11 @@ ThreadState KThread::RequestTerminate() {
1258 // Change the thread's priority to be higher than any system thread's. 1258 // Change the thread's priority to be higher than any system thread's.
1259 this->IncreaseBasePriority(TerminatingThreadPriority); 1259 this->IncreaseBasePriority(TerminatingThreadPriority);
1260 1260
1261 // If the thread is runnable, send a termination interrupt to other cores. 1261 // If the thread is runnable, send a termination interrupt to cores it may be running on.
1262 if (this->GetState() == ThreadState::Runnable) { 1262 if (this->GetState() == ThreadState::Runnable) {
1263 if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask() & 1263 // NOTE: We do not mask the "current core", because this code may not actually be
1264 ~(1ULL << GetCurrentCoreId(m_kernel)); 1264 // executing from the thread representing the "current core".
1265 core_mask != 0) { 1265 if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask(); core_mask != 0) {
1266 Kernel::KInterruptManager::SendInterProcessorInterrupt(m_kernel, core_mask); 1266 Kernel::KInterruptManager::SendInterProcessorInterrupt(m_kernel, core_mask);
1267 } 1267 }
1268 } 1268 }
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 97eb56ff0..9e05bdafa 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -13,7 +13,6 @@
13#include "core/file_sys/patch_manager.h" 13#include "core/file_sys/patch_manager.h"
14#include "core/file_sys/registered_cache.h" 14#include "core/file_sys/registered_cache.h"
15#include "core/file_sys/savedata_factory.h" 15#include "core/file_sys/savedata_factory.h"
16#include "core/hid/hid_types.h"
17#include "core/hle/kernel/k_event.h" 16#include "core/hle/kernel/k_event.h"
18#include "core/hle/kernel/k_transfer_memory.h" 17#include "core/hle/kernel/k_transfer_memory.h"
19#include "core/hle/result.h" 18#include "core/hle/result.h"
@@ -37,7 +36,6 @@
37#include "core/hle/service/caps/caps_su.h" 36#include "core/hle/service/caps/caps_su.h"
38#include "core/hle/service/caps/caps_types.h" 37#include "core/hle/service/caps/caps_types.h"
39#include "core/hle/service/filesystem/filesystem.h" 38#include "core/hle/service/filesystem/filesystem.h"
40#include "core/hle/service/hid/controllers/npad.h"
41#include "core/hle/service/ipc_helpers.h" 39#include "core/hle/service/ipc_helpers.h"
42#include "core/hle/service/ns/ns.h" 40#include "core/hle/service/ns/ns.h"
43#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" 41#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
@@ -48,6 +46,8 @@
48#include "core/hle/service/vi/vi.h" 46#include "core/hle/service/vi/vi.h"
49#include "core/hle/service/vi/vi_results.h" 47#include "core/hle/service/vi/vi_results.h"
50#include "core/memory.h" 48#include "core/memory.h"
49#include "hid_core/hid_types.h"
50#include "hid_core/resources/npad/npad.h"
51 51
52namespace Service::AM { 52namespace Service::AM {
53 53
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp
index 3906c0fa4..c2ff444a6 100644
--- a/src/core/hle/service/am/applets/applet_cabinet.cpp
+++ b/src/core/hle/service/am/applets/applet_cabinet.cpp
@@ -5,13 +5,13 @@
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "core/core.h" 6#include "core/core.h"
7#include "core/frontend/applets/cabinet.h" 7#include "core/frontend/applets/cabinet.h"
8#include "core/hid/hid_core.h"
9#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
10#include "core/hle/kernel/k_readable_event.h" 9#include "core/hle/kernel/k_readable_event.h"
11#include "core/hle/service/am/am.h" 10#include "core/hle/service/am/am.h"
12#include "core/hle/service/am/applets/applet_cabinet.h" 11#include "core/hle/service/am/applets/applet_cabinet.h"
13#include "core/hle/service/mii/mii_manager.h" 12#include "core/hle/service/mii/mii_manager.h"
14#include "core/hle/service/nfc/common/device.h" 13#include "core/hle/service/nfc/common/device.h"
14#include "hid_core/hid_core.h"
15 15
16namespace Service::AM::Applets { 16namespace Service::AM::Applets {
17 17
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp
index 9840d2547..0e4d9cc39 100644
--- a/src/core/hle/service/am/applets/applet_controller.cpp
+++ b/src/core/hle/service/am/applets/applet_controller.cpp
@@ -9,13 +9,13 @@
9#include "common/string_util.h" 9#include "common/string_util.h"
10#include "core/core.h" 10#include "core/core.h"
11#include "core/frontend/applets/controller.h" 11#include "core/frontend/applets/controller.h"
12#include "core/hid/emulated_controller.h"
13#include "core/hid/hid_core.h"
14#include "core/hid/hid_types.h"
15#include "core/hle/result.h" 12#include "core/hle/result.h"
16#include "core/hle/service/am/am.h" 13#include "core/hle/service/am/am.h"
17#include "core/hle/service/am/applets/applet_controller.h" 14#include "core/hle/service/am/applets/applet_controller.h"
18#include "core/hle/service/hid/controllers/npad.h" 15#include "hid_core/frontend/emulated_controller.h"
16#include "hid_core/hid_core.h"
17#include "hid_core/hid_types.h"
18#include "hid_core/resources/npad/npad.h"
19 19
20namespace Service::AM::Applets { 20namespace Service::AM::Applets {
21 21
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
deleted file mode 100644
index 80cfcb2bb..000000000
--- a/src/core/hle/service/hid/controllers/npad.h
+++ /dev/null
@@ -1,197 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <array>
7#include <atomic>
8#include <mutex>
9#include <span>
10
11#include "common/common_types.h"
12#include "core/hid/hid_types.h"
13#include "core/hle/service/hid/controllers/controller_base.h"
14#include "core/hle/service/hid/controllers/types/npad_types.h"
15
16namespace Core::HID {
17class EmulatedController;
18enum class ControllerTriggerType;
19} // namespace Core::HID
20
21namespace Kernel {
22class KEvent;
23class KReadableEvent;
24} // namespace Kernel
25
26namespace Service::KernelHelpers {
27class ServiceContext;
28} // namespace Service::KernelHelpers
29
30union Result;
31
32namespace Service::HID {
33class AppletResource;
34struct NpadInternalState;
35struct NpadSixAxisSensorLifo;
36struct NpadSharedMemoryFormat;
37
38class NPad final : public ControllerBase {
39public:
40 explicit NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
41 ~NPad() override;
42
43 // Called when the controller is initialized
44 void OnInit() override;
45
46 // When the controller is released
47 void OnRelease() override;
48
49 // When the controller is requesting an update for the shared memory
50 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
51
52 void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
53 Core::HID::NpadStyleTag GetSupportedStyleSet() const;
54
55 Result SetSupportedNpadIdTypes(std::span<const u8> data);
56 void GetSupportedNpadIdTypes(u32* data, std::size_t max_length);
57 std::size_t GetSupportedNpadIdTypesSize() const;
58
59 void SetHoldType(NpadJoyHoldType joy_hold_type);
60 NpadJoyHoldType GetHoldType() const;
61
62 void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode);
63 NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
64
65 void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
66 NpadCommunicationMode GetNpadCommunicationMode() const;
67
68 bool SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
69 NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
70
71 bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
72 const Core::HID::VibrationValue& vibration_value);
73
74 void VibrateController(const Core::HID::VibrationDeviceHandle& vibration_device_handle,
75 const Core::HID::VibrationValue& vibration_value);
76
77 void VibrateControllers(
78 std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
79 std::span<const Core::HID::VibrationValue> vibration_values);
80
81 Core::HID::VibrationValue GetLastVibration(
82 const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
83
84 void InitializeVibrationDevice(const Core::HID::VibrationDeviceHandle& vibration_device_handle);
85
86 void InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index);
87
88 void SetPermitVibrationSession(bool permit_vibration_session);
89
90 bool IsVibrationDeviceMounted(
91 const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
92
93 Kernel::KReadableEvent& GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id);
94 void SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const;
95
96 // Adds a new controller at an index.
97 void AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id);
98 // Adds a new controller at an index with connection status.
99 void UpdateControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id,
100 bool connected);
101
102 Result DisconnectNpad(Core::HID::NpadIdType npad_id);
103
104 Result IsFirmwareUpdateAvailableForSixAxisSensor(
105 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const;
106 Result ResetIsSixAxisSensorDeviceNewlyAssigned(
107 const Core::HID::SixAxisSensorHandle& sixaxis_handle);
108
109 Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
110 Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
111 bool& is_enabled) const;
112 Result SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
113 Core::HID::NpadIdType npad_id);
114 void SetAnalogStickUseCenterClamp(bool use_center_clamp);
115 void ClearAllConnectedControllers();
116 void DisconnectAllConnectedControllers();
117 void ConnectAllDisconnectedControllers();
118 void ClearAllControllers();
119
120 Result MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
121 Core::HID::NpadIdType npad_id_2);
122 void StartLRAssignmentMode();
123 void StopLRAssignmentMode();
124 Result SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
125
126 // Logical OR for all buttons presses on all controllers
127 // Specifically for cheat engine and other features.
128 Core::HID::NpadButton GetAndResetPressState();
129
130 void ApplyNpadSystemCommonPolicy();
131
132 AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
133
134private:
135 struct VibrationData {
136 bool device_mounted{};
137 Core::HID::VibrationValue latest_vibration_value{};
138 std::chrono::steady_clock::time_point last_vibration_timepoint{};
139 };
140
141 struct NpadControllerData {
142 Kernel::KEvent* styleset_changed_event{};
143 NpadInternalState* shared_memory = nullptr;
144 Core::HID::EmulatedController* device = nullptr;
145
146 std::array<VibrationData, 2> vibration{};
147 bool unintended_home_button_input_protection{};
148 bool is_connected{};
149
150 // Dual joycons can have only one side connected
151 bool is_dual_left_connected{true};
152 bool is_dual_right_connected{true};
153
154 // Current pad state
155 NPadGenericState npad_pad_state{};
156 NPadGenericState npad_libnx_state{};
157 NpadGcTriggerState npad_trigger_state{};
158 int callback_key{};
159 };
160
161 void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
162 void InitNewlyAddedController(Core::HID::NpadIdType npad_id);
163 bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const;
164 void RequestPadStateUpdate(Core::HID::NpadIdType npad_id);
165 void WriteEmptyEntry(NpadInternalState* npad);
166
167 NpadControllerData& GetControllerFromHandle(
168 const Core::HID::VibrationDeviceHandle& device_handle);
169 const NpadControllerData& GetControllerFromHandle(
170 const Core::HID::VibrationDeviceHandle& device_handle) const;
171 NpadControllerData& GetControllerFromHandle(
172 const Core::HID::SixAxisSensorHandle& device_handle);
173 const NpadControllerData& GetControllerFromHandle(
174 const Core::HID::SixAxisSensorHandle& device_handle) const;
175 NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
176 const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
177
178 Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
179 const Core::HID::SixAxisSensorHandle& device_handle);
180 const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
181 const Core::HID::SixAxisSensorHandle& device_handle) const;
182
183 std::atomic<u64> press_state{};
184
185 std::array<NpadControllerData, NpadCount> controller_data{};
186 KernelHelpers::ServiceContext& service_context;
187 std::mutex mutex;
188 std::vector<Core::HID::NpadIdType> supported_npad_id_types{};
189 NpadJoyHoldType hold_type{NpadJoyHoldType::Vertical};
190 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
191 NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
192 bool permit_vibration_session_enabled{false};
193 bool analog_stick_use_center_clamp{false};
194 bool is_in_lr_assignment_mode{false};
195 bool is_controller_initialized{false};
196};
197} // namespace Service::HID
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h
deleted file mode 100644
index 6dc976fe1..000000000
--- a/src/core/hle/service/hid/errors.h
+++ /dev/null
@@ -1,39 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/result.h"
7
8namespace Service::HID {
9
10constexpr Result PalmaResultSuccess{ErrorModule::HID, 0};
11constexpr Result NpadInvalidHandle{ErrorModule::HID, 100};
12constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
13constexpr Result VibrationInvalidStyleIndex{ErrorModule::HID, 122};
14constexpr Result VibrationInvalidNpadId{ErrorModule::HID, 123};
15constexpr Result VibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
16constexpr Result InvalidSixAxisFusionRange{ErrorModule::HID, 423};
17constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};
18constexpr Result NpadIsSameType{ErrorModule::HID, 602};
19constexpr Result InvalidNpadId{ErrorModule::HID, 709};
20constexpr Result NpadNotConnected{ErrorModule::HID, 710};
21constexpr Result InvalidArraySize{ErrorModule::HID, 715};
22
23constexpr Result ResultAppletResourceOverflow{ErrorModule::HID, 1041};
24constexpr Result ResultAppletResourceNotInitialized{ErrorModule::HID, 1042};
25constexpr Result ResultSharedMemoryNotInitialized{ErrorModule::HID, 1043};
26constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044};
27constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046};
28constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047};
29
30constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
31
32} // namespace Service::HID
33
34namespace Service::IRS {
35
36constexpr Result InvalidProcessorState{ErrorModule::Irsensor, 78};
37constexpr Result InvalidIrCameraHandle{ErrorModule::Irsensor, 204};
38
39} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index afbcb019f..fc8a3ab66 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -5,14 +5,14 @@
5#include "core/hle/kernel/kernel.h" 5#include "core/hle/kernel/kernel.h"
6#include "core/hle/service/hid/hid.h" 6#include "core/hle/service/hid/hid.h"
7#include "core/hle/service/hid/hid_debug_server.h" 7#include "core/hle/service/hid/hid_debug_server.h"
8#include "core/hle/service/hid/hid_firmware_settings.h"
9#include "core/hle/service/hid/hid_server.h" 8#include "core/hle/service/hid/hid_server.h"
10#include "core/hle/service/hid/hid_system_server.h" 9#include "core/hle/service/hid/hid_system_server.h"
11#include "core/hle/service/hid/hidbus.h" 10#include "core/hle/service/hid/hidbus.h"
12#include "core/hle/service/hid/irs.h" 11#include "core/hle/service/hid/irs.h"
13#include "core/hle/service/hid/resource_manager.h"
14#include "core/hle/service/hid/xcd.h" 12#include "core/hle/service/hid/xcd.h"
15#include "core/hle/service/server_manager.h" 13#include "core/hle/service/server_manager.h"
14#include "hid_core/resource_manager.h"
15#include "hid_core/resources/hid_firmware_settings.h"
16 16
17namespace Service::HID { 17namespace Service::HID {
18 18
@@ -25,6 +25,7 @@ void LoopProcess(Core::System& system) {
25 // TODO: Remove this hack until this service is emulated properly. 25 // TODO: Remove this hack until this service is emulated properly.
26 const auto process_list = system.Kernel().GetProcessList(); 26 const auto process_list = system.Kernel().GetProcessList();
27 if (!process_list.empty()) { 27 if (!process_list.empty()) {
28 resouce_manager->Initialize();
28 resouce_manager->RegisterAppletResourceUserId(process_list[0]->GetId(), true); 29 resouce_manager->RegisterAppletResourceUserId(process_list[0]->GetId(), true);
29 } 30 }
30 31
diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp
index 6294f3dfb..f2a767d37 100644
--- a/src/core/hle/service/hid/hid_debug_server.cpp
+++ b/src/core/hle/service/hid/hid_debug_server.cpp
@@ -2,8 +2,8 @@
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/hle/service/hid/hid_debug_server.h" 4#include "core/hle/service/hid/hid_debug_server.h"
5#include "core/hle/service/hid/resource_manager.h"
6#include "core/hle/service/ipc_helpers.h" 5#include "core/hle/service/ipc_helpers.h"
6#include "hid_core/resource_manager.h"
7 7
8namespace Service::HID { 8namespace Service::HID {
9 9
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 3174672af..2ff00d30d 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -5,30 +5,29 @@
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "common/settings.h" 7#include "common/settings.h"
8#include "core/hid/hid_core.h"
9#include "core/hle/kernel/k_shared_memory.h" 8#include "core/hle/kernel/k_shared_memory.h"
10#include "core/hle/kernel/k_transfer_memory.h" 9#include "core/hle/kernel/k_transfer_memory.h"
11#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
12#include "core/hle/service/hid/errors.h"
13#include "core/hle/service/hid/hid_firmware_settings.h"
14#include "core/hle/service/hid/hid_server.h" 11#include "core/hle/service/hid/hid_server.h"
15#include "core/hle/service/hid/hid_util.h"
16#include "core/hle/service/hid/resource_manager.h"
17#include "core/hle/service/ipc_helpers.h" 12#include "core/hle/service/ipc_helpers.h"
18#include "core/memory.h" 13#include "core/memory.h"
19 14#include "hid_core/hid_result.h"
20#include "core/hle/service/hid/controllers/console_six_axis.h" 15#include "hid_core/hid_util.h"
21#include "core/hle/service/hid/controllers/controller_base.h" 16#include "hid_core/resource_manager.h"
22#include "core/hle/service/hid/controllers/debug_pad.h" 17#include "hid_core/resources/hid_firmware_settings.h"
23#include "core/hle/service/hid/controllers/gesture.h" 18
24#include "core/hle/service/hid/controllers/keyboard.h" 19#include "hid_core/resources/controller_base.h"
25#include "core/hle/service/hid/controllers/mouse.h" 20#include "hid_core/resources/debug_pad/debug_pad.h"
26#include "core/hle/service/hid/controllers/npad.h" 21#include "hid_core/resources/keyboard/keyboard.h"
27#include "core/hle/service/hid/controllers/palma.h" 22#include "hid_core/resources/mouse/mouse.h"
28#include "core/hle/service/hid/controllers/seven_six_axis.h" 23#include "hid_core/resources/npad/npad.h"
29#include "core/hle/service/hid/controllers/six_axis.h" 24#include "hid_core/resources/npad/npad_types.h"
30#include "core/hle/service/hid/controllers/touchscreen.h" 25#include "hid_core/resources/palma/palma.h"
31#include "core/hle/service/hid/controllers/types/npad_types.h" 26#include "hid_core/resources/six_axis/console_six_axis.h"
27#include "hid_core/resources/six_axis/seven_six_axis.h"
28#include "hid_core/resources/six_axis/six_axis.h"
29#include "hid_core/resources/touch_screen/gesture.h"
30#include "hid_core/resources/touch_screen/touch_screen.h"
32 31
33namespace Service::HID { 32namespace Service::HID {
34 33
@@ -785,8 +784,8 @@ void IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ct
785 784
786 bool is_firmware_available{}; 785 bool is_firmware_available{};
787 auto controller = GetResourceManager()->GetNpad(); 786 auto controller = GetResourceManager()->GetNpad();
788 controller->IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle, 787 controller->IsFirmwareUpdateAvailableForSixAxisSensor(
789 is_firmware_available); 788 parameters.applet_resource_user_id, parameters.sixaxis_handle, is_firmware_available);
790 789
791 LOG_WARNING( 790 LOG_WARNING(
792 Service_HID, 791 Service_HID,
@@ -924,8 +923,8 @@ void IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx)
924 const auto parameters{rp.PopRaw<Parameters>()}; 923 const auto parameters{rp.PopRaw<Parameters>()};
925 924
926 auto controller = GetResourceManager()->GetNpad(); 925 auto controller = GetResourceManager()->GetNpad();
927 const auto result = 926 const auto result = controller->ResetIsSixAxisSensorDeviceNewlyAssigned(
928 controller->ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle); 927 parameters.applet_resource_user_id, parameters.sixaxis_handle);
929 928
930 LOG_WARNING( 929 LOG_WARNING(
931 Service_HID, 930 Service_HID,
@@ -970,7 +969,7 @@ void IHidServer::ActivateGesture(HLERequestContext& ctx) {
970void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) { 969void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
971 IPC::RequestParser rp{ctx}; 970 IPC::RequestParser rp{ctx};
972 struct Parameters { 971 struct Parameters {
973 Core::HID::NpadStyleSet supported_styleset; 972 Core::HID::NpadStyleSet supported_style_set;
974 INSERT_PADDING_WORDS_NOINIT(1); 973 INSERT_PADDING_WORDS_NOINIT(1);
975 u64 applet_resource_user_id; 974 u64 applet_resource_user_id;
976 }; 975 };
@@ -978,13 +977,25 @@ void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
978 977
979 const auto parameters{rp.PopRaw<Parameters>()}; 978 const auto parameters{rp.PopRaw<Parameters>()};
980 979
981 GetResourceManager()->GetNpad()->SetSupportedStyleSet({parameters.supported_styleset}); 980 LOG_DEBUG(Service_HID, "called, supported_style_set={}, applet_resource_user_id={}",
981 parameters.supported_style_set, parameters.applet_resource_user_id);
982 982
983 LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}", 983 const auto npad = GetResourceManager()->GetNpad();
984 parameters.supported_styleset, parameters.applet_resource_user_id); 984 const Result result = npad->SetSupportedNpadStyleSet(parameters.applet_resource_user_id,
985 parameters.supported_style_set);
986
987 if (result.IsSuccess()) {
988 Core::HID::NpadStyleTag style_tag{parameters.supported_style_set};
989 const auto revision = npad->GetRevision(parameters.applet_resource_user_id);
990
991 if (style_tag.palma != 0 && revision < NpadRevision::Revision3) {
992 // GetResourceManager()->GetPalma()->EnableBoostMode(parameters.applet_resource_user_id,
993 // true);
994 }
995 }
985 996
986 IPC::ResponseBuilder rb{ctx, 2}; 997 IPC::ResponseBuilder rb{ctx, 2};
987 rb.Push(ResultSuccess); 998 rb.Push(result);
988} 999}
989 1000
990void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) { 1001void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
@@ -993,19 +1004,31 @@ void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
993 1004
994 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1005 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
995 1006
1007 Core::HID::NpadStyleSet supported_style_set{};
1008 const auto npad = GetResourceManager()->GetNpad();
1009 const auto result =
1010 npad->GetSupportedNpadStyleSet(applet_resource_user_id, supported_style_set);
1011
996 IPC::ResponseBuilder rb{ctx, 3}; 1012 IPC::ResponseBuilder rb{ctx, 3};
997 rb.Push(ResultSuccess); 1013 rb.Push(result);
998 rb.PushEnum(GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw); 1014 rb.PushEnum(supported_style_set);
999} 1015}
1000 1016
1001void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) { 1017void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) {
1002 IPC::RequestParser rp{ctx}; 1018 IPC::RequestParser rp{ctx};
1003 const auto applet_resource_user_id{rp.Pop<u64>()}; 1019 const auto applet_resource_user_id{rp.Pop<u64>()};
1004 1020 const auto buffer = ctx.ReadBuffer();
1005 const auto result = GetResourceManager()->GetNpad()->SetSupportedNpadIdTypes(ctx.ReadBuffer()); 1021 const std::size_t elements = ctx.GetReadBufferNumElements<Core::HID::NpadIdType>();
1006 1022
1007 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1023 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1008 1024
1025 std::vector<Core::HID::NpadIdType> supported_npad_list(elements);
1026 memcpy(supported_npad_list.data(), buffer.data(), buffer.size());
1027
1028 const auto npad = GetResourceManager()->GetNpad();
1029 const Result result =
1030 npad->SetSupportedNpadIdType(applet_resource_user_id, supported_npad_list);
1031
1009 IPC::ResponseBuilder rb{ctx, 2}; 1032 IPC::ResponseBuilder rb{ctx, 2};
1010 rb.Push(result); 1033 rb.Push(result);
1011} 1034}
@@ -1018,7 +1041,7 @@ void IHidServer::ActivateNpad(HLERequestContext& ctx) {
1018 1041
1019 auto npad = GetResourceManager()->GetNpad(); 1042 auto npad = GetResourceManager()->GetNpad();
1020 1043
1021 // TODO: npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0); 1044 npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0);
1022 const Result result = npad->Activate(applet_resource_user_id); 1045 const Result result = npad->Activate(applet_resource_user_id);
1023 1046
1024 IPC::ResponseBuilder rb{ctx, 2}; 1047 IPC::ResponseBuilder rb{ctx, 2};
@@ -1052,13 +1075,13 @@ void IHidServer::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
1052 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", 1075 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
1053 parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown); 1076 parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
1054 1077
1055 // Games expect this event to be signaled after calling this function 1078 Kernel::KReadableEvent* style_set_update_event;
1056 GetResourceManager()->GetNpad()->SignalStyleSetChangedEvent(parameters.npad_id); 1079 const auto result = GetResourceManager()->GetNpad()->AcquireNpadStyleSetUpdateEventHandle(
1080 parameters.applet_resource_user_id, &style_set_update_event, parameters.npad_id);
1057 1081
1058 IPC::ResponseBuilder rb{ctx, 2, 1}; 1082 IPC::ResponseBuilder rb{ctx, 2, 1};
1059 rb.Push(ResultSuccess); 1083 rb.Push(result);
1060 rb.PushCopyObjects( 1084 rb.PushCopyObjects(style_set_update_event);
1061 GetResourceManager()->GetNpad()->GetStyleSetChangedEvent(parameters.npad_id));
1062} 1085}
1063 1086
1064void IHidServer::DisconnectNpad(HLERequestContext& ctx) { 1087void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
@@ -1073,7 +1096,7 @@ void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
1073 const auto parameters{rp.PopRaw<Parameters>()}; 1096 const auto parameters{rp.PopRaw<Parameters>()};
1074 1097
1075 auto controller = GetResourceManager()->GetNpad(); 1098 auto controller = GetResourceManager()->GetNpad();
1076 controller->DisconnectNpad(parameters.npad_id); 1099 controller->DisconnectNpad(parameters.applet_resource_user_id, parameters.npad_id);
1077 1100
1078 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, 1101 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1079 parameters.applet_resource_user_id); 1102 parameters.applet_resource_user_id);
@@ -1113,7 +1136,7 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
1113 1136
1114 auto npad = GetResourceManager()->GetNpad(); 1137 auto npad = GetResourceManager()->GetNpad();
1115 1138
1116 // TODO: npad->SetRevision(applet_resource_user_id, revision); 1139 npad->SetRevision(parameters.applet_resource_user_id, parameters.revision);
1117 const auto result = npad->Activate(parameters.applet_resource_user_id); 1140 const auto result = npad->Activate(parameters.applet_resource_user_id);
1118 1141
1119 IPC::ResponseBuilder rb{ctx, 2}; 1142 IPC::ResponseBuilder rb{ctx, 2};
@@ -1125,13 +1148,19 @@ void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) {
1125 const auto applet_resource_user_id{rp.Pop<u64>()}; 1148 const auto applet_resource_user_id{rp.Pop<u64>()};
1126 const auto hold_type{rp.PopEnum<NpadJoyHoldType>()}; 1149 const auto hold_type{rp.PopEnum<NpadJoyHoldType>()};
1127 1150
1128 GetResourceManager()->GetNpad()->SetHoldType(hold_type);
1129
1130 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}", 1151 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
1131 applet_resource_user_id, hold_type); 1152 applet_resource_user_id, hold_type);
1132 1153
1154 if (hold_type != NpadJoyHoldType::Horizontal && hold_type != NpadJoyHoldType::Vertical) {
1155 // This should crash console
1156 ASSERT_MSG(false, "Invalid npad joy hold type");
1157 }
1158
1159 const auto npad = GetResourceManager()->GetNpad();
1160 const auto result = npad->SetNpadJoyHoldType(applet_resource_user_id, hold_type);
1161
1133 IPC::ResponseBuilder rb{ctx, 2}; 1162 IPC::ResponseBuilder rb{ctx, 2};
1134 rb.Push(ResultSuccess); 1163 rb.Push(result);
1135} 1164}
1136 1165
1137void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) { 1166void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
@@ -1140,9 +1169,13 @@ void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
1140 1169
1141 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1170 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1142 1171
1172 NpadJoyHoldType hold_type{};
1173 const auto npad = GetResourceManager()->GetNpad();
1174 const auto result = npad->GetNpadJoyHoldType(applet_resource_user_id, hold_type);
1175
1143 IPC::ResponseBuilder rb{ctx, 4}; 1176 IPC::ResponseBuilder rb{ctx, 4};
1144 rb.Push(ResultSuccess); 1177 rb.Push(result);
1145 rb.PushEnum(GetResourceManager()->GetNpad()->GetHoldType()); 1178 rb.PushEnum(hold_type);
1146} 1179}
1147 1180
1148void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) { 1181void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
@@ -1158,8 +1191,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx)
1158 1191
1159 Core::HID::NpadIdType new_npad_id{}; 1192 Core::HID::NpadIdType new_npad_id{};
1160 auto controller = GetResourceManager()->GetNpad(); 1193 auto controller = GetResourceManager()->GetNpad();
1161 controller->SetNpadMode(new_npad_id, parameters.npad_id, NpadJoyDeviceType::Left, 1194 controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
1162 NpadJoyAssignmentMode::Single); 1195 NpadJoyDeviceType::Left, NpadJoyAssignmentMode::Single);
1163 1196
1164 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, 1197 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1165 parameters.applet_resource_user_id); 1198 parameters.applet_resource_user_id);
@@ -1182,8 +1215,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
1182 1215
1183 Core::HID::NpadIdType new_npad_id{}; 1216 Core::HID::NpadIdType new_npad_id{};
1184 auto controller = GetResourceManager()->GetNpad(); 1217 auto controller = GetResourceManager()->GetNpad();
1185 controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, 1218 controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
1186 NpadJoyAssignmentMode::Single); 1219 parameters.npad_joy_device_type, NpadJoyAssignmentMode::Single);
1187 1220
1188 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", 1221 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1189 parameters.npad_id, parameters.applet_resource_user_id, 1222 parameters.npad_id, parameters.applet_resource_user_id,
@@ -1206,7 +1239,8 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
1206 1239
1207 Core::HID::NpadIdType new_npad_id{}; 1240 Core::HID::NpadIdType new_npad_id{};
1208 auto controller = GetResourceManager()->GetNpad(); 1241 auto controller = GetResourceManager()->GetNpad();
1209 controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NpadJoyAssignmentMode::Dual); 1242 controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id, {},
1243 NpadJoyAssignmentMode::Dual);
1210 1244
1211 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, 1245 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1212 parameters.applet_resource_user_id); // Spams a lot when controller applet is open 1246 parameters.applet_resource_user_id); // Spams a lot when controller applet is open
@@ -1222,7 +1256,8 @@ void IHidServer::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
1222 const auto applet_resource_user_id{rp.Pop<u64>()}; 1256 const auto applet_resource_user_id{rp.Pop<u64>()};
1223 1257
1224 auto controller = GetResourceManager()->GetNpad(); 1258 auto controller = GetResourceManager()->GetNpad();
1225 const auto result = controller->MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); 1259 const auto result =
1260 controller->MergeSingleJoyAsDualJoy(applet_resource_user_id, npad_id_1, npad_id_2);
1226 1261
1227 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", 1262 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
1228 npad_id_1, npad_id_2, applet_resource_user_id); 1263 npad_id_1, npad_id_2, applet_resource_user_id);
@@ -1235,10 +1270,10 @@ void IHidServer::StartLrAssignmentMode(HLERequestContext& ctx) {
1235 IPC::RequestParser rp{ctx}; 1270 IPC::RequestParser rp{ctx};
1236 const auto applet_resource_user_id{rp.Pop<u64>()}; 1271 const auto applet_resource_user_id{rp.Pop<u64>()};
1237 1272
1238 GetResourceManager()->GetNpad()->StartLRAssignmentMode();
1239
1240 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1273 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1241 1274
1275 GetResourceManager()->GetNpad()->StartLrAssignmentMode(applet_resource_user_id);
1276
1242 IPC::ResponseBuilder rb{ctx, 2}; 1277 IPC::ResponseBuilder rb{ctx, 2};
1243 rb.Push(ResultSuccess); 1278 rb.Push(ResultSuccess);
1244} 1279}
@@ -1247,10 +1282,10 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) {
1247 IPC::RequestParser rp{ctx}; 1282 IPC::RequestParser rp{ctx};
1248 const auto applet_resource_user_id{rp.Pop<u64>()}; 1283 const auto applet_resource_user_id{rp.Pop<u64>()};
1249 1284
1250 GetResourceManager()->GetNpad()->StopLRAssignmentMode();
1251
1252 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1285 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1253 1286
1287 GetResourceManager()->GetNpad()->StopLrAssignmentMode(applet_resource_user_id);
1288
1254 IPC::ResponseBuilder rb{ctx, 2}; 1289 IPC::ResponseBuilder rb{ctx, 2};
1255 rb.Push(ResultSuccess); 1290 rb.Push(ResultSuccess);
1256} 1291}
@@ -1260,13 +1295,23 @@ void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
1260 const auto applet_resource_user_id{rp.Pop<u64>()}; 1295 const auto applet_resource_user_id{rp.Pop<u64>()};
1261 const auto activation_mode{rp.PopEnum<NpadHandheldActivationMode>()}; 1296 const auto activation_mode{rp.PopEnum<NpadHandheldActivationMode>()};
1262 1297
1263 GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode);
1264
1265 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}", 1298 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
1266 applet_resource_user_id, activation_mode); 1299 applet_resource_user_id, activation_mode);
1267 1300
1301 if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) {
1302 // Console should crash here
1303 ASSERT_MSG(false, "Activation mode should be always None, Single or Dual");
1304 IPC::ResponseBuilder rb{ctx, 2};
1305 rb.Push(ResultSuccess);
1306 return;
1307 }
1308
1309 const auto npad = GetResourceManager()->GetNpad();
1310 const auto result =
1311 npad->SetNpadHandheldActivationMode(applet_resource_user_id, activation_mode);
1312
1268 IPC::ResponseBuilder rb{ctx, 2}; 1313 IPC::ResponseBuilder rb{ctx, 2};
1269 rb.Push(ResultSuccess); 1314 rb.Push(result);
1270} 1315}
1271 1316
1272void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) { 1317void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
@@ -1275,9 +1320,14 @@ void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
1275 1320
1276 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1321 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1277 1322
1323 NpadHandheldActivationMode activation_mode{};
1324 const auto npad = GetResourceManager()->GetNpad();
1325 const auto result =
1326 npad->GetNpadHandheldActivationMode(applet_resource_user_id, activation_mode);
1327
1278 IPC::ResponseBuilder rb{ctx, 4}; 1328 IPC::ResponseBuilder rb{ctx, 4};
1279 rb.Push(ResultSuccess); 1329 rb.Push(result);
1280 rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadHandheldActivationMode()); 1330 rb.PushEnum(activation_mode);
1281} 1331}
1282 1332
1283void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) { 1333void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
@@ -1286,12 +1336,12 @@ void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
1286 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; 1336 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
1287 const auto applet_resource_user_id{rp.Pop<u64>()}; 1337 const auto applet_resource_user_id{rp.Pop<u64>()};
1288 1338
1289 auto controller = GetResourceManager()->GetNpad();
1290 const auto result = controller->SwapNpadAssignment(npad_id_1, npad_id_2);
1291
1292 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", 1339 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
1293 npad_id_1, npad_id_2, applet_resource_user_id); 1340 npad_id_1, npad_id_2, applet_resource_user_id);
1294 1341
1342 const auto npad = GetResourceManager()->GetNpad();
1343 const auto result = npad->SwapNpadAssignment(applet_resource_user_id, npad_id_1, npad_id_2);
1344
1295 IPC::ResponseBuilder rb{ctx, 2}; 1345 IPC::ResponseBuilder rb{ctx, 2};
1296 rb.Push(result); 1346 rb.Push(result);
1297} 1347}
@@ -1307,13 +1357,19 @@ void IHidServer::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext&
1307 1357
1308 const auto parameters{rp.PopRaw<Parameters>()}; 1358 const auto parameters{rp.PopRaw<Parameters>()};
1309 1359
1310 bool is_enabled = false; 1360 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1311 auto controller = GetResourceManager()->GetNpad(); 1361 parameters.applet_resource_user_id);
1312 const auto result =
1313 controller->IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
1314 1362
1315 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", 1363 if (!IsNpadIdValid(parameters.npad_id)) {
1316 parameters.npad_id, parameters.applet_resource_user_id); 1364 IPC::ResponseBuilder rb{ctx, 3};
1365 rb.Push(ResultInvalidNpadId);
1366 return;
1367 }
1368
1369 bool is_enabled{};
1370 const auto npad = GetResourceManager()->GetNpad();
1371 const auto result = npad->IsUnintendedHomeButtonInputProtectionEnabled(
1372 is_enabled, parameters.applet_resource_user_id, parameters.npad_id);
1317 1373
1318 IPC::ResponseBuilder rb{ctx, 3}; 1374 IPC::ResponseBuilder rb{ctx, 3};
1319 rb.Push(result); 1375 rb.Push(result);
@@ -1332,13 +1388,18 @@ void IHidServer::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ct
1332 1388
1333 const auto parameters{rp.PopRaw<Parameters>()}; 1389 const auto parameters{rp.PopRaw<Parameters>()};
1334 1390
1335 auto controller = GetResourceManager()->GetNpad(); 1391 LOG_INFO(Service_HID, "called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
1336 const auto result = controller->SetUnintendedHomeButtonInputProtectionEnabled( 1392 parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
1337 parameters.is_enabled, parameters.npad_id);
1338 1393
1339 LOG_DEBUG(Service_HID, 1394 if (!IsNpadIdValid(parameters.npad_id)) {
1340 "(STUBBED) called, is_enabled={}, npad_id={}, applet_resource_user_id={}", 1395 IPC::ResponseBuilder rb{ctx, 3};
1341 parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id); 1396 rb.Push(ResultInvalidNpadId);
1397 return;
1398 }
1399
1400 const auto npad = GetResourceManager()->GetNpad();
1401 const auto result = npad->EnableUnintendedHomeButtonInputProtection(
1402 parameters.applet_resource_user_id, parameters.npad_id, parameters.is_enabled);
1342 1403
1343 IPC::ResponseBuilder rb{ctx, 2}; 1404 IPC::ResponseBuilder rb{ctx, 2};
1344 rb.Push(result); 1405 rb.Push(result);
@@ -1359,8 +1420,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
1359 Core::HID::NpadIdType new_npad_id{}; 1420 Core::HID::NpadIdType new_npad_id{};
1360 auto controller = GetResourceManager()->GetNpad(); 1421 auto controller = GetResourceManager()->GetNpad();
1361 const auto is_reassigned = 1422 const auto is_reassigned =
1362 controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, 1423 controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
1363 NpadJoyAssignmentMode::Single); 1424 parameters.npad_joy_device_type, NpadJoyAssignmentMode::Single);
1364 1425
1365 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", 1426 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1366 parameters.npad_id, parameters.applet_resource_user_id, 1427 parameters.npad_id, parameters.applet_resource_user_id,
@@ -1375,7 +1436,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
1375void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) { 1436void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
1376 IPC::RequestParser rp{ctx}; 1437 IPC::RequestParser rp{ctx};
1377 struct Parameters { 1438 struct Parameters {
1378 bool analog_stick_use_center_clamp; 1439 bool use_center_clamp;
1379 INSERT_PADDING_BYTES_NOINIT(7); 1440 INSERT_PADDING_BYTES_NOINIT(7);
1380 u64 applet_resource_user_id; 1441 u64 applet_resource_user_id;
1381 }; 1442 };
@@ -1383,12 +1444,11 @@ void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
1383 1444
1384 const auto parameters{rp.PopRaw<Parameters>()}; 1445 const auto parameters{rp.PopRaw<Parameters>()};
1385 1446
1386 GetResourceManager()->GetNpad()->SetAnalogStickUseCenterClamp( 1447 LOG_WARNING(Service_HID, "(STUBBED) called, use_center_clamp={}, applet_resource_user_id={}",
1387 parameters.analog_stick_use_center_clamp); 1448 parameters.use_center_clamp, parameters.applet_resource_user_id);
1388 1449
1389 LOG_WARNING(Service_HID, 1450 GetResourceManager()->GetNpad()->SetNpadAnalogStickUseCenterClamp(
1390 "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}", 1451 parameters.applet_resource_user_id, parameters.use_center_clamp);
1391 parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id);
1392 1452
1393 IPC::ResponseBuilder rb{ctx, 2}; 1453 IPC::ResponseBuilder rb{ctx, 2};
1394 rb.Push(ResultSuccess); 1454 rb.Push(ResultSuccess);
@@ -1496,7 +1556,8 @@ void IHidServer::SendVibrationValue(HLERequestContext& ctx) {
1496 1556
1497 const auto parameters{rp.PopRaw<Parameters>()}; 1557 const auto parameters{rp.PopRaw<Parameters>()};
1498 1558
1499 GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle, 1559 GetResourceManager()->GetNpad()->VibrateController(parameters.applet_resource_user_id,
1560 parameters.vibration_device_handle,
1500 parameters.vibration_value); 1561 parameters.vibration_value);
1501 1562
1502 LOG_DEBUG(Service_HID, 1563 LOG_DEBUG(Service_HID,
@@ -1528,8 +1589,8 @@ void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {
1528 1589
1529 IPC::ResponseBuilder rb{ctx, 6}; 1590 IPC::ResponseBuilder rb{ctx, 6};
1530 rb.Push(ResultSuccess); 1591 rb.Push(ResultSuccess);
1531 rb.PushRaw( 1592 rb.PushRaw(GetResourceManager()->GetNpad()->GetLastVibration(
1532 GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle)); 1593 parameters.applet_resource_user_id, parameters.vibration_device_handle));
1533} 1594}
1534 1595
1535void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) { 1596void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
@@ -1580,7 +1641,8 @@ void IHidServer::SendVibrationValues(HLERequestContext& ctx) {
1580 auto vibration_values = std::span( 1641 auto vibration_values = std::span(
1581 reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count); 1642 reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count);
1582 1643
1583 GetResourceManager()->GetNpad()->VibrateControllers(vibration_device_handles, vibration_values); 1644 GetResourceManager()->GetNpad()->VibrateControllers(applet_resource_user_id,
1645 vibration_device_handles, vibration_values);
1584 1646
1585 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1647 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1586 1648
@@ -1634,8 +1696,8 @@ void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
1634 } 1696 }
1635 }(); 1697 }();
1636 1698
1637 GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle, 1699 GetResourceManager()->GetNpad()->VibrateController(
1638 vibration_value); 1700 parameters.applet_resource_user_id, parameters.vibration_device_handle, vibration_value);
1639 1701
1640 LOG_DEBUG(Service_HID, 1702 LOG_DEBUG(Service_HID,
1641 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, " 1703 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
@@ -1659,8 +1721,8 @@ void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
1659 1721
1660 const auto parameters{rp.PopRaw<Parameters>()}; 1722 const auto parameters{rp.PopRaw<Parameters>()};
1661 1723
1662 const auto last_vibration = 1724 const auto last_vibration = GetResourceManager()->GetNpad()->GetLastVibration(
1663 GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle); 1725 parameters.applet_resource_user_id, parameters.vibration_device_handle);
1664 1726
1665 const auto gc_erm_command = [last_vibration] { 1727 const auto gc_erm_command = [last_vibration] {
1666 if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) { 1728 if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) {
@@ -1732,7 +1794,7 @@ void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) {
1732 IPC::ResponseBuilder rb{ctx, 3}; 1794 IPC::ResponseBuilder rb{ctx, 3};
1733 rb.Push(ResultSuccess); 1795 rb.Push(ResultSuccess);
1734 rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted( 1796 rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted(
1735 parameters.vibration_device_handle)); 1797 parameters.applet_resource_user_id, parameters.vibration_device_handle));
1736} 1798}
1737 1799
1738void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) { 1800void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
@@ -2315,10 +2377,10 @@ void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
2315 const auto applet_resource_user_id{rp.Pop<u64>()}; 2377 const auto applet_resource_user_id{rp.Pop<u64>()};
2316 const auto communication_mode{rp.PopEnum<NpadCommunicationMode>()}; 2378 const auto communication_mode{rp.PopEnum<NpadCommunicationMode>()};
2317 2379
2318 GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode); 2380 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, communication_mode={}",
2381 applet_resource_user_id, communication_mode);
2319 2382
2320 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}", 2383 // This function has been stubbed since 2.0.0+
2321 applet_resource_user_id, communication_mode);
2322 2384
2323 IPC::ResponseBuilder rb{ctx, 2}; 2385 IPC::ResponseBuilder rb{ctx, 2};
2324 rb.Push(ResultSuccess); 2386 rb.Push(ResultSuccess);
@@ -2326,12 +2388,15 @@ void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
2326 2388
2327void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) { 2389void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) {
2328 IPC::RequestParser rp{ctx}; 2390 IPC::RequestParser rp{ctx};
2391 const auto applet_resource_user_id{rp.Pop<u64>()};
2329 2392
2330 LOG_WARNING(Service_HID, "(STUBBED) called"); 2393 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
2394
2395 // This function has been stubbed since 2.0.0+
2331 2396
2332 IPC::ResponseBuilder rb{ctx, 4}; 2397 IPC::ResponseBuilder rb{ctx, 4};
2333 rb.Push(ResultSuccess); 2398 rb.Push(ResultSuccess);
2334 rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadCommunicationMode()); 2399 rb.PushEnum(NpadCommunicationMode::Default);
2335} 2400}
2336 2401
2337void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) { 2402void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index 5cc88c4a1..2a65615e8 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -1,15 +1,14 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/hid/hid_core.h"
5#include "core/hle/service/hid/controllers/npad.h"
6#include "core/hle/service/hid/controllers/palma.h"
7#include "core/hle/service/hid/controllers/touchscreen.h"
8#include "core/hle/service/hid/controllers/types/npad_types.h"
9#include "core/hle/service/hid/errors.h"
10#include "core/hle/service/hid/hid_system_server.h" 4#include "core/hle/service/hid/hid_system_server.h"
11#include "core/hle/service/hid/resource_manager.h"
12#include "core/hle/service/ipc_helpers.h" 5#include "core/hle/service/ipc_helpers.h"
6#include "hid_core/hid_result.h"
7#include "hid_core/resource_manager.h"
8#include "hid_core/resources/npad/npad.h"
9#include "hid_core/resources/npad/npad_types.h"
10#include "hid_core/resources/palma/palma.h"
11#include "hid_core/resources/touch_screen/touch_screen.h"
13 12
14namespace Service::HID { 13namespace Service::HID {
15 14
@@ -82,7 +81,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
82 {522, nullptr, "SetJoyConRailEnabled"}, 81 {522, nullptr, "SetJoyConRailEnabled"},
83 {523, nullptr, "IsJoyConRailEnabled"}, 82 {523, nullptr, "IsJoyConRailEnabled"},
84 {524, nullptr, "IsHandheldHidsEnabled"}, 83 {524, nullptr, "IsHandheldHidsEnabled"},
85 {525, nullptr, "IsJoyConAttachedOnAllRail"}, 84 {525, &IHidSystemServer::IsJoyConAttachedOnAllRail, "IsJoyConAttachedOnAllRail"},
86 {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"}, 85 {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
87 {541, nullptr, "GetPlayReportControllerUsages"}, 86 {541, nullptr, "GetPlayReportControllerUsages"},
88 {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"}, 87 {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
@@ -132,7 +131,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
132 {1001, nullptr, "GetFirmwareVersion"}, 131 {1001, nullptr, "GetFirmwareVersion"},
133 {1002, nullptr, "GetAvailableFirmwareVersion"}, 132 {1002, nullptr, "GetAvailableFirmwareVersion"},
134 {1003, nullptr, "IsFirmwareUpdateAvailable"}, 133 {1003, nullptr, "IsFirmwareUpdateAvailable"},
135 {1004, nullptr, "CheckFirmwareUpdateRequired"}, 134 {1004, &IHidSystemServer::CheckFirmwareUpdateRequired, "CheckFirmwareUpdateRequired"},
136 {1005, nullptr, "StartFirmwareUpdate"}, 135 {1005, nullptr, "StartFirmwareUpdate"},
137 {1006, nullptr, "AbortFirmwareUpdate"}, 136 {1006, nullptr, "AbortFirmwareUpdate"},
138 {1007, nullptr, "GetFirmwareUpdateState"}, 137 {1007, nullptr, "GetFirmwareUpdateState"},
@@ -145,9 +144,9 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
145 {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"}, 144 {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
146 {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"}, 145 {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
147 {1100, nullptr, "GetHidbusSystemServiceObject"}, 146 {1100, nullptr, "GetHidbusSystemServiceObject"},
148 {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"}, 147 {1120, &IHidSystemServer::SetFirmwareHotfixUpdateSkipEnabled, "SetFirmwareHotfixUpdateSkipEnabled"},
149 {1130, nullptr, "InitializeUsbFirmwareUpdate"}, 148 {1130, &IHidSystemServer::InitializeUsbFirmwareUpdate, "InitializeUsbFirmwareUpdate"},
150 {1131, nullptr, "FinalizeUsbFirmwareUpdate"}, 149 {1131, &IHidSystemServer::FinalizeUsbFirmwareUpdate, "FinalizeUsbFirmwareUpdate"},
151 {1132, nullptr, "CheckUsbFirmwareUpdateRequired"}, 150 {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
152 {1133, nullptr, "StartUsbFirmwareUpdate"}, 151 {1133, nullptr, "StartUsbFirmwareUpdate"},
153 {1134, nullptr, "GetUsbFirmwareUpdateState"}, 152 {1134, nullptr, "GetUsbFirmwareUpdateState"},
@@ -197,7 +196,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
197 {1268, nullptr, "DeleteButtonConfigStorageFull"}, 196 {1268, nullptr, "DeleteButtonConfigStorageFull"},
198 {1269, nullptr, "DeleteButtonConfigStorageLeft"}, 197 {1269, nullptr, "DeleteButtonConfigStorageLeft"},
199 {1270, nullptr, "DeleteButtonConfigStorageRight"}, 198 {1270, nullptr, "DeleteButtonConfigStorageRight"},
200 {1271, nullptr, "IsUsingCustomButtonConfig"}, 199 {1271, &IHidSystemServer::IsUsingCustomButtonConfig, "IsUsingCustomButtonConfig"},
201 {1272, nullptr, "IsAnyCustomButtonConfigEnabled"}, 200 {1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
202 {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, 201 {1273, nullptr, "SetAllCustomButtonConfigEnabled"},
203 {1274, nullptr, "SetDefaultButtonConfig"}, 202 {1274, nullptr, "SetDefaultButtonConfig"},
@@ -240,9 +239,12 @@ IHidSystemServer::~IHidSystemServer() {
240}; 239};
241 240
242void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) { 241void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
243 LOG_WARNING(Service_HID, "called"); 242 IPC::RequestParser rp{ctx};
243 const auto applet_resource_user_id{rp.Pop<u64>()};
244
245 LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
244 246
245 GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy(); 247 GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy(applet_resource_user_id);
246 248
247 IPC::ResponseBuilder rb{ctx, 2}; 249 IPC::ResponseBuilder rb{ctx, 2};
248 rb.Push(ResultSuccess); 250 rb.Push(ResultSuccess);
@@ -267,13 +269,16 @@ void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
267 269
268 IPC::ResponseBuilder rb{ctx, 3}; 270 IPC::ResponseBuilder rb{ctx, 3};
269 rb.Push(ResultSuccess); 271 rb.Push(ResultSuccess);
270 rb.PushEnum(system.HIDCore().GetLastActiveController()); 272 rb.Push(0); // Dont forget to fix this
271} 273}
272 274
273void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) { 275void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) {
274 LOG_WARNING(Service_HID, "called"); 276 IPC::RequestParser rp{ctx};
277 const auto applet_resource_user_id{rp.Pop<u64>()};
275 278
276 GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy(); 279 LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
280
281 GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicyFull(applet_resource_user_id);
277 282
278 IPC::ResponseBuilder rb{ctx, 2}; 283 IPC::ResponseBuilder rb{ctx, 2};
279 rb.Push(ResultSuccess); 284 rb.Push(ResultSuccess);
@@ -298,28 +303,32 @@ void IHidSystemServer::GetNpadFullKeyGripColor(HLERequestContext& ctx) {
298 303
299void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) { 304void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) {
300 IPC::RequestParser rp{ctx}; 305 IPC::RequestParser rp{ctx};
306 const auto applet_resource_user_id{rp.Pop<u64>()};
301 307
302 LOG_INFO(Service_HID, "(STUBBED) called"); 308 LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
303 309
304 Core::HID::NpadStyleSet supported_styleset = 310 Core::HID::NpadStyleSet supported_styleset{};
305 GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw; 311 const auto& npad = GetResourceManager()->GetNpad();
312 const Result result =
313 npad->GetMaskedSupportedNpadStyleSet(applet_resource_user_id, supported_styleset);
306 314
307 IPC::ResponseBuilder rb{ctx, 3}; 315 IPC::ResponseBuilder rb{ctx, 3};
308 rb.Push(ResultSuccess); 316 rb.Push(result);
309 rb.PushEnum(supported_styleset); 317 rb.PushEnum(supported_styleset);
310} 318}
311 319
312void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) { 320void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) {
313 IPC::RequestParser rp{ctx}; 321 IPC::RequestParser rp{ctx};
322 const auto applet_resource_user_id{rp.Pop<u64>()};
314 323
315 LOG_INFO(Service_HID, "(STUBBED) called"); 324 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
316 325
317 Core::HID::NpadStyleSet supported_styleset = 326 const auto& npad = GetResourceManager()->GetNpad();
318 GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw; 327 const auto result =
328 npad->SetSupportedNpadStyleSet(applet_resource_user_id, Core::HID::NpadStyleSet::All);
319 329
320 IPC::ResponseBuilder rb{ctx, 3}; 330 IPC::ResponseBuilder rb{ctx, 2};
321 rb.Push(ResultSuccess); 331 rb.Push(result);
322 rb.PushEnum(supported_styleset);
323} 332}
324 333
325void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) { 334void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
@@ -546,6 +555,16 @@ void IHidSystemServer::EnableAppletToGetTouchScreen(HLERequestContext& ctx) {
546 rb.Push(ResultSuccess); 555 rb.Push(ResultSuccess);
547} 556}
548 557
558void IHidSystemServer::IsJoyConAttachedOnAllRail(HLERequestContext& ctx) {
559 const bool is_attached = true;
560
561 LOG_DEBUG(Service_HID, "(STUBBED) called, is_attached={}", is_attached);
562
563 IPC::ResponseBuilder rb{ctx, 3};
564 rb.Push(ResultSuccess);
565 rb.Push(is_attached);
566}
567
549void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) { 568void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) {
550 LOG_INFO(Service_AM, "(STUBBED) called"); 569 LOG_INFO(Service_AM, "(STUBBED) called");
551 570
@@ -632,6 +651,34 @@ void IHidSystemServer::InitializeFirmwareUpdate(HLERequestContext& ctx) {
632 rb.Push(ResultSuccess); 651 rb.Push(ResultSuccess);
633} 652}
634 653
654void IHidSystemServer::CheckFirmwareUpdateRequired(HLERequestContext& ctx) {
655 LOG_WARNING(Service_HID, "(STUBBED) called");
656
657 IPC::ResponseBuilder rb{ctx, 2};
658 rb.Push(ResultSuccess);
659}
660
661void IHidSystemServer::SetFirmwareHotfixUpdateSkipEnabled(HLERequestContext& ctx) {
662 LOG_WARNING(Service_HID, "(STUBBED) called");
663
664 IPC::ResponseBuilder rb{ctx, 2};
665 rb.Push(ResultSuccess);
666}
667
668void IHidSystemServer::InitializeUsbFirmwareUpdate(HLERequestContext& ctx) {
669 LOG_WARNING(Service_HID, "(STUBBED) called");
670
671 IPC::ResponseBuilder rb{ctx, 2};
672 rb.Push(ResultSuccess);
673}
674
675void IHidSystemServer::FinalizeUsbFirmwareUpdate(HLERequestContext& ctx) {
676 LOG_WARNING(Service_HID, "(STUBBED) called");
677
678 IPC::ResponseBuilder rb{ctx, 2};
679 rb.Push(ResultSuccess);
680}
681
635void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) { 682void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) {
636 LOG_WARNING(Service_HID, "(STUBBED) called"); 683 LOG_WARNING(Service_HID, "(STUBBED) called");
637 684
@@ -656,6 +703,16 @@ void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx
656 rb.PushRaw(touchscreen_config); 703 rb.PushRaw(touchscreen_config);
657} 704}
658 705
706void IHidSystemServer::IsUsingCustomButtonConfig(HLERequestContext& ctx) {
707 const bool is_enabled = false;
708
709 LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled);
710
711 IPC::ResponseBuilder rb{ctx, 3};
712 rb.Push(ResultSuccess);
713 rb.Push(is_enabled);
714}
715
659std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() { 716std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() {
660 resource_manager->Initialize(); 717 resource_manager->Initialize();
661 return resource_manager; 718 return resource_manager;
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h
index 1e623dfc2..f467e2aa8 100644
--- a/src/core/hle/service/hid/hid_system_server.h
+++ b/src/core/hle/service/hid/hid_system_server.h
@@ -44,6 +44,7 @@ private:
44 void EnableAppletToGetSixAxisSensor(HLERequestContext& ctx); 44 void EnableAppletToGetSixAxisSensor(HLERequestContext& ctx);
45 void EnableAppletToGetPadInput(HLERequestContext& ctx); 45 void EnableAppletToGetPadInput(HLERequestContext& ctx);
46 void EnableAppletToGetTouchScreen(HLERequestContext& ctx); 46 void EnableAppletToGetTouchScreen(HLERequestContext& ctx);
47 void IsJoyConAttachedOnAllRail(HLERequestContext& ctx);
47 void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx); 48 void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
48 void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx); 49 void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
49 void GetRegisteredDevices(HLERequestContext& ctx); 50 void GetRegisteredDevices(HLERequestContext& ctx);
@@ -53,8 +54,13 @@ private:
53 void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx); 54 void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
54 void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx); 55 void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx);
55 void InitializeFirmwareUpdate(HLERequestContext& ctx); 56 void InitializeFirmwareUpdate(HLERequestContext& ctx);
57 void CheckFirmwareUpdateRequired(HLERequestContext& ctx);
58 void SetFirmwareHotfixUpdateSkipEnabled(HLERequestContext& ctx);
59 void InitializeUsbFirmwareUpdate(HLERequestContext& ctx);
60 void FinalizeUsbFirmwareUpdate(HLERequestContext& ctx);
56 void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx); 61 void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx);
57 void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); 62 void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx);
63 void IsUsingCustomButtonConfig(HLERequestContext& ctx);
58 64
59 std::shared_ptr<ResourceManager> GetResourceManager(); 65 std::shared_ptr<ResourceManager> GetResourceManager();
60 66
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index ffa7e144d..46f503d38 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -5,18 +5,18 @@
5#include "common/settings.h" 5#include "common/settings.h"
6#include "core/core.h" 6#include "core/core.h"
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/hid/hid_types.h"
9#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
10#include "core/hle/kernel/k_readable_event.h" 9#include "core/hle/kernel/k_readable_event.h"
11#include "core/hle/kernel/k_shared_memory.h" 10#include "core/hle/kernel/k_shared_memory.h"
12#include "core/hle/kernel/k_transfer_memory.h" 11#include "core/hle/kernel/k_transfer_memory.h"
13#include "core/hle/service/hid/hidbus.h" 12#include "core/hle/service/hid/hidbus.h"
14#include "core/hle/service/hid/hidbus/ringcon.h"
15#include "core/hle/service/hid/hidbus/starlink.h"
16#include "core/hle/service/hid/hidbus/stubbed.h"
17#include "core/hle/service/ipc_helpers.h" 13#include "core/hle/service/ipc_helpers.h"
18#include "core/hle/service/service.h" 14#include "core/hle/service/service.h"
19#include "core/memory.h" 15#include "core/memory.h"
16#include "hid_core/hid_types.h"
17#include "hid_core/hidbus/ringcon.h"
18#include "hid_core/hidbus/starlink.h"
19#include "hid_core/hidbus/stubbed.h"
20 20
21namespace Service::HID { 21namespace Service::HID {
22// (15ms, 66Hz) 22// (15ms, 66Hz)
diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h
index 85a1df133..05f62f634 100644
--- a/src/core/hle/service/hid/hidbus.h
+++ b/src/core/hle/service/hid/hidbus.h
@@ -5,9 +5,9 @@
5 5
6#include <functional> 6#include <functional>
7 7
8#include "core/hle/service/hid/hidbus/hidbus_base.h"
9#include "core/hle/service/kernel_helpers.h" 8#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
10#include "hid_core/hidbus/hidbus_base.h"
11 11
12namespace Core::Timing { 12namespace Core::Timing {
13struct EventType; 13struct EventType;
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 008debfd1..18e544f2f 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -6,22 +6,22 @@
6 6
7#include "core/core.h" 7#include "core/core.h"
8#include "core/core_timing.h" 8#include "core/core_timing.h"
9#include "core/hid/emulated_controller.h"
10#include "core/hid/hid_core.h"
11#include "core/hle/kernel/k_shared_memory.h" 9#include "core/hle/kernel/k_shared_memory.h"
12#include "core/hle/kernel/k_transfer_memory.h" 10#include "core/hle/kernel/k_transfer_memory.h"
13#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/kernel.h"
14#include "core/hle/service/hid/errors.h"
15#include "core/hle/service/hid/hid_util.h"
16#include "core/hle/service/hid/irs.h" 12#include "core/hle/service/hid/irs.h"
17#include "core/hle/service/hid/irsensor/clustering_processor.h"
18#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
19#include "core/hle/service/hid/irsensor/ir_led_processor.h"
20#include "core/hle/service/hid/irsensor/moment_processor.h"
21#include "core/hle/service/hid/irsensor/pointing_processor.h"
22#include "core/hle/service/hid/irsensor/tera_plugin_processor.h"
23#include "core/hle/service/ipc_helpers.h" 13#include "core/hle/service/ipc_helpers.h"
24#include "core/memory.h" 14#include "core/memory.h"
15#include "hid_core/frontend/emulated_controller.h"
16#include "hid_core/hid_core.h"
17#include "hid_core/hid_result.h"
18#include "hid_core/hid_util.h"
19#include "hid_core/irsensor/clustering_processor.h"
20#include "hid_core/irsensor/image_transfer_processor.h"
21#include "hid_core/irsensor/ir_led_processor.h"
22#include "hid_core/irsensor/moment_processor.h"
23#include "hid_core/irsensor/pointing_processor.h"
24#include "hid_core/irsensor/tera_plugin_processor.h"
25 25
26namespace Service::IRS { 26namespace Service::IRS {
27 27
@@ -315,7 +315,7 @@ void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) {
315 if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid && 315 if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid &&
316 npad_id != Core::HID::NpadIdType::Handheld) { 316 npad_id != Core::HID::NpadIdType::Handheld) {
317 IPC::ResponseBuilder rb{ctx, 2}; 317 IPC::ResponseBuilder rb{ctx, 2};
318 rb.Push(Service::HID::InvalidNpadId); 318 rb.Push(Service::HID::ResultInvalidNpadId);
319 return; 319 return;
320 } 320 }
321 321
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index c8e6dab17..06b7279ee 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -4,10 +4,10 @@
4#pragma once 4#pragma once
5 5
6#include "core/core.h" 6#include "core/core.h"
7#include "core/hid/hid_types.h"
8#include "core/hid/irs_types.h"
9#include "core/hle/service/hid/irsensor/processor_base.h"
10#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8#include "hid_core/hid_types.h"
9#include "hid_core/irsensor/irs_types.h"
10#include "hid_core/irsensor/processor_base.h"
11 11
12namespace Core::HID { 12namespace Core::HID {
13class EmulatedController; 13class EmulatedController;
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index f97e5b44c..b37fb6da3 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -22,9 +22,6 @@
22#include "common/string_util.h" 22#include "common/string_util.h"
23#include "common/tiny_mt.h" 23#include "common/tiny_mt.h"
24#include "core/core.h" 24#include "core/core.h"
25#include "core/hid/emulated_controller.h"
26#include "core/hid/hid_core.h"
27#include "core/hid/hid_types.h"
28#include "core/hle/kernel/k_event.h" 25#include "core/hle/kernel/k_event.h"
29#include "core/hle/service/ipc_helpers.h" 26#include "core/hle/service/ipc_helpers.h"
30#include "core/hle/service/mii/mii_manager.h" 27#include "core/hle/service/mii/mii_manager.h"
@@ -33,6 +30,9 @@
33#include "core/hle/service/nfc/mifare_result.h" 30#include "core/hle/service/nfc/mifare_result.h"
34#include "core/hle/service/nfc/nfc_result.h" 31#include "core/hle/service/nfc/nfc_result.h"
35#include "core/hle/service/time/time_manager.h" 32#include "core/hle/service/time/time_manager.h"
33#include "hid_core/frontend/emulated_controller.h"
34#include "hid_core/hid_core.h"
35#include "hid_core/hid_types.h"
36 36
37namespace Service::NFC { 37namespace Service::NFC {
38NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, 38NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_,
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index ad534177d..44f651b87 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -5,15 +5,15 @@
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hid/hid_types.h"
9#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
10#include "core/hle/service/hid/hid_util.h"
11#include "core/hle/service/ipc_helpers.h" 9#include "core/hle/service/ipc_helpers.h"
12#include "core/hle/service/nfc/common/device.h" 10#include "core/hle/service/nfc/common/device.h"
13#include "core/hle/service/nfc/common/device_manager.h" 11#include "core/hle/service/nfc/common/device_manager.h"
14#include "core/hle/service/nfc/nfc_result.h" 12#include "core/hle/service/nfc/nfc_result.h"
15#include "core/hle/service/time/clock_types.h" 13#include "core/hle/service/time/clock_types.h"
16#include "core/hle/service/time/time_manager.h" 14#include "core/hle/service/time/time_manager.h"
15#include "hid_core/hid_types.h"
16#include "hid_core/hid_util.h"
17 17
18namespace Service::NFC { 18namespace Service::NFC {
19 19
diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h
index c9f038e32..f02bdccf5 100644
--- a/src/core/hle/service/nfc/common/device_manager.h
+++ b/src/core/hle/service/nfc/common/device_manager.h
@@ -8,13 +8,13 @@
8#include <optional> 8#include <optional>
9#include <span> 9#include <span>
10 10
11#include "core/hid/hid_types.h"
12#include "core/hle/service/kernel_helpers.h" 11#include "core/hle/service/kernel_helpers.h"
13#include "core/hle/service/nfc/mifare_types.h" 12#include "core/hle/service/nfc/mifare_types.h"
14#include "core/hle/service/nfc/nfc_types.h" 13#include "core/hle/service/nfc/nfc_types.h"
15#include "core/hle/service/nfp/nfp_types.h" 14#include "core/hle/service/nfp/nfp_types.h"
16#include "core/hle/service/service.h" 15#include "core/hle/service/service.h"
17#include "core/hle/service/time/clock_types.h" 16#include "core/hle/service/time/clock_types.h"
17#include "hid_core/hid_types.h"
18 18
19namespace Service::NFC { 19namespace Service::NFC {
20class NfcDevice; 20class NfcDevice;
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp
index 179c7ba2c..a71cf74b8 100644
--- a/src/core/hle/service/nfc/nfc_interface.cpp
+++ b/src/core/hle/service/nfc/nfc_interface.cpp
@@ -3,7 +3,6 @@
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hid/hid_types.h"
7#include "core/hle/kernel/k_event.h" 6#include "core/hle/kernel/k_event.h"
8#include "core/hle/service/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/nfc/common/device.h" 8#include "core/hle/service/nfc/common/device.h"
@@ -15,6 +14,7 @@
15#include "core/hle/service/nfc/nfc_types.h" 14#include "core/hle/service/nfc/nfc_types.h"
16#include "core/hle/service/nfp/nfp_result.h" 15#include "core/hle/service/nfp/nfp_result.h"
17#include "core/hle/service/time/clock_types.h" 16#include "core/hle/service/time/clock_types.h"
17#include "hid_core/hid_types.h"
18 18
19namespace Service::NFC { 19namespace Service::NFC {
20 20
diff --git a/src/core/hle/service/nfp/nfp_interface.cpp b/src/core/hle/service/nfp/nfp_interface.cpp
index 34ef9d82d..5ba6d1742 100644
--- a/src/core/hle/service/nfp/nfp_interface.cpp
+++ b/src/core/hle/service/nfp/nfp_interface.cpp
@@ -3,7 +3,6 @@
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hid/hid_types.h"
7#include "core/hle/kernel/k_event.h" 6#include "core/hle/kernel/k_event.h"
8#include "core/hle/service/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/nfc/common/device.h" 8#include "core/hle/service/nfc/common/device.h"
@@ -12,6 +11,7 @@
12#include "core/hle/service/nfp/nfp_interface.h" 11#include "core/hle/service/nfp/nfp_interface.h"
13#include "core/hle/service/nfp/nfp_result.h" 12#include "core/hle/service/nfp/nfp_result.h"
14#include "core/hle/service/nfp/nfp_types.h" 13#include "core/hle/service/nfp/nfp_types.h"
14#include "hid_core/hid_types.h"
15 15
16namespace Service::NFP { 16namespace Service::NFP {
17 17
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 7bc5b5ae5..96fa7fa3a 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -9,12 +9,12 @@
9#include "core/core_timing.h" 9#include "core/core_timing.h"
10#include "core/hle/kernel/k_page_table.h" 10#include "core/hle/kernel/k_page_table.h"
11#include "core/hle/kernel/k_process.h" 11#include "core/hle/kernel/k_process.h"
12#include "core/hle/service/hid/controllers/npad.h"
13#include "core/hle/service/hid/hid_server.h" 12#include "core/hle/service/hid/hid_server.h"
14#include "core/hle/service/hid/resource_manager.h"
15#include "core/hle/service/sm/sm.h" 13#include "core/hle/service/sm/sm.h"
16#include "core/memory.h" 14#include "core/memory.h"
17#include "core/memory/cheat_engine.h" 15#include "core/memory/cheat_engine.h"
16#include "hid_core/resource_manager.h"
17#include "hid_core/resources/npad/npad.h"
18 18
19namespace Core::Memory { 19namespace Core::Memory {
20namespace { 20namespace {
diff --git a/src/frontend_common/config.cpp b/src/frontend_common/config.cpp
index 51576b4ee..9eb4799a6 100644
--- a/src/frontend_common/config.cpp
+++ b/src/frontend_common/config.cpp
@@ -11,7 +11,7 @@
11#include "config.h" 11#include "config.h"
12#include "core/core.h" 12#include "core/core.h"
13#include "core/hle/service/acc/profile_manager.h" 13#include "core/hle/service/acc/profile_manager.h"
14#include "core/hle/service/hid/controllers/npad.h" 14#include "hid_core/resources/npad/npad.h"
15#include "network/network.h" 15#include "network/network.h"
16 16
17#include <boost/algorithm/string/replace.hpp> 17#include <boost/algorithm/string/replace.hpp>
@@ -762,17 +762,6 @@ void Config::WriteBooleanSetting(const std::string& key, const bool& value,
762 WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global); 762 WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
763} 763}
764 764
765template <typename T>
766std::enable_if_t<std::is_integral_v<T>> Config::WriteIntegerSetting(
767 const std::string& key, const T& value, const std::optional<T>& default_value,
768 const std::optional<bool>& use_global) {
769 std::optional<std::string> string_default = std::nullopt;
770 if (default_value.has_value()) {
771 string_default = std::make_optional(ToString(default_value.value()));
772 }
773 WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
774}
775
776void Config::WriteDoubleSetting(const std::string& key, const double& value, 765void Config::WriteDoubleSetting(const std::string& key, const double& value,
777 const std::optional<double>& default_value, 766 const std::optional<double>& default_value,
778 const std::optional<bool>& use_global) { 767 const std::optional<bool>& use_global) {
@@ -894,9 +883,10 @@ void Config::WriteSettingGeneric(const Settings::BasicSetting* const setting) {
894 WriteBooleanSetting(std::string(key).append("\\use_global"), setting->UsingGlobal()); 883 WriteBooleanSetting(std::string(key).append("\\use_global"), setting->UsingGlobal());
895 } 884 }
896 if (global || !setting->UsingGlobal()) { 885 if (global || !setting->UsingGlobal()) {
886 auto value = global ? setting->ToStringGlobal() : setting->ToString();
897 WriteBooleanSetting(std::string(key).append("\\default"), 887 WriteBooleanSetting(std::string(key).append("\\default"),
898 setting->ToString() == setting->DefaultToString()); 888 value == setting->DefaultToString());
899 WriteStringSetting(key, setting->ToString()); 889 WriteStringSetting(key, value);
900 } 890 }
901 } else if (global) { 891 } else if (global) {
902 WriteBooleanSetting(std::string(key).append("\\default"), 892 WriteBooleanSetting(std::string(key).append("\\default"),
diff --git a/src/frontend_common/config.h b/src/frontend_common/config.h
index 0c4d505b8..b01631649 100644
--- a/src/frontend_common/config.h
+++ b/src/frontend_common/config.h
@@ -157,17 +157,23 @@ protected:
157 void WriteBooleanSetting(const std::string& key, const bool& value, 157 void WriteBooleanSetting(const std::string& key, const bool& value,
158 const std::optional<bool>& default_value = std::nullopt, 158 const std::optional<bool>& default_value = std::nullopt,
159 const std::optional<bool>& use_global = std::nullopt); 159 const std::optional<bool>& use_global = std::nullopt);
160 template <typename T>
161 std::enable_if_t<std::is_integral_v<T>> WriteIntegerSetting(
162 const std::string& key, const T& value,
163 const std::optional<T>& default_value = std::nullopt,
164 const std::optional<bool>& use_global = std::nullopt);
165 void WriteDoubleSetting(const std::string& key, const double& value, 160 void WriteDoubleSetting(const std::string& key, const double& value,
166 const std::optional<double>& default_value = std::nullopt, 161 const std::optional<double>& default_value = std::nullopt,
167 const std::optional<bool>& use_global = std::nullopt); 162 const std::optional<bool>& use_global = std::nullopt);
168 void WriteStringSetting(const std::string& key, const std::string& value, 163 void WriteStringSetting(const std::string& key, const std::string& value,
169 const std::optional<std::string>& default_value = std::nullopt, 164 const std::optional<std::string>& default_value = std::nullopt,
170 const std::optional<bool>& use_global = std::nullopt); 165 const std::optional<bool>& use_global = std::nullopt);
166 template <typename T>
167 std::enable_if_t<std::is_integral_v<T>> WriteIntegerSetting(
168 const std::string& key, const T& value,
169 const std::optional<T>& default_value = std::nullopt,
170 const std::optional<bool>& use_global = std::nullopt) {
171 std::optional<std::string> string_default = std::nullopt;
172 if (default_value.has_value()) {
173 string_default = std::make_optional(ToString(default_value.value()));
174 }
175 WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
176 }
171 177
172 void ReadCategory(Settings::Category category); 178 void ReadCategory(Settings::Category category);
173 void WriteCategory(Settings::Category category); 179 void WriteCategory(Settings::Category category);
diff --git a/src/hid_core/CMakeLists.txt b/src/hid_core/CMakeLists.txt
new file mode 100644
index 000000000..cce4e6857
--- /dev/null
+++ b/src/hid_core/CMakeLists.txt
@@ -0,0 +1,126 @@
1# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
2# SPDX-License-Identifier: GPL-2.0-or-later
3
4add_library(hid_core STATIC
5 frontend/emulated_console.cpp
6 frontend/emulated_console.h
7 frontend/emulated_controller.cpp
8 frontend/emulated_controller.h
9 frontend/emulated_devices.cpp
10 frontend/emulated_devices.h
11 frontend/input_converter.cpp
12 frontend/input_converter.h
13 frontend/input_interpreter.cpp
14 frontend/input_interpreter.h
15 frontend/motion_input.cpp
16 frontend/motion_input.h
17 hidbus/hidbus_base.cpp
18 hidbus/hidbus_base.h
19 hidbus/ringcon.cpp
20 hidbus/ringcon.h
21 hidbus/starlink.cpp
22 hidbus/starlink.h
23 hidbus/stubbed.cpp
24 hidbus/stubbed.h
25 irsensor/clustering_processor.cpp
26 irsensor/clustering_processor.h
27 irsensor/image_transfer_processor.cpp
28 irsensor/image_transfer_processor.h
29 irsensor/ir_led_processor.cpp
30 irsensor/ir_led_processor.h
31 irsensor/moment_processor.cpp
32 irsensor/moment_processor.h
33 irsensor/pointing_processor.cpp
34 irsensor/pointing_processor.h
35 irsensor/processor_base.cpp
36 irsensor/processor_base.h
37 irsensor/tera_plugin_processor.cpp
38 irsensor/tera_plugin_processor.h
39 resources/debug_pad/debug_pad.cpp
40 resources/debug_pad/debug_pad.h
41 resources/debug_pad/debug_pad_types.h
42 resources/digitizer/digitizer.cpp
43 resources/digitizer/digitizer.h
44 resources/keyboard/keyboard.cpp
45 resources/keyboard/keyboard.h
46 resources/keyboard/keyboard_types.h
47 resources/mouse/debug_mouse.cpp
48 resources/mouse/debug_mouse.h
49 resources/mouse/mouse.cpp
50 resources/mouse/mouse.h
51 resources/mouse/mouse_types.h
52 resources/npad/npad.cpp
53 resources/npad/npad.h
54 resources/npad/npad_data.cpp
55 resources/npad/npad_data.h
56 resources/npad/npad_resource.cpp
57 resources/npad/npad_resource.h
58 resources/npad/npad_types.h
59 resources/palma/palma.cpp
60 resources/palma/palma.h
61 resources/six_axis/console_six_axis.cpp
62 resources/six_axis/console_six_axis.h
63 resources/six_axis/seven_six_axis.cpp
64 resources/six_axis/seven_six_axis.h
65 resources/six_axis/six_axis.cpp
66 resources/six_axis/six_axis.h
67 resources/system_buttons/capture_button.cpp
68 resources/system_buttons/capture_button.h
69 resources/system_buttons/home_button.cpp
70 resources/system_buttons/home_button.h
71 resources/system_buttons/sleep_button.cpp
72 resources/system_buttons/sleep_button.h
73 resources/touch_screen/gesture.cpp
74 resources/touch_screen/gesture.h
75 resources/touch_screen/gesture_types.h
76 resources/touch_screen/touch_screen.cpp
77 resources/touch_screen/touch_screen.h
78 resources/touch_screen/touch_types.h
79 resources/unique_pad/unique_pad.cpp
80 resources/unique_pad/unique_pad.h
81 resources/applet_resource.cpp
82 resources/applet_resource.h
83 resources/controller_base.cpp
84 resources/controller_base.h
85 resources/hid_firmware_settings.cpp
86 resources/hid_firmware_settings.h
87 resources/irs_ring_lifo.h
88 resources/ring_lifo.h
89 resources/shared_memory_format.h
90 resources/shared_memory_holder.cpp
91 resources/shared_memory_holder.h
92 hid_core.cpp
93 hid_core.h
94 hid_result.h
95 hid_types.h
96 hid_util.h
97 precompiled_headers.h
98 resource_manager.cpp
99 resource_manager.h
100)
101
102if (MSVC)
103 target_compile_options(hid_core PRIVATE
104 /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
105 /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data
106 /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch
107 /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
108 /we4800 # Implicit conversion from 'type' to bool. Possible information loss
109 )
110else()
111 target_compile_options(hid_core PRIVATE
112 -Werror=conversion
113
114 -Wno-sign-conversion
115 -Wno-cast-function-type
116
117 $<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
118 )
119endif()
120
121create_target_directory_groups(hid_core)
122target_link_libraries(hid_core PUBLIC core)
123
124if (YUZU_USE_PRECOMPILED_HEADERS)
125 target_precompile_headers(hid_core PRIVATE precompiled_headers.h)
126endif()
diff --git a/src/core/hid/emulated_console.cpp b/src/hid_core/frontend/emulated_console.cpp
index b4afd930e..114c22fb7 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/hid_core/frontend/emulated_console.cpp
@@ -2,8 +2,8 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/settings.h" 4#include "common/settings.h"
5#include "core/hid/emulated_console.h" 5#include "hid_core/frontend/emulated_console.h"
6#include "core/hid/input_converter.h" 6#include "hid_core/frontend/input_converter.h"
7 7
8namespace Core::HID { 8namespace Core::HID {
9EmulatedConsole::EmulatedConsole() = default; 9EmulatedConsole::EmulatedConsole() = default;
diff --git a/src/core/hid/emulated_console.h b/src/hid_core/frontend/emulated_console.h
index fae15a556..847551395 100644
--- a/src/core/hid/emulated_console.h
+++ b/src/hid_core/frontend/emulated_console.h
@@ -17,8 +17,8 @@
17#include "common/point.h" 17#include "common/point.h"
18#include "common/quaternion.h" 18#include "common/quaternion.h"
19#include "common/vector_math.h" 19#include "common/vector_math.h"
20#include "core/hid/hid_types.h" 20#include "hid_core/frontend/motion_input.h"
21#include "core/hid/motion_input.h" 21#include "hid_core/hid_types.h"
22 22
23namespace Core::HID { 23namespace Core::HID {
24static constexpr std::size_t MaxTouchDevices = 32; 24static constexpr std::size_t MaxTouchDevices = 32;
diff --git a/src/core/hid/emulated_controller.cpp b/src/hid_core/frontend/emulated_controller.cpp
index a6e681e15..3d2d1e9f9 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/hid_core/frontend/emulated_controller.cpp
@@ -6,9 +6,9 @@
6 6
7#include "common/polyfill_ranges.h" 7#include "common/polyfill_ranges.h"
8#include "common/thread.h" 8#include "common/thread.h"
9#include "core/hid/emulated_controller.h" 9#include "hid_core/frontend/emulated_controller.h"
10#include "core/hid/input_converter.h" 10#include "hid_core/frontend/input_converter.h"
11#include "core/hle/service/hid/hid_util.h" 11#include "hid_core/hid_util.h"
12 12
13namespace Core::HID { 13namespace Core::HID {
14constexpr s32 HID_JOYSTICK_MAX = 0x7fff; 14constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
diff --git a/src/core/hid/emulated_controller.h b/src/hid_core/frontend/emulated_controller.h
index d6e20ab66..94798164d 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/hid_core/frontend/emulated_controller.h
@@ -15,9 +15,9 @@
15#include "common/param_package.h" 15#include "common/param_package.h"
16#include "common/settings.h" 16#include "common/settings.h"
17#include "common/vector_math.h" 17#include "common/vector_math.h"
18#include "core/hid/hid_types.h" 18#include "hid_core/frontend/motion_input.h"
19#include "core/hid/irs_types.h" 19#include "hid_core/hid_types.h"
20#include "core/hid/motion_input.h" 20#include "hid_core/irsensor/irs_types.h"
21 21
22namespace Core::HID { 22namespace Core::HID {
23const std::size_t max_emulated_controllers = 2; 23const std::size_t max_emulated_controllers = 2;
diff --git a/src/core/hid/emulated_devices.cpp b/src/hid_core/frontend/emulated_devices.cpp
index 8e165dded..a827aa9b7 100644
--- a/src/core/hid/emulated_devices.cpp
+++ b/src/hid_core/frontend/emulated_devices.cpp
@@ -4,8 +4,8 @@
4#include <algorithm> 4#include <algorithm>
5#include <fmt/format.h> 5#include <fmt/format.h>
6 6
7#include "core/hid/emulated_devices.h" 7#include "hid_core/frontend/emulated_devices.h"
8#include "core/hid/input_converter.h" 8#include "hid_core/frontend/input_converter.h"
9 9
10namespace Core::HID { 10namespace Core::HID {
11 11
diff --git a/src/core/hid/emulated_devices.h b/src/hid_core/frontend/emulated_devices.h
index 5eab693e4..b2e57318c 100644
--- a/src/core/hid/emulated_devices.h
+++ b/src/hid_core/frontend/emulated_devices.h
@@ -14,7 +14,7 @@
14#include "common/input.h" 14#include "common/input.h"
15#include "common/param_package.h" 15#include "common/param_package.h"
16#include "common/settings.h" 16#include "common/settings.h"
17#include "core/hid/hid_types.h" 17#include "hid_core/hid_types.h"
18 18
19namespace Core::HID { 19namespace Core::HID {
20using KeyboardDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, 20using KeyboardDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
diff --git a/src/core/hid/input_converter.cpp b/src/hid_core/frontend/input_converter.cpp
index a05716fd8..f245a3f76 100644
--- a/src/core/hid/input_converter.cpp
+++ b/src/hid_core/frontend/input_converter.cpp
@@ -5,7 +5,7 @@
5#include <random> 5#include <random>
6 6
7#include "common/input.h" 7#include "common/input.h"
8#include "core/hid/input_converter.h" 8#include "hid_core/frontend/input_converter.h"
9 9
10namespace Core::HID { 10namespace Core::HID {
11 11
diff --git a/src/core/hid/input_converter.h b/src/hid_core/frontend/input_converter.h
index c51c03e57..c51c03e57 100644
--- a/src/core/hid/input_converter.h
+++ b/src/hid_core/frontend/input_converter.h
diff --git a/src/core/hid/input_interpreter.cpp b/src/hid_core/frontend/input_interpreter.cpp
index 072f38a68..b6c8d8c5d 100644
--- a/src/core/hid/input_interpreter.cpp
+++ b/src/hid_core/frontend/input_interpreter.cpp
@@ -2,12 +2,12 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hid/hid_types.h"
6#include "core/hid/input_interpreter.h"
7#include "core/hle/service/hid/controllers/npad.h"
8#include "core/hle/service/hid/hid_server.h" 5#include "core/hle/service/hid/hid_server.h"
9#include "core/hle/service/hid/resource_manager.h"
10#include "core/hle/service/sm/sm.h" 6#include "core/hle/service/sm/sm.h"
7#include "hid_core/frontend/input_interpreter.h"
8#include "hid_core/hid_types.h"
9#include "hid_core/resource_manager.h"
10#include "hid_core/resources/npad/npad.h"
11 11
12InputInterpreter::InputInterpreter(Core::System& system) 12InputInterpreter::InputInterpreter(Core::System& system)
13 : npad{system.ServiceManager() 13 : npad{system.ServiceManager()
diff --git a/src/core/hid/input_interpreter.h b/src/hid_core/frontend/input_interpreter.h
index 3569aac93..3569aac93 100644
--- a/src/core/hid/input_interpreter.h
+++ b/src/hid_core/frontend/input_interpreter.h
diff --git a/src/core/hid/motion_input.cpp b/src/hid_core/frontend/motion_input.cpp
index f56f2ae1d..417cd03f9 100644
--- a/src/core/hid/motion_input.cpp
+++ b/src/hid_core/frontend/motion_input.cpp
@@ -4,7 +4,7 @@
4#include <cmath> 4#include <cmath>
5 5
6#include "common/math_util.h" 6#include "common/math_util.h"
7#include "core/hid/motion_input.h" 7#include "hid_core/frontend/motion_input.h"
8 8
9namespace Core::HID { 9namespace Core::HID {
10 10
diff --git a/src/core/hid/motion_input.h b/src/hid_core/frontend/motion_input.h
index 11678983d..11678983d 100644
--- a/src/core/hid/motion_input.h
+++ b/src/hid_core/frontend/motion_input.h
diff --git a/src/core/hid/hid_core.cpp b/src/hid_core/hid_core.cpp
index 2cf25a870..410c84afb 100644
--- a/src/core/hid/hid_core.cpp
+++ b/src/hid_core/hid_core.cpp
@@ -2,11 +2,11 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/assert.h" 4#include "common/assert.h"
5#include "core/hid/emulated_console.h" 5#include "hid_core/frontend/emulated_console.h"
6#include "core/hid/emulated_controller.h" 6#include "hid_core/frontend/emulated_controller.h"
7#include "core/hid/emulated_devices.h" 7#include "hid_core/frontend/emulated_devices.h"
8#include "core/hid/hid_core.h" 8#include "hid_core/hid_core.h"
9#include "core/hle/service/hid/hid_util.h" 9#include "hid_core/hid_util.h"
10 10
11namespace Core::HID { 11namespace Core::HID {
12 12
diff --git a/src/core/hid/hid_core.h b/src/hid_core/hid_core.h
index 80abab18b..dae29c506 100644
--- a/src/core/hid/hid_core.h
+++ b/src/hid_core/hid_core.h
@@ -6,7 +6,7 @@
6#include <memory> 6#include <memory>
7 7
8#include "common/common_funcs.h" 8#include "common/common_funcs.h"
9#include "core/hid/hid_types.h" 9#include "hid_core/hid_types.h"
10 10
11namespace Core::HID { 11namespace Core::HID {
12class EmulatedConsole; 12class EmulatedConsole;
diff --git a/src/hid_core/hid_result.h b/src/hid_core/hid_result.h
new file mode 100644
index 000000000..bb14aa61e
--- /dev/null
+++ b/src/hid_core/hid_result.h
@@ -0,0 +1,59 @@
1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/result.h"
7
8namespace Service::HID {
9
10constexpr Result PalmaResultSuccess{ErrorModule::HID, 0};
11constexpr Result NpadInvalidHandle{ErrorModule::HID, 100};
12constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
13
14constexpr Result ResultVibrationNotInitialized{ErrorModule::HID, 121};
15constexpr Result ResultVibrationInvalidStyleIndex{ErrorModule::HID, 122};
16constexpr Result ResultVibrationInvalidNpadId{ErrorModule::HID, 123};
17constexpr Result ResultVibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
18constexpr Result ResultVibrationStrenghtOutOfRange{ErrorModule::HID, 126};
19constexpr Result ResultVibrationArraySizeMismatch{ErrorModule::HID, 131};
20
21constexpr Result InvalidSixAxisFusionRange{ErrorModule::HID, 423};
22
23constexpr Result ResultNfcIsNotReady{ErrorModule::HID, 461};
24constexpr Result ResultNfcXcdHandleIsNotInitialized{ErrorModule::HID, 464};
25constexpr Result ResultIrSensorIsNotReady{ErrorModule::HID, 501};
26constexpr Result ResultMcuIsNotReady{ErrorModule::HID, 541};
27
28constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};
29constexpr Result NpadIsSameType{ErrorModule::HID, 602};
30constexpr Result ResultNpadIsNotProController{ErrorModule::HID, 604};
31
32constexpr Result ResultInvalidNpadId{ErrorModule::HID, 709};
33constexpr Result ResultNpadNotConnected{ErrorModule::HID, 710};
34constexpr Result ResultNpadHandlerOverflow{ErrorModule::HID, 711};
35constexpr Result ResultNpadHandlerNotInitialized{ErrorModule::HID, 712};
36constexpr Result ResultInvalidArraySize{ErrorModule::HID, 715};
37constexpr Result ResultUndefinedStyleset{ErrorModule::HID, 716};
38constexpr Result ResultMultipleStyleSetSelected{ErrorModule::HID, 717};
39
40constexpr Result ResultAppletResourceOverflow{ErrorModule::HID, 1041};
41constexpr Result ResultAppletResourceNotInitialized{ErrorModule::HID, 1042};
42constexpr Result ResultSharedMemoryNotInitialized{ErrorModule::HID, 1043};
43constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044};
44constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046};
45constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047};
46
47constexpr Result ResultNpadResourceOverflow{ErrorModule::HID, 2001};
48constexpr Result ResultNpadResourceNotInitialized{ErrorModule::HID, 2002};
49
50constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
51
52} // namespace Service::HID
53
54namespace Service::IRS {
55
56constexpr Result InvalidProcessorState{ErrorModule::Irsensor, 78};
57constexpr Result InvalidIrCameraHandle{ErrorModule::Irsensor, 204};
58
59} // namespace Service::IRS
diff --git a/src/core/hid/hid_types.h b/src/hid_core/hid_types.h
index 4bf285f36..a81ed6af0 100644
--- a/src/core/hid/hid_types.h
+++ b/src/hid_core/hid_types.h
@@ -267,6 +267,7 @@ enum class NpadStyleSet : u32 {
267 All = 0xFFFFFFFFU, 267 All = 0xFFFFFFFFU,
268}; 268};
269static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); 269static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
270DECLARE_ENUM_FLAG_OPERATORS(NpadStyleSet)
270 271
271// This is nn::hid::VibrationDevicePosition 272// This is nn::hid::VibrationDevicePosition
272enum class VibrationDevicePosition : u32 { 273enum class VibrationDevicePosition : u32 {
diff --git a/src/core/hle/service/hid/hid_util.h b/src/hid_core/hid_util.h
index b87cc10e3..94ff2d23a 100644
--- a/src/core/hle/service/hid/hid_util.h
+++ b/src/hid_core/hid_util.h
@@ -3,8 +3,8 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hid/hid_types.h" 6#include "hid_core/hid_result.h"
7#include "core/hle/service/hid/errors.h" 7#include "hid_core/hid_types.h"
8 8
9namespace Service::HID { 9namespace Service::HID {
10 10
@@ -31,7 +31,7 @@ constexpr Result IsSixaxisHandleValid(const Core::HID::SixAxisSensorHandle& hand
31 const bool device_index = handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex; 31 const bool device_index = handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
32 32
33 if (!npad_id) { 33 if (!npad_id) {
34 return InvalidNpadId; 34 return ResultInvalidNpadId;
35 } 35 }
36 if (!device_index) { 36 if (!device_index) {
37 return NpadDeviceIndexOutOfRange; 37 return NpadDeviceIndexOutOfRange;
@@ -54,15 +54,15 @@ constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle&
54 // These support vibration 54 // These support vibration
55 break; 55 break;
56 default: 56 default:
57 return VibrationInvalidStyleIndex; 57 return ResultVibrationInvalidStyleIndex;
58 } 58 }
59 59
60 if (!IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id))) { 60 if (!IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id))) {
61 return VibrationInvalidNpadId; 61 return ResultVibrationInvalidNpadId;
62 } 62 }
63 63
64 if (handle.device_index >= Core::HID::DeviceIndex::MaxDeviceIndex) { 64 if (handle.device_index >= Core::HID::DeviceIndex::MaxDeviceIndex) {
65 return VibrationDeviceIndexOutOfRange; 65 return ResultVibrationDeviceIndexOutOfRange;
66 } 66 }
67 67
68 return ResultSuccess; 68 return ResultSuccess;
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.cpp b/src/hid_core/hidbus/hidbus_base.cpp
index 8c44f93e8..632bb173b 100644
--- a/src/core/hle/service/hid/hidbus/hidbus_base.cpp
+++ b/src/hid_core/hidbus/hidbus_base.cpp
@@ -1,11 +1,11 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hid/hid_core.h"
5#include "core/hle/kernel/k_event.h" 4#include "core/hle/kernel/k_event.h"
6#include "core/hle/kernel/k_readable_event.h" 5#include "core/hle/kernel/k_readable_event.h"
7#include "core/hle/service/hid/hidbus/hidbus_base.h"
8#include "core/hle/service/kernel_helpers.h" 6#include "core/hle/service/kernel_helpers.h"
7#include "hid_core/hid_core.h"
8#include "hid_core/hidbus/hidbus_base.h"
9 9
10namespace Service::HID { 10namespace Service::HID {
11 11
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.h b/src/hid_core/hidbus/hidbus_base.h
index ec41684e1..ec41684e1 100644
--- a/src/core/hle/service/hid/hidbus/hidbus_base.h
+++ b/src/hid_core/hidbus/hidbus_base.h
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/hid_core/hidbus/ringcon.cpp
index 378108012..cedf25c16 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ b/src/hid_core/hidbus/ringcon.cpp
@@ -2,12 +2,12 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hid/emulated_controller.h"
6#include "core/hid/hid_core.h"
7#include "core/hle/kernel/k_event.h" 5#include "core/hle/kernel/k_event.h"
8#include "core/hle/kernel/k_readable_event.h" 6#include "core/hle/kernel/k_readable_event.h"
9#include "core/hle/service/hid/hidbus/ringcon.h"
10#include "core/memory.h" 7#include "core/memory.h"
8#include "hid_core/frontend/emulated_controller.h"
9#include "hid_core/hid_core.h"
10#include "hid_core/hidbus/ringcon.h"
11 11
12namespace Service::HID { 12namespace Service::HID {
13 13
diff --git a/src/core/hle/service/hid/hidbus/ringcon.h b/src/hid_core/hidbus/ringcon.h
index f42f3ea41..0953e8100 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.h
+++ b/src/hid_core/hidbus/ringcon.h
@@ -7,7 +7,7 @@
7#include <span> 7#include <span>
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/service/hid/hidbus/hidbus_base.h" 10#include "hid_core/hidbus/hidbus_base.h"
11 11
12namespace Core::HID { 12namespace Core::HID {
13class EmulatedController; 13class EmulatedController;
diff --git a/src/core/hle/service/hid/hidbus/starlink.cpp b/src/hid_core/hidbus/starlink.cpp
index 36573274e..31b263aa1 100644
--- a/src/core/hle/service/hid/hidbus/starlink.cpp
+++ b/src/hid_core/hidbus/starlink.cpp
@@ -1,9 +1,9 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hid/emulated_controller.h" 4#include "hid_core/frontend/emulated_controller.h"
5#include "core/hid/hid_core.h" 5#include "hid_core/hid_core.h"
6#include "core/hle/service/hid/hidbus/starlink.h" 6#include "hid_core/hidbus/starlink.h"
7 7
8namespace Service::HID { 8namespace Service::HID {
9constexpr u8 DEVICE_ID = 0x28; 9constexpr u8 DEVICE_ID = 0x28;
diff --git a/src/core/hle/service/hid/hidbus/starlink.h b/src/hid_core/hidbus/starlink.h
index a276aa88f..ee37763b4 100644
--- a/src/core/hle/service/hid/hidbus/starlink.h
+++ b/src/hid_core/hidbus/starlink.h
@@ -4,7 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hle/service/hid/hidbus/hidbus_base.h" 7#include "hid_core/hidbus/hidbus_base.h"
8 8
9namespace Core::HID { 9namespace Core::HID {
10class EmulatedController; 10class EmulatedController;
diff --git a/src/core/hle/service/hid/hidbus/stubbed.cpp b/src/hid_core/hidbus/stubbed.cpp
index 8160b7218..f16051aa9 100644
--- a/src/core/hle/service/hid/hidbus/stubbed.cpp
+++ b/src/hid_core/hidbus/stubbed.cpp
@@ -1,9 +1,9 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hid/emulated_controller.h" 4#include "hid_core/frontend/emulated_controller.h"
5#include "core/hid/hid_core.h" 5#include "hid_core/hid_core.h"
6#include "core/hle/service/hid/hidbus/stubbed.h" 6#include "hid_core/hidbus/stubbed.h"
7 7
8namespace Service::HID { 8namespace Service::HID {
9constexpr u8 DEVICE_ID = 0xFF; 9constexpr u8 DEVICE_ID = 0xFF;
diff --git a/src/core/hle/service/hid/hidbus/stubbed.h b/src/hid_core/hidbus/stubbed.h
index 2e58d42fc..7a711cea0 100644
--- a/src/core/hle/service/hid/hidbus/stubbed.h
+++ b/src/hid_core/hidbus/stubbed.h
@@ -4,7 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hle/service/hid/hidbus/hidbus_base.h" 7#include "hid_core/hidbus/hidbus_base.h"
8 8
9namespace Core::HID { 9namespace Core::HID {
10class EmulatedController; 10class EmulatedController;
diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.cpp b/src/hid_core/irsensor/clustering_processor.cpp
index c559eb0d5..3abe19365 100644
--- a/src/core/hle/service/hid/irsensor/clustering_processor.cpp
+++ b/src/hid_core/irsensor/clustering_processor.cpp
@@ -5,9 +5,9 @@
5 5
6#include "core/core.h" 6#include "core/core.h"
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/hid/emulated_controller.h" 8#include "hid_core/frontend/emulated_controller.h"
9#include "core/hid/hid_core.h" 9#include "hid_core/hid_core.h"
10#include "core/hle/service/hid/irsensor/clustering_processor.h" 10#include "hid_core/irsensor/clustering_processor.h"
11 11
12namespace Service::IRS { 12namespace Service::IRS {
13ClusteringProcessor::ClusteringProcessor(Core::System& system_, 13ClusteringProcessor::ClusteringProcessor(Core::System& system_,
diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.h b/src/hid_core/irsensor/clustering_processor.h
index 83f34734a..e3b60d9b0 100644
--- a/src/core/hle/service/hid/irsensor/clustering_processor.h
+++ b/src/hid_core/irsensor/clustering_processor.h
@@ -4,9 +4,9 @@
4#pragma once 4#pragma once
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hid/irs_types.h" 7#include "hid_core/irsensor/irs_types.h"
8#include "core/hle/service/hid/irs_ring_lifo.h" 8#include "hid_core/irsensor/processor_base.h"
9#include "core/hle/service/hid/irsensor/processor_base.h" 9#include "hid_core/resources/irs_ring_lifo.h"
10 10
11namespace Core { 11namespace Core {
12class System; 12class System;
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/hid_core/irsensor/image_transfer_processor.cpp
index 22067a591..d6573f8dc 100644
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
+++ b/src/hid_core/irsensor/image_transfer_processor.cpp
@@ -2,10 +2,10 @@
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hid/emulated_controller.h"
6#include "core/hid/hid_core.h"
7#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
8#include "core/memory.h" 5#include "core/memory.h"
6#include "hid_core/frontend/emulated_controller.h"
7#include "hid_core/hid_core.h"
8#include "hid_core/irsensor/image_transfer_processor.h"
9 9
10namespace Service::IRS { 10namespace Service::IRS {
11ImageTransferProcessor::ImageTransferProcessor(Core::System& system_, 11ImageTransferProcessor::ImageTransferProcessor(Core::System& system_,
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.h b/src/hid_core/irsensor/image_transfer_processor.h
index 7f42d8453..4e0117084 100644
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.h
+++ b/src/hid_core/irsensor/image_transfer_processor.h
@@ -4,8 +4,8 @@
4#pragma once 4#pragma once
5 5
6#include "common/typed_address.h" 6#include "common/typed_address.h"
7#include "core/hid/irs_types.h" 7#include "hid_core/irsensor/irs_types.h"
8#include "core/hle/service/hid/irsensor/processor_base.h" 8#include "hid_core/irsensor/processor_base.h"
9 9
10namespace Core { 10namespace Core {
11class System; 11class System;
diff --git a/src/core/hle/service/hid/irsensor/ir_led_processor.cpp b/src/hid_core/irsensor/ir_led_processor.cpp
index 8e6dd99e4..4b04e05b5 100644
--- a/src/core/hle/service/hid/irsensor/ir_led_processor.cpp
+++ b/src/hid_core/irsensor/ir_led_processor.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/hle/service/hid/irsensor/ir_led_processor.h" 4#include "hid_core/irsensor/ir_led_processor.h"
5 5
6namespace Service::IRS { 6namespace Service::IRS {
7IrLedProcessor::IrLedProcessor(Core::IrSensor::DeviceFormat& device_format) 7IrLedProcessor::IrLedProcessor(Core::IrSensor::DeviceFormat& device_format)
diff --git a/src/core/hle/service/hid/irsensor/ir_led_processor.h b/src/hid_core/irsensor/ir_led_processor.h
index c3d8693c9..03d0c4245 100644
--- a/src/core/hle/service/hid/irsensor/ir_led_processor.h
+++ b/src/hid_core/irsensor/ir_led_processor.h
@@ -5,8 +5,8 @@
5 5
6#include "common/bit_field.h" 6#include "common/bit_field.h"
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hid/irs_types.h" 8#include "hid_core/irsensor/irs_types.h"
9#include "core/hle/service/hid/irsensor/processor_base.h" 9#include "hid_core/irsensor/processor_base.h"
10 10
11namespace Service::IRS { 11namespace Service::IRS {
12class IrLedProcessor final : public ProcessorBase { 12class IrLedProcessor final : public ProcessorBase {
diff --git a/src/core/hid/irs_types.h b/src/hid_core/irsensor/irs_types.h
index 0d1bfe53f..017f38e6c 100644
--- a/src/core/hid/irs_types.h
+++ b/src/hid_core/irsensor/irs_types.h
@@ -5,7 +5,7 @@
5 5
6#include "common/common_funcs.h" 6#include "common/common_funcs.h"
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hid/hid_types.h" 8#include "hid_core/hid_types.h"
9 9
10namespace Core::IrSensor { 10namespace Core::IrSensor {
11 11
diff --git a/src/core/hle/service/hid/irsensor/moment_processor.cpp b/src/hid_core/irsensor/moment_processor.cpp
index cf045bda7..0284a58bd 100644
--- a/src/core/hle/service/hid/irsensor/moment_processor.cpp
+++ b/src/hid_core/irsensor/moment_processor.cpp
@@ -3,9 +3,9 @@
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/core_timing.h" 5#include "core/core_timing.h"
6#include "core/hid/emulated_controller.h" 6#include "hid_core/frontend/emulated_controller.h"
7#include "core/hid/hid_core.h" 7#include "hid_core/hid_core.h"
8#include "core/hle/service/hid/irsensor/moment_processor.h" 8#include "hid_core/irsensor/moment_processor.h"
9 9
10namespace Service::IRS { 10namespace Service::IRS {
11static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Size40x30; 11static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Size40x30;
diff --git a/src/core/hle/service/hid/irsensor/moment_processor.h b/src/hid_core/irsensor/moment_processor.h
index 398cfbdc1..78c9c035f 100644
--- a/src/core/hle/service/hid/irsensor/moment_processor.h
+++ b/src/hid_core/irsensor/moment_processor.h
@@ -5,9 +5,9 @@
5 5
6#include "common/bit_field.h" 6#include "common/bit_field.h"
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hid/irs_types.h" 8#include "hid_core/irsensor/irs_types.h"
9#include "core/hle/service/hid/irs_ring_lifo.h" 9#include "hid_core/irsensor/processor_base.h"
10#include "core/hle/service/hid/irsensor/processor_base.h" 10#include "hid_core/resources/irs_ring_lifo.h"
11 11
12namespace Core { 12namespace Core {
13class System; 13class System;
diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.cpp b/src/hid_core/irsensor/pointing_processor.cpp
index 929f177fc..c1d6c1bb6 100644
--- a/src/core/hle/service/hid/irsensor/pointing_processor.cpp
+++ b/src/hid_core/irsensor/pointing_processor.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/hle/service/hid/irsensor/pointing_processor.h" 4#include "hid_core/irsensor/pointing_processor.h"
5 5
6namespace Service::IRS { 6namespace Service::IRS {
7PointingProcessor::PointingProcessor(Core::IrSensor::DeviceFormat& device_format) 7PointingProcessor::PointingProcessor(Core::IrSensor::DeviceFormat& device_format)
diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.h b/src/hid_core/irsensor/pointing_processor.h
index d63423aff..968c2e5bd 100644
--- a/src/core/hle/service/hid/irsensor/pointing_processor.h
+++ b/src/hid_core/irsensor/pointing_processor.h
@@ -4,8 +4,8 @@
4#pragma once 4#pragma once
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hid/irs_types.h" 7#include "hid_core/irsensor/irs_types.h"
8#include "core/hle/service/hid/irsensor/processor_base.h" 8#include "hid_core/irsensor/processor_base.h"
9 9
10namespace Service::IRS { 10namespace Service::IRS {
11class PointingProcessor final : public ProcessorBase { 11class PointingProcessor final : public ProcessorBase {
diff --git a/src/core/hle/service/hid/irsensor/processor_base.cpp b/src/hid_core/irsensor/processor_base.cpp
index 4d43ca17a..91a513a70 100644
--- a/src/core/hle/service/hid/irsensor/processor_base.cpp
+++ b/src/hid_core/irsensor/processor_base.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/hle/service/hid/irsensor/processor_base.h" 4#include "hid_core/irsensor/processor_base.h"
5 5
6namespace Service::IRS { 6namespace Service::IRS {
7 7
diff --git a/src/core/hle/service/hid/irsensor/processor_base.h b/src/hid_core/irsensor/processor_base.h
index bc0d2977b..48beeafba 100644
--- a/src/core/hle/service/hid/irsensor/processor_base.h
+++ b/src/hid_core/irsensor/processor_base.h
@@ -4,7 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hid/irs_types.h" 7#include "hid_core/irsensor/irs_types.h"
8 8
9namespace Service::IRS { 9namespace Service::IRS {
10class ProcessorBase { 10class ProcessorBase {
diff --git a/src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp b/src/hid_core/irsensor/tera_plugin_processor.cpp
index e691c840a..2382e208a 100644
--- a/src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp
+++ b/src/hid_core/irsensor/tera_plugin_processor.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/hle/service/hid/irsensor/tera_plugin_processor.h" 4#include "hid_core/irsensor/tera_plugin_processor.h"
5 5
6namespace Service::IRS { 6namespace Service::IRS {
7TeraPluginProcessor::TeraPluginProcessor(Core::IrSensor::DeviceFormat& device_format) 7TeraPluginProcessor::TeraPluginProcessor(Core::IrSensor::DeviceFormat& device_format)
diff --git a/src/core/hle/service/hid/irsensor/tera_plugin_processor.h b/src/hid_core/irsensor/tera_plugin_processor.h
index bbea7ed0b..dc8fe7d07 100644
--- a/src/core/hle/service/hid/irsensor/tera_plugin_processor.h
+++ b/src/hid_core/irsensor/tera_plugin_processor.h
@@ -5,8 +5,8 @@
5 5
6#include "common/bit_field.h" 6#include "common/bit_field.h"
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hid/irs_types.h" 8#include "hid_core/irsensor/irs_types.h"
9#include "core/hle/service/hid/irsensor/processor_base.h" 9#include "hid_core/irsensor/processor_base.h"
10 10
11namespace Service::IRS { 11namespace Service::IRS {
12class TeraPluginProcessor final : public ProcessorBase { 12class TeraPluginProcessor final : public ProcessorBase {
diff --git a/src/hid_core/precompiled_headers.h b/src/hid_core/precompiled_headers.h
new file mode 100644
index 000000000..aabae730b
--- /dev/null
+++ b/src/hid_core/precompiled_headers.h
@@ -0,0 +1,6 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/common_precompiled_headers.h"
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/hid_core/resource_manager.cpp
index 84b4be3ed..2c5fe6d51 100644
--- a/src/core/hle/service/hid/resource_manager.cpp
+++ b/src/hid_core/resource_manager.cpp
@@ -4,29 +4,29 @@
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/core_timing.h" 6#include "core/core_timing.h"
7#include "core/hid/hid_core.h"
8#include "core/hle/kernel/k_shared_memory.h" 7#include "core/hle/kernel/k_shared_memory.h"
9#include "core/hle/service/hid/resource_manager.h"
10#include "core/hle/service/ipc_helpers.h" 8#include "core/hle/service/ipc_helpers.h"
11 9#include "hid_core/hid_core.h"
12#include "core/hle/service/hid/controllers/applet_resource.h" 10#include "hid_core/resource_manager.h"
13#include "core/hle/service/hid/controllers/capture_button.h" 11
14#include "core/hle/service/hid/controllers/console_six_axis.h" 12#include "hid_core/resources/applet_resource.h"
15#include "core/hle/service/hid/controllers/debug_mouse.h" 13#include "hid_core/resources/debug_pad/debug_pad.h"
16#include "core/hle/service/hid/controllers/debug_pad.h" 14#include "hid_core/resources/digitizer/digitizer.h"
17#include "core/hle/service/hid/controllers/digitizer.h" 15#include "hid_core/resources/keyboard/keyboard.h"
18#include "core/hle/service/hid/controllers/gesture.h" 16#include "hid_core/resources/mouse/debug_mouse.h"
19#include "core/hle/service/hid/controllers/home_button.h" 17#include "hid_core/resources/mouse/mouse.h"
20#include "core/hle/service/hid/controllers/keyboard.h" 18#include "hid_core/resources/npad/npad.h"
21#include "core/hle/service/hid/controllers/mouse.h" 19#include "hid_core/resources/palma/palma.h"
22#include "core/hle/service/hid/controllers/npad.h" 20#include "hid_core/resources/shared_memory_format.h"
23#include "core/hle/service/hid/controllers/palma.h" 21#include "hid_core/resources/six_axis/console_six_axis.h"
24#include "core/hle/service/hid/controllers/seven_six_axis.h" 22#include "hid_core/resources/six_axis/seven_six_axis.h"
25#include "core/hle/service/hid/controllers/six_axis.h" 23#include "hid_core/resources/six_axis/six_axis.h"
26#include "core/hle/service/hid/controllers/sleep_button.h" 24#include "hid_core/resources/system_buttons/capture_button.h"
27#include "core/hle/service/hid/controllers/touchscreen.h" 25#include "hid_core/resources/system_buttons/home_button.h"
28#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 26#include "hid_core/resources/system_buttons/sleep_button.h"
29#include "core/hle/service/hid/controllers/unique_pad.h" 27#include "hid_core/resources/touch_screen/gesture.h"
28#include "hid_core/resources/touch_screen/touch_screen.h"
29#include "hid_core/resources/unique_pad/unique_pad.h"
30 30
31namespace Service::HID { 31namespace Service::HID {
32 32
@@ -129,12 +129,12 @@ std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const {
129} 129}
130 130
131Result ResourceManager::CreateAppletResource(u64 aruid) { 131Result ResourceManager::CreateAppletResource(u64 aruid) {
132 if (aruid == 0) { 132 if (aruid == SystemAruid) {
133 const auto result = RegisterCoreAppletResource(); 133 const auto result = RegisterCoreAppletResource();
134 if (result.IsError()) { 134 if (result.IsError()) {
135 return result; 135 return result;
136 } 136 }
137 return GetNpad()->Activate(); 137 return GetNpad()->ActivateNpadResource();
138 } 138 }
139 139
140 const auto result = CreateAppletResourceImpl(aruid); 140 const auto result = CreateAppletResourceImpl(aruid);
@@ -147,7 +147,7 @@ Result ResourceManager::CreateAppletResource(u64 aruid) {
147 six_axis->Activate(); 147 six_axis->Activate();
148 touch_screen->Activate(); 148 touch_screen->Activate();
149 149
150 return GetNpad()->Activate(aruid); 150 return GetNpad()->ActivateNpadResource(aruid);
151} 151}
152 152
153Result ResourceManager::CreateAppletResourceImpl(u64 aruid) { 153Result ResourceManager::CreateAppletResourceImpl(u64 aruid) {
@@ -171,31 +171,31 @@ void ResourceManager::InitializeHidCommonSampler() {
171 palma = std::make_shared<Palma>(system.HIDCore(), service_context); 171 palma = std::make_shared<Palma>(system.HIDCore(), service_context);
172 six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); 172 six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
173 173
174 debug_pad->SetAppletResource(applet_resource); 174 debug_pad->SetAppletResource(applet_resource, &shared_mutex);
175 digitizer->SetAppletResource(applet_resource); 175 digitizer->SetAppletResource(applet_resource, &shared_mutex);
176 keyboard->SetAppletResource(applet_resource); 176 keyboard->SetAppletResource(applet_resource, &shared_mutex);
177 npad->SetAppletResource(applet_resource); 177 npad->SetNpadExternals(applet_resource, &shared_mutex);
178 six_axis->SetAppletResource(applet_resource); 178 six_axis->SetAppletResource(applet_resource, &shared_mutex);
179 mouse->SetAppletResource(applet_resource); 179 mouse->SetAppletResource(applet_resource, &shared_mutex);
180 debug_mouse->SetAppletResource(applet_resource); 180 debug_mouse->SetAppletResource(applet_resource, &shared_mutex);
181 home_button->SetAppletResource(applet_resource); 181 home_button->SetAppletResource(applet_resource, &shared_mutex);
182 sleep_button->SetAppletResource(applet_resource); 182 sleep_button->SetAppletResource(applet_resource, &shared_mutex);
183 capture_button->SetAppletResource(applet_resource); 183 capture_button->SetAppletResource(applet_resource, &shared_mutex);
184} 184}
185 185
186void ResourceManager::InitializeTouchScreenSampler() { 186void ResourceManager::InitializeTouchScreenSampler() {
187 gesture = std::make_shared<Gesture>(system.HIDCore()); 187 gesture = std::make_shared<Gesture>(system.HIDCore());
188 touch_screen = std::make_shared<TouchScreen>(system.HIDCore()); 188 touch_screen = std::make_shared<TouchScreen>(system.HIDCore());
189 189
190 touch_screen->SetAppletResource(applet_resource); 190 touch_screen->SetAppletResource(applet_resource, &shared_mutex);
191 gesture->SetAppletResource(applet_resource); 191 gesture->SetAppletResource(applet_resource, &shared_mutex);
192} 192}
193 193
194void ResourceManager::InitializeConsoleSixAxisSampler() { 194void ResourceManager::InitializeConsoleSixAxisSampler() {
195 console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore()); 195 console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore());
196 seven_six_axis = std::make_shared<SevenSixAxis>(system); 196 seven_six_axis = std::make_shared<SevenSixAxis>(system);
197 197
198 console_six_axis->SetAppletResource(applet_resource); 198 console_six_axis->SetAppletResource(applet_resource, &shared_mutex);
199} 199}
200 200
201void ResourceManager::InitializeAHidSampler() { 201void ResourceManager::InitializeAHidSampler() {
@@ -214,12 +214,17 @@ Result ResourceManager::UnregisterCoreAppletResource() {
214 214
215Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) { 215Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) {
216 std::scoped_lock lock{shared_mutex}; 216 std::scoped_lock lock{shared_mutex};
217 return applet_resource->RegisterAppletResourceUserId(aruid, bool_value); 217 auto result = applet_resource->RegisterAppletResourceUserId(aruid, bool_value);
218 if (result.IsSuccess()) {
219 result = npad->RegisterAppletResourceUserId(aruid);
220 }
221 return result;
218} 222}
219 223
220void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) { 224void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) {
221 std::scoped_lock lock{shared_mutex}; 225 std::scoped_lock lock{shared_mutex};
222 applet_resource->UnregisterAppletResourceUserId(aruid); 226 applet_resource->UnregisterAppletResourceUserId(aruid);
227 npad->UnregisterAppletResourceUserId(aruid);
223} 228}
224 229
225Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) { 230Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/hid_core/resource_manager.h
index 70d9b6550..7a21d8eb8 100644
--- a/src/core/hle/service/hid/resource_manager.h
+++ b/src/hid_core/resource_manager.h
@@ -93,7 +93,7 @@ private:
93 93
94 bool is_initialized{false}; 94 bool is_initialized{false};
95 95
96 mutable std::mutex shared_mutex; 96 mutable std::recursive_mutex shared_mutex;
97 std::shared_ptr<AppletResource> applet_resource = nullptr; 97 std::shared_ptr<AppletResource> applet_resource = nullptr;
98 98
99 std::shared_ptr<CaptureButton> capture_button = nullptr; 99 std::shared_ptr<CaptureButton> capture_button = nullptr;
diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/hid_core/resources/applet_resource.cpp
index b4ff663c2..d09a525c6 100644
--- a/src/core/hle/service/hid/controllers/applet_resource.cpp
+++ b/src/hid_core/resources/applet_resource.cpp
@@ -3,9 +3,9 @@
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/kernel/k_shared_memory.h" 5#include "core/hle/kernel/k_shared_memory.h"
6#include "core/hle/service/hid/controllers/applet_resource.h" 6#include "hid_core/hid_result.h"
7#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 7#include "hid_core/resources/applet_resource.h"
8#include "core/hle/service/hid/errors.h" 8#include "hid_core/resources/shared_memory_format.h"
9 9
10namespace Service::HID { 10namespace Service::HID {
11 11
@@ -87,7 +87,9 @@ Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input
87 data_index = i; 87 data_index = i;
88 break; 88 break;
89 } 89 }
90 if (registration_list.flag[i] == RegistrationStatus::None) { 90 // TODO: Don't Handle pending delete here
91 if (registration_list.flag[i] == RegistrationStatus::None ||
92 registration_list.flag[i] == RegistrationStatus::PendingDelete) {
91 data_index = i; 93 data_index = i;
92 break; 94 break;
93 } 95 }
@@ -104,30 +106,22 @@ Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input
104} 106}
105 107
106void AppletResource::UnregisterAppletResourceUserId(u64 aruid) { 108void AppletResource::UnregisterAppletResourceUserId(u64 aruid) {
107 u64 index = GetIndexFromAruid(aruid); 109 const u64 index = GetIndexFromAruid(aruid);
108 110
109 if (index < AruidIndexMax) { 111 if (index >= AruidIndexMax) {
110 if (data[index].flag.is_assigned) { 112 return;
111 data[index].shared_memory_format = nullptr;
112 data[index].flag.is_assigned.Assign(false);
113 }
114 } 113 }
115 114
116 index = GetIndexFromAruid(aruid); 115 FreeAppletResourceId(aruid);
117 if (index < AruidIndexMax) { 116 DestroySevenSixAxisTransferMemory();
118 DestroySevenSixAxisTransferMemory(); 117 data[index].flag.raw = 0;
119 data[index].flag.raw = 0; 118 data[index].aruid = 0;
120 data[index].aruid = 0;
121 119
122 index = GetIndexFromAruid(aruid); 120 registration_list.flag[index] = RegistrationStatus::PendingDelete;
123 if (index < AruidIndexMax) {
124 registration_list.flag[index] = RegistrationStatus::PendingDelete;
125 }
126 }
127} 121}
128 122
129void AppletResource::FreeAppletResourceId(u64 aruid) { 123void AppletResource::FreeAppletResourceId(u64 aruid) {
130 u64 index = GetIndexFromAruid(aruid); 124 const u64 index = GetIndexFromAruid(aruid);
131 if (index >= AruidIndexMax) { 125 if (index >= AruidIndexMax) {
132 return; 126 return;
133 } 127 }
@@ -144,7 +138,7 @@ u64 AppletResource::GetActiveAruid() {
144} 138}
145 139
146Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) { 140Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
147 u64 index = GetIndexFromAruid(aruid); 141 const u64 index = GetIndexFromAruid(aruid);
148 if (index >= AruidIndexMax) { 142 if (index >= AruidIndexMax) {
149 return ResultAruidNotRegistered; 143 return ResultAruidNotRegistered;
150 } 144 }
@@ -155,7 +149,7 @@ Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle,
155 149
156Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, 150Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format,
157 u64 aruid) { 151 u64 aruid) {
158 u64 index = GetIndexFromAruid(aruid); 152 const u64 index = GetIndexFromAruid(aruid);
159 if (index >= AruidIndexMax) { 153 if (index >= AruidIndexMax) {
160 return ResultAruidNotRegistered; 154 return ResultAruidNotRegistered;
161 } 155 }
diff --git a/src/core/hle/service/hid/controllers/applet_resource.h b/src/hid_core/resources/applet_resource.h
index 52cc4cf42..f3f32bac1 100644
--- a/src/core/hle/service/hid/controllers/applet_resource.h
+++ b/src/hid_core/resources/applet_resource.h
@@ -9,7 +9,7 @@
9#include "common/bit_field.h" 9#include "common/bit_field.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/hle/result.h" 11#include "core/hle/result.h"
12#include "core/hle/service/hid/controllers/shared_memory_holder.h" 12#include "hid_core/resources/shared_memory_holder.h"
13 13
14namespace Core { 14namespace Core {
15class System; 15class System;
@@ -25,6 +25,7 @@ class AppletResource;
25class NPadResource; 25class NPadResource;
26 26
27static constexpr std::size_t AruidIndexMax = 0x20; 27static constexpr std::size_t AruidIndexMax = 0x20;
28static constexpr u64 SystemAruid = 0;
28 29
29enum class RegistrationStatus : u32 { 30enum class RegistrationStatus : u32 {
30 None, 31 None,
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/hid_core/resources/controller_base.cpp
index 2083ccfad..df5f5c884 100644
--- a/src/core/hle/service/hid/controllers/controller_base.cpp
+++ b/src/hid_core/resources/controller_base.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/hid/controllers/controller_base.h" 4#include "hid_core/resources/controller_base.h"
5 5
6namespace Service::HID { 6namespace Service::HID {
7 7
@@ -32,8 +32,10 @@ bool ControllerBase::IsControllerActivated() const {
32 return is_activated; 32 return is_activated;
33} 33}
34 34
35void ControllerBase::SetAppletResource(std::shared_ptr<AppletResource> resource) { 35void ControllerBase::SetAppletResource(std::shared_ptr<AppletResource> resource,
36 std::recursive_mutex* resource_mutex) {
36 applet_resource = resource; 37 applet_resource = resource;
38 shared_mutex = resource_mutex;
37} 39}
38 40
39} // namespace Service::HID 41} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/hid_core/resources/controller_base.h
index 759ae0053..e61bc6376 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/hid_core/resources/controller_base.h
@@ -7,7 +7,7 @@
7 7
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/result.h" 9#include "core/hle/result.h"
10#include "core/hle/service/hid/controllers/applet_resource.h" 10#include "hid_core/resources/applet_resource.h"
11 11
12namespace Core::Timing { 12namespace Core::Timing {
13class CoreTiming; 13class CoreTiming;
@@ -42,11 +42,13 @@ public:
42 42
43 bool IsControllerActivated() const; 43 bool IsControllerActivated() const;
44 44
45 void SetAppletResource(std::shared_ptr<AppletResource> resource); 45 void SetAppletResource(std::shared_ptr<AppletResource> resource,
46 std::recursive_mutex* resource_mutex);
46 47
47protected: 48protected:
48 bool is_activated{false}; 49 bool is_activated{false};
49 std::shared_ptr<AppletResource> applet_resource{nullptr}; 50 std::shared_ptr<AppletResource> applet_resource{nullptr};
51 std::recursive_mutex* shared_mutex{nullptr};
50 52
51 Core::HID::HIDCore& hid_core; 53 Core::HID::HIDCore& hid_core;
52}; 54};
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/hid_core/resources/debug_pad/debug_pad.cpp
index 1811cf620..1102dad6c 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/hid_core/resources/debug_pad/debug_pad.cpp
@@ -3,12 +3,12 @@
3 3
4#include "common/settings.h" 4#include "common/settings.h"
5#include "core/core_timing.h" 5#include "core/core_timing.h"
6#include "core/hid/emulated_controller.h" 6#include "hid_core/frontend/emulated_controller.h"
7#include "core/hid/hid_core.h" 7#include "hid_core/hid_core.h"
8#include "core/hid/hid_types.h" 8#include "hid_core/hid_types.h"
9#include "core/hle/service/hid/controllers/applet_resource.h" 9#include "hid_core/resources/applet_resource.h"
10#include "core/hle/service/hid/controllers/debug_pad.h" 10#include "hid_core/resources/debug_pad/debug_pad.h"
11#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 11#include "hid_core/resources/shared_memory_format.h"
12 12
13namespace Service::HID { 13namespace Service::HID {
14 14
@@ -23,10 +23,11 @@ void DebugPad::OnInit() {}
23void DebugPad::OnRelease() {} 23void DebugPad::OnRelease() {}
24 24
25void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 25void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
26 std::scoped_lock shared_lock{*shared_mutex};
26 const u64 aruid = applet_resource->GetActiveAruid(); 27 const u64 aruid = applet_resource->GetActiveAruid();
27 auto* data = applet_resource->GetAruidData(aruid); 28 auto* data = applet_resource->GetAruidData(aruid);
28 29
29 if (data == nullptr) { 30 if (data == nullptr || !data->flag.is_assigned) {
30 return; 31 return;
31 } 32 }
32 33
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/hid_core/resources/debug_pad/debug_pad.h
index dd00b2402..73c3d4421 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/hid_core/resources/debug_pad/debug_pad.h
@@ -3,12 +3,13 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/resources/controller_base.h"
7#include "core/hle/service/hid/controllers/types/debug_pad_types.h" 7#include "hid_core/resources/debug_pad/debug_pad_types.h"
8 8
9namespace Core::HID { 9namespace Core::HID {
10class HIDCore; 10class HIDCore;
11} 11class EmulatedController;
12} // namespace Core::HID
12 13
13namespace Core::Timing { 14namespace Core::Timing {
14class CoreTiming; 15class CoreTiming;
diff --git a/src/core/hle/service/hid/controllers/types/debug_pad_types.h b/src/hid_core/resources/debug_pad/debug_pad_types.h
index a96171b62..8b5eb108e 100644
--- a/src/core/hle/service/hid/controllers/types/debug_pad_types.h
+++ b/src/hid_core/resources/debug_pad/debug_pad_types.h
@@ -5,7 +5,7 @@
5 5
6#include "common/bit_field.h" 6#include "common/bit_field.h"
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hid/hid_types.h" 8#include "hid_core/hid_types.h"
9 9
10namespace Service::HID { 10namespace Service::HID {
11 11
diff --git a/src/core/hle/service/hid/controllers/digitizer.cpp b/src/hid_core/resources/digitizer/digitizer.cpp
index c01580fd6..cd72fd6e5 100644
--- a/src/core/hle/service/hid/controllers/digitizer.cpp
+++ b/src/hid_core/resources/digitizer/digitizer.cpp
@@ -2,9 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/hle/service/hid/controllers/applet_resource.h" 5#include "hid_core/resources/applet_resource.h"
6#include "core/hle/service/hid/controllers/digitizer.h" 6#include "hid_core/resources/digitizer/digitizer.h"
7#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 7#include "hid_core/resources/shared_memory_format.h"
8 8
9namespace Service::HID { 9namespace Service::HID {
10 10
@@ -21,10 +21,11 @@ void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
21 return; 21 return;
22 } 22 }
23 23
24 std::scoped_lock shared_lock{*shared_mutex};
24 const u64 aruid = applet_resource->GetActiveAruid(); 25 const u64 aruid = applet_resource->GetActiveAruid();
25 auto* data = applet_resource->GetAruidData(aruid); 26 auto* data = applet_resource->GetAruidData(aruid);
26 27
27 if (data == nullptr) { 28 if (data == nullptr || !data->flag.is_assigned) {
28 return; 29 return;
29 } 30 }
30 31
diff --git a/src/core/hle/service/hid/controllers/digitizer.h b/src/hid_core/resources/digitizer/digitizer.h
index d81f814c3..e031a16b0 100644
--- a/src/core/hle/service/hid/controllers/digitizer.h
+++ b/src/hid_core/resources/digitizer/digitizer.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/resources/controller_base.h"
7 7
8namespace Service::HID { 8namespace Service::HID {
9 9
diff --git a/src/core/hle/service/hid/hid_firmware_settings.cpp b/src/hid_core/resources/hid_firmware_settings.cpp
index 59bd6825c..e76b3a016 100644
--- a/src/core/hle/service/hid/hid_firmware_settings.cpp
+++ b/src/hid_core/resources/hid_firmware_settings.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/hle/service/hid/hid_firmware_settings.h" 4#include "hid_core/resources/hid_firmware_settings.h"
5 5
6namespace Service::HID { 6namespace Service::HID {
7 7
diff --git a/src/core/hle/service/hid/hid_firmware_settings.h b/src/hid_core/resources/hid_firmware_settings.h
index 6c10c440b..6c10c440b 100644
--- a/src/core/hle/service/hid/hid_firmware_settings.h
+++ b/src/hid_core/resources/hid_firmware_settings.h
diff --git a/src/core/hle/service/hid/irs_ring_lifo.h b/src/hid_core/resources/irs_ring_lifo.h
index 255d1d296..255d1d296 100644
--- a/src/core/hle/service/hid/irs_ring_lifo.h
+++ b/src/hid_core/resources/irs_ring_lifo.h
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/hid_core/resources/keyboard/keyboard.cpp
index c72b3e5ce..340e8a65c 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/hid_core/resources/keyboard/keyboard.cpp
@@ -3,11 +3,11 @@
3 3
4#include "common/settings.h" 4#include "common/settings.h"
5#include "core/core_timing.h" 5#include "core/core_timing.h"
6#include "core/hid/emulated_devices.h" 6#include "hid_core/frontend/emulated_devices.h"
7#include "core/hid/hid_core.h" 7#include "hid_core/hid_core.h"
8#include "core/hle/service/hid/controllers/applet_resource.h" 8#include "hid_core/resources/applet_resource.h"
9#include "core/hle/service/hid/controllers/keyboard.h" 9#include "hid_core/resources/keyboard/keyboard.h"
10#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 10#include "hid_core/resources/shared_memory_format.h"
11 11
12namespace Service::HID { 12namespace Service::HID {
13 13
@@ -22,10 +22,11 @@ void Keyboard::OnInit() {}
22void Keyboard::OnRelease() {} 22void Keyboard::OnRelease() {}
23 23
24void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 24void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
25 std::scoped_lock shared_lock{*shared_mutex};
25 const u64 aruid = applet_resource->GetActiveAruid(); 26 const u64 aruid = applet_resource->GetActiveAruid();
26 auto* data = applet_resource->GetAruidData(aruid); 27 auto* data = applet_resource->GetAruidData(aruid);
27 28
28 if (data == nullptr) { 29 if (data == nullptr || !data->flag.is_assigned) {
29 return; 30 return;
30 } 31 }
31 32
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/hid_core/resources/keyboard/keyboard.h
index e8ca326c6..4bcc1c1b2 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/hid_core/resources/keyboard/keyboard.h
@@ -3,8 +3,13 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/resources/controller_base.h"
7#include "core/hle/service/hid/controllers/types/keyboard_types.h" 7#include "hid_core/resources/keyboard/keyboard_types.h"
8
9namespace Core::HID {
10class HIDCore;
11class EmulatedDevices;
12} // namespace Core::HID
8 13
9namespace Service::HID { 14namespace Service::HID {
10class Keyboard final : public ControllerBase { 15class Keyboard final : public ControllerBase {
diff --git a/src/core/hle/service/hid/controllers/types/keyboard_types.h b/src/hid_core/resources/keyboard/keyboard_types.h
index f44a536b9..4d7ff2f0a 100644
--- a/src/core/hle/service/hid/controllers/types/keyboard_types.h
+++ b/src/hid_core/resources/keyboard/keyboard_types.h
@@ -4,7 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hid/hid_types.h" 7#include "hid_core/hid_types.h"
8 8
9namespace Service::HID { 9namespace Service::HID {
10 10
diff --git a/src/core/hle/service/hid/controllers/debug_mouse.cpp b/src/hid_core/resources/mouse/debug_mouse.cpp
index f2f1a27f8..5f6f6e8e1 100644
--- a/src/core/hle/service/hid/controllers/debug_mouse.cpp
+++ b/src/hid_core/resources/mouse/debug_mouse.cpp
@@ -3,11 +3,11 @@
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/frontend/emu_window.h" 5#include "core/frontend/emu_window.h"
6#include "core/hid/emulated_devices.h" 6#include "hid_core/frontend/emulated_devices.h"
7#include "core/hid/hid_core.h" 7#include "hid_core/hid_core.h"
8#include "core/hle/service/hid/controllers/applet_resource.h" 8#include "hid_core/resources/applet_resource.h"
9#include "core/hle/service/hid/controllers/debug_mouse.h" 9#include "hid_core/resources/mouse/debug_mouse.h"
10#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 10#include "hid_core/resources/shared_memory_format.h"
11 11
12namespace Service::HID { 12namespace Service::HID {
13 13
@@ -21,10 +21,11 @@ void DebugMouse::OnInit() {}
21void DebugMouse::OnRelease() {} 21void DebugMouse::OnRelease() {}
22 22
23void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 23void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
24 std::scoped_lock shared_lock{*shared_mutex};
24 const u64 aruid = applet_resource->GetActiveAruid(); 25 const u64 aruid = applet_resource->GetActiveAruid();
25 auto* data = applet_resource->GetAruidData(aruid); 26 auto* data = applet_resource->GetAruidData(aruid);
26 27
27 if (data == nullptr) { 28 if (data == nullptr || !data->flag.is_assigned) {
28 return; 29 return;
29 } 30 }
30 31
diff --git a/src/core/hle/service/hid/controllers/debug_mouse.h b/src/hid_core/resources/mouse/debug_mouse.h
index ec939fa9f..006b53da6 100644
--- a/src/core/hle/service/hid/controllers/debug_mouse.h
+++ b/src/hid_core/resources/mouse/debug_mouse.h
@@ -3,12 +3,12 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/hid_types.h"
7#include "hid_core/resources/controller_base.h"
7 8
8namespace Core::HID { 9namespace Core::HID {
10class HIDCore;
9class EmulatedDevices; 11class EmulatedDevices;
10struct MouseState;
11struct AnalogStickState;
12} // namespace Core::HID 12} // namespace Core::HID
13 13
14namespace Service::HID { 14namespace Service::HID {
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/hid_core/resources/mouse/mouse.cpp
index 58deafbc5..53a8938a1 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/hid_core/resources/mouse/mouse.cpp
@@ -3,11 +3,11 @@
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/frontend/emu_window.h" 5#include "core/frontend/emu_window.h"
6#include "core/hid/emulated_devices.h" 6#include "hid_core/frontend/emulated_devices.h"
7#include "core/hid/hid_core.h" 7#include "hid_core/hid_core.h"
8#include "core/hle/service/hid/controllers/applet_resource.h" 8#include "hid_core/resources/applet_resource.h"
9#include "core/hle/service/hid/controllers/mouse.h" 9#include "hid_core/resources/mouse/mouse.h"
10#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 10#include "hid_core/resources/shared_memory_format.h"
11 11
12namespace Service::HID { 12namespace Service::HID {
13 13
@@ -21,10 +21,11 @@ void Mouse::OnInit() {}
21void Mouse::OnRelease() {} 21void Mouse::OnRelease() {}
22 22
23void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 23void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
24 std::scoped_lock shared_lock{*shared_mutex};
24 const u64 aruid = applet_resource->GetActiveAruid(); 25 const u64 aruid = applet_resource->GetActiveAruid();
25 auto* data = applet_resource->GetAruidData(aruid); 26 auto* data = applet_resource->GetAruidData(aruid);
26 27
27 if (data == nullptr) { 28 if (data == nullptr || !data->flag.is_assigned) {
28 return; 29 return;
29 } 30 }
30 31
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/hid_core/resources/mouse/mouse.h
index cefad956c..e9ac6ad36 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/hid_core/resources/mouse/mouse.h
@@ -3,12 +3,12 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/hid_types.h"
7#include "hid_core/resources/controller_base.h"
7 8
8namespace Core::HID { 9namespace Core::HID {
10class HIDCore;
9class EmulatedDevices; 11class EmulatedDevices;
10struct MouseState;
11struct AnalogStickState;
12} // namespace Core::HID 12} // namespace Core::HID
13 13
14namespace Service::HID { 14namespace Service::HID {
diff --git a/src/core/hle/service/hid/controllers/types/mouse_types.h b/src/hid_core/resources/mouse/mouse_types.h
index 8bd6e167c..8bd6e167c 100644
--- a/src/core/hle/service/hid/controllers/types/mouse_types.h
+++ b/src/hid_core/resources/mouse/mouse_types.h
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index c7aa606bc..97f31d26e 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -12,49 +12,106 @@
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/settings.h" 13#include "common/settings.h"
14#include "core/core_timing.h" 14#include "core/core_timing.h"
15#include "core/hid/emulated_controller.h"
16#include "core/hid/hid_core.h"
17#include "core/hle/kernel/k_event.h" 15#include "core/hle/kernel/k_event.h"
18#include "core/hle/kernel/k_readable_event.h" 16#include "core/hle/kernel/k_readable_event.h"
19#include "core/hle/service/hid/controllers/applet_resource.h"
20#include "core/hle/service/hid/controllers/npad.h"
21#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
22#include "core/hle/service/hid/errors.h"
23#include "core/hle/service/hid/hid_util.h"
24#include "core/hle/service/kernel_helpers.h" 17#include "core/hle/service/kernel_helpers.h"
18#include "hid_core/frontend/emulated_controller.h"
19#include "hid_core/hid_core.h"
20#include "hid_core/hid_result.h"
21#include "hid_core/hid_util.h"
22#include "hid_core/resources/applet_resource.h"
23#include "hid_core/resources/npad/npad.h"
24#include "hid_core/resources/shared_memory_format.h"
25 25
26namespace Service::HID { 26namespace Service::HID {
27constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
28 Core::HID::NpadIdType::Player1, Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3,
29 Core::HID::NpadIdType::Player4, Core::HID::NpadIdType::Player5, Core::HID::NpadIdType::Player6,
30 Core::HID::NpadIdType::Player7, Core::HID::NpadIdType::Player8, Core::HID::NpadIdType::Other,
31 Core::HID::NpadIdType::Handheld,
32};
33 27
34NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_) 28NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_)
35 : ControllerBase{hid_core_}, service_context{service_context_} { 29 : hid_core{hid_core_}, service_context{service_context_}, npad_resource{service_context} {
36 for (std::size_t i = 0; i < controller_data.size(); ++i) { 30 for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
37 auto& controller = controller_data[i]; 31 for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
38 controller.device = hid_core.GetEmulatedControllerByIndex(i); 32 auto& controller = controller_data[aruid_index][i];
39 controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = 33 controller.device = hid_core.GetEmulatedControllerByIndex(i);
40 Core::HID::DEFAULT_VIBRATION_VALUE; 34 controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
41 controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex].latest_vibration_value = 35 Core::HID::DEFAULT_VIBRATION_VALUE;
42 Core::HID::DEFAULT_VIBRATION_VALUE; 36 controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex]
43 Core::HID::ControllerUpdateCallback engine_callback{ 37 .latest_vibration_value = Core::HID::DEFAULT_VIBRATION_VALUE;
44 .on_change = [this, 38 Core::HID::ControllerUpdateCallback engine_callback{
45 i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }, 39 .on_change =
46 .is_npad_service = true, 40 [this, i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); },
47 }; 41 .is_npad_service = true,
48 controller.callback_key = controller.device->SetCallback(engine_callback); 42 };
43 controller.callback_key = controller.device->SetCallback(engine_callback);
44 }
49 } 45 }
50} 46}
51 47
52NPad::~NPad() { 48NPad::~NPad() {
53 for (std::size_t i = 0; i < controller_data.size(); ++i) { 49 for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
54 auto& controller = controller_data[i]; 50 for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
55 controller.device->DeleteCallback(controller.callback_key); 51 auto& controller = controller_data[aruid_index][i];
52 controller.device->DeleteCallback(controller.callback_key);
53 }
54 }
55}
56
57Result NPad::Activate() {
58 if (ref_counter == std::numeric_limits<s32>::max() - 1) {
59 return ResultNpadResourceOverflow;
56 } 60 }
57 OnRelease(); 61
62 if (ref_counter == 0) {
63 std::scoped_lock lock{mutex};
64
65 // TODO: Activate handlers and AbstractedPad
66 }
67
68 ref_counter++;
69 return ResultSuccess;
70}
71
72Result NPad::Activate(u64 aruid) {
73 std::scoped_lock lock{mutex};
74 std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
75
76 auto* data = applet_resource_holder.applet_resource->GetAruidData(aruid);
77 const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
78
79 if (data == nullptr || !data->flag.is_assigned) {
80 return ResultSuccess;
81 }
82
83 for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
84 auto& controller = controller_data[aruid_index][i];
85 controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
86 }
87
88 // Prefill controller buffers
89 for (auto& controller : controller_data[aruid_index]) {
90 auto* npad = controller.shared_memory;
91 npad->fullkey_color = {
92 .attribute = ColorAttribute::NoController,
93 .fullkey = {},
94 };
95 npad->joycon_color = {
96 .attribute = ColorAttribute::NoController,
97 .left = {},
98 .right = {},
99 };
100 // HW seems to initialize the first 19 entries
101 for (std::size_t i = 0; i < 19; ++i) {
102 WriteEmptyEntry(npad);
103 }
104 }
105
106 return ResultSuccess;
107}
108
109Result NPad::ActivateNpadResource() {
110 return npad_resource.Activate();
111}
112
113Result NPad::ActivateNpadResource(u64 aruid) {
114 return npad_resource.Activate(aruid);
58} 115}
59 116
60void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) { 117void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) {
@@ -63,41 +120,50 @@ void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t c
63 ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx); 120 ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx);
64 return; 121 return;
65 } 122 }
66 if (controller_idx >= controller_data.size()) {
67 return;
68 }
69 123
70 auto& controller = controller_data[controller_idx]; 124 for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
71 const auto is_connected = controller.device->IsConnected(); 125 if (controller_idx >= controller_data[aruid_index].size()) {
72 const auto npad_type = controller.device->GetNpadStyleIndex();
73 const auto npad_id = controller.device->GetNpadIdType();
74 switch (type) {
75 case Core::HID::ControllerTriggerType::Connected:
76 case Core::HID::ControllerTriggerType::Disconnected:
77 if (is_connected == controller.is_connected) {
78 return; 126 return;
79 } 127 }
80 UpdateControllerAt(npad_type, npad_id, is_connected); 128
81 break; 129 auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index);
82 case Core::HID::ControllerTriggerType::Battery: { 130
83 if (!controller.device->IsConnected()) { 131 if (!data->flag.is_assigned) {
84 return; 132 continue;
133 }
134
135 auto& controller = controller_data[aruid_index][controller_idx];
136 const auto is_connected = controller.device->IsConnected();
137 const auto npad_type = controller.device->GetNpadStyleIndex();
138 const auto npad_id = controller.device->GetNpadIdType();
139 switch (type) {
140 case Core::HID::ControllerTriggerType::Connected:
141 case Core::HID::ControllerTriggerType::Disconnected:
142 if (is_connected == controller.is_connected) {
143 return;
144 }
145 UpdateControllerAt(data->aruid, npad_type, npad_id, is_connected);
146 break;
147 case Core::HID::ControllerTriggerType::Battery: {
148 if (!controller.device->IsConnected()) {
149 return;
150 }
151 auto* shared_memory = controller.shared_memory;
152 const auto& battery_level = controller.device->GetBattery();
153 shared_memory->battery_level_dual = battery_level.dual.battery_level;
154 shared_memory->battery_level_left = battery_level.left.battery_level;
155 shared_memory->battery_level_right = battery_level.right.battery_level;
156 break;
157 }
158 default:
159 break;
85 } 160 }
86 auto* shared_memory = controller.shared_memory;
87 const auto& battery_level = controller.device->GetBattery();
88 shared_memory->battery_level_dual = battery_level.dual.battery_level;
89 shared_memory->battery_level_left = battery_level.left.battery_level;
90 shared_memory->battery_level_right = battery_level.right.battery_level;
91 break;
92 }
93 default:
94 break;
95 } 161 }
96} 162}
97 163
98void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { 164void NPad::InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id) {
99 auto& controller = GetControllerFromNpadIdType(npad_id); 165 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
100 if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) { 166 if (!npad_resource.IsControllerSupported(aruid, controller.device->GetNpadStyleIndex())) {
101 return; 167 return;
102 } 168 }
103 LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); 169 LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
@@ -106,7 +172,7 @@ void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
106 const auto& battery_level = controller.device->GetBattery(); 172 const auto& battery_level = controller.device->GetBattery();
107 auto* shared_memory = controller.shared_memory; 173 auto* shared_memory = controller.shared_memory;
108 if (controller_type == Core::HID::NpadStyleIndex::None) { 174 if (controller_type == Core::HID::NpadStyleIndex::None) {
109 controller.styleset_changed_event->Signal(); 175 npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id);
110 return; 176 return;
111 } 177 }
112 178
@@ -290,53 +356,11 @@ void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
290 Common::Input::PollingMode::Active); 356 Common::Input::PollingMode::Active);
291 } 357 }
292 358
293 SignalStyleSetChangedEvent(npad_id); 359 npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id);
294 WriteEmptyEntry(controller.shared_memory); 360 WriteEmptyEntry(controller.shared_memory);
295 hid_core.SetLastActiveController(npad_id); 361 hid_core.SetLastActiveController(npad_id);
296} 362}
297 363
298void NPad::OnInit() {
299 const u64 aruid = applet_resource->GetActiveAruid();
300 auto* data = applet_resource->GetAruidData(aruid);
301
302 if (data == nullptr) {
303 return;
304 }
305
306 if (!IsControllerActivated()) {
307 return;
308 }
309
310 for (std::size_t i = 0; i < controller_data.size(); ++i) {
311 auto& controller = controller_data[i];
312 controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
313 controller.styleset_changed_event =
314 service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
315 }
316
317 supported_npad_id_types.resize(npad_id_list.size());
318 std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
319 npad_id_list.size() * sizeof(Core::HID::NpadIdType));
320
321 // Prefill controller buffers
322 for (auto& controller : controller_data) {
323 auto* npad = controller.shared_memory;
324 npad->fullkey_color = {
325 .attribute = ColorAttribute::NoController,
326 .fullkey = {},
327 };
328 npad->joycon_color = {
329 .attribute = ColorAttribute::NoController,
330 .left = {},
331 .right = {},
332 };
333 // HW seems to initialize the first 19 entries
334 for (std::size_t i = 0; i < 19; ++i) {
335 WriteEmptyEntry(npad);
336 }
337 }
338}
339
340void NPad::WriteEmptyEntry(NpadInternalState* npad) { 364void NPad::WriteEmptyEntry(NpadInternalState* npad) {
341 NPadGenericState dummy_pad_state{}; 365 NPadGenericState dummy_pad_state{};
342 NpadGcTriggerState dummy_gc_state{}; 366 NpadGcTriggerState dummy_gc_state{};
@@ -358,33 +382,20 @@ void NPad::WriteEmptyEntry(NpadInternalState* npad) {
358 npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state); 382 npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
359} 383}
360 384
361void NPad::OnRelease() { 385void NPad::RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id) {
362 is_controller_initialized = false; 386 std::scoped_lock lock{*applet_resource_holder.shared_mutex};
363 for (std::size_t i = 0; i < controller_data.size(); ++i) { 387 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
364 auto& controller = controller_data[i];
365 if (controller.styleset_changed_event) {
366 service_context.CloseEvent(controller.styleset_changed_event);
367 }
368 for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
369 VibrateControllerAtIndex(controller.device->GetNpadIdType(), device_idx, {});
370 }
371 }
372}
373
374void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
375 std::scoped_lock lock{mutex};
376 auto& controller = GetControllerFromNpadIdType(npad_id);
377 const auto controller_type = controller.device->GetNpadStyleIndex(); 388 const auto controller_type = controller.device->GetNpadStyleIndex();
378 389
379 if (!controller.device->IsConnected() && controller.is_connected) { 390 if (!controller.device->IsConnected() && controller.is_connected) {
380 DisconnectNpad(npad_id); 391 DisconnectNpad(aruid, npad_id);
381 return; 392 return;
382 } 393 }
383 if (!controller.device->IsConnected()) { 394 if (!controller.device->IsConnected()) {
384 return; 395 return;
385 } 396 }
386 if (controller.device->IsConnected() && !controller.is_connected) { 397 if (controller.device->IsConnected() && !controller.is_connected) {
387 InitNewlyAddedController(npad_id); 398 InitNewlyAddedController(aruid, npad_id);
388 } 399 }
389 400
390 // This function is unique to yuzu for the turbo buttons and motion to work properly 401 // This function is unique to yuzu for the turbo buttons and motion to work properly
@@ -441,230 +452,232 @@ void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
441} 452}
442 453
443void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 454void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
444 const u64 aruid = applet_resource->GetActiveAruid(); 455 if (ref_counter == 0) {
445 auto* data = applet_resource->GetAruidData(aruid);
446
447 if (data == nullptr) {
448 return;
449 }
450
451 if (!IsControllerActivated()) {
452 return; 456 return;
453 } 457 }
454 458
455 for (std::size_t i = 0; i < controller_data.size(); ++i) { 459 std::scoped_lock lock{*applet_resource_holder.shared_mutex};
456 auto& controller = controller_data[i]; 460 for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
457 controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state; 461 const auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index);
458 auto* npad = controller.shared_memory; 462 const auto aruid = data->aruid;
459
460 const auto& controller_type = controller.device->GetNpadStyleIndex();
461 463
462 if (controller_type == Core::HID::NpadStyleIndex::None || 464 if (!data->flag.is_assigned) {
463 !controller.device->IsConnected()) {
464 continue; 465 continue;
465 } 466 }
466 467
467 RequestPadStateUpdate(controller.device->GetNpadIdType()); 468 for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
468 auto& pad_state = controller.npad_pad_state; 469 auto& controller = controller_data[aruid_index][i];
469 auto& libnx_state = controller.npad_libnx_state; 470 controller.shared_memory =
470 auto& trigger_state = controller.npad_trigger_state; 471 &data->shared_memory_format->npad.npad_entry[i].internal_state;
471 472 auto* npad = controller.shared_memory;
472 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate 473
473 // any controllers. 474 const auto& controller_type = controller.device->GetNpadStyleIndex();
474 libnx_state.connection_status.raw = 0; 475
475 libnx_state.connection_status.is_connected.Assign(1); 476 if (controller_type == Core::HID::NpadStyleIndex::None ||
476 switch (controller_type) { 477 !controller.device->IsConnected()) {
477 case Core::HID::NpadStyleIndex::None: 478 continue;
478 ASSERT(false); 479 }
479 break; 480
480 case Core::HID::NpadStyleIndex::ProController: 481 RequestPadStateUpdate(aruid, controller.device->GetNpadIdType());
481 case Core::HID::NpadStyleIndex::NES: 482 auto& pad_state = controller.npad_pad_state;
482 case Core::HID::NpadStyleIndex::SNES: 483 auto& libnx_state = controller.npad_libnx_state;
483 case Core::HID::NpadStyleIndex::N64: 484 auto& trigger_state = controller.npad_trigger_state;
484 case Core::HID::NpadStyleIndex::SegaGenesis: 485
485 pad_state.connection_status.raw = 0; 486 // LibNX exclusively uses this section, so we always update it since LibNX doesn't
486 pad_state.connection_status.is_connected.Assign(1); 487 // activate any controllers.
487 pad_state.connection_status.is_wired.Assign(1); 488 libnx_state.connection_status.raw = 0;
488 489 libnx_state.connection_status.is_connected.Assign(1);
489 libnx_state.connection_status.is_wired.Assign(1); 490 switch (controller_type) {
490 pad_state.sampling_number = 491 case Core::HID::NpadStyleIndex::None:
491 npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; 492 ASSERT(false);
492 npad->fullkey_lifo.WriteNextEntry(pad_state); 493 break;
493 break; 494 case Core::HID::NpadStyleIndex::ProController:
494 case Core::HID::NpadStyleIndex::Handheld: 495 case Core::HID::NpadStyleIndex::NES:
495 pad_state.connection_status.raw = 0; 496 case Core::HID::NpadStyleIndex::SNES:
496 pad_state.connection_status.is_connected.Assign(1); 497 case Core::HID::NpadStyleIndex::N64:
497 pad_state.connection_status.is_wired.Assign(1); 498 case Core::HID::NpadStyleIndex::SegaGenesis:
498 pad_state.connection_status.is_left_connected.Assign(1); 499 pad_state.connection_status.raw = 0;
499 pad_state.connection_status.is_right_connected.Assign(1); 500 pad_state.connection_status.is_connected.Assign(1);
500 pad_state.connection_status.is_left_wired.Assign(1); 501 pad_state.connection_status.is_wired.Assign(1);
501 pad_state.connection_status.is_right_wired.Assign(1); 502
502 503 libnx_state.connection_status.is_wired.Assign(1);
503 libnx_state.connection_status.is_wired.Assign(1); 504 pad_state.sampling_number =
504 libnx_state.connection_status.is_left_connected.Assign(1); 505 npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
505 libnx_state.connection_status.is_right_connected.Assign(1); 506 npad->fullkey_lifo.WriteNextEntry(pad_state);
506 libnx_state.connection_status.is_left_wired.Assign(1); 507 break;
507 libnx_state.connection_status.is_right_wired.Assign(1); 508 case Core::HID::NpadStyleIndex::Handheld:
508 pad_state.sampling_number = 509 pad_state.connection_status.raw = 0;
509 npad->handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; 510 pad_state.connection_status.is_connected.Assign(1);
510 npad->handheld_lifo.WriteNextEntry(pad_state); 511 pad_state.connection_status.is_wired.Assign(1);
511 break;
512 case Core::HID::NpadStyleIndex::JoyconDual:
513 pad_state.connection_status.raw = 0;
514 pad_state.connection_status.is_connected.Assign(1);
515 if (controller.is_dual_left_connected) {
516 pad_state.connection_status.is_left_connected.Assign(1); 512 pad_state.connection_status.is_left_connected.Assign(1);
513 pad_state.connection_status.is_right_connected.Assign(1);
514 pad_state.connection_status.is_left_wired.Assign(1);
515 pad_state.connection_status.is_right_wired.Assign(1);
516
517 libnx_state.connection_status.is_wired.Assign(1);
517 libnx_state.connection_status.is_left_connected.Assign(1); 518 libnx_state.connection_status.is_left_connected.Assign(1);
518 } 519 libnx_state.connection_status.is_right_connected.Assign(1);
519 if (controller.is_dual_right_connected) { 520 libnx_state.connection_status.is_left_wired.Assign(1);
521 libnx_state.connection_status.is_right_wired.Assign(1);
522 pad_state.sampling_number =
523 npad->handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
524 npad->handheld_lifo.WriteNextEntry(pad_state);
525 break;
526 case Core::HID::NpadStyleIndex::JoyconDual:
527 pad_state.connection_status.raw = 0;
528 pad_state.connection_status.is_connected.Assign(1);
529 if (controller.is_dual_left_connected) {
530 pad_state.connection_status.is_left_connected.Assign(1);
531 libnx_state.connection_status.is_left_connected.Assign(1);
532 }
533 if (controller.is_dual_right_connected) {
534 pad_state.connection_status.is_right_connected.Assign(1);
535 libnx_state.connection_status.is_right_connected.Assign(1);
536 }
537
538 pad_state.sampling_number =
539 npad->joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
540 npad->joy_dual_lifo.WriteNextEntry(pad_state);
541 break;
542 case Core::HID::NpadStyleIndex::JoyconLeft:
543 pad_state.connection_status.raw = 0;
544 pad_state.connection_status.is_connected.Assign(1);
545 pad_state.connection_status.is_left_connected.Assign(1);
546
547 libnx_state.connection_status.is_left_connected.Assign(1);
548 pad_state.sampling_number =
549 npad->joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
550 npad->joy_left_lifo.WriteNextEntry(pad_state);
551 break;
552 case Core::HID::NpadStyleIndex::JoyconRight:
553 pad_state.connection_status.raw = 0;
554 pad_state.connection_status.is_connected.Assign(1);
520 pad_state.connection_status.is_right_connected.Assign(1); 555 pad_state.connection_status.is_right_connected.Assign(1);
556
521 libnx_state.connection_status.is_right_connected.Assign(1); 557 libnx_state.connection_status.is_right_connected.Assign(1);
558 pad_state.sampling_number =
559 npad->joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
560 npad->joy_right_lifo.WriteNextEntry(pad_state);
561 break;
562 case Core::HID::NpadStyleIndex::GameCube:
563 pad_state.connection_status.raw = 0;
564 pad_state.connection_status.is_connected.Assign(1);
565 pad_state.connection_status.is_wired.Assign(1);
566
567 libnx_state.connection_status.is_wired.Assign(1);
568 pad_state.sampling_number =
569 npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
570 trigger_state.sampling_number =
571 npad->gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
572 npad->fullkey_lifo.WriteNextEntry(pad_state);
573 npad->gc_trigger_lifo.WriteNextEntry(trigger_state);
574 break;
575 case Core::HID::NpadStyleIndex::Pokeball:
576 pad_state.connection_status.raw = 0;
577 pad_state.connection_status.is_connected.Assign(1);
578 pad_state.sampling_number =
579 npad->palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
580 npad->palma_lifo.WriteNextEntry(pad_state);
581 break;
582 default:
583 break;
522 } 584 }
523 585
524 pad_state.sampling_number = 586 libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
525 npad->joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1; 587 libnx_state.l_stick = pad_state.l_stick;
526 npad->joy_dual_lifo.WriteNextEntry(pad_state); 588 libnx_state.r_stick = pad_state.r_stick;
527 break; 589 npad->system_ext_lifo.WriteNextEntry(pad_state);
528 case Core::HID::NpadStyleIndex::JoyconLeft:
529 pad_state.connection_status.raw = 0;
530 pad_state.connection_status.is_connected.Assign(1);
531 pad_state.connection_status.is_left_connected.Assign(1);
532
533 libnx_state.connection_status.is_left_connected.Assign(1);
534 pad_state.sampling_number =
535 npad->joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
536 npad->joy_left_lifo.WriteNextEntry(pad_state);
537 break;
538 case Core::HID::NpadStyleIndex::JoyconRight:
539 pad_state.connection_status.raw = 0;
540 pad_state.connection_status.is_connected.Assign(1);
541 pad_state.connection_status.is_right_connected.Assign(1);
542
543 libnx_state.connection_status.is_right_connected.Assign(1);
544 pad_state.sampling_number =
545 npad->joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
546 npad->joy_right_lifo.WriteNextEntry(pad_state);
547 break;
548 case Core::HID::NpadStyleIndex::GameCube:
549 pad_state.connection_status.raw = 0;
550 pad_state.connection_status.is_connected.Assign(1);
551 pad_state.connection_status.is_wired.Assign(1);
552
553 libnx_state.connection_status.is_wired.Assign(1);
554 pad_state.sampling_number =
555 npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
556 trigger_state.sampling_number =
557 npad->gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
558 npad->fullkey_lifo.WriteNextEntry(pad_state);
559 npad->gc_trigger_lifo.WriteNextEntry(trigger_state);
560 break;
561 case Core::HID::NpadStyleIndex::Pokeball:
562 pad_state.connection_status.raw = 0;
563 pad_state.connection_status.is_connected.Assign(1);
564 pad_state.sampling_number =
565 npad->palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
566 npad->palma_lifo.WriteNextEntry(pad_state);
567 break;
568 default:
569 break;
570 }
571
572 libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
573 libnx_state.l_stick = pad_state.l_stick;
574 libnx_state.r_stick = pad_state.r_stick;
575 npad->system_ext_lifo.WriteNextEntry(pad_state);
576 590
577 press_state |= static_cast<u64>(pad_state.npad_buttons.raw); 591 press_state |= static_cast<u64>(pad_state.npad_buttons.raw);
592 }
578 } 593 }
579} 594}
580 595
581void NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) { 596Result NPad::SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet supported_style_set) {
582 hid_core.SetSupportedStyleTag(style_set); 597 std::scoped_lock lock{mutex};
583 598 hid_core.SetSupportedStyleTag({supported_style_set});
584 if (is_controller_initialized) { 599 const Result result = npad_resource.SetSupportedNpadStyleSet(aruid, supported_style_set);
585 return; 600 if (result.IsSuccess()) {
601 OnUpdate({});
586 } 602 }
587 603 return result;
588 // Once SetSupportedStyleSet is called controllers are fully initialized
589 is_controller_initialized = true;
590} 604}
591 605
592Core::HID::NpadStyleTag NPad::GetSupportedStyleSet() const { 606Result NPad::GetSupportedNpadStyleSet(u64 aruid,
593 if (!is_controller_initialized) { 607 Core::HID::NpadStyleSet& out_supported_style_set) const {
594 return {Core::HID::NpadStyleSet::None}; 608 std::scoped_lock lock{mutex};
609 const Result result = npad_resource.GetSupportedNpadStyleSet(out_supported_style_set, aruid);
610
611 if (result == ResultUndefinedStyleset) {
612 out_supported_style_set = Core::HID::NpadStyleSet::None;
613 return ResultSuccess;
595 } 614 }
596 return hid_core.GetSupportedStyleTag(); 615
616 return result;
597} 617}
598 618
599Result NPad::SetSupportedNpadIdTypes(std::span<const u8> data) { 619Result NPad::GetMaskedSupportedNpadStyleSet(
600 constexpr std::size_t max_number_npad_ids = 0xa; 620 u64 aruid, Core::HID::NpadStyleSet& out_supported_style_set) const {
601 const auto length = data.size(); 621 std::scoped_lock lock{mutex};
602 ASSERT(length > 0 && (length % sizeof(u32)) == 0); 622 const Result result =
603 const std::size_t elements = length / sizeof(u32); 623 npad_resource.GetMaskedSupportedNpadStyleSet(out_supported_style_set, aruid);
604 624
605 if (elements > max_number_npad_ids) { 625 if (result == ResultUndefinedStyleset) {
606 return InvalidArraySize; 626 out_supported_style_set = Core::HID::NpadStyleSet::None;
627 return ResultSuccess;
607 } 628 }
608 629
609 supported_npad_id_types.clear(); 630 return result;
610 supported_npad_id_types.resize(elements);
611 std::memcpy(supported_npad_id_types.data(), data.data(), length);
612 return ResultSuccess;
613} 631}
614 632
615void NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { 633Result NPad::SetSupportedNpadIdType(u64 aruid,
616 const auto copy_amount = supported_npad_id_types.size() * sizeof(u32); 634 std::span<const Core::HID::NpadIdType> supported_npad_list) {
617 ASSERT(max_length <= copy_amount); 635 std::scoped_lock lock{mutex};
618 std::memcpy(data, supported_npad_id_types.data(), copy_amount); 636 if (supported_npad_list.size() > MaxSupportedNpadIdTypes) {
619} 637 return ResultInvalidArraySize;
638 }
620 639
621std::size_t NPad::GetSupportedNpadIdTypesSize() const { 640 Result result = npad_resource.SetSupportedNpadIdType(aruid, supported_npad_list);
622 return supported_npad_id_types.size();
623}
624 641
625void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { 642 if (result.IsSuccess()) {
626 if (joy_hold_type != NpadJoyHoldType::Horizontal && 643 OnUpdate({});
627 joy_hold_type != NpadJoyHoldType::Vertical) {
628 LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}",
629 joy_hold_type);
630 return;
631 } 644 }
632 hold_type = joy_hold_type;
633}
634 645
635NpadJoyHoldType NPad::GetHoldType() const { 646 return result;
636 return hold_type;
637} 647}
638 648
639void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) { 649Result NPad::SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type) {
640 if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) { 650 std::scoped_lock lock{mutex};
641 ASSERT_MSG(false, "Activation mode should be always None, Single or Dual"); 651 return npad_resource.SetNpadJoyHoldType(aruid, hold_type);
642 return;
643 }
644
645 handheld_activation_mode = activation_mode;
646} 652}
647 653
648NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { 654Result NPad::GetNpadJoyHoldType(u64 aruid, NpadJoyHoldType& out_hold_type) const {
649 return handheld_activation_mode; 655 std::scoped_lock lock{mutex};
656 return npad_resource.GetNpadJoyHoldType(out_hold_type, aruid);
650} 657}
651 658
652void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) { 659Result NPad::SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode mode) {
653 communication_mode = communication_mode_; 660 std::scoped_lock lock{mutex};
661 Result result = npad_resource.SetNpadHandheldActivationMode(aruid, mode);
662 if (result.IsSuccess()) {
663 OnUpdate({});
664 }
665 return result;
654} 666}
655 667
656NpadCommunicationMode NPad::GetNpadCommunicationMode() const { 668Result NPad::GetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode& out_mode) const {
657 return communication_mode; 669 std::scoped_lock lock{mutex};
670 return npad_resource.GetNpadHandheldActivationMode(out_mode, aruid);
658} 671}
659 672
660bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, 673bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
661 NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) { 674 NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) {
662 if (!IsNpadIdValid(npad_id)) { 675 if (!IsNpadIdValid(npad_id)) {
663 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 676 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
664 return false; 677 return false;
665 } 678 }
666 679
667 auto& controller = GetControllerFromNpadIdType(npad_id); 680 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
668 if (controller.shared_memory->assignment_mode != assignment_mode) { 681 if (controller.shared_memory->assignment_mode != assignment_mode) {
669 controller.shared_memory->assignment_mode = assignment_mode; 682 controller.shared_memory->assignment_mode = assignment_mode;
670 } 683 }
@@ -675,17 +688,17 @@ bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType
675 688
676 if (assignment_mode == NpadJoyAssignmentMode::Dual) { 689 if (assignment_mode == NpadJoyAssignmentMode::Dual) {
677 if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft) { 690 if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft) {
678 DisconnectNpad(npad_id); 691 DisconnectNpad(aruid, npad_id);
679 controller.is_dual_left_connected = true; 692 controller.is_dual_left_connected = true;
680 controller.is_dual_right_connected = false; 693 controller.is_dual_right_connected = false;
681 UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); 694 UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
682 return false; 695 return false;
683 } 696 }
684 if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) { 697 if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) {
685 DisconnectNpad(npad_id); 698 DisconnectNpad(aruid, npad_id);
686 controller.is_dual_left_connected = false; 699 controller.is_dual_left_connected = false;
687 controller.is_dual_right_connected = true; 700 controller.is_dual_right_connected = true;
688 UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); 701 UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
689 return false; 702 return false;
690 } 703 }
691 return false; 704 return false;
@@ -699,37 +712,38 @@ bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType
699 } 712 }
700 713
701 if (controller.is_dual_left_connected && !controller.is_dual_right_connected) { 714 if (controller.is_dual_left_connected && !controller.is_dual_right_connected) {
702 DisconnectNpad(npad_id); 715 DisconnectNpad(aruid, npad_id);
703 UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); 716 UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
704 return false; 717 return false;
705 } 718 }
706 if (!controller.is_dual_left_connected && controller.is_dual_right_connected) { 719 if (!controller.is_dual_left_connected && controller.is_dual_right_connected) {
707 DisconnectNpad(npad_id); 720 DisconnectNpad(aruid, npad_id);
708 UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); 721 UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
709 return false; 722 return false;
710 } 723 }
711 724
712 // We have two controllers connected to the same npad_id we need to split them 725 // We have two controllers connected to the same npad_id we need to split them
713 new_npad_id = hid_core.GetFirstDisconnectedNpadId(); 726 new_npad_id = hid_core.GetFirstDisconnectedNpadId();
714 auto& controller_2 = GetControllerFromNpadIdType(new_npad_id); 727 auto& controller_2 = GetControllerFromNpadIdType(aruid, new_npad_id);
715 DisconnectNpad(npad_id); 728 DisconnectNpad(aruid, npad_id);
716 if (npad_device_type == NpadJoyDeviceType::Left) { 729 if (npad_device_type == NpadJoyDeviceType::Left) {
717 UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); 730 UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
718 controller_2.is_dual_left_connected = false; 731 controller_2.is_dual_left_connected = false;
719 controller_2.is_dual_right_connected = true; 732 controller_2.is_dual_right_connected = true;
720 UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true); 733 UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
721 } else { 734 } else {
722 UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); 735 UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
723 controller_2.is_dual_left_connected = true; 736 controller_2.is_dual_left_connected = true;
724 controller_2.is_dual_right_connected = false; 737 controller_2.is_dual_right_connected = false;
725 UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true); 738 UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
726 } 739 }
727 return true; 740 return true;
728} 741}
729 742
730bool NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, 743bool NPad::VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
744 std::size_t device_index,
731 const Core::HID::VibrationValue& vibration_value) { 745 const Core::HID::VibrationValue& vibration_value) {
732 auto& controller = GetControllerFromNpadIdType(npad_id); 746 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
733 if (!controller.device->IsConnected()) { 747 if (!controller.device->IsConnected()) {
734 return false; 748 return false;
735 } 749 }
@@ -772,7 +786,8 @@ bool NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t d
772 return controller.device->SetVibration(device_index, vibration); 786 return controller.device->SetVibration(device_index, vibration);
773} 787}
774 788
775void NPad::VibrateController(const Core::HID::VibrationDeviceHandle& vibration_device_handle, 789void NPad::VibrateController(u64 aruid,
790 const Core::HID::VibrationDeviceHandle& vibration_device_handle,
776 const Core::HID::VibrationValue& vibration_value) { 791 const Core::HID::VibrationValue& vibration_value) {
777 if (IsVibrationHandleValid(vibration_device_handle).IsError()) { 792 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
778 return; 793 return;
@@ -782,7 +797,7 @@ void NPad::VibrateController(const Core::HID::VibrationDeviceHandle& vibration_d
782 return; 797 return;
783 } 798 }
784 799
785 auto& controller = GetControllerFromHandle(vibration_device_handle); 800 auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
786 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 801 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
787 802
788 if (!controller.vibration[device_index].device_mounted || !controller.device->IsConnected()) { 803 if (!controller.vibration[device_index].device_mounted || !controller.device->IsConnected()) {
@@ -812,14 +827,14 @@ void NPad::VibrateController(const Core::HID::VibrationDeviceHandle& vibration_d
812 return; 827 return;
813 } 828 }
814 829
815 if (VibrateControllerAtIndex(controller.device->GetNpadIdType(), device_index, 830 if (VibrateControllerAtIndex(aruid, controller.device->GetNpadIdType(), device_index,
816 vibration_value)) { 831 vibration_value)) {
817 controller.vibration[device_index].latest_vibration_value = vibration_value; 832 controller.vibration[device_index].latest_vibration_value = vibration_value;
818 } 833 }
819} 834}
820 835
821void NPad::VibrateControllers( 836void NPad::VibrateControllers(
822 std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, 837 u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
823 std::span<const Core::HID::VibrationValue> vibration_values) { 838 std::span<const Core::HID::VibrationValue> vibration_values) {
824 if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { 839 if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
825 return; 840 return;
@@ -831,17 +846,17 @@ void NPad::VibrateControllers(
831 "this is undefined behavior!"); 846 "this is undefined behavior!");
832 847
833 for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) { 848 for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) {
834 VibrateController(vibration_device_handles[i], vibration_values[i]); 849 VibrateController(aruid, vibration_device_handles[i], vibration_values[i]);
835 } 850 }
836} 851}
837 852
838Core::HID::VibrationValue NPad::GetLastVibration( 853Core::HID::VibrationValue NPad::GetLastVibration(
839 const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { 854 u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
840 if (IsVibrationHandleValid(vibration_device_handle).IsError()) { 855 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
841 return {}; 856 return {};
842 } 857 }
843 858
844 const auto& controller = GetControllerFromHandle(vibration_device_handle); 859 const auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
845 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 860 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
846 return controller.vibration[device_index].latest_vibration_value; 861 return controller.vibration[device_index].latest_vibration_value;
847} 862}
@@ -852,14 +867,20 @@ void NPad::InitializeVibrationDevice(
852 return; 867 return;
853 } 868 }
854 869
870 const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();
855 const auto npad_index = static_cast<Core::HID::NpadIdType>(vibration_device_handle.npad_id); 871 const auto npad_index = static_cast<Core::HID::NpadIdType>(vibration_device_handle.npad_id);
856 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 872 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
857 InitializeVibrationDeviceAtIndex(npad_index, device_index); 873
874 if (aruid == 0) {
875 return;
876 }
877
878 InitializeVibrationDeviceAtIndex(aruid, npad_index, device_index);
858} 879}
859 880
860void NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id, 881void NPad::InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
861 std::size_t device_index) { 882 std::size_t device_index) {
862 auto& controller = GetControllerFromNpadIdType(npad_id); 883 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
863 if (!Settings::values.vibration_enabled.GetValue()) { 884 if (!Settings::values.vibration_enabled.GetValue()) {
864 controller.vibration[device_index].device_mounted = false; 885 controller.vibration[device_index].device_mounted = false;
865 return; 886 return;
@@ -874,60 +895,50 @@ void NPad::SetPermitVibrationSession(bool permit_vibration_session) {
874} 895}
875 896
876bool NPad::IsVibrationDeviceMounted( 897bool NPad::IsVibrationDeviceMounted(
877 const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { 898 u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
878 if (IsVibrationHandleValid(vibration_device_handle).IsError()) { 899 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
879 return false; 900 return false;
880 } 901 }
881 902
882 const auto& controller = GetControllerFromHandle(vibration_device_handle); 903 const auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
883 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 904 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
884 return controller.vibration[device_index].device_mounted; 905 return controller.vibration[device_index].device_mounted;
885} 906}
886 907
887Kernel::KReadableEvent& NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) { 908Result NPad::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
888 if (!IsNpadIdValid(npad_id)) { 909 Core::HID::NpadIdType npad_id) {
889 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 910 std::scoped_lock lock{mutex};
890 // Fallback to player 1 911 return npad_resource.AcquireNpadStyleSetUpdateEventHandle(aruid, out_event, npad_id);
891 const auto& controller = GetControllerFromNpadIdType(Core::HID::NpadIdType::Player1);
892 return controller.styleset_changed_event->GetReadableEvent();
893 }
894
895 const auto& controller = GetControllerFromNpadIdType(npad_id);
896 return controller.styleset_changed_event->GetReadableEvent();
897}
898
899void NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
900 const auto& controller = GetControllerFromNpadIdType(npad_id);
901 controller.styleset_changed_event->Signal();
902} 912}
903 913
904void NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id) { 914void NPad::AddNewControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
905 UpdateControllerAt(controller, npad_id, true); 915 Core::HID::NpadIdType npad_id) {
916 UpdateControllerAt(aruid, controller, npad_id, true);
906} 917}
907 918
908void NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, Core::HID::NpadIdType npad_id, 919void NPad::UpdateControllerAt(u64 aruid, Core::HID::NpadStyleIndex type,
909 bool connected) { 920 Core::HID::NpadIdType npad_id, bool connected) {
910 auto& controller = GetControllerFromNpadIdType(npad_id); 921 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
911 if (!connected) { 922 if (!connected) {
912 DisconnectNpad(npad_id); 923 DisconnectNpad(aruid, npad_id);
913 return; 924 return;
914 } 925 }
915 926
916 controller.device->SetNpadStyleIndex(type); 927 controller.device->SetNpadStyleIndex(type);
917 InitNewlyAddedController(npad_id); 928 InitNewlyAddedController(aruid, npad_id);
918} 929}
919 930
920Result NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { 931Result NPad::DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id) {
921 if (!IsNpadIdValid(npad_id)) { 932 if (!IsNpadIdValid(npad_id)) {
922 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 933 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
923 return InvalidNpadId; 934 return ResultInvalidNpadId;
924 } 935 }
925 936
926 LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id); 937 LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id);
927 auto& controller = GetControllerFromNpadIdType(npad_id); 938 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
928 for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) { 939 for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
929 // Send an empty vibration to stop any vibrations. 940 // Send an empty vibration to stop any vibrations.
930 VibrateControllerAtIndex(npad_id, device_idx, {}); 941 VibrateControllerAtIndex(aruid, npad_id, device_idx, {});
931 controller.vibration[device_idx].device_mounted = false; 942 controller.vibration[device_idx].device_mounted = false;
932 } 943 }
933 944
@@ -961,47 +972,48 @@ Result NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
961 controller.is_dual_right_connected = true; 972 controller.is_dual_right_connected = true;
962 controller.is_connected = false; 973 controller.is_connected = false;
963 controller.device->Disconnect(); 974 controller.device->Disconnect();
964 SignalStyleSetChangedEvent(npad_id); 975 npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id);
965 WriteEmptyEntry(shared_memory); 976 WriteEmptyEntry(shared_memory);
966 return ResultSuccess; 977 return ResultSuccess;
967} 978}
968 979
969Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor( 980Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
970 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const { 981 u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle,
982 bool& is_firmware_available) const {
971 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); 983 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
972 if (is_valid.IsError()) { 984 if (is_valid.IsError()) {
973 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); 985 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
974 return is_valid; 986 return is_valid;
975 } 987 }
976 988
977 const auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle); 989 const auto& sixaxis_properties = GetSixaxisProperties(aruid, sixaxis_handle);
978 is_firmware_available = sixaxis_properties.is_firmware_update_available != 0; 990 is_firmware_available = sixaxis_properties.is_firmware_update_available != 0;
979 return ResultSuccess; 991 return ResultSuccess;
980} 992}
981 993
982Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( 994Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
983 const Core::HID::SixAxisSensorHandle& sixaxis_handle) { 995 u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
984 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); 996 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
985 if (is_valid.IsError()) { 997 if (is_valid.IsError()) {
986 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); 998 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
987 return is_valid; 999 return is_valid;
988 } 1000 }
989 1001
990 auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle); 1002 auto& sixaxis_properties = GetSixaxisProperties(aruid, sixaxis_handle);
991 sixaxis_properties.is_newly_assigned.Assign(0); 1003 sixaxis_properties.is_newly_assigned.Assign(0);
992 1004
993 return ResultSuccess; 1005 return ResultSuccess;
994} 1006}
995 1007
996Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, 1008Result NPad::MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1,
997 Core::HID::NpadIdType npad_id_2) { 1009 Core::HID::NpadIdType npad_id_2) {
998 if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { 1010 if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
999 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, 1011 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
1000 npad_id_2); 1012 npad_id_2);
1001 return InvalidNpadId; 1013 return ResultInvalidNpadId;
1002 } 1014 }
1003 auto& controller_1 = GetControllerFromNpadIdType(npad_id_1); 1015 auto& controller_1 = GetControllerFromNpadIdType(aruid, npad_id_1);
1004 auto& controller_2 = GetControllerFromNpadIdType(npad_id_2); 1016 auto& controller_2 = GetControllerFromNpadIdType(aruid, npad_id_2);
1005 auto controller_style_1 = controller_1.device->GetNpadStyleIndex(); 1017 auto controller_style_1 = controller_1.device->GetNpadStyleIndex();
1006 auto controller_style_2 = controller_2.device->GetNpadStyleIndex(); 1018 auto controller_style_2 = controller_2.device->GetNpadStyleIndex();
1007 1019
@@ -1048,51 +1060,62 @@ Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
1048 } 1060 }
1049 1061
1050 // Disconnect the joycons and connect them as dual joycon at the first index. 1062 // Disconnect the joycons and connect them as dual joycon at the first index.
1051 DisconnectNpad(npad_id_1); 1063 DisconnectNpad(aruid, npad_id_1);
1052 DisconnectNpad(npad_id_2); 1064 DisconnectNpad(aruid, npad_id_2);
1053 controller_1.is_dual_left_connected = true; 1065 controller_1.is_dual_left_connected = true;
1054 controller_1.is_dual_right_connected = true; 1066 controller_1.is_dual_right_connected = true;
1055 AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1); 1067 AddNewControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
1056 return ResultSuccess; 1068 return ResultSuccess;
1057} 1069}
1058 1070
1059void NPad::StartLRAssignmentMode() { 1071Result NPad::StartLrAssignmentMode(u64 aruid) {
1060 // Nothing internally is used for lr assignment mode. Since we have the ability to set the 1072 std::scoped_lock lock{mutex};
1061 // controller types from boot, it doesn't really matter about showing a selection screen 1073 bool is_enabled{};
1062 is_in_lr_assignment_mode = true; 1074 Result result = npad_resource.GetLrAssignmentMode(is_enabled, aruid);
1075 if (result.IsSuccess() && is_enabled == false) {
1076 result = npad_resource.SetLrAssignmentMode(aruid, true);
1077 }
1078 return result;
1063} 1079}
1064 1080
1065void NPad::StopLRAssignmentMode() { 1081Result NPad::StopLrAssignmentMode(u64 aruid) {
1066 is_in_lr_assignment_mode = false; 1082 std::scoped_lock lock{mutex};
1083 bool is_enabled{};
1084 Result result = npad_resource.GetLrAssignmentMode(is_enabled, aruid);
1085 if (result.IsSuccess() && is_enabled == true) {
1086 result = npad_resource.SetLrAssignmentMode(aruid, false);
1087 }
1088 return result;
1067} 1089}
1068 1090
1069Result NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2) { 1091Result NPad::SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
1092 Core::HID::NpadIdType npad_id_2) {
1070 if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { 1093 if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
1071 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, 1094 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
1072 npad_id_2); 1095 npad_id_2);
1073 return InvalidNpadId; 1096 return ResultInvalidNpadId;
1074 } 1097 }
1075 if (npad_id_1 == Core::HID::NpadIdType::Handheld || 1098 if (npad_id_1 == Core::HID::NpadIdType::Handheld ||
1076 npad_id_2 == Core::HID::NpadIdType::Handheld || npad_id_1 == Core::HID::NpadIdType::Other || 1099 npad_id_2 == Core::HID::NpadIdType::Handheld || npad_id_1 == Core::HID::NpadIdType::Other ||
1077 npad_id_2 == Core::HID::NpadIdType::Other) { 1100 npad_id_2 == Core::HID::NpadIdType::Other) {
1078 return ResultSuccess; 1101 return ResultSuccess;
1079 } 1102 }
1080 const auto& controller_1 = GetControllerFromNpadIdType(npad_id_1).device; 1103 const auto& controller_1 = GetControllerFromNpadIdType(aruid, npad_id_1).device;
1081 const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device; 1104 const auto& controller_2 = GetControllerFromNpadIdType(aruid, npad_id_2).device;
1082 const auto type_index_1 = controller_1->GetNpadStyleIndex(); 1105 const auto type_index_1 = controller_1->GetNpadStyleIndex();
1083 const auto type_index_2 = controller_2->GetNpadStyleIndex(); 1106 const auto type_index_2 = controller_2->GetNpadStyleIndex();
1084 const auto is_connected_1 = controller_1->IsConnected(); 1107 const auto is_connected_1 = controller_1->IsConnected();
1085 const auto is_connected_2 = controller_2->IsConnected(); 1108 const auto is_connected_2 = controller_2->IsConnected();
1086 1109
1087 if (!IsControllerSupported(type_index_1) && is_connected_1) { 1110 if (!npad_resource.IsControllerSupported(aruid, type_index_1) && is_connected_1) {
1088 return NpadNotConnected; 1111 return ResultNpadNotConnected;
1089 } 1112 }
1090 if (!IsControllerSupported(type_index_2) && is_connected_2) { 1113 if (!npad_resource.IsControllerSupported(aruid, type_index_2) && is_connected_2) {
1091 return NpadNotConnected; 1114 return ResultNpadNotConnected;
1092 } 1115 }
1093 1116
1094 UpdateControllerAt(type_index_2, npad_id_1, is_connected_2); 1117 UpdateControllerAt(aruid, type_index_2, npad_id_1, is_connected_2);
1095 UpdateControllerAt(type_index_1, npad_id_2, is_connected_1); 1118 UpdateControllerAt(aruid, type_index_1, npad_id_2, is_connected_1);
1096 1119
1097 return ResultSuccess; 1120 return ResultSuccess;
1098} 1121}
@@ -1100,68 +1123,68 @@ Result NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::Npad
1100Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const { 1123Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const {
1101 if (!IsNpadIdValid(npad_id)) { 1124 if (!IsNpadIdValid(npad_id)) {
1102 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1125 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1103 return InvalidNpadId; 1126 return ResultInvalidNpadId;
1104 } 1127 }
1105 const auto& controller = GetControllerFromNpadIdType(npad_id).device; 1128 const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();
1129 const auto& controller = GetControllerFromNpadIdType(aruid, npad_id).device;
1106 pattern = controller->GetLedPattern(); 1130 pattern = controller->GetLedPattern();
1107 return ResultSuccess; 1131 return ResultSuccess;
1108} 1132}
1109 1133
1110Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, 1134Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
1111 bool& is_valid) const { 1135 Core::HID::NpadIdType npad_id) const {
1112 if (!IsNpadIdValid(npad_id)) { 1136 std::scoped_lock lock{mutex};
1113 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1137 return npad_resource.GetHomeProtectionEnabled(out_is_enabled, aruid, npad_id);
1114 return InvalidNpadId;
1115 }
1116 const auto& controller = GetControllerFromNpadIdType(npad_id);
1117 is_valid = controller.unintended_home_button_input_protection;
1118 return ResultSuccess;
1119} 1138}
1120 1139
1121Result NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, 1140Result NPad::EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id,
1122 Core::HID::NpadIdType npad_id) { 1141 bool is_enabled) {
1123 if (!IsNpadIdValid(npad_id)) { 1142 std::scoped_lock lock{mutex};
1124 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1143 return npad_resource.SetHomeProtectionEnabled(aruid, npad_id, is_enabled);
1125 return InvalidNpadId;
1126 }
1127 auto& controller = GetControllerFromNpadIdType(npad_id);
1128 controller.unintended_home_button_input_protection = is_protection_enabled;
1129 return ResultSuccess;
1130} 1144}
1131 1145
1132void NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) { 1146void NPad::SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled) {
1133 analog_stick_use_center_clamp = use_center_clamp; 1147 std::scoped_lock lock{mutex};
1148 npad_resource.SetNpadAnalogStickUseCenterClamp(aruid, is_enabled);
1134} 1149}
1135 1150
1136void NPad::ClearAllConnectedControllers() { 1151void NPad::ClearAllConnectedControllers() {
1137 for (auto& controller : controller_data) { 1152 for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
1138 if (controller.device->IsConnected() && 1153 for (auto& controller : controller_data[aruid_index]) {
1139 controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) { 1154 if (controller.device->IsConnected() &&
1140 controller.device->Disconnect(); 1155 controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) {
1141 controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None); 1156 controller.device->Disconnect();
1157 controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
1158 }
1142 } 1159 }
1143 } 1160 }
1144} 1161}
1145 1162
1146void NPad::DisconnectAllConnectedControllers() { 1163void NPad::DisconnectAllConnectedControllers() {
1147 for (auto& controller : controller_data) { 1164 for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
1148 controller.device->Disconnect(); 1165 for (auto& controller : controller_data[aruid_index]) {
1166 controller.device->Disconnect();
1167 }
1149 } 1168 }
1150} 1169}
1151 1170
1152void NPad::ConnectAllDisconnectedControllers() { 1171void NPad::ConnectAllDisconnectedControllers() {
1153 for (auto& controller : controller_data) { 1172 for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
1154 if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None && 1173 for (auto& controller : controller_data[aruid_index]) {
1155 !controller.device->IsConnected()) { 1174 if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None &&
1156 controller.device->Connect(); 1175 !controller.device->IsConnected()) {
1176 controller.device->Connect();
1177 }
1157 } 1178 }
1158 } 1179 }
1159} 1180}
1160 1181
1161void NPad::ClearAllControllers() { 1182void NPad::ClearAllControllers() {
1162 for (auto& controller : controller_data) { 1183 for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
1163 controller.device->Disconnect(); 1184 for (auto& controller : controller_data[aruid_index]) {
1164 controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None); 1185 controller.device->Disconnect();
1186 controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
1187 }
1165 } 1188 }
1166} 1189}
1167 1190
@@ -1169,128 +1192,105 @@ Core::HID::NpadButton NPad::GetAndResetPressState() {
1169 return static_cast<Core::HID::NpadButton>(press_state.exchange(0)); 1192 return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
1170} 1193}
1171 1194
1172void NPad::ApplyNpadSystemCommonPolicy() { 1195Result NPad::ApplyNpadSystemCommonPolicy(u64 aruid) {
1173 Core::HID::NpadStyleTag styletag{}; 1196 std::scoped_lock lock{mutex};
1174 styletag.fullkey.Assign(1); 1197 const Result result = npad_resource.ApplyNpadSystemCommonPolicy(aruid, false);
1175 styletag.handheld.Assign(1); 1198 if (result.IsSuccess()) {
1176 styletag.joycon_dual.Assign(1); 1199 OnUpdate({});
1177 styletag.system_ext.Assign(1); 1200 }
1178 styletag.system.Assign(1); 1201 return result;
1179 SetSupportedStyleSet(styletag); 1202}
1180
1181 SetNpadHandheldActivationMode(NpadHandheldActivationMode::Dual);
1182
1183 supported_npad_id_types.clear();
1184 supported_npad_id_types.resize(10);
1185 supported_npad_id_types[0] = Core::HID::NpadIdType::Player1;
1186 supported_npad_id_types[1] = Core::HID::NpadIdType::Player2;
1187 supported_npad_id_types[2] = Core::HID::NpadIdType::Player3;
1188 supported_npad_id_types[3] = Core::HID::NpadIdType::Player4;
1189 supported_npad_id_types[4] = Core::HID::NpadIdType::Player5;
1190 supported_npad_id_types[5] = Core::HID::NpadIdType::Player6;
1191 supported_npad_id_types[6] = Core::HID::NpadIdType::Player7;
1192 supported_npad_id_types[7] = Core::HID::NpadIdType::Player8;
1193 supported_npad_id_types[8] = Core::HID::NpadIdType::Other;
1194 supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld;
1195}
1196
1197bool NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
1198 if (controller == Core::HID::NpadStyleIndex::Handheld) {
1199 const bool support_handheld =
1200 std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
1201 Core::HID::NpadIdType::Handheld) != supported_npad_id_types.end();
1202 // Handheld is not even a supported type, lets stop here
1203 if (!support_handheld) {
1204 return false;
1205 }
1206 // Handheld shouldn't be supported in docked mode
1207 if (Settings::IsDockedMode()) {
1208 return false;
1209 }
1210 1203
1211 return true; 1204Result NPad::ApplyNpadSystemCommonPolicyFull(u64 aruid) {
1212 } 1205 std::scoped_lock lock{mutex};
1213 1206 const Result result = npad_resource.ApplyNpadSystemCommonPolicy(aruid, true);
1214 if (std::any_of(supported_npad_id_types.begin(), supported_npad_id_types.end(), 1207 if (result.IsSuccess()) {
1215 [](Core::HID::NpadIdType npad_id) { 1208 OnUpdate({});
1216 return npad_id <= Core::HID::NpadIdType::Player8;
1217 })) {
1218 Core::HID::NpadStyleTag style = GetSupportedStyleSet();
1219 switch (controller) {
1220 case Core::HID::NpadStyleIndex::ProController:
1221 return style.fullkey.As<bool>();
1222 case Core::HID::NpadStyleIndex::JoyconDual:
1223 return style.joycon_dual.As<bool>();
1224 case Core::HID::NpadStyleIndex::JoyconLeft:
1225 return style.joycon_left.As<bool>();
1226 case Core::HID::NpadStyleIndex::JoyconRight:
1227 return style.joycon_right.As<bool>();
1228 case Core::HID::NpadStyleIndex::GameCube:
1229 return style.gamecube.As<bool>();
1230 case Core::HID::NpadStyleIndex::Pokeball:
1231 return style.palma.As<bool>();
1232 case Core::HID::NpadStyleIndex::NES:
1233 return style.lark.As<bool>();
1234 case Core::HID::NpadStyleIndex::SNES:
1235 return style.lucia.As<bool>();
1236 case Core::HID::NpadStyleIndex::N64:
1237 return style.lagoon.As<bool>();
1238 case Core::HID::NpadStyleIndex::SegaGenesis:
1239 return style.lager.As<bool>();
1240 default:
1241 return false;
1242 }
1243 } 1209 }
1210 return result;
1211}
1212
1213Result NPad::ClearNpadSystemCommonPolicy(u64 aruid) {
1214 std::scoped_lock lock{mutex};
1215 const Result result = npad_resource.ClearNpadSystemCommonPolicy(aruid);
1216 if (result.IsSuccess()) {
1217 OnUpdate({});
1218 }
1219 return result;
1220}
1221
1222void NPad::SetRevision(u64 aruid, NpadRevision revision) {
1223 npad_resource.SetNpadRevision(aruid, revision);
1224}
1225
1226NpadRevision NPad::GetRevision(u64 aruid) {
1227 return npad_resource.GetNpadRevision(aruid);
1228}
1229
1230Result NPad::RegisterAppletResourceUserId(u64 aruid) {
1231 return npad_resource.RegisterAppletResourceUserId(aruid);
1232}
1233
1234void NPad::UnregisterAppletResourceUserId(u64 aruid) {
1235 npad_resource.UnregisterAppletResourceUserId(aruid);
1236}
1244 1237
1245 return false; 1238void NPad::SetNpadExternals(std::shared_ptr<AppletResource> resource,
1239 std::recursive_mutex* shared_mutex) {
1240 applet_resource_holder.applet_resource = resource;
1241 applet_resource_holder.shared_mutex = shared_mutex;
1242 applet_resource_holder.shared_npad_resource = &npad_resource;
1246} 1243}
1247 1244
1248NPad::NpadControllerData& NPad::GetControllerFromHandle( 1245NPad::NpadControllerData& NPad::GetControllerFromHandle(
1249 const Core::HID::VibrationDeviceHandle& device_handle) { 1246 u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) {
1250 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1247 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1251 return GetControllerFromNpadIdType(npad_id); 1248 return GetControllerFromNpadIdType(aruid, npad_id);
1252} 1249}
1253 1250
1254const NPad::NpadControllerData& NPad::GetControllerFromHandle( 1251const NPad::NpadControllerData& NPad::GetControllerFromHandle(
1255 const Core::HID::VibrationDeviceHandle& device_handle) const { 1252 u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const {
1256 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1253 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1257 return GetControllerFromNpadIdType(npad_id); 1254 return GetControllerFromNpadIdType(aruid, npad_id);
1258} 1255}
1259 1256
1260NPad::NpadControllerData& NPad::GetControllerFromHandle( 1257NPad::NpadControllerData& NPad::GetControllerFromHandle(
1261 const Core::HID::SixAxisSensorHandle& device_handle) { 1258 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) {
1262 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1259 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1263 return GetControllerFromNpadIdType(npad_id); 1260 return GetControllerFromNpadIdType(aruid, npad_id);
1264} 1261}
1265 1262
1266const NPad::NpadControllerData& NPad::GetControllerFromHandle( 1263const NPad::NpadControllerData& NPad::GetControllerFromHandle(
1267 const Core::HID::SixAxisSensorHandle& device_handle) const { 1264 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const {
1268 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1265 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1269 return GetControllerFromNpadIdType(npad_id); 1266 return GetControllerFromNpadIdType(aruid, npad_id);
1270} 1267}
1271 1268
1272NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) { 1269NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(u64 aruid,
1270 Core::HID::NpadIdType npad_id) {
1273 if (!IsNpadIdValid(npad_id)) { 1271 if (!IsNpadIdValid(npad_id)) {
1274 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1272 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1275 npad_id = Core::HID::NpadIdType::Player1; 1273 npad_id = Core::HID::NpadIdType::Player1;
1276 } 1274 }
1277 const auto npad_index = NpadIdTypeToIndex(npad_id); 1275 const auto npad_index = NpadIdTypeToIndex(npad_id);
1278 return controller_data[npad_index]; 1276 const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
1277 return controller_data[aruid_index][npad_index];
1279} 1278}
1280 1279
1281const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType( 1280const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(
1282 Core::HID::NpadIdType npad_id) const { 1281 u64 aruid, Core::HID::NpadIdType npad_id) const {
1283 if (!IsNpadIdValid(npad_id)) { 1282 if (!IsNpadIdValid(npad_id)) {
1284 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1283 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1285 npad_id = Core::HID::NpadIdType::Player1; 1284 npad_id = Core::HID::NpadIdType::Player1;
1286 } 1285 }
1287 const auto npad_index = NpadIdTypeToIndex(npad_id); 1286 const auto npad_index = NpadIdTypeToIndex(npad_id);
1288 return controller_data[npad_index]; 1287 const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
1288 return controller_data[aruid_index][npad_index];
1289} 1289}
1290 1290
1291Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( 1291Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
1292 const Core::HID::SixAxisSensorHandle& sixaxis_handle) { 1292 u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
1293 auto& controller = GetControllerFromHandle(sixaxis_handle); 1293 auto& controller = GetControllerFromHandle(aruid, sixaxis_handle);
1294 switch (sixaxis_handle.npad_type) { 1294 switch (sixaxis_handle.npad_type) {
1295 case Core::HID::NpadStyleIndex::ProController: 1295 case Core::HID::NpadStyleIndex::ProController:
1296 case Core::HID::NpadStyleIndex::Pokeball: 1296 case Core::HID::NpadStyleIndex::Pokeball:
@@ -1312,8 +1312,8 @@ Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
1312} 1312}
1313 1313
1314const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( 1314const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
1315 const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { 1315 u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
1316 const auto& controller = GetControllerFromHandle(sixaxis_handle); 1316 const auto& controller = GetControllerFromHandle(aruid, sixaxis_handle);
1317 switch (sixaxis_handle.npad_type) { 1317 switch (sixaxis_handle.npad_type) {
1318 case Core::HID::NpadStyleIndex::ProController: 1318 case Core::HID::NpadStyleIndex::ProController:
1319 case Core::HID::NpadStyleIndex::Pokeball: 1319 case Core::HID::NpadStyleIndex::Pokeball:
@@ -1335,7 +1335,8 @@ const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
1335} 1335}
1336 1336
1337AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { 1337AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) {
1338 const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory; 1338 const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();
1339 const auto& shared_memory = GetControllerFromNpadIdType(aruid, npad_id).shared_memory;
1339 1340
1340 return { 1341 return {
1341 .ui_variant = 0, 1342 .ui_variant = 0,
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
new file mode 100644
index 000000000..58f8c7acf
--- /dev/null
+++ b/src/hid_core/resources/npad/npad.h
@@ -0,0 +1,214 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <array>
7#include <atomic>
8#include <mutex>
9#include <span>
10
11#include "common/common_types.h"
12#include "hid_core/hid_types.h"
13#include "hid_core/resources/controller_base.h"
14#include "hid_core/resources/npad/npad_resource.h"
15#include "hid_core/resources/npad/npad_types.h"
16
17namespace Core::HID {
18class EmulatedController;
19enum class ControllerTriggerType;
20} // namespace Core::HID
21
22namespace Kernel {
23class KEvent;
24class KReadableEvent;
25} // namespace Kernel
26
27namespace Service::KernelHelpers {
28class ServiceContext;
29} // namespace Service::KernelHelpers
30
31union Result;
32
33namespace Service::HID {
34class AppletResource;
35struct NpadInternalState;
36struct NpadSixAxisSensorLifo;
37struct NpadSharedMemoryFormat;
38
39class NPad final {
40public:
41 explicit NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
42 ~NPad();
43
44 Result Activate();
45 Result Activate(u64 aruid);
46
47 Result ActivateNpadResource();
48 Result ActivateNpadResource(u64 aruid);
49
50 // When the controller is requesting an update for the shared memory
51 void OnUpdate(const Core::Timing::CoreTiming& core_timing);
52
53 Result SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet supported_style_set);
54 Result GetSupportedNpadStyleSet(u64 aruid,
55 Core::HID::NpadStyleSet& out_supported_style_set) const;
56 Result GetMaskedSupportedNpadStyleSet(u64 aruid,
57 Core::HID::NpadStyleSet& out_supported_style_set) const;
58
59 Result SetSupportedNpadIdType(u64 aruid,
60 std::span<const Core::HID::NpadIdType> supported_npad_list);
61
62 Result SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type);
63 Result GetNpadJoyHoldType(u64 aruid, NpadJoyHoldType& out_hold_type) const;
64
65 Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode mode);
66 Result GetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode& out_mode) const;
67
68 bool SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
69 NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
70
71 bool VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
72 std::size_t device_index,
73 const Core::HID::VibrationValue& vibration_value);
74
75 void VibrateController(u64 aruid,
76 const Core::HID::VibrationDeviceHandle& vibration_device_handle,
77 const Core::HID::VibrationValue& vibration_value);
78
79 void VibrateControllers(
80 u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
81 std::span<const Core::HID::VibrationValue> vibration_values);
82
83 Core::HID::VibrationValue GetLastVibration(
84 u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
85
86 void InitializeVibrationDevice(const Core::HID::VibrationDeviceHandle& vibration_device_handle);
87
88 void InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
89 std::size_t device_index);
90
91 void SetPermitVibrationSession(bool permit_vibration_session);
92
93 bool IsVibrationDeviceMounted(
94 u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
95
96 Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
97 Core::HID::NpadIdType npad_id);
98
99 // Adds a new controller at an index.
100 void AddNewControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
101 Core::HID::NpadIdType npad_id);
102 // Adds a new controller at an index with connection status.
103 void UpdateControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
104 Core::HID::NpadIdType npad_id, bool connected);
105
106 Result DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id);
107
108 Result IsFirmwareUpdateAvailableForSixAxisSensor(
109 u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle,
110 bool& is_firmware_available) const;
111 Result ResetIsSixAxisSensorDeviceNewlyAssigned(
112 u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle);
113
114 Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
115
116 Result IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
117 Core::HID::NpadIdType npad_id) const;
118 Result EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id,
119 bool is_enabled);
120
121 void SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled);
122 void ClearAllConnectedControllers();
123 void DisconnectAllConnectedControllers();
124 void ConnectAllDisconnectedControllers();
125 void ClearAllControllers();
126
127 Result MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1,
128 Core::HID::NpadIdType npad_id_2);
129 Result StartLrAssignmentMode(u64 aruid);
130 Result StopLrAssignmentMode(u64 aruid);
131 Result SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
132 Core::HID::NpadIdType npad_id_2);
133
134 // Logical OR for all buttons presses on all controllers
135 // Specifically for cheat engine and other features.
136 Core::HID::NpadButton GetAndResetPressState();
137
138 Result ApplyNpadSystemCommonPolicy(u64 aruid);
139 Result ApplyNpadSystemCommonPolicyFull(u64 aruid);
140 Result ClearNpadSystemCommonPolicy(u64 aruid);
141
142 void SetRevision(u64 aruid, NpadRevision revision);
143 NpadRevision GetRevision(u64 aruid);
144
145 Result RegisterAppletResourceUserId(u64 aruid);
146 void UnregisterAppletResourceUserId(u64 aruid);
147 void SetNpadExternals(std::shared_ptr<AppletResource> resource,
148 std::recursive_mutex* shared_mutex);
149
150 AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
151
152private:
153 struct VibrationData {
154 bool device_mounted{};
155 Core::HID::VibrationValue latest_vibration_value{};
156 std::chrono::steady_clock::time_point last_vibration_timepoint{};
157 };
158
159 struct NpadControllerData {
160 NpadInternalState* shared_memory = nullptr;
161 Core::HID::EmulatedController* device = nullptr;
162
163 std::array<VibrationData, 2> vibration{};
164 bool is_connected{};
165
166 // Dual joycons can have only one side connected
167 bool is_dual_left_connected{true};
168 bool is_dual_right_connected{true};
169
170 // Current pad state
171 NPadGenericState npad_pad_state{};
172 NPadGenericState npad_libnx_state{};
173 NpadGcTriggerState npad_trigger_state{};
174 int callback_key{};
175 };
176
177 void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
178 void InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id);
179 void RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id);
180 void WriteEmptyEntry(NpadInternalState* npad);
181
182 NpadControllerData& GetControllerFromHandle(
183 u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle);
184 const NpadControllerData& GetControllerFromHandle(
185 u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const;
186 NpadControllerData& GetControllerFromHandle(
187 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
188 const NpadControllerData& GetControllerFromHandle(
189 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
190 NpadControllerData& GetControllerFromNpadIdType(u64 aruid, Core::HID::NpadIdType npad_id);
191 const NpadControllerData& GetControllerFromNpadIdType(u64 aruid,
192 Core::HID::NpadIdType npad_id) const;
193
194 Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
195 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
196 const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
197 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
198
199 Core::HID::HIDCore& hid_core;
200 KernelHelpers::ServiceContext& service_context;
201
202 s32 ref_counter{};
203 mutable std::mutex mutex;
204 NPadResource npad_resource;
205 AppletResourceHolder applet_resource_holder{};
206 Kernel::KEvent* input_event{nullptr};
207 std::mutex* input_mutex{nullptr};
208
209 std::atomic<u64> press_state{};
210 bool permit_vibration_session_enabled;
211 std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax>
212 controller_data{};
213};
214} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad_data.cpp b/src/hid_core/resources/npad/npad_data.cpp
new file mode 100644
index 000000000..c7e9760cb
--- /dev/null
+++ b/src/hid_core/resources/npad/npad_data.cpp
@@ -0,0 +1,228 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "hid_core/hid_util.h"
5#include "hid_core/resources/npad/npad_data.h"
6
7namespace Service::HID {
8
9NPadData::NPadData() {
10 ClearNpadSystemCommonPolicy();
11}
12
13NPadData::~NPadData() = default;
14
15NpadStatus NPadData::GetNpadStatus() const {
16 return status;
17}
18
19void NPadData::SetNpadAnalogStickUseCenterClamp(bool is_enabled) {
20 status.use_center_clamp.Assign(is_enabled);
21}
22
23bool NPadData::GetNpadAnalogStickUseCenterClamp() const {
24 return status.use_center_clamp.As<bool>();
25}
26
27void NPadData::SetNpadSystemExtStateEnabled(bool is_enabled) {
28 status.system_ext_state.Assign(is_enabled);
29}
30
31bool NPadData::GetNpadSystemExtState() const {
32 return status.system_ext_state.As<bool>();
33}
34
35Result NPadData::SetSupportedNpadIdType(std::span<const Core::HID::NpadIdType> list) {
36 // Note: Real limit is 11. But array size is 10. N's bug?
37 if (list.size() > MaxSupportedNpadIdTypes) {
38 return ResultInvalidArraySize;
39 }
40
41 supported_npad_id_types_count = list.size();
42 memcpy(supported_npad_id_types.data(), list.data(),
43 list.size() * sizeof(Core::HID::NpadIdType));
44
45 return ResultSuccess;
46}
47
48std::size_t NPadData::GetSupportedNpadIdType(std::span<Core::HID::NpadIdType> out_list) const {
49 std::size_t out_size = std::min(supported_npad_id_types_count, out_list.size());
50
51 memcpy(out_list.data(), supported_npad_id_types.data(),
52 out_size * sizeof(Core::HID::NpadIdType));
53
54 return out_size;
55}
56
57bool NPadData::IsNpadIdTypeSupported(Core::HID::NpadIdType npad_id) const {
58 for (std::size_t i = 0; i < supported_npad_id_types_count; i++) {
59 if (supported_npad_id_types[i] == npad_id) {
60 return true;
61 }
62 }
63
64 return false;
65}
66
67void NPadData::SetNpadSystemCommonPolicy(bool is_full_policy) {
68 supported_npad_style_set = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::JoyDual |
69 Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System;
70 handheld_activation_mode = NpadHandheldActivationMode::Dual;
71
72 status.is_supported_styleset_set.Assign(true);
73 status.is_hold_type_set.Assign(true);
74 status.lr_assignment_mode.Assign(false);
75 status.is_policy.Assign(true);
76 if (is_full_policy) {
77 status.is_full_policy.Assign(true);
78 }
79
80 supported_npad_id_types_count = 10;
81 supported_npad_id_types[0] = Core::HID::NpadIdType::Player1;
82 supported_npad_id_types[1] = Core::HID::NpadIdType::Player2;
83 supported_npad_id_types[2] = Core::HID::NpadIdType::Player3;
84 supported_npad_id_types[3] = Core::HID::NpadIdType::Player4;
85 supported_npad_id_types[4] = Core::HID::NpadIdType::Player5;
86 supported_npad_id_types[5] = Core::HID::NpadIdType::Player6;
87 supported_npad_id_types[6] = Core::HID::NpadIdType::Player7;
88 supported_npad_id_types[7] = Core::HID::NpadIdType::Player8;
89 supported_npad_id_types[8] = Core::HID::NpadIdType::Other;
90 supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld;
91
92 for (auto& input_protection : is_unintended_home_button_input_protection) {
93 input_protection = true;
94 }
95}
96
97void NPadData::ClearNpadSystemCommonPolicy() {
98 status.raw = 0;
99 supported_npad_style_set = Core::HID::NpadStyleSet::All;
100 npad_hold_type = NpadJoyHoldType::Vertical;
101 handheld_activation_mode = NpadHandheldActivationMode::Dual;
102
103 for (auto& button_assignment : npad_button_assignment) {
104 button_assignment = Core::HID::NpadButton::None;
105 }
106
107 supported_npad_id_types_count = 10;
108 supported_npad_id_types[0] = Core::HID::NpadIdType::Player1;
109 supported_npad_id_types[1] = Core::HID::NpadIdType::Player2;
110 supported_npad_id_types[2] = Core::HID::NpadIdType::Player3;
111 supported_npad_id_types[3] = Core::HID::NpadIdType::Player4;
112 supported_npad_id_types[4] = Core::HID::NpadIdType::Player5;
113 supported_npad_id_types[5] = Core::HID::NpadIdType::Player6;
114 supported_npad_id_types[6] = Core::HID::NpadIdType::Player7;
115 supported_npad_id_types[7] = Core::HID::NpadIdType::Player8;
116 supported_npad_id_types[8] = Core::HID::NpadIdType::Other;
117 supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld;
118
119 for (auto& input_protection : is_unintended_home_button_input_protection) {
120 input_protection = true;
121 }
122}
123
124void NPadData::SetNpadJoyHoldType(NpadJoyHoldType hold_type) {
125 npad_hold_type = hold_type;
126 status.is_hold_type_set.Assign(true);
127}
128
129NpadJoyHoldType NPadData::GetNpadJoyHoldType() const {
130 return npad_hold_type;
131}
132
133void NPadData::SetHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
134 handheld_activation_mode = activation_mode;
135}
136
137NpadHandheldActivationMode NPadData::GetHandheldActivationMode() const {
138 return handheld_activation_mode;
139}
140
141void NPadData::SetSupportedNpadStyleSet(Core::HID::NpadStyleSet style_set) {
142 supported_npad_style_set = style_set;
143 status.is_supported_styleset_set.Assign(true);
144 status.is_hold_type_set.Assign(true);
145}
146
147Core::HID::NpadStyleSet NPadData::GetSupportedNpadStyleSet() const {
148 return supported_npad_style_set;
149}
150
151bool NPadData::IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index) const {
152 Core::HID::NpadStyleTag style = {supported_npad_style_set};
153 switch (style_index) {
154 case Core::HID::NpadStyleIndex::ProController:
155 return style.fullkey.As<bool>();
156 case Core::HID::NpadStyleIndex::Handheld:
157 return style.handheld.As<bool>();
158 case Core::HID::NpadStyleIndex::JoyconDual:
159 return style.joycon_dual.As<bool>();
160 case Core::HID::NpadStyleIndex::JoyconLeft:
161 return style.joycon_left.As<bool>();
162 case Core::HID::NpadStyleIndex::JoyconRight:
163 return style.joycon_right.As<bool>();
164 case Core::HID::NpadStyleIndex::GameCube:
165 return style.gamecube.As<bool>();
166 case Core::HID::NpadStyleIndex::Pokeball:
167 return style.palma.As<bool>();
168 case Core::HID::NpadStyleIndex::NES:
169 return style.lark.As<bool>();
170 case Core::HID::NpadStyleIndex::SNES:
171 return style.lucia.As<bool>();
172 case Core::HID::NpadStyleIndex::N64:
173 return style.lagoon.As<bool>();
174 case Core::HID::NpadStyleIndex::SegaGenesis:
175 return style.lager.As<bool>();
176 default:
177 return false;
178 }
179}
180
181void NPadData::SetLrAssignmentMode(bool is_enabled) {
182 status.lr_assignment_mode.Assign(is_enabled);
183}
184
185bool NPadData::GetLrAssignmentMode() const {
186 return status.lr_assignment_mode.As<bool>();
187}
188
189void NPadData::SetAssigningSingleOnSlSrPress(bool is_enabled) {
190 status.assigning_single_on_sl_sr_press.Assign(is_enabled);
191}
192
193bool NPadData::GetAssigningSingleOnSlSrPress() const {
194 return status.assigning_single_on_sl_sr_press.As<bool>();
195}
196
197void NPadData::SetHomeProtectionEnabled(bool is_enabled, Core::HID::NpadIdType npad_id) {
198 is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)] = is_enabled;
199}
200
201bool NPadData::GetHomeProtectionEnabled(Core::HID::NpadIdType npad_id) const {
202 return is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)];
203}
204
205void NPadData::SetCaptureButtonAssignment(Core::HID::NpadButton button_assignment,
206 std::size_t style_index) {
207 npad_button_assignment[style_index] = button_assignment;
208}
209
210Core::HID::NpadButton NPadData::GetCaptureButtonAssignment(std::size_t style_index) const {
211 return npad_button_assignment[style_index];
212}
213
214std::size_t NPadData::GetNpadCaptureButtonAssignmentList(
215 std::span<Core::HID::NpadButton> out_list) const {
216 for (std::size_t i = 0; i < out_list.size(); i++) {
217 Core::HID::NpadStyleSet style_set = GetStylesetByIndex(i);
218 if ((style_set & supported_npad_style_set) == Core::HID::NpadStyleSet::None ||
219 npad_button_assignment[i] == Core::HID::NpadButton::None) {
220 return i;
221 }
222 out_list[i] = npad_button_assignment[i];
223 }
224
225 return out_list.size();
226}
227
228} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad_data.h b/src/hid_core/resources/npad/npad_data.h
new file mode 100644
index 000000000..86bd3b81c
--- /dev/null
+++ b/src/hid_core/resources/npad/npad_data.h
@@ -0,0 +1,88 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <array>
7#include <span>
8
9#include "common/common_types.h"
10#include "core/hle/result.h"
11#include "hid_core/hid_types.h"
12#include "hid_core/resources/npad/npad_types.h"
13
14namespace Service::HID {
15
16struct NpadStatus {
17 union {
18 u32 raw{};
19
20 BitField<0, 1, u32> is_supported_styleset_set;
21 BitField<1, 1, u32> is_hold_type_set;
22 BitField<2, 1, u32> lr_assignment_mode;
23 BitField<3, 1, u32> assigning_single_on_sl_sr_press;
24 BitField<4, 1, u32> is_full_policy;
25 BitField<5, 1, u32> is_policy;
26 BitField<6, 1, u32> use_center_clamp;
27 BitField<7, 1, u32> system_ext_state;
28 };
29};
30static_assert(sizeof(NpadStatus) == 4, "NpadStatus is an invalid size");
31
32/// Handles Npad request from HID interfaces
33class NPadData final {
34public:
35 explicit NPadData();
36 ~NPadData();
37
38 NpadStatus GetNpadStatus() const;
39
40 void SetNpadAnalogStickUseCenterClamp(bool is_enabled);
41 bool GetNpadAnalogStickUseCenterClamp() const;
42
43 void SetNpadSystemExtStateEnabled(bool is_enabled);
44 bool GetNpadSystemExtState() const;
45
46 Result SetSupportedNpadIdType(std::span<const Core::HID::NpadIdType> list);
47 std::size_t GetSupportedNpadIdType(std::span<Core::HID::NpadIdType> out_list) const;
48 bool IsNpadIdTypeSupported(Core::HID::NpadIdType npad_id) const;
49
50 void SetNpadSystemCommonPolicy(bool is_full_policy);
51 void ClearNpadSystemCommonPolicy();
52
53 void SetNpadJoyHoldType(NpadJoyHoldType hold_type);
54 NpadJoyHoldType GetNpadJoyHoldType() const;
55
56 void SetHandheldActivationMode(NpadHandheldActivationMode activation_mode);
57 NpadHandheldActivationMode GetHandheldActivationMode() const;
58
59 void SetSupportedNpadStyleSet(Core::HID::NpadStyleSet style_set);
60 Core::HID::NpadStyleSet GetSupportedNpadStyleSet() const;
61 bool IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index) const;
62
63 void SetLrAssignmentMode(bool is_enabled);
64 bool GetLrAssignmentMode() const;
65
66 void SetAssigningSingleOnSlSrPress(bool is_enabled);
67 bool GetAssigningSingleOnSlSrPress() const;
68
69 void SetHomeProtectionEnabled(bool is_enabled, Core::HID::NpadIdType npad_id);
70 bool GetHomeProtectionEnabled(Core::HID::NpadIdType npad_id) const;
71
72 void SetCaptureButtonAssignment(Core::HID::NpadButton button_assignment,
73 std::size_t style_index);
74 Core::HID::NpadButton GetCaptureButtonAssignment(std::size_t style_index) const;
75 std::size_t GetNpadCaptureButtonAssignmentList(std::span<Core::HID::NpadButton> out_list) const;
76
77private:
78 NpadStatus status{};
79 Core::HID::NpadStyleSet supported_npad_style_set{Core::HID::NpadStyleSet::All};
80 NpadJoyHoldType npad_hold_type{NpadJoyHoldType::Vertical};
81 NpadHandheldActivationMode handheld_activation_mode{};
82 std::array<Core::HID::NpadIdType, MaxSupportedNpadIdTypes> supported_npad_id_types{};
83 std::array<Core::HID::NpadButton, StyleIndexCount> npad_button_assignment{};
84 std::size_t supported_npad_id_types_count{};
85 std::array<bool, MaxSupportedNpadIdTypes> is_unintended_home_button_input_protection{};
86};
87
88} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad_resource.cpp b/src/hid_core/resources/npad/npad_resource.cpp
new file mode 100644
index 000000000..ea9fc14ed
--- /dev/null
+++ b/src/hid_core/resources/npad/npad_resource.cpp
@@ -0,0 +1,687 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/kernel/k_event.h"
5#include "core/hle/kernel/k_readable_event.h"
6#include "hid_core/hid_result.h"
7#include "hid_core/hid_util.h"
8#include "hid_core/resources/npad/npad_resource.h"
9#include "hid_core/resources/npad/npad_types.h"
10
11namespace Service::HID {
12
13NPadResource::NPadResource(KernelHelpers::ServiceContext& context) : service_context{context} {}
14
15NPadResource::~NPadResource() = default;
16
17Result NPadResource::RegisterAppletResourceUserId(u64 aruid) {
18 const auto aruid_index = GetIndexFromAruid(aruid);
19 if (aruid_index < AruidIndexMax) {
20 return ResultAruidAlreadyRegistered;
21 }
22
23 std::size_t data_index = AruidIndexMax;
24 for (std::size_t i = 0; i < AruidIndexMax; i++) {
25 if (!state[i].flag.is_initialized) {
26 data_index = i;
27 break;
28 }
29 }
30
31 if (data_index == AruidIndexMax) {
32 return ResultAruidNoAvailableEntries;
33 }
34
35 auto& aruid_data = state[data_index];
36
37 aruid_data.aruid = aruid;
38 aruid_data.flag.is_initialized.Assign(true);
39
40 data_index = AruidIndexMax;
41 for (std::size_t i = 0; i < AruidIndexMax; i++) {
42 if (registration_list.flag[i] == RegistrationStatus::Initialized) {
43 if (registration_list.aruid[i] != aruid) {
44 continue;
45 }
46 data_index = i;
47 break;
48 }
49 // TODO: Don't Handle pending delete here
50 if (registration_list.flag[i] == RegistrationStatus::None ||
51 registration_list.flag[i] == RegistrationStatus::PendingDelete) {
52 data_index = i;
53 break;
54 }
55 }
56
57 if (data_index == AruidIndexMax) {
58 return ResultSuccess;
59 }
60
61 registration_list.flag[data_index] = RegistrationStatus::Initialized;
62 registration_list.aruid[data_index] = aruid;
63
64 return ResultSuccess;
65}
66
67void NPadResource::UnregisterAppletResourceUserId(u64 aruid) {
68 const u64 aruid_index = GetIndexFromAruid(aruid);
69
70 DestroyStyleSetUpdateEvents(aruid);
71 if (aruid_index < AruidIndexMax) {
72 state[aruid_index] = {};
73 registration_list.flag[aruid_index] = RegistrationStatus::PendingDelete;
74 }
75}
76
77void NPadResource::DestroyStyleSetUpdateEvents(u64 aruid) {
78 const u64 aruid_index = GetIndexFromAruid(aruid);
79
80 if (aruid_index >= AruidIndexMax) {
81 return;
82 }
83
84 for (auto& controller_state : state[aruid_index].controller_state) {
85 if (!controller_state.is_styleset_update_event_initialized) {
86 continue;
87 }
88 service_context.CloseEvent(controller_state.style_set_update_event);
89 controller_state.is_styleset_update_event_initialized = false;
90 }
91}
92
93Result NPadResource::Activate(u64 aruid) {
94 const u64 aruid_index = GetIndexFromAruid(aruid);
95
96 if (aruid_index >= AruidIndexMax) {
97 return ResultSuccess;
98 }
99
100 auto& state_data = state[aruid_index];
101
102 if (state_data.flag.is_assigned) {
103 return ResultAruidAlreadyRegistered;
104 }
105
106 state_data.flag.is_assigned.Assign(true);
107 state_data.data.ClearNpadSystemCommonPolicy();
108 state_data.npad_revision = NpadRevision::Revision0;
109 state_data.button_config = {};
110
111 if (active_data_aruid == aruid) {
112 default_hold_type = active_data.GetNpadJoyHoldType();
113 active_data.SetNpadJoyHoldType(default_hold_type);
114 }
115 return ResultSuccess;
116}
117
118Result NPadResource::Activate() {
119 if (ref_counter == std::numeric_limits<s32>::max() - 1) {
120 return ResultAppletResourceOverflow;
121 }
122 if (ref_counter == 0) {
123 RegisterAppletResourceUserId(SystemAruid);
124 Activate(SystemAruid);
125 }
126 ref_counter++;
127 return ResultSuccess;
128}
129
130Result NPadResource::Deactivate() {
131 if (ref_counter == 0) {
132 return ResultAppletResourceNotInitialized;
133 }
134
135 UnregisterAppletResourceUserId(SystemAruid);
136 ref_counter--;
137 return ResultSuccess;
138}
139
140NPadData* NPadResource::GetActiveData() {
141 return &active_data;
142}
143
144u64 NPadResource::GetActiveDataAruid() {
145 return active_data_aruid;
146}
147
148void NPadResource::SetAppletResourceUserId(u64 aruid) {
149 if (active_data_aruid == aruid) {
150 return;
151 }
152
153 active_data_aruid = aruid;
154 default_hold_type = active_data.GetNpadJoyHoldType();
155 const u64 aruid_index = GetIndexFromAruid(aruid);
156
157 if (aruid_index >= AruidIndexMax) {
158 return;
159 }
160
161 auto& data = state[aruid_index].data;
162 if (data.GetNpadStatus().is_policy || data.GetNpadStatus().is_full_policy) {
163 data.SetNpadJoyHoldType(default_hold_type);
164 }
165
166 active_data = data;
167 if (data.GetNpadStatus().is_hold_type_set) {
168 active_data.SetNpadJoyHoldType(default_hold_type);
169 }
170}
171
172std::size_t NPadResource::GetIndexFromAruid(u64 aruid) const {
173 for (std::size_t i = 0; i < AruidIndexMax; i++) {
174 if (registration_list.flag[i] == RegistrationStatus::Initialized &&
175 registration_list.aruid[i] == aruid) {
176 return i;
177 }
178 }
179 return AruidIndexMax;
180}
181
182Result NPadResource::ApplyNpadSystemCommonPolicy(u64 aruid, bool is_full_policy) {
183 const u64 aruid_index = GetIndexFromAruid(aruid);
184 if (aruid_index >= AruidIndexMax) {
185 return ResultNpadNotConnected;
186 }
187
188 auto& data = state[aruid_index].data;
189 data.SetNpadSystemCommonPolicy(is_full_policy);
190 data.SetNpadJoyHoldType(default_hold_type);
191 if (active_data_aruid == aruid) {
192 active_data.SetNpadSystemCommonPolicy(is_full_policy);
193 active_data.SetNpadJoyHoldType(default_hold_type);
194 }
195 return ResultSuccess;
196}
197
198Result NPadResource::ClearNpadSystemCommonPolicy(u64 aruid) {
199 const u64 aruid_index = GetIndexFromAruid(aruid);
200 if (aruid_index >= AruidIndexMax) {
201 return ResultNpadNotConnected;
202 }
203
204 state[aruid_index].data.ClearNpadSystemCommonPolicy();
205 if (active_data_aruid == aruid) {
206 active_data.ClearNpadSystemCommonPolicy();
207 }
208 return ResultSuccess;
209}
210
211Result NPadResource::SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet style_set) {
212 const u64 aruid_index = GetIndexFromAruid(aruid);
213 if (aruid_index >= AruidIndexMax) {
214 return ResultNpadNotConnected;
215 }
216
217 auto& data = state[aruid_index].data;
218 data.SetSupportedNpadStyleSet(style_set);
219 if (active_data_aruid == aruid) {
220 active_data.SetSupportedNpadStyleSet(style_set);
221 active_data.SetNpadJoyHoldType(data.GetNpadJoyHoldType());
222 }
223 return ResultSuccess;
224}
225
226Result NPadResource::GetSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_Set,
227 u64 aruid) const {
228 const u64 aruid_index = GetIndexFromAruid(aruid);
229 if (aruid_index >= AruidIndexMax) {
230 return ResultNpadNotConnected;
231 }
232
233 auto& data = state[aruid_index].data;
234 if (!data.GetNpadStatus().is_supported_styleset_set) {
235 return ResultUndefinedStyleset;
236 }
237
238 out_style_Set = data.GetSupportedNpadStyleSet();
239 return ResultSuccess;
240}
241
242Result NPadResource::GetMaskedSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_set,
243 u64 aruid) const {
244 if (aruid == SystemAruid) {
245 out_style_set = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
246 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
247 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Palma |
248 Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System;
249 return ResultSuccess;
250 }
251
252 const u64 aruid_index = GetIndexFromAruid(aruid);
253 if (aruid_index >= AruidIndexMax) {
254 return ResultNpadNotConnected;
255 }
256
257 auto& data = state[aruid_index].data;
258 if (!data.GetNpadStatus().is_supported_styleset_set) {
259 return ResultUndefinedStyleset;
260 }
261
262 Core::HID::NpadStyleSet mask{Core::HID::NpadStyleSet::None};
263 out_style_set = data.GetSupportedNpadStyleSet();
264
265 switch (state[aruid_index].npad_revision) {
266 case NpadRevision::Revision1:
267 mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
268 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
269 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc |
270 Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::SystemExt |
271 Core::HID::NpadStyleSet::System;
272 break;
273 case NpadRevision::Revision2:
274 mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
275 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
276 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc |
277 Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark |
278 Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System;
279 break;
280 case NpadRevision::Revision3:
281 mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
282 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
283 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc |
284 Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark |
285 Core::HID::NpadStyleSet::HandheldLark | Core::HID::NpadStyleSet::Lucia |
286 Core::HID::NpadStyleSet::Lagoon | Core::HID::NpadStyleSet::Lager |
287 Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System;
288 break;
289 default:
290 mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
291 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
292 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::SystemExt |
293 Core::HID::NpadStyleSet::System;
294 break;
295 }
296
297 out_style_set = out_style_set & mask;
298 return ResultSuccess;
299}
300
301Result NPadResource::GetAvailableStyleset(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const {
302 const u64 aruid_index = GetIndexFromAruid(aruid);
303 if (aruid_index >= AruidIndexMax) {
304 return ResultNpadNotConnected;
305 }
306
307 auto& data = state[aruid_index].data;
308 if (!data.GetNpadStatus().is_supported_styleset_set) {
309 return ResultUndefinedStyleset;
310 }
311
312 Core::HID::NpadStyleSet mask{Core::HID::NpadStyleSet::None};
313 out_style_set = data.GetSupportedNpadStyleSet();
314
315 switch (state[aruid_index].npad_revision) {
316 case NpadRevision::Revision1:
317 mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
318 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
319 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc |
320 Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::SystemExt |
321 Core::HID::NpadStyleSet::System;
322 break;
323 case NpadRevision::Revision2:
324 mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
325 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
326 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc |
327 Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark |
328 Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System;
329 break;
330 case NpadRevision::Revision3:
331 mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
332 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
333 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc |
334 Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark |
335 Core::HID::NpadStyleSet::HandheldLark | Core::HID::NpadStyleSet::Lucia |
336 Core::HID::NpadStyleSet::Lagoon | Core::HID::NpadStyleSet::Lager |
337 Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System;
338 break;
339 default:
340 mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld |
341 Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft |
342 Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::SystemExt |
343 Core::HID::NpadStyleSet::System;
344 break;
345 }
346
347 out_style_set = out_style_set & mask;
348 return ResultSuccess;
349}
350
351NpadRevision NPadResource::GetNpadRevision(u64 aruid) const {
352 const u64 aruid_index = GetIndexFromAruid(aruid);
353 if (aruid_index >= AruidIndexMax) {
354 return NpadRevision::Revision0;
355 }
356
357 return state[aruid_index].npad_revision;
358}
359
360Result NPadResource::IsSupportedNpadStyleSet(bool& is_set, u64 aruid) {
361 const u64 aruid_index = GetIndexFromAruid(aruid);
362 if (aruid_index >= AruidIndexMax) {
363 return ResultNpadNotConnected;
364 }
365
366 is_set = state[aruid_index].data.GetNpadStatus().is_supported_styleset_set.Value() != 0;
367 return ResultSuccess;
368}
369
370Result NPadResource::SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type) {
371 const u64 aruid_index = GetIndexFromAruid(aruid);
372 if (aruid_index >= AruidIndexMax) {
373 return ResultNpadNotConnected;
374 }
375
376 state[aruid_index].data.SetNpadJoyHoldType(hold_type);
377 if (active_data_aruid == aruid) {
378 active_data.SetNpadJoyHoldType(hold_type);
379 }
380 return ResultSuccess;
381}
382
383Result NPadResource::GetNpadJoyHoldType(NpadJoyHoldType& hold_type, u64 aruid) const {
384 const u64 aruid_index = GetIndexFromAruid(aruid);
385 if (aruid_index >= AruidIndexMax) {
386 return ResultNpadNotConnected;
387 }
388
389 auto& data = state[aruid_index].data;
390 if (data.GetNpadStatus().is_policy || data.GetNpadStatus().is_full_policy) {
391 hold_type = active_data.GetNpadJoyHoldType();
392 return ResultSuccess;
393 }
394 hold_type = data.GetNpadJoyHoldType();
395 return ResultSuccess;
396}
397
398Result NPadResource::SetNpadHandheldActivationMode(u64 aruid,
399 NpadHandheldActivationMode activation_mode) {
400 const u64 aruid_index = GetIndexFromAruid(aruid);
401 if (aruid_index >= AruidIndexMax) {
402 return ResultNpadNotConnected;
403 }
404
405 state[aruid_index].data.SetHandheldActivationMode(activation_mode);
406 if (active_data_aruid == aruid) {
407 active_data.SetHandheldActivationMode(activation_mode);
408 }
409 return ResultSuccess;
410}
411
412Result NPadResource::GetNpadHandheldActivationMode(NpadHandheldActivationMode& activation_mode,
413 u64 aruid) const {
414 const u64 aruid_index = GetIndexFromAruid(aruid);
415 if (aruid_index >= AruidIndexMax) {
416 return ResultNpadNotConnected;
417 }
418
419 activation_mode = state[aruid_index].data.GetHandheldActivationMode();
420 return ResultSuccess;
421}
422
423Result NPadResource::SetSupportedNpadIdType(
424 u64 aruid, std::span<const Core::HID::NpadIdType> supported_npad_list) {
425 const u64 aruid_index = GetIndexFromAruid(aruid);
426 if (aruid_index >= AruidIndexMax) {
427 return ResultNpadNotConnected;
428 }
429 if (supported_npad_list.size() > MaxSupportedNpadIdTypes) {
430 return ResultInvalidArraySize;
431 }
432
433 Result result = state[aruid_index].data.SetSupportedNpadIdType(supported_npad_list);
434 if (result.IsSuccess() && active_data_aruid == aruid) {
435 result = active_data.SetSupportedNpadIdType(supported_npad_list);
436 }
437
438 return result;
439}
440
441bool NPadResource::IsControllerSupported(u64 aruid, Core::HID::NpadStyleIndex style_index) const {
442 const u64 aruid_index = GetIndexFromAruid(aruid);
443 if (aruid_index >= AruidIndexMax) {
444 return false;
445 }
446 return state[aruid_index].data.IsNpadStyleIndexSupported(style_index);
447}
448
449Result NPadResource::SetLrAssignmentMode(u64 aruid, bool is_enabled) {
450 const u64 aruid_index = GetIndexFromAruid(aruid);
451 if (aruid_index >= AruidIndexMax) {
452 return ResultNpadNotConnected;
453 }
454
455 state[aruid_index].data.SetLrAssignmentMode(is_enabled);
456 if (active_data_aruid == aruid) {
457 active_data.SetLrAssignmentMode(is_enabled);
458 }
459 return ResultSuccess;
460}
461
462Result NPadResource::GetLrAssignmentMode(bool& is_enabled, u64 aruid) const {
463 const u64 aruid_index = GetIndexFromAruid(aruid);
464 if (aruid_index >= AruidIndexMax) {
465 return ResultNpadNotConnected;
466 }
467
468 is_enabled = state[aruid_index].data.GetLrAssignmentMode();
469 return ResultSuccess;
470}
471
472Result NPadResource::SetAssigningSingleOnSlSrPress(u64 aruid, bool is_enabled) {
473 const u64 aruid_index = GetIndexFromAruid(aruid);
474 if (aruid_index >= AruidIndexMax) {
475 return ResultNpadNotConnected;
476 }
477
478 state[aruid_index].data.SetAssigningSingleOnSlSrPress(is_enabled);
479 if (active_data_aruid == aruid) {
480 active_data.SetAssigningSingleOnSlSrPress(is_enabled);
481 }
482 return ResultSuccess;
483}
484
485Result NPadResource::IsAssigningSingleOnSlSrPressEnabled(bool& is_enabled, u64 aruid) const {
486 const u64 aruid_index = GetIndexFromAruid(aruid);
487 if (aruid_index >= AruidIndexMax) {
488 return ResultNpadNotConnected;
489 }
490
491 is_enabled = state[aruid_index].data.GetAssigningSingleOnSlSrPress();
492 return ResultSuccess;
493}
494
495Result NPadResource::AcquireNpadStyleSetUpdateEventHandle(u64 aruid,
496 Kernel::KReadableEvent** out_event,
497 Core::HID::NpadIdType npad_id) {
498 const u64 aruid_index = GetIndexFromAruid(aruid);
499 if (aruid_index >= AruidIndexMax) {
500 return ResultNpadNotConnected;
501 }
502
503 auto& controller_state = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)];
504 if (!controller_state.is_styleset_update_event_initialized) {
505 // Auto clear = true
506 controller_state.style_set_update_event =
507 service_context.CreateEvent("NpadResource:StylesetUpdateEvent");
508
509 // Assume creating the event succeeds otherwise crash the system here
510 controller_state.is_styleset_update_event_initialized = true;
511 }
512
513 *out_event = &controller_state.style_set_update_event->GetReadableEvent();
514
515 if (controller_state.is_styleset_update_event_initialized) {
516 controller_state.style_set_update_event->Signal();
517 }
518
519 return ResultSuccess;
520}
521
522Result NPadResource::SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType npad_id) {
523 const u64 aruid_index = GetIndexFromAruid(aruid);
524 if (aruid_index >= AruidIndexMax) {
525 return ResultNpadNotConnected;
526 }
527 auto controller = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)];
528 if (controller.is_styleset_update_event_initialized) {
529 controller.style_set_update_event->Signal();
530 }
531 return ResultSuccess;
532}
533
534Result NPadResource::GetHomeProtectionEnabled(bool& is_enabled, u64 aruid,
535 Core::HID::NpadIdType npad_id) const {
536 const u64 aruid_index = GetIndexFromAruid(aruid);
537 if (aruid_index >= AruidIndexMax) {
538 return ResultNpadNotConnected;
539 }
540
541 is_enabled = state[aruid_index].data.GetHomeProtectionEnabled(npad_id);
542 return ResultSuccess;
543}
544
545Result NPadResource::SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id,
546 bool is_enabled) {
547 const u64 aruid_index = GetIndexFromAruid(aruid);
548 if (aruid_index >= AruidIndexMax) {
549 return ResultNpadNotConnected;
550 }
551
552 state[aruid_index].data.SetHomeProtectionEnabled(is_enabled, npad_id);
553 if (active_data_aruid == aruid) {
554 active_data.SetHomeProtectionEnabled(is_enabled, npad_id);
555 }
556 return ResultSuccess;
557}
558
559Result NPadResource::SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled) {
560 const u64 aruid_index = GetIndexFromAruid(aruid);
561 if (aruid_index >= AruidIndexMax) {
562 return ResultNpadNotConnected;
563 }
564
565 state[aruid_index].data.SetNpadAnalogStickUseCenterClamp(is_enabled);
566 if (active_data_aruid == aruid) {
567 active_data.SetNpadAnalogStickUseCenterClamp(is_enabled);
568 }
569 return ResultSuccess;
570}
571
572Result NPadResource::SetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index,
573 Core::HID::NpadButton button_config) {
574 const u64 aruid_index = GetIndexFromAruid(aruid);
575 if (aruid_index >= AruidIndexMax) {
576 return ResultNpadNotConnected;
577 }
578
579 state[aruid_index].button_config[NpadIdTypeToIndex(npad_id)][index] = button_config;
580 return ResultSuccess;
581}
582
583Core::HID::NpadButton NPadResource::GetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id,
584 std::size_t index, Core::HID::NpadButton mask,
585 bool is_enabled) {
586 const u64 aruid_index = GetIndexFromAruid(aruid);
587 if (aruid_index >= AruidIndexMax) {
588 return Core::HID::NpadButton::None;
589 }
590
591 auto& button_config = state[aruid_index].button_config[NpadIdTypeToIndex(npad_id)][index];
592 if (is_enabled) {
593 button_config = button_config | mask;
594 return button_config;
595 }
596
597 button_config = Core::HID::NpadButton::None;
598 return Core::HID::NpadButton::None;
599}
600
601void NPadResource::ResetButtonConfig() {
602 for (auto& selected_state : state) {
603 selected_state.button_config = {};
604 }
605}
606
607Result NPadResource::SetNpadCaptureButtonAssignment(u64 aruid,
608 Core::HID::NpadStyleSet npad_style_set,
609 Core::HID::NpadButton button_assignment) {
610 const u64 aruid_index = GetIndexFromAruid(aruid);
611 if (aruid_index >= AruidIndexMax) {
612 return ResultNpadNotConnected;
613 }
614
615 // Must be a power of two
616 const auto raw_styleset = static_cast<u32>(npad_style_set);
617 if (raw_styleset == 0 && (raw_styleset & (raw_styleset - 1)) != 0) {
618 return ResultMultipleStyleSetSelected;
619 }
620
621 std::size_t style_index{};
622 Core::HID::NpadStyleSet style_selected{};
623 for (style_index = 0; style_index < StyleIndexCount; ++style_index) {
624 style_selected = GetStylesetByIndex(style_index);
625 if (npad_style_set == style_selected) {
626 break;
627 }
628 }
629
630 if (style_selected == Core::HID::NpadStyleSet::None) {
631 return ResultMultipleStyleSetSelected;
632 }
633
634 state[aruid_index].data.SetCaptureButtonAssignment(button_assignment, style_index);
635 if (active_data_aruid == aruid) {
636 active_data.SetCaptureButtonAssignment(button_assignment, style_index);
637 }
638 return ResultSuccess;
639}
640
641Result NPadResource::ClearNpadCaptureButtonAssignment(u64 aruid) {
642 const u64 aruid_index = GetIndexFromAruid(aruid);
643 if (aruid_index >= AruidIndexMax) {
644 return ResultNpadNotConnected;
645 }
646
647 for (std::size_t i = 0; i < StyleIndexCount; i++) {
648 state[aruid_index].data.SetCaptureButtonAssignment(Core::HID::NpadButton::None, i);
649 if (active_data_aruid == aruid) {
650 active_data.SetCaptureButtonAssignment(Core::HID::NpadButton::None, i);
651 }
652 }
653 return ResultSuccess;
654}
655
656std::size_t NPadResource::GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list,
657 u64 aruid) const {
658 const u64 aruid_index = GetIndexFromAruid(aruid);
659 if (aruid_index >= AruidIndexMax) {
660 return 0;
661 }
662 return state[aruid_index].data.GetNpadCaptureButtonAssignmentList(out_list);
663}
664
665void NPadResource::SetNpadRevision(u64 aruid, NpadRevision revision) {
666 const u64 aruid_index = GetIndexFromAruid(aruid);
667 if (aruid_index >= AruidIndexMax) {
668 return;
669 }
670
671 state[aruid_index].npad_revision = revision;
672}
673
674Result NPadResource::SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled) {
675 const u64 aruid_index = GetIndexFromAruid(aruid);
676 if (aruid_index >= AruidIndexMax) {
677 return ResultNpadNotConnected;
678 }
679
680 state[aruid_index].data.SetNpadAnalogStickUseCenterClamp(is_enabled);
681 if (active_data_aruid == aruid) {
682 active_data.SetNpadAnalogStickUseCenterClamp(is_enabled);
683 }
684 return ResultSuccess;
685}
686
687} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad_resource.h b/src/hid_core/resources/npad/npad_resource.h
new file mode 100644
index 000000000..aed89eec6
--- /dev/null
+++ b/src/hid_core/resources/npad/npad_resource.h
@@ -0,0 +1,132 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <array>
7#include <mutex>
8#include <span>
9
10#include "common/common_types.h"
11#include "core/hle/result.h"
12#include "core/hle/service/kernel_helpers.h"
13#include "hid_core/hid_types.h"
14#include "hid_core/resources/applet_resource.h"
15#include "hid_core/resources/npad/npad_data.h"
16#include "hid_core/resources/npad/npad_types.h"
17
18namespace Core {
19class System;
20}
21
22namespace Kernel {
23class KReadableEvent;
24}
25
26namespace Service::HID {
27struct DataStatusFlag;
28
29struct NpadControllerState {
30 bool is_styleset_update_event_initialized{};
31 INSERT_PADDING_BYTES(0x7);
32 Kernel::KEvent* style_set_update_event{nullptr};
33 INSERT_PADDING_BYTES(0x27);
34};
35
36struct NpadState {
37 DataStatusFlag flag{};
38 u64 aruid{};
39 NPadData data{};
40 std::array<std::array<Core::HID::NpadButton, StyleIndexCount>, MaxSupportedNpadIdTypes>
41 button_config;
42 std::array<NpadControllerState, MaxSupportedNpadIdTypes> controller_state;
43 NpadRevision npad_revision;
44};
45
46/// Handles Npad request from HID interfaces
47class NPadResource final {
48public:
49 explicit NPadResource(KernelHelpers::ServiceContext& context);
50 ~NPadResource();
51
52 NPadData* GetActiveData();
53 u64 GetActiveDataAruid();
54
55 Result RegisterAppletResourceUserId(u64 aruid);
56 void UnregisterAppletResourceUserId(u64 aruid);
57
58 void DestroyStyleSetUpdateEvents(u64 aruid);
59
60 Result Activate(u64 aruid);
61 Result Activate();
62 Result Deactivate();
63
64 void SetAppletResourceUserId(u64 aruid);
65 std::size_t GetIndexFromAruid(u64 aruid) const;
66
67 Result ApplyNpadSystemCommonPolicy(u64 aruid, bool is_full_policy);
68 Result ClearNpadSystemCommonPolicy(u64 aruid);
69
70 Result SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet style_set);
71 Result GetSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_Set, u64 aruid) const;
72 Result GetMaskedSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const;
73 Result GetAvailableStyleset(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const;
74
75 NpadRevision GetNpadRevision(u64 aruid) const;
76 void SetNpadRevision(u64 aruid, NpadRevision revision);
77
78 Result IsSupportedNpadStyleSet(bool& is_set, u64 aruid);
79
80 Result SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type);
81 Result GetNpadJoyHoldType(NpadJoyHoldType& hold_type, u64 aruid) const;
82
83 Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode activation_mode);
84 Result GetNpadHandheldActivationMode(NpadHandheldActivationMode& activation_mode,
85 u64 aruid) const;
86
87 Result SetSupportedNpadIdType(u64 aruid,
88 std::span<const Core::HID::NpadIdType> supported_npad_list);
89 bool IsControllerSupported(u64 aruid, Core::HID::NpadStyleIndex style_index) const;
90
91 Result SetLrAssignmentMode(u64 aruid, bool is_enabled);
92 Result GetLrAssignmentMode(bool& is_enabled, u64 aruid) const;
93
94 Result SetAssigningSingleOnSlSrPress(u64 aruid, bool is_enabled);
95 Result IsAssigningSingleOnSlSrPressEnabled(bool& is_enabled, u64 aruid) const;
96
97 Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
98 Core::HID::NpadIdType npad_id);
99 Result SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType npad_id);
100
101 Result GetHomeProtectionEnabled(bool& is_enabled, u64 aruid,
102 Core::HID::NpadIdType npad_id) const;
103 Result SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id, bool is_enabled);
104
105 Result SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled);
106
107 Result SetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index,
108 Core::HID::NpadButton button_config);
109 Core::HID::NpadButton GetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id,
110 std::size_t index, Core::HID::NpadButton mask,
111 bool is_enabled);
112 void ResetButtonConfig();
113
114 Result SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set,
115 Core::HID::NpadButton button_assignment);
116 Result ClearNpadCaptureButtonAssignment(u64 aruid);
117 std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list,
118 u64 aruid) const;
119
120 Result SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled);
121
122private:
123 NPadData active_data{};
124 AruidRegisterList registration_list{};
125 std::array<NpadState, AruidIndexMax> state{};
126 u64 active_data_aruid{};
127 NpadJoyHoldType default_hold_type{};
128 s32 ref_counter{};
129
130 KernelHelpers::ServiceContext& service_context;
131};
132} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/npad_types.h b/src/hid_core/resources/npad/npad_types.h
index a5ce2562b..a02f9cf16 100644
--- a/src/core/hle/service/hid/controllers/types/npad_types.h
+++ b/src/hid_core/resources/npad/npad_types.h
@@ -6,10 +6,11 @@
6#include "common/bit_field.h" 6#include "common/bit_field.h"
7#include "common/common_funcs.h" 7#include "common/common_funcs.h"
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hid/hid_types.h" 9#include "hid_core/hid_types.h"
10 10
11namespace Service::HID { 11namespace Service::HID {
12static constexpr std::size_t NpadCount = 10; 12static constexpr std::size_t MaxSupportedNpadIdTypes = 10;
13static constexpr std::size_t StyleIndexCount = 7;
13 14
14// This is nn::hid::NpadJoyHoldType 15// This is nn::hid::NpadJoyHoldType
15enum class NpadJoyHoldType : u64 { 16enum class NpadJoyHoldType : u64 {
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/hid_core/resources/palma/palma.cpp
index aa0454b5e..ea4a291fd 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/hid_core/resources/palma/palma.cpp
@@ -2,13 +2,12 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/hid/emulated_controller.h"
6#include "core/hid/hid_core.h"
7#include "core/hid/hid_types.h"
8#include "core/hle/kernel/k_event.h" 5#include "core/hle/kernel/k_event.h"
9#include "core/hle/kernel/k_readable_event.h" 6#include "core/hle/kernel/k_readable_event.h"
10#include "core/hle/service/hid/controllers/palma.h"
11#include "core/hle/service/kernel_helpers.h" 7#include "core/hle/service/kernel_helpers.h"
8#include "hid_core/frontend/emulated_controller.h"
9#include "hid_core/hid_core.h"
10#include "hid_core/resources/palma/palma.h"
12 11
13namespace Service::HID { 12namespace Service::HID {
14 13
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/hid_core/resources/palma/palma.h
index 73884230d..60259c3d8 100644
--- a/src/core/hle/service/hid/controllers/palma.h
+++ b/src/hid_core/resources/palma/palma.h
@@ -6,8 +6,9 @@
6#include <array> 6#include <array>
7#include "common/common_funcs.h" 7#include "common/common_funcs.h"
8#include "common/typed_address.h" 8#include "common/typed_address.h"
9#include "core/hle/service/hid/controllers/controller_base.h" 9#include "hid_core/hid_result.h"
10#include "core/hle/service/hid/errors.h" 10#include "hid_core/hid_types.h"
11#include "hid_core/resources/controller_base.h"
11 12
12namespace Kernel { 13namespace Kernel {
13class KEvent; 14class KEvent;
diff --git a/src/core/hle/service/hid/ring_lifo.h b/src/hid_core/resources/ring_lifo.h
index 0816784e0..0816784e0 100644
--- a/src/core/hle/service/hid/ring_lifo.h
+++ b/src/hid_core/resources/ring_lifo.h
diff --git a/src/core/hle/service/hid/controllers/types/shared_memory_format.h b/src/hid_core/resources/shared_memory_format.h
index 2986c113e..2ae0004ba 100644
--- a/src/core/hle/service/hid/controllers/types/shared_memory_format.h
+++ b/src/hid_core/resources/shared_memory_format.h
@@ -6,13 +6,13 @@
6#include "common/common_funcs.h" 6#include "common/common_funcs.h"
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/vector_math.h" 8#include "common/vector_math.h"
9#include "core/hid/hid_types.h" 9#include "hid_core/hid_types.h"
10#include "core/hle/service/hid//controllers/types/debug_pad_types.h" 10#include "hid_core/resources/debug_pad/debug_pad_types.h"
11#include "core/hle/service/hid//controllers/types/keyboard_types.h" 11#include "hid_core/resources/keyboard/keyboard_types.h"
12#include "core/hle/service/hid//controllers/types/mouse_types.h" 12#include "hid_core/resources/mouse/mouse_types.h"
13#include "core/hle/service/hid//controllers/types/npad_types.h" 13#include "hid_core/resources/npad/npad_types.h"
14#include "core/hle/service/hid//controllers/types/touch_types.h" 14#include "hid_core/resources/ring_lifo.h"
15#include "core/hle/service/hid/ring_lifo.h" 15#include "hid_core/resources/touch_screen/touch_types.h"
16 16
17namespace Service::HID { 17namespace Service::HID {
18static const std::size_t HidEntryCount = 17; 18static const std::size_t HidEntryCount = 17;
@@ -171,7 +171,7 @@ static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is
171 171
172// This is nn::hid::detail::NpadSharedMemoryFormat 172// This is nn::hid::detail::NpadSharedMemoryFormat
173struct NpadSharedMemoryFormat { 173struct NpadSharedMemoryFormat {
174 std::array<NpadSharedMemoryEntry, NpadCount> npad_entry; 174 std::array<NpadSharedMemoryEntry, MaxSupportedNpadIdTypes> npad_entry;
175}; 175};
176static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000, 176static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000,
177 "NpadSharedMemoryFormat is an invalid size"); 177 "NpadSharedMemoryFormat is an invalid size");
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp b/src/hid_core/resources/shared_memory_holder.cpp
index 0bc5169c6..ada593d8b 100644
--- a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp
+++ b/src/hid_core/resources/shared_memory_holder.cpp
@@ -3,10 +3,10 @@
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/kernel/k_shared_memory.h" 5#include "core/hle/kernel/k_shared_memory.h"
6#include "core/hle/service/hid/controllers/applet_resource.h" 6#include "hid_core/hid_result.h"
7#include "core/hle/service/hid/controllers/shared_memory_holder.h" 7#include "hid_core/resources/applet_resource.h"
8#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 8#include "hid_core/resources/shared_memory_format.h"
9#include "core/hle/service/hid/errors.h" 9#include "hid_core/resources/shared_memory_holder.h"
10 10
11namespace Service::HID { 11namespace Service::HID {
12SharedMemoryHolder::SharedMemoryHolder() {} 12SharedMemoryHolder::SharedMemoryHolder() {}
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.h b/src/hid_core/resources/shared_memory_holder.h
index 943407c00..943407c00 100644
--- a/src/core/hle/service/hid/controllers/shared_memory_holder.h
+++ b/src/hid_core/resources/shared_memory_holder.h
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/hid_core/resources/six_axis/console_six_axis.cpp
index 8eba2c292..4f733cc76 100644
--- a/src/core/hle/service/hid/controllers/console_six_axis.cpp
+++ b/src/hid_core/resources/six_axis/console_six_axis.cpp
@@ -2,10 +2,10 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/hid/emulated_console.h" 5#include "hid_core/frontend/emulated_console.h"
6#include "core/hid/hid_core.h" 6#include "hid_core/hid_core.h"
7#include "core/hle/service/hid/controllers/console_six_axis.h" 7#include "hid_core/resources/shared_memory_format.h"
8#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 8#include "hid_core/resources/six_axis/console_six_axis.h"
9 9
10namespace Service::HID { 10namespace Service::HID {
11 11
@@ -20,10 +20,11 @@ void ConsoleSixAxis::OnInit() {}
20void ConsoleSixAxis::OnRelease() {} 20void ConsoleSixAxis::OnRelease() {}
21 21
22void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 22void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
23 std::scoped_lock shared_lock{*shared_mutex};
23 const u64 aruid = applet_resource->GetActiveAruid(); 24 const u64 aruid = applet_resource->GetActiveAruid();
24 auto* data = applet_resource->GetAruidData(aruid); 25 auto* data = applet_resource->GetAruidData(aruid);
25 26
26 if (data == nullptr) { 27 if (data == nullptr || !data->flag.is_assigned) {
27 return; 28 return;
28 } 29 }
29 30
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/hid_core/resources/six_axis/console_six_axis.h
index e3351f83c..013b2e93b 100644
--- a/src/core/hle/service/hid/controllers/console_six_axis.h
+++ b/src/hid_core/resources/six_axis/console_six_axis.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/resources/controller_base.h"
7 7
8namespace Core::HID { 8namespace Core::HID {
9class EmulatedConsole; 9class EmulatedConsole;
diff --git a/src/core/hle/service/hid/controllers/seven_six_axis.cpp b/src/hid_core/resources/six_axis/seven_six_axis.cpp
index 495568484..d84ef31e1 100644
--- a/src/core/hle/service/hid/controllers/seven_six_axis.cpp
+++ b/src/hid_core/resources/six_axis/seven_six_axis.cpp
@@ -6,11 +6,11 @@
6#include "core/core.h" 6#include "core/core.h"
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/frontend/emu_window.h" 8#include "core/frontend/emu_window.h"
9#include "core/hid/emulated_console.h"
10#include "core/hid/emulated_devices.h"
11#include "core/hid/hid_core.h"
12#include "core/hle/service/hid/controllers/seven_six_axis.h"
13#include "core/memory.h" 9#include "core/memory.h"
10#include "hid_core/frontend/emulated_console.h"
11#include "hid_core/frontend/emulated_devices.h"
12#include "hid_core/hid_core.h"
13#include "hid_core/resources/six_axis/seven_six_axis.h"
14 14
15namespace Service::HID { 15namespace Service::HID {
16SevenSixAxis::SevenSixAxis(Core::System& system_) 16SevenSixAxis::SevenSixAxis(Core::System& system_)
diff --git a/src/core/hle/service/hid/controllers/seven_six_axis.h b/src/hid_core/resources/six_axis/seven_six_axis.h
index 40e3f5d12..0a26c77c9 100644
--- a/src/core/hle/service/hid/controllers/seven_six_axis.h
+++ b/src/hid_core/resources/six_axis/seven_six_axis.h
@@ -6,8 +6,8 @@
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "common/quaternion.h" 7#include "common/quaternion.h"
8#include "common/typed_address.h" 8#include "common/typed_address.h"
9#include "core/hle/service/hid/controllers/controller_base.h" 9#include "hid_core/resources/controller_base.h"
10#include "core/hle/service/hid/ring_lifo.h" 10#include "hid_core/resources/ring_lifo.h"
11 11
12namespace Core { 12namespace Core {
13class System; 13class System;
diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/hid_core/resources/six_axis/six_axis.cpp
index a5a67dea6..8a9677c50 100644
--- a/src/core/hle/service/hid/controllers/six_axis.cpp
+++ b/src/hid_core/resources/six_axis/six_axis.cpp
@@ -3,13 +3,13 @@
3 3
4#include "common/common_types.h" 4#include "common/common_types.h"
5#include "core/core_timing.h" 5#include "core/core_timing.h"
6#include "core/hid/emulated_controller.h" 6#include "hid_core/frontend/emulated_controller.h"
7#include "core/hid/hid_core.h" 7#include "hid_core/hid_core.h"
8#include "core/hle/service/hid/controllers/npad.h" 8#include "hid_core/hid_result.h"
9#include "core/hle/service/hid/controllers/six_axis.h" 9#include "hid_core/hid_util.h"
10#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 10#include "hid_core/resources/npad/npad.h"
11#include "core/hle/service/hid/errors.h" 11#include "hid_core/resources/shared_memory_format.h"
12#include "core/hle/service/hid/hid_util.h" 12#include "hid_core/resources/six_axis/six_axis.h"
13 13
14namespace Service::HID { 14namespace Service::HID {
15 15
@@ -27,10 +27,11 @@ void SixAxis::OnInit() {}
27void SixAxis::OnRelease() {} 27void SixAxis::OnRelease() {}
28 28
29void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 29void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
30 std::scoped_lock shared_lock{*shared_mutex};
30 const u64 aruid = applet_resource->GetActiveAruid(); 31 const u64 aruid = applet_resource->GetActiveAruid();
31 auto* data = applet_resource->GetAruidData(aruid); 32 auto* data = applet_resource->GetAruidData(aruid);
32 33
33 if (data == nullptr) { 34 if (data == nullptr || !data->flag.is_assigned) {
34 return; 35 return;
35 } 36 }
36 37
diff --git a/src/core/hle/service/hid/controllers/six_axis.h b/src/hid_core/resources/six_axis/six_axis.h
index 4c4f5dc7b..1054e1b27 100644
--- a/src/core/hle/service/hid/controllers/six_axis.h
+++ b/src/hid_core/resources/six_axis/six_axis.h
@@ -4,9 +4,9 @@
4#pragma once 4#pragma once
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hid/hid_types.h" 7#include "hid_core/hid_types.h"
8#include "core/hle/service/hid/controllers/controller_base.h" 8#include "hid_core/resources/controller_base.h"
9#include "core/hle/service/hid/ring_lifo.h" 9#include "hid_core/resources/ring_lifo.h"
10 10
11namespace Core::HID { 11namespace Core::HID {
12class EmulatedController; 12class EmulatedController;
diff --git a/src/core/hle/service/hid/controllers/capture_button.cpp b/src/hid_core/resources/system_buttons/capture_button.cpp
index 8b486fcb5..70973ae25 100644
--- a/src/core/hle/service/hid/controllers/capture_button.cpp
+++ b/src/hid_core/resources/system_buttons/capture_button.cpp
@@ -2,9 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/hle/service/hid/controllers/applet_resource.h" 5#include "hid_core/resources/applet_resource.h"
6#include "core/hle/service/hid/controllers/capture_button.h" 6#include "hid_core/resources/shared_memory_format.h"
7#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 7#include "hid_core/resources/system_buttons/capture_button.h"
8 8
9namespace Service::HID { 9namespace Service::HID {
10 10
@@ -21,10 +21,11 @@ void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
21 return; 21 return;
22 } 22 }
23 23
24 std::scoped_lock shared_lock{*shared_mutex};
24 const u64 aruid = applet_resource->GetActiveAruid(); 25 const u64 aruid = applet_resource->GetActiveAruid();
25 auto* data = applet_resource->GetAruidData(aruid); 26 auto* data = applet_resource->GetAruidData(aruid);
26 27
27 if (data == nullptr) { 28 if (data == nullptr || !data->flag.is_assigned) {
28 return; 29 return;
29 } 30 }
30 31
diff --git a/src/core/hle/service/hid/controllers/capture_button.h b/src/hid_core/resources/system_buttons/capture_button.h
index dcc4715c5..ad95d7cad 100644
--- a/src/core/hle/service/hid/controllers/capture_button.h
+++ b/src/hid_core/resources/system_buttons/capture_button.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/resources/controller_base.h"
7 7
8namespace Service::HID { 8namespace Service::HID {
9 9
diff --git a/src/core/hle/service/hid/controllers/home_button.cpp b/src/hid_core/resources/system_buttons/home_button.cpp
index 71dd9bc08..f9c1f44b5 100644
--- a/src/core/hle/service/hid/controllers/home_button.cpp
+++ b/src/hid_core/resources/system_buttons/home_button.cpp
@@ -2,9 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/hle/service/hid/controllers/applet_resource.h" 5#include "hid_core/resources/applet_resource.h"
6#include "core/hle/service/hid/controllers/home_button.h" 6#include "hid_core/resources/shared_memory_format.h"
7#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 7#include "hid_core/resources/system_buttons/home_button.h"
8 8
9namespace Service::HID { 9namespace Service::HID {
10 10
@@ -21,10 +21,11 @@ void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
21 return; 21 return;
22 } 22 }
23 23
24 std::scoped_lock shared_lock{*shared_mutex};
24 const u64 aruid = applet_resource->GetActiveAruid(); 25 const u64 aruid = applet_resource->GetActiveAruid();
25 auto* data = applet_resource->GetAruidData(aruid); 26 auto* data = applet_resource->GetAruidData(aruid);
26 27
27 if (data == nullptr) { 28 if (data == nullptr || !data->flag.is_assigned) {
28 return; 29 return;
29 } 30 }
30 31
diff --git a/src/core/hle/service/hid/controllers/home_button.h b/src/hid_core/resources/system_buttons/home_button.h
index e91c2aa5d..ecf8327f4 100644
--- a/src/core/hle/service/hid/controllers/home_button.h
+++ b/src/hid_core/resources/system_buttons/home_button.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/resources/controller_base.h"
7 7
8namespace Service::HID { 8namespace Service::HID {
9 9
diff --git a/src/core/hle/service/hid/controllers/sleep_button.cpp b/src/hid_core/resources/system_buttons/sleep_button.cpp
index 978dc4c1f..22adf501f 100644
--- a/src/core/hle/service/hid/controllers/sleep_button.cpp
+++ b/src/hid_core/resources/system_buttons/sleep_button.cpp
@@ -2,9 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/hle/service/hid/controllers/applet_resource.h" 5#include "hid_core/resources/applet_resource.h"
6#include "core/hle/service/hid/controllers/sleep_button.h" 6#include "hid_core/resources/shared_memory_format.h"
7#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 7#include "hid_core/resources/system_buttons/sleep_button.h"
8 8
9namespace Service::HID { 9namespace Service::HID {
10 10
@@ -21,10 +21,11 @@ void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
21 return; 21 return;
22 } 22 }
23 23
24 std::scoped_lock shared_lock{*shared_mutex};
24 const u64 aruid = applet_resource->GetActiveAruid(); 25 const u64 aruid = applet_resource->GetActiveAruid();
25 auto* data = applet_resource->GetAruidData(aruid); 26 auto* data = applet_resource->GetAruidData(aruid);
26 27
27 if (data == nullptr) { 28 if (data == nullptr || !data->flag.is_assigned) {
28 return; 29 return;
29 } 30 }
30 31
diff --git a/src/core/hle/service/hid/controllers/sleep_button.h b/src/hid_core/resources/system_buttons/sleep_button.h
index 59964bf63..f9ed38c33 100644
--- a/src/core/hle/service/hid/controllers/sleep_button.h
+++ b/src/hid_core/resources/system_buttons/sleep_button.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/resources/controller_base.h"
7 7
8namespace Service::HID { 8namespace Service::HID {
9 9
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/hid_core/resources/touch_screen/gesture.cpp
index 6e686fe65..0ecc0941f 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/hid_core/resources/touch_screen/gesture.cpp
@@ -4,11 +4,11 @@
4#include "common/math_util.h" 4#include "common/math_util.h"
5#include "common/settings.h" 5#include "common/settings.h"
6#include "core/frontend/emu_window.h" 6#include "core/frontend/emu_window.h"
7#include "core/hid/emulated_console.h" 7#include "hid_core/frontend/emulated_console.h"
8#include "core/hid/hid_core.h" 8#include "hid_core/hid_core.h"
9#include "core/hle/service/hid/controllers/applet_resource.h" 9#include "hid_core/resources/applet_resource.h"
10#include "core/hle/service/hid/controllers/gesture.h" 10#include "hid_core/resources/shared_memory_format.h"
11#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 11#include "hid_core/resources/touch_screen/gesture.h"
12 12
13namespace Service::HID { 13namespace Service::HID {
14// HW is around 700, value is set to 400 to make it easier to trigger with mouse 14// HW is around 700, value is set to 400 to make it easier to trigger with mouse
@@ -28,10 +28,11 @@ Gesture::Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) {
28Gesture::~Gesture() = default; 28Gesture::~Gesture() = default;
29 29
30void Gesture::OnInit() { 30void Gesture::OnInit() {
31 std::scoped_lock shared_lock{*shared_mutex};
31 const u64 aruid = applet_resource->GetActiveAruid(); 32 const u64 aruid = applet_resource->GetActiveAruid();
32 auto* data = applet_resource->GetAruidData(aruid); 33 auto* data = applet_resource->GetAruidData(aruid);
33 34
34 if (data == nullptr) { 35 if (data == nullptr || !data->flag.is_assigned) {
35 return; 36 return;
36 } 37 }
37 38
@@ -44,10 +45,11 @@ void Gesture::OnInit() {
44void Gesture::OnRelease() {} 45void Gesture::OnRelease() {}
45 46
46void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 47void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
48 std::scoped_lock shared_lock{*shared_mutex};
47 const u64 aruid = applet_resource->GetActiveAruid(); 49 const u64 aruid = applet_resource->GetActiveAruid();
48 auto* data = applet_resource->GetAruidData(aruid); 50 auto* data = applet_resource->GetAruidData(aruid);
49 51
50 if (data == nullptr) { 52 if (data == nullptr || !data->flag.is_assigned) {
51 return; 53 return;
52 } 54 }
53 55
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/hid_core/resources/touch_screen/gesture.h
index 78da1552a..32e9a8690 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/hid_core/resources/touch_screen/gesture.h
@@ -6,8 +6,8 @@
6#include <array> 6#include <array>
7 7
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/service/hid/controllers/controller_base.h" 9#include "hid_core/resources/controller_base.h"
10#include "core/hle/service/hid/controllers/types/touch_types.h" 10#include "hid_core/resources/touch_screen/touch_types.h"
11 11
12namespace Core::HID { 12namespace Core::HID {
13class EmulatedConsole; 13class EmulatedConsole;
diff --git a/src/core/hle/service/hid/controllers/types/gesture_types.h b/src/hid_core/resources/touch_screen/gesture_types.h
index b4f034cd3..b4f034cd3 100644
--- a/src/core/hle/service/hid/controllers/types/gesture_types.h
+++ b/src/hid_core/resources/touch_screen/gesture_types.h
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/hid_core/resources/touch_screen/touch_screen.cpp
index 291dc707e..48d956c51 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/hid_core/resources/touch_screen/touch_screen.cpp
@@ -6,11 +6,11 @@
6#include "common/settings.h" 6#include "common/settings.h"
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/frontend/emu_window.h" 8#include "core/frontend/emu_window.h"
9#include "core/hid/emulated_console.h" 9#include "hid_core/frontend/emulated_console.h"
10#include "core/hid/hid_core.h" 10#include "hid_core/hid_core.h"
11#include "core/hle/service/hid/controllers/applet_resource.h" 11#include "hid_core/resources/applet_resource.h"
12#include "core/hle/service/hid/controllers/touchscreen.h" 12#include "hid_core/resources/shared_memory_format.h"
13#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 13#include "hid_core/resources/touch_screen/touch_screen.h"
14 14
15namespace Service::HID { 15namespace Service::HID {
16 16
@@ -30,7 +30,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
30 const u64 aruid = applet_resource->GetActiveAruid(); 30 const u64 aruid = applet_resource->GetActiveAruid();
31 auto* data = applet_resource->GetAruidData(aruid); 31 auto* data = applet_resource->GetAruidData(aruid);
32 32
33 if (data == nullptr) { 33 if (data == nullptr || !data->flag.is_assigned) {
34 return; 34 return;
35 } 35 }
36 36
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/hid_core/resources/touch_screen/touch_screen.h
index 945d359be..4b3824742 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/hid_core/resources/touch_screen/touch_screen.h
@@ -5,9 +5,9 @@
5 5
6#include <array> 6#include <array>
7 7
8#include "core/hid/hid_types.h" 8#include "hid_core/hid_types.h"
9#include "core/hle/service/hid/controllers/controller_base.h" 9#include "hid_core/resources/controller_base.h"
10#include "core/hle/service/hid/controllers/types/touch_types.h" 10#include "hid_core/resources/touch_screen/touch_types.h"
11 11
12namespace Core::HID { 12namespace Core::HID {
13class EmulatedConsole; 13class EmulatedConsole;
diff --git a/src/core/hle/service/hid/controllers/types/touch_types.h b/src/hid_core/resources/touch_screen/touch_types.h
index efeaa796d..97ee847da 100644
--- a/src/core/hle/service/hid/controllers/types/touch_types.h
+++ b/src/hid_core/resources/touch_screen/touch_types.h
@@ -10,7 +10,7 @@
10#include "common/common_funcs.h" 10#include "common/common_funcs.h"
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/point.h" 12#include "common/point.h"
13#include "core/hid/hid_types.h" 13#include "hid_core/hid_types.h"
14 14
15namespace Service::HID { 15namespace Service::HID {
16static constexpr std::size_t MAX_FINGERS = 16; 16static constexpr std::size_t MAX_FINGERS = 16;
diff --git a/src/core/hle/service/hid/controllers/unique_pad.cpp b/src/hid_core/resources/unique_pad/unique_pad.cpp
index 8230501a5..892bbe3c9 100644
--- a/src/core/hle/service/hid/controllers/unique_pad.cpp
+++ b/src/hid_core/resources/unique_pad/unique_pad.cpp
@@ -2,9 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core_timing.h" 4#include "core/core_timing.h"
5#include "core/hle/service/hid/controllers/applet_resource.h" 5#include "hid_core/resources/applet_resource.h"
6#include "core/hle/service/hid/controllers/types/shared_memory_format.h" 6#include "hid_core/resources/shared_memory_format.h"
7#include "core/hle/service/hid/controllers/unique_pad.h" 7#include "hid_core/resources/unique_pad/unique_pad.h"
8 8
9namespace Service::HID { 9namespace Service::HID {
10 10
@@ -24,7 +24,7 @@ void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
24 const u64 aruid = applet_resource->GetActiveAruid(); 24 const u64 aruid = applet_resource->GetActiveAruid();
25 auto* data = applet_resource->GetAruidData(aruid); 25 auto* data = applet_resource->GetAruidData(aruid);
26 26
27 if (data == nullptr) { 27 if (data == nullptr || !data->flag.is_assigned) {
28 return; 28 return;
29 } 29 }
30 30
diff --git a/src/core/hle/service/hid/controllers/unique_pad.h b/src/hid_core/resources/unique_pad/unique_pad.h
index 966368264..674ad1691 100644
--- a/src/core/hle/service/hid/controllers/unique_pad.h
+++ b/src/hid_core/resources/unique_pad/unique_pad.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/hid/controllers/controller_base.h" 6#include "hid_core/resources/controller_base.h"
7 7
8namespace Service::HID { 8namespace Service::HID {
9 9
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 5c127c8ef..d2fbea488 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -87,7 +87,7 @@ if (ENABLE_LIBUSB)
87endif() 87endif()
88 88
89create_target_directory_groups(input_common) 89create_target_directory_groups(input_common)
90target_link_libraries(input_common PUBLIC core PRIVATE common Boost::headers) 90target_link_libraries(input_common PUBLIC hid_core PRIVATE common Boost::headers)
91 91
92if (YUZU_USE_PRECOMPILED_HEADERS) 92if (YUZU_USE_PRECOMPILED_HEADERS)
93 target_precompile_headers(input_common PRIVATE precompiled_headers.h) 93 target_precompile_headers(input_common PRIVATE precompiled_headers.h)
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
index 6e940bd5a..ad39f44c3 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
@@ -449,7 +449,7 @@ void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& inde
449} 449}
450 450
451void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 451void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
452 std::string_view coords, std::string_view offset, std::string_view lod, 452 std::string_view coords, const IR::Value& offset, std::string_view lod,
453 std::string_view ms) { 453 std::string_view ms) {
454 const auto info{inst.Flags<IR::TextureInstInfo>()}; 454 const auto info{inst.Flags<IR::TextureInstInfo>()};
455 if (info.has_bias) { 455 if (info.has_bias) {
@@ -470,9 +470,9 @@ void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
470 const auto int_coords{CoordsCastToInt(coords, info)}; 470 const auto int_coords{CoordsCastToInt(coords, info)};
471 if (!ms.empty()) { 471 if (!ms.empty()) {
472 ctx.Add("{}=texelFetch({},{},int({}));", texel, texture, int_coords, ms); 472 ctx.Add("{}=texelFetch({},{},int({}));", texel, texture, int_coords, ms);
473 } else if (!offset.empty()) { 473 } else if (!offset.IsEmpty()) {
474 ctx.Add("{}=texelFetchOffset({},{},int({}),{});", texel, texture, int_coords, lod, 474 ctx.Add("{}=texelFetchOffset({},{},int({}),{});", texel, texture, int_coords, lod,
475 CoordsCastToInt(offset, info)); 475 GetOffsetVec(ctx, offset));
476 } else { 476 } else {
477 if (info.type == TextureType::Buffer) { 477 if (info.type == TextureType::Buffer) {
478 ctx.Add("{}=texelFetch({},int({}));", texel, texture, coords); 478 ctx.Add("{}=texelFetch({},int({}));", texel, texture, coords);
@@ -485,10 +485,10 @@ void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
485 if (!ms.empty()) { 485 if (!ms.empty()) {
486 throw NotImplementedException("EmitImageFetch Sparse MSAA samples"); 486 throw NotImplementedException("EmitImageFetch Sparse MSAA samples");
487 } 487 }
488 if (!offset.empty()) { 488 if (!offset.IsEmpty()) {
489 ctx.AddU1("{}=sparseTexelsResidentARB(sparseTexelFetchOffsetARB({},{},int({}),{},{}));", 489 ctx.AddU1("{}=sparseTexelsResidentARB(sparseTexelFetchOffsetARB({},{},int({}),{},{}));",
490 *sparse_inst, texture, CastToIntVec(coords, info), lod, 490 *sparse_inst, texture, CastToIntVec(coords, info), lod, GetOffsetVec(ctx, offset),
491 CastToIntVec(offset, info), texel); 491 texel);
492 } else { 492 } else {
493 ctx.AddU1("{}=sparseTexelsResidentARB(sparseTexelFetchARB({},{},int({}),{}));", 493 ctx.AddU1("{}=sparseTexelsResidentARB(sparseTexelFetchARB({},{},int({}),{}));",
494 *sparse_inst, texture, CastToIntVec(coords, info), lod, texel); 494 *sparse_inst, texture, CastToIntVec(coords, info), lod, texel);
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
index 8d0a65047..acebaa785 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
@@ -651,7 +651,7 @@ void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& inde
651 std::string_view coords, const IR::Value& offset, const IR::Value& offset2, 651 std::string_view coords, const IR::Value& offset, const IR::Value& offset2,
652 std::string_view dref); 652 std::string_view dref);
653void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 653void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
654 std::string_view coords, std::string_view offset, std::string_view lod, 654 std::string_view coords, const IR::Value& offset, std::string_view lod,
655 std::string_view ms); 655 std::string_view ms);
656void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, 656void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
657 std::string_view lod, const IR::Value& skip_mips); 657 std::string_view lod, const IR::Value& skip_mips);
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
index 89ebab08e..0442adc83 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
@@ -1440,7 +1440,7 @@ void EmitContext::DefineInputs(const IR::Program& program) {
1440 if (profile.support_vertex_instance_id) { 1440 if (profile.support_vertex_instance_id) {
1441 instance_id = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceId); 1441 instance_id = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceId);
1442 if (loads[IR::Attribute::BaseInstance]) { 1442 if (loads[IR::Attribute::BaseInstance]) {
1443 base_instance = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseVertex); 1443 base_instance = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseInstance);
1444 } 1444 }
1445 } else { 1445 } else {
1446 instance_index = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceIndex); 1446 instance_index = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceIndex);
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 993438a27..9be1b0805 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -195,9 +195,9 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
195 has_texture_shadow_lod = HasExtension(extensions, "GL_EXT_texture_shadow_lod"); 195 has_texture_shadow_lod = HasExtension(extensions, "GL_EXT_texture_shadow_lod");
196 has_astc = !has_slow_software_astc && IsASTCSupported(); 196 has_astc = !has_slow_software_astc && IsASTCSupported();
197 has_variable_aoffi = TestVariableAoffi(); 197 has_variable_aoffi = TestVariableAoffi();
198 has_component_indexing_bug = is_amd; 198 has_component_indexing_bug = false;
199 has_precise_bug = TestPreciseBug(); 199 has_precise_bug = TestPreciseBug();
200 has_broken_texture_view_formats = is_amd || (!is_linux && is_intel); 200 has_broken_texture_view_formats = (!is_linux && is_intel);
201 has_nv_viewport_array2 = GLAD_GL_NV_viewport_array2; 201 has_nv_viewport_array2 = GLAD_GL_NV_viewport_array2;
202 has_derivative_control = GLAD_GL_ARB_derivative_control; 202 has_derivative_control = GLAD_GL_ARB_derivative_control;
203 has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory; 203 has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory;
@@ -238,10 +238,11 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
238 has_lmem_perf_bug = is_nvidia; 238 has_lmem_perf_bug = is_nvidia;
239 239
240 strict_context_required = emu_window.StrictContextRequired(); 240 strict_context_required = emu_window.StrictContextRequired();
241 // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation. 241 // Blocks Intel OpenGL drivers on Windows from using asynchronous shader compilation.
242 // Blocks EGL on Wayland from using asynchronous shader compilation. 242 // Blocks EGL on Wayland from using asynchronous shader compilation.
243 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && 243 const bool blacklist_async_shaders = (is_intel && !is_linux) || strict_context_required;
244 !(is_amd || (is_intel && !is_linux)) && !strict_context_required; 244 use_asynchronous_shaders =
245 Settings::values.use_asynchronous_shaders.GetValue() && !blacklist_async_shaders;
245 use_driver_cache = is_nvidia; 246 use_driver_cache = is_nvidia;
246 supports_conditional_barriers = !is_intel; 247 supports_conditional_barriers = !is_intel;
247 248
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index 9e5319716..8b340ee6c 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -9,11 +9,11 @@
9#include "common/settings_enums.h" 9#include "common/settings_enums.h"
10#include "common/string_util.h" 10#include "common/string_util.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/hid/emulated_controller.h"
13#include "core/hid/hid_core.h"
14#include "core/hid/hid_types.h"
15#include "core/hle/service/hid/controllers/npad.h"
16#include "core/hle/service/sm/sm.h" 12#include "core/hle/service/sm/sm.h"
13#include "hid_core/frontend/emulated_controller.h"
14#include "hid_core/hid_core.h"
15#include "hid_core/hid_types.h"
16#include "hid_core/resources/npad/npad.h"
17#include "ui_qt_controller.h" 17#include "ui_qt_controller.h"
18#include "yuzu/applets/qt_controller.h" 18#include "yuzu/applets/qt_controller.h"
19#include "yuzu/configuration/configure_input.h" 19#include "yuzu/configuration/configure_input.h"
diff --git a/src/yuzu/applets/qt_software_keyboard.cpp b/src/yuzu/applets/qt_software_keyboard.cpp
index 4ae49506d..bbe17c35e 100644
--- a/src/yuzu/applets/qt_software_keyboard.cpp
+++ b/src/yuzu/applets/qt_software_keyboard.cpp
@@ -9,10 +9,10 @@
9#include "common/settings.h" 9#include "common/settings.h"
10#include "common/string_util.h" 10#include "common/string_util.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/hid/emulated_controller.h" 12#include "hid_core/frontend/emulated_controller.h"
13#include "core/hid/hid_core.h" 13#include "hid_core/frontend/input_interpreter.h"
14#include "core/hid/hid_types.h" 14#include "hid_core/hid_core.h"
15#include "core/hid/input_interpreter.h" 15#include "hid_core/hid_types.h"
16#include "ui_qt_software_keyboard.h" 16#include "ui_qt_software_keyboard.h"
17#include "yuzu/applets/qt_software_keyboard.h" 17#include "yuzu/applets/qt_software_keyboard.h"
18#include "yuzu/main.h" 18#include "yuzu/main.h"
diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp
index 28acc0ff8..34c5fd3be 100644
--- a/src/yuzu/applets/qt_web_browser.cpp
+++ b/src/yuzu/applets/qt_web_browser.cpp
@@ -13,7 +13,7 @@
13#include <QWebEngineSettings> 13#include <QWebEngineSettings>
14#include <QWebEngineUrlScheme> 14#include <QWebEngineUrlScheme>
15 15
16#include "core/hid/input_interpreter.h" 16#include "hid_core/frontend/input_interpreter.h"
17#include "yuzu/applets/qt_web_browser_scripts.h" 17#include "yuzu/applets/qt_web_browser_scripts.h"
18#endif 18#endif
19 19
diff --git a/src/yuzu/configuration/configure_debug_controller.cpp b/src/yuzu/configuration/configure_debug_controller.cpp
index 42abe9119..74208d1cc 100644
--- a/src/yuzu/configuration/configure_debug_controller.cpp
+++ b/src/yuzu/configuration/configure_debug_controller.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hid/hid_core.h" 4#include "hid_core/hid_core.h"
5#include "ui_configure_debug_controller.h" 5#include "ui_configure_debug_controller.h"
6#include "yuzu/configuration/configure_debug_controller.h" 6#include "yuzu/configuration/configure_debug_controller.h"
7#include "yuzu/configuration/configure_input_player.h" 7#include "yuzu/configuration/configure_input_player.h"
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp
index 76fc33e49..3d18670ce 100644
--- a/src/yuzu/configuration/configure_hotkeys.cpp
+++ b/src/yuzu/configuration/configure_hotkeys.cpp
@@ -6,8 +6,8 @@
6#include <QStandardItemModel> 6#include <QStandardItemModel>
7#include <QTimer> 7#include <QTimer>
8 8
9#include "core/hid/emulated_controller.h" 9#include "hid_core/frontend/emulated_controller.h"
10#include "core/hid/hid_core.h" 10#include "hid_core/hid_core.h"
11 11
12#include "frontend_common/config.h" 12#include "frontend_common/config.h"
13#include "ui_configure_hotkeys.h" 13#include "ui_configure_hotkeys.h"
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 02e23cce6..49ec52546 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -7,12 +7,12 @@
7#include "common/settings.h" 7#include "common/settings.h"
8#include "common/settings_enums.h" 8#include "common/settings_enums.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "core/hid/emulated_controller.h"
11#include "core/hid/hid_core.h"
12#include "core/hle/service/am/am.h" 10#include "core/hle/service/am/am.h"
13#include "core/hle/service/am/applet_ae.h" 11#include "core/hle/service/am/applet_ae.h"
14#include "core/hle/service/am/applet_oe.h" 12#include "core/hle/service/am/applet_oe.h"
15#include "core/hle/service/sm/sm.h" 13#include "core/hle/service/sm/sm.h"
14#include "hid_core/frontend/emulated_controller.h"
15#include "hid_core/hid_core.h"
16#include "ui_configure_input.h" 16#include "ui_configure_input.h"
17#include "ui_configure_input_advanced.h" 17#include "ui_configure_input_advanced.h"
18#include "ui_configure_input_player.h" 18#include "ui_configure_input_player.h"
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index 441cea3f6..d6c4e09ec 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -4,8 +4,8 @@
4#include <QColorDialog> 4#include <QColorDialog>
5#include "common/settings.h" 5#include "common/settings.h"
6#include "core/core.h" 6#include "core/core.h"
7#include "core/hid/emulated_controller.h" 7#include "hid_core/frontend/emulated_controller.h"
8#include "core/hid/hid_core.h" 8#include "hid_core/hid_core.h"
9#include "ui_configure_input_advanced.h" 9#include "ui_configure_input_advanced.h"
10#include "yuzu/configuration/configure_input_advanced.h" 10#include "yuzu/configuration/configure_input_advanced.h"
11 11
diff --git a/src/yuzu/configuration/configure_input_per_game.cpp b/src/yuzu/configuration/configure_input_per_game.cpp
index 8d9f65a05..eea7ec369 100644
--- a/src/yuzu/configuration/configure_input_per_game.cpp
+++ b/src/yuzu/configuration/configure_input_per_game.cpp
@@ -3,9 +3,9 @@
3 3
4#include "common/settings.h" 4#include "common/settings.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hid/emulated_controller.h"
7#include "core/hid/hid_core.h"
8#include "frontend_common/config.h" 6#include "frontend_common/config.h"
7#include "hid_core/frontend/emulated_controller.h"
8#include "hid_core/hid_core.h"
9#include "ui_configure_input_per_game.h" 9#include "ui_configure_input_per_game.h"
10#include "yuzu/configuration/configure_input_per_game.h" 10#include "yuzu/configuration/configure_input_per_game.h"
11#include "yuzu/configuration/input_profiles.h" 11#include "yuzu/configuration/input_profiles.h"
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 0f7b3714e..f3552191a 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -13,10 +13,10 @@
13#include "common/assert.h" 13#include "common/assert.h"
14#include "common/param_package.h" 14#include "common/param_package.h"
15#include "configuration/qt_config.h" 15#include "configuration/qt_config.h"
16#include "core/hid/emulated_controller.h"
17#include "core/hid/hid_core.h"
18#include "core/hid/hid_types.h"
19#include "frontend_common/config.h" 16#include "frontend_common/config.h"
17#include "hid_core/frontend/emulated_controller.h"
18#include "hid_core/hid_core.h"
19#include "hid_core/hid_types.h"
20#include "input_common/drivers/keyboard.h" 20#include "input_common/drivers/keyboard.h"
21#include "input_common/drivers/mouse.h" 21#include "input_common/drivers/mouse.h"
22#include "input_common/main.h" 22#include "input_common/main.h"
diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp
index 550cff9a0..19fdca7d3 100644
--- a/src/yuzu/configuration/configure_input_player_widget.cpp
+++ b/src/yuzu/configuration/configure_input_player_widget.cpp
@@ -6,7 +6,7 @@
6#include <QPainter> 6#include <QPainter>
7#include <QTimer> 7#include <QTimer>
8 8
9#include "core/hid/emulated_controller.h" 9#include "hid_core/frontend/emulated_controller.h"
10#include "yuzu/configuration/configure_input_player_widget.h" 10#include "yuzu/configuration/configure_input_player_widget.h"
11 11
12PlayerControlPreview::PlayerControlPreview(QWidget* parent) : QFrame(parent) { 12PlayerControlPreview::PlayerControlPreview(QWidget* parent) : QFrame(parent) {
diff --git a/src/yuzu/configuration/configure_input_player_widget.h b/src/yuzu/configuration/configure_input_player_widget.h
index a16943c3c..76340912d 100644
--- a/src/yuzu/configuration/configure_input_player_widget.h
+++ b/src/yuzu/configuration/configure_input_player_widget.h
@@ -10,8 +10,8 @@
10#include "common/input.h" 10#include "common/input.h"
11#include "common/settings_input.h" 11#include "common/settings_input.h"
12#include "common/vector_math.h" 12#include "common/vector_math.h"
13#include "core/hid/emulated_controller.h" 13#include "hid_core/frontend/emulated_controller.h"
14#include "core/hid/hid_types.h" 14#include "hid_core/hid_types.h"
15 15
16class QLabel; 16class QLabel;
17 17
diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp
index 9572ff43c..3a7f6101d 100644
--- a/src/yuzu/configuration/configure_ringcon.cpp
+++ b/src/yuzu/configuration/configure_ringcon.cpp
@@ -9,8 +9,8 @@
9#include <fmt/format.h> 9#include <fmt/format.h>
10 10
11#include "configuration/qt_config.h" 11#include "configuration/qt_config.h"
12#include "core/hid/emulated_controller.h" 12#include "hid_core/frontend/emulated_controller.h"
13#include "core/hid/hid_core.h" 13#include "hid_core/hid_core.h"
14#include "input_common/drivers/keyboard.h" 14#include "input_common/drivers/keyboard.h"
15#include "input_common/drivers/mouse.h" 15#include "input_common/drivers/mouse.h"
16#include "input_common/main.h" 16#include "input_common/main.h"
diff --git a/src/yuzu/configuration/configure_vibration.cpp b/src/yuzu/configuration/configure_vibration.cpp
index 68c28b320..d898d8acc 100644
--- a/src/yuzu/configuration/configure_vibration.cpp
+++ b/src/yuzu/configuration/configure_vibration.cpp
@@ -2,9 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/settings.h" 4#include "common/settings.h"
5#include "core/hid/emulated_controller.h" 5#include "hid_core/frontend/emulated_controller.h"
6#include "core/hid/hid_core.h" 6#include "hid_core/hid_core.h"
7#include "core/hid/hid_types.h" 7#include "hid_core/hid_types.h"
8#include "ui_configure_vibration.h" 8#include "ui_configure_vibration.h"
9#include "yuzu/configuration/configure_vibration.h" 9#include "yuzu/configuration/configure_vibration.h"
10 10
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index 7e908924c..922eb1b1a 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -228,7 +228,7 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
228 { 228 {
229 PAIR(ShaderBackend, Glsl, tr("GLSL")), 229 PAIR(ShaderBackend, Glsl, tr("GLSL")),
230 PAIR(ShaderBackend, Glasm, tr("GLASM (Assembly Shaders, NVIDIA Only)")), 230 PAIR(ShaderBackend, Glasm, tr("GLASM (Assembly Shaders, NVIDIA Only)")),
231 PAIR(ShaderBackend, SpirV, tr("SPIR-V (Experimental, Mesa Only)")), 231 PAIR(ShaderBackend, SpirV, tr("SPIR-V (Experimental, AMD/Mesa Only)")),
232 }}); 232 }});
233 translations->insert({Settings::EnumMetadata<Settings::GpuAccuracy>::Index(), 233 translations->insert({Settings::EnumMetadata<Settings::GpuAccuracy>::Index(),
234 { 234 {
diff --git a/src/yuzu/debugger/controller.cpp b/src/yuzu/debugger/controller.cpp
index e2f55ebae..216d2974d 100644
--- a/src/yuzu/debugger/controller.cpp
+++ b/src/yuzu/debugger/controller.cpp
@@ -5,8 +5,8 @@
5#include <QLayout> 5#include <QLayout>
6#include <QString> 6#include <QString>
7#include "common/settings.h" 7#include "common/settings.h"
8#include "core/hid/emulated_controller.h" 8#include "hid_core/frontend/emulated_controller.h"
9#include "core/hid/hid_core.h" 9#include "hid_core/hid_core.h"
10#include "input_common/drivers/tas_input.h" 10#include "input_common/drivers/tas_input.h"
11#include "input_common/main.h" 11#include "input_common/main.h"
12#include "yuzu/configuration/configure_input_player_widget.h" 12#include "yuzu/configuration/configure_input_player_widget.h"
diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp
index eebfbf155..b7693ad0d 100644
--- a/src/yuzu/hotkeys.cpp
+++ b/src/yuzu/hotkeys.cpp
@@ -6,7 +6,7 @@
6#include <QTreeWidgetItem> 6#include <QTreeWidgetItem>
7#include <QtGlobal> 7#include <QtGlobal>
8 8
9#include "core/hid/emulated_controller.h" 9#include "hid_core/frontend/emulated_controller.h"
10#include "yuzu/hotkeys.h" 10#include "yuzu/hotkeys.h"
11#include "yuzu/uisettings.h" 11#include "yuzu/uisettings.h"
12 12
diff --git a/src/yuzu/hotkeys.h b/src/yuzu/hotkeys.h
index e11332d2e..bdc081649 100644
--- a/src/yuzu/hotkeys.h
+++ b/src/yuzu/hotkeys.h
@@ -7,7 +7,7 @@
7#include <QKeySequence> 7#include <QKeySequence>
8#include <QString> 8#include <QString>
9#include <QWidget> 9#include <QWidget>
10#include "core/hid/hid_types.h" 10#include "hid_core/hid_types.h"
11 11
12class QDialog; 12class QDialog;
13class QSettings; 13class QSettings;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index c789c1e59..2a83486f9 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -42,13 +42,13 @@
42#include "core/frontend/applets/general_frontend.h" 42#include "core/frontend/applets/general_frontend.h"
43#include "core/frontend/applets/mii_edit.h" 43#include "core/frontend/applets/mii_edit.h"
44#include "core/frontend/applets/software_keyboard.h" 44#include "core/frontend/applets/software_keyboard.h"
45#include "core/hid/emulated_controller.h"
46#include "core/hid/hid_core.h"
47#include "core/hle/service/acc/profile_manager.h" 45#include "core/hle/service/acc/profile_manager.h"
48#include "core/hle/service/am/applet_ae.h" 46#include "core/hle/service/am/applet_ae.h"
49#include "core/hle/service/am/applet_oe.h" 47#include "core/hle/service/am/applet_oe.h"
50#include "core/hle/service/am/applets/applets.h" 48#include "core/hle/service/am/applets/applets.h"
51#include "core/hle/service/set/set_sys.h" 49#include "core/hle/service/set/set_sys.h"
50#include "hid_core/frontend/emulated_controller.h"
51#include "hid_core/hid_core.h"
52#include "yuzu/multiplayer/state.h" 52#include "yuzu/multiplayer/state.h"
53#include "yuzu/util/controller_navigation.h" 53#include "yuzu/util/controller_navigation.h"
54 54
diff --git a/src/yuzu/util/controller_navigation.cpp b/src/yuzu/util/controller_navigation.cpp
index d49ae67cd..2690b075d 100644
--- a/src/yuzu/util/controller_navigation.cpp
+++ b/src/yuzu/util/controller_navigation.cpp
@@ -2,8 +2,8 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/settings_input.h" 4#include "common/settings_input.h"
5#include "core/hid/emulated_controller.h" 5#include "hid_core/frontend/emulated_controller.h"
6#include "core/hid/hid_core.h" 6#include "hid_core/hid_core.h"
7#include "yuzu/util/controller_navigation.h" 7#include "yuzu/util/controller_navigation.h"
8 8
9ControllerNavigation::ControllerNavigation(Core::HID::HIDCore& hid_core, QWidget* parent) { 9ControllerNavigation::ControllerNavigation(Core::HID::HIDCore& hid_core, QWidget* parent) {
diff --git a/src/yuzu/util/overlay_dialog.cpp b/src/yuzu/util/overlay_dialog.cpp
index ee35a3e15..466bbe7b2 100644
--- a/src/yuzu/util/overlay_dialog.cpp
+++ b/src/yuzu/util/overlay_dialog.cpp
@@ -6,8 +6,8 @@
6#include <QWindow> 6#include <QWindow>
7 7
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hid/hid_types.h" 9#include "hid_core/frontend/input_interpreter.h"
10#include "core/hid/input_interpreter.h" 10#include "hid_core/hid_types.h"
11#include "ui_overlay_dialog.h" 11#include "ui_overlay_dialog.h"
12#include "yuzu/util/overlay_dialog.h" 12#include "yuzu/util/overlay_dialog.h"
13 13
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 1a35d471c..eae614f9d 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -7,8 +7,8 @@
7#include "common/scm_rev.h" 7#include "common/scm_rev.h"
8#include "common/settings.h" 8#include "common/settings.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "core/hid/hid_core.h"
11#include "core/perf_stats.h" 10#include "core/perf_stats.h"
11#include "hid_core/hid_core.h"
12#include "input_common/drivers/keyboard.h" 12#include "input_common/drivers/keyboard.h"
13#include "input_common/drivers/mouse.h" 13#include "input_common/drivers/mouse.h"
14#include "input_common/drivers/touch_screen.h" 14#include "input_common/drivers/touch_screen.h"