diff options
| author | 2023-11-26 21:08:53 -0500 | |
|---|---|---|
| committer | 2023-11-26 21:08:53 -0500 | |
| commit | 1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a (patch) | |
| tree | c219aacab776c0a1e3956614b60a01fa2f6164cb /src/core/hle/service | |
| parent | shader_recompiler: Align SSBO offsets in GlobalMemory functions (diff) | |
| parent | Merge pull request #11535 from GPUCode/upload_cmdbuf (diff) | |
| download | yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.gz yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.xz yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.zip | |
Merge branch 'master' into ssbo-align
Diffstat (limited to 'src/core/hle/service')
97 files changed, 6028 insertions, 4478 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 1b1c8190e..f21553644 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -3,11 +3,13 @@ | |||
| 3 | 3 | ||
| 4 | #include <algorithm> | 4 | #include <algorithm> |
| 5 | #include <array> | 5 | #include <array> |
| 6 | |||
| 6 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 7 | #include "common/fs/file.h" | 8 | #include "common/fs/file.h" |
| 8 | #include "common/fs/path_util.h" | 9 | #include "common/fs/path_util.h" |
| 9 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 10 | #include "common/polyfill_ranges.h" | 11 | #include "common/polyfill_ranges.h" |
| 12 | #include "common/stb.h" | ||
| 11 | #include "common/string_util.h" | 13 | #include "common/string_util.h" |
| 12 | #include "common/swap.h" | 14 | #include "common/swap.h" |
| 13 | #include "core/constants.h" | 15 | #include "core/constants.h" |
| @@ -38,9 +40,36 @@ static std::filesystem::path GetImagePath(const Common::UUID& uuid) { | |||
| 38 | fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString()); | 40 | fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString()); |
| 39 | } | 41 | } |
| 40 | 42 | ||
| 41 | static constexpr u32 SanitizeJPEGSize(std::size_t size) { | 43 | static void JPGToMemory(void* context, void* data, int len) { |
| 44 | std::vector<u8>* jpg_image = static_cast<std::vector<u8>*>(context); | ||
| 45 | unsigned char* jpg = static_cast<unsigned char*>(data); | ||
| 46 | jpg_image->insert(jpg_image->end(), jpg, jpg + len); | ||
| 47 | } | ||
| 48 | |||
| 49 | static void SanitizeJPEGImageSize(std::vector<u8>& image) { | ||
| 42 | constexpr std::size_t max_jpeg_image_size = 0x20000; | 50 | constexpr std::size_t max_jpeg_image_size = 0x20000; |
| 43 | return static_cast<u32>(std::min(size, max_jpeg_image_size)); | 51 | constexpr int profile_dimensions = 256; |
| 52 | int original_width, original_height, color_channels; | ||
| 53 | |||
| 54 | const auto plain_image = | ||
| 55 | stbi_load_from_memory(image.data(), static_cast<int>(image.size()), &original_width, | ||
| 56 | &original_height, &color_channels, STBI_rgb); | ||
| 57 | |||
| 58 | // Resize image to match 256*256 | ||
| 59 | if (original_width != profile_dimensions || original_height != profile_dimensions) { | ||
| 60 | // Use vector instead of array to avoid overflowing the stack | ||
| 61 | std::vector<u8> out_image(profile_dimensions * profile_dimensions * STBI_rgb); | ||
| 62 | stbir_resize_uint8_srgb(plain_image, original_width, original_height, 0, out_image.data(), | ||
| 63 | profile_dimensions, profile_dimensions, 0, STBI_rgb, 0, | ||
| 64 | STBIR_FILTER_BOX); | ||
| 65 | image.clear(); | ||
| 66 | if (!stbi_write_jpg_to_func(JPGToMemory, &image, profile_dimensions, profile_dimensions, | ||
| 67 | STBI_rgb, out_image.data(), 0)) { | ||
| 68 | LOG_ERROR(Service_ACC, "Failed to resize the user provided image."); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | image.resize(std::min(image.size(), max_jpeg_image_size)); | ||
| 44 | } | 73 | } |
| 45 | 74 | ||
| 46 | class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> { | 75 | class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> { |
| @@ -339,19 +368,20 @@ protected: | |||
| 339 | LOG_WARNING(Service_ACC, | 368 | LOG_WARNING(Service_ACC, |
| 340 | "Failed to load user provided image! Falling back to built-in backup..."); | 369 | "Failed to load user provided image! Falling back to built-in backup..."); |
| 341 | ctx.WriteBuffer(Core::Constants::ACCOUNT_BACKUP_JPEG); | 370 | ctx.WriteBuffer(Core::Constants::ACCOUNT_BACKUP_JPEG); |
| 342 | rb.Push(SanitizeJPEGSize(Core::Constants::ACCOUNT_BACKUP_JPEG.size())); | 371 | rb.Push(static_cast<u32>(Core::Constants::ACCOUNT_BACKUP_JPEG.size())); |
| 343 | return; | 372 | return; |
| 344 | } | 373 | } |
| 345 | 374 | ||
| 346 | const u32 size = SanitizeJPEGSize(image.GetSize()); | 375 | std::vector<u8> buffer(image.GetSize()); |
| 347 | std::vector<u8> buffer(size); | ||
| 348 | 376 | ||
| 349 | if (image.Read(buffer) != buffer.size()) { | 377 | if (image.Read(buffer) != buffer.size()) { |
| 350 | LOG_ERROR(Service_ACC, "Failed to read all the bytes in the user provided image."); | 378 | LOG_ERROR(Service_ACC, "Failed to read all the bytes in the user provided image."); |
| 351 | } | 379 | } |
| 352 | 380 | ||
| 381 | SanitizeJPEGImageSize(buffer); | ||
| 382 | |||
| 353 | ctx.WriteBuffer(buffer); | 383 | ctx.WriteBuffer(buffer); |
| 354 | rb.Push<u32>(size); | 384 | rb.Push(static_cast<u32>(buffer.size())); |
| 355 | } | 385 | } |
| 356 | 386 | ||
| 357 | void GetImageSize(HLERequestContext& ctx) { | 387 | void GetImageSize(HLERequestContext& ctx) { |
| @@ -365,10 +395,18 @@ protected: | |||
| 365 | if (!image.IsOpen()) { | 395 | if (!image.IsOpen()) { |
| 366 | LOG_WARNING(Service_ACC, | 396 | LOG_WARNING(Service_ACC, |
| 367 | "Failed to load user provided image! Falling back to built-in backup..."); | 397 | "Failed to load user provided image! Falling back to built-in backup..."); |
| 368 | rb.Push(SanitizeJPEGSize(Core::Constants::ACCOUNT_BACKUP_JPEG.size())); | 398 | rb.Push(static_cast<u32>(Core::Constants::ACCOUNT_BACKUP_JPEG.size())); |
| 369 | } else { | 399 | return; |
| 370 | rb.Push(SanitizeJPEGSize(image.GetSize())); | ||
| 371 | } | 400 | } |
| 401 | |||
| 402 | std::vector<u8> buffer(image.GetSize()); | ||
| 403 | |||
| 404 | if (image.Read(buffer) != buffer.size()) { | ||
| 405 | LOG_ERROR(Service_ACC, "Failed to read all the bytes in the user provided image."); | ||
| 406 | } | ||
| 407 | |||
| 408 | SanitizeJPEGImageSize(buffer); | ||
| 409 | rb.Push(static_cast<u32>(buffer.size())); | ||
| 372 | } | 410 | } |
| 373 | 411 | ||
| 374 | void Store(HLERequestContext& ctx) { | 412 | void Store(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index cc643ea09..a266d7c21 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 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" | ||
| 16 | #include "core/hle/kernel/k_event.h" | 17 | #include "core/hle/kernel/k_event.h" |
| 17 | #include "core/hle/kernel/k_transfer_memory.h" | 18 | #include "core/hle/kernel/k_transfer_memory.h" |
| 18 | #include "core/hle/result.h" | 19 | #include "core/hle/result.h" |
| @@ -21,6 +22,7 @@ | |||
| 21 | #include "core/hle/service/am/applet_ae.h" | 22 | #include "core/hle/service/am/applet_ae.h" |
| 22 | #include "core/hle/service/am/applet_oe.h" | 23 | #include "core/hle/service/am/applet_oe.h" |
| 23 | #include "core/hle/service/am/applets/applet_cabinet.h" | 24 | #include "core/hle/service/am/applets/applet_cabinet.h" |
| 25 | #include "core/hle/service/am/applets/applet_controller.h" | ||
| 24 | #include "core/hle/service/am/applets/applet_mii_edit_types.h" | 26 | #include "core/hle/service/am/applets/applet_mii_edit_types.h" |
| 25 | #include "core/hle/service/am/applets/applet_profile_select.h" | 27 | #include "core/hle/service/am/applets/applet_profile_select.h" |
| 26 | #include "core/hle/service/am/applets/applet_software_keyboard_types.h" | 28 | #include "core/hle/service/am/applets/applet_software_keyboard_types.h" |
| @@ -35,6 +37,7 @@ | |||
| 35 | #include "core/hle/service/caps/caps_su.h" | 37 | #include "core/hle/service/caps/caps_su.h" |
| 36 | #include "core/hle/service/caps/caps_types.h" | 38 | #include "core/hle/service/caps/caps_types.h" |
| 37 | #include "core/hle/service/filesystem/filesystem.h" | 39 | #include "core/hle/service/filesystem/filesystem.h" |
| 40 | #include "core/hle/service/hid/controllers/npad.h" | ||
| 38 | #include "core/hle/service/ipc_helpers.h" | 41 | #include "core/hle/service/ipc_helpers.h" |
| 39 | #include "core/hle/service/ns/ns.h" | 42 | #include "core/hle/service/ns/ns.h" |
| 40 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | 43 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" |
| @@ -73,7 +76,7 @@ IWindowController::IWindowController(Core::System& system_) | |||
| 73 | static const FunctionInfo functions[] = { | 76 | static const FunctionInfo functions[] = { |
| 74 | {0, nullptr, "CreateWindow"}, | 77 | {0, nullptr, "CreateWindow"}, |
| 75 | {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"}, | 78 | {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"}, |
| 76 | {2, nullptr, "GetAppletResourceUserIdOfCallerApplet"}, | 79 | {2, &IWindowController::GetAppletResourceUserIdOfCallerApplet, "GetAppletResourceUserIdOfCallerApplet"}, |
| 77 | {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"}, | 80 | {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"}, |
| 78 | {11, nullptr, "ReleaseForegroundRights"}, | 81 | {11, nullptr, "ReleaseForegroundRights"}, |
| 79 | {12, nullptr, "RejectToChangeIntoBackground"}, | 82 | {12, nullptr, "RejectToChangeIntoBackground"}, |
| @@ -97,6 +100,16 @@ void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) { | |||
| 97 | rb.Push<u64>(process_id); | 100 | rb.Push<u64>(process_id); |
| 98 | } | 101 | } |
| 99 | 102 | ||
| 103 | void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) { | ||
| 104 | const u64 process_id = 0; | ||
| 105 | |||
| 106 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 107 | |||
| 108 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 109 | rb.Push(ResultSuccess); | ||
| 110 | rb.Push<u64>(process_id); | ||
| 111 | } | ||
| 112 | |||
| 100 | void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) { | 113 | void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) { |
| 101 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 114 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 102 | IPC::ResponseBuilder rb{ctx, 2}; | 115 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -1565,7 +1578,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) | |||
| 1565 | {6, nullptr, "GetPopInteractiveInDataEvent"}, | 1578 | {6, nullptr, "GetPopInteractiveInDataEvent"}, |
| 1566 | {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"}, | 1579 | {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"}, |
| 1567 | {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"}, | 1580 | {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"}, |
| 1568 | {12, nullptr, "GetMainAppletIdentityInfo"}, | 1581 | {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"}, |
| 1569 | {13, nullptr, "CanUseApplicationCore"}, | 1582 | {13, nullptr, "CanUseApplicationCore"}, |
| 1570 | {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"}, | 1583 | {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"}, |
| 1571 | {15, nullptr, "GetMainAppletApplicationControlProperty"}, | 1584 | {15, nullptr, "GetMainAppletApplicationControlProperty"}, |
| @@ -1609,6 +1622,9 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) | |||
| 1609 | case Applets::AppletId::SoftwareKeyboard: | 1622 | case Applets::AppletId::SoftwareKeyboard: |
| 1610 | PushInShowSoftwareKeyboard(); | 1623 | PushInShowSoftwareKeyboard(); |
| 1611 | break; | 1624 | break; |
| 1625 | case Applets::AppletId::Controller: | ||
| 1626 | PushInShowController(); | ||
| 1627 | break; | ||
| 1612 | default: | 1628 | default: |
| 1613 | break; | 1629 | break; |
| 1614 | } | 1630 | } |
| @@ -1666,13 +1682,33 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) { | |||
| 1666 | rb.PushRaw(applet_info); | 1682 | rb.PushRaw(applet_info); |
| 1667 | } | 1683 | } |
| 1668 | 1684 | ||
| 1669 | void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) { | 1685 | void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) { |
| 1670 | struct AppletIdentityInfo { | 1686 | struct AppletIdentityInfo { |
| 1671 | Applets::AppletId applet_id; | 1687 | Applets::AppletId applet_id; |
| 1672 | INSERT_PADDING_BYTES(0x4); | 1688 | INSERT_PADDING_BYTES(0x4); |
| 1673 | u64 application_id; | 1689 | u64 application_id; |
| 1674 | }; | 1690 | }; |
| 1691 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | ||
| 1692 | |||
| 1693 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 1694 | |||
| 1695 | const AppletIdentityInfo applet_info{ | ||
| 1696 | .applet_id = Applets::AppletId::QLaunch, | ||
| 1697 | .application_id = 0x0100000000001000ull, | ||
| 1698 | }; | ||
| 1699 | |||
| 1700 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 1701 | rb.Push(ResultSuccess); | ||
| 1702 | rb.PushRaw(applet_info); | ||
| 1703 | } | ||
| 1675 | 1704 | ||
| 1705 | void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) { | ||
| 1706 | struct AppletIdentityInfo { | ||
| 1707 | Applets::AppletId applet_id; | ||
| 1708 | INSERT_PADDING_BYTES(0x4); | ||
| 1709 | u64 application_id; | ||
| 1710 | }; | ||
| 1711 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | ||
| 1676 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 1712 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 1677 | 1713 | ||
| 1678 | const AppletIdentityInfo applet_info{ | 1714 | const AppletIdentityInfo applet_info{ |
| @@ -1737,6 +1773,55 @@ void ILibraryAppletSelfAccessor::PushInShowAlbum() { | |||
| 1737 | queue_data.emplace_back(std::move(settings_data)); | 1773 | queue_data.emplace_back(std::move(settings_data)); |
| 1738 | } | 1774 | } |
| 1739 | 1775 | ||
| 1776 | void ILibraryAppletSelfAccessor::PushInShowController() { | ||
| 1777 | const Applets::CommonArguments common_args = { | ||
| 1778 | .arguments_version = Applets::CommonArgumentVersion::Version3, | ||
| 1779 | .size = Applets::CommonArgumentSize::Version3, | ||
| 1780 | .library_version = static_cast<u32>(Applets::ControllerAppletVersion::Version8), | ||
| 1781 | .theme_color = Applets::ThemeColor::BasicBlack, | ||
| 1782 | .play_startup_sound = true, | ||
| 1783 | .system_tick = system.CoreTiming().GetClockTicks(), | ||
| 1784 | }; | ||
| 1785 | |||
| 1786 | Applets::ControllerSupportArgNew user_args = { | ||
| 1787 | .header = {.player_count_min = 1, | ||
| 1788 | .player_count_max = 4, | ||
| 1789 | .enable_take_over_connection = true, | ||
| 1790 | .enable_left_justify = false, | ||
| 1791 | .enable_permit_joy_dual = true, | ||
| 1792 | .enable_single_mode = false, | ||
| 1793 | .enable_identification_color = false}, | ||
| 1794 | .identification_colors = {}, | ||
| 1795 | .enable_explain_text = false, | ||
| 1796 | .explain_text = {}, | ||
| 1797 | }; | ||
| 1798 | |||
| 1799 | Applets::ControllerSupportArgPrivate private_args = { | ||
| 1800 | .arg_private_size = sizeof(Applets::ControllerSupportArgPrivate), | ||
| 1801 | .arg_size = sizeof(Applets::ControllerSupportArgNew), | ||
| 1802 | .is_home_menu = true, | ||
| 1803 | .flag_1 = true, | ||
| 1804 | .mode = Applets::ControllerSupportMode::ShowControllerSupport, | ||
| 1805 | .caller = Applets::ControllerSupportCaller:: | ||
| 1806 | Application, // switchbrew: Always zero except with | ||
| 1807 | // ShowControllerFirmwareUpdateForSystem/ShowControllerKeyRemappingForSystem, | ||
| 1808 | // which sets this to the input param | ||
| 1809 | .style_set = Core::HID::NpadStyleSet::None, | ||
| 1810 | .joy_hold_type = 0, | ||
| 1811 | }; | ||
| 1812 | std::vector<u8> common_args_data(sizeof(common_args)); | ||
| 1813 | std::vector<u8> private_args_data(sizeof(private_args)); | ||
| 1814 | std::vector<u8> user_args_data(sizeof(user_args)); | ||
| 1815 | |||
| 1816 | std::memcpy(common_args_data.data(), &common_args, sizeof(common_args)); | ||
| 1817 | std::memcpy(private_args_data.data(), &private_args, sizeof(private_args)); | ||
| 1818 | std::memcpy(user_args_data.data(), &user_args, sizeof(user_args)); | ||
| 1819 | |||
| 1820 | queue_data.emplace_back(std::move(common_args_data)); | ||
| 1821 | queue_data.emplace_back(std::move(private_args_data)); | ||
| 1822 | queue_data.emplace_back(std::move(user_args_data)); | ||
| 1823 | } | ||
| 1824 | |||
| 1740 | void ILibraryAppletSelfAccessor::PushInShowCabinetData() { | 1825 | void ILibraryAppletSelfAccessor::PushInShowCabinetData() { |
| 1741 | const Applets::CommonArguments arguments{ | 1826 | const Applets::CommonArguments arguments{ |
| 1742 | .arguments_version = Applets::CommonArgumentVersion::Version3, | 1827 | .arguments_version = Applets::CommonArgumentVersion::Version3, |
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 8f8cb8a9e..905a71b9f 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -87,6 +87,7 @@ public: | |||
| 87 | 87 | ||
| 88 | private: | 88 | private: |
| 89 | void GetAppletResourceUserId(HLERequestContext& ctx); | 89 | void GetAppletResourceUserId(HLERequestContext& ctx); |
| 90 | void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx); | ||
| 90 | void AcquireForegroundRights(HLERequestContext& ctx); | 91 | void AcquireForegroundRights(HLERequestContext& ctx); |
| 91 | }; | 92 | }; |
| 92 | 93 | ||
| @@ -345,6 +346,7 @@ private: | |||
| 345 | void PopInData(HLERequestContext& ctx); | 346 | void PopInData(HLERequestContext& ctx); |
| 346 | void PushOutData(HLERequestContext& ctx); | 347 | void PushOutData(HLERequestContext& ctx); |
| 347 | void GetLibraryAppletInfo(HLERequestContext& ctx); | 348 | void GetLibraryAppletInfo(HLERequestContext& ctx); |
| 349 | void GetMainAppletIdentityInfo(HLERequestContext& ctx); | ||
| 348 | void ExitProcessAndReturn(HLERequestContext& ctx); | 350 | void ExitProcessAndReturn(HLERequestContext& ctx); |
| 349 | void GetCallerAppletIdentityInfo(HLERequestContext& ctx); | 351 | void GetCallerAppletIdentityInfo(HLERequestContext& ctx); |
| 350 | void GetDesirableKeyboardLayout(HLERequestContext& ctx); | 352 | void GetDesirableKeyboardLayout(HLERequestContext& ctx); |
| @@ -355,6 +357,7 @@ private: | |||
| 355 | void PushInShowCabinetData(); | 357 | void PushInShowCabinetData(); |
| 356 | void PushInShowMiiEditData(); | 358 | void PushInShowMiiEditData(); |
| 357 | void PushInShowSoftwareKeyboard(); | 359 | void PushInShowSoftwareKeyboard(); |
| 360 | void PushInShowController(); | ||
| 358 | 361 | ||
| 359 | std::deque<std::vector<u8>> queue_data; | 362 | std::deque<std::vector<u8>> queue_data; |
| 360 | }; | 363 | }; |
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index b379dadeb..9d1960cb7 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp | |||
| @@ -122,7 +122,8 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) | |||
| 122 | Service::NFP::RegisterInfoPrivate register_info{}; | 122 | Service::NFP::RegisterInfoPrivate register_info{}; |
| 123 | std::memcpy(register_info.amiibo_name.data(), amiibo_name.data(), | 123 | std::memcpy(register_info.amiibo_name.data(), amiibo_name.data(), |
| 124 | std::min(amiibo_name.size(), register_info.amiibo_name.size() - 1)); | 124 | std::min(amiibo_name.size(), register_info.amiibo_name.size() - 1)); |
| 125 | 125 | register_info.mii_store_data.BuildRandom(Mii::Age::All, Mii::Gender::All, Mii::Race::All); | |
| 126 | register_info.mii_store_data.SetNickname({u'y', u'u', u'z', u'u'}); | ||
| 126 | nfp_device->SetRegisterInfoPrivate(register_info); | 127 | nfp_device->SetRegisterInfoPrivate(register_info); |
| 127 | break; | 128 | break; |
| 128 | } | 129 | } |
diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h index f6c64f633..9f839f3d7 100644 --- a/src/core/hle/service/am/applets/applet_controller.h +++ b/src/core/hle/service/am/applets/applet_controller.h | |||
| @@ -56,7 +56,7 @@ enum class ControllerSupportResult : u32 { | |||
| 56 | struct ControllerSupportArgPrivate { | 56 | struct ControllerSupportArgPrivate { |
| 57 | u32 arg_private_size{}; | 57 | u32 arg_private_size{}; |
| 58 | u32 arg_size{}; | 58 | u32 arg_size{}; |
| 59 | bool flag_0{}; | 59 | bool is_home_menu{}; |
| 60 | bool flag_1{}; | 60 | bool flag_1{}; |
| 61 | ControllerSupportMode mode{}; | 61 | ControllerSupportMode mode{}; |
| 62 | ControllerSupportCaller caller{}; | 62 | ControllerSupportCaller caller{}; |
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp index 1c9a1dc29..b0ea2b381 100644 --- a/src/core/hle/service/am/applets/applet_web_browser.cpp +++ b/src/core/hle/service/am/applets/applet_web_browser.cpp | |||
| @@ -330,8 +330,7 @@ void WebBrowser::ExtractOfflineRomFS() { | |||
| 330 | LOG_DEBUG(Service_AM, "Extracting RomFS to {}", | 330 | LOG_DEBUG(Service_AM, "Extracting RomFS to {}", |
| 331 | Common::FS::PathToUTF8String(offline_cache_dir)); | 331 | Common::FS::PathToUTF8String(offline_cache_dir)); |
| 332 | 332 | ||
| 333 | const auto extracted_romfs_dir = | 333 | const auto extracted_romfs_dir = FileSys::ExtractRomFS(offline_romfs); |
| 334 | FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard); | ||
| 335 | 334 | ||
| 336 | const auto temp_dir = system.GetFilesystem()->CreateDirectory( | 335 | const auto temp_dir = system.GetFilesystem()->CreateDirectory( |
| 337 | Common::FS::PathToUTF8String(offline_cache_dir), FileSys::Mode::ReadWrite); | 336 | Common::FS::PathToUTF8String(offline_cache_dir), FileSys::Mode::ReadWrite); |
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index f02bbc450..0bf2598b7 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -69,6 +69,30 @@ enum class AppletId : u32 { | |||
| 69 | MyPage = 0x1A, | 69 | MyPage = 0x1A, |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | enum class AppletProgramId : u64 { | ||
| 73 | QLaunch = 0x0100000000001000ull, | ||
| 74 | Auth = 0x0100000000001001ull, | ||
| 75 | Cabinet = 0x0100000000001002ull, | ||
| 76 | Controller = 0x0100000000001003ull, | ||
| 77 | DataErase = 0x0100000000001004ull, | ||
| 78 | Error = 0x0100000000001005ull, | ||
| 79 | NetConnect = 0x0100000000001006ull, | ||
| 80 | ProfileSelect = 0x0100000000001007ull, | ||
| 81 | SoftwareKeyboard = 0x0100000000001008ull, | ||
| 82 | MiiEdit = 0x0100000000001009ull, | ||
| 83 | Web = 0x010000000000100Aull, | ||
| 84 | Shop = 0x010000000000100Bull, | ||
| 85 | OverlayDisplay = 0x010000000000100Cull, | ||
| 86 | PhotoViewer = 0x010000000000100Dull, | ||
| 87 | Settings = 0x010000000000100Eull, | ||
| 88 | OfflineWeb = 0x010000000000100Full, | ||
| 89 | LoginShare = 0x0100000000001010ull, | ||
| 90 | WebAuth = 0x0100000000001011ull, | ||
| 91 | Starter = 0x0100000000001012ull, | ||
| 92 | MyPage = 0x0100000000001013ull, | ||
| 93 | MaxProgramId = 0x0100000000001FFFull, | ||
| 94 | }; | ||
| 95 | |||
| 72 | enum class LibraryAppletMode : u32 { | 96 | enum class LibraryAppletMode : u32 { |
| 73 | AllForeground = 0, | 97 | AllForeground = 0, |
| 74 | Background = 1, | 98 | Background = 1, |
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 8069f75b7..c65e32489 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp | |||
| @@ -127,7 +127,7 @@ public: | |||
| 127 | 127 | ||
| 128 | private: | 128 | private: |
| 129 | void GetCore(HLERequestContext& ctx) { | 129 | void GetCore(HLERequestContext& ctx) { |
| 130 | LOG_DEBUG(Service_BTM, "called"); | 130 | LOG_WARNING(Service_BTM, "called"); |
| 131 | 131 | ||
| 132 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 132 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 133 | rb.Push(ResultSuccess); | 133 | rb.Push(ResultSuccess); |
| @@ -263,13 +263,13 @@ public: | |||
| 263 | explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} { | 263 | explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} { |
| 264 | // clang-format off | 264 | // clang-format off |
| 265 | static const FunctionInfo functions[] = { | 265 | static const FunctionInfo functions[] = { |
| 266 | {0, nullptr, "StartGamepadPairing"}, | 266 | {0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"}, |
| 267 | {1, nullptr, "CancelGamepadPairing"}, | 267 | {1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"}, |
| 268 | {2, nullptr, "ClearGamepadPairingDatabase"}, | 268 | {2, nullptr, "ClearGamepadPairingDatabase"}, |
| 269 | {3, nullptr, "GetPairedGamepadCount"}, | 269 | {3, nullptr, "GetPairedGamepadCount"}, |
| 270 | {4, nullptr, "EnableRadio"}, | 270 | {4, nullptr, "EnableRadio"}, |
| 271 | {5, nullptr, "DisableRadio"}, | 271 | {5, nullptr, "DisableRadio"}, |
| 272 | {6, nullptr, "GetRadioOnOff"}, | 272 | {6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"}, |
| 273 | {7, nullptr, "AcquireRadioEvent"}, | 273 | {7, nullptr, "AcquireRadioEvent"}, |
| 274 | {8, nullptr, "AcquireGamepadPairingEvent"}, | 274 | {8, nullptr, "AcquireGamepadPairingEvent"}, |
| 275 | {9, nullptr, "IsGamepadPairingStarted"}, | 275 | {9, nullptr, "IsGamepadPairingStarted"}, |
| @@ -280,18 +280,58 @@ public: | |||
| 280 | {14, nullptr, "AcquireAudioDeviceConnectionEvent"}, | 280 | {14, nullptr, "AcquireAudioDeviceConnectionEvent"}, |
| 281 | {15, nullptr, "ConnectAudioDevice"}, | 281 | {15, nullptr, "ConnectAudioDevice"}, |
| 282 | {16, nullptr, "IsConnectingAudioDevice"}, | 282 | {16, nullptr, "IsConnectingAudioDevice"}, |
| 283 | {17, nullptr, "GetConnectedAudioDevices"}, | 283 | {17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"}, |
| 284 | {18, nullptr, "DisconnectAudioDevice"}, | 284 | {18, nullptr, "DisconnectAudioDevice"}, |
| 285 | {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"}, | 285 | {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"}, |
| 286 | {20, nullptr, "GetPairedAudioDevices"}, | 286 | {20, nullptr, "GetPairedAudioDevices"}, |
| 287 | {21, nullptr, "RemoveAudioDevicePairing"}, | 287 | {21, nullptr, "RemoveAudioDevicePairing"}, |
| 288 | {22, nullptr, "RequestAudioDeviceConnectionRejection"}, | 288 | {22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"}, |
| 289 | {23, nullptr, "CancelAudioDeviceConnectionRejection"} | 289 | {23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"} |
| 290 | }; | 290 | }; |
| 291 | // clang-format on | 291 | // clang-format on |
| 292 | 292 | ||
| 293 | RegisterHandlers(functions); | 293 | RegisterHandlers(functions); |
| 294 | } | 294 | } |
| 295 | |||
| 296 | private: | ||
| 297 | void IsRadioEnabled(HLERequestContext& ctx) { | ||
| 298 | LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running | ||
| 299 | |||
| 300 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 301 | rb.Push(ResultSuccess); | ||
| 302 | rb.Push(true); | ||
| 303 | } | ||
| 304 | |||
| 305 | void StartGamepadPairing(HLERequestContext& ctx) { | ||
| 306 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 307 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 308 | rb.Push(ResultSuccess); | ||
| 309 | } | ||
| 310 | |||
| 311 | void CancelGamepadPairing(HLERequestContext& ctx) { | ||
| 312 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 313 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 314 | rb.Push(ResultSuccess); | ||
| 315 | } | ||
| 316 | |||
| 317 | void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) { | ||
| 318 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 319 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 320 | rb.Push(ResultSuccess); | ||
| 321 | } | ||
| 322 | |||
| 323 | void GetConnectedAudioDevices(HLERequestContext& ctx) { | ||
| 324 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 325 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 326 | rb.Push(ResultSuccess); | ||
| 327 | rb.Push<u32>(0); | ||
| 328 | } | ||
| 329 | |||
| 330 | void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) { | ||
| 331 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 332 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 333 | rb.Push(ResultSuccess); | ||
| 334 | } | ||
| 295 | }; | 335 | }; |
| 296 | 336 | ||
| 297 | class BTM_SYS final : public ServiceFramework<BTM_SYS> { | 337 | class BTM_SYS final : public ServiceFramework<BTM_SYS> { |
| @@ -308,7 +348,7 @@ public: | |||
| 308 | 348 | ||
| 309 | private: | 349 | private: |
| 310 | void GetCore(HLERequestContext& ctx) { | 350 | void GetCore(HLERequestContext& ctx) { |
| 311 | LOG_DEBUG(Service_BTM, "called"); | 351 | LOG_WARNING(Service_BTM, "called"); |
| 312 | 352 | ||
| 313 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 353 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 314 | rb.Push(ResultSuccess); | 354 | rb.Push(ResultSuccess); |
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 9d05f9801..0507b14e7 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -32,7 +32,7 @@ public: | |||
| 32 | {10200, nullptr, "SendFriendRequestForApplication"}, | 32 | {10200, nullptr, "SendFriendRequestForApplication"}, |
| 33 | {10211, nullptr, "AddFacedFriendRequestForApplication"}, | 33 | {10211, nullptr, "AddFacedFriendRequestForApplication"}, |
| 34 | {10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"}, | 34 | {10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"}, |
| 35 | {10420, nullptr, "IsBlockedUserListCacheAvailable"}, | 35 | {10420, &IFriendService::CheckBlockedUserListAvailability, "CheckBlockedUserListAvailability"}, |
| 36 | {10421, nullptr, "EnsureBlockedUserListAvailable"}, | 36 | {10421, nullptr, "EnsureBlockedUserListAvailable"}, |
| 37 | {10500, nullptr, "GetProfileList"}, | 37 | {10500, nullptr, "GetProfileList"}, |
| 38 | {10600, nullptr, "DeclareOpenOnlinePlaySession"}, | 38 | {10600, nullptr, "DeclareOpenOnlinePlaySession"}, |
| @@ -206,6 +206,17 @@ private: | |||
| 206 | rb.Push(true); | 206 | rb.Push(true); |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | void CheckBlockedUserListAvailability(HLERequestContext& ctx) { | ||
| 210 | IPC::RequestParser rp{ctx}; | ||
| 211 | const auto uuid{rp.PopRaw<Common::UUID>()}; | ||
| 212 | |||
| 213 | LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | ||
| 214 | |||
| 215 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 216 | rb.Push(ResultSuccess); | ||
| 217 | rb.Push(true); | ||
| 218 | } | ||
| 219 | |||
| 209 | KernelHelpers::ServiceContext service_context; | 220 | KernelHelpers::ServiceContext service_context; |
| 210 | 221 | ||
| 211 | Kernel::KEvent* completion_event; | 222 | Kernel::KEvent* completion_event; |
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp new file mode 100644 index 000000000..b2bf1d78d --- /dev/null +++ b/src/core/hle/service/hid/controllers/console_six_axis.cpp | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/core_timing.h" | ||
| 6 | #include "core/hid/emulated_console.h" | ||
| 7 | #include "core/hid/hid_core.h" | ||
| 8 | #include "core/hle/service/hid/controllers/console_six_axis.h" | ||
| 9 | #include "core/memory.h" | ||
| 10 | |||
| 11 | namespace Service::HID { | ||
| 12 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; | ||
| 13 | |||
| 14 | ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | ||
| 15 | : ControllerBase{hid_core_} { | ||
| 16 | console = hid_core.GetEmulatedConsole(); | ||
| 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size, | ||
| 18 | "ConsoleSharedMemory is bigger than the shared memory"); | ||
| 19 | shared_memory = std::construct_at( | ||
| 20 | reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 21 | } | ||
| 22 | |||
| 23 | ConsoleSixAxis::~ConsoleSixAxis() = default; | ||
| 24 | |||
| 25 | void ConsoleSixAxis::OnInit() {} | ||
| 26 | |||
| 27 | void ConsoleSixAxis::OnRelease() {} | ||
| 28 | |||
| 29 | void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||
| 30 | if (!IsControllerActivated()) { | ||
| 31 | return; | ||
| 32 | } | ||
| 33 | |||
| 34 | const auto motion_status = console->GetMotion(); | ||
| 35 | |||
| 36 | shared_memory->sampling_number++; | ||
| 37 | shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; | ||
| 38 | shared_memory->verticalization_error = motion_status.verticalization_error; | ||
| 39 | shared_memory->gyro_bias = motion_status.gyro_bias; | ||
| 40 | } | ||
| 41 | |||
| 42 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h new file mode 100644 index 000000000..5b7c6a29a --- /dev/null +++ b/src/core/hle/service/hid/controllers/console_six_axis.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/vector_math.h" | ||
| 7 | #include "core/hle/service/hid/controllers/controller_base.h" | ||
| 8 | |||
| 9 | namespace Core::HID { | ||
| 10 | class EmulatedConsole; | ||
| 11 | } // namespace Core::HID | ||
| 12 | |||
| 13 | namespace Service::HID { | ||
| 14 | class ConsoleSixAxis final : public ControllerBase { | ||
| 15 | public: | ||
| 16 | explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||
| 17 | ~ConsoleSixAxis() override; | ||
| 18 | |||
| 19 | // Called when the controller is initialized | ||
| 20 | void OnInit() override; | ||
| 21 | |||
| 22 | // When the controller is released | ||
| 23 | void OnRelease() override; | ||
| 24 | |||
| 25 | // When the controller is requesting an update for the shared memory | ||
| 26 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||
| 27 | |||
| 28 | private: | ||
| 29 | // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat | ||
| 30 | struct ConsoleSharedMemory { | ||
| 31 | u64 sampling_number{}; | ||
| 32 | bool is_seven_six_axis_sensor_at_rest{}; | ||
| 33 | INSERT_PADDING_BYTES(3); // padding | ||
| 34 | f32 verticalization_error{}; | ||
| 35 | Common::Vec3f gyro_bias{}; | ||
| 36 | INSERT_PADDING_BYTES(4); // padding | ||
| 37 | }; | ||
| 38 | static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); | ||
| 39 | |||
| 40 | ConsoleSharedMemory* shared_memory = nullptr; | ||
| 41 | Core::HID::EmulatedConsole* console = nullptr; | ||
| 42 | }; | ||
| 43 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp index c58d67d7d..0bcd87062 100644 --- a/src/core/hle/service/hid/controllers/controller_base.cpp +++ b/src/core/hle/service/hid/controllers/controller_base.cpp | |||
| @@ -8,12 +8,17 @@ namespace Service::HID { | |||
| 8 | ControllerBase::ControllerBase(Core::HID::HIDCore& hid_core_) : hid_core(hid_core_) {} | 8 | ControllerBase::ControllerBase(Core::HID::HIDCore& hid_core_) : hid_core(hid_core_) {} |
| 9 | ControllerBase::~ControllerBase() = default; | 9 | ControllerBase::~ControllerBase() = default; |
| 10 | 10 | ||
| 11 | void ControllerBase::ActivateController() { | 11 | Result ControllerBase::Activate() { |
| 12 | if (is_activated) { | 12 | if (is_activated) { |
| 13 | return; | 13 | return ResultSuccess; |
| 14 | } | 14 | } |
| 15 | is_activated = true; | 15 | is_activated = true; |
| 16 | OnInit(); | 16 | OnInit(); |
| 17 | return ResultSuccess; | ||
| 18 | } | ||
| 19 | |||
| 20 | Result ControllerBase::Activate(u64 aruid) { | ||
| 21 | return Activate(); | ||
| 17 | } | 22 | } |
| 18 | 23 | ||
| 19 | void ControllerBase::DeactivateController() { | 24 | void ControllerBase::DeactivateController() { |
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h index d6f7a5073..9a44ee41e 100644 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ b/src/core/hle/service/hid/controllers/controller_base.h | |||
| @@ -4,6 +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/result.h" | ||
| 7 | 8 | ||
| 8 | namespace Core::Timing { | 9 | namespace Core::Timing { |
| 9 | class CoreTiming; | 10 | class CoreTiming; |
| @@ -31,7 +32,8 @@ public: | |||
| 31 | // When the controller is requesting a motion update for the shared memory | 32 | // When the controller is requesting a motion update for the shared memory |
| 32 | virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {} | 33 | virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {} |
| 33 | 34 | ||
| 34 | void ActivateController(); | 35 | Result Activate(); |
| 36 | Result Activate(u64 aruid); | ||
| 35 | 37 | ||
| 36 | void DeactivateController(); | 38 | void DeactivateController(); |
| 37 | 39 | ||
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index 8ec9f4a95..9de19ebfc 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | namespace Service::HID { | 13 | namespace Service::HID { |
| 14 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; | 14 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; |
| 15 | 15 | ||
| 16 | Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 16 | DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 17 | : ControllerBase{hid_core_} { | 17 | : ControllerBase{hid_core_} { |
| 18 | static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size, | 18 | static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size, |
| 19 | "DebugPadSharedMemory is bigger than the shared memory"); | 19 | "DebugPadSharedMemory is bigger than the shared memory"); |
| @@ -22,13 +22,13 @@ Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_ | |||
| 22 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); | 22 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | Controller_DebugPad::~Controller_DebugPad() = default; | 25 | DebugPad::~DebugPad() = default; |
| 26 | 26 | ||
| 27 | void Controller_DebugPad::OnInit() {} | 27 | void DebugPad::OnInit() {} |
| 28 | 28 | ||
| 29 | void Controller_DebugPad::OnRelease() {} | 29 | void DebugPad::OnRelease() {} |
| 30 | 30 | ||
| 31 | void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 31 | void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 32 | if (!IsControllerActivated()) { | 32 | if (!IsControllerActivated()) { |
| 33 | shared_memory->debug_pad_lifo.buffer_count = 0; | 33 | shared_memory->debug_pad_lifo.buffer_count = 0; |
| 34 | shared_memory->debug_pad_lifo.buffer_tail = 0; | 34 | shared_memory->debug_pad_lifo.buffer_tail = 0; |
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index 68ff0ea79..5566dba77 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h | |||
| @@ -15,10 +15,10 @@ struct AnalogStickState; | |||
| 15 | } // namespace Core::HID | 15 | } // namespace Core::HID |
| 16 | 16 | ||
| 17 | namespace Service::HID { | 17 | namespace Service::HID { |
| 18 | class Controller_DebugPad final : public ControllerBase { | 18 | class DebugPad final : public ControllerBase { |
| 19 | public: | 19 | public: |
| 20 | explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 20 | explicit DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 21 | ~Controller_DebugPad() override; | 21 | ~DebugPad() override; |
| 22 | 22 | ||
| 23 | // Called when the controller is initialized | 23 | // Called when the controller is initialized |
| 24 | void OnInit() override; | 24 | void OnInit() override; |
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index 63eecd42b..59b2ec73c 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp | |||
| @@ -23,7 +23,7 @@ constexpr f32 Square(s32 num) { | |||
| 23 | return static_cast<f32>(num * num); | 23 | return static_cast<f32>(num * num); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 26 | Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 27 | : ControllerBase(hid_core_) { | 27 | : ControllerBase(hid_core_) { |
| 28 | static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size, | 28 | static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size, |
| 29 | "GestureSharedMemory is bigger than the shared memory"); | 29 | "GestureSharedMemory is bigger than the shared memory"); |
| @@ -31,17 +31,17 @@ Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_sh | |||
| 31 | reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | 31 | reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); |
| 32 | console = hid_core.GetEmulatedConsole(); | 32 | console = hid_core.GetEmulatedConsole(); |
| 33 | } | 33 | } |
| 34 | Controller_Gesture::~Controller_Gesture() = default; | 34 | Gesture::~Gesture() = default; |
| 35 | 35 | ||
| 36 | void Controller_Gesture::OnInit() { | 36 | void Gesture::OnInit() { |
| 37 | shared_memory->gesture_lifo.buffer_count = 0; | 37 | shared_memory->gesture_lifo.buffer_count = 0; |
| 38 | shared_memory->gesture_lifo.buffer_tail = 0; | 38 | shared_memory->gesture_lifo.buffer_tail = 0; |
| 39 | force_update = true; | 39 | force_update = true; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | void Controller_Gesture::OnRelease() {} | 42 | void Gesture::OnRelease() {} |
| 43 | 43 | ||
| 44 | void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 44 | void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 45 | if (!IsControllerActivated()) { | 45 | if (!IsControllerActivated()) { |
| 46 | shared_memory->gesture_lifo.buffer_count = 0; | 46 | shared_memory->gesture_lifo.buffer_count = 0; |
| 47 | shared_memory->gesture_lifo.buffer_tail = 0; | 47 | shared_memory->gesture_lifo.buffer_tail = 0; |
| @@ -64,7 +64,7 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 64 | UpdateGestureSharedMemory(gesture, time_difference); | 64 | UpdateGestureSharedMemory(gesture, time_difference); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | void Controller_Gesture::ReadTouchInput() { | 67 | void Gesture::ReadTouchInput() { |
| 68 | if (!Settings::values.touchscreen.enabled) { | 68 | if (!Settings::values.touchscreen.enabled) { |
| 69 | fingers = {}; | 69 | fingers = {}; |
| 70 | return; | 70 | return; |
| @@ -76,8 +76,7 @@ void Controller_Gesture::ReadTouchInput() { | |||
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture, | 79 | bool Gesture::ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference) { |
| 80 | f32 time_difference) { | ||
| 81 | const auto& last_entry = GetLastGestureEntry(); | 80 | const auto& last_entry = GetLastGestureEntry(); |
| 82 | if (force_update) { | 81 | if (force_update) { |
| 83 | force_update = false; | 82 | force_update = false; |
| @@ -100,8 +99,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture, | |||
| 100 | return false; | 99 | return false; |
| 101 | } | 100 | } |
| 102 | 101 | ||
| 103 | void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, | 102 | void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference) { |
| 104 | f32 time_difference) { | ||
| 105 | GestureType type = GestureType::Idle; | 103 | GestureType type = GestureType::Idle; |
| 106 | GestureAttribute attributes{}; | 104 | GestureAttribute attributes{}; |
| 107 | 105 | ||
| @@ -138,8 +136,8 @@ void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, | |||
| 138 | shared_memory->gesture_lifo.WriteNextEntry(next_state); | 136 | shared_memory->gesture_lifo.WriteNextEntry(next_state); |
| 139 | } | 137 | } |
| 140 | 138 | ||
| 141 | void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type, | 139 | void Gesture::NewGesture(GestureProperties& gesture, GestureType& type, |
| 142 | GestureAttribute& attributes) { | 140 | GestureAttribute& attributes) { |
| 143 | const auto& last_entry = GetLastGestureEntry(); | 141 | const auto& last_entry = GetLastGestureEntry(); |
| 144 | 142 | ||
| 145 | gesture.detection_count++; | 143 | gesture.detection_count++; |
| @@ -152,8 +150,8 @@ void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& typ | |||
| 152 | } | 150 | } |
| 153 | } | 151 | } |
| 154 | 152 | ||
| 155 | void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type, | 153 | void Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type, |
| 156 | f32 time_difference) { | 154 | f32 time_difference) { |
| 157 | const auto& last_entry = GetLastGestureEntry(); | 155 | const auto& last_entry = GetLastGestureEntry(); |
| 158 | 156 | ||
| 159 | // Promote to pan type if touch moved | 157 | // Promote to pan type if touch moved |
| @@ -186,9 +184,8 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Gestu | |||
| 186 | } | 184 | } |
| 187 | } | 185 | } |
| 188 | 186 | ||
| 189 | void Controller_Gesture::EndGesture(GestureProperties& gesture, | 187 | void Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props, |
| 190 | GestureProperties& last_gesture_props, GestureType& type, | 188 | GestureType& type, GestureAttribute& attributes, f32 time_difference) { |
| 191 | GestureAttribute& attributes, f32 time_difference) { | ||
| 192 | const auto& last_entry = GetLastGestureEntry(); | 189 | const auto& last_entry = GetLastGestureEntry(); |
| 193 | 190 | ||
| 194 | if (last_gesture_props.active_points != 0) { | 191 | if (last_gesture_props.active_points != 0) { |
| @@ -222,9 +219,8 @@ void Controller_Gesture::EndGesture(GestureProperties& gesture, | |||
| 222 | } | 219 | } |
| 223 | } | 220 | } |
| 224 | 221 | ||
| 225 | void Controller_Gesture::SetTapEvent(GestureProperties& gesture, | 222 | void Gesture::SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, |
| 226 | GestureProperties& last_gesture_props, GestureType& type, | 223 | GestureType& type, GestureAttribute& attributes) { |
| 227 | GestureAttribute& attributes) { | ||
| 228 | type = GestureType::Tap; | 224 | type = GestureType::Tap; |
| 229 | gesture = last_gesture_props; | 225 | gesture = last_gesture_props; |
| 230 | force_update = true; | 226 | force_update = true; |
| @@ -236,9 +232,8 @@ void Controller_Gesture::SetTapEvent(GestureProperties& gesture, | |||
| 236 | } | 232 | } |
| 237 | } | 233 | } |
| 238 | 234 | ||
| 239 | void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture, | 235 | void Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, |
| 240 | GestureProperties& last_gesture_props, GestureType& type, | 236 | GestureType& type, f32 time_difference) { |
| 241 | f32 time_difference) { | ||
| 242 | const auto& last_entry = GetLastGestureEntry(); | 237 | const auto& last_entry = GetLastGestureEntry(); |
| 243 | 238 | ||
| 244 | next_state.delta = gesture.mid_point - last_entry.pos; | 239 | next_state.delta = gesture.mid_point - last_entry.pos; |
| @@ -263,9 +258,8 @@ void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture, | |||
| 263 | } | 258 | } |
| 264 | } | 259 | } |
| 265 | 260 | ||
| 266 | void Controller_Gesture::EndPanEvent(GestureProperties& gesture, | 261 | void Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, |
| 267 | GestureProperties& last_gesture_props, GestureType& type, | 262 | GestureType& type, f32 time_difference) { |
| 268 | f32 time_difference) { | ||
| 269 | const auto& last_entry = GetLastGestureEntry(); | 263 | const auto& last_entry = GetLastGestureEntry(); |
| 270 | next_state.vel_x = | 264 | next_state.vel_x = |
| 271 | static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference); | 265 | static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference); |
| @@ -287,8 +281,8 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture, | |||
| 287 | force_update = true; | 281 | force_update = true; |
| 288 | } | 282 | } |
| 289 | 283 | ||
| 290 | void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture, | 284 | void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, |
| 291 | GestureProperties& last_gesture_props, GestureType& type) { | 285 | GestureType& type) { |
| 292 | const auto& last_entry = GetLastGestureEntry(); | 286 | const auto& last_entry = GetLastGestureEntry(); |
| 293 | 287 | ||
| 294 | type = GestureType::Swipe; | 288 | type = GestureType::Swipe; |
| @@ -311,11 +305,11 @@ void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture, | |||
| 311 | next_state.direction = GestureDirection::Up; | 305 | next_state.direction = GestureDirection::Up; |
| 312 | } | 306 | } |
| 313 | 307 | ||
| 314 | const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const { | 308 | const Gesture::GestureState& Gesture::GetLastGestureEntry() const { |
| 315 | return shared_memory->gesture_lifo.ReadCurrentEntry().state; | 309 | return shared_memory->gesture_lifo.ReadCurrentEntry().state; |
| 316 | } | 310 | } |
| 317 | 311 | ||
| 318 | Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() { | 312 | Gesture::GestureProperties Gesture::GetGestureProperties() { |
| 319 | GestureProperties gesture; | 313 | GestureProperties gesture; |
| 320 | std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; | 314 | std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; |
| 321 | const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), | 315 | const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), |
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index 0d6099ea0..4c6f8ee07 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h | |||
| @@ -12,10 +12,10 @@ | |||
| 12 | #include "core/hle/service/hid/ring_lifo.h" | 12 | #include "core/hle/service/hid/ring_lifo.h" |
| 13 | 13 | ||
| 14 | namespace Service::HID { | 14 | namespace Service::HID { |
| 15 | class Controller_Gesture final : public ControllerBase { | 15 | class Gesture final : public ControllerBase { |
| 16 | public: | 16 | public: |
| 17 | explicit Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 17 | explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 18 | ~Controller_Gesture() override; | 18 | ~Gesture() override; |
| 19 | 19 | ||
| 20 | // Called when the controller is initialized | 20 | // Called when the controller is initialized |
| 21 | void OnInit() override; | 21 | void OnInit() override; |
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 117d87433..ddb1b0ba4 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | namespace Service::HID { | 12 | namespace Service::HID { |
| 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; | 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; |
| 14 | 14 | ||
| 15 | Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 15 | Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 16 | : ControllerBase{hid_core_} { | 16 | : ControllerBase{hid_core_} { |
| 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size, | 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size, |
| 18 | "KeyboardSharedMemory is bigger than the shared memory"); | 18 | "KeyboardSharedMemory is bigger than the shared memory"); |
| @@ -21,13 +21,13 @@ Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_ | |||
| 21 | emulated_devices = hid_core.GetEmulatedDevices(); | 21 | emulated_devices = hid_core.GetEmulatedDevices(); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | Controller_Keyboard::~Controller_Keyboard() = default; | 24 | Keyboard::~Keyboard() = default; |
| 25 | 25 | ||
| 26 | void Controller_Keyboard::OnInit() {} | 26 | void Keyboard::OnInit() {} |
| 27 | 27 | ||
| 28 | void Controller_Keyboard::OnRelease() {} | 28 | void Keyboard::OnRelease() {} |
| 29 | 29 | ||
| 30 | void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 30 | void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 31 | if (!IsControllerActivated()) { | 31 | if (!IsControllerActivated()) { |
| 32 | shared_memory->keyboard_lifo.buffer_count = 0; | 32 | shared_memory->keyboard_lifo.buffer_count = 0; |
| 33 | shared_memory->keyboard_lifo.buffer_tail = 0; | 33 | shared_memory->keyboard_lifo.buffer_tail = 0; |
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 7532f53c6..172ec1309 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h | |||
| @@ -14,10 +14,10 @@ struct KeyboardKey; | |||
| 14 | } // namespace Core::HID | 14 | } // namespace Core::HID |
| 15 | 15 | ||
| 16 | namespace Service::HID { | 16 | namespace Service::HID { |
| 17 | class Controller_Keyboard final : public ControllerBase { | 17 | class Keyboard final : public ControllerBase { |
| 18 | public: | 18 | public: |
| 19 | explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 19 | explicit Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 20 | ~Controller_Keyboard() override; | 20 | ~Keyboard() override; |
| 21 | 21 | ||
| 22 | // Called when the controller is initialized | 22 | // Called when the controller is initialized |
| 23 | void OnInit() override; | 23 | void OnInit() override; |
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 0afc66681..6e5a04e34 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp | |||
| @@ -12,8 +12,7 @@ | |||
| 12 | namespace Service::HID { | 12 | namespace Service::HID { |
| 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; | 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; |
| 14 | 14 | ||
| 15 | Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 15 | Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { |
| 16 | : ControllerBase{hid_core_} { | ||
| 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size, | 16 | static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size, |
| 18 | "MouseSharedMemory is bigger than the shared memory"); | 17 | "MouseSharedMemory is bigger than the shared memory"); |
| 19 | shared_memory = std::construct_at( | 18 | shared_memory = std::construct_at( |
| @@ -21,12 +20,12 @@ Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared | |||
| 21 | emulated_devices = hid_core.GetEmulatedDevices(); | 20 | emulated_devices = hid_core.GetEmulatedDevices(); |
| 22 | } | 21 | } |
| 23 | 22 | ||
| 24 | Controller_Mouse::~Controller_Mouse() = default; | 23 | Mouse::~Mouse() = default; |
| 25 | 24 | ||
| 26 | void Controller_Mouse::OnInit() {} | 25 | void Mouse::OnInit() {} |
| 27 | void Controller_Mouse::OnRelease() {} | 26 | void Mouse::OnRelease() {} |
| 28 | 27 | ||
| 29 | void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 28 | void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 30 | if (!IsControllerActivated()) { | 29 | if (!IsControllerActivated()) { |
| 31 | shared_memory->mouse_lifo.buffer_count = 0; | 30 | shared_memory->mouse_lifo.buffer_count = 0; |
| 32 | shared_memory->mouse_lifo.buffer_tail = 0; | 31 | shared_memory->mouse_lifo.buffer_tail = 0; |
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 733d00577..a80f3823f 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h | |||
| @@ -14,10 +14,10 @@ struct AnalogStickState; | |||
| 14 | } // namespace Core::HID | 14 | } // namespace Core::HID |
| 15 | 15 | ||
| 16 | namespace Service::HID { | 16 | namespace Service::HID { |
| 17 | class Controller_Mouse final : public ControllerBase { | 17 | class Mouse final : public ControllerBase { |
| 18 | public: | 18 | public: |
| 19 | explicit Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 19 | explicit Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 20 | ~Controller_Mouse() override; | 20 | ~Mouse() override; |
| 21 | 21 | ||
| 22 | // Called when the controller is initialized | 22 | // Called when the controller is initialized |
| 23 | void OnInit() override; | 23 | void OnInit() override; |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index bc822f19e..08ee9de9c 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "core/hle/kernel/k_readable_event.h" | 18 | #include "core/hle/kernel/k_readable_event.h" |
| 19 | #include "core/hle/service/hid/controllers/npad.h" | 19 | #include "core/hle/service/hid/controllers/npad.h" |
| 20 | #include "core/hle/service/hid/errors.h" | 20 | #include "core/hle/service/hid/errors.h" |
| 21 | #include "core/hle/service/hid/hid_util.h" | ||
| 21 | #include "core/hle/service/kernel_helpers.h" | 22 | #include "core/hle/service/kernel_helpers.h" |
| 22 | 23 | ||
| 23 | namespace Service::HID { | 24 | namespace Service::HID { |
| @@ -29,60 +30,8 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ | |||
| 29 | Core::HID::NpadIdType::Handheld, | 30 | Core::HID::NpadIdType::Handheld, |
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | bool Controller_NPad::IsNpadIdValid(Core::HID::NpadIdType npad_id) { | 33 | NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, |
| 33 | switch (npad_id) { | 34 | KernelHelpers::ServiceContext& service_context_) |
| 34 | case Core::HID::NpadIdType::Player1: | ||
| 35 | case Core::HID::NpadIdType::Player2: | ||
| 36 | case Core::HID::NpadIdType::Player3: | ||
| 37 | case Core::HID::NpadIdType::Player4: | ||
| 38 | case Core::HID::NpadIdType::Player5: | ||
| 39 | case Core::HID::NpadIdType::Player6: | ||
| 40 | case Core::HID::NpadIdType::Player7: | ||
| 41 | case Core::HID::NpadIdType::Player8: | ||
| 42 | case Core::HID::NpadIdType::Other: | ||
| 43 | case Core::HID::NpadIdType::Handheld: | ||
| 44 | return true; | ||
| 45 | default: | ||
| 46 | LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id); | ||
| 47 | return false; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | Result Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) { | ||
| 52 | const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)); | ||
| 53 | const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType; | ||
| 54 | const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex; | ||
| 55 | |||
| 56 | if (!npad_type) { | ||
| 57 | return VibrationInvalidStyleIndex; | ||
| 58 | } | ||
| 59 | if (!npad_id) { | ||
| 60 | return VibrationInvalidNpadId; | ||
| 61 | } | ||
| 62 | if (!device_index) { | ||
| 63 | return VibrationDeviceIndexOutOfRange; | ||
| 64 | } | ||
| 65 | |||
| 66 | return ResultSuccess; | ||
| 67 | } | ||
| 68 | |||
| 69 | Result Controller_NPad::VerifyValidSixAxisSensorHandle( | ||
| 70 | const Core::HID::SixAxisSensorHandle& device_handle) { | ||
| 71 | const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)); | ||
| 72 | const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex; | ||
| 73 | |||
| 74 | if (!npad_id) { | ||
| 75 | return InvalidNpadId; | ||
| 76 | } | ||
| 77 | if (!device_index) { | ||
| 78 | return NpadDeviceIndexOutOfRange; | ||
| 79 | } | ||
| 80 | |||
| 81 | return ResultSuccess; | ||
| 82 | } | ||
| 83 | |||
| 84 | Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | ||
| 85 | KernelHelpers::ServiceContext& service_context_) | ||
| 86 | : ControllerBase{hid_core_}, service_context{service_context_} { | 35 | : ControllerBase{hid_core_}, service_context{service_context_} { |
| 87 | static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size); | 36 | static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size); |
| 88 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 37 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| @@ -103,7 +52,7 @@ Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_m | |||
| 103 | } | 52 | } |
| 104 | } | 53 | } |
| 105 | 54 | ||
| 106 | Controller_NPad::~Controller_NPad() { | 55 | NPad::~NPad() { |
| 107 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 56 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| 108 | auto& controller = controller_data[i]; | 57 | auto& controller = controller_data[i]; |
| 109 | controller.device->DeleteCallback(controller.callback_key); | 58 | controller.device->DeleteCallback(controller.callback_key); |
| @@ -111,8 +60,7 @@ Controller_NPad::~Controller_NPad() { | |||
| 111 | OnRelease(); | 60 | OnRelease(); |
| 112 | } | 61 | } |
| 113 | 62 | ||
| 114 | void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | 63 | void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) { |
| 115 | std::size_t controller_idx) { | ||
| 116 | if (type == Core::HID::ControllerTriggerType::All) { | 64 | if (type == Core::HID::ControllerTriggerType::All) { |
| 117 | ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx); | 65 | ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx); |
| 118 | ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx); | 66 | ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx); |
| @@ -150,7 +98,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | |||
| 150 | } | 98 | } |
| 151 | } | 99 | } |
| 152 | 100 | ||
| 153 | void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | 101 | void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { |
| 154 | auto& controller = GetControllerFromNpadIdType(npad_id); | 102 | auto& controller = GetControllerFromNpadIdType(npad_id); |
| 155 | if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) { | 103 | if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) { |
| 156 | return; | 104 | return; |
| @@ -344,12 +292,13 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | |||
| 344 | controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices, | 292 | controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices, |
| 345 | Common::Input::PollingMode::Active); | 293 | Common::Input::PollingMode::Active); |
| 346 | } | 294 | } |
| 295 | |||
| 347 | SignalStyleSetChangedEvent(npad_id); | 296 | SignalStyleSetChangedEvent(npad_id); |
| 348 | WriteEmptyEntry(controller.shared_memory); | 297 | WriteEmptyEntry(controller.shared_memory); |
| 349 | hid_core.SetLastActiveController(npad_id); | 298 | hid_core.SetLastActiveController(npad_id); |
| 350 | } | 299 | } |
| 351 | 300 | ||
| 352 | void Controller_NPad::OnInit() { | 301 | void NPad::OnInit() { |
| 353 | if (!IsControllerActivated()) { | 302 | if (!IsControllerActivated()) { |
| 354 | return; | 303 | return; |
| 355 | } | 304 | } |
| @@ -383,7 +332,7 @@ void Controller_NPad::OnInit() { | |||
| 383 | } | 332 | } |
| 384 | } | 333 | } |
| 385 | 334 | ||
| 386 | void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) { | 335 | void NPad::WriteEmptyEntry(NpadInternalState* npad) { |
| 387 | NPadGenericState dummy_pad_state{}; | 336 | NPadGenericState dummy_pad_state{}; |
| 388 | NpadGcTriggerState dummy_gc_state{}; | 337 | NpadGcTriggerState dummy_gc_state{}; |
| 389 | dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1; | 338 | dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1; |
| @@ -404,7 +353,7 @@ void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) { | |||
| 404 | npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state); | 353 | npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state); |
| 405 | } | 354 | } |
| 406 | 355 | ||
| 407 | void Controller_NPad::OnRelease() { | 356 | void NPad::OnRelease() { |
| 408 | is_controller_initialized = false; | 357 | is_controller_initialized = false; |
| 409 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 358 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| 410 | auto& controller = controller_data[i]; | 359 | auto& controller = controller_data[i]; |
| @@ -415,7 +364,7 @@ void Controller_NPad::OnRelease() { | |||
| 415 | } | 364 | } |
| 416 | } | 365 | } |
| 417 | 366 | ||
| 418 | void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) { | 367 | void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) { |
| 419 | std::scoped_lock lock{mutex}; | 368 | std::scoped_lock lock{mutex}; |
| 420 | auto& controller = GetControllerFromNpadIdType(npad_id); | 369 | auto& controller = GetControllerFromNpadIdType(npad_id); |
| 421 | const auto controller_type = controller.device->GetNpadStyleIndex(); | 370 | const auto controller_type = controller.device->GetNpadStyleIndex(); |
| @@ -457,12 +406,14 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) { | |||
| 457 | pad_entry.l_stick = stick_state.left; | 406 | pad_entry.l_stick = stick_state.left; |
| 458 | } | 407 | } |
| 459 | 408 | ||
| 460 | if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft) { | 409 | if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft || |
| 410 | controller_type == Core::HID::NpadStyleIndex::JoyconDual) { | ||
| 461 | pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl); | 411 | pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl); |
| 462 | pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr); | 412 | pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr); |
| 463 | } | 413 | } |
| 464 | 414 | ||
| 465 | if (controller_type == Core::HID::NpadStyleIndex::JoyconRight) { | 415 | if (controller_type == Core::HID::NpadStyleIndex::JoyconRight || |
| 416 | controller_type == Core::HID::NpadStyleIndex::JoyconDual) { | ||
| 466 | pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl); | 417 | pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl); |
| 467 | pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr); | 418 | pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr); |
| 468 | } | 419 | } |
| @@ -482,7 +433,7 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) { | |||
| 482 | } | 433 | } |
| 483 | } | 434 | } |
| 484 | 435 | ||
| 485 | void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 436 | void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 486 | if (!IsControllerActivated()) { | 437 | if (!IsControllerActivated()) { |
| 487 | return; | 438 | return; |
| 488 | } | 439 | } |
| @@ -612,134 +563,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 612 | } | 563 | } |
| 613 | } | 564 | } |
| 614 | 565 | ||
| 615 | void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) { | 566 | void NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) { |
| 616 | if (!IsControllerActivated()) { | ||
| 617 | return; | ||
| 618 | } | ||
| 619 | |||
| 620 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | ||
| 621 | auto& controller = controller_data[i]; | ||
| 622 | |||
| 623 | const auto& controller_type = controller.device->GetNpadStyleIndex(); | ||
| 624 | |||
| 625 | if (controller_type == Core::HID::NpadStyleIndex::None || | ||
| 626 | !controller.device->IsConnected()) { | ||
| 627 | continue; | ||
| 628 | } | ||
| 629 | |||
| 630 | auto* npad = controller.shared_memory; | ||
| 631 | const auto& motion_state = controller.device->GetMotions(); | ||
| 632 | auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state; | ||
| 633 | auto& sixaxis_handheld_state = controller.sixaxis_handheld_state; | ||
| 634 | auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state; | ||
| 635 | auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state; | ||
| 636 | auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state; | ||
| 637 | auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state; | ||
| 638 | |||
| 639 | // Clear previous state | ||
| 640 | sixaxis_fullkey_state = {}; | ||
| 641 | sixaxis_handheld_state = {}; | ||
| 642 | sixaxis_dual_left_state = {}; | ||
| 643 | sixaxis_dual_right_state = {}; | ||
| 644 | sixaxis_left_lifo_state = {}; | ||
| 645 | sixaxis_right_lifo_state = {}; | ||
| 646 | |||
| 647 | if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) { | ||
| 648 | controller.sixaxis_at_rest = true; | ||
| 649 | for (std::size_t e = 0; e < motion_state.size(); ++e) { | ||
| 650 | controller.sixaxis_at_rest = | ||
| 651 | controller.sixaxis_at_rest && motion_state[e].is_at_rest; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | |||
| 655 | const auto set_motion_state = [&](SixAxisSensorState& state, | ||
| 656 | const Core::HID::ControllerMotion& hid_state) { | ||
| 657 | using namespace std::literals::chrono_literals; | ||
| 658 | static constexpr SixAxisSensorState default_motion_state = { | ||
| 659 | .delta_time = std::chrono::nanoseconds(5ms).count(), | ||
| 660 | .accel = {0, 0, -1.0f}, | ||
| 661 | .orientation = | ||
| 662 | { | ||
| 663 | Common::Vec3f{1.0f, 0, 0}, | ||
| 664 | Common::Vec3f{0, 1.0f, 0}, | ||
| 665 | Common::Vec3f{0, 0, 1.0f}, | ||
| 666 | }, | ||
| 667 | .attribute = {1}, | ||
| 668 | }; | ||
| 669 | if (!controller.sixaxis_sensor_enabled) { | ||
| 670 | state = default_motion_state; | ||
| 671 | return; | ||
| 672 | } | ||
| 673 | if (!Settings::values.motion_enabled.GetValue()) { | ||
| 674 | state = default_motion_state; | ||
| 675 | return; | ||
| 676 | } | ||
| 677 | state.attribute.is_connected.Assign(1); | ||
| 678 | state.delta_time = std::chrono::nanoseconds(5ms).count(); | ||
| 679 | state.accel = hid_state.accel; | ||
| 680 | state.gyro = hid_state.gyro; | ||
| 681 | state.rotation = hid_state.rotation; | ||
| 682 | state.orientation = hid_state.orientation; | ||
| 683 | }; | ||
| 684 | |||
| 685 | switch (controller_type) { | ||
| 686 | case Core::HID::NpadStyleIndex::None: | ||
| 687 | ASSERT(false); | ||
| 688 | break; | ||
| 689 | case Core::HID::NpadStyleIndex::ProController: | ||
| 690 | set_motion_state(sixaxis_fullkey_state, motion_state[0]); | ||
| 691 | break; | ||
| 692 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 693 | set_motion_state(sixaxis_handheld_state, motion_state[0]); | ||
| 694 | break; | ||
| 695 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 696 | set_motion_state(sixaxis_dual_left_state, motion_state[0]); | ||
| 697 | set_motion_state(sixaxis_dual_right_state, motion_state[1]); | ||
| 698 | break; | ||
| 699 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 700 | set_motion_state(sixaxis_left_lifo_state, motion_state[0]); | ||
| 701 | break; | ||
| 702 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 703 | set_motion_state(sixaxis_right_lifo_state, motion_state[1]); | ||
| 704 | break; | ||
| 705 | case Core::HID::NpadStyleIndex::Pokeball: | ||
| 706 | using namespace std::literals::chrono_literals; | ||
| 707 | set_motion_state(sixaxis_fullkey_state, motion_state[0]); | ||
| 708 | sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count(); | ||
| 709 | break; | ||
| 710 | default: | ||
| 711 | break; | ||
| 712 | } | ||
| 713 | |||
| 714 | sixaxis_fullkey_state.sampling_number = | ||
| 715 | npad->sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 716 | sixaxis_handheld_state.sampling_number = | ||
| 717 | npad->sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 718 | sixaxis_dual_left_state.sampling_number = | ||
| 719 | npad->sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 720 | sixaxis_dual_right_state.sampling_number = | ||
| 721 | npad->sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 722 | sixaxis_left_lifo_state.sampling_number = | ||
| 723 | npad->sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 724 | sixaxis_right_lifo_state.sampling_number = | ||
| 725 | npad->sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 726 | |||
| 727 | if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { | ||
| 728 | // This buffer only is updated on handheld on HW | ||
| 729 | npad->sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); | ||
| 730 | } else { | ||
| 731 | // Handheld doesn't update this buffer on HW | ||
| 732 | npad->sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); | ||
| 733 | } | ||
| 734 | |||
| 735 | npad->sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); | ||
| 736 | npad->sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); | ||
| 737 | npad->sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); | ||
| 738 | npad->sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); | ||
| 739 | } | ||
| 740 | } | ||
| 741 | |||
| 742 | void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) { | ||
| 743 | hid_core.SetSupportedStyleTag(style_set); | 567 | hid_core.SetSupportedStyleTag(style_set); |
| 744 | 568 | ||
| 745 | if (is_controller_initialized) { | 569 | if (is_controller_initialized) { |
| @@ -750,14 +574,14 @@ void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) { | |||
| 750 | is_controller_initialized = true; | 574 | is_controller_initialized = true; |
| 751 | } | 575 | } |
| 752 | 576 | ||
| 753 | Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const { | 577 | Core::HID::NpadStyleTag NPad::GetSupportedStyleSet() const { |
| 754 | if (!is_controller_initialized) { | 578 | if (!is_controller_initialized) { |
| 755 | return {Core::HID::NpadStyleSet::None}; | 579 | return {Core::HID::NpadStyleSet::None}; |
| 756 | } | 580 | } |
| 757 | return hid_core.GetSupportedStyleTag(); | 581 | return hid_core.GetSupportedStyleTag(); |
| 758 | } | 582 | } |
| 759 | 583 | ||
| 760 | Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) { | 584 | Result NPad::SetSupportedNpadIdTypes(std::span<const u8> data) { |
| 761 | constexpr std::size_t max_number_npad_ids = 0xa; | 585 | constexpr std::size_t max_number_npad_ids = 0xa; |
| 762 | const auto length = data.size(); | 586 | const auto length = data.size(); |
| 763 | ASSERT(length > 0 && (length % sizeof(u32)) == 0); | 587 | ASSERT(length > 0 && (length % sizeof(u32)) == 0); |
| @@ -773,17 +597,17 @@ Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) { | |||
| 773 | return ResultSuccess; | 597 | return ResultSuccess; |
| 774 | } | 598 | } |
| 775 | 599 | ||
| 776 | void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { | 600 | void NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { |
| 777 | const auto copy_amount = supported_npad_id_types.size() * sizeof(u32); | 601 | const auto copy_amount = supported_npad_id_types.size() * sizeof(u32); |
| 778 | ASSERT(max_length <= copy_amount); | 602 | ASSERT(max_length <= copy_amount); |
| 779 | std::memcpy(data, supported_npad_id_types.data(), copy_amount); | 603 | std::memcpy(data, supported_npad_id_types.data(), copy_amount); |
| 780 | } | 604 | } |
| 781 | 605 | ||
| 782 | std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const { | 606 | std::size_t NPad::GetSupportedNpadIdTypesSize() const { |
| 783 | return supported_npad_id_types.size(); | 607 | return supported_npad_id_types.size(); |
| 784 | } | 608 | } |
| 785 | 609 | ||
| 786 | void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { | 610 | void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { |
| 787 | if (joy_hold_type != NpadJoyHoldType::Horizontal && | 611 | if (joy_hold_type != NpadJoyHoldType::Horizontal && |
| 788 | joy_hold_type != NpadJoyHoldType::Vertical) { | 612 | joy_hold_type != NpadJoyHoldType::Vertical) { |
| 789 | LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}", | 613 | LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}", |
| @@ -793,11 +617,11 @@ void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { | |||
| 793 | hold_type = joy_hold_type; | 617 | hold_type = joy_hold_type; |
| 794 | } | 618 | } |
| 795 | 619 | ||
| 796 | Controller_NPad::NpadJoyHoldType Controller_NPad::GetHoldType() const { | 620 | NPad::NpadJoyHoldType NPad::GetHoldType() const { |
| 797 | return hold_type; | 621 | return hold_type; |
| 798 | } | 622 | } |
| 799 | 623 | ||
| 800 | void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) { | 624 | void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) { |
| 801 | if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) { | 625 | if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) { |
| 802 | ASSERT_MSG(false, "Activation mode should be always None, Single or Dual"); | 626 | ASSERT_MSG(false, "Activation mode should be always None, Single or Dual"); |
| 803 | return; | 627 | return; |
| @@ -806,21 +630,20 @@ void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode a | |||
| 806 | handheld_activation_mode = activation_mode; | 630 | handheld_activation_mode = activation_mode; |
| 807 | } | 631 | } |
| 808 | 632 | ||
| 809 | Controller_NPad::NpadHandheldActivationMode Controller_NPad::GetNpadHandheldActivationMode() const { | 633 | NPad::NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { |
| 810 | return handheld_activation_mode; | 634 | return handheld_activation_mode; |
| 811 | } | 635 | } |
| 812 | 636 | ||
| 813 | void Controller_NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) { | 637 | void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) { |
| 814 | communication_mode = communication_mode_; | 638 | communication_mode = communication_mode_; |
| 815 | } | 639 | } |
| 816 | 640 | ||
| 817 | Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode() const { | 641 | NPad::NpadCommunicationMode NPad::GetNpadCommunicationMode() const { |
| 818 | return communication_mode; | 642 | return communication_mode; |
| 819 | } | 643 | } |
| 820 | 644 | ||
| 821 | bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, | 645 | bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, |
| 822 | NpadJoyDeviceType npad_device_type, | 646 | NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) { |
| 823 | NpadJoyAssignmentMode assignment_mode) { | ||
| 824 | if (!IsNpadIdValid(npad_id)) { | 647 | if (!IsNpadIdValid(npad_id)) { |
| 825 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 648 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 826 | return false; | 649 | return false; |
| @@ -889,9 +712,8 @@ bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID: | |||
| 889 | return true; | 712 | return true; |
| 890 | } | 713 | } |
| 891 | 714 | ||
| 892 | bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, | 715 | bool NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, |
| 893 | std::size_t device_index, | 716 | const Core::HID::VibrationValue& vibration_value) { |
| 894 | const Core::HID::VibrationValue& vibration_value) { | ||
| 895 | auto& controller = GetControllerFromNpadIdType(npad_id); | 717 | auto& controller = GetControllerFromNpadIdType(npad_id); |
| 896 | if (!controller.device->IsConnected()) { | 718 | if (!controller.device->IsConnected()) { |
| 897 | return false; | 719 | return false; |
| @@ -935,10 +757,9 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, | |||
| 935 | return controller.device->SetVibration(device_index, vibration); | 757 | return controller.device->SetVibration(device_index, vibration); |
| 936 | } | 758 | } |
| 937 | 759 | ||
| 938 | void Controller_NPad::VibrateController( | 760 | void NPad::VibrateController(const Core::HID::VibrationDeviceHandle& vibration_device_handle, |
| 939 | const Core::HID::VibrationDeviceHandle& vibration_device_handle, | 761 | const Core::HID::VibrationValue& vibration_value) { |
| 940 | const Core::HID::VibrationValue& vibration_value) { | 762 | if (IsVibrationHandleValid(vibration_device_handle).IsError()) { |
| 941 | if (IsDeviceHandleValid(vibration_device_handle).IsError()) { | ||
| 942 | return; | 763 | return; |
| 943 | } | 764 | } |
| 944 | 765 | ||
| @@ -982,7 +803,7 @@ void Controller_NPad::VibrateController( | |||
| 982 | } | 803 | } |
| 983 | } | 804 | } |
| 984 | 805 | ||
| 985 | void Controller_NPad::VibrateControllers( | 806 | void NPad::VibrateControllers( |
| 986 | std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, | 807 | std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, |
| 987 | std::span<const Core::HID::VibrationValue> vibration_values) { | 808 | std::span<const Core::HID::VibrationValue> vibration_values) { |
| 988 | if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { | 809 | if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { |
| @@ -999,9 +820,9 @@ void Controller_NPad::VibrateControllers( | |||
| 999 | } | 820 | } |
| 1000 | } | 821 | } |
| 1001 | 822 | ||
| 1002 | Core::HID::VibrationValue Controller_NPad::GetLastVibration( | 823 | Core::HID::VibrationValue NPad::GetLastVibration( |
| 1003 | const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { | 824 | const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { |
| 1004 | if (IsDeviceHandleValid(vibration_device_handle).IsError()) { | 825 | if (IsVibrationHandleValid(vibration_device_handle).IsError()) { |
| 1005 | return {}; | 826 | return {}; |
| 1006 | } | 827 | } |
| 1007 | 828 | ||
| @@ -1010,9 +831,9 @@ Core::HID::VibrationValue Controller_NPad::GetLastVibration( | |||
| 1010 | return controller.vibration[device_index].latest_vibration_value; | 831 | return controller.vibration[device_index].latest_vibration_value; |
| 1011 | } | 832 | } |
| 1012 | 833 | ||
| 1013 | void Controller_NPad::InitializeVibrationDevice( | 834 | void NPad::InitializeVibrationDevice( |
| 1014 | const Core::HID::VibrationDeviceHandle& vibration_device_handle) { | 835 | const Core::HID::VibrationDeviceHandle& vibration_device_handle) { |
| 1015 | if (IsDeviceHandleValid(vibration_device_handle).IsError()) { | 836 | if (IsVibrationHandleValid(vibration_device_handle).IsError()) { |
| 1016 | return; | 837 | return; |
| 1017 | } | 838 | } |
| 1018 | 839 | ||
| @@ -1021,8 +842,8 @@ void Controller_NPad::InitializeVibrationDevice( | |||
| 1021 | InitializeVibrationDeviceAtIndex(npad_index, device_index); | 842 | InitializeVibrationDeviceAtIndex(npad_index, device_index); |
| 1022 | } | 843 | } |
| 1023 | 844 | ||
| 1024 | void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id, | 845 | void NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id, |
| 1025 | std::size_t device_index) { | 846 | std::size_t device_index) { |
| 1026 | auto& controller = GetControllerFromNpadIdType(npad_id); | 847 | auto& controller = GetControllerFromNpadIdType(npad_id); |
| 1027 | if (!Settings::values.vibration_enabled.GetValue()) { | 848 | if (!Settings::values.vibration_enabled.GetValue()) { |
| 1028 | controller.vibration[device_index].device_mounted = false; | 849 | controller.vibration[device_index].device_mounted = false; |
| @@ -1033,13 +854,13 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa | |||
| 1033 | controller.device->IsVibrationEnabled(device_index); | 854 | controller.device->IsVibrationEnabled(device_index); |
| 1034 | } | 855 | } |
| 1035 | 856 | ||
| 1036 | void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { | 857 | void NPad::SetPermitVibrationSession(bool permit_vibration_session) { |
| 1037 | permit_vibration_session_enabled = permit_vibration_session; | 858 | permit_vibration_session_enabled = permit_vibration_session; |
| 1038 | } | 859 | } |
| 1039 | 860 | ||
| 1040 | bool Controller_NPad::IsVibrationDeviceMounted( | 861 | bool NPad::IsVibrationDeviceMounted( |
| 1041 | const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { | 862 | const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { |
| 1042 | if (IsDeviceHandleValid(vibration_device_handle).IsError()) { | 863 | if (IsVibrationHandleValid(vibration_device_handle).IsError()) { |
| 1043 | return false; | 864 | return false; |
| 1044 | } | 865 | } |
| 1045 | 866 | ||
| @@ -1048,7 +869,7 @@ bool Controller_NPad::IsVibrationDeviceMounted( | |||
| 1048 | return controller.vibration[device_index].device_mounted; | 869 | return controller.vibration[device_index].device_mounted; |
| 1049 | } | 870 | } |
| 1050 | 871 | ||
| 1051 | Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) { | 872 | Kernel::KReadableEvent& NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) { |
| 1052 | if (!IsNpadIdValid(npad_id)) { | 873 | if (!IsNpadIdValid(npad_id)) { |
| 1053 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 874 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1054 | // Fallback to player 1 | 875 | // Fallback to player 1 |
| @@ -1060,18 +881,17 @@ Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::Npad | |||
| 1060 | return controller.styleset_changed_event->GetReadableEvent(); | 881 | return controller.styleset_changed_event->GetReadableEvent(); |
| 1061 | } | 882 | } |
| 1062 | 883 | ||
| 1063 | void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const { | 884 | void NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const { |
| 1064 | const auto& controller = GetControllerFromNpadIdType(npad_id); | 885 | const auto& controller = GetControllerFromNpadIdType(npad_id); |
| 1065 | controller.styleset_changed_event->Signal(); | 886 | controller.styleset_changed_event->Signal(); |
| 1066 | } | 887 | } |
| 1067 | 888 | ||
| 1068 | void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, | 889 | void NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id) { |
| 1069 | Core::HID::NpadIdType npad_id) { | ||
| 1070 | UpdateControllerAt(controller, npad_id, true); | 890 | UpdateControllerAt(controller, npad_id, true); |
| 1071 | } | 891 | } |
| 1072 | 892 | ||
| 1073 | void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, | 893 | void NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, Core::HID::NpadIdType npad_id, |
| 1074 | Core::HID::NpadIdType npad_id, bool connected) { | 894 | bool connected) { |
| 1075 | auto& controller = GetControllerFromNpadIdType(npad_id); | 895 | auto& controller = GetControllerFromNpadIdType(npad_id); |
| 1076 | if (!connected) { | 896 | if (!connected) { |
| 1077 | DisconnectNpad(npad_id); | 897 | DisconnectNpad(npad_id); |
| @@ -1082,7 +902,7 @@ void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, | |||
| 1082 | InitNewlyAddedController(npad_id); | 902 | InitNewlyAddedController(npad_id); |
| 1083 | } | 903 | } |
| 1084 | 904 | ||
| 1085 | Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | 905 | Result NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { |
| 1086 | if (!IsNpadIdValid(npad_id)) { | 906 | if (!IsNpadIdValid(npad_id)) { |
| 1087 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 907 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1088 | return InvalidNpadId; | 908 | return InvalidNpadId; |
| @@ -1108,9 +928,9 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | |||
| 1108 | shared_memory->sixaxis_dual_right_properties.raw = 0; | 928 | shared_memory->sixaxis_dual_right_properties.raw = 0; |
| 1109 | shared_memory->sixaxis_left_properties.raw = 0; | 929 | shared_memory->sixaxis_left_properties.raw = 0; |
| 1110 | shared_memory->sixaxis_right_properties.raw = 0; | 930 | shared_memory->sixaxis_right_properties.raw = 0; |
| 1111 | shared_memory->battery_level_dual = 0; | 931 | shared_memory->battery_level_dual = Core::HID::NpadBatteryLevel::Empty; |
| 1112 | shared_memory->battery_level_left = 0; | 932 | shared_memory->battery_level_left = Core::HID::NpadBatteryLevel::Empty; |
| 1113 | shared_memory->battery_level_right = 0; | 933 | shared_memory->battery_level_right = Core::HID::NpadBatteryLevel::Empty; |
| 1114 | shared_memory->fullkey_color = { | 934 | shared_memory->fullkey_color = { |
| 1115 | .attribute = ColorAttribute::NoController, | 935 | .attribute = ColorAttribute::NoController, |
| 1116 | .fullkey = {}, | 936 | .fullkey = {}, |
| @@ -1131,54 +951,9 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | |||
| 1131 | return ResultSuccess; | 951 | return ResultSuccess; |
| 1132 | } | 952 | } |
| 1133 | 953 | ||
| 1134 | Result Controller_NPad::SetGyroscopeZeroDriftMode( | 954 | Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor( |
| 1135 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 1136 | Core::HID::GyroscopeZeroDriftMode drift_mode) { | ||
| 1137 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1138 | if (is_valid.IsError()) { | ||
| 1139 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1140 | return is_valid; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1144 | auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 1145 | sixaxis.gyroscope_zero_drift_mode = drift_mode; | ||
| 1146 | controller.device->SetGyroscopeZeroDriftMode(drift_mode); | ||
| 1147 | |||
| 1148 | return ResultSuccess; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | Result Controller_NPad::GetGyroscopeZeroDriftMode( | ||
| 1152 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 1153 | Core::HID::GyroscopeZeroDriftMode& drift_mode) const { | ||
| 1154 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1155 | if (is_valid.IsError()) { | ||
| 1156 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1157 | return is_valid; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1161 | drift_mode = sixaxis.gyroscope_zero_drift_mode; | ||
| 1162 | |||
| 1163 | return ResultSuccess; | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | Result Controller_NPad::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 1167 | bool& is_at_rest) const { | ||
| 1168 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1169 | if (is_valid.IsError()) { | ||
| 1170 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1171 | return is_valid; | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | const auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 1175 | is_at_rest = controller.sixaxis_at_rest; | ||
| 1176 | return ResultSuccess; | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | Result Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor( | ||
| 1180 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const { | 955 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const { |
| 1181 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 956 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); |
| 1182 | if (is_valid.IsError()) { | 957 | if (is_valid.IsError()) { |
| 1183 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | 958 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); |
| 1184 | return is_valid; | 959 | return is_valid; |
| @@ -1189,65 +964,9 @@ Result Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor( | |||
| 1189 | return ResultSuccess; | 964 | return ResultSuccess; |
| 1190 | } | 965 | } |
| 1191 | 966 | ||
| 1192 | Result Controller_NPad::EnableSixAxisSensorUnalteredPassthrough( | 967 | Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( |
| 1193 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) { | ||
| 1194 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1195 | if (is_valid.IsError()) { | ||
| 1196 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1197 | return is_valid; | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1201 | sixaxis.unaltered_passtrough = is_enabled; | ||
| 1202 | return ResultSuccess; | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | Result Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled( | ||
| 1206 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const { | ||
| 1207 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1208 | if (is_valid.IsError()) { | ||
| 1209 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1210 | return is_valid; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1214 | is_enabled = sixaxis.unaltered_passtrough; | ||
| 1215 | return ResultSuccess; | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | Result Controller_NPad::LoadSixAxisSensorCalibrationParameter( | ||
| 1219 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 1220 | Core::HID::SixAxisSensorCalibrationParameter& calibration) const { | ||
| 1221 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1222 | if (is_valid.IsError()) { | ||
| 1223 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1224 | return is_valid; | ||
| 1225 | } | ||
| 1226 | |||
| 1227 | // TODO: Request this data to the controller. On error return 0xd8ca | ||
| 1228 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1229 | calibration = sixaxis.calibration; | ||
| 1230 | return ResultSuccess; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | Result Controller_NPad::GetSixAxisSensorIcInformation( | ||
| 1234 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 1235 | Core::HID::SixAxisSensorIcInformation& ic_information) const { | ||
| 1236 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1237 | if (is_valid.IsError()) { | ||
| 1238 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1239 | return is_valid; | ||
| 1240 | } | ||
| 1241 | |||
| 1242 | // TODO: Request this data to the controller. On error return 0xd8ca | ||
| 1243 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1244 | ic_information = sixaxis.ic_information; | ||
| 1245 | return ResultSuccess; | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | Result Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( | ||
| 1249 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) { | 968 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) { |
| 1250 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 969 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); |
| 1251 | if (is_valid.IsError()) { | 970 | if (is_valid.IsError()) { |
| 1252 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | 971 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); |
| 1253 | return is_valid; | 972 | return is_valid; |
| @@ -1259,83 +978,32 @@ Result Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( | |||
| 1259 | return ResultSuccess; | 978 | return ResultSuccess; |
| 1260 | } | 979 | } |
| 1261 | 980 | ||
| 1262 | Result Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 981 | NPad::SixAxisLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) { |
| 1263 | bool sixaxis_status) { | 982 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo; |
| 1264 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1265 | if (is_valid.IsError()) { | ||
| 1266 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1267 | return is_valid; | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 1271 | controller.sixaxis_sensor_enabled = sixaxis_status; | ||
| 1272 | return ResultSuccess; | ||
| 1273 | } | 983 | } |
| 1274 | 984 | ||
| 1275 | Result Controller_NPad::IsSixAxisSensorFusionEnabled( | 985 | NPad::SixAxisLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) { |
| 1276 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const { | 986 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo; |
| 1277 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1278 | if (is_valid.IsError()) { | ||
| 1279 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1280 | return is_valid; | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1284 | is_fusion_enabled = sixaxis.is_fusion_enabled; | ||
| 1285 | |||
| 1286 | return ResultSuccess; | ||
| 1287 | } | 987 | } |
| 1288 | Result Controller_NPad::SetSixAxisFusionEnabled( | ||
| 1289 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) { | ||
| 1290 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1291 | if (is_valid.IsError()) { | ||
| 1292 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1293 | return is_valid; | ||
| 1294 | } | ||
| 1295 | 988 | ||
| 1296 | auto& sixaxis = GetSixaxisState(sixaxis_handle); | 989 | NPad::SixAxisLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) { |
| 1297 | sixaxis.is_fusion_enabled = is_fusion_enabled; | 990 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo; |
| 1298 | |||
| 1299 | return ResultSuccess; | ||
| 1300 | } | 991 | } |
| 1301 | 992 | ||
| 1302 | Result Controller_NPad::SetSixAxisFusionParameters( | 993 | NPad::SixAxisLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) { |
| 1303 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 994 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo; |
| 1304 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) { | ||
| 1305 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1306 | if (is_valid.IsError()) { | ||
| 1307 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1308 | return is_valid; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | const auto param1 = sixaxis_fusion_parameters.parameter1; | ||
| 1312 | if (param1 < 0.0f || param1 > 1.0f) { | ||
| 1313 | return InvalidSixAxisFusionRange; | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1317 | sixaxis.fusion = sixaxis_fusion_parameters; | ||
| 1318 | |||
| 1319 | return ResultSuccess; | ||
| 1320 | } | 995 | } |
| 1321 | 996 | ||
| 1322 | Result Controller_NPad::GetSixAxisFusionParameters( | 997 | NPad::SixAxisLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) { |
| 1323 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 998 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo; |
| 1324 | Core::HID::SixAxisSensorFusionParameters& parameters) const { | 999 | } |
| 1325 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||
| 1326 | if (is_valid.IsError()) { | ||
| 1327 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 1328 | return is_valid; | ||
| 1329 | } | ||
| 1330 | |||
| 1331 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 1332 | parameters = sixaxis.fusion; | ||
| 1333 | 1000 | ||
| 1334 | return ResultSuccess; | 1001 | NPad::SixAxisLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) { |
| 1002 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo; | ||
| 1335 | } | 1003 | } |
| 1336 | 1004 | ||
| 1337 | Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, | 1005 | Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, |
| 1338 | Core::HID::NpadIdType npad_id_2) { | 1006 | Core::HID::NpadIdType npad_id_2) { |
| 1339 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { | 1007 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { |
| 1340 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, | 1008 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, |
| 1341 | npad_id_2); | 1009 | npad_id_2); |
| @@ -1397,18 +1065,17 @@ Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, | |||
| 1397 | return ResultSuccess; | 1065 | return ResultSuccess; |
| 1398 | } | 1066 | } |
| 1399 | 1067 | ||
| 1400 | void Controller_NPad::StartLRAssignmentMode() { | 1068 | void NPad::StartLRAssignmentMode() { |
| 1401 | // Nothing internally is used for lr assignment mode. Since we have the ability to set the | 1069 | // Nothing internally is used for lr assignment mode. Since we have the ability to set the |
| 1402 | // controller types from boot, it doesn't really matter about showing a selection screen | 1070 | // controller types from boot, it doesn't really matter about showing a selection screen |
| 1403 | is_in_lr_assignment_mode = true; | 1071 | is_in_lr_assignment_mode = true; |
| 1404 | } | 1072 | } |
| 1405 | 1073 | ||
| 1406 | void Controller_NPad::StopLRAssignmentMode() { | 1074 | void NPad::StopLRAssignmentMode() { |
| 1407 | is_in_lr_assignment_mode = false; | 1075 | is_in_lr_assignment_mode = false; |
| 1408 | } | 1076 | } |
| 1409 | 1077 | ||
| 1410 | Result Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, | 1078 | Result NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2) { |
| 1411 | Core::HID::NpadIdType npad_id_2) { | ||
| 1412 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { | 1079 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { |
| 1413 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, | 1080 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, |
| 1414 | npad_id_2); | 1081 | npad_id_2); |
| @@ -1439,8 +1106,7 @@ Result Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, | |||
| 1439 | return ResultSuccess; | 1106 | return ResultSuccess; |
| 1440 | } | 1107 | } |
| 1441 | 1108 | ||
| 1442 | Result Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id, | 1109 | Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const { |
| 1443 | Core::HID::LedPattern& pattern) const { | ||
| 1444 | if (!IsNpadIdValid(npad_id)) { | 1110 | if (!IsNpadIdValid(npad_id)) { |
| 1445 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 1111 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1446 | return InvalidNpadId; | 1112 | return InvalidNpadId; |
| @@ -1450,8 +1116,8 @@ Result Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id, | |||
| 1450 | return ResultSuccess; | 1116 | return ResultSuccess; |
| 1451 | } | 1117 | } |
| 1452 | 1118 | ||
| 1453 | Result Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, | 1119 | Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, |
| 1454 | bool& is_valid) const { | 1120 | bool& is_valid) const { |
| 1455 | if (!IsNpadIdValid(npad_id)) { | 1121 | if (!IsNpadIdValid(npad_id)) { |
| 1456 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 1122 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1457 | return InvalidNpadId; | 1123 | return InvalidNpadId; |
| @@ -1461,8 +1127,8 @@ Result Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID:: | |||
| 1461 | return ResultSuccess; | 1127 | return ResultSuccess; |
| 1462 | } | 1128 | } |
| 1463 | 1129 | ||
| 1464 | Result Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled( | 1130 | Result NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, |
| 1465 | bool is_protection_enabled, Core::HID::NpadIdType npad_id) { | 1131 | Core::HID::NpadIdType npad_id) { |
| 1466 | if (!IsNpadIdValid(npad_id)) { | 1132 | if (!IsNpadIdValid(npad_id)) { |
| 1467 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 1133 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1468 | return InvalidNpadId; | 1134 | return InvalidNpadId; |
| @@ -1472,11 +1138,11 @@ Result Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled( | |||
| 1472 | return ResultSuccess; | 1138 | return ResultSuccess; |
| 1473 | } | 1139 | } |
| 1474 | 1140 | ||
| 1475 | void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) { | 1141 | void NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) { |
| 1476 | analog_stick_use_center_clamp = use_center_clamp; | 1142 | analog_stick_use_center_clamp = use_center_clamp; |
| 1477 | } | 1143 | } |
| 1478 | 1144 | ||
| 1479 | void Controller_NPad::ClearAllConnectedControllers() { | 1145 | void NPad::ClearAllConnectedControllers() { |
| 1480 | for (auto& controller : controller_data) { | 1146 | for (auto& controller : controller_data) { |
| 1481 | if (controller.device->IsConnected() && | 1147 | if (controller.device->IsConnected() && |
| 1482 | controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) { | 1148 | controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) { |
| @@ -1486,13 +1152,13 @@ void Controller_NPad::ClearAllConnectedControllers() { | |||
| 1486 | } | 1152 | } |
| 1487 | } | 1153 | } |
| 1488 | 1154 | ||
| 1489 | void Controller_NPad::DisconnectAllConnectedControllers() { | 1155 | void NPad::DisconnectAllConnectedControllers() { |
| 1490 | for (auto& controller : controller_data) { | 1156 | for (auto& controller : controller_data) { |
| 1491 | controller.device->Disconnect(); | 1157 | controller.device->Disconnect(); |
| 1492 | } | 1158 | } |
| 1493 | } | 1159 | } |
| 1494 | 1160 | ||
| 1495 | void Controller_NPad::ConnectAllDisconnectedControllers() { | 1161 | void NPad::ConnectAllDisconnectedControllers() { |
| 1496 | for (auto& controller : controller_data) { | 1162 | for (auto& controller : controller_data) { |
| 1497 | if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None && | 1163 | if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None && |
| 1498 | !controller.device->IsConnected()) { | 1164 | !controller.device->IsConnected()) { |
| @@ -1501,18 +1167,18 @@ void Controller_NPad::ConnectAllDisconnectedControllers() { | |||
| 1501 | } | 1167 | } |
| 1502 | } | 1168 | } |
| 1503 | 1169 | ||
| 1504 | void Controller_NPad::ClearAllControllers() { | 1170 | void NPad::ClearAllControllers() { |
| 1505 | for (auto& controller : controller_data) { | 1171 | for (auto& controller : controller_data) { |
| 1506 | controller.device->Disconnect(); | 1172 | controller.device->Disconnect(); |
| 1507 | controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None); | 1173 | controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None); |
| 1508 | } | 1174 | } |
| 1509 | } | 1175 | } |
| 1510 | 1176 | ||
| 1511 | Core::HID::NpadButton Controller_NPad::GetAndResetPressState() { | 1177 | Core::HID::NpadButton NPad::GetAndResetPressState() { |
| 1512 | return static_cast<Core::HID::NpadButton>(press_state.exchange(0)); | 1178 | return static_cast<Core::HID::NpadButton>(press_state.exchange(0)); |
| 1513 | } | 1179 | } |
| 1514 | 1180 | ||
| 1515 | void Controller_NPad::ApplyNpadSystemCommonPolicy() { | 1181 | void NPad::ApplyNpadSystemCommonPolicy() { |
| 1516 | Core::HID::NpadStyleTag styletag{}; | 1182 | Core::HID::NpadStyleTag styletag{}; |
| 1517 | styletag.fullkey.Assign(1); | 1183 | styletag.fullkey.Assign(1); |
| 1518 | styletag.handheld.Assign(1); | 1184 | styletag.handheld.Assign(1); |
| @@ -1537,7 +1203,7 @@ void Controller_NPad::ApplyNpadSystemCommonPolicy() { | |||
| 1537 | supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld; | 1203 | supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld; |
| 1538 | } | 1204 | } |
| 1539 | 1205 | ||
| 1540 | bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const { | 1206 | bool NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const { |
| 1541 | if (controller == Core::HID::NpadStyleIndex::Handheld) { | 1207 | if (controller == Core::HID::NpadStyleIndex::Handheld) { |
| 1542 | const bool support_handheld = | 1208 | const bool support_handheld = |
| 1543 | std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), | 1209 | std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), |
| @@ -1588,51 +1254,50 @@ bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller | |||
| 1588 | return false; | 1254 | return false; |
| 1589 | } | 1255 | } |
| 1590 | 1256 | ||
| 1591 | Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle( | 1257 | NPad::NpadControllerData& NPad::GetControllerFromHandle( |
| 1592 | const Core::HID::SixAxisSensorHandle& device_handle) { | 1258 | const Core::HID::VibrationDeviceHandle& device_handle) { |
| 1593 | 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); |
| 1594 | return GetControllerFromNpadIdType(npad_id); | 1260 | return GetControllerFromNpadIdType(npad_id); |
| 1595 | } | 1261 | } |
| 1596 | 1262 | ||
| 1597 | const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle( | 1263 | const NPad::NpadControllerData& NPad::GetControllerFromHandle( |
| 1598 | const Core::HID::SixAxisSensorHandle& device_handle) const { | 1264 | const Core::HID::VibrationDeviceHandle& device_handle) const { |
| 1599 | 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); |
| 1600 | return GetControllerFromNpadIdType(npad_id); | 1266 | return GetControllerFromNpadIdType(npad_id); |
| 1601 | } | 1267 | } |
| 1602 | 1268 | ||
| 1603 | Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle( | 1269 | NPad::NpadControllerData& NPad::GetControllerFromHandle( |
| 1604 | const Core::HID::VibrationDeviceHandle& device_handle) { | 1270 | const Core::HID::SixAxisSensorHandle& device_handle) { |
| 1605 | const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); | 1271 | const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); |
| 1606 | return GetControllerFromNpadIdType(npad_id); | 1272 | return GetControllerFromNpadIdType(npad_id); |
| 1607 | } | 1273 | } |
| 1608 | 1274 | ||
| 1609 | const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle( | 1275 | const NPad::NpadControllerData& NPad::GetControllerFromHandle( |
| 1610 | const Core::HID::VibrationDeviceHandle& device_handle) const { | 1276 | const Core::HID::SixAxisSensorHandle& device_handle) const { |
| 1611 | const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); | 1277 | const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); |
| 1612 | return GetControllerFromNpadIdType(npad_id); | 1278 | return GetControllerFromNpadIdType(npad_id); |
| 1613 | } | 1279 | } |
| 1614 | 1280 | ||
| 1615 | Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType( | 1281 | NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) { |
| 1616 | Core::HID::NpadIdType npad_id) { | ||
| 1617 | if (!IsNpadIdValid(npad_id)) { | 1282 | if (!IsNpadIdValid(npad_id)) { |
| 1618 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 1283 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1619 | npad_id = Core::HID::NpadIdType::Player1; | 1284 | npad_id = Core::HID::NpadIdType::Player1; |
| 1620 | } | 1285 | } |
| 1621 | const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id); | 1286 | const auto npad_index = NpadIdTypeToIndex(npad_id); |
| 1622 | return controller_data[npad_index]; | 1287 | return controller_data[npad_index]; |
| 1623 | } | 1288 | } |
| 1624 | 1289 | ||
| 1625 | const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType( | 1290 | const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType( |
| 1626 | Core::HID::NpadIdType npad_id) const { | 1291 | Core::HID::NpadIdType npad_id) const { |
| 1627 | if (!IsNpadIdValid(npad_id)) { | 1292 | if (!IsNpadIdValid(npad_id)) { |
| 1628 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 1293 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1629 | npad_id = Core::HID::NpadIdType::Player1; | 1294 | npad_id = Core::HID::NpadIdType::Player1; |
| 1630 | } | 1295 | } |
| 1631 | const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id); | 1296 | const auto npad_index = NpadIdTypeToIndex(npad_id); |
| 1632 | return controller_data[npad_index]; | 1297 | return controller_data[npad_index]; |
| 1633 | } | 1298 | } |
| 1634 | 1299 | ||
| 1635 | Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties( | 1300 | Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( |
| 1636 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) { | 1301 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) { |
| 1637 | auto& controller = GetControllerFromHandle(sixaxis_handle); | 1302 | auto& controller = GetControllerFromHandle(sixaxis_handle); |
| 1638 | switch (sixaxis_handle.npad_type) { | 1303 | switch (sixaxis_handle.npad_type) { |
| @@ -1655,7 +1320,7 @@ Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties( | |||
| 1655 | } | 1320 | } |
| 1656 | } | 1321 | } |
| 1657 | 1322 | ||
| 1658 | const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties( | 1323 | const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( |
| 1659 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { | 1324 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { |
| 1660 | const auto& controller = GetControllerFromHandle(sixaxis_handle); | 1325 | const auto& controller = GetControllerFromHandle(sixaxis_handle); |
| 1661 | switch (sixaxis_handle.npad_type) { | 1326 | switch (sixaxis_handle.npad_type) { |
| @@ -1678,50 +1343,13 @@ const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties( | |||
| 1678 | } | 1343 | } |
| 1679 | } | 1344 | } |
| 1680 | 1345 | ||
| 1681 | Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState( | 1346 | NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { |
| 1682 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) { | 1347 | const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory; |
| 1683 | auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 1684 | switch (sixaxis_handle.npad_type) { | ||
| 1685 | case Core::HID::NpadStyleIndex::ProController: | ||
| 1686 | case Core::HID::NpadStyleIndex::Pokeball: | ||
| 1687 | return controller.sixaxis_fullkey; | ||
| 1688 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 1689 | return controller.sixaxis_handheld; | ||
| 1690 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 1691 | if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { | ||
| 1692 | return controller.sixaxis_dual_left; | ||
| 1693 | } | ||
| 1694 | return controller.sixaxis_dual_right; | ||
| 1695 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 1696 | return controller.sixaxis_left; | ||
| 1697 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 1698 | return controller.sixaxis_right; | ||
| 1699 | default: | ||
| 1700 | return controller.sixaxis_unknown; | ||
| 1701 | } | ||
| 1702 | } | ||
| 1703 | 1348 | ||
| 1704 | const Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState( | 1349 | return { |
| 1705 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { | 1350 | .ui_variant = 0, |
| 1706 | const auto& controller = GetControllerFromHandle(sixaxis_handle); | 1351 | .footer = shared_memory->applet_footer_type, |
| 1707 | switch (sixaxis_handle.npad_type) { | 1352 | }; |
| 1708 | case Core::HID::NpadStyleIndex::ProController: | ||
| 1709 | case Core::HID::NpadStyleIndex::Pokeball: | ||
| 1710 | return controller.sixaxis_fullkey; | ||
| 1711 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 1712 | return controller.sixaxis_handheld; | ||
| 1713 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 1714 | if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { | ||
| 1715 | return controller.sixaxis_dual_left; | ||
| 1716 | } | ||
| 1717 | return controller.sixaxis_dual_right; | ||
| 1718 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 1719 | return controller.sixaxis_left; | ||
| 1720 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 1721 | return controller.sixaxis_right; | ||
| 1722 | default: | ||
| 1723 | return controller.sixaxis_unknown; | ||
| 1724 | } | ||
| 1725 | } | 1353 | } |
| 1726 | 1354 | ||
| 1727 | } // namespace Service::HID | 1355 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 949e58a4c..9167c93f0 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | 10 | ||
| 11 | #include "common/bit_field.h" | 11 | #include "common/bit_field.h" |
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "common/vector_math.h" | ||
| 14 | 13 | ||
| 15 | #include "core/hid/hid_types.h" | 14 | #include "core/hid/hid_types.h" |
| 16 | #include "core/hle/service/hid/controllers/controller_base.h" | 15 | #include "core/hle/service/hid/controllers/controller_base.h" |
| @@ -34,11 +33,11 @@ union Result; | |||
| 34 | 33 | ||
| 35 | namespace Service::HID { | 34 | namespace Service::HID { |
| 36 | 35 | ||
| 37 | class Controller_NPad final : public ControllerBase { | 36 | class NPad final : public ControllerBase { |
| 38 | public: | 37 | public: |
| 39 | explicit Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | 38 | explicit NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, |
| 40 | KernelHelpers::ServiceContext& service_context_); | 39 | KernelHelpers::ServiceContext& service_context_); |
| 41 | ~Controller_NPad() override; | 40 | ~NPad() override; |
| 42 | 41 | ||
| 43 | // Called when the controller is initialized | 42 | // Called when the controller is initialized |
| 44 | void OnInit() override; | 43 | void OnInit() override; |
| @@ -49,9 +48,6 @@ public: | |||
| 49 | // When the controller is requesting an update for the shared memory | 48 | // When the controller is requesting an update for the shared memory |
| 50 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 49 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 51 | 50 | ||
| 52 | // When the controller is requesting a motion update for the shared memory | ||
| 53 | void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||
| 54 | |||
| 55 | // This is nn::hid::NpadJoyHoldType | 51 | // This is nn::hid::NpadJoyHoldType |
| 56 | enum class NpadJoyHoldType : u64 { | 52 | enum class NpadJoyHoldType : u64 { |
| 57 | Vertical = 0, | 53 | Vertical = 0, |
| @@ -78,6 +74,46 @@ public: | |||
| 78 | MaxActivationMode = 3, | 74 | MaxActivationMode = 3, |
| 79 | }; | 75 | }; |
| 80 | 76 | ||
| 77 | // This is nn::hid::system::AppletFooterUiAttributesSet | ||
| 78 | struct AppletFooterUiAttributes { | ||
| 79 | INSERT_PADDING_BYTES(0x4); | ||
| 80 | }; | ||
| 81 | |||
| 82 | // This is nn::hid::system::AppletFooterUiType | ||
| 83 | enum class AppletFooterUiType : u8 { | ||
| 84 | None = 0, | ||
| 85 | HandheldNone = 1, | ||
| 86 | HandheldJoyConLeftOnly = 2, | ||
| 87 | HandheldJoyConRightOnly = 3, | ||
| 88 | HandheldJoyConLeftJoyConRight = 4, | ||
| 89 | JoyDual = 5, | ||
| 90 | JoyDualLeftOnly = 6, | ||
| 91 | JoyDualRightOnly = 7, | ||
| 92 | JoyLeftHorizontal = 8, | ||
| 93 | JoyLeftVertical = 9, | ||
| 94 | JoyRightHorizontal = 10, | ||
| 95 | JoyRightVertical = 11, | ||
| 96 | SwitchProController = 12, | ||
| 97 | CompatibleProController = 13, | ||
| 98 | CompatibleJoyCon = 14, | ||
| 99 | LarkHvc1 = 15, | ||
| 100 | LarkHvc2 = 16, | ||
| 101 | LarkNesLeft = 17, | ||
| 102 | LarkNesRight = 18, | ||
| 103 | Lucia = 19, | ||
| 104 | Verification = 20, | ||
| 105 | Lagon = 21, | ||
| 106 | }; | ||
| 107 | |||
| 108 | using AppletFooterUiVariant = u8; | ||
| 109 | |||
| 110 | // This is "nn::hid::system::AppletDetailedUiType". | ||
| 111 | struct AppletDetailedUiType { | ||
| 112 | AppletFooterUiVariant ui_variant; | ||
| 113 | INSERT_PADDING_BYTES(0x2); | ||
| 114 | AppletFooterUiType footer; | ||
| 115 | }; | ||
| 116 | static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); | ||
| 81 | // This is nn::hid::NpadCommunicationMode | 117 | // This is nn::hid::NpadCommunicationMode |
| 82 | enum class NpadCommunicationMode : u64 { | 118 | enum class NpadCommunicationMode : u64 { |
| 83 | Mode_5ms = 0, | 119 | Mode_5ms = 0, |
| @@ -86,6 +122,15 @@ public: | |||
| 86 | Default = 3, | 122 | Default = 3, |
| 87 | }; | 123 | }; |
| 88 | 124 | ||
| 125 | enum class NpadRevision : u32 { | ||
| 126 | Revision0 = 0, | ||
| 127 | Revision1 = 1, | ||
| 128 | Revision2 = 2, | ||
| 129 | Revision3 = 3, | ||
| 130 | }; | ||
| 131 | |||
| 132 | using SixAxisLifo = Lifo<Core::HID::SixAxisSensorState, hid_entry_count>; | ||
| 133 | |||
| 89 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); | 134 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); |
| 90 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; | 135 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; |
| 91 | 136 | ||
| @@ -138,37 +183,18 @@ public: | |||
| 138 | 183 | ||
| 139 | Result DisconnectNpad(Core::HID::NpadIdType npad_id); | 184 | Result DisconnectNpad(Core::HID::NpadIdType npad_id); |
| 140 | 185 | ||
| 141 | Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 142 | Core::HID::GyroscopeZeroDriftMode drift_mode); | ||
| 143 | Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 144 | Core::HID::GyroscopeZeroDriftMode& drift_mode) const; | ||
| 145 | Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 146 | bool& is_at_rest) const; | ||
| 147 | Result IsFirmwareUpdateAvailableForSixAxisSensor( | 186 | Result IsFirmwareUpdateAvailableForSixAxisSensor( |
| 148 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const; | 187 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const; |
| 149 | Result EnableSixAxisSensorUnalteredPassthrough( | ||
| 150 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled); | ||
| 151 | Result IsSixAxisSensorUnalteredPassthroughEnabled( | ||
| 152 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const; | ||
| 153 | Result LoadSixAxisSensorCalibrationParameter( | ||
| 154 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 155 | Core::HID::SixAxisSensorCalibrationParameter& calibration) const; | ||
| 156 | Result GetSixAxisSensorIcInformation( | ||
| 157 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 158 | Core::HID::SixAxisSensorIcInformation& ic_information) const; | ||
| 159 | Result ResetIsSixAxisSensorDeviceNewlyAssigned( | 188 | Result ResetIsSixAxisSensorDeviceNewlyAssigned( |
| 160 | const Core::HID::SixAxisSensorHandle& sixaxis_handle); | 189 | const Core::HID::SixAxisSensorHandle& sixaxis_handle); |
| 161 | Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 190 | |
| 162 | bool sixaxis_status); | 191 | SixAxisLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id); |
| 163 | Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 192 | SixAxisLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id); |
| 164 | bool& is_fusion_enabled) const; | 193 | SixAxisLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id); |
| 165 | Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 194 | SixAxisLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id); |
| 166 | bool is_fusion_enabled); | 195 | SixAxisLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id); |
| 167 | Result SetSixAxisFusionParameters( | 196 | SixAxisLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id); |
| 168 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 197 | |
| 169 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters); | ||
| 170 | Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 171 | Core::HID::SixAxisSensorFusionParameters& parameters) const; | ||
| 172 | Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; | 198 | Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; |
| 173 | Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, | 199 | Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, |
| 174 | bool& is_enabled) const; | 200 | bool& is_enabled) const; |
| @@ -192,10 +218,7 @@ public: | |||
| 192 | 218 | ||
| 193 | void ApplyNpadSystemCommonPolicy(); | 219 | void ApplyNpadSystemCommonPolicy(); |
| 194 | 220 | ||
| 195 | static bool IsNpadIdValid(Core::HID::NpadIdType npad_id); | 221 | AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); |
| 196 | static Result IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle); | ||
| 197 | static Result VerifyValidSixAxisSensorHandle( | ||
| 198 | const Core::HID::SixAxisSensorHandle& device_handle); | ||
| 199 | 222 | ||
| 200 | private: | 223 | private: |
| 201 | static constexpr std::size_t NPAD_COUNT = 10; | 224 | static constexpr std::size_t NPAD_COUNT = 10; |
| @@ -254,29 +277,6 @@ private: | |||
| 254 | }; | 277 | }; |
| 255 | static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); | 278 | static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); |
| 256 | 279 | ||
| 257 | // This is nn::hid::SixAxisSensorAttribute | ||
| 258 | struct SixAxisSensorAttribute { | ||
| 259 | union { | ||
| 260 | u32 raw{}; | ||
| 261 | BitField<0, 1, u32> is_connected; | ||
| 262 | BitField<1, 1, u32> is_interpolated; | ||
| 263 | }; | ||
| 264 | }; | ||
| 265 | static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size"); | ||
| 266 | |||
| 267 | // This is nn::hid::SixAxisSensorState | ||
| 268 | struct SixAxisSensorState { | ||
| 269 | s64 delta_time{}; | ||
| 270 | s64 sampling_number{}; | ||
| 271 | Common::Vec3f accel{}; | ||
| 272 | Common::Vec3f gyro{}; | ||
| 273 | Common::Vec3f rotation{}; | ||
| 274 | std::array<Common::Vec3f, 3> orientation{}; | ||
| 275 | SixAxisSensorAttribute attribute{}; | ||
| 276 | INSERT_PADDING_BYTES(4); // Reserved | ||
| 277 | }; | ||
| 278 | static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size"); | ||
| 279 | |||
| 280 | // This is nn::hid::server::NpadGcTriggerState | 280 | // This is nn::hid::server::NpadGcTriggerState |
| 281 | struct NpadGcTriggerState { | 281 | struct NpadGcTriggerState { |
| 282 | s64 sampling_number{}; | 282 | s64 sampling_number{}; |
| @@ -353,37 +353,6 @@ private: | |||
| 353 | static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, | 353 | static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, |
| 354 | "NfcXcdDeviceHandleStateImpl is an invalid size"); | 354 | "NfcXcdDeviceHandleStateImpl is an invalid size"); |
| 355 | 355 | ||
| 356 | // This is nn::hid::system::AppletFooterUiAttributesSet | ||
| 357 | struct AppletFooterUiAttributes { | ||
| 358 | INSERT_PADDING_BYTES(0x4); | ||
| 359 | }; | ||
| 360 | |||
| 361 | // This is nn::hid::system::AppletFooterUiType | ||
| 362 | enum class AppletFooterUiType : u8 { | ||
| 363 | None = 0, | ||
| 364 | HandheldNone = 1, | ||
| 365 | HandheldJoyConLeftOnly = 2, | ||
| 366 | HandheldJoyConRightOnly = 3, | ||
| 367 | HandheldJoyConLeftJoyConRight = 4, | ||
| 368 | JoyDual = 5, | ||
| 369 | JoyDualLeftOnly = 6, | ||
| 370 | JoyDualRightOnly = 7, | ||
| 371 | JoyLeftHorizontal = 8, | ||
| 372 | JoyLeftVertical = 9, | ||
| 373 | JoyRightHorizontal = 10, | ||
| 374 | JoyRightVertical = 11, | ||
| 375 | SwitchProController = 12, | ||
| 376 | CompatibleProController = 13, | ||
| 377 | CompatibleJoyCon = 14, | ||
| 378 | LarkHvc1 = 15, | ||
| 379 | LarkHvc2 = 16, | ||
| 380 | LarkNesLeft = 17, | ||
| 381 | LarkNesRight = 18, | ||
| 382 | Lucia = 19, | ||
| 383 | Verification = 20, | ||
| 384 | Lagon = 21, | ||
| 385 | }; | ||
| 386 | |||
| 387 | // This is nn::hid::NpadLarkType | 356 | // This is nn::hid::NpadLarkType |
| 388 | enum class NpadLarkType : u32 { | 357 | enum class NpadLarkType : u32 { |
| 389 | Invalid, | 358 | Invalid, |
| @@ -427,12 +396,12 @@ private: | |||
| 427 | Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{}; | 396 | Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{}; |
| 428 | Lifo<NPadGenericState, hid_entry_count> palma_lifo{}; | 397 | Lifo<NPadGenericState, hid_entry_count> palma_lifo{}; |
| 429 | Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{}; | 398 | Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{}; |
| 430 | Lifo<SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{}; | 399 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{}; |
| 431 | Lifo<SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{}; | 400 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{}; |
| 432 | Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{}; | 401 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{}; |
| 433 | Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{}; | 402 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{}; |
| 434 | Lifo<SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{}; | 403 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{}; |
| 435 | Lifo<SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{}; | 404 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{}; |
| 436 | DeviceType device_type{}; | 405 | DeviceType device_type{}; |
| 437 | INSERT_PADDING_BYTES(0x4); // Reserved | 406 | INSERT_PADDING_BYTES(0x4); // Reserved |
| 438 | NPadSystemProperties system_properties{}; | 407 | NPadSystemProperties system_properties{}; |
| @@ -466,16 +435,6 @@ private: | |||
| 466 | std::chrono::steady_clock::time_point last_vibration_timepoint{}; | 435 | std::chrono::steady_clock::time_point last_vibration_timepoint{}; |
| 467 | }; | 436 | }; |
| 468 | 437 | ||
| 469 | struct SixaxisParameters { | ||
| 470 | bool is_fusion_enabled{true}; | ||
| 471 | bool unaltered_passtrough{false}; | ||
| 472 | Core::HID::SixAxisSensorFusionParameters fusion{}; | ||
| 473 | Core::HID::SixAxisSensorCalibrationParameter calibration{}; | ||
| 474 | Core::HID::SixAxisSensorIcInformation ic_information{}; | ||
| 475 | Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{ | ||
| 476 | Core::HID::GyroscopeZeroDriftMode::Standard}; | ||
| 477 | }; | ||
| 478 | |||
| 479 | struct NpadControllerData { | 438 | struct NpadControllerData { |
| 480 | Kernel::KEvent* styleset_changed_event{}; | 439 | Kernel::KEvent* styleset_changed_event{}; |
| 481 | NpadInternalState* shared_memory = nullptr; | 440 | NpadInternalState* shared_memory = nullptr; |
| @@ -489,27 +448,10 @@ private: | |||
| 489 | bool is_dual_left_connected{true}; | 448 | bool is_dual_left_connected{true}; |
| 490 | bool is_dual_right_connected{true}; | 449 | bool is_dual_right_connected{true}; |
| 491 | 450 | ||
| 492 | // Motion parameters | ||
| 493 | bool sixaxis_at_rest{true}; | ||
| 494 | bool sixaxis_sensor_enabled{true}; | ||
| 495 | SixaxisParameters sixaxis_fullkey{}; | ||
| 496 | SixaxisParameters sixaxis_handheld{}; | ||
| 497 | SixaxisParameters sixaxis_dual_left{}; | ||
| 498 | SixaxisParameters sixaxis_dual_right{}; | ||
| 499 | SixaxisParameters sixaxis_left{}; | ||
| 500 | SixaxisParameters sixaxis_right{}; | ||
| 501 | SixaxisParameters sixaxis_unknown{}; | ||
| 502 | |||
| 503 | // Current pad state | 451 | // Current pad state |
| 504 | NPadGenericState npad_pad_state{}; | 452 | NPadGenericState npad_pad_state{}; |
| 505 | NPadGenericState npad_libnx_state{}; | 453 | NPadGenericState npad_libnx_state{}; |
| 506 | NpadGcTriggerState npad_trigger_state{}; | 454 | NpadGcTriggerState npad_trigger_state{}; |
| 507 | SixAxisSensorState sixaxis_fullkey_state{}; | ||
| 508 | SixAxisSensorState sixaxis_handheld_state{}; | ||
| 509 | SixAxisSensorState sixaxis_dual_left_state{}; | ||
| 510 | SixAxisSensorState sixaxis_dual_right_state{}; | ||
| 511 | SixAxisSensorState sixaxis_left_lifo_state{}; | ||
| 512 | SixAxisSensorState sixaxis_right_lifo_state{}; | ||
| 513 | int callback_key{}; | 455 | int callback_key{}; |
| 514 | }; | 456 | }; |
| 515 | 457 | ||
| @@ -520,13 +462,13 @@ private: | |||
| 520 | void WriteEmptyEntry(NpadInternalState* npad); | 462 | void WriteEmptyEntry(NpadInternalState* npad); |
| 521 | 463 | ||
| 522 | NpadControllerData& GetControllerFromHandle( | 464 | NpadControllerData& GetControllerFromHandle( |
| 523 | const Core::HID::SixAxisSensorHandle& device_handle); | ||
| 524 | const NpadControllerData& GetControllerFromHandle( | ||
| 525 | const Core::HID::SixAxisSensorHandle& device_handle) const; | ||
| 526 | NpadControllerData& GetControllerFromHandle( | ||
| 527 | const Core::HID::VibrationDeviceHandle& device_handle); | 465 | const Core::HID::VibrationDeviceHandle& device_handle); |
| 528 | const NpadControllerData& GetControllerFromHandle( | 466 | const NpadControllerData& GetControllerFromHandle( |
| 529 | const Core::HID::VibrationDeviceHandle& device_handle) const; | 467 | const Core::HID::VibrationDeviceHandle& device_handle) const; |
| 468 | NpadControllerData& GetControllerFromHandle( | ||
| 469 | const Core::HID::SixAxisSensorHandle& device_handle); | ||
| 470 | const NpadControllerData& GetControllerFromHandle( | ||
| 471 | const Core::HID::SixAxisSensorHandle& device_handle) const; | ||
| 530 | NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id); | 472 | NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id); |
| 531 | const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const; | 473 | const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const; |
| 532 | 474 | ||
| @@ -534,9 +476,6 @@ private: | |||
| 534 | const Core::HID::SixAxisSensorHandle& device_handle); | 476 | const Core::HID::SixAxisSensorHandle& device_handle); |
| 535 | const Core::HID::SixAxisSensorProperties& GetSixaxisProperties( | 477 | const Core::HID::SixAxisSensorProperties& GetSixaxisProperties( |
| 536 | const Core::HID::SixAxisSensorHandle& device_handle) const; | 478 | const Core::HID::SixAxisSensorHandle& device_handle) const; |
| 537 | SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle); | ||
| 538 | const SixaxisParameters& GetSixaxisState( | ||
| 539 | const Core::HID::SixAxisSensorHandle& device_handle) const; | ||
| 540 | 479 | ||
| 541 | std::atomic<u64> press_state{}; | 480 | std::atomic<u64> press_state{}; |
| 542 | 481 | ||
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp index 73a2a2b91..588ff9d62 100644 --- a/src/core/hle/service/hid/controllers/palma.cpp +++ b/src/core/hle/service/hid/controllers/palma.cpp | |||
| @@ -12,43 +12,43 @@ | |||
| 12 | 12 | ||
| 13 | namespace Service::HID { | 13 | namespace Service::HID { |
| 14 | 14 | ||
| 15 | Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | 15 | Palma::Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, |
| 16 | KernelHelpers::ServiceContext& service_context_) | 16 | KernelHelpers::ServiceContext& service_context_) |
| 17 | : ControllerBase{hid_core_}, service_context{service_context_} { | 17 | : ControllerBase{hid_core_}, service_context{service_context_} { |
| 18 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); | 18 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); |
| 19 | operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); | 19 | operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | Controller_Palma::~Controller_Palma() { | 22 | Palma::~Palma() { |
| 23 | service_context.CloseEvent(operation_complete_event); | 23 | service_context.CloseEvent(operation_complete_event); |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | void Controller_Palma::OnInit() {} | 26 | void Palma::OnInit() {} |
| 27 | 27 | ||
| 28 | void Controller_Palma::OnRelease() {} | 28 | void Palma::OnRelease() {} |
| 29 | 29 | ||
| 30 | void Controller_Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 30 | void Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 31 | if (!IsControllerActivated()) { | 31 | if (!IsControllerActivated()) { |
| 32 | return; | 32 | return; |
| 33 | } | 33 | } |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | Result Controller_Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, | 36 | Result Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, |
| 37 | PalmaConnectionHandle& handle) { | 37 | PalmaConnectionHandle& handle) { |
| 38 | active_handle.npad_id = npad_id; | 38 | active_handle.npad_id = npad_id; |
| 39 | handle = active_handle; | 39 | handle = active_handle; |
| 40 | return ResultSuccess; | 40 | return ResultSuccess; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) { | 43 | Result Palma::InitializePalma(const PalmaConnectionHandle& handle) { |
| 44 | if (handle.npad_id != active_handle.npad_id) { | 44 | if (handle.npad_id != active_handle.npad_id) { |
| 45 | return InvalidPalmaHandle; | 45 | return InvalidPalmaHandle; |
| 46 | } | 46 | } |
| 47 | ActivateController(); | 47 | Activate(); |
| 48 | return ResultSuccess; | 48 | return ResultSuccess; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent( | 51 | Kernel::KReadableEvent& Palma::AcquirePalmaOperationCompleteEvent( |
| 52 | const PalmaConnectionHandle& handle) const { | 52 | const PalmaConnectionHandle& handle) const { |
| 53 | if (handle.npad_id != active_handle.npad_id) { | 53 | if (handle.npad_id != active_handle.npad_id) { |
| 54 | LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id); | 54 | LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id); |
| @@ -56,9 +56,9 @@ Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent( | |||
| 56 | return operation_complete_event->GetReadableEvent(); | 56 | return operation_complete_event->GetReadableEvent(); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle, | 59 | Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle, |
| 60 | PalmaOperationType& operation_type, | 60 | PalmaOperationType& operation_type, |
| 61 | PalmaOperationData& data) const { | 61 | PalmaOperationData& data) const { |
| 62 | if (handle.npad_id != active_handle.npad_id) { | 62 | if (handle.npad_id != active_handle.npad_id) { |
| 63 | return InvalidPalmaHandle; | 63 | return InvalidPalmaHandle; |
| 64 | } | 64 | } |
| @@ -67,8 +67,7 @@ Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& hand | |||
| 67 | return ResultSuccess; | 67 | return ResultSuccess; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, | 70 | Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity) { |
| 71 | u64 palma_activity) { | ||
| 72 | if (handle.npad_id != active_handle.npad_id) { | 71 | if (handle.npad_id != active_handle.npad_id) { |
| 73 | return InvalidPalmaHandle; | 72 | return InvalidPalmaHandle; |
| 74 | } | 73 | } |
| @@ -79,8 +78,7 @@ Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, | |||
| 79 | return ResultSuccess; | 78 | return ResultSuccess; |
| 80 | } | 79 | } |
| 81 | 80 | ||
| 82 | Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, | 81 | Result Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_) { |
| 83 | PalmaFrModeType fr_mode_) { | ||
| 84 | if (handle.npad_id != active_handle.npad_id) { | 82 | if (handle.npad_id != active_handle.npad_id) { |
| 85 | return InvalidPalmaHandle; | 83 | return InvalidPalmaHandle; |
| 86 | } | 84 | } |
| @@ -88,7 +86,7 @@ Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, | |||
| 88 | return ResultSuccess; | 86 | return ResultSuccess; |
| 89 | } | 87 | } |
| 90 | 88 | ||
| 91 | Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) { | 89 | Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) { |
| 92 | if (handle.npad_id != active_handle.npad_id) { | 90 | if (handle.npad_id != active_handle.npad_id) { |
| 93 | return InvalidPalmaHandle; | 91 | return InvalidPalmaHandle; |
| 94 | } | 92 | } |
| @@ -99,25 +97,25 @@ Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) { | |||
| 99 | return ResultSuccess; | 97 | return ResultSuccess; |
| 100 | } | 98 | } |
| 101 | 99 | ||
| 102 | Result Controller_Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) { | 100 | Result Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) { |
| 103 | if (handle.npad_id != active_handle.npad_id) { | 101 | if (handle.npad_id != active_handle.npad_id) { |
| 104 | return InvalidPalmaHandle; | 102 | return InvalidPalmaHandle; |
| 105 | } | 103 | } |
| 106 | return ResultSuccess; | 104 | return ResultSuccess; |
| 107 | } | 105 | } |
| 108 | 106 | ||
| 109 | Result Controller_Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) { | 107 | Result Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) { |
| 110 | if (handle.npad_id != active_handle.npad_id) { | 108 | if (handle.npad_id != active_handle.npad_id) { |
| 111 | return InvalidPalmaHandle; | 109 | return InvalidPalmaHandle; |
| 112 | } | 110 | } |
| 113 | return ResultSuccess; | 111 | return ResultSuccess; |
| 114 | } | 112 | } |
| 115 | 113 | ||
| 116 | void Controller_Palma::ReadPalmaApplicationSection() {} | 114 | void Palma::ReadPalmaApplicationSection() {} |
| 117 | 115 | ||
| 118 | void Controller_Palma::WritePalmaApplicationSection() {} | 116 | void Palma::WritePalmaApplicationSection() {} |
| 119 | 117 | ||
| 120 | Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) { | 118 | Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) { |
| 121 | if (handle.npad_id != active_handle.npad_id) { | 119 | if (handle.npad_id != active_handle.npad_id) { |
| 122 | return InvalidPalmaHandle; | 120 | return InvalidPalmaHandle; |
| 123 | } | 121 | } |
| @@ -128,7 +126,7 @@ Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle | |||
| 128 | return ResultSuccess; | 126 | return ResultSuccess; |
| 129 | } | 127 | } |
| 130 | 128 | ||
| 131 | Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) { | 129 | Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) { |
| 132 | if (handle.npad_id != active_handle.npad_id) { | 130 | if (handle.npad_id != active_handle.npad_id) { |
| 133 | return InvalidPalmaHandle; | 131 | return InvalidPalmaHandle; |
| 134 | } | 132 | } |
| @@ -139,10 +137,9 @@ Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& | |||
| 139 | return ResultSuccess; | 137 | return ResultSuccess; |
| 140 | } | 138 | } |
| 141 | 139 | ||
| 142 | void Controller_Palma::WritePalmaActivityEntry() {} | 140 | void Palma::WritePalmaActivityEntry() {} |
| 143 | 141 | ||
| 144 | Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, | 142 | Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown) { |
| 145 | u64 unknown) { | ||
| 146 | if (handle.npad_id != active_handle.npad_id) { | 143 | if (handle.npad_id != active_handle.npad_id) { |
| 147 | return InvalidPalmaHandle; | 144 | return InvalidPalmaHandle; |
| 148 | } | 145 | } |
| @@ -153,8 +150,8 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl | |||
| 153 | return ResultSuccess; | 150 | return ResultSuccess; |
| 154 | } | 151 | } |
| 155 | 152 | ||
| 156 | Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, | 153 | Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, |
| 157 | Common::ProcessAddress t_mem, u64 size) { | 154 | Common::ProcessAddress t_mem, u64 size) { |
| 158 | if (handle.npad_id != active_handle.npad_id) { | 155 | if (handle.npad_id != active_handle.npad_id) { |
| 159 | return InvalidPalmaHandle; | 156 | return InvalidPalmaHandle; |
| 160 | } | 157 | } |
| @@ -165,8 +162,8 @@ Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle | |||
| 165 | return ResultSuccess; | 162 | return ResultSuccess; |
| 166 | } | 163 | } |
| 167 | 164 | ||
| 168 | Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, | 165 | Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, |
| 169 | s32 database_id_version_) { | 166 | s32 database_id_version_) { |
| 170 | if (handle.npad_id != active_handle.npad_id) { | 167 | if (handle.npad_id != active_handle.npad_id) { |
| 171 | return InvalidPalmaHandle; | 168 | return InvalidPalmaHandle; |
| 172 | } | 169 | } |
| @@ -178,8 +175,7 @@ Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnec | |||
| 178 | return ResultSuccess; | 175 | return ResultSuccess; |
| 179 | } | 176 | } |
| 180 | 177 | ||
| 181 | Result Controller_Palma::GetPalmaDataBaseIdentificationVersion( | 178 | Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle) { |
| 182 | const PalmaConnectionHandle& handle) { | ||
| 183 | if (handle.npad_id != active_handle.npad_id) { | 179 | if (handle.npad_id != active_handle.npad_id) { |
| 184 | return InvalidPalmaHandle; | 180 | return InvalidPalmaHandle; |
| 185 | } | 181 | } |
| @@ -191,26 +187,26 @@ Result Controller_Palma::GetPalmaDataBaseIdentificationVersion( | |||
| 191 | return ResultSuccess; | 187 | return ResultSuccess; |
| 192 | } | 188 | } |
| 193 | 189 | ||
| 194 | void Controller_Palma::SuspendPalmaFeature() {} | 190 | void Palma::SuspendPalmaFeature() {} |
| 195 | 191 | ||
| 196 | Result Controller_Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const { | 192 | Result Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const { |
| 197 | if (handle.npad_id != active_handle.npad_id) { | 193 | if (handle.npad_id != active_handle.npad_id) { |
| 198 | return InvalidPalmaHandle; | 194 | return InvalidPalmaHandle; |
| 199 | } | 195 | } |
| 200 | return operation.result; | 196 | return operation.result; |
| 201 | } | 197 | } |
| 202 | void Controller_Palma::ReadPalmaPlayLog() {} | 198 | void Palma::ReadPalmaPlayLog() {} |
| 203 | 199 | ||
| 204 | void Controller_Palma::ResetPalmaPlayLog() {} | 200 | void Palma::ResetPalmaPlayLog() {} |
| 205 | 201 | ||
| 206 | void Controller_Palma::SetIsPalmaAllConnectable(bool is_all_connectable) { | 202 | void Palma::SetIsPalmaAllConnectable(bool is_all_connectable) { |
| 207 | // If true controllers are able to be paired | 203 | // If true controllers are able to be paired |
| 208 | is_connectable = is_all_connectable; | 204 | is_connectable = is_all_connectable; |
| 209 | } | 205 | } |
| 210 | 206 | ||
| 211 | void Controller_Palma::SetIsPalmaPairedConnectable() {} | 207 | void Palma::SetIsPalmaPairedConnectable() {} |
| 212 | 208 | ||
| 213 | Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) { | 209 | Result Palma::PairPalma(const PalmaConnectionHandle& handle) { |
| 214 | if (handle.npad_id != active_handle.npad_id) { | 210 | if (handle.npad_id != active_handle.npad_id) { |
| 215 | return InvalidPalmaHandle; | 211 | return InvalidPalmaHandle; |
| 216 | } | 212 | } |
| @@ -218,14 +214,14 @@ Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) { | |||
| 218 | return ResultSuccess; | 214 | return ResultSuccess; |
| 219 | } | 215 | } |
| 220 | 216 | ||
| 221 | void Controller_Palma::SetPalmaBoostMode(bool boost_mode) {} | 217 | void Palma::SetPalmaBoostMode(bool boost_mode) {} |
| 222 | 218 | ||
| 223 | void Controller_Palma::CancelWritePalmaWaveEntry() {} | 219 | void Palma::CancelWritePalmaWaveEntry() {} |
| 224 | 220 | ||
| 225 | void Controller_Palma::EnablePalmaBoostMode() {} | 221 | void Palma::EnablePalmaBoostMode() {} |
| 226 | 222 | ||
| 227 | void Controller_Palma::GetPalmaBluetoothAddress() {} | 223 | void Palma::GetPalmaBluetoothAddress() {} |
| 228 | 224 | ||
| 229 | void Controller_Palma::SetDisallowedPalmaConnection() {} | 225 | void Palma::SetDisallowedPalmaConnection() {} |
| 230 | 226 | ||
| 231 | } // namespace Service::HID | 227 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h index a0491a819..a6047f36a 100644 --- a/src/core/hle/service/hid/controllers/palma.h +++ b/src/core/hle/service/hid/controllers/palma.h | |||
| @@ -23,7 +23,7 @@ class EmulatedController; | |||
| 23 | } // namespace Core::HID | 23 | } // namespace Core::HID |
| 24 | 24 | ||
| 25 | namespace Service::HID { | 25 | namespace Service::HID { |
| 26 | class Controller_Palma final : public ControllerBase { | 26 | class Palma final : public ControllerBase { |
| 27 | public: | 27 | public: |
| 28 | using PalmaOperationData = std::array<u8, 0x140>; | 28 | using PalmaOperationData = std::array<u8, 0x140>; |
| 29 | 29 | ||
| @@ -97,9 +97,9 @@ public: | |||
| 97 | static_assert(sizeof(PalmaConnectionHandle) == 0x8, | 97 | static_assert(sizeof(PalmaConnectionHandle) == 0x8, |
| 98 | "PalmaConnectionHandle has incorrect size."); | 98 | "PalmaConnectionHandle has incorrect size."); |
| 99 | 99 | ||
| 100 | explicit Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | 100 | explicit Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, |
| 101 | KernelHelpers::ServiceContext& service_context_); | 101 | KernelHelpers::ServiceContext& service_context_); |
| 102 | ~Controller_Palma() override; | 102 | ~Palma() override; |
| 103 | 103 | ||
| 104 | // Called when the controller is initialized | 104 | // Called when the controller is initialized |
| 105 | void OnInit() override; | 105 | void OnInit() override; |
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/seven_six_axis.cpp index bcb272eaf..495568484 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp +++ b/src/core/hle/service/hid/controllers/seven_six_axis.cpp | |||
| @@ -1,32 +1,29 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include <cstring> | ||
| 5 | #include "common/common_types.h" | ||
| 4 | #include "core/core.h" | 6 | #include "core/core.h" |
| 5 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/frontend/emu_window.h" | ||
| 6 | #include "core/hid/emulated_console.h" | 9 | #include "core/hid/emulated_console.h" |
| 10 | #include "core/hid/emulated_devices.h" | ||
| 7 | #include "core/hid/hid_core.h" | 11 | #include "core/hid/hid_core.h" |
| 8 | #include "core/hle/service/hid/controllers/console_sixaxis.h" | 12 | #include "core/hle/service/hid/controllers/seven_six_axis.h" |
| 9 | #include "core/memory.h" | 13 | #include "core/memory.h" |
| 10 | 14 | ||
| 11 | namespace Service::HID { | 15 | namespace Service::HID { |
| 12 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; | 16 | SevenSixAxis::SevenSixAxis(Core::System& system_) |
| 13 | |||
| 14 | Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_) | ||
| 15 | : ControllerBase{system_.HIDCore()}, system{system_} { | 17 | : ControllerBase{system_.HIDCore()}, system{system_} { |
| 16 | console = hid_core.GetEmulatedConsole(); | 18 | console = hid_core.GetEmulatedConsole(); |
| 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size, | ||
| 18 | "ConsoleSharedMemory is bigger than the shared memory"); | ||
| 19 | shared_memory = std::construct_at( | ||
| 20 | reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 21 | } | 19 | } |
| 22 | 20 | ||
| 23 | Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default; | 21 | SevenSixAxis::~SevenSixAxis() = default; |
| 24 | |||
| 25 | void Controller_ConsoleSixAxis::OnInit() {} | ||
| 26 | 22 | ||
| 27 | void Controller_ConsoleSixAxis::OnRelease() {} | 23 | void SevenSixAxis::OnInit() {} |
| 24 | void SevenSixAxis::OnRelease() {} | ||
| 28 | 25 | ||
| 29 | void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 26 | void SevenSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 30 | if (!IsControllerActivated() || transfer_memory == 0) { | 27 | if (!IsControllerActivated() || transfer_memory == 0) { |
| 31 | seven_sixaxis_lifo.buffer_count = 0; | 28 | seven_sixaxis_lifo.buffer_count = 0; |
| 32 | seven_sixaxis_lifo.buffer_tail = 0; | 29 | seven_sixaxis_lifo.buffer_tail = 0; |
| @@ -53,22 +50,17 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti | |||
| 53 | -motion_status.quaternion.xyz.z, | 50 | -motion_status.quaternion.xyz.z, |
| 54 | }; | 51 | }; |
| 55 | 52 | ||
| 56 | shared_memory->sampling_number++; | ||
| 57 | shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; | ||
| 58 | shared_memory->verticalization_error = motion_status.verticalization_error; | ||
| 59 | shared_memory->gyro_bias = motion_status.gyro_bias; | ||
| 60 | |||
| 61 | // Update seven six axis transfer memory | ||
| 62 | seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); | 53 | seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); |
| 63 | system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, | 54 | system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, |
| 64 | sizeof(seven_sixaxis_lifo)); | 55 | sizeof(seven_sixaxis_lifo)); |
| 65 | } | 56 | } |
| 66 | 57 | ||
| 67 | void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { | 58 | void SevenSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { |
| 68 | transfer_memory = t_mem; | 59 | transfer_memory = t_mem; |
| 69 | } | 60 | } |
| 70 | 61 | ||
| 71 | void Controller_ConsoleSixAxis::ResetTimestamp() { | 62 | void SevenSixAxis::ResetTimestamp() { |
| 72 | last_saved_timestamp = last_global_timestamp; | 63 | last_saved_timestamp = last_global_timestamp; |
| 73 | } | 64 | } |
| 65 | |||
| 74 | } // namespace Service::HID | 66 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/seven_six_axis.h index 7015d924c..40e3f5d12 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.h +++ b/src/core/hle/service/hid/controllers/seven_six_axis.h | |||
| @@ -1,10 +1,9 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include "common/common_types.h" |
| 7 | |||
| 8 | #include "common/quaternion.h" | 7 | #include "common/quaternion.h" |
| 9 | #include "common/typed_address.h" | 8 | #include "common/typed_address.h" |
| 10 | #include "core/hle/service/hid/controllers/controller_base.h" | 9 | #include "core/hle/service/hid/controllers/controller_base.h" |
| @@ -19,10 +18,10 @@ class EmulatedConsole; | |||
| 19 | } // namespace Core::HID | 18 | } // namespace Core::HID |
| 20 | 19 | ||
| 21 | namespace Service::HID { | 20 | namespace Service::HID { |
| 22 | class Controller_ConsoleSixAxis final : public ControllerBase { | 21 | class SevenSixAxis final : public ControllerBase { |
| 23 | public: | 22 | public: |
| 24 | explicit Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_); | 23 | explicit SevenSixAxis(Core::System& system_); |
| 25 | ~Controller_ConsoleSixAxis() override; | 24 | ~SevenSixAxis() override; |
| 26 | 25 | ||
| 27 | // Called when the controller is initialized | 26 | // Called when the controller is initialized |
| 28 | void OnInit() override; | 27 | void OnInit() override; |
| @@ -51,28 +50,16 @@ private: | |||
| 51 | }; | 50 | }; |
| 52 | static_assert(sizeof(SevenSixAxisState) == 0x48, "SevenSixAxisState is an invalid size"); | 51 | static_assert(sizeof(SevenSixAxisState) == 0x48, "SevenSixAxisState is an invalid size"); |
| 53 | 52 | ||
| 54 | // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat | ||
| 55 | struct ConsoleSharedMemory { | ||
| 56 | u64 sampling_number{}; | ||
| 57 | bool is_seven_six_axis_sensor_at_rest{}; | ||
| 58 | INSERT_PADDING_BYTES(3); // padding | ||
| 59 | f32 verticalization_error{}; | ||
| 60 | Common::Vec3f gyro_bias{}; | ||
| 61 | INSERT_PADDING_BYTES(4); // padding | ||
| 62 | }; | ||
| 63 | static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); | ||
| 64 | |||
| 65 | Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{}; | 53 | Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{}; |
| 66 | static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); | 54 | static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); |
| 67 | 55 | ||
| 56 | u64 last_saved_timestamp{}; | ||
| 57 | u64 last_global_timestamp{}; | ||
| 58 | |||
| 68 | SevenSixAxisState next_seven_sixaxis_state{}; | 59 | SevenSixAxisState next_seven_sixaxis_state{}; |
| 69 | Common::ProcessAddress transfer_memory{}; | 60 | Common::ProcessAddress transfer_memory{}; |
| 70 | ConsoleSharedMemory* shared_memory = nullptr; | ||
| 71 | Core::HID::EmulatedConsole* console = nullptr; | 61 | Core::HID::EmulatedConsole* console = nullptr; |
| 72 | 62 | ||
| 73 | u64 last_saved_timestamp{}; | ||
| 74 | u64 last_global_timestamp{}; | ||
| 75 | |||
| 76 | Core::System& system; | 63 | Core::System& system; |
| 77 | }; | 64 | }; |
| 78 | } // namespace Service::HID | 65 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp new file mode 100644 index 000000000..3d24a5c04 --- /dev/null +++ b/src/core/hle/service/hid/controllers/six_axis.cpp | |||
| @@ -0,0 +1,413 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "common/common_types.h" | ||
| 5 | #include "core/core_timing.h" | ||
| 6 | #include "core/hid/emulated_controller.h" | ||
| 7 | #include "core/hid/hid_core.h" | ||
| 8 | #include "core/hle/service/hid/controllers/npad.h" | ||
| 9 | #include "core/hle/service/hid/controllers/six_axis.h" | ||
| 10 | #include "core/hle/service/hid/errors.h" | ||
| 11 | #include "core/hle/service/hid/hid_util.h" | ||
| 12 | |||
| 13 | namespace Service::HID { | ||
| 14 | |||
| 15 | SixAxis::SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_) | ||
| 16 | : ControllerBase{hid_core_}, npad{npad_} { | ||
| 17 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | ||
| 18 | auto& controller = controller_data[i]; | ||
| 19 | controller.device = hid_core.GetEmulatedControllerByIndex(i); | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | SixAxis::~SixAxis() = default; | ||
| 24 | |||
| 25 | void SixAxis::OnInit() {} | ||
| 26 | void SixAxis::OnRelease() {} | ||
| 27 | |||
| 28 | void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||
| 29 | if (!IsControllerActivated()) { | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | |||
| 33 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | ||
| 34 | auto& controller = controller_data[i]; | ||
| 35 | |||
| 36 | const auto npad_id = IndexToNpadIdType(i); | ||
| 37 | const auto& controller_type = controller.device->GetNpadStyleIndex(); | ||
| 38 | |||
| 39 | if (controller_type == Core::HID::NpadStyleIndex::None || | ||
| 40 | !controller.device->IsConnected()) { | ||
| 41 | continue; | ||
| 42 | } | ||
| 43 | |||
| 44 | const auto& motion_state = controller.device->GetMotions(); | ||
| 45 | auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state; | ||
| 46 | auto& sixaxis_handheld_state = controller.sixaxis_handheld_state; | ||
| 47 | auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state; | ||
| 48 | auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state; | ||
| 49 | auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state; | ||
| 50 | auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state; | ||
| 51 | |||
| 52 | auto& sixaxis_fullkey_lifo = npad->GetSixAxisFullkeyLifo(npad_id); | ||
| 53 | auto& sixaxis_handheld_lifo = npad->GetSixAxisHandheldLifo(npad_id); | ||
| 54 | auto& sixaxis_dual_left_lifo = npad->GetSixAxisDualLeftLifo(npad_id); | ||
| 55 | auto& sixaxis_dual_right_lifo = npad->GetSixAxisDualRightLifo(npad_id); | ||
| 56 | auto& sixaxis_left_lifo = npad->GetSixAxisLeftLifo(npad_id); | ||
| 57 | auto& sixaxis_right_lifo = npad->GetSixAxisRightLifo(npad_id); | ||
| 58 | |||
| 59 | // Clear previous state | ||
| 60 | sixaxis_fullkey_state = {}; | ||
| 61 | sixaxis_handheld_state = {}; | ||
| 62 | sixaxis_dual_left_state = {}; | ||
| 63 | sixaxis_dual_right_state = {}; | ||
| 64 | sixaxis_left_lifo_state = {}; | ||
| 65 | sixaxis_right_lifo_state = {}; | ||
| 66 | |||
| 67 | if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) { | ||
| 68 | controller.sixaxis_at_rest = true; | ||
| 69 | for (std::size_t e = 0; e < motion_state.size(); ++e) { | ||
| 70 | controller.sixaxis_at_rest = | ||
| 71 | controller.sixaxis_at_rest && motion_state[e].is_at_rest; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | const auto set_motion_state = [&](Core::HID::SixAxisSensorState& state, | ||
| 76 | const Core::HID::ControllerMotion& hid_state) { | ||
| 77 | using namespace std::literals::chrono_literals; | ||
| 78 | static constexpr Core::HID::SixAxisSensorState default_motion_state = { | ||
| 79 | .delta_time = std::chrono::nanoseconds(5ms).count(), | ||
| 80 | .accel = {0, 0, -1.0f}, | ||
| 81 | .orientation = | ||
| 82 | { | ||
| 83 | Common::Vec3f{1.0f, 0, 0}, | ||
| 84 | Common::Vec3f{0, 1.0f, 0}, | ||
| 85 | Common::Vec3f{0, 0, 1.0f}, | ||
| 86 | }, | ||
| 87 | .attribute = {1}, | ||
| 88 | }; | ||
| 89 | if (!controller.sixaxis_sensor_enabled) { | ||
| 90 | state = default_motion_state; | ||
| 91 | return; | ||
| 92 | } | ||
| 93 | if (!Settings::values.motion_enabled.GetValue()) { | ||
| 94 | state = default_motion_state; | ||
| 95 | return; | ||
| 96 | } | ||
| 97 | state.attribute.is_connected.Assign(1); | ||
| 98 | state.delta_time = std::chrono::nanoseconds(5ms).count(); | ||
| 99 | state.accel = hid_state.accel; | ||
| 100 | state.gyro = hid_state.gyro; | ||
| 101 | state.rotation = hid_state.rotation; | ||
| 102 | state.orientation = hid_state.orientation; | ||
| 103 | }; | ||
| 104 | |||
| 105 | switch (controller_type) { | ||
| 106 | case Core::HID::NpadStyleIndex::None: | ||
| 107 | ASSERT(false); | ||
| 108 | break; | ||
| 109 | case Core::HID::NpadStyleIndex::ProController: | ||
| 110 | set_motion_state(sixaxis_fullkey_state, motion_state[0]); | ||
| 111 | break; | ||
| 112 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 113 | set_motion_state(sixaxis_handheld_state, motion_state[0]); | ||
| 114 | break; | ||
| 115 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 116 | set_motion_state(sixaxis_dual_left_state, motion_state[0]); | ||
| 117 | set_motion_state(sixaxis_dual_right_state, motion_state[1]); | ||
| 118 | break; | ||
| 119 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 120 | set_motion_state(sixaxis_left_lifo_state, motion_state[0]); | ||
| 121 | break; | ||
| 122 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 123 | set_motion_state(sixaxis_right_lifo_state, motion_state[1]); | ||
| 124 | break; | ||
| 125 | case Core::HID::NpadStyleIndex::Pokeball: | ||
| 126 | using namespace std::literals::chrono_literals; | ||
| 127 | set_motion_state(sixaxis_fullkey_state, motion_state[0]); | ||
| 128 | sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count(); | ||
| 129 | break; | ||
| 130 | default: | ||
| 131 | break; | ||
| 132 | } | ||
| 133 | |||
| 134 | sixaxis_fullkey_state.sampling_number = | ||
| 135 | sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 136 | sixaxis_handheld_state.sampling_number = | ||
| 137 | sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 138 | sixaxis_dual_left_state.sampling_number = | ||
| 139 | sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 140 | sixaxis_dual_right_state.sampling_number = | ||
| 141 | sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 142 | sixaxis_left_lifo_state.sampling_number = | ||
| 143 | sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 144 | sixaxis_right_lifo_state.sampling_number = | ||
| 145 | sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 146 | |||
| 147 | if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { | ||
| 148 | // This buffer only is updated on handheld on HW | ||
| 149 | sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); | ||
| 150 | } else { | ||
| 151 | // Handheld doesn't update this buffer on HW | ||
| 152 | sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); | ||
| 153 | } | ||
| 154 | |||
| 155 | sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); | ||
| 156 | sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); | ||
| 157 | sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); | ||
| 158 | sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | Result SixAxis::SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 163 | Core::HID::GyroscopeZeroDriftMode drift_mode) { | ||
| 164 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 165 | if (is_valid.IsError()) { | ||
| 166 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 167 | return is_valid; | ||
| 168 | } | ||
| 169 | |||
| 170 | auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 171 | auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 172 | sixaxis.gyroscope_zero_drift_mode = drift_mode; | ||
| 173 | controller.device->SetGyroscopeZeroDriftMode(drift_mode); | ||
| 174 | |||
| 175 | return ResultSuccess; | ||
| 176 | } | ||
| 177 | |||
| 178 | Result SixAxis::GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 179 | Core::HID::GyroscopeZeroDriftMode& drift_mode) const { | ||
| 180 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 181 | if (is_valid.IsError()) { | ||
| 182 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 183 | return is_valid; | ||
| 184 | } | ||
| 185 | |||
| 186 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 187 | drift_mode = sixaxis.gyroscope_zero_drift_mode; | ||
| 188 | |||
| 189 | return ResultSuccess; | ||
| 190 | } | ||
| 191 | |||
| 192 | Result SixAxis::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 193 | bool& is_at_rest) const { | ||
| 194 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 195 | if (is_valid.IsError()) { | ||
| 196 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 197 | return is_valid; | ||
| 198 | } | ||
| 199 | |||
| 200 | const auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 201 | is_at_rest = controller.sixaxis_at_rest; | ||
| 202 | return ResultSuccess; | ||
| 203 | } | ||
| 204 | |||
| 205 | Result SixAxis::LoadSixAxisSensorCalibrationParameter( | ||
| 206 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 207 | Core::HID::SixAxisSensorCalibrationParameter& calibration) const { | ||
| 208 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 209 | if (is_valid.IsError()) { | ||
| 210 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 211 | return is_valid; | ||
| 212 | } | ||
| 213 | |||
| 214 | // TODO: Request this data to the controller. On error return 0xd8ca | ||
| 215 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 216 | calibration = sixaxis.calibration; | ||
| 217 | return ResultSuccess; | ||
| 218 | } | ||
| 219 | |||
| 220 | Result SixAxis::GetSixAxisSensorIcInformation( | ||
| 221 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 222 | Core::HID::SixAxisSensorIcInformation& ic_information) const { | ||
| 223 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 224 | if (is_valid.IsError()) { | ||
| 225 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 226 | return is_valid; | ||
| 227 | } | ||
| 228 | |||
| 229 | // TODO: Request this data to the controller. On error return 0xd8ca | ||
| 230 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 231 | ic_information = sixaxis.ic_information; | ||
| 232 | return ResultSuccess; | ||
| 233 | } | ||
| 234 | |||
| 235 | Result SixAxis::EnableSixAxisSensorUnalteredPassthrough( | ||
| 236 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) { | ||
| 237 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 238 | if (is_valid.IsError()) { | ||
| 239 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 240 | return is_valid; | ||
| 241 | } | ||
| 242 | |||
| 243 | auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 244 | sixaxis.unaltered_passtrough = is_enabled; | ||
| 245 | return ResultSuccess; | ||
| 246 | } | ||
| 247 | |||
| 248 | Result SixAxis::IsSixAxisSensorUnalteredPassthroughEnabled( | ||
| 249 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const { | ||
| 250 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 251 | if (is_valid.IsError()) { | ||
| 252 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 253 | return is_valid; | ||
| 254 | } | ||
| 255 | |||
| 256 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 257 | is_enabled = sixaxis.unaltered_passtrough; | ||
| 258 | return ResultSuccess; | ||
| 259 | } | ||
| 260 | |||
| 261 | Result SixAxis::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 262 | bool sixaxis_status) { | ||
| 263 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 264 | if (is_valid.IsError()) { | ||
| 265 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 266 | return is_valid; | ||
| 267 | } | ||
| 268 | |||
| 269 | auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 270 | controller.sixaxis_sensor_enabled = sixaxis_status; | ||
| 271 | return ResultSuccess; | ||
| 272 | } | ||
| 273 | |||
| 274 | Result SixAxis::IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 275 | bool& is_fusion_enabled) const { | ||
| 276 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 277 | if (is_valid.IsError()) { | ||
| 278 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 279 | return is_valid; | ||
| 280 | } | ||
| 281 | |||
| 282 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 283 | is_fusion_enabled = sixaxis.is_fusion_enabled; | ||
| 284 | |||
| 285 | return ResultSuccess; | ||
| 286 | } | ||
| 287 | Result SixAxis::SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 288 | bool is_fusion_enabled) { | ||
| 289 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 290 | if (is_valid.IsError()) { | ||
| 291 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 292 | return is_valid; | ||
| 293 | } | ||
| 294 | |||
| 295 | auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 296 | sixaxis.is_fusion_enabled = is_fusion_enabled; | ||
| 297 | |||
| 298 | return ResultSuccess; | ||
| 299 | } | ||
| 300 | |||
| 301 | Result SixAxis::SetSixAxisFusionParameters( | ||
| 302 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 303 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) { | ||
| 304 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 305 | if (is_valid.IsError()) { | ||
| 306 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 307 | return is_valid; | ||
| 308 | } | ||
| 309 | |||
| 310 | const auto param1 = sixaxis_fusion_parameters.parameter1; | ||
| 311 | if (param1 < 0.0f || param1 > 1.0f) { | ||
| 312 | return InvalidSixAxisFusionRange; | ||
| 313 | } | ||
| 314 | |||
| 315 | auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 316 | sixaxis.fusion = sixaxis_fusion_parameters; | ||
| 317 | |||
| 318 | return ResultSuccess; | ||
| 319 | } | ||
| 320 | |||
| 321 | Result SixAxis::GetSixAxisFusionParameters( | ||
| 322 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 323 | Core::HID::SixAxisSensorFusionParameters& parameters) const { | ||
| 324 | const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); | ||
| 325 | if (is_valid.IsError()) { | ||
| 326 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||
| 327 | return is_valid; | ||
| 328 | } | ||
| 329 | |||
| 330 | const auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||
| 331 | parameters = sixaxis.fusion; | ||
| 332 | |||
| 333 | return ResultSuccess; | ||
| 334 | } | ||
| 335 | |||
| 336 | SixAxis::SixaxisParameters& SixAxis::GetSixaxisState( | ||
| 337 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) { | ||
| 338 | auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 339 | switch (sixaxis_handle.npad_type) { | ||
| 340 | case Core::HID::NpadStyleIndex::ProController: | ||
| 341 | case Core::HID::NpadStyleIndex::Pokeball: | ||
| 342 | return controller.sixaxis_fullkey; | ||
| 343 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 344 | return controller.sixaxis_handheld; | ||
| 345 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 346 | if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { | ||
| 347 | return controller.sixaxis_dual_left; | ||
| 348 | } | ||
| 349 | return controller.sixaxis_dual_right; | ||
| 350 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 351 | return controller.sixaxis_left; | ||
| 352 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 353 | return controller.sixaxis_right; | ||
| 354 | default: | ||
| 355 | return controller.sixaxis_unknown; | ||
| 356 | } | ||
| 357 | } | ||
| 358 | |||
| 359 | const SixAxis::SixaxisParameters& SixAxis::GetSixaxisState( | ||
| 360 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { | ||
| 361 | const auto& controller = GetControllerFromHandle(sixaxis_handle); | ||
| 362 | switch (sixaxis_handle.npad_type) { | ||
| 363 | case Core::HID::NpadStyleIndex::ProController: | ||
| 364 | case Core::HID::NpadStyleIndex::Pokeball: | ||
| 365 | return controller.sixaxis_fullkey; | ||
| 366 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 367 | return controller.sixaxis_handheld; | ||
| 368 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 369 | if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { | ||
| 370 | return controller.sixaxis_dual_left; | ||
| 371 | } | ||
| 372 | return controller.sixaxis_dual_right; | ||
| 373 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 374 | return controller.sixaxis_left; | ||
| 375 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 376 | return controller.sixaxis_right; | ||
| 377 | default: | ||
| 378 | return controller.sixaxis_unknown; | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 382 | SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle( | ||
| 383 | const Core::HID::SixAxisSensorHandle& device_handle) { | ||
| 384 | const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); | ||
| 385 | return GetControllerFromNpadIdType(npad_id); | ||
| 386 | } | ||
| 387 | |||
| 388 | const SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle( | ||
| 389 | const Core::HID::SixAxisSensorHandle& device_handle) const { | ||
| 390 | const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); | ||
| 391 | return GetControllerFromNpadIdType(npad_id); | ||
| 392 | } | ||
| 393 | |||
| 394 | SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) { | ||
| 395 | if (!IsNpadIdValid(npad_id)) { | ||
| 396 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | ||
| 397 | npad_id = Core::HID::NpadIdType::Player1; | ||
| 398 | } | ||
| 399 | const auto npad_index = NpadIdTypeToIndex(npad_id); | ||
| 400 | return controller_data[npad_index]; | ||
| 401 | } | ||
| 402 | |||
| 403 | const SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType( | ||
| 404 | Core::HID::NpadIdType npad_id) const { | ||
| 405 | if (!IsNpadIdValid(npad_id)) { | ||
| 406 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | ||
| 407 | npad_id = Core::HID::NpadIdType::Player1; | ||
| 408 | } | ||
| 409 | const auto npad_index = NpadIdTypeToIndex(npad_id); | ||
| 410 | return controller_data[npad_index]; | ||
| 411 | } | ||
| 412 | |||
| 413 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/six_axis.h b/src/core/hle/service/hid/controllers/six_axis.h new file mode 100644 index 000000000..4c4f5dc7b --- /dev/null +++ b/src/core/hle/service/hid/controllers/six_axis.h | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "core/hid/hid_types.h" | ||
| 8 | #include "core/hle/service/hid/controllers/controller_base.h" | ||
| 9 | #include "core/hle/service/hid/ring_lifo.h" | ||
| 10 | |||
| 11 | namespace Core::HID { | ||
| 12 | class EmulatedController; | ||
| 13 | } // namespace Core::HID | ||
| 14 | |||
| 15 | namespace Service::HID { | ||
| 16 | class NPad; | ||
| 17 | |||
| 18 | class SixAxis final : public ControllerBase { | ||
| 19 | public: | ||
| 20 | explicit SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_); | ||
| 21 | ~SixAxis() override; | ||
| 22 | |||
| 23 | // Called when the controller is initialized | ||
| 24 | void OnInit() override; | ||
| 25 | |||
| 26 | // When the controller is released | ||
| 27 | void OnRelease() override; | ||
| 28 | |||
| 29 | // When the controller is requesting an update for the shared memory | ||
| 30 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||
| 31 | |||
| 32 | Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 33 | Core::HID::GyroscopeZeroDriftMode drift_mode); | ||
| 34 | Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 35 | Core::HID::GyroscopeZeroDriftMode& drift_mode) const; | ||
| 36 | Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 37 | bool& is_at_rest) const; | ||
| 38 | Result EnableSixAxisSensorUnalteredPassthrough( | ||
| 39 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled); | ||
| 40 | Result IsSixAxisSensorUnalteredPassthroughEnabled( | ||
| 41 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const; | ||
| 42 | Result LoadSixAxisSensorCalibrationParameter( | ||
| 43 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 44 | Core::HID::SixAxisSensorCalibrationParameter& calibration) const; | ||
| 45 | Result GetSixAxisSensorIcInformation( | ||
| 46 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 47 | Core::HID::SixAxisSensorIcInformation& ic_information) const; | ||
| 48 | Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 49 | bool sixaxis_status); | ||
| 50 | Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 51 | bool& is_fusion_enabled) const; | ||
| 52 | Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 53 | bool is_fusion_enabled); | ||
| 54 | Result SetSixAxisFusionParameters( | ||
| 55 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 56 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters); | ||
| 57 | Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||
| 58 | Core::HID::SixAxisSensorFusionParameters& parameters) const; | ||
| 59 | |||
| 60 | private: | ||
| 61 | static constexpr std::size_t NPAD_COUNT = 10; | ||
| 62 | |||
| 63 | struct SixaxisParameters { | ||
| 64 | bool is_fusion_enabled{true}; | ||
| 65 | bool unaltered_passtrough{false}; | ||
| 66 | Core::HID::SixAxisSensorFusionParameters fusion{}; | ||
| 67 | Core::HID::SixAxisSensorCalibrationParameter calibration{}; | ||
| 68 | Core::HID::SixAxisSensorIcInformation ic_information{}; | ||
| 69 | Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{ | ||
| 70 | Core::HID::GyroscopeZeroDriftMode::Standard}; | ||
| 71 | }; | ||
| 72 | |||
| 73 | struct NpadControllerData { | ||
| 74 | Core::HID::EmulatedController* device = nullptr; | ||
| 75 | |||
| 76 | // Motion parameters | ||
| 77 | bool sixaxis_at_rest{true}; | ||
| 78 | bool sixaxis_sensor_enabled{true}; | ||
| 79 | SixaxisParameters sixaxis_fullkey{}; | ||
| 80 | SixaxisParameters sixaxis_handheld{}; | ||
| 81 | SixaxisParameters sixaxis_dual_left{}; | ||
| 82 | SixaxisParameters sixaxis_dual_right{}; | ||
| 83 | SixaxisParameters sixaxis_left{}; | ||
| 84 | SixaxisParameters sixaxis_right{}; | ||
| 85 | SixaxisParameters sixaxis_unknown{}; | ||
| 86 | |||
| 87 | // Current pad state | ||
| 88 | Core::HID::SixAxisSensorState sixaxis_fullkey_state{}; | ||
| 89 | Core::HID::SixAxisSensorState sixaxis_handheld_state{}; | ||
| 90 | Core::HID::SixAxisSensorState sixaxis_dual_left_state{}; | ||
| 91 | Core::HID::SixAxisSensorState sixaxis_dual_right_state{}; | ||
| 92 | Core::HID::SixAxisSensorState sixaxis_left_lifo_state{}; | ||
| 93 | Core::HID::SixAxisSensorState sixaxis_right_lifo_state{}; | ||
| 94 | int callback_key{}; | ||
| 95 | }; | ||
| 96 | |||
| 97 | SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle); | ||
| 98 | const SixaxisParameters& GetSixaxisState( | ||
| 99 | const Core::HID::SixAxisSensorHandle& device_handle) const; | ||
| 100 | |||
| 101 | NpadControllerData& GetControllerFromHandle( | ||
| 102 | const Core::HID::SixAxisSensorHandle& device_handle); | ||
| 103 | const NpadControllerData& GetControllerFromHandle( | ||
| 104 | const Core::HID::SixAxisSensorHandle& device_handle) const; | ||
| 105 | NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id); | ||
| 106 | const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const; | ||
| 107 | |||
| 108 | std::shared_ptr<NPad> npad; | ||
| 109 | std::array<NpadControllerData, NPAD_COUNT> controller_data{}; | ||
| 110 | }; | ||
| 111 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 3ef91df4b..3bcf0ee9f 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp | |||
| @@ -15,8 +15,7 @@ | |||
| 15 | namespace Service::HID { | 15 | namespace Service::HID { |
| 16 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; | 16 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; |
| 17 | 17 | ||
| 18 | Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_, | 18 | TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) |
| 19 | u8* raw_shared_memory_) | ||
| 20 | : ControllerBase{hid_core_} { | 19 | : ControllerBase{hid_core_} { |
| 21 | static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size, | 20 | static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size, |
| 22 | "TouchSharedMemory is bigger than the shared memory"); | 21 | "TouchSharedMemory is bigger than the shared memory"); |
| @@ -25,13 +24,13 @@ Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_, | |||
| 25 | console = hid_core.GetEmulatedConsole(); | 24 | console = hid_core.GetEmulatedConsole(); |
| 26 | } | 25 | } |
| 27 | 26 | ||
| 28 | Controller_Touchscreen::~Controller_Touchscreen() = default; | 27 | TouchScreen::~TouchScreen() = default; |
| 29 | 28 | ||
| 30 | void Controller_Touchscreen::OnInit() {} | 29 | void TouchScreen::OnInit() {} |
| 31 | 30 | ||
| 32 | void Controller_Touchscreen::OnRelease() {} | 31 | void TouchScreen::OnRelease() {} |
| 33 | 32 | ||
| 34 | void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 33 | void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 35 | shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); | 34 | shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); |
| 36 | 35 | ||
| 37 | if (!IsControllerActivated()) { | 36 | if (!IsControllerActivated()) { |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index dd00921fd..cd342ce91 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h | |||
| @@ -14,10 +14,10 @@ class EmulatedConsole; | |||
| 14 | } // namespace Core::HID | 14 | } // namespace Core::HID |
| 15 | 15 | ||
| 16 | namespace Service::HID { | 16 | namespace Service::HID { |
| 17 | class Controller_Touchscreen final : public ControllerBase { | 17 | class TouchScreen final : public ControllerBase { |
| 18 | public: | 18 | public: |
| 19 | explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 19 | explicit TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 20 | ~Controller_Touchscreen() override; | 20 | ~TouchScreen() override; |
| 21 | 21 | ||
| 22 | // Called when the controller is initialized | 22 | // Called when the controller is initialized |
| 23 | void OnInit() override; | 23 | void OnInit() override; |
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp index 62119e2c5..0aaed1fa7 100644 --- a/src/core/hle/service/hid/controllers/xpad.cpp +++ b/src/core/hle/service/hid/controllers/xpad.cpp | |||
| @@ -10,20 +10,19 @@ | |||
| 10 | namespace Service::HID { | 10 | namespace Service::HID { |
| 11 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; | 11 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; |
| 12 | 12 | ||
| 13 | Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 13 | XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { |
| 14 | : ControllerBase{hid_core_} { | ||
| 15 | static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size, | 14 | static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size, |
| 16 | "XpadSharedMemory is bigger than the shared memory"); | 15 | "XpadSharedMemory is bigger than the shared memory"); |
| 17 | shared_memory = std::construct_at( | 16 | shared_memory = std::construct_at( |
| 18 | reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | 17 | reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); |
| 19 | } | 18 | } |
| 20 | Controller_XPad::~Controller_XPad() = default; | 19 | XPad::~XPad() = default; |
| 21 | 20 | ||
| 22 | void Controller_XPad::OnInit() {} | 21 | void XPad::OnInit() {} |
| 23 | 22 | ||
| 24 | void Controller_XPad::OnRelease() {} | 23 | void XPad::OnRelease() {} |
| 25 | 24 | ||
| 26 | void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 25 | void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 27 | if (!IsControllerActivated()) { | 26 | if (!IsControllerActivated()) { |
| 28 | shared_memory->basic_xpad_lifo.buffer_count = 0; | 27 | shared_memory->basic_xpad_lifo.buffer_count = 0; |
| 29 | shared_memory->basic_xpad_lifo.buffer_tail = 0; | 28 | shared_memory->basic_xpad_lifo.buffer_tail = 0; |
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h index d01dee5fc..9e63a317a 100644 --- a/src/core/hle/service/hid/controllers/xpad.h +++ b/src/core/hle/service/hid/controllers/xpad.h | |||
| @@ -10,10 +10,10 @@ | |||
| 10 | #include "core/hle/service/hid/ring_lifo.h" | 10 | #include "core/hle/service/hid/ring_lifo.h" |
| 11 | 11 | ||
| 12 | namespace Service::HID { | 12 | namespace Service::HID { |
| 13 | class Controller_XPad final : public ControllerBase { | 13 | class XPad final : public ControllerBase { |
| 14 | public: | 14 | public: |
| 15 | explicit Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 15 | explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); |
| 16 | ~Controller_XPad() override; | 16 | ~XPad() override; |
| 17 | 17 | ||
| 18 | // Called when the controller is initialized | 18 | // Called when the controller is initialized |
| 19 | void OnInit() override; | 19 | void OnInit() override; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 929dd5f03..1b7381d8d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -1,2864 +1,39 @@ | |||
| 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 <array> | ||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "common/settings.h" | ||
| 8 | #include "core/core.h" | ||
| 9 | #include "core/core_timing.h" | ||
| 10 | #include "core/hid/hid_core.h" | ||
| 11 | #include "core/hle/kernel/k_readable_event.h" | ||
| 12 | #include "core/hle/kernel/k_shared_memory.h" | ||
| 13 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 14 | #include "core/hle/kernel/kernel.h" | ||
| 15 | #include "core/hle/service/hid/errors.h" | ||
| 16 | #include "core/hle/service/hid/hid.h" | 4 | #include "core/hle/service/hid/hid.h" |
| 5 | #include "core/hle/service/hid/hid_debug_server.h" | ||
| 6 | #include "core/hle/service/hid/hid_firmware_settings.h" | ||
| 7 | #include "core/hle/service/hid/hid_server.h" | ||
| 8 | #include "core/hle/service/hid/hid_system_server.h" | ||
| 17 | #include "core/hle/service/hid/hidbus.h" | 9 | #include "core/hle/service/hid/hidbus.h" |
| 18 | #include "core/hle/service/hid/irs.h" | 10 | #include "core/hle/service/hid/irs.h" |
| 11 | #include "core/hle/service/hid/resource_manager.h" | ||
| 19 | #include "core/hle/service/hid/xcd.h" | 12 | #include "core/hle/service/hid/xcd.h" |
| 20 | #include "core/hle/service/ipc_helpers.h" | ||
| 21 | #include "core/hle/service/server_manager.h" | 13 | #include "core/hle/service/server_manager.h" |
| 22 | #include "core/memory.h" | ||
| 23 | |||
| 24 | #include "core/hle/service/hid/controllers/console_sixaxis.h" | ||
| 25 | #include "core/hle/service/hid/controllers/controller_base.h" | ||
| 26 | #include "core/hle/service/hid/controllers/debug_pad.h" | ||
| 27 | #include "core/hle/service/hid/controllers/gesture.h" | ||
| 28 | #include "core/hle/service/hid/controllers/keyboard.h" | ||
| 29 | #include "core/hle/service/hid/controllers/mouse.h" | ||
| 30 | #include "core/hle/service/hid/controllers/npad.h" | ||
| 31 | #include "core/hle/service/hid/controllers/palma.h" | ||
| 32 | #include "core/hle/service/hid/controllers/stubbed.h" | ||
| 33 | #include "core/hle/service/hid/controllers/touchscreen.h" | ||
| 34 | #include "core/hle/service/hid/controllers/xpad.h" | ||
| 35 | 14 | ||
| 36 | namespace Service::HID { | 15 | namespace Service::HID { |
| 37 | 16 | ||
| 38 | // Updating period for each HID device. | ||
| 39 | // Period time is obtained by measuring the number of samples in a second on HW using a homebrew | ||
| 40 | // Correct npad_update_ns is 4ms this is overclocked to lower input lag | ||
| 41 | constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz) | ||
| 42 | constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz) | ||
| 43 | constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) | ||
| 44 | constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) | ||
| 45 | |||
| 46 | IAppletResource::IAppletResource(Core::System& system_, | ||
| 47 | KernelHelpers::ServiceContext& service_context_) | ||
| 48 | : ServiceFramework{system_, "IAppletResource"}, service_context{service_context_} { | ||
| 49 | static const FunctionInfo functions[] = { | ||
| 50 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, | ||
| 51 | }; | ||
| 52 | RegisterHandlers(functions); | ||
| 53 | u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer(); | ||
| 54 | MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory); | ||
| 55 | MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory); | ||
| 56 | MakeController<Controller_Mouse>(HidController::Mouse, shared_memory); | ||
| 57 | MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory); | ||
| 58 | MakeController<Controller_XPad>(HidController::XPad, shared_memory); | ||
| 59 | MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory); | ||
| 60 | MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory); | ||
| 61 | MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory); | ||
| 62 | MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory); | ||
| 63 | MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory); | ||
| 64 | MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory); | ||
| 65 | MakeController<Controller_Gesture>(HidController::Gesture, shared_memory); | ||
| 66 | MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory); | ||
| 67 | MakeController<Controller_Stubbed>(HidController::DebugMouse, shared_memory); | ||
| 68 | MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory); | ||
| 69 | |||
| 70 | // Homebrew doesn't try to activate some controllers, so we activate them by default | ||
| 71 | GetController<Controller_NPad>(HidController::NPad).ActivateController(); | ||
| 72 | GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController(); | ||
| 73 | |||
| 74 | GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00); | ||
| 75 | GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00); | ||
| 76 | GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000); | ||
| 77 | GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200); | ||
| 78 | GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00); | ||
| 79 | GetController<Controller_Stubbed>(HidController::DebugMouse).SetCommonHeaderOffset(0x3DC00); | ||
| 80 | |||
| 81 | // Register update callbacks | ||
| 82 | npad_update_event = Core::Timing::CreateEvent( | ||
| 83 | "HID::UpdatePadCallback", | ||
| 84 | [this](std::uintptr_t user_data, s64 time, | ||
| 85 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 86 | const auto guard = LockService(); | ||
| 87 | UpdateNpad(user_data, ns_late); | ||
| 88 | return std::nullopt; | ||
| 89 | }); | ||
| 90 | default_update_event = Core::Timing::CreateEvent( | ||
| 91 | "HID::UpdateDefaultCallback", | ||
| 92 | [this](std::uintptr_t user_data, s64 time, | ||
| 93 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 94 | const auto guard = LockService(); | ||
| 95 | UpdateControllers(user_data, ns_late); | ||
| 96 | return std::nullopt; | ||
| 97 | }); | ||
| 98 | mouse_keyboard_update_event = Core::Timing::CreateEvent( | ||
| 99 | "HID::UpdateMouseKeyboardCallback", | ||
| 100 | [this](std::uintptr_t user_data, s64 time, | ||
| 101 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 102 | const auto guard = LockService(); | ||
| 103 | UpdateMouseKeyboard(user_data, ns_late); | ||
| 104 | return std::nullopt; | ||
| 105 | }); | ||
| 106 | motion_update_event = Core::Timing::CreateEvent( | ||
| 107 | "HID::UpdateMotionCallback", | ||
| 108 | [this](std::uintptr_t user_data, s64 time, | ||
| 109 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 110 | const auto guard = LockService(); | ||
| 111 | UpdateMotion(user_data, ns_late); | ||
| 112 | return std::nullopt; | ||
| 113 | }); | ||
| 114 | |||
| 115 | system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event); | ||
| 116 | system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns, | ||
| 117 | default_update_event); | ||
| 118 | system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns, | ||
| 119 | mouse_keyboard_update_event); | ||
| 120 | system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns, | ||
| 121 | motion_update_event); | ||
| 122 | |||
| 123 | system.HIDCore().ReloadInputDevices(); | ||
| 124 | } | ||
| 125 | |||
| 126 | void IAppletResource::ActivateController(HidController controller) { | ||
| 127 | controllers[static_cast<size_t>(controller)]->ActivateController(); | ||
| 128 | } | ||
| 129 | |||
| 130 | void IAppletResource::DeactivateController(HidController controller) { | ||
| 131 | controllers[static_cast<size_t>(controller)]->DeactivateController(); | ||
| 132 | } | ||
| 133 | |||
| 134 | IAppletResource::~IAppletResource() { | ||
| 135 | system.CoreTiming().UnscheduleEvent(npad_update_event, 0); | ||
| 136 | system.CoreTiming().UnscheduleEvent(default_update_event, 0); | ||
| 137 | system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0); | ||
| 138 | system.CoreTiming().UnscheduleEvent(motion_update_event, 0); | ||
| 139 | } | ||
| 140 | |||
| 141 | void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { | ||
| 142 | LOG_DEBUG(Service_HID, "called"); | ||
| 143 | |||
| 144 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 145 | rb.Push(ResultSuccess); | ||
| 146 | rb.PushCopyObjects(&system.Kernel().GetHidSharedMem()); | ||
| 147 | } | ||
| 148 | |||
| 149 | void IAppletResource::UpdateControllers(std::uintptr_t user_data, | ||
| 150 | std::chrono::nanoseconds ns_late) { | ||
| 151 | auto& core_timing = system.CoreTiming(); | ||
| 152 | |||
| 153 | for (const auto& controller : controllers) { | ||
| 154 | // Keyboard has it's own update event | ||
| 155 | if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) { | ||
| 156 | continue; | ||
| 157 | } | ||
| 158 | // Mouse has it's own update event | ||
| 159 | if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) { | ||
| 160 | continue; | ||
| 161 | } | ||
| 162 | // Npad has it's own update event | ||
| 163 | if (controller == controllers[static_cast<size_t>(HidController::NPad)]) { | ||
| 164 | continue; | ||
| 165 | } | ||
| 166 | controller->OnUpdate(core_timing); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | void IAppletResource::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | ||
| 171 | auto& core_timing = system.CoreTiming(); | ||
| 172 | |||
| 173 | controllers[static_cast<size_t>(HidController::NPad)]->OnUpdate(core_timing); | ||
| 174 | } | ||
| 175 | |||
| 176 | void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data, | ||
| 177 | std::chrono::nanoseconds ns_late) { | ||
| 178 | auto& core_timing = system.CoreTiming(); | ||
| 179 | |||
| 180 | controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing); | ||
| 181 | controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing); | ||
| 182 | } | ||
| 183 | |||
| 184 | void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | ||
| 185 | auto& core_timing = system.CoreTiming(); | ||
| 186 | |||
| 187 | controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing); | ||
| 188 | } | ||
| 189 | |||
| 190 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { | ||
| 191 | public: | ||
| 192 | explicit IActiveVibrationDeviceList(Core::System& system_, | ||
| 193 | std::shared_ptr<IAppletResource> applet_resource_) | ||
| 194 | : ServiceFramework{system_, "IActiveVibrationDeviceList"}, | ||
| 195 | applet_resource(applet_resource_) { | ||
| 196 | // clang-format off | ||
| 197 | static const FunctionInfo functions[] = { | ||
| 198 | {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"}, | ||
| 199 | }; | ||
| 200 | // clang-format on | ||
| 201 | |||
| 202 | RegisterHandlers(functions); | ||
| 203 | } | ||
| 204 | |||
| 205 | private: | ||
| 206 | void InitializeVibrationDevice(HLERequestContext& ctx) { | ||
| 207 | IPC::RequestParser rp{ctx}; | ||
| 208 | const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; | ||
| 209 | |||
| 210 | if (applet_resource != nullptr) { | ||
| 211 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 212 | .InitializeVibrationDevice(vibration_device_handle); | ||
| 213 | } | ||
| 214 | |||
| 215 | LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}", | ||
| 216 | vibration_device_handle.npad_type, vibration_device_handle.npad_id, | ||
| 217 | vibration_device_handle.device_index); | ||
| 218 | |||
| 219 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 220 | rb.Push(ResultSuccess); | ||
| 221 | } | ||
| 222 | |||
| 223 | std::shared_ptr<IAppletResource> applet_resource; | ||
| 224 | }; | ||
| 225 | |||
| 226 | std::shared_ptr<IAppletResource> Hid::GetAppletResource() { | ||
| 227 | if (applet_resource == nullptr) { | ||
| 228 | applet_resource = std::make_shared<IAppletResource>(system, service_context); | ||
| 229 | } | ||
| 230 | |||
| 231 | return applet_resource; | ||
| 232 | } | ||
| 233 | |||
| 234 | Hid::Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_) | ||
| 235 | : ServiceFramework{system_, "hid"}, applet_resource{applet_resource_}, service_context{ | ||
| 236 | system_, | ||
| 237 | service_name} { | ||
| 238 | // clang-format off | ||
| 239 | static const FunctionInfo functions[] = { | ||
| 240 | {0, &Hid::CreateAppletResource, "CreateAppletResource"}, | ||
| 241 | {1, &Hid::ActivateDebugPad, "ActivateDebugPad"}, | ||
| 242 | {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"}, | ||
| 243 | {21, &Hid::ActivateMouse, "ActivateMouse"}, | ||
| 244 | {26, nullptr, "ActivateDebugMouse"}, | ||
| 245 | {31, &Hid::ActivateKeyboard, "ActivateKeyboard"}, | ||
| 246 | {32, &Hid::SendKeyboardLockKeyEvent, "SendKeyboardLockKeyEvent"}, | ||
| 247 | {40, nullptr, "AcquireXpadIdEventHandle"}, | ||
| 248 | {41, nullptr, "ReleaseXpadIdEventHandle"}, | ||
| 249 | {51, &Hid::ActivateXpad, "ActivateXpad"}, | ||
| 250 | {55, &Hid::GetXpadIDs, "GetXpadIds"}, | ||
| 251 | {56, nullptr, "ActivateJoyXpad"}, | ||
| 252 | {58, nullptr, "GetJoyXpadLifoHandle"}, | ||
| 253 | {59, nullptr, "GetJoyXpadIds"}, | ||
| 254 | {60, &Hid::ActivateSixAxisSensor, "ActivateSixAxisSensor"}, | ||
| 255 | {61, &Hid::DeactivateSixAxisSensor, "DeactivateSixAxisSensor"}, | ||
| 256 | {62, nullptr, "GetSixAxisSensorLifoHandle"}, | ||
| 257 | {63, nullptr, "ActivateJoySixAxisSensor"}, | ||
| 258 | {64, nullptr, "DeactivateJoySixAxisSensor"}, | ||
| 259 | {65, nullptr, "GetJoySixAxisSensorLifoHandle"}, | ||
| 260 | {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"}, | ||
| 261 | {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"}, | ||
| 262 | {68, &Hid::IsSixAxisSensorFusionEnabled, "IsSixAxisSensorFusionEnabled"}, | ||
| 263 | {69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"}, | ||
| 264 | {70, &Hid::SetSixAxisSensorFusionParameters, "SetSixAxisSensorFusionParameters"}, | ||
| 265 | {71, &Hid::GetSixAxisSensorFusionParameters, "GetSixAxisSensorFusionParameters"}, | ||
| 266 | {72, &Hid::ResetSixAxisSensorFusionParameters, "ResetSixAxisSensorFusionParameters"}, | ||
| 267 | {73, nullptr, "SetAccelerometerParameters"}, | ||
| 268 | {74, nullptr, "GetAccelerometerParameters"}, | ||
| 269 | {75, nullptr, "ResetAccelerometerParameters"}, | ||
| 270 | {76, nullptr, "SetAccelerometerPlayMode"}, | ||
| 271 | {77, nullptr, "GetAccelerometerPlayMode"}, | ||
| 272 | {78, nullptr, "ResetAccelerometerPlayMode"}, | ||
| 273 | {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"}, | ||
| 274 | {80, &Hid::GetGyroscopeZeroDriftMode, "GetGyroscopeZeroDriftMode"}, | ||
| 275 | {81, &Hid::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"}, | ||
| 276 | {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"}, | ||
| 277 | {83, &Hid::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"}, | ||
| 278 | {84, &Hid::EnableSixAxisSensorUnalteredPassthrough, "EnableSixAxisSensorUnalteredPassthrough"}, | ||
| 279 | {85, &Hid::IsSixAxisSensorUnalteredPassthroughEnabled, "IsSixAxisSensorUnalteredPassthroughEnabled"}, | ||
| 280 | {86, nullptr, "StoreSixAxisSensorCalibrationParameter"}, | ||
| 281 | {87, &Hid::LoadSixAxisSensorCalibrationParameter, "LoadSixAxisSensorCalibrationParameter"}, | ||
| 282 | {88, &Hid::GetSixAxisSensorIcInformation, "GetSixAxisSensorIcInformation"}, | ||
| 283 | {89, &Hid::ResetIsSixAxisSensorDeviceNewlyAssigned, "ResetIsSixAxisSensorDeviceNewlyAssigned"}, | ||
| 284 | {91, &Hid::ActivateGesture, "ActivateGesture"}, | ||
| 285 | {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, | ||
| 286 | {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"}, | ||
| 287 | {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"}, | ||
| 288 | {103, &Hid::ActivateNpad, "ActivateNpad"}, | ||
| 289 | {104, &Hid::DeactivateNpad, "DeactivateNpad"}, | ||
| 290 | {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"}, | ||
| 291 | {107, &Hid::DisconnectNpad, "DisconnectNpad"}, | ||
| 292 | {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"}, | ||
| 293 | {109, &Hid::ActivateNpadWithRevision, "ActivateNpadWithRevision"}, | ||
| 294 | {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, | ||
| 295 | {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, | ||
| 296 | {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, | ||
| 297 | {123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"}, | ||
| 298 | {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, | ||
| 299 | {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, | ||
| 300 | {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"}, | ||
| 301 | {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"}, | ||
| 302 | {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, | ||
| 303 | {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"}, | ||
| 304 | {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, | ||
| 305 | {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"}, | ||
| 306 | {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, | ||
| 307 | {133, &Hid::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"}, | ||
| 308 | {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"}, | ||
| 309 | {135, &Hid::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"}, | ||
| 310 | {136, &Hid::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"}, | ||
| 311 | {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, | ||
| 312 | {201, &Hid::SendVibrationValue, "SendVibrationValue"}, | ||
| 313 | {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"}, | ||
| 314 | {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"}, | ||
| 315 | {204, &Hid::PermitVibration, "PermitVibration"}, | ||
| 316 | {205, &Hid::IsVibrationPermitted, "IsVibrationPermitted"}, | ||
| 317 | {206, &Hid::SendVibrationValues, "SendVibrationValues"}, | ||
| 318 | {207, &Hid::SendVibrationGcErmCommand, "SendVibrationGcErmCommand"}, | ||
| 319 | {208, &Hid::GetActualVibrationGcErmCommand, "GetActualVibrationGcErmCommand"}, | ||
| 320 | {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, | ||
| 321 | {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"}, | ||
| 322 | {211, &Hid::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"}, | ||
| 323 | {212, nullptr, "SendVibrationValueInBool"}, | ||
| 324 | {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"}, | ||
| 325 | {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"}, | ||
| 326 | {302, &Hid::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"}, | ||
| 327 | {303, &Hid::ActivateSevenSixAxisSensor, "ActivateSevenSixAxisSensor"}, | ||
| 328 | {304, &Hid::StartSevenSixAxisSensor, "StartSevenSixAxisSensor"}, | ||
| 329 | {305, &Hid::StopSevenSixAxisSensor, "StopSevenSixAxisSensor"}, | ||
| 330 | {306, &Hid::InitializeSevenSixAxisSensor, "InitializeSevenSixAxisSensor"}, | ||
| 331 | {307, &Hid::FinalizeSevenSixAxisSensor, "FinalizeSevenSixAxisSensor"}, | ||
| 332 | {308, nullptr, "SetSevenSixAxisSensorFusionStrength"}, | ||
| 333 | {309, nullptr, "GetSevenSixAxisSensorFusionStrength"}, | ||
| 334 | {310, &Hid::ResetSevenSixAxisSensorTimestamp, "ResetSevenSixAxisSensorTimestamp"}, | ||
| 335 | {400, &Hid::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"}, | ||
| 336 | {401, nullptr, "EnableUsbFullKeyController"}, | ||
| 337 | {402, nullptr, "IsUsbFullKeyControllerConnected"}, | ||
| 338 | {403, nullptr, "HasBattery"}, | ||
| 339 | {404, nullptr, "HasLeftRightBattery"}, | ||
| 340 | {405, nullptr, "GetNpadInterfaceType"}, | ||
| 341 | {406, nullptr, "GetNpadLeftRightInterfaceType"}, | ||
| 342 | {407, nullptr, "GetNpadOfHighestBatteryLevel"}, | ||
| 343 | {408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"}, | ||
| 344 | {500, &Hid::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"}, | ||
| 345 | {501, &Hid::InitializePalma, "InitializePalma"}, | ||
| 346 | {502, &Hid::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"}, | ||
| 347 | {503, &Hid::GetPalmaOperationInfo, "GetPalmaOperationInfo"}, | ||
| 348 | {504, &Hid::PlayPalmaActivity, "PlayPalmaActivity"}, | ||
| 349 | {505, &Hid::SetPalmaFrModeType, "SetPalmaFrModeType"}, | ||
| 350 | {506, &Hid::ReadPalmaStep, "ReadPalmaStep"}, | ||
| 351 | {507, &Hid::EnablePalmaStep, "EnablePalmaStep"}, | ||
| 352 | {508, &Hid::ResetPalmaStep, "ResetPalmaStep"}, | ||
| 353 | {509, &Hid::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"}, | ||
| 354 | {510, &Hid::WritePalmaApplicationSection, "WritePalmaApplicationSection"}, | ||
| 355 | {511, &Hid::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"}, | ||
| 356 | {512, &Hid::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"}, | ||
| 357 | {513, &Hid::WritePalmaActivityEntry, "WritePalmaActivityEntry"}, | ||
| 358 | {514, &Hid::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"}, | ||
| 359 | {515, &Hid::WritePalmaWaveEntry, "WritePalmaWaveEntry"}, | ||
| 360 | {516, &Hid::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"}, | ||
| 361 | {517, &Hid::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"}, | ||
| 362 | {518, &Hid::SuspendPalmaFeature, "SuspendPalmaFeature"}, | ||
| 363 | {519, &Hid::GetPalmaOperationResult, "GetPalmaOperationResult"}, | ||
| 364 | {520, &Hid::ReadPalmaPlayLog, "ReadPalmaPlayLog"}, | ||
| 365 | {521, &Hid::ResetPalmaPlayLog, "ResetPalmaPlayLog"}, | ||
| 366 | {522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"}, | ||
| 367 | {523, &Hid::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"}, | ||
| 368 | {524, &Hid::PairPalma, "PairPalma"}, | ||
| 369 | {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"}, | ||
| 370 | {526, &Hid::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"}, | ||
| 371 | {527, &Hid::EnablePalmaBoostMode, "EnablePalmaBoostMode"}, | ||
| 372 | {528, &Hid::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"}, | ||
| 373 | {529, &Hid::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"}, | ||
| 374 | {1000, &Hid::SetNpadCommunicationMode, "SetNpadCommunicationMode"}, | ||
| 375 | {1001, &Hid::GetNpadCommunicationMode, "GetNpadCommunicationMode"}, | ||
| 376 | {1002, &Hid::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"}, | ||
| 377 | {1003, &Hid::IsFirmwareUpdateNeededForNotification, "IsFirmwareUpdateNeededForNotification"}, | ||
| 378 | {2000, nullptr, "ActivateDigitizer"}, | ||
| 379 | }; | ||
| 380 | // clang-format on | ||
| 381 | |||
| 382 | RegisterHandlers(functions); | ||
| 383 | } | ||
| 384 | |||
| 385 | Hid::~Hid() = default; | ||
| 386 | |||
| 387 | void Hid::CreateAppletResource(HLERequestContext& ctx) { | ||
| 388 | IPC::RequestParser rp{ctx}; | ||
| 389 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 390 | |||
| 391 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 392 | |||
| 393 | if (applet_resource == nullptr) { | ||
| 394 | applet_resource = std::make_shared<IAppletResource>(system, service_context); | ||
| 395 | } | ||
| 396 | |||
| 397 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 398 | rb.Push(ResultSuccess); | ||
| 399 | rb.PushIpcInterface<IAppletResource>(applet_resource); | ||
| 400 | } | ||
| 401 | |||
| 402 | void Hid::ActivateDebugPad(HLERequestContext& ctx) { | ||
| 403 | IPC::RequestParser rp{ctx}; | ||
| 404 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 405 | |||
| 406 | applet_resource->ActivateController(HidController::DebugPad); | ||
| 407 | |||
| 408 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 409 | |||
| 410 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 411 | rb.Push(ResultSuccess); | ||
| 412 | } | ||
| 413 | |||
| 414 | void Hid::ActivateTouchScreen(HLERequestContext& ctx) { | ||
| 415 | IPC::RequestParser rp{ctx}; | ||
| 416 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 417 | |||
| 418 | applet_resource->ActivateController(HidController::Touchscreen); | ||
| 419 | |||
| 420 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 421 | |||
| 422 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 423 | rb.Push(ResultSuccess); | ||
| 424 | } | ||
| 425 | |||
| 426 | void Hid::ActivateMouse(HLERequestContext& ctx) { | ||
| 427 | IPC::RequestParser rp{ctx}; | ||
| 428 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 429 | |||
| 430 | applet_resource->ActivateController(HidController::Mouse); | ||
| 431 | |||
| 432 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 433 | |||
| 434 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 435 | rb.Push(ResultSuccess); | ||
| 436 | } | ||
| 437 | |||
| 438 | void Hid::ActivateKeyboard(HLERequestContext& ctx) { | ||
| 439 | IPC::RequestParser rp{ctx}; | ||
| 440 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 441 | |||
| 442 | applet_resource->ActivateController(HidController::Keyboard); | ||
| 443 | |||
| 444 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 445 | |||
| 446 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 447 | rb.Push(ResultSuccess); | ||
| 448 | } | ||
| 449 | |||
| 450 | void Hid::SendKeyboardLockKeyEvent(HLERequestContext& ctx) { | ||
| 451 | IPC::RequestParser rp{ctx}; | ||
| 452 | const auto flags{rp.Pop<u32>()}; | ||
| 453 | |||
| 454 | LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags); | ||
| 455 | |||
| 456 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 457 | rb.Push(ResultSuccess); | ||
| 458 | } | ||
| 459 | |||
| 460 | void Hid::ActivateXpad(HLERequestContext& ctx) { | ||
| 461 | IPC::RequestParser rp{ctx}; | ||
| 462 | struct Parameters { | ||
| 463 | u32 basic_xpad_id; | ||
| 464 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 465 | u64 applet_resource_user_id; | ||
| 466 | }; | ||
| 467 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 468 | |||
| 469 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 470 | |||
| 471 | applet_resource->ActivateController(HidController::XPad); | ||
| 472 | |||
| 473 | LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", | ||
| 474 | parameters.basic_xpad_id, parameters.applet_resource_user_id); | ||
| 475 | |||
| 476 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 477 | rb.Push(ResultSuccess); | ||
| 478 | } | ||
| 479 | |||
| 480 | void Hid::GetXpadIDs(HLERequestContext& ctx) { | ||
| 481 | IPC::RequestParser rp{ctx}; | ||
| 482 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 483 | |||
| 484 | LOG_DEBUG(Service_HID, "(STUBBED) called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 485 | |||
| 486 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 487 | rb.Push(ResultSuccess); | ||
| 488 | rb.Push(0); | ||
| 489 | } | ||
| 490 | |||
| 491 | void Hid::ActivateSixAxisSensor(HLERequestContext& ctx) { | ||
| 492 | IPC::RequestParser rp{ctx}; | ||
| 493 | struct Parameters { | ||
| 494 | u32 basic_xpad_id; | ||
| 495 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 496 | u64 applet_resource_user_id; | ||
| 497 | }; | ||
| 498 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 499 | |||
| 500 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 501 | |||
| 502 | // This function does nothing on 10.0.0+ | ||
| 503 | |||
| 504 | LOG_WARNING(Service_HID, "(STUBBED) called, basic_xpad_id={}, applet_resource_user_id={}", | ||
| 505 | parameters.basic_xpad_id, parameters.applet_resource_user_id); | ||
| 506 | |||
| 507 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 508 | rb.Push(ResultSuccess); | ||
| 509 | } | ||
| 510 | |||
| 511 | void Hid::DeactivateSixAxisSensor(HLERequestContext& ctx) { | ||
| 512 | IPC::RequestParser rp{ctx}; | ||
| 513 | struct Parameters { | ||
| 514 | u32 basic_xpad_id; | ||
| 515 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 516 | u64 applet_resource_user_id; | ||
| 517 | }; | ||
| 518 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 519 | |||
| 520 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 521 | |||
| 522 | // This function does nothing on 10.0.0+ | ||
| 523 | |||
| 524 | LOG_WARNING(Service_HID, "(STUBBED) called, basic_xpad_id={}, applet_resource_user_id={}", | ||
| 525 | parameters.basic_xpad_id, parameters.applet_resource_user_id); | ||
| 526 | |||
| 527 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 528 | rb.Push(ResultSuccess); | ||
| 529 | } | ||
| 530 | |||
| 531 | void Hid::StartSixAxisSensor(HLERequestContext& ctx) { | ||
| 532 | IPC::RequestParser rp{ctx}; | ||
| 533 | struct Parameters { | ||
| 534 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 535 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 536 | u64 applet_resource_user_id; | ||
| 537 | }; | ||
| 538 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 539 | |||
| 540 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 541 | |||
| 542 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 543 | const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true); | ||
| 544 | |||
| 545 | LOG_DEBUG(Service_HID, | ||
| 546 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 547 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 548 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 549 | |||
| 550 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 551 | rb.Push(result); | ||
| 552 | } | ||
| 553 | |||
| 554 | void Hid::StopSixAxisSensor(HLERequestContext& ctx) { | ||
| 555 | IPC::RequestParser rp{ctx}; | ||
| 556 | struct Parameters { | ||
| 557 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 558 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 559 | u64 applet_resource_user_id; | ||
| 560 | }; | ||
| 561 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 562 | |||
| 563 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 564 | |||
| 565 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 566 | const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false); | ||
| 567 | |||
| 568 | LOG_DEBUG(Service_HID, | ||
| 569 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 570 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 571 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 572 | |||
| 573 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 574 | rb.Push(result); | ||
| 575 | } | ||
| 576 | |||
| 577 | void Hid::IsSixAxisSensorFusionEnabled(HLERequestContext& ctx) { | ||
| 578 | IPC::RequestParser rp{ctx}; | ||
| 579 | struct Parameters { | ||
| 580 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 581 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 582 | u64 applet_resource_user_id; | ||
| 583 | }; | ||
| 584 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 585 | |||
| 586 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 587 | |||
| 588 | bool is_enabled{}; | ||
| 589 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 590 | const auto result = | ||
| 591 | controller.IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled); | ||
| 592 | |||
| 593 | LOG_DEBUG(Service_HID, | ||
| 594 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 595 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 596 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 597 | |||
| 598 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 599 | rb.Push(result); | ||
| 600 | rb.Push(is_enabled); | ||
| 601 | } | ||
| 602 | |||
| 603 | void Hid::EnableSixAxisSensorFusion(HLERequestContext& ctx) { | ||
| 604 | IPC::RequestParser rp{ctx}; | ||
| 605 | struct Parameters { | ||
| 606 | bool enable_sixaxis_sensor_fusion; | ||
| 607 | INSERT_PADDING_BYTES_NOINIT(3); | ||
| 608 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 609 | u64 applet_resource_user_id; | ||
| 610 | }; | ||
| 611 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 612 | |||
| 613 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 614 | |||
| 615 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 616 | const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, | ||
| 617 | parameters.enable_sixaxis_sensor_fusion); | ||
| 618 | |||
| 619 | LOG_DEBUG(Service_HID, | ||
| 620 | "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, " | ||
| 621 | "device_index={}, applet_resource_user_id={}", | ||
| 622 | parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type, | ||
| 623 | parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index, | ||
| 624 | parameters.applet_resource_user_id); | ||
| 625 | |||
| 626 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 627 | rb.Push(result); | ||
| 628 | } | ||
| 629 | |||
| 630 | void Hid::SetSixAxisSensorFusionParameters(HLERequestContext& ctx) { | ||
| 631 | IPC::RequestParser rp{ctx}; | ||
| 632 | struct Parameters { | ||
| 633 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 634 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion; | ||
| 635 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 636 | u64 applet_resource_user_id; | ||
| 637 | }; | ||
| 638 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 639 | |||
| 640 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 641 | |||
| 642 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 643 | const auto result = | ||
| 644 | controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion); | ||
| 645 | |||
| 646 | LOG_DEBUG(Service_HID, | ||
| 647 | "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, " | ||
| 648 | "parameter2={}, applet_resource_user_id={}", | ||
| 649 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 650 | parameters.sixaxis_handle.device_index, parameters.sixaxis_fusion.parameter1, | ||
| 651 | parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id); | ||
| 652 | |||
| 653 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 654 | rb.Push(result); | ||
| 655 | } | ||
| 656 | |||
| 657 | void Hid::GetSixAxisSensorFusionParameters(HLERequestContext& ctx) { | ||
| 658 | IPC::RequestParser rp{ctx}; | ||
| 659 | struct Parameters { | ||
| 660 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 661 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 662 | u64 applet_resource_user_id; | ||
| 663 | }; | ||
| 664 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 665 | |||
| 666 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 667 | |||
| 668 | Core::HID::SixAxisSensorFusionParameters fusion_parameters{}; | ||
| 669 | const auto& controller = | ||
| 670 | GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 671 | const auto result = | ||
| 672 | controller.GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters); | ||
| 673 | |||
| 674 | LOG_DEBUG(Service_HID, | ||
| 675 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 676 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 677 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 678 | |||
| 679 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 680 | rb.Push(result); | ||
| 681 | rb.PushRaw(fusion_parameters); | ||
| 682 | } | ||
| 683 | |||
| 684 | void Hid::ResetSixAxisSensorFusionParameters(HLERequestContext& ctx) { | ||
| 685 | IPC::RequestParser rp{ctx}; | ||
| 686 | struct Parameters { | ||
| 687 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 688 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 689 | u64 applet_resource_user_id; | ||
| 690 | }; | ||
| 691 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 692 | |||
| 693 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 694 | |||
| 695 | // Since these parameters are unknown just use what HW outputs | ||
| 696 | const Core::HID::SixAxisSensorFusionParameters fusion_parameters{ | ||
| 697 | .parameter1 = 0.03f, | ||
| 698 | .parameter2 = 0.4f, | ||
| 699 | }; | ||
| 700 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 701 | const auto result1 = | ||
| 702 | controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters); | ||
| 703 | const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true); | ||
| 704 | |||
| 705 | LOG_DEBUG(Service_HID, | ||
| 706 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 707 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 708 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 709 | |||
| 710 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 711 | if (result1.IsError()) { | ||
| 712 | rb.Push(result1); | ||
| 713 | return; | ||
| 714 | } | ||
| 715 | rb.Push(result2); | ||
| 716 | } | ||
| 717 | |||
| 718 | void Hid::SetGyroscopeZeroDriftMode(HLERequestContext& ctx) { | ||
| 719 | IPC::RequestParser rp{ctx}; | ||
| 720 | const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()}; | ||
| 721 | const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()}; | ||
| 722 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 723 | |||
| 724 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 725 | const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode); | ||
| 726 | |||
| 727 | LOG_DEBUG(Service_HID, | ||
| 728 | "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, " | ||
| 729 | "applet_resource_user_id={}", | ||
| 730 | sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index, | ||
| 731 | drift_mode, applet_resource_user_id); | ||
| 732 | |||
| 733 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 734 | rb.Push(result); | ||
| 735 | } | ||
| 736 | |||
| 737 | void Hid::GetGyroscopeZeroDriftMode(HLERequestContext& ctx) { | ||
| 738 | IPC::RequestParser rp{ctx}; | ||
| 739 | struct Parameters { | ||
| 740 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 741 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 742 | u64 applet_resource_user_id; | ||
| 743 | }; | ||
| 744 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 745 | |||
| 746 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 747 | |||
| 748 | auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard}; | ||
| 749 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 750 | const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); | ||
| 751 | |||
| 752 | LOG_DEBUG(Service_HID, | ||
| 753 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 754 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 755 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 756 | |||
| 757 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 758 | rb.Push(result); | ||
| 759 | rb.PushEnum(drift_mode); | ||
| 760 | } | ||
| 761 | |||
| 762 | void Hid::ResetGyroscopeZeroDriftMode(HLERequestContext& ctx) { | ||
| 763 | IPC::RequestParser rp{ctx}; | ||
| 764 | struct Parameters { | ||
| 765 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 766 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 767 | u64 applet_resource_user_id; | ||
| 768 | }; | ||
| 769 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 770 | |||
| 771 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 772 | |||
| 773 | const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard}; | ||
| 774 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 775 | const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); | ||
| 776 | |||
| 777 | LOG_DEBUG(Service_HID, | ||
| 778 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 779 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 780 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 781 | |||
| 782 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 783 | rb.Push(result); | ||
| 784 | } | ||
| 785 | |||
| 786 | void Hid::IsSixAxisSensorAtRest(HLERequestContext& ctx) { | ||
| 787 | IPC::RequestParser rp{ctx}; | ||
| 788 | struct Parameters { | ||
| 789 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 790 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 791 | u64 applet_resource_user_id; | ||
| 792 | }; | ||
| 793 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 794 | |||
| 795 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 796 | |||
| 797 | bool is_at_rest{}; | ||
| 798 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 799 | controller.IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest); | ||
| 800 | |||
| 801 | LOG_DEBUG(Service_HID, | ||
| 802 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 803 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 804 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 805 | |||
| 806 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 807 | rb.Push(ResultSuccess); | ||
| 808 | rb.Push(is_at_rest); | ||
| 809 | } | ||
| 810 | |||
| 811 | void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx) { | ||
| 812 | IPC::RequestParser rp{ctx}; | ||
| 813 | struct Parameters { | ||
| 814 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 815 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 816 | u64 applet_resource_user_id; | ||
| 817 | }; | ||
| 818 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 819 | |||
| 820 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 821 | |||
| 822 | bool is_firmware_available{}; | ||
| 823 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 824 | controller.IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle, | ||
| 825 | is_firmware_available); | ||
| 826 | |||
| 827 | LOG_WARNING( | ||
| 828 | Service_HID, | ||
| 829 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 830 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 831 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 832 | |||
| 833 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 834 | rb.Push(ResultSuccess); | ||
| 835 | rb.Push(is_firmware_available); | ||
| 836 | } | ||
| 837 | |||
| 838 | void Hid::EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx) { | ||
| 839 | IPC::RequestParser rp{ctx}; | ||
| 840 | struct Parameters { | ||
| 841 | bool enabled; | ||
| 842 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 843 | u64 applet_resource_user_id; | ||
| 844 | }; | ||
| 845 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 846 | |||
| 847 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 848 | |||
| 849 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 850 | const auto result = controller.EnableSixAxisSensorUnalteredPassthrough( | ||
| 851 | parameters.sixaxis_handle, parameters.enabled); | ||
| 852 | |||
| 853 | LOG_DEBUG(Service_HID, | ||
| 854 | "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, " | ||
| 855 | "applet_resource_user_id={}", | ||
| 856 | parameters.enabled, parameters.sixaxis_handle.npad_type, | ||
| 857 | parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index, | ||
| 858 | parameters.applet_resource_user_id); | ||
| 859 | |||
| 860 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 861 | rb.Push(result); | ||
| 862 | } | ||
| 863 | |||
| 864 | void Hid::IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx) { | ||
| 865 | IPC::RequestParser rp{ctx}; | ||
| 866 | struct Parameters { | ||
| 867 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 868 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 869 | u64 applet_resource_user_id; | ||
| 870 | }; | ||
| 871 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 872 | |||
| 873 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 874 | |||
| 875 | bool is_unaltered_sisxaxis_enabled{}; | ||
| 876 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 877 | const auto result = controller.IsSixAxisSensorUnalteredPassthroughEnabled( | ||
| 878 | parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled); | ||
| 879 | |||
| 880 | LOG_DEBUG( | ||
| 881 | Service_HID, | ||
| 882 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 883 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 884 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 885 | |||
| 886 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 887 | rb.Push(result); | ||
| 888 | rb.Push(is_unaltered_sisxaxis_enabled); | ||
| 889 | } | ||
| 890 | |||
| 891 | void Hid::LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx) { | ||
| 892 | IPC::RequestParser rp{ctx}; | ||
| 893 | struct Parameters { | ||
| 894 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 895 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 896 | u64 applet_resource_user_id; | ||
| 897 | }; | ||
| 898 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 899 | |||
| 900 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 901 | |||
| 902 | Core::HID::SixAxisSensorCalibrationParameter calibration{}; | ||
| 903 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 904 | const auto result = | ||
| 905 | controller.LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration); | ||
| 906 | |||
| 907 | LOG_WARNING( | ||
| 908 | Service_HID, | ||
| 909 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 910 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 911 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 912 | |||
| 913 | if (result.IsSuccess()) { | ||
| 914 | ctx.WriteBuffer(calibration); | ||
| 915 | } | ||
| 916 | |||
| 917 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 918 | rb.Push(result); | ||
| 919 | } | ||
| 920 | |||
| 921 | void Hid::GetSixAxisSensorIcInformation(HLERequestContext& ctx) { | ||
| 922 | IPC::RequestParser rp{ctx}; | ||
| 923 | struct Parameters { | ||
| 924 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 925 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 926 | u64 applet_resource_user_id; | ||
| 927 | }; | ||
| 928 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 929 | |||
| 930 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 931 | |||
| 932 | Core::HID::SixAxisSensorIcInformation ic_information{}; | ||
| 933 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 934 | const auto result = | ||
| 935 | controller.GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information); | ||
| 936 | |||
| 937 | LOG_WARNING( | ||
| 938 | Service_HID, | ||
| 939 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 940 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 941 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 942 | |||
| 943 | if (result.IsSuccess()) { | ||
| 944 | ctx.WriteBuffer(ic_information); | ||
| 945 | } | ||
| 946 | |||
| 947 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 948 | rb.Push(result); | ||
| 949 | } | ||
| 950 | |||
| 951 | void Hid::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx) { | ||
| 952 | IPC::RequestParser rp{ctx}; | ||
| 953 | struct Parameters { | ||
| 954 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 955 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 956 | u64 applet_resource_user_id; | ||
| 957 | }; | ||
| 958 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 959 | |||
| 960 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 961 | |||
| 962 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 963 | const auto result = | ||
| 964 | controller.ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle); | ||
| 965 | |||
| 966 | LOG_WARNING( | ||
| 967 | Service_HID, | ||
| 968 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 969 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 970 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 971 | |||
| 972 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 973 | rb.Push(result); | ||
| 974 | } | ||
| 975 | |||
| 976 | void Hid::ActivateGesture(HLERequestContext& ctx) { | ||
| 977 | IPC::RequestParser rp{ctx}; | ||
| 978 | struct Parameters { | ||
| 979 | u32 unknown; | ||
| 980 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 981 | u64 applet_resource_user_id; | ||
| 982 | }; | ||
| 983 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 984 | |||
| 985 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 986 | |||
| 987 | applet_resource->ActivateController(HidController::Gesture); | ||
| 988 | |||
| 989 | LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}", | ||
| 990 | parameters.unknown, parameters.applet_resource_user_id); | ||
| 991 | |||
| 992 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 993 | rb.Push(ResultSuccess); | ||
| 994 | } | ||
| 995 | |||
| 996 | void Hid::SetSupportedNpadStyleSet(HLERequestContext& ctx) { | ||
| 997 | IPC::RequestParser rp{ctx}; | ||
| 998 | struct Parameters { | ||
| 999 | Core::HID::NpadStyleSet supported_styleset; | ||
| 1000 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1001 | u64 applet_resource_user_id; | ||
| 1002 | }; | ||
| 1003 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1004 | |||
| 1005 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1006 | |||
| 1007 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1008 | .SetSupportedStyleSet({parameters.supported_styleset}); | ||
| 1009 | |||
| 1010 | LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}", | ||
| 1011 | parameters.supported_styleset, parameters.applet_resource_user_id); | ||
| 1012 | |||
| 1013 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1014 | rb.Push(ResultSuccess); | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | void Hid::GetSupportedNpadStyleSet(HLERequestContext& ctx) { | ||
| 1018 | IPC::RequestParser rp{ctx}; | ||
| 1019 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1020 | |||
| 1021 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1022 | |||
| 1023 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1024 | rb.Push(ResultSuccess); | ||
| 1025 | rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1026 | .GetSupportedStyleSet() | ||
| 1027 | .raw); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | void Hid::SetSupportedNpadIdType(HLERequestContext& ctx) { | ||
| 1031 | IPC::RequestParser rp{ctx}; | ||
| 1032 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1033 | |||
| 1034 | const auto result = applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1035 | .SetSupportedNpadIdTypes(ctx.ReadBuffer()); | ||
| 1036 | |||
| 1037 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1038 | |||
| 1039 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1040 | rb.Push(result); | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | void Hid::ActivateNpad(HLERequestContext& ctx) { | ||
| 1044 | IPC::RequestParser rp{ctx}; | ||
| 1045 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1046 | |||
| 1047 | applet_resource->ActivateController(HidController::NPad); | ||
| 1048 | |||
| 1049 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1050 | |||
| 1051 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1052 | rb.Push(ResultSuccess); | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | void Hid::DeactivateNpad(HLERequestContext& ctx) { | ||
| 1056 | IPC::RequestParser rp{ctx}; | ||
| 1057 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1058 | |||
| 1059 | applet_resource->DeactivateController(HidController::NPad); | ||
| 1060 | |||
| 1061 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1062 | |||
| 1063 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1064 | rb.Push(ResultSuccess); | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | void Hid::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) { | ||
| 1068 | IPC::RequestParser rp{ctx}; | ||
| 1069 | struct Parameters { | ||
| 1070 | Core::HID::NpadIdType npad_id; | ||
| 1071 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1072 | u64 applet_resource_user_id; | ||
| 1073 | u64 unknown; | ||
| 1074 | }; | ||
| 1075 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1076 | |||
| 1077 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1078 | |||
| 1079 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", | ||
| 1080 | parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown); | ||
| 1081 | |||
| 1082 | // Games expect this event to be signaled after calling this function | ||
| 1083 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1084 | .SignalStyleSetChangedEvent(parameters.npad_id); | ||
| 1085 | |||
| 1086 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 1087 | rb.Push(ResultSuccess); | ||
| 1088 | rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1089 | .GetStyleSetChangedEvent(parameters.npad_id)); | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | void Hid::DisconnectNpad(HLERequestContext& ctx) { | ||
| 1093 | IPC::RequestParser rp{ctx}; | ||
| 1094 | struct Parameters { | ||
| 1095 | Core::HID::NpadIdType npad_id; | ||
| 1096 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1097 | u64 applet_resource_user_id; | ||
| 1098 | }; | ||
| 1099 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1100 | |||
| 1101 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1102 | |||
| 1103 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1104 | controller.DisconnectNpad(parameters.npad_id); | ||
| 1105 | |||
| 1106 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||
| 1107 | parameters.applet_resource_user_id); | ||
| 1108 | |||
| 1109 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1110 | rb.Push(ResultSuccess); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | void Hid::GetPlayerLedPattern(HLERequestContext& ctx) { | ||
| 1114 | IPC::RequestParser rp{ctx}; | ||
| 1115 | const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1116 | |||
| 1117 | Core::HID::LedPattern pattern{0, 0, 0, 0}; | ||
| 1118 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1119 | const auto result = controller.GetLedPattern(npad_id, pattern); | ||
| 1120 | |||
| 1121 | LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id); | ||
| 1122 | |||
| 1123 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1124 | rb.Push(result); | ||
| 1125 | rb.Push(pattern.raw); | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | void Hid::ActivateNpadWithRevision(HLERequestContext& ctx) { | ||
| 1129 | // Should have no effect with how our npad sets up the data | ||
| 1130 | IPC::RequestParser rp{ctx}; | ||
| 1131 | struct Parameters { | ||
| 1132 | s32 revision; | ||
| 1133 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1134 | u64 applet_resource_user_id; | ||
| 1135 | }; | ||
| 1136 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1137 | |||
| 1138 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1139 | |||
| 1140 | applet_resource->ActivateController(HidController::NPad); | ||
| 1141 | |||
| 1142 | LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision, | ||
| 1143 | parameters.applet_resource_user_id); | ||
| 1144 | |||
| 1145 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1146 | rb.Push(ResultSuccess); | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | void Hid::SetNpadJoyHoldType(HLERequestContext& ctx) { | ||
| 1150 | IPC::RequestParser rp{ctx}; | ||
| 1151 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1152 | const auto hold_type{rp.PopEnum<Controller_NPad::NpadJoyHoldType>()}; | ||
| 1153 | |||
| 1154 | applet_resource->GetController<Controller_NPad>(HidController::NPad).SetHoldType(hold_type); | ||
| 1155 | |||
| 1156 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}", | ||
| 1157 | applet_resource_user_id, hold_type); | ||
| 1158 | |||
| 1159 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1160 | rb.Push(ResultSuccess); | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | void Hid::GetNpadJoyHoldType(HLERequestContext& ctx) { | ||
| 1164 | IPC::RequestParser rp{ctx}; | ||
| 1165 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1166 | |||
| 1167 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1168 | |||
| 1169 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1170 | rb.Push(ResultSuccess); | ||
| 1171 | rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad).GetHoldType()); | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | void Hid::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) { | ||
| 1175 | IPC::RequestParser rp{ctx}; | ||
| 1176 | struct Parameters { | ||
| 1177 | Core::HID::NpadIdType npad_id; | ||
| 1178 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1179 | u64 applet_resource_user_id; | ||
| 1180 | }; | ||
| 1181 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1182 | |||
| 1183 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1184 | |||
| 1185 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1186 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1187 | controller.SetNpadMode(new_npad_id, parameters.npad_id, | ||
| 1188 | Controller_NPad::NpadJoyDeviceType::Left, | ||
| 1189 | Controller_NPad::NpadJoyAssignmentMode::Single); | ||
| 1190 | |||
| 1191 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||
| 1192 | parameters.applet_resource_user_id); | ||
| 1193 | |||
| 1194 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1195 | rb.Push(ResultSuccess); | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | void Hid::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { | ||
| 1199 | IPC::RequestParser rp{ctx}; | ||
| 1200 | struct Parameters { | ||
| 1201 | Core::HID::NpadIdType npad_id; | ||
| 1202 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1203 | u64 applet_resource_user_id; | ||
| 1204 | Controller_NPad::NpadJoyDeviceType npad_joy_device_type; | ||
| 1205 | }; | ||
| 1206 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1207 | |||
| 1208 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1209 | |||
| 1210 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1211 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1212 | controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | ||
| 1213 | Controller_NPad::NpadJoyAssignmentMode::Single); | ||
| 1214 | |||
| 1215 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||
| 1216 | parameters.npad_id, parameters.applet_resource_user_id, | ||
| 1217 | parameters.npad_joy_device_type); | ||
| 1218 | |||
| 1219 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1220 | rb.Push(ResultSuccess); | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | void Hid::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) { | ||
| 1224 | IPC::RequestParser rp{ctx}; | ||
| 1225 | struct Parameters { | ||
| 1226 | Core::HID::NpadIdType npad_id; | ||
| 1227 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1228 | u64 applet_resource_user_id; | ||
| 1229 | }; | ||
| 1230 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1231 | |||
| 1232 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1233 | |||
| 1234 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1235 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1236 | controller.SetNpadMode(new_npad_id, parameters.npad_id, {}, | ||
| 1237 | Controller_NPad::NpadJoyAssignmentMode::Dual); | ||
| 1238 | |||
| 1239 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||
| 1240 | parameters.applet_resource_user_id); | ||
| 1241 | |||
| 1242 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1243 | rb.Push(ResultSuccess); | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | void Hid::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) { | ||
| 1247 | IPC::RequestParser rp{ctx}; | ||
| 1248 | const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1249 | const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1250 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1251 | |||
| 1252 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1253 | const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); | ||
| 1254 | |||
| 1255 | LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", | ||
| 1256 | npad_id_1, npad_id_2, applet_resource_user_id); | ||
| 1257 | |||
| 1258 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1259 | rb.Push(result); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | void Hid::StartLrAssignmentMode(HLERequestContext& ctx) { | ||
| 1263 | IPC::RequestParser rp{ctx}; | ||
| 1264 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1265 | |||
| 1266 | applet_resource->GetController<Controller_NPad>(HidController::NPad).StartLRAssignmentMode(); | ||
| 1267 | |||
| 1268 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1269 | |||
| 1270 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1271 | rb.Push(ResultSuccess); | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | void Hid::StopLrAssignmentMode(HLERequestContext& ctx) { | ||
| 1275 | IPC::RequestParser rp{ctx}; | ||
| 1276 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1277 | |||
| 1278 | applet_resource->GetController<Controller_NPad>(HidController::NPad).StopLRAssignmentMode(); | ||
| 1279 | |||
| 1280 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1281 | |||
| 1282 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1283 | rb.Push(ResultSuccess); | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | void Hid::SetNpadHandheldActivationMode(HLERequestContext& ctx) { | ||
| 1287 | IPC::RequestParser rp{ctx}; | ||
| 1288 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1289 | const auto activation_mode{rp.PopEnum<Controller_NPad::NpadHandheldActivationMode>()}; | ||
| 1290 | |||
| 1291 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1292 | .SetNpadHandheldActivationMode(activation_mode); | ||
| 1293 | |||
| 1294 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}", | ||
| 1295 | applet_resource_user_id, activation_mode); | ||
| 1296 | |||
| 1297 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1298 | rb.Push(ResultSuccess); | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | void Hid::GetNpadHandheldActivationMode(HLERequestContext& ctx) { | ||
| 1302 | IPC::RequestParser rp{ctx}; | ||
| 1303 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1304 | |||
| 1305 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1306 | |||
| 1307 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1308 | rb.Push(ResultSuccess); | ||
| 1309 | rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1310 | .GetNpadHandheldActivationMode()); | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | void Hid::SwapNpadAssignment(HLERequestContext& ctx) { | ||
| 1314 | IPC::RequestParser rp{ctx}; | ||
| 1315 | const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1316 | const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1317 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1318 | |||
| 1319 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1320 | const auto result = controller.SwapNpadAssignment(npad_id_1, npad_id_2); | ||
| 1321 | |||
| 1322 | LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", | ||
| 1323 | npad_id_1, npad_id_2, applet_resource_user_id); | ||
| 1324 | |||
| 1325 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1326 | rb.Push(result); | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | void Hid::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx) { | ||
| 1330 | IPC::RequestParser rp{ctx}; | ||
| 1331 | struct Parameters { | ||
| 1332 | Core::HID::NpadIdType npad_id; | ||
| 1333 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1334 | u64 applet_resource_user_id; | ||
| 1335 | }; | ||
| 1336 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1337 | |||
| 1338 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1339 | |||
| 1340 | bool is_enabled = false; | ||
| 1341 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1342 | const auto result = | ||
| 1343 | controller.IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled); | ||
| 1344 | |||
| 1345 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", | ||
| 1346 | parameters.npad_id, parameters.applet_resource_user_id); | ||
| 1347 | |||
| 1348 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1349 | rb.Push(result); | ||
| 1350 | rb.Push(is_enabled); | ||
| 1351 | } | ||
| 1352 | |||
| 1353 | void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) { | ||
| 1354 | IPC::RequestParser rp{ctx}; | ||
| 1355 | struct Parameters { | ||
| 1356 | bool unintended_home_button_input_protection; | ||
| 1357 | INSERT_PADDING_BYTES_NOINIT(3); | ||
| 1358 | Core::HID::NpadIdType npad_id; | ||
| 1359 | u64 applet_resource_user_id; | ||
| 1360 | }; | ||
| 1361 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1362 | |||
| 1363 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1364 | |||
| 1365 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1366 | const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled( | ||
| 1367 | parameters.unintended_home_button_input_protection, parameters.npad_id); | ||
| 1368 | |||
| 1369 | LOG_WARNING(Service_HID, | ||
| 1370 | "(STUBBED) called, unintended_home_button_input_protection={}, npad_id={}," | ||
| 1371 | "applet_resource_user_id={}", | ||
| 1372 | parameters.unintended_home_button_input_protection, parameters.npad_id, | ||
| 1373 | parameters.applet_resource_user_id); | ||
| 1374 | |||
| 1375 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1376 | rb.Push(result); | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | void Hid::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) { | ||
| 1380 | IPC::RequestParser rp{ctx}; | ||
| 1381 | struct Parameters { | ||
| 1382 | Core::HID::NpadIdType npad_id; | ||
| 1383 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1384 | u64 applet_resource_user_id; | ||
| 1385 | Controller_NPad::NpadJoyDeviceType npad_joy_device_type; | ||
| 1386 | }; | ||
| 1387 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1388 | |||
| 1389 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1390 | |||
| 1391 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1392 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1393 | const auto is_reassigned = | ||
| 1394 | controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | ||
| 1395 | Controller_NPad::NpadJoyAssignmentMode::Single); | ||
| 1396 | |||
| 1397 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||
| 1398 | parameters.npad_id, parameters.applet_resource_user_id, | ||
| 1399 | parameters.npad_joy_device_type); | ||
| 1400 | |||
| 1401 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1402 | rb.Push(ResultSuccess); | ||
| 1403 | rb.Push(is_reassigned); | ||
| 1404 | rb.PushEnum(new_npad_id); | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | void Hid::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) { | ||
| 1408 | IPC::RequestParser rp{ctx}; | ||
| 1409 | struct Parameters { | ||
| 1410 | bool analog_stick_use_center_clamp; | ||
| 1411 | INSERT_PADDING_BYTES_NOINIT(7); | ||
| 1412 | u64 applet_resource_user_id; | ||
| 1413 | }; | ||
| 1414 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1415 | |||
| 1416 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1417 | |||
| 1418 | GetAppletResource() | ||
| 1419 | ->GetController<Controller_NPad>(HidController::NPad) | ||
| 1420 | .SetAnalogStickUseCenterClamp(parameters.analog_stick_use_center_clamp); | ||
| 1421 | |||
| 1422 | LOG_WARNING(Service_HID, | ||
| 1423 | "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}", | ||
| 1424 | parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id); | ||
| 1425 | |||
| 1426 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1427 | rb.Push(ResultSuccess); | ||
| 1428 | } | ||
| 1429 | |||
| 1430 | void Hid::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) { | ||
| 1431 | IPC::RequestParser rp{ctx}; | ||
| 1432 | struct Parameters { | ||
| 1433 | Core::HID::NpadStyleSet npad_styleset; | ||
| 1434 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1435 | u64 applet_resource_user_id; | ||
| 1436 | Core::HID::NpadButton button; | ||
| 1437 | }; | ||
| 1438 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1439 | |||
| 1440 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1441 | |||
| 1442 | LOG_WARNING(Service_HID, | ||
| 1443 | "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}", | ||
| 1444 | parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button); | ||
| 1445 | |||
| 1446 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1447 | rb.Push(ResultSuccess); | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | void Hid::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) { | ||
| 1451 | IPC::RequestParser rp{ctx}; | ||
| 1452 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1453 | |||
| 1454 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1455 | applet_resource_user_id); | ||
| 1456 | |||
| 1457 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1458 | rb.Push(ResultSuccess); | ||
| 1459 | } | ||
| 1460 | |||
| 1461 | void Hid::GetVibrationDeviceInfo(HLERequestContext& ctx) { | ||
| 1462 | IPC::RequestParser rp{ctx}; | ||
| 1463 | const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; | ||
| 1464 | const auto& controller = | ||
| 1465 | GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||
| 1466 | |||
| 1467 | Core::HID::VibrationDeviceInfo vibration_device_info; | ||
| 1468 | bool check_device_index = false; | ||
| 1469 | |||
| 1470 | switch (vibration_device_handle.npad_type) { | ||
| 1471 | case Core::HID::NpadStyleIndex::ProController: | ||
| 1472 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 1473 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 1474 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 1475 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 1476 | vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator; | ||
| 1477 | check_device_index = true; | ||
| 1478 | break; | ||
| 1479 | case Core::HID::NpadStyleIndex::GameCube: | ||
| 1480 | vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm; | ||
| 1481 | break; | ||
| 1482 | case Core::HID::NpadStyleIndex::N64: | ||
| 1483 | vibration_device_info.type = Core::HID::VibrationDeviceType::N64; | ||
| 1484 | break; | ||
| 1485 | default: | ||
| 1486 | vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown; | ||
| 1487 | break; | ||
| 1488 | } | ||
| 1489 | |||
| 1490 | vibration_device_info.position = Core::HID::VibrationDevicePosition::None; | ||
| 1491 | if (check_device_index) { | ||
| 1492 | switch (vibration_device_handle.device_index) { | ||
| 1493 | case Core::HID::DeviceIndex::Left: | ||
| 1494 | vibration_device_info.position = Core::HID::VibrationDevicePosition::Left; | ||
| 1495 | break; | ||
| 1496 | case Core::HID::DeviceIndex::Right: | ||
| 1497 | vibration_device_info.position = Core::HID::VibrationDevicePosition::Right; | ||
| 1498 | break; | ||
| 1499 | case Core::HID::DeviceIndex::None: | ||
| 1500 | default: | ||
| 1501 | ASSERT_MSG(false, "DeviceIndex should never be None!"); | ||
| 1502 | break; | ||
| 1503 | } | ||
| 1504 | } | ||
| 1505 | |||
| 1506 | LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}", | ||
| 1507 | vibration_device_info.type, vibration_device_info.position); | ||
| 1508 | |||
| 1509 | const auto result = controller.IsDeviceHandleValid(vibration_device_handle); | ||
| 1510 | if (result.IsError()) { | ||
| 1511 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1512 | rb.Push(result); | ||
| 1513 | return; | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1517 | rb.Push(ResultSuccess); | ||
| 1518 | rb.PushRaw(vibration_device_info); | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | void Hid::SendVibrationValue(HLERequestContext& ctx) { | ||
| 1522 | IPC::RequestParser rp{ctx}; | ||
| 1523 | struct Parameters { | ||
| 1524 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1525 | Core::HID::VibrationValue vibration_value; | ||
| 1526 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1527 | u64 applet_resource_user_id; | ||
| 1528 | }; | ||
| 1529 | static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size."); | ||
| 1530 | |||
| 1531 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1532 | |||
| 1533 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1534 | .VibrateController(parameters.vibration_device_handle, parameters.vibration_value); | ||
| 1535 | |||
| 1536 | LOG_DEBUG(Service_HID, | ||
| 1537 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 1538 | parameters.vibration_device_handle.npad_type, | ||
| 1539 | parameters.vibration_device_handle.npad_id, | ||
| 1540 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); | ||
| 1541 | |||
| 1542 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1543 | rb.Push(ResultSuccess); | ||
| 1544 | } | ||
| 1545 | |||
| 1546 | void Hid::GetActualVibrationValue(HLERequestContext& ctx) { | ||
| 1547 | IPC::RequestParser rp{ctx}; | ||
| 1548 | struct Parameters { | ||
| 1549 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1550 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1551 | u64 applet_resource_user_id; | ||
| 1552 | }; | ||
| 1553 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1554 | |||
| 1555 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1556 | |||
| 1557 | LOG_DEBUG(Service_HID, | ||
| 1558 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 1559 | parameters.vibration_device_handle.npad_type, | ||
| 1560 | parameters.vibration_device_handle.npad_id, | ||
| 1561 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); | ||
| 1562 | |||
| 1563 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 1564 | rb.Push(ResultSuccess); | ||
| 1565 | rb.PushRaw(applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1566 | .GetLastVibration(parameters.vibration_device_handle)); | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | void Hid::CreateActiveVibrationDeviceList(HLERequestContext& ctx) { | ||
| 1570 | LOG_DEBUG(Service_HID, "called"); | ||
| 1571 | |||
| 1572 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 1573 | rb.Push(ResultSuccess); | ||
| 1574 | rb.PushIpcInterface<IActiveVibrationDeviceList>(system, applet_resource); | ||
| 1575 | } | ||
| 1576 | |||
| 1577 | void Hid::PermitVibration(HLERequestContext& ctx) { | ||
| 1578 | IPC::RequestParser rp{ctx}; | ||
| 1579 | const auto can_vibrate{rp.Pop<bool>()}; | ||
| 1580 | |||
| 1581 | // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value | ||
| 1582 | // by converting it to a bool | ||
| 1583 | Settings::values.vibration_enabled.SetValue(can_vibrate); | ||
| 1584 | |||
| 1585 | LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); | ||
| 1586 | |||
| 1587 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1588 | rb.Push(ResultSuccess); | ||
| 1589 | } | ||
| 1590 | |||
| 1591 | void Hid::IsVibrationPermitted(HLERequestContext& ctx) { | ||
| 1592 | LOG_DEBUG(Service_HID, "called"); | ||
| 1593 | |||
| 1594 | // nnSDK checks if a float is greater than zero. We return the bool we stored earlier | ||
| 1595 | const auto is_enabled = Settings::values.vibration_enabled.GetValue(); | ||
| 1596 | |||
| 1597 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1598 | rb.Push(ResultSuccess); | ||
| 1599 | rb.Push(is_enabled); | ||
| 1600 | } | ||
| 1601 | |||
| 1602 | void Hid::SendVibrationValues(HLERequestContext& ctx) { | ||
| 1603 | IPC::RequestParser rp{ctx}; | ||
| 1604 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1605 | |||
| 1606 | const auto handle_data = ctx.ReadBuffer(0); | ||
| 1607 | const auto handle_count = ctx.GetReadBufferNumElements<Core::HID::VibrationDeviceHandle>(0); | ||
| 1608 | const auto vibration_data = ctx.ReadBuffer(1); | ||
| 1609 | const auto vibration_count = ctx.GetReadBufferNumElements<Core::HID::VibrationValue>(1); | ||
| 1610 | |||
| 1611 | auto vibration_device_handles = | ||
| 1612 | std::span(reinterpret_cast<const Core::HID::VibrationDeviceHandle*>(handle_data.data()), | ||
| 1613 | handle_count); | ||
| 1614 | auto vibration_values = std::span( | ||
| 1615 | reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count); | ||
| 1616 | |||
| 1617 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1618 | .VibrateControllers(vibration_device_handles, vibration_values); | ||
| 1619 | |||
| 1620 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1621 | |||
| 1622 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1623 | rb.Push(ResultSuccess); | ||
| 1624 | } | ||
| 1625 | |||
| 1626 | void Hid::SendVibrationGcErmCommand(HLERequestContext& ctx) { | ||
| 1627 | IPC::RequestParser rp{ctx}; | ||
| 1628 | struct Parameters { | ||
| 1629 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1630 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1631 | u64 applet_resource_user_id; | ||
| 1632 | Core::HID::VibrationGcErmCommand gc_erm_command; | ||
| 1633 | }; | ||
| 1634 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1635 | |||
| 1636 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1637 | |||
| 1638 | /** | ||
| 1639 | * Note: This uses yuzu-specific behavior such that the StopHard command produces | ||
| 1640 | * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below, | ||
| 1641 | * in order to differentiate between Stop and StopHard commands. | ||
| 1642 | * This is done to reuse the controller vibration functions made for regular controllers. | ||
| 1643 | */ | ||
| 1644 | const auto vibration_value = [parameters] { | ||
| 1645 | switch (parameters.gc_erm_command) { | ||
| 1646 | case Core::HID::VibrationGcErmCommand::Stop: | ||
| 1647 | return Core::HID::VibrationValue{ | ||
| 1648 | .low_amplitude = 0.0f, | ||
| 1649 | .low_frequency = 160.0f, | ||
| 1650 | .high_amplitude = 0.0f, | ||
| 1651 | .high_frequency = 320.0f, | ||
| 1652 | }; | ||
| 1653 | case Core::HID::VibrationGcErmCommand::Start: | ||
| 1654 | return Core::HID::VibrationValue{ | ||
| 1655 | .low_amplitude = 1.0f, | ||
| 1656 | .low_frequency = 160.0f, | ||
| 1657 | .high_amplitude = 1.0f, | ||
| 1658 | .high_frequency = 320.0f, | ||
| 1659 | }; | ||
| 1660 | case Core::HID::VibrationGcErmCommand::StopHard: | ||
| 1661 | return Core::HID::VibrationValue{ | ||
| 1662 | .low_amplitude = 0.0f, | ||
| 1663 | .low_frequency = 0.0f, | ||
| 1664 | .high_amplitude = 0.0f, | ||
| 1665 | .high_frequency = 0.0f, | ||
| 1666 | }; | ||
| 1667 | default: | ||
| 1668 | return Core::HID::DEFAULT_VIBRATION_VALUE; | ||
| 1669 | } | ||
| 1670 | }(); | ||
| 1671 | |||
| 1672 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1673 | .VibrateController(parameters.vibration_device_handle, vibration_value); | ||
| 1674 | |||
| 1675 | LOG_DEBUG(Service_HID, | ||
| 1676 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, " | ||
| 1677 | "gc_erm_command={}", | ||
| 1678 | parameters.vibration_device_handle.npad_type, | ||
| 1679 | parameters.vibration_device_handle.npad_id, | ||
| 1680 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id, | ||
| 1681 | parameters.gc_erm_command); | ||
| 1682 | |||
| 1683 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1684 | rb.Push(ResultSuccess); | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | void Hid::GetActualVibrationGcErmCommand(HLERequestContext& ctx) { | ||
| 1688 | IPC::RequestParser rp{ctx}; | ||
| 1689 | struct Parameters { | ||
| 1690 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1691 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1692 | u64 applet_resource_user_id; | ||
| 1693 | }; | ||
| 1694 | |||
| 1695 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1696 | |||
| 1697 | const auto last_vibration = applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1698 | .GetLastVibration(parameters.vibration_device_handle); | ||
| 1699 | |||
| 1700 | const auto gc_erm_command = [last_vibration] { | ||
| 1701 | if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) { | ||
| 1702 | return Core::HID::VibrationGcErmCommand::Start; | ||
| 1703 | } | ||
| 1704 | |||
| 1705 | /** | ||
| 1706 | * Note: This uses yuzu-specific behavior such that the StopHard command produces | ||
| 1707 | * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function | ||
| 1708 | * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands. | ||
| 1709 | * This is done to reuse the controller vibration functions made for regular controllers. | ||
| 1710 | */ | ||
| 1711 | if (last_vibration.low_frequency == 0.0f && last_vibration.high_frequency == 0.0f) { | ||
| 1712 | return Core::HID::VibrationGcErmCommand::StopHard; | ||
| 1713 | } | ||
| 1714 | |||
| 1715 | return Core::HID::VibrationGcErmCommand::Stop; | ||
| 1716 | }(); | ||
| 1717 | |||
| 1718 | LOG_DEBUG(Service_HID, | ||
| 1719 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 1720 | parameters.vibration_device_handle.npad_type, | ||
| 1721 | parameters.vibration_device_handle.npad_id, | ||
| 1722 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); | ||
| 1723 | |||
| 1724 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1725 | rb.Push(ResultSuccess); | ||
| 1726 | rb.PushEnum(gc_erm_command); | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | void Hid::BeginPermitVibrationSession(HLERequestContext& ctx) { | ||
| 1730 | IPC::RequestParser rp{ctx}; | ||
| 1731 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1732 | |||
| 1733 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1734 | .SetPermitVibrationSession(true); | ||
| 1735 | |||
| 1736 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1737 | |||
| 1738 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1739 | rb.Push(ResultSuccess); | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | void Hid::EndPermitVibrationSession(HLERequestContext& ctx) { | ||
| 1743 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1744 | .SetPermitVibrationSession(false); | ||
| 1745 | |||
| 1746 | LOG_DEBUG(Service_HID, "called"); | ||
| 1747 | |||
| 1748 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1749 | rb.Push(ResultSuccess); | ||
| 1750 | } | ||
| 1751 | |||
| 1752 | void Hid::IsVibrationDeviceMounted(HLERequestContext& ctx) { | ||
| 1753 | IPC::RequestParser rp{ctx}; | ||
| 1754 | struct Parameters { | ||
| 1755 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1756 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1757 | u64 applet_resource_user_id; | ||
| 1758 | }; | ||
| 1759 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1760 | |||
| 1761 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1762 | |||
| 1763 | LOG_DEBUG(Service_HID, | ||
| 1764 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 1765 | parameters.vibration_device_handle.npad_type, | ||
| 1766 | parameters.vibration_device_handle.npad_id, | ||
| 1767 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); | ||
| 1768 | |||
| 1769 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1770 | rb.Push(ResultSuccess); | ||
| 1771 | rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1772 | .IsVibrationDeviceMounted(parameters.vibration_device_handle)); | ||
| 1773 | } | ||
| 1774 | |||
| 1775 | void Hid::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) { | ||
| 1776 | IPC::RequestParser rp{ctx}; | ||
| 1777 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1778 | |||
| 1779 | applet_resource->ActivateController(HidController::ConsoleSixAxisSensor); | ||
| 1780 | |||
| 1781 | LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1782 | |||
| 1783 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1784 | rb.Push(ResultSuccess); | ||
| 1785 | } | ||
| 1786 | |||
| 1787 | void Hid::StartConsoleSixAxisSensor(HLERequestContext& ctx) { | ||
| 1788 | IPC::RequestParser rp{ctx}; | ||
| 1789 | struct Parameters { | ||
| 1790 | Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle; | ||
| 1791 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1792 | u64 applet_resource_user_id; | ||
| 1793 | }; | ||
| 1794 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1795 | |||
| 1796 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1797 | |||
| 1798 | LOG_WARNING(Service_HID, | ||
| 1799 | "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", | ||
| 1800 | parameters.console_sixaxis_handle.unknown_1, | ||
| 1801 | parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id); | ||
| 1802 | |||
| 1803 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1804 | rb.Push(ResultSuccess); | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | void Hid::StopConsoleSixAxisSensor(HLERequestContext& ctx) { | ||
| 1808 | IPC::RequestParser rp{ctx}; | ||
| 1809 | struct Parameters { | ||
| 1810 | Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle; | ||
| 1811 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1812 | u64 applet_resource_user_id; | ||
| 1813 | }; | ||
| 1814 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1815 | |||
| 1816 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1817 | |||
| 1818 | LOG_WARNING(Service_HID, | ||
| 1819 | "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", | ||
| 1820 | parameters.console_sixaxis_handle.unknown_1, | ||
| 1821 | parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id); | ||
| 1822 | |||
| 1823 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1824 | rb.Push(ResultSuccess); | ||
| 1825 | } | ||
| 1826 | |||
| 1827 | void Hid::ActivateSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1828 | IPC::RequestParser rp{ctx}; | ||
| 1829 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1830 | |||
| 1831 | applet_resource->ActivateController(HidController::ConsoleSixAxisSensor); | ||
| 1832 | |||
| 1833 | LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1834 | |||
| 1835 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1836 | rb.Push(ResultSuccess); | ||
| 1837 | } | ||
| 1838 | |||
| 1839 | void Hid::StartSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1840 | IPC::RequestParser rp{ctx}; | ||
| 1841 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1842 | |||
| 1843 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1844 | applet_resource_user_id); | ||
| 1845 | |||
| 1846 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1847 | rb.Push(ResultSuccess); | ||
| 1848 | } | ||
| 1849 | |||
| 1850 | void Hid::StopSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1851 | IPC::RequestParser rp{ctx}; | ||
| 1852 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1853 | |||
| 1854 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1855 | applet_resource_user_id); | ||
| 1856 | |||
| 1857 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1858 | rb.Push(ResultSuccess); | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | void Hid::InitializeSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1862 | IPC::RequestParser rp{ctx}; | ||
| 1863 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1864 | const auto t_mem_1_size{rp.Pop<u64>()}; | ||
| 1865 | const auto t_mem_2_size{rp.Pop<u64>()}; | ||
| 1866 | const auto t_mem_1_handle{ctx.GetCopyHandle(0)}; | ||
| 1867 | const auto t_mem_2_handle{ctx.GetCopyHandle(1)}; | ||
| 1868 | |||
| 1869 | ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes"); | ||
| 1870 | ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes"); | ||
| 1871 | |||
| 1872 | auto t_mem_1 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( | ||
| 1873 | t_mem_1_handle); | ||
| 1874 | |||
| 1875 | if (t_mem_1.IsNull()) { | ||
| 1876 | LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle); | ||
| 1877 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1878 | rb.Push(ResultUnknown); | ||
| 1879 | return; | ||
| 1880 | } | ||
| 1881 | |||
| 1882 | auto t_mem_2 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( | ||
| 1883 | t_mem_2_handle); | ||
| 1884 | |||
| 1885 | if (t_mem_2.IsNull()) { | ||
| 1886 | LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle); | ||
| 1887 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1888 | rb.Push(ResultUnknown); | ||
| 1889 | return; | ||
| 1890 | } | ||
| 1891 | |||
| 1892 | ASSERT_MSG(t_mem_1->GetSize() == 0x1000, "t_mem_1 has incorrect size"); | ||
| 1893 | ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size"); | ||
| 1894 | |||
| 1895 | // Activate console six axis controller | ||
| 1896 | applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor) | ||
| 1897 | .ActivateController(); | ||
| 1898 | |||
| 1899 | applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor) | ||
| 1900 | .SetTransferMemoryAddress(t_mem_1->GetSourceAddress()); | ||
| 1901 | |||
| 1902 | LOG_WARNING(Service_HID, | ||
| 1903 | "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, " | ||
| 1904 | "applet_resource_user_id={}", | ||
| 1905 | t_mem_1_handle, t_mem_2_handle, applet_resource_user_id); | ||
| 1906 | |||
| 1907 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1908 | rb.Push(ResultSuccess); | ||
| 1909 | } | ||
| 1910 | |||
| 1911 | void Hid::FinalizeSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1912 | IPC::RequestParser rp{ctx}; | ||
| 1913 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1914 | |||
| 1915 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1916 | applet_resource_user_id); | ||
| 1917 | |||
| 1918 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1919 | rb.Push(ResultSuccess); | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | void Hid::ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx) { | ||
| 1923 | IPC::RequestParser rp{ctx}; | ||
| 1924 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1925 | |||
| 1926 | applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor) | ||
| 1927 | .ResetTimestamp(); | ||
| 1928 | |||
| 1929 | LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1930 | |||
| 1931 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1932 | rb.Push(ResultSuccess); | ||
| 1933 | } | ||
| 1934 | |||
| 1935 | void Hid::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) { | ||
| 1936 | IPC::RequestParser rp{ctx}; | ||
| 1937 | |||
| 1938 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 1939 | |||
| 1940 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1941 | rb.Push(ResultSuccess); | ||
| 1942 | rb.Push(false); | ||
| 1943 | } | ||
| 1944 | |||
| 1945 | void Hid::GetPalmaConnectionHandle(HLERequestContext& ctx) { | ||
| 1946 | IPC::RequestParser rp{ctx}; | ||
| 1947 | struct Parameters { | ||
| 1948 | Core::HID::NpadIdType npad_id; | ||
| 1949 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1950 | u64 applet_resource_user_id; | ||
| 1951 | }; | ||
| 1952 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1953 | |||
| 1954 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1955 | |||
| 1956 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", | ||
| 1957 | parameters.npad_id, parameters.applet_resource_user_id); | ||
| 1958 | |||
| 1959 | Controller_Palma::PalmaConnectionHandle handle; | ||
| 1960 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 1961 | const auto result = controller.GetPalmaConnectionHandle(parameters.npad_id, handle); | ||
| 1962 | |||
| 1963 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1964 | rb.Push(result); | ||
| 1965 | rb.PushRaw(handle); | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | void Hid::InitializePalma(HLERequestContext& ctx) { | ||
| 1969 | IPC::RequestParser rp{ctx}; | ||
| 1970 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 1971 | |||
| 1972 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 1973 | |||
| 1974 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 1975 | const auto result = controller.InitializePalma(connection_handle); | ||
| 1976 | |||
| 1977 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1978 | rb.Push(result); | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | void Hid::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) { | ||
| 1982 | IPC::RequestParser rp{ctx}; | ||
| 1983 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 1984 | |||
| 1985 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 1986 | |||
| 1987 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 1988 | |||
| 1989 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 1990 | rb.Push(ResultSuccess); | ||
| 1991 | rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle)); | ||
| 1992 | } | ||
| 1993 | |||
| 1994 | void Hid::GetPalmaOperationInfo(HLERequestContext& ctx) { | ||
| 1995 | IPC::RequestParser rp{ctx}; | ||
| 1996 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 1997 | |||
| 1998 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 1999 | |||
| 2000 | Controller_Palma::PalmaOperationType operation_type; | ||
| 2001 | Controller_Palma::PalmaOperationData data; | ||
| 2002 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 2003 | const auto result = controller.GetPalmaOperationInfo(connection_handle, operation_type, data); | ||
| 2004 | |||
| 2005 | if (result.IsError()) { | ||
| 2006 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2007 | rb.Push(result); | ||
| 2008 | } | ||
| 2009 | |||
| 2010 | ctx.WriteBuffer(data); | ||
| 2011 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 2012 | rb.Push(result); | ||
| 2013 | rb.Push(static_cast<u64>(operation_type)); | ||
| 2014 | } | ||
| 2015 | |||
| 2016 | void Hid::PlayPalmaActivity(HLERequestContext& ctx) { | ||
| 2017 | IPC::RequestParser rp{ctx}; | ||
| 2018 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2019 | const auto palma_activity{rp.Pop<u64>()}; | ||
| 2020 | |||
| 2021 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}", | ||
| 2022 | connection_handle.npad_id, palma_activity); | ||
| 2023 | |||
| 2024 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 2025 | const auto result = controller.PlayPalmaActivity(connection_handle, palma_activity); | ||
| 2026 | |||
| 2027 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2028 | rb.Push(result); | ||
| 2029 | } | ||
| 2030 | |||
| 2031 | void Hid::SetPalmaFrModeType(HLERequestContext& ctx) { | ||
| 2032 | IPC::RequestParser rp{ctx}; | ||
| 2033 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2034 | const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()}; | ||
| 2035 | |||
| 2036 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}", | ||
| 2037 | connection_handle.npad_id, fr_mode); | ||
| 2038 | |||
| 2039 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 2040 | const auto result = controller.SetPalmaFrModeType(connection_handle, fr_mode); | ||
| 2041 | |||
| 2042 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2043 | rb.Push(result); | ||
| 2044 | } | ||
| 2045 | |||
| 2046 | void Hid::ReadPalmaStep(HLERequestContext& ctx) { | ||
| 2047 | IPC::RequestParser rp{ctx}; | ||
| 2048 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2049 | |||
| 2050 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2051 | |||
| 2052 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 2053 | const auto result = controller.ReadPalmaStep(connection_handle); | ||
| 2054 | |||
| 2055 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2056 | rb.Push(result); | ||
| 2057 | } | ||
| 2058 | |||
| 2059 | void Hid::EnablePalmaStep(HLERequestContext& ctx) { | ||
| 2060 | IPC::RequestParser rp{ctx}; | ||
| 2061 | struct Parameters { | ||
| 2062 | bool is_enabled; | ||
| 2063 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 2064 | Controller_Palma::PalmaConnectionHandle connection_handle; | ||
| 2065 | }; | ||
| 2066 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 2067 | |||
| 2068 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 2069 | |||
| 2070 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}", | ||
| 2071 | parameters.connection_handle.npad_id, parameters.is_enabled); | ||
| 2072 | |||
| 2073 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 2074 | const auto result = | ||
| 2075 | controller.EnablePalmaStep(parameters.connection_handle, parameters.is_enabled); | ||
| 2076 | |||
| 2077 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2078 | rb.Push(result); | ||
| 2079 | } | ||
| 2080 | |||
| 2081 | void Hid::ResetPalmaStep(HLERequestContext& ctx) { | ||
| 2082 | IPC::RequestParser rp{ctx}; | ||
| 2083 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2084 | |||
| 2085 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2086 | |||
| 2087 | auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); | ||
| 2088 | const auto result = controller.ResetPalmaStep(connection_handle); | ||
| 2089 | |||
| 2090 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2091 | rb.Push(result); | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | void Hid::ReadPalmaApplicationSection(HLERequestContext& ctx) { | ||
| 2095 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2096 | |||
| 2097 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2098 | rb.Push(ResultSuccess); | ||
| 2099 | } | ||
| 2100 | |||
| 2101 | void Hid::WritePalmaApplicationSection(HLERequestContext& ctx) { | ||
| 2102 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2103 | |||
| 2104 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2105 | rb.Push(ResultSuccess); | ||
| 2106 | } | ||
| 2107 | |||
| 2108 | void Hid::ReadPalmaUniqueCode(HLERequestContext& ctx) { | ||
| 2109 | IPC::RequestParser rp{ctx}; | ||
| 2110 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2111 | |||
| 2112 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2113 | |||
| 2114 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2115 | .ReadPalmaUniqueCode(connection_handle); | ||
| 2116 | |||
| 2117 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2118 | rb.Push(ResultSuccess); | ||
| 2119 | } | ||
| 2120 | |||
| 2121 | void Hid::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) { | ||
| 2122 | IPC::RequestParser rp{ctx}; | ||
| 2123 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2124 | |||
| 2125 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2126 | |||
| 2127 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2128 | .SetPalmaUniqueCodeInvalid(connection_handle); | ||
| 2129 | |||
| 2130 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2131 | rb.Push(ResultSuccess); | ||
| 2132 | } | ||
| 2133 | |||
| 2134 | void Hid::WritePalmaActivityEntry(HLERequestContext& ctx) { | ||
| 2135 | LOG_CRITICAL(Service_HID, "(STUBBED) called"); | ||
| 2136 | |||
| 2137 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2138 | rb.Push(ResultSuccess); | ||
| 2139 | } | ||
| 2140 | |||
| 2141 | void Hid::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) { | ||
| 2142 | IPC::RequestParser rp{ctx}; | ||
| 2143 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2144 | const auto unknown{rp.Pop<u64>()}; | ||
| 2145 | |||
| 2146 | [[maybe_unused]] const auto buffer = ctx.ReadBuffer(); | ||
| 2147 | |||
| 2148 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}", | ||
| 2149 | connection_handle.npad_id, unknown); | ||
| 2150 | |||
| 2151 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2152 | .WritePalmaRgbLedPatternEntry(connection_handle, unknown); | ||
| 2153 | |||
| 2154 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2155 | rb.Push(ResultSuccess); | ||
| 2156 | } | ||
| 2157 | |||
| 2158 | void Hid::WritePalmaWaveEntry(HLERequestContext& ctx) { | ||
| 2159 | IPC::RequestParser rp{ctx}; | ||
| 2160 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2161 | const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()}; | ||
| 2162 | const auto unknown{rp.Pop<u64>()}; | ||
| 2163 | const auto t_mem_size{rp.Pop<u64>()}; | ||
| 2164 | const auto t_mem_handle{ctx.GetCopyHandle(0)}; | ||
| 2165 | const auto size{rp.Pop<u64>()}; | ||
| 2166 | |||
| 2167 | ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes"); | ||
| 2168 | |||
| 2169 | auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( | ||
| 2170 | t_mem_handle); | ||
| 2171 | |||
| 2172 | if (t_mem.IsNull()) { | ||
| 2173 | LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle); | ||
| 2174 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2175 | rb.Push(ResultUnknown); | ||
| 2176 | return; | ||
| 2177 | } | ||
| 2178 | |||
| 2179 | ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size"); | ||
| 2180 | |||
| 2181 | LOG_WARNING(Service_HID, | ||
| 2182 | "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, " | ||
| 2183 | "t_mem_handle=0x{:08X}, t_mem_size={}, size={}", | ||
| 2184 | connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size); | ||
| 2185 | |||
| 2186 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2187 | .WritePalmaWaveEntry(connection_handle, wave_set, t_mem->GetSourceAddress(), t_mem_size); | ||
| 2188 | |||
| 2189 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2190 | rb.Push(ResultSuccess); | ||
| 2191 | } | ||
| 2192 | |||
| 2193 | void Hid::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) { | ||
| 2194 | IPC::RequestParser rp{ctx}; | ||
| 2195 | struct Parameters { | ||
| 2196 | s32 database_id_version; | ||
| 2197 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 2198 | Controller_Palma::PalmaConnectionHandle connection_handle; | ||
| 2199 | }; | ||
| 2200 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 2201 | |||
| 2202 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 2203 | |||
| 2204 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}", | ||
| 2205 | parameters.connection_handle.npad_id, parameters.database_id_version); | ||
| 2206 | |||
| 2207 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2208 | .SetPalmaDataBaseIdentificationVersion(parameters.connection_handle, | ||
| 2209 | parameters.database_id_version); | ||
| 2210 | |||
| 2211 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2212 | rb.Push(ResultSuccess); | ||
| 2213 | } | ||
| 2214 | |||
| 2215 | void Hid::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) { | ||
| 2216 | IPC::RequestParser rp{ctx}; | ||
| 2217 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2218 | |||
| 2219 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2220 | |||
| 2221 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2222 | .GetPalmaDataBaseIdentificationVersion(connection_handle); | ||
| 2223 | |||
| 2224 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2225 | rb.Push(ResultSuccess); | ||
| 2226 | } | ||
| 2227 | |||
| 2228 | void Hid::SuspendPalmaFeature(HLERequestContext& ctx) { | ||
| 2229 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2230 | |||
| 2231 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2232 | rb.Push(ResultSuccess); | ||
| 2233 | } | ||
| 2234 | |||
| 2235 | void Hid::GetPalmaOperationResult(HLERequestContext& ctx) { | ||
| 2236 | IPC::RequestParser rp{ctx}; | ||
| 2237 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2238 | |||
| 2239 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2240 | |||
| 2241 | const auto result = applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2242 | .GetPalmaOperationResult(connection_handle); | ||
| 2243 | |||
| 2244 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2245 | rb.Push(result); | ||
| 2246 | } | ||
| 2247 | |||
| 2248 | void Hid::ReadPalmaPlayLog(HLERequestContext& ctx) { | ||
| 2249 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2250 | |||
| 2251 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2252 | rb.Push(ResultSuccess); | ||
| 2253 | } | ||
| 2254 | |||
| 2255 | void Hid::ResetPalmaPlayLog(HLERequestContext& ctx) { | ||
| 2256 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2257 | |||
| 2258 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2259 | rb.Push(ResultSuccess); | ||
| 2260 | } | ||
| 2261 | |||
| 2262 | void Hid::SetIsPalmaAllConnectable(HLERequestContext& ctx) { | ||
| 2263 | IPC::RequestParser rp{ctx}; | ||
| 2264 | struct Parameters { | ||
| 2265 | bool is_palma_all_connectable; | ||
| 2266 | INSERT_PADDING_BYTES_NOINIT(7); | ||
| 2267 | u64 applet_resource_user_id; | ||
| 2268 | }; | ||
| 2269 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 2270 | |||
| 2271 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 2272 | |||
| 2273 | LOG_WARNING(Service_HID, | ||
| 2274 | "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}", | ||
| 2275 | parameters.is_palma_all_connectable, parameters.applet_resource_user_id); | ||
| 2276 | |||
| 2277 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2278 | .SetIsPalmaAllConnectable(parameters.is_palma_all_connectable); | ||
| 2279 | |||
| 2280 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2281 | rb.Push(ResultSuccess); | ||
| 2282 | } | ||
| 2283 | |||
| 2284 | void Hid::SetIsPalmaPairedConnectable(HLERequestContext& ctx) { | ||
| 2285 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2286 | |||
| 2287 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2288 | rb.Push(ResultSuccess); | ||
| 2289 | } | ||
| 2290 | |||
| 2291 | void Hid::PairPalma(HLERequestContext& ctx) { | ||
| 2292 | IPC::RequestParser rp{ctx}; | ||
| 2293 | const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; | ||
| 2294 | |||
| 2295 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2296 | |||
| 2297 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2298 | .PairPalma(connection_handle); | ||
| 2299 | |||
| 2300 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2301 | rb.Push(ResultSuccess); | ||
| 2302 | } | ||
| 2303 | |||
| 2304 | void Hid::SetPalmaBoostMode(HLERequestContext& ctx) { | ||
| 2305 | IPC::RequestParser rp{ctx}; | ||
| 2306 | const auto palma_boost_mode{rp.Pop<bool>()}; | ||
| 2307 | |||
| 2308 | LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode); | ||
| 2309 | |||
| 2310 | applet_resource->GetController<Controller_Palma>(HidController::Palma) | ||
| 2311 | .SetPalmaBoostMode(palma_boost_mode); | ||
| 2312 | |||
| 2313 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2314 | rb.Push(ResultSuccess); | ||
| 2315 | } | ||
| 2316 | |||
| 2317 | void Hid::CancelWritePalmaWaveEntry(HLERequestContext& ctx) { | ||
| 2318 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2319 | |||
| 2320 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2321 | rb.Push(ResultSuccess); | ||
| 2322 | } | ||
| 2323 | |||
| 2324 | void Hid::EnablePalmaBoostMode(HLERequestContext& ctx) { | ||
| 2325 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2326 | |||
| 2327 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2328 | rb.Push(ResultSuccess); | ||
| 2329 | } | ||
| 2330 | |||
| 2331 | void Hid::GetPalmaBluetoothAddress(HLERequestContext& ctx) { | ||
| 2332 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2333 | |||
| 2334 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2335 | rb.Push(ResultSuccess); | ||
| 2336 | } | ||
| 2337 | |||
| 2338 | void Hid::SetDisallowedPalmaConnection(HLERequestContext& ctx) { | ||
| 2339 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2340 | |||
| 2341 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2342 | rb.Push(ResultSuccess); | ||
| 2343 | } | ||
| 2344 | |||
| 2345 | void Hid::SetNpadCommunicationMode(HLERequestContext& ctx) { | ||
| 2346 | IPC::RequestParser rp{ctx}; | ||
| 2347 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 2348 | const auto communication_mode{rp.PopEnum<Controller_NPad::NpadCommunicationMode>()}; | ||
| 2349 | |||
| 2350 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 2351 | .SetNpadCommunicationMode(communication_mode); | ||
| 2352 | |||
| 2353 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}", | ||
| 2354 | applet_resource_user_id, communication_mode); | ||
| 2355 | |||
| 2356 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2357 | rb.Push(ResultSuccess); | ||
| 2358 | } | ||
| 2359 | |||
| 2360 | void Hid::GetNpadCommunicationMode(HLERequestContext& ctx) { | ||
| 2361 | IPC::RequestParser rp{ctx}; | ||
| 2362 | |||
| 2363 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2364 | |||
| 2365 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 2366 | rb.Push(ResultSuccess); | ||
| 2367 | rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 2368 | .GetNpadCommunicationMode()); | ||
| 2369 | } | ||
| 2370 | |||
| 2371 | void Hid::SetTouchScreenConfiguration(HLERequestContext& ctx) { | ||
| 2372 | IPC::RequestParser rp{ctx}; | ||
| 2373 | const auto touchscreen_mode{rp.PopRaw<Core::HID::TouchScreenConfigurationForNx>()}; | ||
| 2374 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 2375 | |||
| 2376 | LOG_WARNING(Service_HID, "(STUBBED) called, touchscreen_mode={}, applet_resource_user_id={}", | ||
| 2377 | touchscreen_mode.mode, applet_resource_user_id); | ||
| 2378 | |||
| 2379 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2380 | rb.Push(ResultSuccess); | ||
| 2381 | } | ||
| 2382 | |||
| 2383 | void Hid::IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx) { | ||
| 2384 | IPC::RequestParser rp{ctx}; | ||
| 2385 | struct Parameters { | ||
| 2386 | s32 unknown; | ||
| 2387 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 2388 | u64 applet_resource_user_id; | ||
| 2389 | }; | ||
| 2390 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 2391 | |||
| 2392 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 2393 | |||
| 2394 | LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}", | ||
| 2395 | parameters.unknown, parameters.applet_resource_user_id); | ||
| 2396 | |||
| 2397 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 2398 | rb.Push(ResultSuccess); | ||
| 2399 | rb.Push(false); | ||
| 2400 | } | ||
| 2401 | |||
| 2402 | class HidDbg final : public ServiceFramework<HidDbg> { | ||
| 2403 | public: | ||
| 2404 | explicit HidDbg(Core::System& system_) : ServiceFramework{system_, "hid:dbg"} { | ||
| 2405 | // clang-format off | ||
| 2406 | static const FunctionInfo functions[] = { | ||
| 2407 | {0, nullptr, "DeactivateDebugPad"}, | ||
| 2408 | {1, nullptr, "SetDebugPadAutoPilotState"}, | ||
| 2409 | {2, nullptr, "UnsetDebugPadAutoPilotState"}, | ||
| 2410 | {10, nullptr, "DeactivateTouchScreen"}, | ||
| 2411 | {11, nullptr, "SetTouchScreenAutoPilotState"}, | ||
| 2412 | {12, nullptr, "UnsetTouchScreenAutoPilotState"}, | ||
| 2413 | {13, nullptr, "GetTouchScreenConfiguration"}, | ||
| 2414 | {14, nullptr, "ProcessTouchScreenAutoTune"}, | ||
| 2415 | {15, nullptr, "ForceStopTouchScreenManagement"}, | ||
| 2416 | {16, nullptr, "ForceRestartTouchScreenManagement"}, | ||
| 2417 | {17, nullptr, "IsTouchScreenManaged"}, | ||
| 2418 | {20, nullptr, "DeactivateMouse"}, | ||
| 2419 | {21, nullptr, "SetMouseAutoPilotState"}, | ||
| 2420 | {22, nullptr, "UnsetMouseAutoPilotState"}, | ||
| 2421 | {25, nullptr, "SetDebugMouseAutoPilotState"}, | ||
| 2422 | {26, nullptr, "UnsetDebugMouseAutoPilotState"}, | ||
| 2423 | {30, nullptr, "DeactivateKeyboard"}, | ||
| 2424 | {31, nullptr, "SetKeyboardAutoPilotState"}, | ||
| 2425 | {32, nullptr, "UnsetKeyboardAutoPilotState"}, | ||
| 2426 | {50, nullptr, "DeactivateXpad"}, | ||
| 2427 | {51, nullptr, "SetXpadAutoPilotState"}, | ||
| 2428 | {52, nullptr, "UnsetXpadAutoPilotState"}, | ||
| 2429 | {53, nullptr, "DeactivateJoyXpad"}, | ||
| 2430 | {60, nullptr, "ClearNpadSystemCommonPolicy"}, | ||
| 2431 | {61, nullptr, "DeactivateNpad"}, | ||
| 2432 | {62, nullptr, "ForceDisconnectNpad"}, | ||
| 2433 | {91, nullptr, "DeactivateGesture"}, | ||
| 2434 | {110, nullptr, "DeactivateHomeButton"}, | ||
| 2435 | {111, nullptr, "SetHomeButtonAutoPilotState"}, | ||
| 2436 | {112, nullptr, "UnsetHomeButtonAutoPilotState"}, | ||
| 2437 | {120, nullptr, "DeactivateSleepButton"}, | ||
| 2438 | {121, nullptr, "SetSleepButtonAutoPilotState"}, | ||
| 2439 | {122, nullptr, "UnsetSleepButtonAutoPilotState"}, | ||
| 2440 | {123, nullptr, "DeactivateInputDetector"}, | ||
| 2441 | {130, nullptr, "DeactivateCaptureButton"}, | ||
| 2442 | {131, nullptr, "SetCaptureButtonAutoPilotState"}, | ||
| 2443 | {132, nullptr, "UnsetCaptureButtonAutoPilotState"}, | ||
| 2444 | {133, nullptr, "SetShiftAccelerometerCalibrationValue"}, | ||
| 2445 | {134, nullptr, "GetShiftAccelerometerCalibrationValue"}, | ||
| 2446 | {135, nullptr, "SetShiftGyroscopeCalibrationValue"}, | ||
| 2447 | {136, nullptr, "GetShiftGyroscopeCalibrationValue"}, | ||
| 2448 | {140, nullptr, "DeactivateConsoleSixAxisSensor"}, | ||
| 2449 | {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"}, | ||
| 2450 | {142, nullptr, "DeactivateSevenSixAxisSensor"}, | ||
| 2451 | {143, nullptr, "GetConsoleSixAxisSensorCountStates"}, | ||
| 2452 | {144, nullptr, "GetAccelerometerFsr"}, | ||
| 2453 | {145, nullptr, "SetAccelerometerFsr"}, | ||
| 2454 | {146, nullptr, "GetAccelerometerOdr"}, | ||
| 2455 | {147, nullptr, "SetAccelerometerOdr"}, | ||
| 2456 | {148, nullptr, "GetGyroscopeFsr"}, | ||
| 2457 | {149, nullptr, "SetGyroscopeFsr"}, | ||
| 2458 | {150, nullptr, "GetGyroscopeOdr"}, | ||
| 2459 | {151, nullptr, "SetGyroscopeOdr"}, | ||
| 2460 | {152, nullptr, "GetWhoAmI"}, | ||
| 2461 | {201, nullptr, "ActivateFirmwareUpdate"}, | ||
| 2462 | {202, nullptr, "DeactivateFirmwareUpdate"}, | ||
| 2463 | {203, nullptr, "StartFirmwareUpdate"}, | ||
| 2464 | {204, nullptr, "GetFirmwareUpdateStage"}, | ||
| 2465 | {205, nullptr, "GetFirmwareVersion"}, | ||
| 2466 | {206, nullptr, "GetDestinationFirmwareVersion"}, | ||
| 2467 | {207, nullptr, "DiscardFirmwareInfoCacheForRevert"}, | ||
| 2468 | {208, nullptr, "StartFirmwareUpdateForRevert"}, | ||
| 2469 | {209, nullptr, "GetAvailableFirmwareVersionForRevert"}, | ||
| 2470 | {210, nullptr, "IsFirmwareUpdatingDevice"}, | ||
| 2471 | {211, nullptr, "StartFirmwareUpdateIndividual"}, | ||
| 2472 | {215, nullptr, "SetUsbFirmwareForceUpdateEnabled"}, | ||
| 2473 | {216, nullptr, "SetAllKuinaDevicesToFirmwareUpdateMode"}, | ||
| 2474 | {221, nullptr, "UpdateControllerColor"}, | ||
| 2475 | {222, nullptr, "ConnectUsbPadsAsync"}, | ||
| 2476 | {223, nullptr, "DisconnectUsbPadsAsync"}, | ||
| 2477 | {224, nullptr, "UpdateDesignInfo"}, | ||
| 2478 | {225, nullptr, "GetUniquePadDriverState"}, | ||
| 2479 | {226, nullptr, "GetSixAxisSensorDriverStates"}, | ||
| 2480 | {227, nullptr, "GetRxPacketHistory"}, | ||
| 2481 | {228, nullptr, "AcquireOperationEventHandle"}, | ||
| 2482 | {229, nullptr, "ReadSerialFlash"}, | ||
| 2483 | {230, nullptr, "WriteSerialFlash"}, | ||
| 2484 | {231, nullptr, "GetOperationResult"}, | ||
| 2485 | {232, nullptr, "EnableShipmentMode"}, | ||
| 2486 | {233, nullptr, "ClearPairingInfo"}, | ||
| 2487 | {234, nullptr, "GetUniquePadDeviceTypeSetInternal"}, | ||
| 2488 | {235, nullptr, "EnableAnalogStickPower"}, | ||
| 2489 | {236, nullptr, "RequestKuinaUartClockCal"}, | ||
| 2490 | {237, nullptr, "GetKuinaUartClockCal"}, | ||
| 2491 | {238, nullptr, "SetKuinaUartClockTrim"}, | ||
| 2492 | {239, nullptr, "KuinaLoopbackTest"}, | ||
| 2493 | {240, nullptr, "RequestBatteryVoltage"}, | ||
| 2494 | {241, nullptr, "GetBatteryVoltage"}, | ||
| 2495 | {242, nullptr, "GetUniquePadPowerInfo"}, | ||
| 2496 | {243, nullptr, "RebootUniquePad"}, | ||
| 2497 | {244, nullptr, "RequestKuinaFirmwareVersion"}, | ||
| 2498 | {245, nullptr, "GetKuinaFirmwareVersion"}, | ||
| 2499 | {246, nullptr, "GetVidPid"}, | ||
| 2500 | {247, nullptr, "GetAnalogStickCalibrationValue"}, | ||
| 2501 | {248, nullptr, "GetUniquePadIdsFull"}, | ||
| 2502 | {249, nullptr, "ConnectUniquePad"}, | ||
| 2503 | {250, nullptr, "IsVirtual"}, | ||
| 2504 | {251, nullptr, "GetAnalogStickModuleParam"}, | ||
| 2505 | {301, nullptr, "GetAbstractedPadHandles"}, | ||
| 2506 | {302, nullptr, "GetAbstractedPadState"}, | ||
| 2507 | {303, nullptr, "GetAbstractedPadsState"}, | ||
| 2508 | {321, nullptr, "SetAutoPilotVirtualPadState"}, | ||
| 2509 | {322, nullptr, "UnsetAutoPilotVirtualPadState"}, | ||
| 2510 | {323, nullptr, "UnsetAllAutoPilotVirtualPadState"}, | ||
| 2511 | {324, nullptr, "AttachHdlsWorkBuffer"}, | ||
| 2512 | {325, nullptr, "ReleaseHdlsWorkBuffer"}, | ||
| 2513 | {326, nullptr, "DumpHdlsNpadAssignmentState"}, | ||
| 2514 | {327, nullptr, "DumpHdlsStates"}, | ||
| 2515 | {328, nullptr, "ApplyHdlsNpadAssignmentState"}, | ||
| 2516 | {329, nullptr, "ApplyHdlsStateList"}, | ||
| 2517 | {330, nullptr, "AttachHdlsVirtualDevice"}, | ||
| 2518 | {331, nullptr, "DetachHdlsVirtualDevice"}, | ||
| 2519 | {332, nullptr, "SetHdlsState"}, | ||
| 2520 | {350, nullptr, "AddRegisteredDevice"}, | ||
| 2521 | {400, nullptr, "DisableExternalMcuOnNxDevice"}, | ||
| 2522 | {401, nullptr, "DisableRailDeviceFiltering"}, | ||
| 2523 | {402, nullptr, "EnableWiredPairing"}, | ||
| 2524 | {403, nullptr, "EnableShipmentModeAutoClear"}, | ||
| 2525 | {404, nullptr, "SetRailEnabled"}, | ||
| 2526 | {500, nullptr, "SetFactoryInt"}, | ||
| 2527 | {501, nullptr, "IsFactoryBootEnabled"}, | ||
| 2528 | {550, nullptr, "SetAnalogStickModelDataTemporarily"}, | ||
| 2529 | {551, nullptr, "GetAnalogStickModelData"}, | ||
| 2530 | {552, nullptr, "ResetAnalogStickModelData"}, | ||
| 2531 | {600, nullptr, "ConvertPadState"}, | ||
| 2532 | {650, nullptr, "AddButtonPlayData"}, | ||
| 2533 | {651, nullptr, "StartButtonPlayData"}, | ||
| 2534 | {652, nullptr, "StopButtonPlayData"}, | ||
| 2535 | {2000, nullptr, "DeactivateDigitizer"}, | ||
| 2536 | {2001, nullptr, "SetDigitizerAutoPilotState"}, | ||
| 2537 | {2002, nullptr, "UnsetDigitizerAutoPilotState"}, | ||
| 2538 | {2002, nullptr, "ReloadFirmwareDebugSettings"}, | ||
| 2539 | }; | ||
| 2540 | // clang-format on | ||
| 2541 | |||
| 2542 | RegisterHandlers(functions); | ||
| 2543 | } | ||
| 2544 | }; | ||
| 2545 | |||
| 2546 | class HidSys final : public ServiceFramework<HidSys> { | ||
| 2547 | public: | ||
| 2548 | explicit HidSys(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_) | ||
| 2549 | : ServiceFramework{system_, "hid:sys"}, service_context{system_, "hid:sys"}, | ||
| 2550 | applet_resource{applet_resource_} { | ||
| 2551 | // clang-format off | ||
| 2552 | static const FunctionInfo functions[] = { | ||
| 2553 | {31, nullptr, "SendKeyboardLockKeyEvent"}, | ||
| 2554 | {101, nullptr, "AcquireHomeButtonEventHandle"}, | ||
| 2555 | {111, nullptr, "ActivateHomeButton"}, | ||
| 2556 | {121, nullptr, "AcquireSleepButtonEventHandle"}, | ||
| 2557 | {131, nullptr, "ActivateSleepButton"}, | ||
| 2558 | {141, nullptr, "AcquireCaptureButtonEventHandle"}, | ||
| 2559 | {151, nullptr, "ActivateCaptureButton"}, | ||
| 2560 | {161, nullptr, "GetPlatformConfig"}, | ||
| 2561 | {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"}, | ||
| 2562 | {211, nullptr, "GetNpadsWithNfc"}, | ||
| 2563 | {212, nullptr, "AcquireNfcActivateEventHandle"}, | ||
| 2564 | {213, nullptr, "ActivateNfc"}, | ||
| 2565 | {214, nullptr, "GetXcdHandleForNpadWithNfc"}, | ||
| 2566 | {215, nullptr, "IsNfcActivated"}, | ||
| 2567 | {230, nullptr, "AcquireIrSensorEventHandle"}, | ||
| 2568 | {231, nullptr, "ActivateIrSensor"}, | ||
| 2569 | {232, nullptr, "GetIrSensorState"}, | ||
| 2570 | {233, nullptr, "GetXcdHandleForNpadWithIrSensor"}, | ||
| 2571 | {301, nullptr, "ActivateNpadSystem"}, | ||
| 2572 | {303, &HidSys::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"}, | ||
| 2573 | {304, nullptr, "EnableAssigningSingleOnSlSrPress"}, | ||
| 2574 | {305, nullptr, "DisableAssigningSingleOnSlSrPress"}, | ||
| 2575 | {306, &HidSys::GetLastActiveNpad, "GetLastActiveNpad"}, | ||
| 2576 | {307, nullptr, "GetNpadSystemExtStyle"}, | ||
| 2577 | {308, nullptr, "ApplyNpadSystemCommonPolicyFull"}, | ||
| 2578 | {309, nullptr, "GetNpadFullKeyGripColor"}, | ||
| 2579 | {310, nullptr, "GetMaskedSupportedNpadStyleSet"}, | ||
| 2580 | {311, nullptr, "SetNpadPlayerLedBlinkingDevice"}, | ||
| 2581 | {312, nullptr, "SetSupportedNpadStyleSetAll"}, | ||
| 2582 | {313, nullptr, "GetNpadCaptureButtonAssignment"}, | ||
| 2583 | {314, nullptr, "GetAppletFooterUiType"}, | ||
| 2584 | {315, nullptr, "GetAppletDetailedUiType"}, | ||
| 2585 | {316, nullptr, "GetNpadInterfaceType"}, | ||
| 2586 | {317, nullptr, "GetNpadLeftRightInterfaceType"}, | ||
| 2587 | {318, nullptr, "HasBattery"}, | ||
| 2588 | {319, nullptr, "HasLeftRightBattery"}, | ||
| 2589 | {321, &HidSys::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"}, | ||
| 2590 | {322, nullptr, "GetIrSensorState"}, | ||
| 2591 | {323, nullptr, "GetXcdHandleForNpadWithIrSensor"}, | ||
| 2592 | {324, nullptr, "GetUniquePadButtonSet"}, | ||
| 2593 | {325, nullptr, "GetUniquePadColor"}, | ||
| 2594 | {326, nullptr, "GetUniquePadAppletDetailedUiType"}, | ||
| 2595 | {327, nullptr, "GetAbstractedPadIdDataFromNpad"}, | ||
| 2596 | {328, nullptr, "AttachAbstractedPadToNpad"}, | ||
| 2597 | {329, nullptr, "DetachAbstractedPadAll"}, | ||
| 2598 | {330, nullptr, "CheckAbstractedPadConnection"}, | ||
| 2599 | {500, nullptr, "SetAppletResourceUserId"}, | ||
| 2600 | {501, nullptr, "RegisterAppletResourceUserId"}, | ||
| 2601 | {502, nullptr, "UnregisterAppletResourceUserId"}, | ||
| 2602 | {503, nullptr, "EnableAppletToGetInput"}, | ||
| 2603 | {504, nullptr, "SetAruidValidForVibration"}, | ||
| 2604 | {505, nullptr, "EnableAppletToGetSixAxisSensor"}, | ||
| 2605 | {506, nullptr, "EnableAppletToGetPadInput"}, | ||
| 2606 | {507, nullptr, "EnableAppletToGetTouchScreen"}, | ||
| 2607 | {510, nullptr, "SetVibrationMasterVolume"}, | ||
| 2608 | {511, nullptr, "GetVibrationMasterVolume"}, | ||
| 2609 | {512, nullptr, "BeginPermitVibrationSession"}, | ||
| 2610 | {513, nullptr, "EndPermitVibrationSession"}, | ||
| 2611 | {514, nullptr, "Unknown514"}, | ||
| 2612 | {520, nullptr, "EnableHandheldHids"}, | ||
| 2613 | {521, nullptr, "DisableHandheldHids"}, | ||
| 2614 | {522, nullptr, "SetJoyConRailEnabled"}, | ||
| 2615 | {523, nullptr, "IsJoyConRailEnabled"}, | ||
| 2616 | {524, nullptr, "IsHandheldHidsEnabled"}, | ||
| 2617 | {525, nullptr, "IsJoyConAttachedOnAllRail"}, | ||
| 2618 | {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"}, | ||
| 2619 | {541, nullptr, "GetPlayReportControllerUsages"}, | ||
| 2620 | {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"}, | ||
| 2621 | {543, nullptr, "GetRegisteredDevicesOld"}, | ||
| 2622 | {544, nullptr, "AcquireConnectionTriggerTimeoutEvent"}, | ||
| 2623 | {545, nullptr, "SendConnectionTrigger"}, | ||
| 2624 | {546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"}, | ||
| 2625 | {547, nullptr, "GetAllowedBluetoothLinksCount"}, | ||
| 2626 | {548, nullptr, "GetRegisteredDevices"}, | ||
| 2627 | {549, nullptr, "GetConnectableRegisteredDevices"}, | ||
| 2628 | {700, nullptr, "ActivateUniquePad"}, | ||
| 2629 | {702, nullptr, "AcquireUniquePadConnectionEventHandle"}, | ||
| 2630 | {703, nullptr, "GetUniquePadIds"}, | ||
| 2631 | {751, &HidSys::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"}, | ||
| 2632 | {800, nullptr, "ListSixAxisSensorHandles"}, | ||
| 2633 | {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"}, | ||
| 2634 | {802, nullptr, "ResetSixAxisSensorCalibrationValues"}, | ||
| 2635 | {803, nullptr, "StartSixAxisSensorUserCalibration"}, | ||
| 2636 | {804, nullptr, "CancelSixAxisSensorUserCalibration"}, | ||
| 2637 | {805, nullptr, "GetUniquePadBluetoothAddress"}, | ||
| 2638 | {806, nullptr, "DisconnectUniquePad"}, | ||
| 2639 | {807, nullptr, "GetUniquePadType"}, | ||
| 2640 | {808, nullptr, "GetUniquePadInterface"}, | ||
| 2641 | {809, nullptr, "GetUniquePadSerialNumber"}, | ||
| 2642 | {810, nullptr, "GetUniquePadControllerNumber"}, | ||
| 2643 | {811, nullptr, "GetSixAxisSensorUserCalibrationStage"}, | ||
| 2644 | {812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"}, | ||
| 2645 | {821, nullptr, "StartAnalogStickManualCalibration"}, | ||
| 2646 | {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"}, | ||
| 2647 | {823, nullptr, "CancelAnalogStickManualCalibration"}, | ||
| 2648 | {824, nullptr, "ResetAnalogStickManualCalibration"}, | ||
| 2649 | {825, nullptr, "GetAnalogStickState"}, | ||
| 2650 | {826, nullptr, "GetAnalogStickManualCalibrationStage"}, | ||
| 2651 | {827, nullptr, "IsAnalogStickButtonPressed"}, | ||
| 2652 | {828, nullptr, "IsAnalogStickInReleasePosition"}, | ||
| 2653 | {829, nullptr, "IsAnalogStickInCircumference"}, | ||
| 2654 | {830, nullptr, "SetNotificationLedPattern"}, | ||
| 2655 | {831, nullptr, "SetNotificationLedPatternWithTimeout"}, | ||
| 2656 | {832, nullptr, "PrepareHidsForNotificationWake"}, | ||
| 2657 | {850, &HidSys::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"}, | ||
| 2658 | {851, nullptr, "EnableUsbFullKeyController"}, | ||
| 2659 | {852, nullptr, "IsUsbConnected"}, | ||
| 2660 | {870, nullptr, "IsHandheldButtonPressedOnConsoleMode"}, | ||
| 2661 | {900, nullptr, "ActivateInputDetector"}, | ||
| 2662 | {901, nullptr, "NotifyInputDetector"}, | ||
| 2663 | {1000, nullptr, "InitializeFirmwareUpdate"}, | ||
| 2664 | {1001, nullptr, "GetFirmwareVersion"}, | ||
| 2665 | {1002, nullptr, "GetAvailableFirmwareVersion"}, | ||
| 2666 | {1003, nullptr, "IsFirmwareUpdateAvailable"}, | ||
| 2667 | {1004, nullptr, "CheckFirmwareUpdateRequired"}, | ||
| 2668 | {1005, nullptr, "StartFirmwareUpdate"}, | ||
| 2669 | {1006, nullptr, "AbortFirmwareUpdate"}, | ||
| 2670 | {1007, nullptr, "GetFirmwareUpdateState"}, | ||
| 2671 | {1008, nullptr, "ActivateAudioControl"}, | ||
| 2672 | {1009, nullptr, "AcquireAudioControlEventHandle"}, | ||
| 2673 | {1010, nullptr, "GetAudioControlStates"}, | ||
| 2674 | {1011, nullptr, "DeactivateAudioControl"}, | ||
| 2675 | {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"}, | ||
| 2676 | {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"}, | ||
| 2677 | {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"}, | ||
| 2678 | {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"}, | ||
| 2679 | {1100, nullptr, "GetHidbusSystemServiceObject"}, | ||
| 2680 | {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"}, | ||
| 2681 | {1130, nullptr, "InitializeUsbFirmwareUpdate"}, | ||
| 2682 | {1131, nullptr, "FinalizeUsbFirmwareUpdate"}, | ||
| 2683 | {1132, nullptr, "CheckUsbFirmwareUpdateRequired"}, | ||
| 2684 | {1133, nullptr, "StartUsbFirmwareUpdate"}, | ||
| 2685 | {1134, nullptr, "GetUsbFirmwareUpdateState"}, | ||
| 2686 | {1150, nullptr, "SetTouchScreenMagnification"}, | ||
| 2687 | {1151, nullptr, "GetTouchScreenFirmwareVersion"}, | ||
| 2688 | {1152, nullptr, "SetTouchScreenDefaultConfiguration"}, | ||
| 2689 | {1153, &HidSys::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"}, | ||
| 2690 | {1154, nullptr, "IsFirmwareAvailableForNotification"}, | ||
| 2691 | {1155, nullptr, "SetForceHandheldStyleVibration"}, | ||
| 2692 | {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"}, | ||
| 2693 | {1157, nullptr, "CancelConnectionTrigger"}, | ||
| 2694 | {1200, nullptr, "IsButtonConfigSupported"}, | ||
| 2695 | {1201, nullptr, "IsButtonConfigEmbeddedSupported"}, | ||
| 2696 | {1202, nullptr, "DeleteButtonConfig"}, | ||
| 2697 | {1203, nullptr, "DeleteButtonConfigEmbedded"}, | ||
| 2698 | {1204, nullptr, "SetButtonConfigEnabled"}, | ||
| 2699 | {1205, nullptr, "SetButtonConfigEmbeddedEnabled"}, | ||
| 2700 | {1206, nullptr, "IsButtonConfigEnabled"}, | ||
| 2701 | {1207, nullptr, "IsButtonConfigEmbeddedEnabled"}, | ||
| 2702 | {1208, nullptr, "SetButtonConfigEmbedded"}, | ||
| 2703 | {1209, nullptr, "SetButtonConfigFull"}, | ||
| 2704 | {1210, nullptr, "SetButtonConfigLeft"}, | ||
| 2705 | {1211, nullptr, "SetButtonConfigRight"}, | ||
| 2706 | {1212, nullptr, "GetButtonConfigEmbedded"}, | ||
| 2707 | {1213, nullptr, "GetButtonConfigFull"}, | ||
| 2708 | {1214, nullptr, "GetButtonConfigLeft"}, | ||
| 2709 | {1215, nullptr, "GetButtonConfigRight"}, | ||
| 2710 | {1250, nullptr, "IsCustomButtonConfigSupported"}, | ||
| 2711 | {1251, nullptr, "IsDefaultButtonConfigEmbedded"}, | ||
| 2712 | {1252, nullptr, "IsDefaultButtonConfigFull"}, | ||
| 2713 | {1253, nullptr, "IsDefaultButtonConfigLeft"}, | ||
| 2714 | {1254, nullptr, "IsDefaultButtonConfigRight"}, | ||
| 2715 | {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"}, | ||
| 2716 | {1256, nullptr, "IsButtonConfigStorageFullEmpty"}, | ||
| 2717 | {1257, nullptr, "IsButtonConfigStorageLeftEmpty"}, | ||
| 2718 | {1258, nullptr, "IsButtonConfigStorageRightEmpty"}, | ||
| 2719 | {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"}, | ||
| 2720 | {1260, nullptr, "GetButtonConfigStorageFullDeprecated"}, | ||
| 2721 | {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"}, | ||
| 2722 | {1262, nullptr, "GetButtonConfigStorageRightDeprecated"}, | ||
| 2723 | {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"}, | ||
| 2724 | {1264, nullptr, "SetButtonConfigStorageFullDeprecated"}, | ||
| 2725 | {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"}, | ||
| 2726 | {1266, nullptr, "SetButtonConfigStorageRightDeprecated"}, | ||
| 2727 | {1267, nullptr, "DeleteButtonConfigStorageEmbedded"}, | ||
| 2728 | {1268, nullptr, "DeleteButtonConfigStorageFull"}, | ||
| 2729 | {1269, nullptr, "DeleteButtonConfigStorageLeft"}, | ||
| 2730 | {1270, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 2731 | {1271, nullptr, "IsUsingCustomButtonConfig"}, | ||
| 2732 | {1272, nullptr, "IsAnyCustomButtonConfigEnabled"}, | ||
| 2733 | {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, | ||
| 2734 | {1274, nullptr, "SetDefaultButtonConfig"}, | ||
| 2735 | {1275, nullptr, "SetAllDefaultButtonConfig"}, | ||
| 2736 | {1276, nullptr, "SetHidButtonConfigEmbedded"}, | ||
| 2737 | {1277, nullptr, "SetHidButtonConfigFull"}, | ||
| 2738 | {1278, nullptr, "SetHidButtonConfigLeft"}, | ||
| 2739 | {1279, nullptr, "SetHidButtonConfigRight"}, | ||
| 2740 | {1280, nullptr, "GetHidButtonConfigEmbedded"}, | ||
| 2741 | {1281, nullptr, "GetHidButtonConfigFull"}, | ||
| 2742 | {1282, nullptr, "GetHidButtonConfigLeft"}, | ||
| 2743 | {1283, nullptr, "GetHidButtonConfigRight"}, | ||
| 2744 | {1284, nullptr, "GetButtonConfigStorageEmbedded"}, | ||
| 2745 | {1285, nullptr, "GetButtonConfigStorageFull"}, | ||
| 2746 | {1286, nullptr, "GetButtonConfigStorageLeft"}, | ||
| 2747 | {1287, nullptr, "GetButtonConfigStorageRight"}, | ||
| 2748 | {1288, nullptr, "SetButtonConfigStorageEmbedded"}, | ||
| 2749 | {1289, nullptr, "SetButtonConfigStorageFull"}, | ||
| 2750 | {1290, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 2751 | {1291, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 2752 | }; | ||
| 2753 | // clang-format on | ||
| 2754 | |||
| 2755 | RegisterHandlers(functions); | ||
| 2756 | |||
| 2757 | joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent"); | ||
| 2758 | } | ||
| 2759 | |||
| 2760 | ~HidSys() { | ||
| 2761 | service_context.CloseEvent(joy_detach_event); | ||
| 2762 | }; | ||
| 2763 | |||
| 2764 | private: | ||
| 2765 | void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) { | ||
| 2766 | LOG_WARNING(Service_HID, "called"); | ||
| 2767 | |||
| 2768 | GetAppletResource() | ||
| 2769 | ->GetController<Controller_NPad>(HidController::NPad) | ||
| 2770 | .ApplyNpadSystemCommonPolicy(); | ||
| 2771 | |||
| 2772 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2773 | rb.Push(ResultSuccess); | ||
| 2774 | } | ||
| 2775 | |||
| 2776 | void GetLastActiveNpad(HLERequestContext& ctx) { | ||
| 2777 | LOG_DEBUG(Service_HID, "(STUBBED) called"); | ||
| 2778 | |||
| 2779 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 2780 | rb.Push(ResultSuccess); | ||
| 2781 | rb.PushEnum(system.HIDCore().GetLastActiveController()); | ||
| 2782 | } | ||
| 2783 | |||
| 2784 | void GetUniquePadsFromNpad(HLERequestContext& ctx) { | ||
| 2785 | IPC::RequestParser rp{ctx}; | ||
| 2786 | const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 2787 | |||
| 2788 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id_type={}", npad_id_type); | ||
| 2789 | |||
| 2790 | const std::vector<Core::HID::UniquePadId> unique_pads{}; | ||
| 2791 | |||
| 2792 | ctx.WriteBuffer(unique_pads); | ||
| 2793 | |||
| 2794 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 2795 | rb.Push(ResultSuccess); | ||
| 2796 | rb.Push(static_cast<u32>(unique_pads.size())); | ||
| 2797 | } | ||
| 2798 | |||
| 2799 | void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) { | ||
| 2800 | LOG_INFO(Service_AM, "called"); | ||
| 2801 | |||
| 2802 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 2803 | rb.Push(ResultSuccess); | ||
| 2804 | rb.PushCopyObjects(joy_detach_event->GetReadableEvent()); | ||
| 2805 | } | ||
| 2806 | |||
| 2807 | void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) { | ||
| 2808 | const bool is_enabled = false; | ||
| 2809 | |||
| 2810 | LOG_WARNING(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled); | ||
| 2811 | |||
| 2812 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 2813 | rb.Push(ResultSuccess); | ||
| 2814 | rb.Push(is_enabled); | ||
| 2815 | } | ||
| 2816 | |||
| 2817 | void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) { | ||
| 2818 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2819 | |||
| 2820 | Core::HID::TouchScreenConfigurationForNx touchscreen_config{ | ||
| 2821 | .mode = Core::HID::TouchScreenModeForNx::Finger, | ||
| 2822 | }; | ||
| 2823 | |||
| 2824 | if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 && | ||
| 2825 | touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) { | ||
| 2826 | touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting; | ||
| 2827 | } | ||
| 2828 | |||
| 2829 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 2830 | rb.Push(ResultSuccess); | ||
| 2831 | rb.PushRaw(touchscreen_config); | ||
| 2832 | } | ||
| 2833 | |||
| 2834 | std::shared_ptr<IAppletResource> GetAppletResource() { | ||
| 2835 | if (applet_resource == nullptr) { | ||
| 2836 | applet_resource = std::make_shared<IAppletResource>(system, service_context); | ||
| 2837 | } | ||
| 2838 | |||
| 2839 | return applet_resource; | ||
| 2840 | } | ||
| 2841 | |||
| 2842 | Kernel::KEvent* joy_detach_event; | ||
| 2843 | KernelHelpers::ServiceContext service_context; | ||
| 2844 | std::shared_ptr<IAppletResource> applet_resource; | ||
| 2845 | }; | ||
| 2846 | |||
| 2847 | void LoopProcess(Core::System& system) { | 17 | void LoopProcess(Core::System& system) { |
| 2848 | auto server_manager = std::make_unique<ServerManager>(system); | 18 | auto server_manager = std::make_unique<ServerManager>(system); |
| 2849 | std::shared_ptr<IAppletResource> applet_resource; | 19 | std::shared_ptr<ResourceManager> resouce_manager = std::make_shared<ResourceManager>(system); |
| 20 | std::shared_ptr<HidFirmwareSettings> firmware_settings = | ||
| 21 | std::make_shared<HidFirmwareSettings>(); | ||
| 22 | |||
| 23 | server_manager->RegisterNamedService( | ||
| 24 | "hid", std::make_shared<IHidServer>(system, resouce_manager, firmware_settings)); | ||
| 25 | server_manager->RegisterNamedService( | ||
| 26 | "hid:dbg", std::make_shared<IHidDebugServer>(system, resouce_manager)); | ||
| 27 | server_manager->RegisterNamedService( | ||
| 28 | "hid:sys", std::make_shared<IHidSystemServer>(system, resouce_manager)); | ||
| 2850 | 29 | ||
| 2851 | server_manager->RegisterNamedService("hid", std::make_shared<Hid>(system, applet_resource)); | ||
| 2852 | server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system)); | 30 | server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system)); |
| 2853 | server_manager->RegisterNamedService("hid:dbg", std::make_shared<HidDbg>(system)); | ||
| 2854 | server_manager->RegisterNamedService("hid:sys", | ||
| 2855 | std::make_shared<HidSys>(system, applet_resource)); | ||
| 2856 | 31 | ||
| 2857 | server_manager->RegisterNamedService("irs", std::make_shared<Service::IRS::IRS>(system)); | 32 | server_manager->RegisterNamedService("irs", std::make_shared<IRS::IRS>(system)); |
| 2858 | server_manager->RegisterNamedService("irs:sys", | 33 | server_manager->RegisterNamedService("irs:sys", std::make_shared<IRS::IRS_SYS>(system)); |
| 2859 | std::make_shared<Service::IRS::IRS_SYS>(system)); | ||
| 2860 | 34 | ||
| 2861 | server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system)); | 35 | server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system)); |
| 36 | |||
| 2862 | system.RunServer(std::move(server_manager)); | 37 | system.RunServer(std::move(server_manager)); |
| 2863 | } | 38 | } |
| 2864 | 39 | ||
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 0ca43de93..ec5463f4e 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -3,220 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <chrono> | 6 | namespace Core { |
| 7 | 7 | class System; | |
| 8 | #include "core/hle/service/hid/controllers/controller_base.h" | ||
| 9 | #include "core/hle/service/kernel_helpers.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | |||
| 12 | namespace Core::Timing { | ||
| 13 | struct EventType; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Service::SM { | ||
| 17 | class ServiceManager; | ||
| 18 | } | 8 | } |
| 19 | 9 | ||
| 20 | namespace Service::HID { | 10 | namespace Service::HID { |
| 21 | 11 | ||
| 22 | enum class HidController : std::size_t { | ||
| 23 | DebugPad, | ||
| 24 | Touchscreen, | ||
| 25 | Mouse, | ||
| 26 | Keyboard, | ||
| 27 | XPad, | ||
| 28 | HomeButton, | ||
| 29 | SleepButton, | ||
| 30 | CaptureButton, | ||
| 31 | InputDetector, | ||
| 32 | UniquePad, | ||
| 33 | NPad, | ||
| 34 | Gesture, | ||
| 35 | ConsoleSixAxisSensor, | ||
| 36 | DebugMouse, | ||
| 37 | Palma, | ||
| 38 | |||
| 39 | MaxControllers, | ||
| 40 | }; | ||
| 41 | |||
| 42 | class IAppletResource final : public ServiceFramework<IAppletResource> { | ||
| 43 | public: | ||
| 44 | explicit IAppletResource(Core::System& system_, | ||
| 45 | KernelHelpers::ServiceContext& service_context_); | ||
| 46 | ~IAppletResource() override; | ||
| 47 | |||
| 48 | void ActivateController(HidController controller); | ||
| 49 | void DeactivateController(HidController controller); | ||
| 50 | |||
| 51 | template <typename T> | ||
| 52 | T& GetController(HidController controller) { | ||
| 53 | return static_cast<T&>(*controllers[static_cast<size_t>(controller)]); | ||
| 54 | } | ||
| 55 | |||
| 56 | template <typename T> | ||
| 57 | const T& GetController(HidController controller) const { | ||
| 58 | return static_cast<T&>(*controllers[static_cast<size_t>(controller)]); | ||
| 59 | } | ||
| 60 | |||
| 61 | private: | ||
| 62 | template <typename T> | ||
| 63 | void MakeController(HidController controller, u8* shared_memory) { | ||
| 64 | if constexpr (std::is_constructible_v<T, Core::System&, u8*>) { | ||
| 65 | controllers[static_cast<std::size_t>(controller)] = | ||
| 66 | std::make_unique<T>(system, shared_memory); | ||
| 67 | } else { | ||
| 68 | controllers[static_cast<std::size_t>(controller)] = | ||
| 69 | std::make_unique<T>(system.HIDCore(), shared_memory); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | template <typename T> | ||
| 74 | void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) { | ||
| 75 | controllers[static_cast<std::size_t>(controller)] = | ||
| 76 | std::make_unique<T>(system.HIDCore(), shared_memory, service_context); | ||
| 77 | } | ||
| 78 | |||
| 79 | void GetSharedMemoryHandle(HLERequestContext& ctx); | ||
| 80 | void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||
| 81 | void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||
| 82 | void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||
| 83 | void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||
| 84 | |||
| 85 | KernelHelpers::ServiceContext& service_context; | ||
| 86 | |||
| 87 | std::shared_ptr<Core::Timing::EventType> npad_update_event; | ||
| 88 | std::shared_ptr<Core::Timing::EventType> default_update_event; | ||
| 89 | std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; | ||
| 90 | std::shared_ptr<Core::Timing::EventType> motion_update_event; | ||
| 91 | |||
| 92 | std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> | ||
| 93 | controllers{}; | ||
| 94 | }; | ||
| 95 | |||
| 96 | class Hid final : public ServiceFramework<Hid> { | ||
| 97 | public: | ||
| 98 | explicit Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_); | ||
| 99 | ~Hid() override; | ||
| 100 | |||
| 101 | std::shared_ptr<IAppletResource> GetAppletResource(); | ||
| 102 | |||
| 103 | private: | ||
| 104 | void CreateAppletResource(HLERequestContext& ctx); | ||
| 105 | void ActivateDebugPad(HLERequestContext& ctx); | ||
| 106 | void ActivateTouchScreen(HLERequestContext& ctx); | ||
| 107 | void ActivateMouse(HLERequestContext& ctx); | ||
| 108 | void ActivateKeyboard(HLERequestContext& ctx); | ||
| 109 | void SendKeyboardLockKeyEvent(HLERequestContext& ctx); | ||
| 110 | void ActivateXpad(HLERequestContext& ctx); | ||
| 111 | void GetXpadIDs(HLERequestContext& ctx); | ||
| 112 | void ActivateSixAxisSensor(HLERequestContext& ctx); | ||
| 113 | void DeactivateSixAxisSensor(HLERequestContext& ctx); | ||
| 114 | void StartSixAxisSensor(HLERequestContext& ctx); | ||
| 115 | void StopSixAxisSensor(HLERequestContext& ctx); | ||
| 116 | void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx); | ||
| 117 | void EnableSixAxisSensorFusion(HLERequestContext& ctx); | ||
| 118 | void SetSixAxisSensorFusionParameters(HLERequestContext& ctx); | ||
| 119 | void GetSixAxisSensorFusionParameters(HLERequestContext& ctx); | ||
| 120 | void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx); | ||
| 121 | void SetGyroscopeZeroDriftMode(HLERequestContext& ctx); | ||
| 122 | void GetGyroscopeZeroDriftMode(HLERequestContext& ctx); | ||
| 123 | void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx); | ||
| 124 | void IsSixAxisSensorAtRest(HLERequestContext& ctx); | ||
| 125 | void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx); | ||
| 126 | void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx); | ||
| 127 | void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx); | ||
| 128 | void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx); | ||
| 129 | void GetSixAxisSensorIcInformation(HLERequestContext& ctx); | ||
| 130 | void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx); | ||
| 131 | void ActivateGesture(HLERequestContext& ctx); | ||
| 132 | void SetSupportedNpadStyleSet(HLERequestContext& ctx); | ||
| 133 | void GetSupportedNpadStyleSet(HLERequestContext& ctx); | ||
| 134 | void SetSupportedNpadIdType(HLERequestContext& ctx); | ||
| 135 | void ActivateNpad(HLERequestContext& ctx); | ||
| 136 | void DeactivateNpad(HLERequestContext& ctx); | ||
| 137 | void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx); | ||
| 138 | void DisconnectNpad(HLERequestContext& ctx); | ||
| 139 | void GetPlayerLedPattern(HLERequestContext& ctx); | ||
| 140 | void ActivateNpadWithRevision(HLERequestContext& ctx); | ||
| 141 | void SetNpadJoyHoldType(HLERequestContext& ctx); | ||
| 142 | void GetNpadJoyHoldType(HLERequestContext& ctx); | ||
| 143 | void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx); | ||
| 144 | void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx); | ||
| 145 | void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx); | ||
| 146 | void MergeSingleJoyAsDualJoy(HLERequestContext& ctx); | ||
| 147 | void StartLrAssignmentMode(HLERequestContext& ctx); | ||
| 148 | void StopLrAssignmentMode(HLERequestContext& ctx); | ||
| 149 | void SetNpadHandheldActivationMode(HLERequestContext& ctx); | ||
| 150 | void GetNpadHandheldActivationMode(HLERequestContext& ctx); | ||
| 151 | void SwapNpadAssignment(HLERequestContext& ctx); | ||
| 152 | void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx); | ||
| 153 | void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx); | ||
| 154 | void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx); | ||
| 155 | void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx); | ||
| 156 | void SetNpadCaptureButtonAssignment(HLERequestContext& ctx); | ||
| 157 | void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx); | ||
| 158 | void GetVibrationDeviceInfo(HLERequestContext& ctx); | ||
| 159 | void SendVibrationValue(HLERequestContext& ctx); | ||
| 160 | void GetActualVibrationValue(HLERequestContext& ctx); | ||
| 161 | void CreateActiveVibrationDeviceList(HLERequestContext& ctx); | ||
| 162 | void PermitVibration(HLERequestContext& ctx); | ||
| 163 | void IsVibrationPermitted(HLERequestContext& ctx); | ||
| 164 | void SendVibrationValues(HLERequestContext& ctx); | ||
| 165 | void SendVibrationGcErmCommand(HLERequestContext& ctx); | ||
| 166 | void GetActualVibrationGcErmCommand(HLERequestContext& ctx); | ||
| 167 | void BeginPermitVibrationSession(HLERequestContext& ctx); | ||
| 168 | void EndPermitVibrationSession(HLERequestContext& ctx); | ||
| 169 | void IsVibrationDeviceMounted(HLERequestContext& ctx); | ||
| 170 | void ActivateConsoleSixAxisSensor(HLERequestContext& ctx); | ||
| 171 | void StartConsoleSixAxisSensor(HLERequestContext& ctx); | ||
| 172 | void StopConsoleSixAxisSensor(HLERequestContext& ctx); | ||
| 173 | void ActivateSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 174 | void StartSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 175 | void StopSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 176 | void InitializeSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 177 | void FinalizeSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 178 | void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx); | ||
| 179 | void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx); | ||
| 180 | void GetPalmaConnectionHandle(HLERequestContext& ctx); | ||
| 181 | void InitializePalma(HLERequestContext& ctx); | ||
| 182 | void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx); | ||
| 183 | void GetPalmaOperationInfo(HLERequestContext& ctx); | ||
| 184 | void PlayPalmaActivity(HLERequestContext& ctx); | ||
| 185 | void SetPalmaFrModeType(HLERequestContext& ctx); | ||
| 186 | void ReadPalmaStep(HLERequestContext& ctx); | ||
| 187 | void EnablePalmaStep(HLERequestContext& ctx); | ||
| 188 | void ResetPalmaStep(HLERequestContext& ctx); | ||
| 189 | void ReadPalmaApplicationSection(HLERequestContext& ctx); | ||
| 190 | void WritePalmaApplicationSection(HLERequestContext& ctx); | ||
| 191 | void ReadPalmaUniqueCode(HLERequestContext& ctx); | ||
| 192 | void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx); | ||
| 193 | void WritePalmaActivityEntry(HLERequestContext& ctx); | ||
| 194 | void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx); | ||
| 195 | void WritePalmaWaveEntry(HLERequestContext& ctx); | ||
| 196 | void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx); | ||
| 197 | void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx); | ||
| 198 | void SuspendPalmaFeature(HLERequestContext& ctx); | ||
| 199 | void GetPalmaOperationResult(HLERequestContext& ctx); | ||
| 200 | void ReadPalmaPlayLog(HLERequestContext& ctx); | ||
| 201 | void ResetPalmaPlayLog(HLERequestContext& ctx); | ||
| 202 | void SetIsPalmaAllConnectable(HLERequestContext& ctx); | ||
| 203 | void SetIsPalmaPairedConnectable(HLERequestContext& ctx); | ||
| 204 | void PairPalma(HLERequestContext& ctx); | ||
| 205 | void SetPalmaBoostMode(HLERequestContext& ctx); | ||
| 206 | void CancelWritePalmaWaveEntry(HLERequestContext& ctx); | ||
| 207 | void EnablePalmaBoostMode(HLERequestContext& ctx); | ||
| 208 | void GetPalmaBluetoothAddress(HLERequestContext& ctx); | ||
| 209 | void SetDisallowedPalmaConnection(HLERequestContext& ctx); | ||
| 210 | void SetNpadCommunicationMode(HLERequestContext& ctx); | ||
| 211 | void GetNpadCommunicationMode(HLERequestContext& ctx); | ||
| 212 | void SetTouchScreenConfiguration(HLERequestContext& ctx); | ||
| 213 | void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx); | ||
| 214 | |||
| 215 | std::shared_ptr<IAppletResource> applet_resource; | ||
| 216 | |||
| 217 | KernelHelpers::ServiceContext service_context; | ||
| 218 | }; | ||
| 219 | |||
| 220 | void LoopProcess(Core::System& system); | 12 | void LoopProcess(Core::System& system); |
| 221 | 13 | ||
| 222 | } // namespace Service::HID | 14 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp new file mode 100644 index 000000000..6294f3dfb --- /dev/null +++ b/src/core/hle/service/hid/hid_debug_server.cpp | |||
| @@ -0,0 +1,159 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 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" | ||
| 7 | |||
| 8 | namespace Service::HID { | ||
| 9 | |||
| 10 | IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource) | ||
| 11 | : ServiceFramework{system_, "hid:dbg"}, resource_manager{resource} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {0, nullptr, "DeactivateDebugPad"}, | ||
| 15 | {1, nullptr, "SetDebugPadAutoPilotState"}, | ||
| 16 | {2, nullptr, "UnsetDebugPadAutoPilotState"}, | ||
| 17 | {10, nullptr, "DeactivateTouchScreen"}, | ||
| 18 | {11, nullptr, "SetTouchScreenAutoPilotState"}, | ||
| 19 | {12, nullptr, "UnsetTouchScreenAutoPilotState"}, | ||
| 20 | {13, nullptr, "GetTouchScreenConfiguration"}, | ||
| 21 | {14, nullptr, "ProcessTouchScreenAutoTune"}, | ||
| 22 | {15, nullptr, "ForceStopTouchScreenManagement"}, | ||
| 23 | {16, nullptr, "ForceRestartTouchScreenManagement"}, | ||
| 24 | {17, nullptr, "IsTouchScreenManaged"}, | ||
| 25 | {20, nullptr, "DeactivateMouse"}, | ||
| 26 | {21, nullptr, "SetMouseAutoPilotState"}, | ||
| 27 | {22, nullptr, "UnsetMouseAutoPilotState"}, | ||
| 28 | {25, nullptr, "SetDebugMouseAutoPilotState"}, | ||
| 29 | {26, nullptr, "UnsetDebugMouseAutoPilotState"}, | ||
| 30 | {30, nullptr, "DeactivateKeyboard"}, | ||
| 31 | {31, nullptr, "SetKeyboardAutoPilotState"}, | ||
| 32 | {32, nullptr, "UnsetKeyboardAutoPilotState"}, | ||
| 33 | {50, nullptr, "DeactivateXpad"}, | ||
| 34 | {51, nullptr, "SetXpadAutoPilotState"}, | ||
| 35 | {52, nullptr, "UnsetXpadAutoPilotState"}, | ||
| 36 | {53, nullptr, "DeactivateJoyXpad"}, | ||
| 37 | {60, nullptr, "ClearNpadSystemCommonPolicy"}, | ||
| 38 | {61, nullptr, "DeactivateNpad"}, | ||
| 39 | {62, nullptr, "ForceDisconnectNpad"}, | ||
| 40 | {91, nullptr, "DeactivateGesture"}, | ||
| 41 | {110, nullptr, "DeactivateHomeButton"}, | ||
| 42 | {111, nullptr, "SetHomeButtonAutoPilotState"}, | ||
| 43 | {112, nullptr, "UnsetHomeButtonAutoPilotState"}, | ||
| 44 | {120, nullptr, "DeactivateSleepButton"}, | ||
| 45 | {121, nullptr, "SetSleepButtonAutoPilotState"}, | ||
| 46 | {122, nullptr, "UnsetSleepButtonAutoPilotState"}, | ||
| 47 | {123, nullptr, "DeactivateInputDetector"}, | ||
| 48 | {130, nullptr, "DeactivateCaptureButton"}, | ||
| 49 | {131, nullptr, "SetCaptureButtonAutoPilotState"}, | ||
| 50 | {132, nullptr, "UnsetCaptureButtonAutoPilotState"}, | ||
| 51 | {133, nullptr, "SetShiftAccelerometerCalibrationValue"}, | ||
| 52 | {134, nullptr, "GetShiftAccelerometerCalibrationValue"}, | ||
| 53 | {135, nullptr, "SetShiftGyroscopeCalibrationValue"}, | ||
| 54 | {136, nullptr, "GetShiftGyroscopeCalibrationValue"}, | ||
| 55 | {140, nullptr, "DeactivateConsoleSixAxisSensor"}, | ||
| 56 | {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"}, | ||
| 57 | {142, nullptr, "DeactivateSevenSixAxisSensor"}, | ||
| 58 | {143, nullptr, "GetConsoleSixAxisSensorCountStates"}, | ||
| 59 | {144, nullptr, "GetAccelerometerFsr"}, | ||
| 60 | {145, nullptr, "SetAccelerometerFsr"}, | ||
| 61 | {146, nullptr, "GetAccelerometerOdr"}, | ||
| 62 | {147, nullptr, "SetAccelerometerOdr"}, | ||
| 63 | {148, nullptr, "GetGyroscopeFsr"}, | ||
| 64 | {149, nullptr, "SetGyroscopeFsr"}, | ||
| 65 | {150, nullptr, "GetGyroscopeOdr"}, | ||
| 66 | {151, nullptr, "SetGyroscopeOdr"}, | ||
| 67 | {152, nullptr, "GetWhoAmI"}, | ||
| 68 | {201, nullptr, "ActivateFirmwareUpdate"}, | ||
| 69 | {202, nullptr, "DeactivateFirmwareUpdate"}, | ||
| 70 | {203, nullptr, "StartFirmwareUpdate"}, | ||
| 71 | {204, nullptr, "GetFirmwareUpdateStage"}, | ||
| 72 | {205, nullptr, "GetFirmwareVersion"}, | ||
| 73 | {206, nullptr, "GetDestinationFirmwareVersion"}, | ||
| 74 | {207, nullptr, "DiscardFirmwareInfoCacheForRevert"}, | ||
| 75 | {208, nullptr, "StartFirmwareUpdateForRevert"}, | ||
| 76 | {209, nullptr, "GetAvailableFirmwareVersionForRevert"}, | ||
| 77 | {210, nullptr, "IsFirmwareUpdatingDevice"}, | ||
| 78 | {211, nullptr, "StartFirmwareUpdateIndividual"}, | ||
| 79 | {215, nullptr, "SetUsbFirmwareForceUpdateEnabled"}, | ||
| 80 | {216, nullptr, "SetAllKuinaDevicesToFirmwareUpdateMode"}, | ||
| 81 | {221, nullptr, "UpdateControllerColor"}, | ||
| 82 | {222, nullptr, "ConnectUsbPadsAsync"}, | ||
| 83 | {223, nullptr, "DisconnectUsbPadsAsync"}, | ||
| 84 | {224, nullptr, "UpdateDesignInfo"}, | ||
| 85 | {225, nullptr, "GetUniquePadDriverState"}, | ||
| 86 | {226, nullptr, "GetSixAxisSensorDriverStates"}, | ||
| 87 | {227, nullptr, "GetRxPacketHistory"}, | ||
| 88 | {228, nullptr, "AcquireOperationEventHandle"}, | ||
| 89 | {229, nullptr, "ReadSerialFlash"}, | ||
| 90 | {230, nullptr, "WriteSerialFlash"}, | ||
| 91 | {231, nullptr, "GetOperationResult"}, | ||
| 92 | {232, nullptr, "EnableShipmentMode"}, | ||
| 93 | {233, nullptr, "ClearPairingInfo"}, | ||
| 94 | {234, nullptr, "GetUniquePadDeviceTypeSetInternal"}, | ||
| 95 | {235, nullptr, "EnableAnalogStickPower"}, | ||
| 96 | {236, nullptr, "RequestKuinaUartClockCal"}, | ||
| 97 | {237, nullptr, "GetKuinaUartClockCal"}, | ||
| 98 | {238, nullptr, "SetKuinaUartClockTrim"}, | ||
| 99 | {239, nullptr, "KuinaLoopbackTest"}, | ||
| 100 | {240, nullptr, "RequestBatteryVoltage"}, | ||
| 101 | {241, nullptr, "GetBatteryVoltage"}, | ||
| 102 | {242, nullptr, "GetUniquePadPowerInfo"}, | ||
| 103 | {243, nullptr, "RebootUniquePad"}, | ||
| 104 | {244, nullptr, "RequestKuinaFirmwareVersion"}, | ||
| 105 | {245, nullptr, "GetKuinaFirmwareVersion"}, | ||
| 106 | {246, nullptr, "GetVidPid"}, | ||
| 107 | {247, nullptr, "GetAnalogStickCalibrationValue"}, | ||
| 108 | {248, nullptr, "GetUniquePadIdsFull"}, | ||
| 109 | {249, nullptr, "ConnectUniquePad"}, | ||
| 110 | {250, nullptr, "IsVirtual"}, | ||
| 111 | {251, nullptr, "GetAnalogStickModuleParam"}, | ||
| 112 | {301, nullptr, "GetAbstractedPadHandles"}, | ||
| 113 | {302, nullptr, "GetAbstractedPadState"}, | ||
| 114 | {303, nullptr, "GetAbstractedPadsState"}, | ||
| 115 | {321, nullptr, "SetAutoPilotVirtualPadState"}, | ||
| 116 | {322, nullptr, "UnsetAutoPilotVirtualPadState"}, | ||
| 117 | {323, nullptr, "UnsetAllAutoPilotVirtualPadState"}, | ||
| 118 | {324, nullptr, "AttachHdlsWorkBuffer"}, | ||
| 119 | {325, nullptr, "ReleaseHdlsWorkBuffer"}, | ||
| 120 | {326, nullptr, "DumpHdlsNpadAssignmentState"}, | ||
| 121 | {327, nullptr, "DumpHdlsStates"}, | ||
| 122 | {328, nullptr, "ApplyHdlsNpadAssignmentState"}, | ||
| 123 | {329, nullptr, "ApplyHdlsStateList"}, | ||
| 124 | {330, nullptr, "AttachHdlsVirtualDevice"}, | ||
| 125 | {331, nullptr, "DetachHdlsVirtualDevice"}, | ||
| 126 | {332, nullptr, "SetHdlsState"}, | ||
| 127 | {350, nullptr, "AddRegisteredDevice"}, | ||
| 128 | {400, nullptr, "DisableExternalMcuOnNxDevice"}, | ||
| 129 | {401, nullptr, "DisableRailDeviceFiltering"}, | ||
| 130 | {402, nullptr, "EnableWiredPairing"}, | ||
| 131 | {403, nullptr, "EnableShipmentModeAutoClear"}, | ||
| 132 | {404, nullptr, "SetRailEnabled"}, | ||
| 133 | {500, nullptr, "SetFactoryInt"}, | ||
| 134 | {501, nullptr, "IsFactoryBootEnabled"}, | ||
| 135 | {550, nullptr, "SetAnalogStickModelDataTemporarily"}, | ||
| 136 | {551, nullptr, "GetAnalogStickModelData"}, | ||
| 137 | {552, nullptr, "ResetAnalogStickModelData"}, | ||
| 138 | {600, nullptr, "ConvertPadState"}, | ||
| 139 | {650, nullptr, "AddButtonPlayData"}, | ||
| 140 | {651, nullptr, "StartButtonPlayData"}, | ||
| 141 | {652, nullptr, "StopButtonPlayData"}, | ||
| 142 | {2000, nullptr, "DeactivateDigitizer"}, | ||
| 143 | {2001, nullptr, "SetDigitizerAutoPilotState"}, | ||
| 144 | {2002, nullptr, "UnsetDigitizerAutoPilotState"}, | ||
| 145 | {2002, nullptr, "ReloadFirmwareDebugSettings"}, | ||
| 146 | }; | ||
| 147 | // clang-format on | ||
| 148 | |||
| 149 | RegisterHandlers(functions); | ||
| 150 | } | ||
| 151 | |||
| 152 | IHidDebugServer::~IHidDebugServer() = default; | ||
| 153 | |||
| 154 | std::shared_ptr<ResourceManager> IHidDebugServer::GetResourceManager() { | ||
| 155 | resource_manager->Initialize(); | ||
| 156 | return resource_manager; | ||
| 157 | } | ||
| 158 | |||
| 159 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/hid_debug_server.h b/src/core/hle/service/hid/hid_debug_server.h new file mode 100644 index 000000000..406db2211 --- /dev/null +++ b/src/core/hle/service/hid/hid_debug_server.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::HID { | ||
| 13 | class ResourceManager; | ||
| 14 | |||
| 15 | class IHidDebugServer final : public ServiceFramework<IHidDebugServer> { | ||
| 16 | public: | ||
| 17 | explicit IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource); | ||
| 18 | ~IHidDebugServer() override; | ||
| 19 | |||
| 20 | private: | ||
| 21 | std::shared_ptr<ResourceManager> GetResourceManager(); | ||
| 22 | |||
| 23 | std::shared_ptr<ResourceManager> resource_manager; | ||
| 24 | }; | ||
| 25 | |||
| 26 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/hid_firmware_settings.cpp b/src/core/hle/service/hid/hid_firmware_settings.cpp new file mode 100644 index 000000000..59bd6825c --- /dev/null +++ b/src/core/hle/service/hid/hid_firmware_settings.cpp | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/hid/hid_firmware_settings.h" | ||
| 5 | |||
| 6 | namespace Service::HID { | ||
| 7 | |||
| 8 | HidFirmwareSettings::HidFirmwareSettings() { | ||
| 9 | LoadSettings(true); | ||
| 10 | } | ||
| 11 | |||
| 12 | void HidFirmwareSettings::Reload() { | ||
| 13 | LoadSettings(true); | ||
| 14 | } | ||
| 15 | |||
| 16 | void HidFirmwareSettings::LoadSettings(bool reload_config) { | ||
| 17 | if (is_initalized && !reload_config) { | ||
| 18 | return; | ||
| 19 | } | ||
| 20 | |||
| 21 | // TODO: Use nn::settings::fwdbg::GetSettingsItemValue to load config values | ||
| 22 | |||
| 23 | is_debug_pad_enabled = true; | ||
| 24 | is_device_managed = true; | ||
| 25 | is_touch_i2c_managed = is_device_managed; | ||
| 26 | is_future_devices_emulated = false; | ||
| 27 | is_mcu_hardware_error_emulated = false; | ||
| 28 | is_rail_enabled = true; | ||
| 29 | is_firmware_update_failure_emulated = false; | ||
| 30 | is_firmware_update_failure = {}; | ||
| 31 | is_ble_disabled = false; | ||
| 32 | is_dscale_disabled = false; | ||
| 33 | is_handheld_forced = true; | ||
| 34 | features_per_id_disabled = {}; | ||
| 35 | is_touch_firmware_auto_update_disabled = false; | ||
| 36 | is_initalized = true; | ||
| 37 | } | ||
| 38 | |||
| 39 | bool HidFirmwareSettings::IsDebugPadEnabled() { | ||
| 40 | LoadSettings(false); | ||
| 41 | return is_debug_pad_enabled; | ||
| 42 | } | ||
| 43 | |||
| 44 | bool HidFirmwareSettings::IsDeviceManaged() { | ||
| 45 | LoadSettings(false); | ||
| 46 | return is_device_managed; | ||
| 47 | } | ||
| 48 | |||
| 49 | bool HidFirmwareSettings::IsEmulateFutureDevice() { | ||
| 50 | LoadSettings(false); | ||
| 51 | return is_future_devices_emulated; | ||
| 52 | } | ||
| 53 | |||
| 54 | bool HidFirmwareSettings::IsTouchI2cManaged() { | ||
| 55 | LoadSettings(false); | ||
| 56 | return is_touch_i2c_managed; | ||
| 57 | } | ||
| 58 | |||
| 59 | bool HidFirmwareSettings::IsHandheldForced() { | ||
| 60 | LoadSettings(false); | ||
| 61 | return is_handheld_forced; | ||
| 62 | } | ||
| 63 | |||
| 64 | bool HidFirmwareSettings::IsRailEnabled() { | ||
| 65 | LoadSettings(false); | ||
| 66 | return is_rail_enabled; | ||
| 67 | } | ||
| 68 | |||
| 69 | bool HidFirmwareSettings::IsHardwareErrorEmulated() { | ||
| 70 | LoadSettings(false); | ||
| 71 | return is_mcu_hardware_error_emulated; | ||
| 72 | } | ||
| 73 | |||
| 74 | bool HidFirmwareSettings::IsBleDisabled() { | ||
| 75 | LoadSettings(false); | ||
| 76 | return is_ble_disabled; | ||
| 77 | } | ||
| 78 | |||
| 79 | bool HidFirmwareSettings::IsDscaleDisabled() { | ||
| 80 | LoadSettings(false); | ||
| 81 | return is_dscale_disabled; | ||
| 82 | } | ||
| 83 | |||
| 84 | bool HidFirmwareSettings::IsTouchAutoUpdateDisabled() { | ||
| 85 | LoadSettings(false); | ||
| 86 | return is_touch_firmware_auto_update_disabled; | ||
| 87 | } | ||
| 88 | |||
| 89 | HidFirmwareSettings::FirmwareSetting HidFirmwareSettings::GetFirmwareUpdateFailure() { | ||
| 90 | LoadSettings(false); | ||
| 91 | return is_firmware_update_failure; | ||
| 92 | } | ||
| 93 | |||
| 94 | HidFirmwareSettings::FeaturesPerId HidFirmwareSettings::FeaturesDisabledPerId() { | ||
| 95 | LoadSettings(false); | ||
| 96 | return features_per_id_disabled; | ||
| 97 | } | ||
| 98 | |||
| 99 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/hid_firmware_settings.h b/src/core/hle/service/hid/hid_firmware_settings.h new file mode 100644 index 000000000..6c10c440b --- /dev/null +++ b/src/core/hle/service/hid/hid_firmware_settings.h | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_types.h" | ||
| 7 | |||
| 8 | namespace Service::HID { | ||
| 9 | |||
| 10 | /// Loads firmware config from nn::settings::fwdbg | ||
| 11 | class HidFirmwareSettings { | ||
| 12 | public: | ||
| 13 | using FirmwareSetting = std::array<u8, 4>; | ||
| 14 | using FeaturesPerId = std::array<bool, 0xA8>; | ||
| 15 | |||
| 16 | HidFirmwareSettings(); | ||
| 17 | |||
| 18 | void Reload(); | ||
| 19 | void LoadSettings(bool reload_config); | ||
| 20 | |||
| 21 | bool IsDebugPadEnabled(); | ||
| 22 | bool IsDeviceManaged(); | ||
| 23 | bool IsEmulateFutureDevice(); | ||
| 24 | bool IsTouchI2cManaged(); | ||
| 25 | bool IsHandheldForced(); | ||
| 26 | bool IsRailEnabled(); | ||
| 27 | bool IsHardwareErrorEmulated(); | ||
| 28 | bool IsBleDisabled(); | ||
| 29 | bool IsDscaleDisabled(); | ||
| 30 | bool IsTouchAutoUpdateDisabled(); | ||
| 31 | |||
| 32 | FirmwareSetting GetFirmwareUpdateFailure(); | ||
| 33 | FeaturesPerId FeaturesDisabledPerId(); | ||
| 34 | |||
| 35 | private: | ||
| 36 | bool is_initalized{}; | ||
| 37 | |||
| 38 | // Debug settings | ||
| 39 | bool is_debug_pad_enabled{}; | ||
| 40 | bool is_device_managed{}; | ||
| 41 | bool is_touch_i2c_managed{}; | ||
| 42 | bool is_future_devices_emulated{}; | ||
| 43 | bool is_mcu_hardware_error_emulated{}; | ||
| 44 | bool is_rail_enabled{}; | ||
| 45 | bool is_firmware_update_failure_emulated{}; | ||
| 46 | bool is_ble_disabled{}; | ||
| 47 | bool is_dscale_disabled{}; | ||
| 48 | bool is_handheld_forced{}; | ||
| 49 | bool is_touch_firmware_auto_update_disabled{}; | ||
| 50 | FirmwareSetting is_firmware_update_failure{}; | ||
| 51 | FeaturesPerId features_per_id_disabled{}; | ||
| 52 | }; | ||
| 53 | |||
| 54 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp new file mode 100644 index 000000000..583142e35 --- /dev/null +++ b/src/core/hle/service/hid/hid_server.cpp | |||
| @@ -0,0 +1,2371 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include <array> | ||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "common/settings.h" | ||
| 8 | #include "core/hid/hid_core.h" | ||
| 9 | #include "core/hle/kernel/k_shared_memory.h" | ||
| 10 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 11 | #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" | ||
| 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" | ||
| 18 | #include "core/memory.h" | ||
| 19 | |||
| 20 | #include "core/hle/service/hid/controllers/console_six_axis.h" | ||
| 21 | #include "core/hle/service/hid/controllers/controller_base.h" | ||
| 22 | #include "core/hle/service/hid/controllers/debug_pad.h" | ||
| 23 | #include "core/hle/service/hid/controllers/gesture.h" | ||
| 24 | #include "core/hle/service/hid/controllers/keyboard.h" | ||
| 25 | #include "core/hle/service/hid/controllers/mouse.h" | ||
| 26 | #include "core/hle/service/hid/controllers/npad.h" | ||
| 27 | #include "core/hle/service/hid/controllers/palma.h" | ||
| 28 | #include "core/hle/service/hid/controllers/seven_six_axis.h" | ||
| 29 | #include "core/hle/service/hid/controllers/six_axis.h" | ||
| 30 | #include "core/hle/service/hid/controllers/touchscreen.h" | ||
| 31 | |||
| 32 | namespace Service::HID { | ||
| 33 | |||
| 34 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { | ||
| 35 | public: | ||
| 36 | explicit IActiveVibrationDeviceList(Core::System& system_, | ||
| 37 | std::shared_ptr<ResourceManager> resource) | ||
| 38 | : ServiceFramework{system_, "IActiveVibrationDeviceList"}, resource_manager(resource) { | ||
| 39 | // clang-format off | ||
| 40 | static const FunctionInfo functions[] = { | ||
| 41 | {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"}, | ||
| 42 | }; | ||
| 43 | // clang-format on | ||
| 44 | |||
| 45 | RegisterHandlers(functions); | ||
| 46 | } | ||
| 47 | |||
| 48 | private: | ||
| 49 | void InitializeVibrationDevice(HLERequestContext& ctx) { | ||
| 50 | IPC::RequestParser rp{ctx}; | ||
| 51 | const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; | ||
| 52 | |||
| 53 | if (resource_manager != nullptr) { | ||
| 54 | resource_manager->GetNpad()->InitializeVibrationDevice(vibration_device_handle); | ||
| 55 | } | ||
| 56 | |||
| 57 | LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}", | ||
| 58 | vibration_device_handle.npad_type, vibration_device_handle.npad_id, | ||
| 59 | vibration_device_handle.device_index); | ||
| 60 | |||
| 61 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 62 | rb.Push(ResultSuccess); | ||
| 63 | } | ||
| 64 | |||
| 65 | std::shared_ptr<ResourceManager> resource_manager; | ||
| 66 | }; | ||
| 67 | |||
| 68 | IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource, | ||
| 69 | std::shared_ptr<HidFirmwareSettings> settings) | ||
| 70 | : ServiceFramework{system_, "hid"}, resource_manager{resource}, firmware_settings{settings} { | ||
| 71 | // clang-format off | ||
| 72 | static const FunctionInfo functions[] = { | ||
| 73 | {0, &IHidServer::CreateAppletResource, "CreateAppletResource"}, | ||
| 74 | {1, &IHidServer::ActivateDebugPad, "ActivateDebugPad"}, | ||
| 75 | {11, &IHidServer::ActivateTouchScreen, "ActivateTouchScreen"}, | ||
| 76 | {21, &IHidServer::ActivateMouse, "ActivateMouse"}, | ||
| 77 | {26, nullptr, "ActivateDebugMouse"}, | ||
| 78 | {31, &IHidServer::ActivateKeyboard, "ActivateKeyboard"}, | ||
| 79 | {32, &IHidServer::SendKeyboardLockKeyEvent, "SendKeyboardLockKeyEvent"}, | ||
| 80 | {40, &IHidServer::AcquireXpadIdEventHandle, "AcquireXpadIdEventHandle"}, | ||
| 81 | {41, &IHidServer::ReleaseXpadIdEventHandle, "ReleaseXpadIdEventHandle"}, | ||
| 82 | {51, &IHidServer::ActivateXpad, "ActivateXpad"}, | ||
| 83 | {55, &IHidServer::GetXpadIds, "GetXpadIds"}, | ||
| 84 | {56, &IHidServer::ActivateJoyXpad, "ActivateJoyXpad"}, | ||
| 85 | {58, &IHidServer::GetJoyXpadLifoHandle, "GetJoyXpadLifoHandle"}, | ||
| 86 | {59, &IHidServer::GetJoyXpadIds, "GetJoyXpadIds"}, | ||
| 87 | {60, &IHidServer::ActivateSixAxisSensor, "ActivateSixAxisSensor"}, | ||
| 88 | {61, &IHidServer::DeactivateSixAxisSensor, "DeactivateSixAxisSensor"}, | ||
| 89 | {62, &IHidServer::GetSixAxisSensorLifoHandle, "GetSixAxisSensorLifoHandle"}, | ||
| 90 | {63, &IHidServer::ActivateJoySixAxisSensor, "ActivateJoySixAxisSensor"}, | ||
| 91 | {64, &IHidServer::DeactivateJoySixAxisSensor, "DeactivateJoySixAxisSensor"}, | ||
| 92 | {65, &IHidServer::GetJoySixAxisSensorLifoHandle, "GetJoySixAxisSensorLifoHandle"}, | ||
| 93 | {66, &IHidServer::StartSixAxisSensor, "StartSixAxisSensor"}, | ||
| 94 | {67, &IHidServer::StopSixAxisSensor, "StopSixAxisSensor"}, | ||
| 95 | {68, &IHidServer::IsSixAxisSensorFusionEnabled, "IsSixAxisSensorFusionEnabled"}, | ||
| 96 | {69, &IHidServer::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"}, | ||
| 97 | {70, &IHidServer::SetSixAxisSensorFusionParameters, "SetSixAxisSensorFusionParameters"}, | ||
| 98 | {71, &IHidServer::GetSixAxisSensorFusionParameters, "GetSixAxisSensorFusionParameters"}, | ||
| 99 | {72, &IHidServer::ResetSixAxisSensorFusionParameters, "ResetSixAxisSensorFusionParameters"}, | ||
| 100 | {73, nullptr, "SetAccelerometerParameters"}, | ||
| 101 | {74, nullptr, "GetAccelerometerParameters"}, | ||
| 102 | {75, nullptr, "ResetAccelerometerParameters"}, | ||
| 103 | {76, nullptr, "SetAccelerometerPlayMode"}, | ||
| 104 | {77, nullptr, "GetAccelerometerPlayMode"}, | ||
| 105 | {78, nullptr, "ResetAccelerometerPlayMode"}, | ||
| 106 | {79, &IHidServer::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"}, | ||
| 107 | {80, &IHidServer::GetGyroscopeZeroDriftMode, "GetGyroscopeZeroDriftMode"}, | ||
| 108 | {81, &IHidServer::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"}, | ||
| 109 | {82, &IHidServer::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"}, | ||
| 110 | {83, &IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"}, | ||
| 111 | {84, &IHidServer::EnableSixAxisSensorUnalteredPassthrough, "EnableSixAxisSensorUnalteredPassthrough"}, | ||
| 112 | {85, &IHidServer::IsSixAxisSensorUnalteredPassthroughEnabled, "IsSixAxisSensorUnalteredPassthroughEnabled"}, | ||
| 113 | {86, nullptr, "StoreSixAxisSensorCalibrationParameter"}, | ||
| 114 | {87, &IHidServer::LoadSixAxisSensorCalibrationParameter, "LoadSixAxisSensorCalibrationParameter"}, | ||
| 115 | {88, &IHidServer::GetSixAxisSensorIcInformation, "GetSixAxisSensorIcInformation"}, | ||
| 116 | {89, &IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned, "ResetIsSixAxisSensorDeviceNewlyAssigned"}, | ||
| 117 | {91, &IHidServer::ActivateGesture, "ActivateGesture"}, | ||
| 118 | {100, &IHidServer::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, | ||
| 119 | {101, &IHidServer::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"}, | ||
| 120 | {102, &IHidServer::SetSupportedNpadIdType, "SetSupportedNpadIdType"}, | ||
| 121 | {103, &IHidServer::ActivateNpad, "ActivateNpad"}, | ||
| 122 | {104, &IHidServer::DeactivateNpad, "DeactivateNpad"}, | ||
| 123 | {106, &IHidServer::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"}, | ||
| 124 | {107, &IHidServer::DisconnectNpad, "DisconnectNpad"}, | ||
| 125 | {108, &IHidServer::GetPlayerLedPattern, "GetPlayerLedPattern"}, | ||
| 126 | {109, &IHidServer::ActivateNpadWithRevision, "ActivateNpadWithRevision"}, | ||
| 127 | {120, &IHidServer::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, | ||
| 128 | {121, &IHidServer::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, | ||
| 129 | {122, &IHidServer::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, | ||
| 130 | {123, &IHidServer::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"}, | ||
| 131 | {124, &IHidServer::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, | ||
| 132 | {125, &IHidServer::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, | ||
| 133 | {126, &IHidServer::StartLrAssignmentMode, "StartLrAssignmentMode"}, | ||
| 134 | {127, &IHidServer::StopLrAssignmentMode, "StopLrAssignmentMode"}, | ||
| 135 | {128, &IHidServer::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, | ||
| 136 | {129, &IHidServer::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"}, | ||
| 137 | {130, &IHidServer::SwapNpadAssignment, "SwapNpadAssignment"}, | ||
| 138 | {131, &IHidServer::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"}, | ||
| 139 | {132, &IHidServer::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, | ||
| 140 | {133, &IHidServer::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"}, | ||
| 141 | {134, &IHidServer::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"}, | ||
| 142 | {135, &IHidServer::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"}, | ||
| 143 | {136, &IHidServer::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"}, | ||
| 144 | {200, &IHidServer::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, | ||
| 145 | {201, &IHidServer::SendVibrationValue, "SendVibrationValue"}, | ||
| 146 | {202, &IHidServer::GetActualVibrationValue, "GetActualVibrationValue"}, | ||
| 147 | {203, &IHidServer::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"}, | ||
| 148 | {204, &IHidServer::PermitVibration, "PermitVibration"}, | ||
| 149 | {205, &IHidServer::IsVibrationPermitted, "IsVibrationPermitted"}, | ||
| 150 | {206, &IHidServer::SendVibrationValues, "SendVibrationValues"}, | ||
| 151 | {207, &IHidServer::SendVibrationGcErmCommand, "SendVibrationGcErmCommand"}, | ||
| 152 | {208, &IHidServer::GetActualVibrationGcErmCommand, "GetActualVibrationGcErmCommand"}, | ||
| 153 | {209, &IHidServer::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, | ||
| 154 | {210, &IHidServer::EndPermitVibrationSession, "EndPermitVibrationSession"}, | ||
| 155 | {211, &IHidServer::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"}, | ||
| 156 | {212, nullptr, "SendVibrationValueInBool"}, | ||
| 157 | {300, &IHidServer::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"}, | ||
| 158 | {301, &IHidServer::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"}, | ||
| 159 | {302, &IHidServer::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"}, | ||
| 160 | {303, &IHidServer::ActivateSevenSixAxisSensor, "ActivateSevenSixAxisSensor"}, | ||
| 161 | {304, &IHidServer::StartSevenSixAxisSensor, "StartSevenSixAxisSensor"}, | ||
| 162 | {305, &IHidServer::StopSevenSixAxisSensor, "StopSevenSixAxisSensor"}, | ||
| 163 | {306, &IHidServer::InitializeSevenSixAxisSensor, "InitializeSevenSixAxisSensor"}, | ||
| 164 | {307, &IHidServer::FinalizeSevenSixAxisSensor, "FinalizeSevenSixAxisSensor"}, | ||
| 165 | {308, nullptr, "SetSevenSixAxisSensorFusionStrength"}, | ||
| 166 | {309, nullptr, "GetSevenSixAxisSensorFusionStrength"}, | ||
| 167 | {310, &IHidServer::ResetSevenSixAxisSensorTimestamp, "ResetSevenSixAxisSensorTimestamp"}, | ||
| 168 | {400, &IHidServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"}, | ||
| 169 | {401, nullptr, "EnableUsbFullKeyController"}, | ||
| 170 | {402, nullptr, "IsUsbFullKeyControllerConnected"}, | ||
| 171 | {403, nullptr, "HasBattery"}, | ||
| 172 | {404, nullptr, "HasLeftRightBattery"}, | ||
| 173 | {405, nullptr, "GetNpadInterfaceType"}, | ||
| 174 | {406, nullptr, "GetNpadLeftRightInterfaceType"}, | ||
| 175 | {407, nullptr, "GetNpadOfHighestBatteryLevel"}, | ||
| 176 | {408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"}, | ||
| 177 | {500, &IHidServer::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"}, | ||
| 178 | {501, &IHidServer::InitializePalma, "InitializePalma"}, | ||
| 179 | {502, &IHidServer::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"}, | ||
| 180 | {503, &IHidServer::GetPalmaOperationInfo, "GetPalmaOperationInfo"}, | ||
| 181 | {504, &IHidServer::PlayPalmaActivity, "PlayPalmaActivity"}, | ||
| 182 | {505, &IHidServer::SetPalmaFrModeType, "SetPalmaFrModeType"}, | ||
| 183 | {506, &IHidServer::ReadPalmaStep, "ReadPalmaStep"}, | ||
| 184 | {507, &IHidServer::EnablePalmaStep, "EnablePalmaStep"}, | ||
| 185 | {508, &IHidServer::ResetPalmaStep, "ResetPalmaStep"}, | ||
| 186 | {509, &IHidServer::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"}, | ||
| 187 | {510, &IHidServer::WritePalmaApplicationSection, "WritePalmaApplicationSection"}, | ||
| 188 | {511, &IHidServer::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"}, | ||
| 189 | {512, &IHidServer::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"}, | ||
| 190 | {513, &IHidServer::WritePalmaActivityEntry, "WritePalmaActivityEntry"}, | ||
| 191 | {514, &IHidServer::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"}, | ||
| 192 | {515, &IHidServer::WritePalmaWaveEntry, "WritePalmaWaveEntry"}, | ||
| 193 | {516, &IHidServer::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"}, | ||
| 194 | {517, &IHidServer::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"}, | ||
| 195 | {518, &IHidServer::SuspendPalmaFeature, "SuspendPalmaFeature"}, | ||
| 196 | {519, &IHidServer::GetPalmaOperationResult, "GetPalmaOperationResult"}, | ||
| 197 | {520, &IHidServer::ReadPalmaPlayLog, "ReadPalmaPlayLog"}, | ||
| 198 | {521, &IHidServer::ResetPalmaPlayLog, "ResetPalmaPlayLog"}, | ||
| 199 | {522, &IHidServer::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"}, | ||
| 200 | {523, &IHidServer::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"}, | ||
| 201 | {524, &IHidServer::PairPalma, "PairPalma"}, | ||
| 202 | {525, &IHidServer::SetPalmaBoostMode, "SetPalmaBoostMode"}, | ||
| 203 | {526, &IHidServer::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"}, | ||
| 204 | {527, &IHidServer::EnablePalmaBoostMode, "EnablePalmaBoostMode"}, | ||
| 205 | {528, &IHidServer::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"}, | ||
| 206 | {529, &IHidServer::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"}, | ||
| 207 | {1000, &IHidServer::SetNpadCommunicationMode, "SetNpadCommunicationMode"}, | ||
| 208 | {1001, &IHidServer::GetNpadCommunicationMode, "GetNpadCommunicationMode"}, | ||
| 209 | {1002, &IHidServer::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"}, | ||
| 210 | {1003, &IHidServer::IsFirmwareUpdateNeededForNotification, "IsFirmwareUpdateNeededForNotification"}, | ||
| 211 | {2000, nullptr, "ActivateDigitizer"}, | ||
| 212 | }; | ||
| 213 | // clang-format on | ||
| 214 | |||
| 215 | RegisterHandlers(functions); | ||
| 216 | } | ||
| 217 | |||
| 218 | IHidServer::~IHidServer() = default; | ||
| 219 | |||
| 220 | void IHidServer::CreateAppletResource(HLERequestContext& ctx) { | ||
| 221 | IPC::RequestParser rp{ctx}; | ||
| 222 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 223 | |||
| 224 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 225 | |||
| 226 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 227 | rb.Push(ResultSuccess); | ||
| 228 | rb.PushIpcInterface<IAppletResource>(system, resource_manager); | ||
| 229 | } | ||
| 230 | |||
| 231 | void IHidServer::ActivateDebugPad(HLERequestContext& ctx) { | ||
| 232 | IPC::RequestParser rp{ctx}; | ||
| 233 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 234 | |||
| 235 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 236 | |||
| 237 | Result result = ResultSuccess; | ||
| 238 | auto debug_pad = GetResourceManager()->GetDebugPad(); | ||
| 239 | |||
| 240 | if (!firmware_settings->IsDeviceManaged()) { | ||
| 241 | result = debug_pad->Activate(); | ||
| 242 | } | ||
| 243 | |||
| 244 | if (result.IsSuccess()) { | ||
| 245 | result = debug_pad->Activate(applet_resource_user_id); | ||
| 246 | } | ||
| 247 | |||
| 248 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 249 | rb.Push(result); | ||
| 250 | } | ||
| 251 | |||
| 252 | void IHidServer::ActivateTouchScreen(HLERequestContext& ctx) { | ||
| 253 | IPC::RequestParser rp{ctx}; | ||
| 254 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 255 | |||
| 256 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 257 | |||
| 258 | Result result = ResultSuccess; | ||
| 259 | auto touch_screen = GetResourceManager()->GetTouchScreen(); | ||
| 260 | |||
| 261 | if (!firmware_settings->IsDeviceManaged()) { | ||
| 262 | result = touch_screen->Activate(); | ||
| 263 | } | ||
| 264 | |||
| 265 | if (result.IsSuccess()) { | ||
| 266 | result = touch_screen->Activate(applet_resource_user_id); | ||
| 267 | } | ||
| 268 | |||
| 269 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 270 | rb.Push(result); | ||
| 271 | } | ||
| 272 | |||
| 273 | void IHidServer::ActivateMouse(HLERequestContext& ctx) { | ||
| 274 | IPC::RequestParser rp{ctx}; | ||
| 275 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 276 | |||
| 277 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 278 | |||
| 279 | Result result = ResultSuccess; | ||
| 280 | auto mouse = GetResourceManager()->GetMouse(); | ||
| 281 | |||
| 282 | if (!firmware_settings->IsDeviceManaged()) { | ||
| 283 | result = mouse->Activate(); | ||
| 284 | } | ||
| 285 | |||
| 286 | if (result.IsSuccess()) { | ||
| 287 | result = mouse->Activate(applet_resource_user_id); | ||
| 288 | } | ||
| 289 | |||
| 290 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 291 | rb.Push(result); | ||
| 292 | } | ||
| 293 | |||
| 294 | void IHidServer::ActivateKeyboard(HLERequestContext& ctx) { | ||
| 295 | IPC::RequestParser rp{ctx}; | ||
| 296 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 297 | |||
| 298 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 299 | |||
| 300 | Result result = ResultSuccess; | ||
| 301 | auto keyboard = GetResourceManager()->GetKeyboard(); | ||
| 302 | |||
| 303 | if (!firmware_settings->IsDeviceManaged()) { | ||
| 304 | result = keyboard->Activate(); | ||
| 305 | } | ||
| 306 | |||
| 307 | if (result.IsSuccess()) { | ||
| 308 | result = keyboard->Activate(applet_resource_user_id); | ||
| 309 | } | ||
| 310 | |||
| 311 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 312 | rb.Push(result); | ||
| 313 | } | ||
| 314 | |||
| 315 | void IHidServer::SendKeyboardLockKeyEvent(HLERequestContext& ctx) { | ||
| 316 | IPC::RequestParser rp{ctx}; | ||
| 317 | const auto flags{rp.Pop<u32>()}; | ||
| 318 | |||
| 319 | LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags); | ||
| 320 | |||
| 321 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 322 | rb.Push(ResultSuccess); | ||
| 323 | } | ||
| 324 | |||
| 325 | void IHidServer::AcquireXpadIdEventHandle(HLERequestContext& ctx) { | ||
| 326 | IPC::RequestParser rp{ctx}; | ||
| 327 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 328 | |||
| 329 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 330 | |||
| 331 | // This function has been stubbed since 10.0.0+ | ||
| 332 | |||
| 333 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 334 | rb.Push(ResultSuccess); | ||
| 335 | // Handle returned is null here | ||
| 336 | } | ||
| 337 | |||
| 338 | void IHidServer::ReleaseXpadIdEventHandle(HLERequestContext& ctx) { | ||
| 339 | IPC::RequestParser rp{ctx}; | ||
| 340 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 341 | |||
| 342 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 343 | |||
| 344 | // This function has been stubbed since 10.0.0+ | ||
| 345 | |||
| 346 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 347 | rb.Push(ResultSuccess); | ||
| 348 | } | ||
| 349 | |||
| 350 | void IHidServer::ActivateXpad(HLERequestContext& ctx) { | ||
| 351 | IPC::RequestParser rp{ctx}; | ||
| 352 | struct Parameters { | ||
| 353 | u32 basic_xpad_id; | ||
| 354 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 355 | u64 applet_resource_user_id; | ||
| 356 | }; | ||
| 357 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 358 | |||
| 359 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 360 | |||
| 361 | LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", | ||
| 362 | parameters.basic_xpad_id, parameters.applet_resource_user_id); | ||
| 363 | |||
| 364 | // This function has been stubbed since 10.0.0+ | ||
| 365 | |||
| 366 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 367 | rb.Push(ResultSuccess); | ||
| 368 | } | ||
| 369 | |||
| 370 | void IHidServer::GetXpadIds(HLERequestContext& ctx) { | ||
| 371 | LOG_DEBUG(Service_HID, "called"); | ||
| 372 | |||
| 373 | // This function has been hardcoded since 10.0.0+ | ||
| 374 | const std::array<u32, 4> basic_xpad_id{0, 1, 2, 3}; | ||
| 375 | ctx.WriteBuffer(basic_xpad_id); | ||
| 376 | |||
| 377 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 378 | rb.Push(ResultSuccess); | ||
| 379 | rb.Push<s64>(basic_xpad_id.size()); | ||
| 380 | } | ||
| 381 | |||
| 382 | void IHidServer::ActivateJoyXpad(HLERequestContext& ctx) { | ||
| 383 | IPC::RequestParser rp{ctx}; | ||
| 384 | const auto joy_xpad_id{rp.Pop<u32>()}; | ||
| 385 | |||
| 386 | LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id); | ||
| 387 | |||
| 388 | // This function has been stubbed since 10.0.0+ | ||
| 389 | |||
| 390 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 391 | rb.Push(ResultSuccess); | ||
| 392 | } | ||
| 393 | |||
| 394 | void IHidServer::GetJoyXpadLifoHandle(HLERequestContext& ctx) { | ||
| 395 | IPC::RequestParser rp{ctx}; | ||
| 396 | const auto joy_xpad_id{rp.Pop<u32>()}; | ||
| 397 | |||
| 398 | LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id); | ||
| 399 | |||
| 400 | // This function has been stubbed since 10.0.0+ | ||
| 401 | |||
| 402 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 403 | rb.Push(ResultSuccess); | ||
| 404 | // Handle returned is null here | ||
| 405 | } | ||
| 406 | |||
| 407 | void IHidServer::GetJoyXpadIds(HLERequestContext& ctx) { | ||
| 408 | LOG_DEBUG(Service_HID, "called"); | ||
| 409 | |||
| 410 | // This function has been hardcoded since 10.0.0+ | ||
| 411 | const s64 basic_xpad_id_count{}; | ||
| 412 | |||
| 413 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 414 | rb.Push(ResultSuccess); | ||
| 415 | rb.Push(basic_xpad_id_count); | ||
| 416 | } | ||
| 417 | |||
| 418 | void IHidServer::ActivateSixAxisSensor(HLERequestContext& ctx) { | ||
| 419 | IPC::RequestParser rp{ctx}; | ||
| 420 | const auto joy_xpad_id{rp.Pop<u32>()}; | ||
| 421 | |||
| 422 | LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id); | ||
| 423 | |||
| 424 | // This function has been stubbed since 10.0.0+ | ||
| 425 | |||
| 426 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 427 | rb.Push(ResultSuccess); | ||
| 428 | } | ||
| 429 | |||
| 430 | void IHidServer::DeactivateSixAxisSensor(HLERequestContext& ctx) { | ||
| 431 | IPC::RequestParser rp{ctx}; | ||
| 432 | const auto joy_xpad_id{rp.Pop<u32>()}; | ||
| 433 | |||
| 434 | LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id); | ||
| 435 | |||
| 436 | // This function has been stubbed since 10.0.0+ | ||
| 437 | |||
| 438 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 439 | rb.Push(ResultSuccess); | ||
| 440 | } | ||
| 441 | |||
| 442 | void IHidServer::GetSixAxisSensorLifoHandle(HLERequestContext& ctx) { | ||
| 443 | IPC::RequestParser rp{ctx}; | ||
| 444 | const auto joy_xpad_id{rp.Pop<u32>()}; | ||
| 445 | |||
| 446 | LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id); | ||
| 447 | |||
| 448 | // This function has been stubbed since 10.0.0+ | ||
| 449 | |||
| 450 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 451 | rb.Push(ResultSuccess); | ||
| 452 | } | ||
| 453 | |||
| 454 | void IHidServer::ActivateJoySixAxisSensor(HLERequestContext& ctx) { | ||
| 455 | IPC::RequestParser rp{ctx}; | ||
| 456 | const auto joy_xpad_id{rp.Pop<u32>()}; | ||
| 457 | |||
| 458 | LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id); | ||
| 459 | |||
| 460 | // This function has been stubbed since 10.0.0+ | ||
| 461 | |||
| 462 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 463 | rb.Push(ResultSuccess); | ||
| 464 | } | ||
| 465 | |||
| 466 | void IHidServer::DeactivateJoySixAxisSensor(HLERequestContext& ctx) { | ||
| 467 | IPC::RequestParser rp{ctx}; | ||
| 468 | const auto joy_xpad_id{rp.Pop<u32>()}; | ||
| 469 | |||
| 470 | LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id); | ||
| 471 | |||
| 472 | // This function has been stubbed since 10.0.0+ | ||
| 473 | |||
| 474 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 475 | rb.Push(ResultSuccess); | ||
| 476 | } | ||
| 477 | |||
| 478 | void IHidServer::GetJoySixAxisSensorLifoHandle(HLERequestContext& ctx) { | ||
| 479 | IPC::RequestParser rp{ctx}; | ||
| 480 | const auto joy_xpad_id{rp.Pop<u32>()}; | ||
| 481 | |||
| 482 | LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id); | ||
| 483 | |||
| 484 | // This function has been stubbed since 10.0.0+ | ||
| 485 | |||
| 486 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 487 | rb.Push(ResultSuccess); | ||
| 488 | // Handle returned is null here | ||
| 489 | } | ||
| 490 | |||
| 491 | void IHidServer::StartSixAxisSensor(HLERequestContext& ctx) { | ||
| 492 | IPC::RequestParser rp{ctx}; | ||
| 493 | struct Parameters { | ||
| 494 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 495 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 496 | u64 applet_resource_user_id; | ||
| 497 | }; | ||
| 498 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 499 | |||
| 500 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 501 | |||
| 502 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 503 | const auto result = six_axis->SetSixAxisEnabled(parameters.sixaxis_handle, true); | ||
| 504 | |||
| 505 | LOG_DEBUG(Service_HID, | ||
| 506 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 507 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 508 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 509 | |||
| 510 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 511 | rb.Push(result); | ||
| 512 | } | ||
| 513 | |||
| 514 | void IHidServer::StopSixAxisSensor(HLERequestContext& ctx) { | ||
| 515 | IPC::RequestParser rp{ctx}; | ||
| 516 | struct Parameters { | ||
| 517 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 518 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 519 | u64 applet_resource_user_id; | ||
| 520 | }; | ||
| 521 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 522 | |||
| 523 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 524 | |||
| 525 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 526 | const auto result = six_axis->SetSixAxisEnabled(parameters.sixaxis_handle, false); | ||
| 527 | |||
| 528 | LOG_DEBUG(Service_HID, | ||
| 529 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 530 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 531 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 532 | |||
| 533 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 534 | rb.Push(result); | ||
| 535 | } | ||
| 536 | |||
| 537 | void IHidServer::IsSixAxisSensorFusionEnabled(HLERequestContext& ctx) { | ||
| 538 | IPC::RequestParser rp{ctx}; | ||
| 539 | struct Parameters { | ||
| 540 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 541 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 542 | u64 applet_resource_user_id; | ||
| 543 | }; | ||
| 544 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 545 | |||
| 546 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 547 | |||
| 548 | bool is_enabled{}; | ||
| 549 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 550 | const auto result = | ||
| 551 | six_axis->IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled); | ||
| 552 | |||
| 553 | LOG_DEBUG(Service_HID, | ||
| 554 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 555 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 556 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 557 | |||
| 558 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 559 | rb.Push(result); | ||
| 560 | rb.Push(is_enabled); | ||
| 561 | } | ||
| 562 | |||
| 563 | void IHidServer::EnableSixAxisSensorFusion(HLERequestContext& ctx) { | ||
| 564 | IPC::RequestParser rp{ctx}; | ||
| 565 | struct Parameters { | ||
| 566 | bool enable_sixaxis_sensor_fusion; | ||
| 567 | INSERT_PADDING_BYTES_NOINIT(3); | ||
| 568 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 569 | u64 applet_resource_user_id; | ||
| 570 | }; | ||
| 571 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 572 | |||
| 573 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 574 | |||
| 575 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 576 | const auto result = six_axis->SetSixAxisFusionEnabled(parameters.sixaxis_handle, | ||
| 577 | parameters.enable_sixaxis_sensor_fusion); | ||
| 578 | |||
| 579 | LOG_DEBUG(Service_HID, | ||
| 580 | "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, " | ||
| 581 | "device_index={}, applet_resource_user_id={}", | ||
| 582 | parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type, | ||
| 583 | parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index, | ||
| 584 | parameters.applet_resource_user_id); | ||
| 585 | |||
| 586 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 587 | rb.Push(result); | ||
| 588 | } | ||
| 589 | |||
| 590 | void IHidServer::SetSixAxisSensorFusionParameters(HLERequestContext& ctx) { | ||
| 591 | IPC::RequestParser rp{ctx}; | ||
| 592 | struct Parameters { | ||
| 593 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 594 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion; | ||
| 595 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 596 | u64 applet_resource_user_id; | ||
| 597 | }; | ||
| 598 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 599 | |||
| 600 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 601 | |||
| 602 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 603 | const auto result = | ||
| 604 | six_axis->SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion); | ||
| 605 | |||
| 606 | LOG_DEBUG(Service_HID, | ||
| 607 | "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, " | ||
| 608 | "parameter2={}, applet_resource_user_id={}", | ||
| 609 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 610 | parameters.sixaxis_handle.device_index, parameters.sixaxis_fusion.parameter1, | ||
| 611 | parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id); | ||
| 612 | |||
| 613 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 614 | rb.Push(result); | ||
| 615 | } | ||
| 616 | |||
| 617 | void IHidServer::GetSixAxisSensorFusionParameters(HLERequestContext& ctx) { | ||
| 618 | IPC::RequestParser rp{ctx}; | ||
| 619 | struct Parameters { | ||
| 620 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 621 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 622 | u64 applet_resource_user_id; | ||
| 623 | }; | ||
| 624 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 625 | |||
| 626 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 627 | |||
| 628 | Core::HID::SixAxisSensorFusionParameters fusion_parameters{}; | ||
| 629 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 630 | const auto result = | ||
| 631 | six_axis->GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters); | ||
| 632 | |||
| 633 | LOG_DEBUG(Service_HID, | ||
| 634 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 635 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 636 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 637 | |||
| 638 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 639 | rb.Push(result); | ||
| 640 | rb.PushRaw(fusion_parameters); | ||
| 641 | } | ||
| 642 | |||
| 643 | void IHidServer::ResetSixAxisSensorFusionParameters(HLERequestContext& ctx) { | ||
| 644 | IPC::RequestParser rp{ctx}; | ||
| 645 | struct Parameters { | ||
| 646 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 647 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 648 | u64 applet_resource_user_id; | ||
| 649 | }; | ||
| 650 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 651 | |||
| 652 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 653 | |||
| 654 | // Since these parameters are unknown just use what HW outputs | ||
| 655 | const Core::HID::SixAxisSensorFusionParameters fusion_parameters{ | ||
| 656 | .parameter1 = 0.03f, | ||
| 657 | .parameter2 = 0.4f, | ||
| 658 | }; | ||
| 659 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 660 | const auto result1 = | ||
| 661 | six_axis->SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters); | ||
| 662 | const auto result2 = six_axis->SetSixAxisFusionEnabled(parameters.sixaxis_handle, true); | ||
| 663 | |||
| 664 | LOG_DEBUG(Service_HID, | ||
| 665 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 666 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 667 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 668 | |||
| 669 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 670 | if (result1.IsError()) { | ||
| 671 | rb.Push(result1); | ||
| 672 | return; | ||
| 673 | } | ||
| 674 | rb.Push(result2); | ||
| 675 | } | ||
| 676 | |||
| 677 | void IHidServer::SetGyroscopeZeroDriftMode(HLERequestContext& ctx) { | ||
| 678 | IPC::RequestParser rp{ctx}; | ||
| 679 | const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()}; | ||
| 680 | const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()}; | ||
| 681 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 682 | |||
| 683 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 684 | const auto result = six_axis->SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode); | ||
| 685 | |||
| 686 | LOG_DEBUG(Service_HID, | ||
| 687 | "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, " | ||
| 688 | "applet_resource_user_id={}", | ||
| 689 | sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index, | ||
| 690 | drift_mode, applet_resource_user_id); | ||
| 691 | |||
| 692 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 693 | rb.Push(result); | ||
| 694 | } | ||
| 695 | |||
| 696 | void IHidServer::GetGyroscopeZeroDriftMode(HLERequestContext& ctx) { | ||
| 697 | IPC::RequestParser rp{ctx}; | ||
| 698 | struct Parameters { | ||
| 699 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 700 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 701 | u64 applet_resource_user_id; | ||
| 702 | }; | ||
| 703 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 704 | |||
| 705 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 706 | |||
| 707 | auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard}; | ||
| 708 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 709 | const auto result = six_axis->GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); | ||
| 710 | |||
| 711 | LOG_DEBUG(Service_HID, | ||
| 712 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 713 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 714 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 715 | |||
| 716 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 717 | rb.Push(result); | ||
| 718 | rb.PushEnum(drift_mode); | ||
| 719 | } | ||
| 720 | |||
| 721 | void IHidServer::ResetGyroscopeZeroDriftMode(HLERequestContext& ctx) { | ||
| 722 | IPC::RequestParser rp{ctx}; | ||
| 723 | struct Parameters { | ||
| 724 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 725 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 726 | u64 applet_resource_user_id; | ||
| 727 | }; | ||
| 728 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 729 | |||
| 730 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 731 | |||
| 732 | const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard}; | ||
| 733 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 734 | const auto result = six_axis->SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); | ||
| 735 | |||
| 736 | LOG_DEBUG(Service_HID, | ||
| 737 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 738 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 739 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 740 | |||
| 741 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 742 | rb.Push(result); | ||
| 743 | } | ||
| 744 | |||
| 745 | void IHidServer::IsSixAxisSensorAtRest(HLERequestContext& ctx) { | ||
| 746 | IPC::RequestParser rp{ctx}; | ||
| 747 | struct Parameters { | ||
| 748 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 749 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 750 | u64 applet_resource_user_id; | ||
| 751 | }; | ||
| 752 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 753 | |||
| 754 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 755 | |||
| 756 | bool is_at_rest{}; | ||
| 757 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 758 | six_axis->IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest); | ||
| 759 | |||
| 760 | LOG_DEBUG(Service_HID, | ||
| 761 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 762 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 763 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 764 | |||
| 765 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 766 | rb.Push(ResultSuccess); | ||
| 767 | rb.Push(is_at_rest); | ||
| 768 | } | ||
| 769 | |||
| 770 | void IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx) { | ||
| 771 | IPC::RequestParser rp{ctx}; | ||
| 772 | struct Parameters { | ||
| 773 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 774 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 775 | u64 applet_resource_user_id; | ||
| 776 | }; | ||
| 777 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 778 | |||
| 779 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 780 | |||
| 781 | bool is_firmware_available{}; | ||
| 782 | auto controller = GetResourceManager()->GetNpad(); | ||
| 783 | controller->IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle, | ||
| 784 | is_firmware_available); | ||
| 785 | |||
| 786 | LOG_WARNING( | ||
| 787 | Service_HID, | ||
| 788 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 789 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 790 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 791 | |||
| 792 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 793 | rb.Push(ResultSuccess); | ||
| 794 | rb.Push(is_firmware_available); | ||
| 795 | } | ||
| 796 | |||
| 797 | void IHidServer::EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx) { | ||
| 798 | IPC::RequestParser rp{ctx}; | ||
| 799 | struct Parameters { | ||
| 800 | bool enabled; | ||
| 801 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 802 | u64 applet_resource_user_id; | ||
| 803 | }; | ||
| 804 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 805 | |||
| 806 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 807 | |||
| 808 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 809 | const auto result = six_axis->EnableSixAxisSensorUnalteredPassthrough(parameters.sixaxis_handle, | ||
| 810 | parameters.enabled); | ||
| 811 | |||
| 812 | LOG_DEBUG(Service_HID, | ||
| 813 | "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, " | ||
| 814 | "applet_resource_user_id={}", | ||
| 815 | parameters.enabled, parameters.sixaxis_handle.npad_type, | ||
| 816 | parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index, | ||
| 817 | parameters.applet_resource_user_id); | ||
| 818 | |||
| 819 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 820 | rb.Push(result); | ||
| 821 | } | ||
| 822 | |||
| 823 | void IHidServer::IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx) { | ||
| 824 | IPC::RequestParser rp{ctx}; | ||
| 825 | struct Parameters { | ||
| 826 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 827 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 828 | u64 applet_resource_user_id; | ||
| 829 | }; | ||
| 830 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 831 | |||
| 832 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 833 | |||
| 834 | bool is_unaltered_sisxaxis_enabled{}; | ||
| 835 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 836 | const auto result = six_axis->IsSixAxisSensorUnalteredPassthroughEnabled( | ||
| 837 | parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled); | ||
| 838 | |||
| 839 | LOG_DEBUG( | ||
| 840 | Service_HID, | ||
| 841 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 842 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 843 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 844 | |||
| 845 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 846 | rb.Push(result); | ||
| 847 | rb.Push(is_unaltered_sisxaxis_enabled); | ||
| 848 | } | ||
| 849 | |||
| 850 | void IHidServer::LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx) { | ||
| 851 | IPC::RequestParser rp{ctx}; | ||
| 852 | struct Parameters { | ||
| 853 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 854 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 855 | u64 applet_resource_user_id; | ||
| 856 | }; | ||
| 857 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 858 | |||
| 859 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 860 | |||
| 861 | Core::HID::SixAxisSensorCalibrationParameter calibration{}; | ||
| 862 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 863 | const auto result = | ||
| 864 | six_axis->LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration); | ||
| 865 | |||
| 866 | LOG_WARNING( | ||
| 867 | Service_HID, | ||
| 868 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 869 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 870 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 871 | |||
| 872 | if (result.IsSuccess()) { | ||
| 873 | ctx.WriteBuffer(calibration); | ||
| 874 | } | ||
| 875 | |||
| 876 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 877 | rb.Push(result); | ||
| 878 | } | ||
| 879 | |||
| 880 | void IHidServer::GetSixAxisSensorIcInformation(HLERequestContext& ctx) { | ||
| 881 | IPC::RequestParser rp{ctx}; | ||
| 882 | struct Parameters { | ||
| 883 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 884 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 885 | u64 applet_resource_user_id; | ||
| 886 | }; | ||
| 887 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 888 | |||
| 889 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 890 | |||
| 891 | Core::HID::SixAxisSensorIcInformation ic_information{}; | ||
| 892 | auto six_axis = GetResourceManager()->GetSixAxis(); | ||
| 893 | const auto result = | ||
| 894 | six_axis->GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information); | ||
| 895 | |||
| 896 | LOG_WARNING( | ||
| 897 | Service_HID, | ||
| 898 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 899 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 900 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 901 | |||
| 902 | if (result.IsSuccess()) { | ||
| 903 | ctx.WriteBuffer(ic_information); | ||
| 904 | } | ||
| 905 | |||
| 906 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 907 | rb.Push(result); | ||
| 908 | } | ||
| 909 | |||
| 910 | void IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx) { | ||
| 911 | IPC::RequestParser rp{ctx}; | ||
| 912 | struct Parameters { | ||
| 913 | Core::HID::SixAxisSensorHandle sixaxis_handle; | ||
| 914 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 915 | u64 applet_resource_user_id; | ||
| 916 | }; | ||
| 917 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 918 | |||
| 919 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 920 | |||
| 921 | auto controller = GetResourceManager()->GetNpad(); | ||
| 922 | const auto result = | ||
| 923 | controller->ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle); | ||
| 924 | |||
| 925 | LOG_WARNING( | ||
| 926 | Service_HID, | ||
| 927 | "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 928 | parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, | ||
| 929 | parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); | ||
| 930 | |||
| 931 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 932 | rb.Push(result); | ||
| 933 | } | ||
| 934 | |||
| 935 | void IHidServer::ActivateGesture(HLERequestContext& ctx) { | ||
| 936 | IPC::RequestParser rp{ctx}; | ||
| 937 | struct Parameters { | ||
| 938 | u32 basic_gesture_id; | ||
| 939 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 940 | u64 applet_resource_user_id; | ||
| 941 | }; | ||
| 942 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 943 | |||
| 944 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 945 | |||
| 946 | LOG_INFO(Service_HID, "called, basic_gesture_id={}, applet_resource_user_id={}", | ||
| 947 | parameters.basic_gesture_id, parameters.applet_resource_user_id); | ||
| 948 | |||
| 949 | Result result = ResultSuccess; | ||
| 950 | auto gesture = GetResourceManager()->GetGesture(); | ||
| 951 | |||
| 952 | if (!firmware_settings->IsDeviceManaged()) { | ||
| 953 | result = gesture->Activate(); | ||
| 954 | } | ||
| 955 | |||
| 956 | if (result.IsSuccess()) { | ||
| 957 | // TODO: Use gesture id here | ||
| 958 | result = gesture->Activate(parameters.applet_resource_user_id); | ||
| 959 | } | ||
| 960 | |||
| 961 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 962 | rb.Push(result); | ||
| 963 | } | ||
| 964 | |||
| 965 | void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) { | ||
| 966 | IPC::RequestParser rp{ctx}; | ||
| 967 | struct Parameters { | ||
| 968 | Core::HID::NpadStyleSet supported_styleset; | ||
| 969 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 970 | u64 applet_resource_user_id; | ||
| 971 | }; | ||
| 972 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 973 | |||
| 974 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 975 | |||
| 976 | GetResourceManager()->GetNpad()->SetSupportedStyleSet({parameters.supported_styleset}); | ||
| 977 | |||
| 978 | LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}", | ||
| 979 | parameters.supported_styleset, parameters.applet_resource_user_id); | ||
| 980 | |||
| 981 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 982 | rb.Push(ResultSuccess); | ||
| 983 | } | ||
| 984 | |||
| 985 | void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) { | ||
| 986 | IPC::RequestParser rp{ctx}; | ||
| 987 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 988 | |||
| 989 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 990 | |||
| 991 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 992 | rb.Push(ResultSuccess); | ||
| 993 | rb.PushEnum(GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw); | ||
| 994 | } | ||
| 995 | |||
| 996 | void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) { | ||
| 997 | IPC::RequestParser rp{ctx}; | ||
| 998 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 999 | |||
| 1000 | const auto result = GetResourceManager()->GetNpad()->SetSupportedNpadIdTypes(ctx.ReadBuffer()); | ||
| 1001 | |||
| 1002 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1003 | |||
| 1004 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1005 | rb.Push(result); | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | void IHidServer::ActivateNpad(HLERequestContext& ctx) { | ||
| 1009 | IPC::RequestParser rp{ctx}; | ||
| 1010 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1011 | |||
| 1012 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1013 | |||
| 1014 | auto npad = GetResourceManager()->GetNpad(); | ||
| 1015 | |||
| 1016 | // TODO: npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0); | ||
| 1017 | const Result result = npad->Activate(applet_resource_user_id); | ||
| 1018 | |||
| 1019 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1020 | rb.Push(result); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | void IHidServer::DeactivateNpad(HLERequestContext& ctx) { | ||
| 1024 | IPC::RequestParser rp{ctx}; | ||
| 1025 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1026 | |||
| 1027 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1028 | |||
| 1029 | // This function does nothing since 10.0.0+ | ||
| 1030 | |||
| 1031 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1032 | rb.Push(ResultSuccess); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | void IHidServer::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) { | ||
| 1036 | IPC::RequestParser rp{ctx}; | ||
| 1037 | struct Parameters { | ||
| 1038 | Core::HID::NpadIdType npad_id; | ||
| 1039 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1040 | u64 applet_resource_user_id; | ||
| 1041 | u64 unknown; | ||
| 1042 | }; | ||
| 1043 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1044 | |||
| 1045 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1046 | |||
| 1047 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", | ||
| 1048 | parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown); | ||
| 1049 | |||
| 1050 | // Games expect this event to be signaled after calling this function | ||
| 1051 | GetResourceManager()->GetNpad()->SignalStyleSetChangedEvent(parameters.npad_id); | ||
| 1052 | |||
| 1053 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 1054 | rb.Push(ResultSuccess); | ||
| 1055 | rb.PushCopyObjects( | ||
| 1056 | GetResourceManager()->GetNpad()->GetStyleSetChangedEvent(parameters.npad_id)); | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | void IHidServer::DisconnectNpad(HLERequestContext& ctx) { | ||
| 1060 | IPC::RequestParser rp{ctx}; | ||
| 1061 | struct Parameters { | ||
| 1062 | Core::HID::NpadIdType npad_id; | ||
| 1063 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1064 | u64 applet_resource_user_id; | ||
| 1065 | }; | ||
| 1066 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1067 | |||
| 1068 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1069 | |||
| 1070 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1071 | controller->DisconnectNpad(parameters.npad_id); | ||
| 1072 | |||
| 1073 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||
| 1074 | parameters.applet_resource_user_id); | ||
| 1075 | |||
| 1076 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1077 | rb.Push(ResultSuccess); | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) { | ||
| 1081 | IPC::RequestParser rp{ctx}; | ||
| 1082 | const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1083 | |||
| 1084 | Core::HID::LedPattern pattern{0, 0, 0, 0}; | ||
| 1085 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1086 | const auto result = controller->GetLedPattern(npad_id, pattern); | ||
| 1087 | |||
| 1088 | LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id); | ||
| 1089 | |||
| 1090 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1091 | rb.Push(result); | ||
| 1092 | rb.Push(pattern.raw); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { | ||
| 1096 | IPC::RequestParser rp{ctx}; | ||
| 1097 | struct Parameters { | ||
| 1098 | NPad::NpadRevision revision; | ||
| 1099 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1100 | u64 applet_resource_user_id; | ||
| 1101 | }; | ||
| 1102 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1103 | |||
| 1104 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1105 | |||
| 1106 | LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision, | ||
| 1107 | parameters.applet_resource_user_id); | ||
| 1108 | |||
| 1109 | auto npad = GetResourceManager()->GetNpad(); | ||
| 1110 | |||
| 1111 | // TODO: npad->SetRevision(applet_resource_user_id, revision); | ||
| 1112 | const auto result = npad->Activate(parameters.applet_resource_user_id); | ||
| 1113 | |||
| 1114 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1115 | rb.Push(result); | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) { | ||
| 1119 | IPC::RequestParser rp{ctx}; | ||
| 1120 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1121 | const auto hold_type{rp.PopEnum<NPad::NpadJoyHoldType>()}; | ||
| 1122 | |||
| 1123 | GetResourceManager()->GetNpad()->SetHoldType(hold_type); | ||
| 1124 | |||
| 1125 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}", | ||
| 1126 | applet_resource_user_id, hold_type); | ||
| 1127 | |||
| 1128 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1129 | rb.Push(ResultSuccess); | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) { | ||
| 1133 | IPC::RequestParser rp{ctx}; | ||
| 1134 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1135 | |||
| 1136 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1137 | |||
| 1138 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1139 | rb.Push(ResultSuccess); | ||
| 1140 | rb.PushEnum(GetResourceManager()->GetNpad()->GetHoldType()); | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) { | ||
| 1144 | IPC::RequestParser rp{ctx}; | ||
| 1145 | struct Parameters { | ||
| 1146 | Core::HID::NpadIdType npad_id; | ||
| 1147 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1148 | u64 applet_resource_user_id; | ||
| 1149 | }; | ||
| 1150 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1151 | |||
| 1152 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1153 | |||
| 1154 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1155 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1156 | controller->SetNpadMode(new_npad_id, parameters.npad_id, NPad::NpadJoyDeviceType::Left, | ||
| 1157 | NPad::NpadJoyAssignmentMode::Single); | ||
| 1158 | |||
| 1159 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||
| 1160 | parameters.applet_resource_user_id); | ||
| 1161 | |||
| 1162 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1163 | rb.Push(ResultSuccess); | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { | ||
| 1167 | IPC::RequestParser rp{ctx}; | ||
| 1168 | struct Parameters { | ||
| 1169 | Core::HID::NpadIdType npad_id; | ||
| 1170 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1171 | u64 applet_resource_user_id; | ||
| 1172 | NPad::NpadJoyDeviceType npad_joy_device_type; | ||
| 1173 | }; | ||
| 1174 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1175 | |||
| 1176 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1177 | |||
| 1178 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1179 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1180 | controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | ||
| 1181 | NPad::NpadJoyAssignmentMode::Single); | ||
| 1182 | |||
| 1183 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||
| 1184 | parameters.npad_id, parameters.applet_resource_user_id, | ||
| 1185 | parameters.npad_joy_device_type); | ||
| 1186 | |||
| 1187 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1188 | rb.Push(ResultSuccess); | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) { | ||
| 1192 | IPC::RequestParser rp{ctx}; | ||
| 1193 | struct Parameters { | ||
| 1194 | Core::HID::NpadIdType npad_id; | ||
| 1195 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1196 | u64 applet_resource_user_id; | ||
| 1197 | }; | ||
| 1198 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1199 | |||
| 1200 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1201 | |||
| 1202 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1203 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1204 | controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NPad::NpadJoyAssignmentMode::Dual); | ||
| 1205 | |||
| 1206 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||
| 1207 | parameters.applet_resource_user_id); // Spams a lot when controller applet is open | ||
| 1208 | |||
| 1209 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1210 | rb.Push(ResultSuccess); | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | void IHidServer::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) { | ||
| 1214 | IPC::RequestParser rp{ctx}; | ||
| 1215 | const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1216 | const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1217 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1218 | |||
| 1219 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1220 | const auto result = controller->MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); | ||
| 1221 | |||
| 1222 | LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", | ||
| 1223 | npad_id_1, npad_id_2, applet_resource_user_id); | ||
| 1224 | |||
| 1225 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1226 | rb.Push(result); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | void IHidServer::StartLrAssignmentMode(HLERequestContext& ctx) { | ||
| 1230 | IPC::RequestParser rp{ctx}; | ||
| 1231 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1232 | |||
| 1233 | GetResourceManager()->GetNpad()->StartLRAssignmentMode(); | ||
| 1234 | |||
| 1235 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1236 | |||
| 1237 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1238 | rb.Push(ResultSuccess); | ||
| 1239 | } | ||
| 1240 | |||
| 1241 | void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) { | ||
| 1242 | IPC::RequestParser rp{ctx}; | ||
| 1243 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1244 | |||
| 1245 | GetResourceManager()->GetNpad()->StopLRAssignmentMode(); | ||
| 1246 | |||
| 1247 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1248 | |||
| 1249 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1250 | rb.Push(ResultSuccess); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) { | ||
| 1254 | IPC::RequestParser rp{ctx}; | ||
| 1255 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1256 | const auto activation_mode{rp.PopEnum<NPad::NpadHandheldActivationMode>()}; | ||
| 1257 | |||
| 1258 | GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode); | ||
| 1259 | |||
| 1260 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}", | ||
| 1261 | applet_resource_user_id, activation_mode); | ||
| 1262 | |||
| 1263 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1264 | rb.Push(ResultSuccess); | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) { | ||
| 1268 | IPC::RequestParser rp{ctx}; | ||
| 1269 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1270 | |||
| 1271 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1272 | |||
| 1273 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1274 | rb.Push(ResultSuccess); | ||
| 1275 | rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadHandheldActivationMode()); | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) { | ||
| 1279 | IPC::RequestParser rp{ctx}; | ||
| 1280 | const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1281 | const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 1282 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1283 | |||
| 1284 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1285 | const auto result = controller->SwapNpadAssignment(npad_id_1, npad_id_2); | ||
| 1286 | |||
| 1287 | LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", | ||
| 1288 | npad_id_1, npad_id_2, applet_resource_user_id); | ||
| 1289 | |||
| 1290 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1291 | rb.Push(result); | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | void IHidServer::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx) { | ||
| 1295 | IPC::RequestParser rp{ctx}; | ||
| 1296 | struct Parameters { | ||
| 1297 | Core::HID::NpadIdType npad_id; | ||
| 1298 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1299 | u64 applet_resource_user_id; | ||
| 1300 | }; | ||
| 1301 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1302 | |||
| 1303 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1304 | |||
| 1305 | bool is_enabled = false; | ||
| 1306 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1307 | const auto result = | ||
| 1308 | controller->IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled); | ||
| 1309 | |||
| 1310 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", | ||
| 1311 | parameters.npad_id, parameters.applet_resource_user_id); | ||
| 1312 | |||
| 1313 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1314 | rb.Push(result); | ||
| 1315 | rb.Push(is_enabled); | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | void IHidServer::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) { | ||
| 1319 | IPC::RequestParser rp{ctx}; | ||
| 1320 | struct Parameters { | ||
| 1321 | bool is_enabled; | ||
| 1322 | INSERT_PADDING_BYTES_NOINIT(3); | ||
| 1323 | Core::HID::NpadIdType npad_id; | ||
| 1324 | u64 applet_resource_user_id; | ||
| 1325 | }; | ||
| 1326 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1327 | |||
| 1328 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1329 | |||
| 1330 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1331 | const auto result = controller->SetUnintendedHomeButtonInputProtectionEnabled( | ||
| 1332 | parameters.is_enabled, parameters.npad_id); | ||
| 1333 | |||
| 1334 | LOG_DEBUG(Service_HID, | ||
| 1335 | "(STUBBED) called, is_enabled={}, npad_id={}, applet_resource_user_id={}", | ||
| 1336 | parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id); | ||
| 1337 | |||
| 1338 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1339 | rb.Push(result); | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) { | ||
| 1343 | IPC::RequestParser rp{ctx}; | ||
| 1344 | struct Parameters { | ||
| 1345 | Core::HID::NpadIdType npad_id; | ||
| 1346 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1347 | u64 applet_resource_user_id; | ||
| 1348 | NPad::NpadJoyDeviceType npad_joy_device_type; | ||
| 1349 | }; | ||
| 1350 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1351 | |||
| 1352 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1353 | |||
| 1354 | Core::HID::NpadIdType new_npad_id{}; | ||
| 1355 | auto controller = GetResourceManager()->GetNpad(); | ||
| 1356 | const auto is_reassigned = | ||
| 1357 | controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | ||
| 1358 | NPad::NpadJoyAssignmentMode::Single); | ||
| 1359 | |||
| 1360 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||
| 1361 | parameters.npad_id, parameters.applet_resource_user_id, | ||
| 1362 | parameters.npad_joy_device_type); | ||
| 1363 | |||
| 1364 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1365 | rb.Push(ResultSuccess); | ||
| 1366 | rb.Push(is_reassigned); | ||
| 1367 | rb.PushEnum(new_npad_id); | ||
| 1368 | } | ||
| 1369 | |||
| 1370 | void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) { | ||
| 1371 | IPC::RequestParser rp{ctx}; | ||
| 1372 | struct Parameters { | ||
| 1373 | bool analog_stick_use_center_clamp; | ||
| 1374 | INSERT_PADDING_BYTES_NOINIT(7); | ||
| 1375 | u64 applet_resource_user_id; | ||
| 1376 | }; | ||
| 1377 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1378 | |||
| 1379 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1380 | |||
| 1381 | GetResourceManager()->GetNpad()->SetAnalogStickUseCenterClamp( | ||
| 1382 | parameters.analog_stick_use_center_clamp); | ||
| 1383 | |||
| 1384 | LOG_WARNING(Service_HID, | ||
| 1385 | "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}", | ||
| 1386 | parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id); | ||
| 1387 | |||
| 1388 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1389 | rb.Push(ResultSuccess); | ||
| 1390 | } | ||
| 1391 | |||
| 1392 | void IHidServer::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) { | ||
| 1393 | IPC::RequestParser rp{ctx}; | ||
| 1394 | struct Parameters { | ||
| 1395 | Core::HID::NpadStyleSet npad_styleset; | ||
| 1396 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1397 | u64 applet_resource_user_id; | ||
| 1398 | Core::HID::NpadButton button; | ||
| 1399 | }; | ||
| 1400 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1401 | |||
| 1402 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1403 | |||
| 1404 | LOG_WARNING(Service_HID, | ||
| 1405 | "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}", | ||
| 1406 | parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button); | ||
| 1407 | |||
| 1408 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1409 | rb.Push(ResultSuccess); | ||
| 1410 | } | ||
| 1411 | |||
| 1412 | void IHidServer::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) { | ||
| 1413 | IPC::RequestParser rp{ctx}; | ||
| 1414 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1415 | |||
| 1416 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1417 | applet_resource_user_id); | ||
| 1418 | |||
| 1419 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1420 | rb.Push(ResultSuccess); | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) { | ||
| 1424 | IPC::RequestParser rp{ctx}; | ||
| 1425 | const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; | ||
| 1426 | const auto controller = GetResourceManager()->GetNpad(); | ||
| 1427 | |||
| 1428 | Core::HID::VibrationDeviceInfo vibration_device_info; | ||
| 1429 | bool check_device_index = false; | ||
| 1430 | |||
| 1431 | switch (vibration_device_handle.npad_type) { | ||
| 1432 | case Core::HID::NpadStyleIndex::ProController: | ||
| 1433 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 1434 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 1435 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 1436 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 1437 | vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator; | ||
| 1438 | check_device_index = true; | ||
| 1439 | break; | ||
| 1440 | case Core::HID::NpadStyleIndex::GameCube: | ||
| 1441 | vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm; | ||
| 1442 | break; | ||
| 1443 | case Core::HID::NpadStyleIndex::N64: | ||
| 1444 | vibration_device_info.type = Core::HID::VibrationDeviceType::N64; | ||
| 1445 | break; | ||
| 1446 | default: | ||
| 1447 | vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown; | ||
| 1448 | break; | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | vibration_device_info.position = Core::HID::VibrationDevicePosition::None; | ||
| 1452 | if (check_device_index) { | ||
| 1453 | switch (vibration_device_handle.device_index) { | ||
| 1454 | case Core::HID::DeviceIndex::Left: | ||
| 1455 | vibration_device_info.position = Core::HID::VibrationDevicePosition::Left; | ||
| 1456 | break; | ||
| 1457 | case Core::HID::DeviceIndex::Right: | ||
| 1458 | vibration_device_info.position = Core::HID::VibrationDevicePosition::Right; | ||
| 1459 | break; | ||
| 1460 | case Core::HID::DeviceIndex::None: | ||
| 1461 | default: | ||
| 1462 | ASSERT_MSG(false, "DeviceIndex should never be None!"); | ||
| 1463 | break; | ||
| 1464 | } | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}", | ||
| 1468 | vibration_device_info.type, vibration_device_info.position); | ||
| 1469 | |||
| 1470 | const auto result = IsVibrationHandleValid(vibration_device_handle); | ||
| 1471 | if (result.IsError()) { | ||
| 1472 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1473 | rb.Push(result); | ||
| 1474 | return; | ||
| 1475 | } | ||
| 1476 | |||
| 1477 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1478 | rb.Push(ResultSuccess); | ||
| 1479 | rb.PushRaw(vibration_device_info); | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | void IHidServer::SendVibrationValue(HLERequestContext& ctx) { | ||
| 1483 | IPC::RequestParser rp{ctx}; | ||
| 1484 | struct Parameters { | ||
| 1485 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1486 | Core::HID::VibrationValue vibration_value; | ||
| 1487 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1488 | u64 applet_resource_user_id; | ||
| 1489 | }; | ||
| 1490 | static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size."); | ||
| 1491 | |||
| 1492 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1493 | |||
| 1494 | GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle, | ||
| 1495 | parameters.vibration_value); | ||
| 1496 | |||
| 1497 | LOG_DEBUG(Service_HID, | ||
| 1498 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 1499 | parameters.vibration_device_handle.npad_type, | ||
| 1500 | parameters.vibration_device_handle.npad_id, | ||
| 1501 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); | ||
| 1502 | |||
| 1503 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1504 | rb.Push(ResultSuccess); | ||
| 1505 | } | ||
| 1506 | |||
| 1507 | void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) { | ||
| 1508 | IPC::RequestParser rp{ctx}; | ||
| 1509 | struct Parameters { | ||
| 1510 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1511 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1512 | u64 applet_resource_user_id; | ||
| 1513 | }; | ||
| 1514 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1515 | |||
| 1516 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1517 | |||
| 1518 | LOG_DEBUG(Service_HID, | ||
| 1519 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 1520 | parameters.vibration_device_handle.npad_type, | ||
| 1521 | parameters.vibration_device_handle.npad_id, | ||
| 1522 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); | ||
| 1523 | |||
| 1524 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 1525 | rb.Push(ResultSuccess); | ||
| 1526 | rb.PushRaw( | ||
| 1527 | GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle)); | ||
| 1528 | } | ||
| 1529 | |||
| 1530 | void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) { | ||
| 1531 | LOG_DEBUG(Service_HID, "called"); | ||
| 1532 | |||
| 1533 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 1534 | rb.Push(ResultSuccess); | ||
| 1535 | rb.PushIpcInterface<IActiveVibrationDeviceList>(system, GetResourceManager()); | ||
| 1536 | } | ||
| 1537 | |||
| 1538 | void IHidServer::PermitVibration(HLERequestContext& ctx) { | ||
| 1539 | IPC::RequestParser rp{ctx}; | ||
| 1540 | const auto can_vibrate{rp.Pop<bool>()}; | ||
| 1541 | |||
| 1542 | // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value | ||
| 1543 | // by converting it to a bool | ||
| 1544 | Settings::values.vibration_enabled.SetValue(can_vibrate); | ||
| 1545 | |||
| 1546 | LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); | ||
| 1547 | |||
| 1548 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1549 | rb.Push(ResultSuccess); | ||
| 1550 | } | ||
| 1551 | |||
| 1552 | void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) { | ||
| 1553 | LOG_DEBUG(Service_HID, "called"); | ||
| 1554 | |||
| 1555 | // nnSDK checks if a float is greater than zero. We return the bool we stored earlier | ||
| 1556 | const auto is_enabled = Settings::values.vibration_enabled.GetValue(); | ||
| 1557 | |||
| 1558 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1559 | rb.Push(ResultSuccess); | ||
| 1560 | rb.Push(is_enabled); | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | void IHidServer::SendVibrationValues(HLERequestContext& ctx) { | ||
| 1564 | IPC::RequestParser rp{ctx}; | ||
| 1565 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1566 | |||
| 1567 | const auto handle_data = ctx.ReadBuffer(0); | ||
| 1568 | const auto handle_count = ctx.GetReadBufferNumElements<Core::HID::VibrationDeviceHandle>(0); | ||
| 1569 | const auto vibration_data = ctx.ReadBuffer(1); | ||
| 1570 | const auto vibration_count = ctx.GetReadBufferNumElements<Core::HID::VibrationValue>(1); | ||
| 1571 | |||
| 1572 | auto vibration_device_handles = | ||
| 1573 | std::span(reinterpret_cast<const Core::HID::VibrationDeviceHandle*>(handle_data.data()), | ||
| 1574 | handle_count); | ||
| 1575 | auto vibration_values = std::span( | ||
| 1576 | reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count); | ||
| 1577 | |||
| 1578 | GetResourceManager()->GetNpad()->VibrateControllers(vibration_device_handles, vibration_values); | ||
| 1579 | |||
| 1580 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1581 | |||
| 1582 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1583 | rb.Push(ResultSuccess); | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) { | ||
| 1587 | IPC::RequestParser rp{ctx}; | ||
| 1588 | struct Parameters { | ||
| 1589 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1590 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1591 | u64 applet_resource_user_id; | ||
| 1592 | Core::HID::VibrationGcErmCommand gc_erm_command; | ||
| 1593 | }; | ||
| 1594 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1595 | |||
| 1596 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1597 | |||
| 1598 | /** | ||
| 1599 | * Note: This uses yuzu-specific behavior such that the StopHard command produces | ||
| 1600 | * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below, | ||
| 1601 | * in order to differentiate between Stop and StopHard commands. | ||
| 1602 | * This is done to reuse the controller vibration functions made for regular controllers. | ||
| 1603 | */ | ||
| 1604 | const auto vibration_value = [parameters] { | ||
| 1605 | switch (parameters.gc_erm_command) { | ||
| 1606 | case Core::HID::VibrationGcErmCommand::Stop: | ||
| 1607 | return Core::HID::VibrationValue{ | ||
| 1608 | .low_amplitude = 0.0f, | ||
| 1609 | .low_frequency = 160.0f, | ||
| 1610 | .high_amplitude = 0.0f, | ||
| 1611 | .high_frequency = 320.0f, | ||
| 1612 | }; | ||
| 1613 | case Core::HID::VibrationGcErmCommand::Start: | ||
| 1614 | return Core::HID::VibrationValue{ | ||
| 1615 | .low_amplitude = 1.0f, | ||
| 1616 | .low_frequency = 160.0f, | ||
| 1617 | .high_amplitude = 1.0f, | ||
| 1618 | .high_frequency = 320.0f, | ||
| 1619 | }; | ||
| 1620 | case Core::HID::VibrationGcErmCommand::StopHard: | ||
| 1621 | return Core::HID::VibrationValue{ | ||
| 1622 | .low_amplitude = 0.0f, | ||
| 1623 | .low_frequency = 0.0f, | ||
| 1624 | .high_amplitude = 0.0f, | ||
| 1625 | .high_frequency = 0.0f, | ||
| 1626 | }; | ||
| 1627 | default: | ||
| 1628 | return Core::HID::DEFAULT_VIBRATION_VALUE; | ||
| 1629 | } | ||
| 1630 | }(); | ||
| 1631 | |||
| 1632 | GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle, | ||
| 1633 | vibration_value); | ||
| 1634 | |||
| 1635 | LOG_DEBUG(Service_HID, | ||
| 1636 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, " | ||
| 1637 | "gc_erm_command={}", | ||
| 1638 | parameters.vibration_device_handle.npad_type, | ||
| 1639 | parameters.vibration_device_handle.npad_id, | ||
| 1640 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id, | ||
| 1641 | parameters.gc_erm_command); | ||
| 1642 | |||
| 1643 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1644 | rb.Push(ResultSuccess); | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) { | ||
| 1648 | IPC::RequestParser rp{ctx}; | ||
| 1649 | struct Parameters { | ||
| 1650 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1651 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1652 | u64 applet_resource_user_id; | ||
| 1653 | }; | ||
| 1654 | |||
| 1655 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1656 | |||
| 1657 | const auto last_vibration = | ||
| 1658 | GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle); | ||
| 1659 | |||
| 1660 | const auto gc_erm_command = [last_vibration] { | ||
| 1661 | if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) { | ||
| 1662 | return Core::HID::VibrationGcErmCommand::Start; | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | /** | ||
| 1666 | * Note: This uses yuzu-specific behavior such that the StopHard command produces | ||
| 1667 | * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function | ||
| 1668 | * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands. | ||
| 1669 | * This is done to reuse the controller vibration functions made for regular controllers. | ||
| 1670 | */ | ||
| 1671 | if (last_vibration.low_frequency == 0.0f && last_vibration.high_frequency == 0.0f) { | ||
| 1672 | return Core::HID::VibrationGcErmCommand::StopHard; | ||
| 1673 | } | ||
| 1674 | |||
| 1675 | return Core::HID::VibrationGcErmCommand::Stop; | ||
| 1676 | }(); | ||
| 1677 | |||
| 1678 | LOG_DEBUG(Service_HID, | ||
| 1679 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 1680 | parameters.vibration_device_handle.npad_type, | ||
| 1681 | parameters.vibration_device_handle.npad_id, | ||
| 1682 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); | ||
| 1683 | |||
| 1684 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1685 | rb.Push(ResultSuccess); | ||
| 1686 | rb.PushEnum(gc_erm_command); | ||
| 1687 | } | ||
| 1688 | |||
| 1689 | void IHidServer::BeginPermitVibrationSession(HLERequestContext& ctx) { | ||
| 1690 | IPC::RequestParser rp{ctx}; | ||
| 1691 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1692 | |||
| 1693 | GetResourceManager()->GetNpad()->SetPermitVibrationSession(true); | ||
| 1694 | |||
| 1695 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1696 | |||
| 1697 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1698 | rb.Push(ResultSuccess); | ||
| 1699 | } | ||
| 1700 | |||
| 1701 | void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) { | ||
| 1702 | GetResourceManager()->GetNpad()->SetPermitVibrationSession(false); | ||
| 1703 | |||
| 1704 | LOG_DEBUG(Service_HID, "called"); | ||
| 1705 | |||
| 1706 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1707 | rb.Push(ResultSuccess); | ||
| 1708 | } | ||
| 1709 | |||
| 1710 | void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) { | ||
| 1711 | IPC::RequestParser rp{ctx}; | ||
| 1712 | struct Parameters { | ||
| 1713 | Core::HID::VibrationDeviceHandle vibration_device_handle; | ||
| 1714 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1715 | u64 applet_resource_user_id; | ||
| 1716 | }; | ||
| 1717 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1718 | |||
| 1719 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1720 | |||
| 1721 | LOG_DEBUG(Service_HID, | ||
| 1722 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | ||
| 1723 | parameters.vibration_device_handle.npad_type, | ||
| 1724 | parameters.vibration_device_handle.npad_id, | ||
| 1725 | parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); | ||
| 1726 | |||
| 1727 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1728 | rb.Push(ResultSuccess); | ||
| 1729 | rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted( | ||
| 1730 | parameters.vibration_device_handle)); | ||
| 1731 | } | ||
| 1732 | |||
| 1733 | void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) { | ||
| 1734 | IPC::RequestParser rp{ctx}; | ||
| 1735 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1736 | |||
| 1737 | LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1738 | |||
| 1739 | Result result = ResultSuccess; | ||
| 1740 | auto console_sixaxis = GetResourceManager()->GetConsoleSixAxis(); | ||
| 1741 | |||
| 1742 | if (!firmware_settings->IsDeviceManaged()) { | ||
| 1743 | result = console_sixaxis->Activate(); | ||
| 1744 | } | ||
| 1745 | |||
| 1746 | if (result.IsSuccess()) { | ||
| 1747 | result = console_sixaxis->Activate(applet_resource_user_id); | ||
| 1748 | } | ||
| 1749 | |||
| 1750 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1751 | rb.Push(result); | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | void IHidServer::StartConsoleSixAxisSensor(HLERequestContext& ctx) { | ||
| 1755 | IPC::RequestParser rp{ctx}; | ||
| 1756 | struct Parameters { | ||
| 1757 | Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle; | ||
| 1758 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1759 | u64 applet_resource_user_id; | ||
| 1760 | }; | ||
| 1761 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1762 | |||
| 1763 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1764 | |||
| 1765 | LOG_WARNING(Service_HID, | ||
| 1766 | "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", | ||
| 1767 | parameters.console_sixaxis_handle.unknown_1, | ||
| 1768 | parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id); | ||
| 1769 | |||
| 1770 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1771 | rb.Push(ResultSuccess); | ||
| 1772 | } | ||
| 1773 | |||
| 1774 | void IHidServer::StopConsoleSixAxisSensor(HLERequestContext& ctx) { | ||
| 1775 | IPC::RequestParser rp{ctx}; | ||
| 1776 | struct Parameters { | ||
| 1777 | Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle; | ||
| 1778 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1779 | u64 applet_resource_user_id; | ||
| 1780 | }; | ||
| 1781 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1782 | |||
| 1783 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1784 | |||
| 1785 | LOG_WARNING(Service_HID, | ||
| 1786 | "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", | ||
| 1787 | parameters.console_sixaxis_handle.unknown_1, | ||
| 1788 | parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id); | ||
| 1789 | |||
| 1790 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1791 | rb.Push(ResultSuccess); | ||
| 1792 | } | ||
| 1793 | |||
| 1794 | void IHidServer::ActivateSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1795 | IPC::RequestParser rp{ctx}; | ||
| 1796 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1797 | |||
| 1798 | LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1799 | |||
| 1800 | Result result = ResultSuccess; | ||
| 1801 | auto seven_sixaxis = GetResourceManager()->GetSevenSixAxis(); | ||
| 1802 | |||
| 1803 | if (!firmware_settings->IsDeviceManaged()) { | ||
| 1804 | result = seven_sixaxis->Activate(); | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | if (result.IsSuccess()) { | ||
| 1808 | seven_sixaxis->Activate(applet_resource_user_id); | ||
| 1809 | } | ||
| 1810 | |||
| 1811 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1812 | rb.Push(ResultSuccess); | ||
| 1813 | } | ||
| 1814 | |||
| 1815 | void IHidServer::StartSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1816 | IPC::RequestParser rp{ctx}; | ||
| 1817 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1818 | |||
| 1819 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1820 | applet_resource_user_id); | ||
| 1821 | |||
| 1822 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1823 | rb.Push(ResultSuccess); | ||
| 1824 | } | ||
| 1825 | |||
| 1826 | void IHidServer::StopSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1827 | IPC::RequestParser rp{ctx}; | ||
| 1828 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1829 | |||
| 1830 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1831 | applet_resource_user_id); | ||
| 1832 | |||
| 1833 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1834 | rb.Push(ResultSuccess); | ||
| 1835 | } | ||
| 1836 | |||
| 1837 | void IHidServer::InitializeSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1838 | IPC::RequestParser rp{ctx}; | ||
| 1839 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1840 | const auto t_mem_1_size{rp.Pop<u64>()}; | ||
| 1841 | const auto t_mem_2_size{rp.Pop<u64>()}; | ||
| 1842 | const auto t_mem_1_handle{ctx.GetCopyHandle(0)}; | ||
| 1843 | const auto t_mem_2_handle{ctx.GetCopyHandle(1)}; | ||
| 1844 | |||
| 1845 | ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes"); | ||
| 1846 | ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes"); | ||
| 1847 | |||
| 1848 | auto t_mem_1 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( | ||
| 1849 | t_mem_1_handle); | ||
| 1850 | |||
| 1851 | if (t_mem_1.IsNull()) { | ||
| 1852 | LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle); | ||
| 1853 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1854 | rb.Push(ResultUnknown); | ||
| 1855 | return; | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | auto t_mem_2 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( | ||
| 1859 | t_mem_2_handle); | ||
| 1860 | |||
| 1861 | if (t_mem_2.IsNull()) { | ||
| 1862 | LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle); | ||
| 1863 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1864 | rb.Push(ResultUnknown); | ||
| 1865 | return; | ||
| 1866 | } | ||
| 1867 | |||
| 1868 | ASSERT_MSG(t_mem_1->GetSize() == 0x1000, "t_mem_1 has incorrect size"); | ||
| 1869 | ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size"); | ||
| 1870 | |||
| 1871 | // Activate console six axis controller | ||
| 1872 | GetResourceManager()->GetConsoleSixAxis()->Activate(); | ||
| 1873 | GetResourceManager()->GetSevenSixAxis()->Activate(); | ||
| 1874 | |||
| 1875 | GetResourceManager()->GetSevenSixAxis()->SetTransferMemoryAddress(t_mem_1->GetSourceAddress()); | ||
| 1876 | |||
| 1877 | LOG_WARNING(Service_HID, | ||
| 1878 | "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, " | ||
| 1879 | "applet_resource_user_id={}", | ||
| 1880 | t_mem_1_handle, t_mem_2_handle, applet_resource_user_id); | ||
| 1881 | |||
| 1882 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1883 | rb.Push(ResultSuccess); | ||
| 1884 | } | ||
| 1885 | |||
| 1886 | void IHidServer::FinalizeSevenSixAxisSensor(HLERequestContext& ctx) { | ||
| 1887 | IPC::RequestParser rp{ctx}; | ||
| 1888 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1889 | |||
| 1890 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1891 | applet_resource_user_id); | ||
| 1892 | |||
| 1893 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1894 | rb.Push(ResultSuccess); | ||
| 1895 | } | ||
| 1896 | |||
| 1897 | void IHidServer::ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx) { | ||
| 1898 | IPC::RequestParser rp{ctx}; | ||
| 1899 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1900 | |||
| 1901 | GetResourceManager()->GetSevenSixAxis()->ResetTimestamp(); | ||
| 1902 | |||
| 1903 | LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 1904 | |||
| 1905 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1906 | rb.Push(ResultSuccess); | ||
| 1907 | } | ||
| 1908 | |||
| 1909 | void IHidServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) { | ||
| 1910 | IPC::RequestParser rp{ctx}; | ||
| 1911 | |||
| 1912 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 1913 | |||
| 1914 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1915 | rb.Push(ResultSuccess); | ||
| 1916 | rb.Push(false); | ||
| 1917 | } | ||
| 1918 | |||
| 1919 | void IHidServer::GetPalmaConnectionHandle(HLERequestContext& ctx) { | ||
| 1920 | IPC::RequestParser rp{ctx}; | ||
| 1921 | struct Parameters { | ||
| 1922 | Core::HID::NpadIdType npad_id; | ||
| 1923 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1924 | u64 applet_resource_user_id; | ||
| 1925 | }; | ||
| 1926 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1927 | |||
| 1928 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1929 | |||
| 1930 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", | ||
| 1931 | parameters.npad_id, parameters.applet_resource_user_id); | ||
| 1932 | |||
| 1933 | Palma::PalmaConnectionHandle handle; | ||
| 1934 | auto controller = GetResourceManager()->GetPalma(); | ||
| 1935 | const auto result = controller->GetPalmaConnectionHandle(parameters.npad_id, handle); | ||
| 1936 | |||
| 1937 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1938 | rb.Push(result); | ||
| 1939 | rb.PushRaw(handle); | ||
| 1940 | } | ||
| 1941 | |||
| 1942 | void IHidServer::InitializePalma(HLERequestContext& ctx) { | ||
| 1943 | IPC::RequestParser rp{ctx}; | ||
| 1944 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 1945 | |||
| 1946 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 1947 | |||
| 1948 | auto controller = GetResourceManager()->GetPalma(); | ||
| 1949 | const auto result = controller->InitializePalma(connection_handle); | ||
| 1950 | |||
| 1951 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1952 | rb.Push(result); | ||
| 1953 | } | ||
| 1954 | |||
| 1955 | void IHidServer::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) { | ||
| 1956 | IPC::RequestParser rp{ctx}; | ||
| 1957 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 1958 | |||
| 1959 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 1960 | |||
| 1961 | auto controller = GetResourceManager()->GetPalma(); | ||
| 1962 | |||
| 1963 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 1964 | rb.Push(ResultSuccess); | ||
| 1965 | rb.PushCopyObjects(controller->AcquirePalmaOperationCompleteEvent(connection_handle)); | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | void IHidServer::GetPalmaOperationInfo(HLERequestContext& ctx) { | ||
| 1969 | IPC::RequestParser rp{ctx}; | ||
| 1970 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 1971 | |||
| 1972 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 1973 | |||
| 1974 | Palma::PalmaOperationType operation_type; | ||
| 1975 | Palma::PalmaOperationData data; | ||
| 1976 | auto controller = GetResourceManager()->GetPalma(); | ||
| 1977 | const auto result = controller->GetPalmaOperationInfo(connection_handle, operation_type, data); | ||
| 1978 | |||
| 1979 | if (result.IsError()) { | ||
| 1980 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1981 | rb.Push(result); | ||
| 1982 | } | ||
| 1983 | |||
| 1984 | ctx.WriteBuffer(data); | ||
| 1985 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 1986 | rb.Push(result); | ||
| 1987 | rb.Push(static_cast<u64>(operation_type)); | ||
| 1988 | } | ||
| 1989 | |||
| 1990 | void IHidServer::PlayPalmaActivity(HLERequestContext& ctx) { | ||
| 1991 | IPC::RequestParser rp{ctx}; | ||
| 1992 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 1993 | const auto palma_activity{rp.Pop<u64>()}; | ||
| 1994 | |||
| 1995 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}", | ||
| 1996 | connection_handle.npad_id, palma_activity); | ||
| 1997 | |||
| 1998 | auto controller = GetResourceManager()->GetPalma(); | ||
| 1999 | const auto result = controller->PlayPalmaActivity(connection_handle, palma_activity); | ||
| 2000 | |||
| 2001 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2002 | rb.Push(result); | ||
| 2003 | } | ||
| 2004 | |||
| 2005 | void IHidServer::SetPalmaFrModeType(HLERequestContext& ctx) { | ||
| 2006 | IPC::RequestParser rp{ctx}; | ||
| 2007 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2008 | const auto fr_mode{rp.PopEnum<Palma::PalmaFrModeType>()}; | ||
| 2009 | |||
| 2010 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}", | ||
| 2011 | connection_handle.npad_id, fr_mode); | ||
| 2012 | |||
| 2013 | auto controller = GetResourceManager()->GetPalma(); | ||
| 2014 | const auto result = controller->SetPalmaFrModeType(connection_handle, fr_mode); | ||
| 2015 | |||
| 2016 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2017 | rb.Push(result); | ||
| 2018 | } | ||
| 2019 | |||
| 2020 | void IHidServer::ReadPalmaStep(HLERequestContext& ctx) { | ||
| 2021 | IPC::RequestParser rp{ctx}; | ||
| 2022 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2023 | |||
| 2024 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2025 | |||
| 2026 | auto controller = GetResourceManager()->GetPalma(); | ||
| 2027 | const auto result = controller->ReadPalmaStep(connection_handle); | ||
| 2028 | |||
| 2029 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2030 | rb.Push(result); | ||
| 2031 | } | ||
| 2032 | |||
| 2033 | void IHidServer::EnablePalmaStep(HLERequestContext& ctx) { | ||
| 2034 | IPC::RequestParser rp{ctx}; | ||
| 2035 | struct Parameters { | ||
| 2036 | bool is_enabled; | ||
| 2037 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 2038 | Palma::PalmaConnectionHandle connection_handle; | ||
| 2039 | }; | ||
| 2040 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 2041 | |||
| 2042 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 2043 | |||
| 2044 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}", | ||
| 2045 | parameters.connection_handle.npad_id, parameters.is_enabled); | ||
| 2046 | |||
| 2047 | auto controller = GetResourceManager()->GetPalma(); | ||
| 2048 | const auto result = | ||
| 2049 | controller->EnablePalmaStep(parameters.connection_handle, parameters.is_enabled); | ||
| 2050 | |||
| 2051 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2052 | rb.Push(result); | ||
| 2053 | } | ||
| 2054 | |||
| 2055 | void IHidServer::ResetPalmaStep(HLERequestContext& ctx) { | ||
| 2056 | IPC::RequestParser rp{ctx}; | ||
| 2057 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2058 | |||
| 2059 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2060 | |||
| 2061 | auto controller = GetResourceManager()->GetPalma(); | ||
| 2062 | const auto result = controller->ResetPalmaStep(connection_handle); | ||
| 2063 | |||
| 2064 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2065 | rb.Push(result); | ||
| 2066 | } | ||
| 2067 | |||
| 2068 | void IHidServer::ReadPalmaApplicationSection(HLERequestContext& ctx) { | ||
| 2069 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2070 | |||
| 2071 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2072 | rb.Push(ResultSuccess); | ||
| 2073 | } | ||
| 2074 | |||
| 2075 | void IHidServer::WritePalmaApplicationSection(HLERequestContext& ctx) { | ||
| 2076 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2077 | |||
| 2078 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2079 | rb.Push(ResultSuccess); | ||
| 2080 | } | ||
| 2081 | |||
| 2082 | void IHidServer::ReadPalmaUniqueCode(HLERequestContext& ctx) { | ||
| 2083 | IPC::RequestParser rp{ctx}; | ||
| 2084 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2085 | |||
| 2086 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2087 | |||
| 2088 | GetResourceManager()->GetPalma()->ReadPalmaUniqueCode(connection_handle); | ||
| 2089 | |||
| 2090 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2091 | rb.Push(ResultSuccess); | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | void IHidServer::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) { | ||
| 2095 | IPC::RequestParser rp{ctx}; | ||
| 2096 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2097 | |||
| 2098 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2099 | |||
| 2100 | GetResourceManager()->GetPalma()->SetPalmaUniqueCodeInvalid(connection_handle); | ||
| 2101 | |||
| 2102 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2103 | rb.Push(ResultSuccess); | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | void IHidServer::WritePalmaActivityEntry(HLERequestContext& ctx) { | ||
| 2107 | LOG_CRITICAL(Service_HID, "(STUBBED) called"); | ||
| 2108 | |||
| 2109 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2110 | rb.Push(ResultSuccess); | ||
| 2111 | } | ||
| 2112 | |||
| 2113 | void IHidServer::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) { | ||
| 2114 | IPC::RequestParser rp{ctx}; | ||
| 2115 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2116 | const auto unknown{rp.Pop<u64>()}; | ||
| 2117 | |||
| 2118 | [[maybe_unused]] const auto buffer = ctx.ReadBuffer(); | ||
| 2119 | |||
| 2120 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}", | ||
| 2121 | connection_handle.npad_id, unknown); | ||
| 2122 | |||
| 2123 | GetResourceManager()->GetPalma()->WritePalmaRgbLedPatternEntry(connection_handle, unknown); | ||
| 2124 | |||
| 2125 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2126 | rb.Push(ResultSuccess); | ||
| 2127 | } | ||
| 2128 | |||
| 2129 | void IHidServer::WritePalmaWaveEntry(HLERequestContext& ctx) { | ||
| 2130 | IPC::RequestParser rp{ctx}; | ||
| 2131 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2132 | const auto wave_set{rp.PopEnum<Palma::PalmaWaveSet>()}; | ||
| 2133 | const auto unknown{rp.Pop<u64>()}; | ||
| 2134 | const auto t_mem_size{rp.Pop<u64>()}; | ||
| 2135 | const auto t_mem_handle{ctx.GetCopyHandle(0)}; | ||
| 2136 | const auto size{rp.Pop<u64>()}; | ||
| 2137 | |||
| 2138 | ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes"); | ||
| 2139 | |||
| 2140 | auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( | ||
| 2141 | t_mem_handle); | ||
| 2142 | |||
| 2143 | if (t_mem.IsNull()) { | ||
| 2144 | LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle); | ||
| 2145 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2146 | rb.Push(ResultUnknown); | ||
| 2147 | return; | ||
| 2148 | } | ||
| 2149 | |||
| 2150 | ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size"); | ||
| 2151 | |||
| 2152 | LOG_WARNING(Service_HID, | ||
| 2153 | "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, " | ||
| 2154 | "t_mem_handle=0x{:08X}, t_mem_size={}, size={}", | ||
| 2155 | connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size); | ||
| 2156 | |||
| 2157 | GetResourceManager()->GetPalma()->WritePalmaWaveEntry(connection_handle, wave_set, | ||
| 2158 | t_mem->GetSourceAddress(), t_mem_size); | ||
| 2159 | |||
| 2160 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2161 | rb.Push(ResultSuccess); | ||
| 2162 | } | ||
| 2163 | |||
| 2164 | void IHidServer::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) { | ||
| 2165 | IPC::RequestParser rp{ctx}; | ||
| 2166 | struct Parameters { | ||
| 2167 | s32 database_id_version; | ||
| 2168 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 2169 | Palma::PalmaConnectionHandle connection_handle; | ||
| 2170 | }; | ||
| 2171 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 2172 | |||
| 2173 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 2174 | |||
| 2175 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}", | ||
| 2176 | parameters.connection_handle.npad_id, parameters.database_id_version); | ||
| 2177 | |||
| 2178 | GetResourceManager()->GetPalma()->SetPalmaDataBaseIdentificationVersion( | ||
| 2179 | parameters.connection_handle, parameters.database_id_version); | ||
| 2180 | |||
| 2181 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2182 | rb.Push(ResultSuccess); | ||
| 2183 | } | ||
| 2184 | |||
| 2185 | void IHidServer::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) { | ||
| 2186 | IPC::RequestParser rp{ctx}; | ||
| 2187 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2188 | |||
| 2189 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2190 | |||
| 2191 | GetResourceManager()->GetPalma()->GetPalmaDataBaseIdentificationVersion(connection_handle); | ||
| 2192 | |||
| 2193 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2194 | rb.Push(ResultSuccess); | ||
| 2195 | } | ||
| 2196 | |||
| 2197 | void IHidServer::SuspendPalmaFeature(HLERequestContext& ctx) { | ||
| 2198 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2199 | |||
| 2200 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2201 | rb.Push(ResultSuccess); | ||
| 2202 | } | ||
| 2203 | |||
| 2204 | void IHidServer::GetPalmaOperationResult(HLERequestContext& ctx) { | ||
| 2205 | IPC::RequestParser rp{ctx}; | ||
| 2206 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2207 | |||
| 2208 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2209 | |||
| 2210 | const auto result = | ||
| 2211 | GetResourceManager()->GetPalma()->GetPalmaOperationResult(connection_handle); | ||
| 2212 | |||
| 2213 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2214 | rb.Push(result); | ||
| 2215 | } | ||
| 2216 | |||
| 2217 | void IHidServer::ReadPalmaPlayLog(HLERequestContext& ctx) { | ||
| 2218 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2219 | |||
| 2220 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2221 | rb.Push(ResultSuccess); | ||
| 2222 | } | ||
| 2223 | |||
| 2224 | void IHidServer::ResetPalmaPlayLog(HLERequestContext& ctx) { | ||
| 2225 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2226 | |||
| 2227 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2228 | rb.Push(ResultSuccess); | ||
| 2229 | } | ||
| 2230 | |||
| 2231 | void IHidServer::SetIsPalmaAllConnectable(HLERequestContext& ctx) { | ||
| 2232 | IPC::RequestParser rp{ctx}; | ||
| 2233 | struct Parameters { | ||
| 2234 | bool is_palma_all_connectable; | ||
| 2235 | INSERT_PADDING_BYTES_NOINIT(7); | ||
| 2236 | u64 applet_resource_user_id; | ||
| 2237 | }; | ||
| 2238 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 2239 | |||
| 2240 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 2241 | |||
| 2242 | LOG_WARNING(Service_HID, | ||
| 2243 | "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}", | ||
| 2244 | parameters.is_palma_all_connectable, parameters.applet_resource_user_id); | ||
| 2245 | |||
| 2246 | GetResourceManager()->GetPalma()->SetIsPalmaAllConnectable(parameters.is_palma_all_connectable); | ||
| 2247 | |||
| 2248 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2249 | rb.Push(ResultSuccess); | ||
| 2250 | } | ||
| 2251 | |||
| 2252 | void IHidServer::SetIsPalmaPairedConnectable(HLERequestContext& ctx) { | ||
| 2253 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2254 | |||
| 2255 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2256 | rb.Push(ResultSuccess); | ||
| 2257 | } | ||
| 2258 | |||
| 2259 | void IHidServer::PairPalma(HLERequestContext& ctx) { | ||
| 2260 | IPC::RequestParser rp{ctx}; | ||
| 2261 | const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()}; | ||
| 2262 | |||
| 2263 | LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); | ||
| 2264 | |||
| 2265 | GetResourceManager()->GetPalma()->PairPalma(connection_handle); | ||
| 2266 | |||
| 2267 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2268 | rb.Push(ResultSuccess); | ||
| 2269 | } | ||
| 2270 | |||
| 2271 | void IHidServer::SetPalmaBoostMode(HLERequestContext& ctx) { | ||
| 2272 | IPC::RequestParser rp{ctx}; | ||
| 2273 | const auto palma_boost_mode{rp.Pop<bool>()}; | ||
| 2274 | |||
| 2275 | LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode); | ||
| 2276 | |||
| 2277 | GetResourceManager()->GetPalma()->SetPalmaBoostMode(palma_boost_mode); | ||
| 2278 | |||
| 2279 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2280 | rb.Push(ResultSuccess); | ||
| 2281 | } | ||
| 2282 | |||
| 2283 | void IHidServer::CancelWritePalmaWaveEntry(HLERequestContext& ctx) { | ||
| 2284 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2285 | |||
| 2286 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2287 | rb.Push(ResultSuccess); | ||
| 2288 | } | ||
| 2289 | |||
| 2290 | void IHidServer::EnablePalmaBoostMode(HLERequestContext& ctx) { | ||
| 2291 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2292 | |||
| 2293 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2294 | rb.Push(ResultSuccess); | ||
| 2295 | } | ||
| 2296 | |||
| 2297 | void IHidServer::GetPalmaBluetoothAddress(HLERequestContext& ctx) { | ||
| 2298 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2299 | |||
| 2300 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2301 | rb.Push(ResultSuccess); | ||
| 2302 | } | ||
| 2303 | |||
| 2304 | void IHidServer::SetDisallowedPalmaConnection(HLERequestContext& ctx) { | ||
| 2305 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2306 | |||
| 2307 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2308 | rb.Push(ResultSuccess); | ||
| 2309 | } | ||
| 2310 | |||
| 2311 | void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) { | ||
| 2312 | IPC::RequestParser rp{ctx}; | ||
| 2313 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 2314 | const auto communication_mode{rp.PopEnum<NPad::NpadCommunicationMode>()}; | ||
| 2315 | |||
| 2316 | GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode); | ||
| 2317 | |||
| 2318 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}", | ||
| 2319 | applet_resource_user_id, communication_mode); | ||
| 2320 | |||
| 2321 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2322 | rb.Push(ResultSuccess); | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) { | ||
| 2326 | IPC::RequestParser rp{ctx}; | ||
| 2327 | |||
| 2328 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 2329 | |||
| 2330 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 2331 | rb.Push(ResultSuccess); | ||
| 2332 | rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadCommunicationMode()); | ||
| 2333 | } | ||
| 2334 | |||
| 2335 | void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) { | ||
| 2336 | IPC::RequestParser rp{ctx}; | ||
| 2337 | const auto touchscreen_mode{rp.PopRaw<Core::HID::TouchScreenConfigurationForNx>()}; | ||
| 2338 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 2339 | |||
| 2340 | LOG_WARNING(Service_HID, "(STUBBED) called, touchscreen_mode={}, applet_resource_user_id={}", | ||
| 2341 | touchscreen_mode.mode, applet_resource_user_id); | ||
| 2342 | |||
| 2343 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 2344 | rb.Push(ResultSuccess); | ||
| 2345 | } | ||
| 2346 | |||
| 2347 | void IHidServer::IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx) { | ||
| 2348 | IPC::RequestParser rp{ctx}; | ||
| 2349 | struct Parameters { | ||
| 2350 | s32 unknown; | ||
| 2351 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 2352 | u64 applet_resource_user_id; | ||
| 2353 | }; | ||
| 2354 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 2355 | |||
| 2356 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 2357 | |||
| 2358 | LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}", | ||
| 2359 | parameters.unknown, parameters.applet_resource_user_id); | ||
| 2360 | |||
| 2361 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 2362 | rb.Push(ResultSuccess); | ||
| 2363 | rb.Push(false); | ||
| 2364 | } | ||
| 2365 | |||
| 2366 | std::shared_ptr<ResourceManager> IHidServer::GetResourceManager() { | ||
| 2367 | resource_manager->Initialize(); | ||
| 2368 | return resource_manager; | ||
| 2369 | } | ||
| 2370 | |||
| 2371 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/hid_server.h b/src/core/hle/service/hid/hid_server.h new file mode 100644 index 000000000..eb2e8e7f4 --- /dev/null +++ b/src/core/hle/service/hid/hid_server.h | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::HID { | ||
| 13 | class ResourceManager; | ||
| 14 | class HidFirmwareSettings; | ||
| 15 | |||
| 16 | class IHidServer final : public ServiceFramework<IHidServer> { | ||
| 17 | public: | ||
| 18 | explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource, | ||
| 19 | std::shared_ptr<HidFirmwareSettings> settings); | ||
| 20 | ~IHidServer() override; | ||
| 21 | |||
| 22 | std::shared_ptr<ResourceManager> GetResourceManager(); | ||
| 23 | |||
| 24 | private: | ||
| 25 | void CreateAppletResource(HLERequestContext& ctx); | ||
| 26 | void ActivateDebugPad(HLERequestContext& ctx); | ||
| 27 | void ActivateTouchScreen(HLERequestContext& ctx); | ||
| 28 | void ActivateMouse(HLERequestContext& ctx); | ||
| 29 | void ActivateKeyboard(HLERequestContext& ctx); | ||
| 30 | void SendKeyboardLockKeyEvent(HLERequestContext& ctx); | ||
| 31 | void AcquireXpadIdEventHandle(HLERequestContext& ctx); | ||
| 32 | void ReleaseXpadIdEventHandle(HLERequestContext& ctx); | ||
| 33 | void ActivateXpad(HLERequestContext& ctx); | ||
| 34 | void GetXpadIds(HLERequestContext& ctx); | ||
| 35 | void ActivateJoyXpad(HLERequestContext& ctx); | ||
| 36 | void GetJoyXpadLifoHandle(HLERequestContext& ctx); | ||
| 37 | void GetJoyXpadIds(HLERequestContext& ctx); | ||
| 38 | void ActivateSixAxisSensor(HLERequestContext& ctx); | ||
| 39 | void DeactivateSixAxisSensor(HLERequestContext& ctx); | ||
| 40 | void GetSixAxisSensorLifoHandle(HLERequestContext& ctx); | ||
| 41 | void ActivateJoySixAxisSensor(HLERequestContext& ctx); | ||
| 42 | void DeactivateJoySixAxisSensor(HLERequestContext& ctx); | ||
| 43 | void GetJoySixAxisSensorLifoHandle(HLERequestContext& ctx); | ||
| 44 | void StartSixAxisSensor(HLERequestContext& ctx); | ||
| 45 | void StopSixAxisSensor(HLERequestContext& ctx); | ||
| 46 | void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx); | ||
| 47 | void EnableSixAxisSensorFusion(HLERequestContext& ctx); | ||
| 48 | void SetSixAxisSensorFusionParameters(HLERequestContext& ctx); | ||
| 49 | void GetSixAxisSensorFusionParameters(HLERequestContext& ctx); | ||
| 50 | void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx); | ||
| 51 | void SetGyroscopeZeroDriftMode(HLERequestContext& ctx); | ||
| 52 | void GetGyroscopeZeroDriftMode(HLERequestContext& ctx); | ||
| 53 | void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx); | ||
| 54 | void IsSixAxisSensorAtRest(HLERequestContext& ctx); | ||
| 55 | void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx); | ||
| 56 | void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx); | ||
| 57 | void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx); | ||
| 58 | void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx); | ||
| 59 | void GetSixAxisSensorIcInformation(HLERequestContext& ctx); | ||
| 60 | void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx); | ||
| 61 | void ActivateGesture(HLERequestContext& ctx); | ||
| 62 | void SetSupportedNpadStyleSet(HLERequestContext& ctx); | ||
| 63 | void GetSupportedNpadStyleSet(HLERequestContext& ctx); | ||
| 64 | void SetSupportedNpadIdType(HLERequestContext& ctx); | ||
| 65 | void ActivateNpad(HLERequestContext& ctx); | ||
| 66 | void DeactivateNpad(HLERequestContext& ctx); | ||
| 67 | void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx); | ||
| 68 | void DisconnectNpad(HLERequestContext& ctx); | ||
| 69 | void GetPlayerLedPattern(HLERequestContext& ctx); | ||
| 70 | void ActivateNpadWithRevision(HLERequestContext& ctx); | ||
| 71 | void SetNpadJoyHoldType(HLERequestContext& ctx); | ||
| 72 | void GetNpadJoyHoldType(HLERequestContext& ctx); | ||
| 73 | void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx); | ||
| 74 | void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx); | ||
| 75 | void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx); | ||
| 76 | void MergeSingleJoyAsDualJoy(HLERequestContext& ctx); | ||
| 77 | void StartLrAssignmentMode(HLERequestContext& ctx); | ||
| 78 | void StopLrAssignmentMode(HLERequestContext& ctx); | ||
| 79 | void SetNpadHandheldActivationMode(HLERequestContext& ctx); | ||
| 80 | void GetNpadHandheldActivationMode(HLERequestContext& ctx); | ||
| 81 | void SwapNpadAssignment(HLERequestContext& ctx); | ||
| 82 | void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx); | ||
| 83 | void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx); | ||
| 84 | void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx); | ||
| 85 | void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx); | ||
| 86 | void SetNpadCaptureButtonAssignment(HLERequestContext& ctx); | ||
| 87 | void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx); | ||
| 88 | void GetVibrationDeviceInfo(HLERequestContext& ctx); | ||
| 89 | void SendVibrationValue(HLERequestContext& ctx); | ||
| 90 | void GetActualVibrationValue(HLERequestContext& ctx); | ||
| 91 | void CreateActiveVibrationDeviceList(HLERequestContext& ctx); | ||
| 92 | void PermitVibration(HLERequestContext& ctx); | ||
| 93 | void IsVibrationPermitted(HLERequestContext& ctx); | ||
| 94 | void SendVibrationValues(HLERequestContext& ctx); | ||
| 95 | void SendVibrationGcErmCommand(HLERequestContext& ctx); | ||
| 96 | void GetActualVibrationGcErmCommand(HLERequestContext& ctx); | ||
| 97 | void BeginPermitVibrationSession(HLERequestContext& ctx); | ||
| 98 | void EndPermitVibrationSession(HLERequestContext& ctx); | ||
| 99 | void IsVibrationDeviceMounted(HLERequestContext& ctx); | ||
| 100 | void ActivateConsoleSixAxisSensor(HLERequestContext& ctx); | ||
| 101 | void StartConsoleSixAxisSensor(HLERequestContext& ctx); | ||
| 102 | void StopConsoleSixAxisSensor(HLERequestContext& ctx); | ||
| 103 | void ActivateSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 104 | void StartSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 105 | void StopSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 106 | void InitializeSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 107 | void FinalizeSevenSixAxisSensor(HLERequestContext& ctx); | ||
| 108 | void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx); | ||
| 109 | void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx); | ||
| 110 | void GetPalmaConnectionHandle(HLERequestContext& ctx); | ||
| 111 | void InitializePalma(HLERequestContext& ctx); | ||
| 112 | void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx); | ||
| 113 | void GetPalmaOperationInfo(HLERequestContext& ctx); | ||
| 114 | void PlayPalmaActivity(HLERequestContext& ctx); | ||
| 115 | void SetPalmaFrModeType(HLERequestContext& ctx); | ||
| 116 | void ReadPalmaStep(HLERequestContext& ctx); | ||
| 117 | void EnablePalmaStep(HLERequestContext& ctx); | ||
| 118 | void ResetPalmaStep(HLERequestContext& ctx); | ||
| 119 | void ReadPalmaApplicationSection(HLERequestContext& ctx); | ||
| 120 | void WritePalmaApplicationSection(HLERequestContext& ctx); | ||
| 121 | void ReadPalmaUniqueCode(HLERequestContext& ctx); | ||
| 122 | void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx); | ||
| 123 | void WritePalmaActivityEntry(HLERequestContext& ctx); | ||
| 124 | void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx); | ||
| 125 | void WritePalmaWaveEntry(HLERequestContext& ctx); | ||
| 126 | void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx); | ||
| 127 | void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx); | ||
| 128 | void SuspendPalmaFeature(HLERequestContext& ctx); | ||
| 129 | void GetPalmaOperationResult(HLERequestContext& ctx); | ||
| 130 | void ReadPalmaPlayLog(HLERequestContext& ctx); | ||
| 131 | void ResetPalmaPlayLog(HLERequestContext& ctx); | ||
| 132 | void SetIsPalmaAllConnectable(HLERequestContext& ctx); | ||
| 133 | void SetIsPalmaPairedConnectable(HLERequestContext& ctx); | ||
| 134 | void PairPalma(HLERequestContext& ctx); | ||
| 135 | void SetPalmaBoostMode(HLERequestContext& ctx); | ||
| 136 | void CancelWritePalmaWaveEntry(HLERequestContext& ctx); | ||
| 137 | void EnablePalmaBoostMode(HLERequestContext& ctx); | ||
| 138 | void GetPalmaBluetoothAddress(HLERequestContext& ctx); | ||
| 139 | void SetDisallowedPalmaConnection(HLERequestContext& ctx); | ||
| 140 | void SetNpadCommunicationMode(HLERequestContext& ctx); | ||
| 141 | void GetNpadCommunicationMode(HLERequestContext& ctx); | ||
| 142 | void SetTouchScreenConfiguration(HLERequestContext& ctx); | ||
| 143 | void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx); | ||
| 144 | |||
| 145 | std::shared_ptr<ResourceManager> resource_manager; | ||
| 146 | std::shared_ptr<HidFirmwareSettings> firmware_settings; | ||
| 147 | }; | ||
| 148 | |||
| 149 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp new file mode 100644 index 000000000..b56d0347a --- /dev/null +++ b/src/core/hle/service/hid/hid_system_server.cpp | |||
| @@ -0,0 +1,539 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hid/hid_core.h" | ||
| 5 | #include "core/hle/service/hid/controllers/npad.h" | ||
| 6 | #include "core/hle/service/hid/controllers/touchscreen.h" | ||
| 7 | #include "core/hle/service/hid/errors.h" | ||
| 8 | #include "core/hle/service/hid/hid_system_server.h" | ||
| 9 | #include "core/hle/service/hid/resource_manager.h" | ||
| 10 | #include "core/hle/service/ipc_helpers.h" | ||
| 11 | |||
| 12 | namespace Service::HID { | ||
| 13 | |||
| 14 | IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource) | ||
| 15 | : ServiceFramework{system_, "hid:sys"}, service_context{system_, service_name}, | ||
| 16 | resource_manager{resource} { | ||
| 17 | // clang-format off | ||
| 18 | static const FunctionInfo functions[] = { | ||
| 19 | {31, nullptr, "SendKeyboardLockKeyEvent"}, | ||
| 20 | {101, nullptr, "AcquireHomeButtonEventHandle"}, | ||
| 21 | {111, nullptr, "ActivateHomeButton"}, | ||
| 22 | {121, nullptr, "AcquireSleepButtonEventHandle"}, | ||
| 23 | {131, nullptr, "ActivateSleepButton"}, | ||
| 24 | {141, nullptr, "AcquireCaptureButtonEventHandle"}, | ||
| 25 | {151, nullptr, "ActivateCaptureButton"}, | ||
| 26 | {161, nullptr, "GetPlatformConfig"}, | ||
| 27 | {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"}, | ||
| 28 | {211, nullptr, "GetNpadsWithNfc"}, | ||
| 29 | {212, nullptr, "AcquireNfcActivateEventHandle"}, | ||
| 30 | {213, nullptr, "ActivateNfc"}, | ||
| 31 | {214, nullptr, "GetXcdHandleForNpadWithNfc"}, | ||
| 32 | {215, nullptr, "IsNfcActivated"}, | ||
| 33 | {230, nullptr, "AcquireIrSensorEventHandle"}, | ||
| 34 | {231, nullptr, "ActivateIrSensor"}, | ||
| 35 | {232, nullptr, "GetIrSensorState"}, | ||
| 36 | {233, nullptr, "GetXcdHandleForNpadWithIrSensor"}, | ||
| 37 | {301, nullptr, "ActivateNpadSystem"}, | ||
| 38 | {303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"}, | ||
| 39 | {304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"}, | ||
| 40 | {305, &IHidSystemServer::DisableAssigningSingleOnSlSrPress, "DisableAssigningSingleOnSlSrPress"}, | ||
| 41 | {306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"}, | ||
| 42 | {307, nullptr, "GetNpadSystemExtStyle"}, | ||
| 43 | {308, &IHidSystemServer::ApplyNpadSystemCommonPolicyFull, "ApplyNpadSystemCommonPolicyFull"}, | ||
| 44 | {309, &IHidSystemServer::GetNpadFullKeyGripColor, "GetNpadFullKeyGripColor"}, | ||
| 45 | {310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"}, | ||
| 46 | {311, nullptr, "SetNpadPlayerLedBlinkingDevice"}, | ||
| 47 | {312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"}, | ||
| 48 | {313, nullptr, "GetNpadCaptureButtonAssignment"}, | ||
| 49 | {314, nullptr, "GetAppletFooterUiType"}, | ||
| 50 | {315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"}, | ||
| 51 | {316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"}, | ||
| 52 | {317, &IHidSystemServer::GetNpadLeftRightInterfaceType, "GetNpadLeftRightInterfaceType"}, | ||
| 53 | {318, &IHidSystemServer::HasBattery, "HasBattery"}, | ||
| 54 | {319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"}, | ||
| 55 | {321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"}, | ||
| 56 | {322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"}, | ||
| 57 | {323, nullptr, "GetXcdHandleForNpadWithIrSensor"}, | ||
| 58 | {324, nullptr, "GetUniquePadButtonSet"}, | ||
| 59 | {325, nullptr, "GetUniquePadColor"}, | ||
| 60 | {326, nullptr, "GetUniquePadAppletDetailedUiType"}, | ||
| 61 | {327, nullptr, "GetAbstractedPadIdDataFromNpad"}, | ||
| 62 | {328, nullptr, "AttachAbstractedPadToNpad"}, | ||
| 63 | {329, nullptr, "DetachAbstractedPadAll"}, | ||
| 64 | {330, nullptr, "CheckAbstractedPadConnection"}, | ||
| 65 | {500, nullptr, "SetAppletResourceUserId"}, | ||
| 66 | {501, nullptr, "RegisterAppletResourceUserId"}, | ||
| 67 | {502, nullptr, "UnregisterAppletResourceUserId"}, | ||
| 68 | {503, nullptr, "EnableAppletToGetInput"}, | ||
| 69 | {504, nullptr, "SetAruidValidForVibration"}, | ||
| 70 | {505, nullptr, "EnableAppletToGetSixAxisSensor"}, | ||
| 71 | {506, nullptr, "EnableAppletToGetPadInput"}, | ||
| 72 | {507, nullptr, "EnableAppletToGetTouchScreen"}, | ||
| 73 | {510, nullptr, "SetVibrationMasterVolume"}, | ||
| 74 | {511, nullptr, "GetVibrationMasterVolume"}, | ||
| 75 | {512, nullptr, "BeginPermitVibrationSession"}, | ||
| 76 | {513, nullptr, "EndPermitVibrationSession"}, | ||
| 77 | {514, nullptr, "Unknown514"}, | ||
| 78 | {520, nullptr, "EnableHandheldHids"}, | ||
| 79 | {521, nullptr, "DisableHandheldHids"}, | ||
| 80 | {522, nullptr, "SetJoyConRailEnabled"}, | ||
| 81 | {523, nullptr, "IsJoyConRailEnabled"}, | ||
| 82 | {524, nullptr, "IsHandheldHidsEnabled"}, | ||
| 83 | {525, nullptr, "IsJoyConAttachedOnAllRail"}, | ||
| 84 | {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"}, | ||
| 85 | {541, nullptr, "GetPlayReportControllerUsages"}, | ||
| 86 | {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"}, | ||
| 87 | {543, nullptr, "GetRegisteredDevicesOld"}, | ||
| 88 | {544, &IHidSystemServer::AcquireConnectionTriggerTimeoutEvent, "AcquireConnectionTriggerTimeoutEvent"}, | ||
| 89 | {545, nullptr, "SendConnectionTrigger"}, | ||
| 90 | {546, &IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport, "AcquireDeviceRegisteredEventForControllerSupport"}, | ||
| 91 | {547, nullptr, "GetAllowedBluetoothLinksCount"}, | ||
| 92 | {548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"}, | ||
| 93 | {549, nullptr, "GetConnectableRegisteredDevices"}, | ||
| 94 | {700, nullptr, "ActivateUniquePad"}, | ||
| 95 | {702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"}, | ||
| 96 | {703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"}, | ||
| 97 | {751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"}, | ||
| 98 | {800, nullptr, "ListSixAxisSensorHandles"}, | ||
| 99 | {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"}, | ||
| 100 | {802, nullptr, "ResetSixAxisSensorCalibrationValues"}, | ||
| 101 | {803, nullptr, "StartSixAxisSensorUserCalibration"}, | ||
| 102 | {804, nullptr, "CancelSixAxisSensorUserCalibration"}, | ||
| 103 | {805, nullptr, "GetUniquePadBluetoothAddress"}, | ||
| 104 | {806, nullptr, "DisconnectUniquePad"}, | ||
| 105 | {807, nullptr, "GetUniquePadType"}, | ||
| 106 | {808, nullptr, "GetUniquePadInterface"}, | ||
| 107 | {809, nullptr, "GetUniquePadSerialNumber"}, | ||
| 108 | {810, nullptr, "GetUniquePadControllerNumber"}, | ||
| 109 | {811, nullptr, "GetSixAxisSensorUserCalibrationStage"}, | ||
| 110 | {812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"}, | ||
| 111 | {821, nullptr, "StartAnalogStickManualCalibration"}, | ||
| 112 | {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"}, | ||
| 113 | {823, nullptr, "CancelAnalogStickManualCalibration"}, | ||
| 114 | {824, nullptr, "ResetAnalogStickManualCalibration"}, | ||
| 115 | {825, nullptr, "GetAnalogStickState"}, | ||
| 116 | {826, nullptr, "GetAnalogStickManualCalibrationStage"}, | ||
| 117 | {827, nullptr, "IsAnalogStickButtonPressed"}, | ||
| 118 | {828, nullptr, "IsAnalogStickInReleasePosition"}, | ||
| 119 | {829, nullptr, "IsAnalogStickInCircumference"}, | ||
| 120 | {830, nullptr, "SetNotificationLedPattern"}, | ||
| 121 | {831, nullptr, "SetNotificationLedPatternWithTimeout"}, | ||
| 122 | {832, nullptr, "PrepareHidsForNotificationWake"}, | ||
| 123 | {850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"}, | ||
| 124 | {851, nullptr, "EnableUsbFullKeyController"}, | ||
| 125 | {852, nullptr, "IsUsbConnected"}, | ||
| 126 | {870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"}, | ||
| 127 | {900, nullptr, "ActivateInputDetector"}, | ||
| 128 | {901, nullptr, "NotifyInputDetector"}, | ||
| 129 | {1000, &IHidSystemServer::InitializeFirmwareUpdate, "InitializeFirmwareUpdate"}, | ||
| 130 | {1001, nullptr, "GetFirmwareVersion"}, | ||
| 131 | {1002, nullptr, "GetAvailableFirmwareVersion"}, | ||
| 132 | {1003, nullptr, "IsFirmwareUpdateAvailable"}, | ||
| 133 | {1004, nullptr, "CheckFirmwareUpdateRequired"}, | ||
| 134 | {1005, nullptr, "StartFirmwareUpdate"}, | ||
| 135 | {1006, nullptr, "AbortFirmwareUpdate"}, | ||
| 136 | {1007, nullptr, "GetFirmwareUpdateState"}, | ||
| 137 | {1008, nullptr, "ActivateAudioControl"}, | ||
| 138 | {1009, nullptr, "AcquireAudioControlEventHandle"}, | ||
| 139 | {1010, nullptr, "GetAudioControlStates"}, | ||
| 140 | {1011, nullptr, "DeactivateAudioControl"}, | ||
| 141 | {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"}, | ||
| 142 | {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"}, | ||
| 143 | {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"}, | ||
| 144 | {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"}, | ||
| 145 | {1100, nullptr, "GetHidbusSystemServiceObject"}, | ||
| 146 | {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"}, | ||
| 147 | {1130, nullptr, "InitializeUsbFirmwareUpdate"}, | ||
| 148 | {1131, nullptr, "FinalizeUsbFirmwareUpdate"}, | ||
| 149 | {1132, nullptr, "CheckUsbFirmwareUpdateRequired"}, | ||
| 150 | {1133, nullptr, "StartUsbFirmwareUpdate"}, | ||
| 151 | {1134, nullptr, "GetUsbFirmwareUpdateState"}, | ||
| 152 | {1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"}, | ||
| 153 | {1150, nullptr, "SetTouchScreenMagnification"}, | ||
| 154 | {1151, nullptr, "GetTouchScreenFirmwareVersion"}, | ||
| 155 | {1152, nullptr, "SetTouchScreenDefaultConfiguration"}, | ||
| 156 | {1153, &IHidSystemServer::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"}, | ||
| 157 | {1154, nullptr, "IsFirmwareAvailableForNotification"}, | ||
| 158 | {1155, nullptr, "SetForceHandheldStyleVibration"}, | ||
| 159 | {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"}, | ||
| 160 | {1157, nullptr, "CancelConnectionTrigger"}, | ||
| 161 | {1200, nullptr, "IsButtonConfigSupported"}, | ||
| 162 | {1201, nullptr, "IsButtonConfigEmbeddedSupported"}, | ||
| 163 | {1202, nullptr, "DeleteButtonConfig"}, | ||
| 164 | {1203, nullptr, "DeleteButtonConfigEmbedded"}, | ||
| 165 | {1204, nullptr, "SetButtonConfigEnabled"}, | ||
| 166 | {1205, nullptr, "SetButtonConfigEmbeddedEnabled"}, | ||
| 167 | {1206, nullptr, "IsButtonConfigEnabled"}, | ||
| 168 | {1207, nullptr, "IsButtonConfigEmbeddedEnabled"}, | ||
| 169 | {1208, nullptr, "SetButtonConfigEmbedded"}, | ||
| 170 | {1209, nullptr, "SetButtonConfigFull"}, | ||
| 171 | {1210, nullptr, "SetButtonConfigLeft"}, | ||
| 172 | {1211, nullptr, "SetButtonConfigRight"}, | ||
| 173 | {1212, nullptr, "GetButtonConfigEmbedded"}, | ||
| 174 | {1213, nullptr, "GetButtonConfigFull"}, | ||
| 175 | {1214, nullptr, "GetButtonConfigLeft"}, | ||
| 176 | {1215, nullptr, "GetButtonConfigRight"}, | ||
| 177 | {1250, nullptr, "IsCustomButtonConfigSupported"}, | ||
| 178 | {1251, nullptr, "IsDefaultButtonConfigEmbedded"}, | ||
| 179 | {1252, nullptr, "IsDefaultButtonConfigFull"}, | ||
| 180 | {1253, nullptr, "IsDefaultButtonConfigLeft"}, | ||
| 181 | {1254, nullptr, "IsDefaultButtonConfigRight"}, | ||
| 182 | {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"}, | ||
| 183 | {1256, nullptr, "IsButtonConfigStorageFullEmpty"}, | ||
| 184 | {1257, nullptr, "IsButtonConfigStorageLeftEmpty"}, | ||
| 185 | {1258, nullptr, "IsButtonConfigStorageRightEmpty"}, | ||
| 186 | {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"}, | ||
| 187 | {1260, nullptr, "GetButtonConfigStorageFullDeprecated"}, | ||
| 188 | {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"}, | ||
| 189 | {1262, nullptr, "GetButtonConfigStorageRightDeprecated"}, | ||
| 190 | {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"}, | ||
| 191 | {1264, nullptr, "SetButtonConfigStorageFullDeprecated"}, | ||
| 192 | {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"}, | ||
| 193 | {1266, nullptr, "SetButtonConfigStorageRightDeprecated"}, | ||
| 194 | {1267, nullptr, "DeleteButtonConfigStorageEmbedded"}, | ||
| 195 | {1268, nullptr, "DeleteButtonConfigStorageFull"}, | ||
| 196 | {1269, nullptr, "DeleteButtonConfigStorageLeft"}, | ||
| 197 | {1270, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 198 | {1271, nullptr, "IsUsingCustomButtonConfig"}, | ||
| 199 | {1272, nullptr, "IsAnyCustomButtonConfigEnabled"}, | ||
| 200 | {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, | ||
| 201 | {1274, nullptr, "SetDefaultButtonConfig"}, | ||
| 202 | {1275, nullptr, "SetAllDefaultButtonConfig"}, | ||
| 203 | {1276, nullptr, "SetHidButtonConfigEmbedded"}, | ||
| 204 | {1277, nullptr, "SetHidButtonConfigFull"}, | ||
| 205 | {1278, nullptr, "SetHidButtonConfigLeft"}, | ||
| 206 | {1279, nullptr, "SetHidButtonConfigRight"}, | ||
| 207 | {1280, nullptr, "GetHidButtonConfigEmbedded"}, | ||
| 208 | {1281, nullptr, "GetHidButtonConfigFull"}, | ||
| 209 | {1282, nullptr, "GetHidButtonConfigLeft"}, | ||
| 210 | {1283, nullptr, "GetHidButtonConfigRight"}, | ||
| 211 | {1284, nullptr, "GetButtonConfigStorageEmbedded"}, | ||
| 212 | {1285, nullptr, "GetButtonConfigStorageFull"}, | ||
| 213 | {1286, nullptr, "GetButtonConfigStorageLeft"}, | ||
| 214 | {1287, nullptr, "GetButtonConfigStorageRight"}, | ||
| 215 | {1288, nullptr, "SetButtonConfigStorageEmbedded"}, | ||
| 216 | {1289, nullptr, "SetButtonConfigStorageFull"}, | ||
| 217 | {1290, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 218 | {1291, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 219 | }; | ||
| 220 | // clang-format on | ||
| 221 | |||
| 222 | RegisterHandlers(functions); | ||
| 223 | |||
| 224 | joy_detach_event = service_context.CreateEvent("IHidSystemServer::JoyDetachEvent"); | ||
| 225 | acquire_device_registered_event = | ||
| 226 | service_context.CreateEvent("IHidSystemServer::AcquireDeviceRegisteredEvent"); | ||
| 227 | acquire_connection_trigger_timeout_event = | ||
| 228 | service_context.CreateEvent("IHidSystemServer::AcquireConnectionTriggerTimeoutEvent"); | ||
| 229 | unique_pad_connection_event = | ||
| 230 | service_context.CreateEvent("IHidSystemServer::AcquireUniquePadConnectionEventHandle"); | ||
| 231 | } | ||
| 232 | |||
| 233 | IHidSystemServer::~IHidSystemServer() { | ||
| 234 | service_context.CloseEvent(joy_detach_event); | ||
| 235 | service_context.CloseEvent(acquire_device_registered_event); | ||
| 236 | service_context.CloseEvent(acquire_connection_trigger_timeout_event); | ||
| 237 | service_context.CloseEvent(unique_pad_connection_event); | ||
| 238 | }; | ||
| 239 | |||
| 240 | void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) { | ||
| 241 | LOG_WARNING(Service_HID, "called"); | ||
| 242 | |||
| 243 | GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy(); | ||
| 244 | |||
| 245 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 246 | rb.Push(ResultSuccess); | ||
| 247 | } | ||
| 248 | |||
| 249 | void IHidSystemServer::EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx) { | ||
| 250 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 251 | |||
| 252 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 253 | rb.Push(ResultSuccess); | ||
| 254 | } | ||
| 255 | |||
| 256 | void IHidSystemServer::DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx) { | ||
| 257 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 258 | |||
| 259 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 260 | rb.Push(ResultSuccess); | ||
| 261 | } | ||
| 262 | |||
| 263 | void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) { | ||
| 264 | LOG_DEBUG(Service_HID, "(STUBBED) called"); // Spams a lot when controller applet is running | ||
| 265 | |||
| 266 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 267 | rb.Push(ResultSuccess); | ||
| 268 | rb.PushEnum(system.HIDCore().GetLastActiveController()); | ||
| 269 | } | ||
| 270 | |||
| 271 | void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) { | ||
| 272 | LOG_WARNING(Service_HID, "called"); | ||
| 273 | |||
| 274 | GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy(); | ||
| 275 | |||
| 276 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 277 | rb.Push(ResultSuccess); | ||
| 278 | } | ||
| 279 | |||
| 280 | void IHidSystemServer::GetNpadFullKeyGripColor(HLERequestContext& ctx) { | ||
| 281 | IPC::RequestParser rp{ctx}; | ||
| 282 | const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 283 | |||
| 284 | LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||
| 285 | npad_id_type); // Spams a lot when controller applet is running | ||
| 286 | |||
| 287 | Core::HID::NpadColor left_color{}; | ||
| 288 | Core::HID::NpadColor right_color{}; | ||
| 289 | // TODO: Get colors from Npad | ||
| 290 | |||
| 291 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 292 | rb.Push(ResultSuccess); | ||
| 293 | rb.PushRaw(left_color); | ||
| 294 | rb.PushRaw(right_color); | ||
| 295 | } | ||
| 296 | |||
| 297 | void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) { | ||
| 298 | IPC::RequestParser rp{ctx}; | ||
| 299 | |||
| 300 | LOG_INFO(Service_HID, "(STUBBED) called"); | ||
| 301 | |||
| 302 | Core::HID::NpadStyleSet supported_styleset = | ||
| 303 | GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw; | ||
| 304 | |||
| 305 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 306 | rb.Push(ResultSuccess); | ||
| 307 | rb.PushEnum(supported_styleset); | ||
| 308 | } | ||
| 309 | |||
| 310 | void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) { | ||
| 311 | IPC::RequestParser rp{ctx}; | ||
| 312 | |||
| 313 | LOG_INFO(Service_HID, "(STUBBED) called"); | ||
| 314 | |||
| 315 | Core::HID::NpadStyleSet supported_styleset = | ||
| 316 | GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw; | ||
| 317 | |||
| 318 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 319 | rb.Push(ResultSuccess); | ||
| 320 | rb.PushEnum(supported_styleset); | ||
| 321 | } | ||
| 322 | |||
| 323 | void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) { | ||
| 324 | IPC::RequestParser rp{ctx}; | ||
| 325 | const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 326 | |||
| 327 | LOG_DEBUG(Service_HID, "called, npad_id_type={}", | ||
| 328 | npad_id_type); // Spams a lot when controller applet is running | ||
| 329 | |||
| 330 | const NPad::AppletDetailedUiType detailed_ui_type = | ||
| 331 | GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type); | ||
| 332 | |||
| 333 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 334 | rb.Push(ResultSuccess); | ||
| 335 | rb.PushRaw(detailed_ui_type); | ||
| 336 | } | ||
| 337 | |||
| 338 | void IHidSystemServer::GetNpadInterfaceType(HLERequestContext& ctx) { | ||
| 339 | IPC::RequestParser rp{ctx}; | ||
| 340 | const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 341 | |||
| 342 | LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||
| 343 | npad_id_type); // Spams a lot when controller applet is running | ||
| 344 | |||
| 345 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 346 | rb.Push(ResultSuccess); | ||
| 347 | rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth); | ||
| 348 | } | ||
| 349 | |||
| 350 | void IHidSystemServer::GetNpadLeftRightInterfaceType(HLERequestContext& ctx) { | ||
| 351 | IPC::RequestParser rp{ctx}; | ||
| 352 | const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 353 | |||
| 354 | LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||
| 355 | npad_id_type); // Spams a lot when controller applet is running | ||
| 356 | |||
| 357 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 358 | rb.Push(ResultSuccess); | ||
| 359 | rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth); | ||
| 360 | rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth); | ||
| 361 | } | ||
| 362 | |||
| 363 | void IHidSystemServer::HasBattery(HLERequestContext& ctx) { | ||
| 364 | IPC::RequestParser rp{ctx}; | ||
| 365 | const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 366 | |||
| 367 | LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||
| 368 | npad_id_type); // Spams a lot when controller applet is running | ||
| 369 | |||
| 370 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 371 | rb.Push(ResultSuccess); | ||
| 372 | rb.Push(false); | ||
| 373 | } | ||
| 374 | |||
| 375 | void IHidSystemServer::HasLeftRightBattery(HLERequestContext& ctx) { | ||
| 376 | IPC::RequestParser rp{ctx}; | ||
| 377 | const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 378 | |||
| 379 | LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||
| 380 | npad_id_type); // Spams a lot when controller applet is running | ||
| 381 | |||
| 382 | struct LeftRightBattery { | ||
| 383 | bool left; | ||
| 384 | bool right; | ||
| 385 | }; | ||
| 386 | |||
| 387 | LeftRightBattery left_right_battery{ | ||
| 388 | .left = false, | ||
| 389 | .right = false, | ||
| 390 | }; | ||
| 391 | |||
| 392 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 393 | rb.Push(ResultSuccess); | ||
| 394 | rb.PushRaw(left_right_battery); | ||
| 395 | } | ||
| 396 | |||
| 397 | void IHidSystemServer::GetUniquePadsFromNpad(HLERequestContext& ctx) { | ||
| 398 | IPC::RequestParser rp{ctx}; | ||
| 399 | const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; | ||
| 400 | |||
| 401 | LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}", | ||
| 402 | npad_id_type); // Spams a lot when controller applet is running | ||
| 403 | |||
| 404 | const std::vector<Core::HID::UniquePadId> unique_pads{}; | ||
| 405 | |||
| 406 | if (!unique_pads.empty()) { | ||
| 407 | ctx.WriteBuffer(unique_pads); | ||
| 408 | } | ||
| 409 | |||
| 410 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 411 | rb.Push(ResultSuccess); | ||
| 412 | rb.Push(static_cast<u32>(unique_pads.size())); | ||
| 413 | } | ||
| 414 | |||
| 415 | void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) { | ||
| 416 | IPC::RequestParser rp{ctx}; | ||
| 417 | |||
| 418 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 419 | |||
| 420 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 421 | rb.Push(ResultSuccess); | ||
| 422 | } | ||
| 423 | |||
| 424 | void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) { | ||
| 425 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
| 426 | |||
| 427 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 428 | rb.Push(ResultSuccess); | ||
| 429 | rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent()); | ||
| 430 | } | ||
| 431 | |||
| 432 | void IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx) { | ||
| 433 | LOG_INFO(Service_HID, "(STUBBED) called"); | ||
| 434 | |||
| 435 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 436 | rb.Push(ResultSuccess); | ||
| 437 | rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent()); | ||
| 438 | } | ||
| 439 | |||
| 440 | void IHidSystemServer::GetRegisteredDevices(HLERequestContext& ctx) { | ||
| 441 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 442 | |||
| 443 | struct RegisterData { | ||
| 444 | std::array<u8, 0x68> data; | ||
| 445 | }; | ||
| 446 | static_assert(sizeof(RegisterData) == 0x68, "RegisterData is an invalid size"); | ||
| 447 | std::vector<RegisterData> registered_devices{}; | ||
| 448 | |||
| 449 | if (!registered_devices.empty()) { | ||
| 450 | ctx.WriteBuffer(registered_devices); | ||
| 451 | } | ||
| 452 | |||
| 453 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 454 | rb.Push(ResultSuccess); | ||
| 455 | rb.Push<u64>(registered_devices.size()); | ||
| 456 | } | ||
| 457 | |||
| 458 | void IHidSystemServer::AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx) { | ||
| 459 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 460 | |||
| 461 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 462 | rb.PushCopyObjects(unique_pad_connection_event->GetReadableEvent()); | ||
| 463 | rb.Push(ResultSuccess); | ||
| 464 | } | ||
| 465 | |||
| 466 | void IHidSystemServer::GetUniquePadIds(HLERequestContext& ctx) { | ||
| 467 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 468 | |||
| 469 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 470 | rb.Push(ResultSuccess); | ||
| 471 | rb.Push<u64>(0); | ||
| 472 | } | ||
| 473 | |||
| 474 | void IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) { | ||
| 475 | LOG_INFO(Service_AM, "called"); | ||
| 476 | |||
| 477 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 478 | rb.Push(ResultSuccess); | ||
| 479 | rb.PushCopyObjects(joy_detach_event->GetReadableEvent()); | ||
| 480 | } | ||
| 481 | |||
| 482 | void IHidSystemServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) { | ||
| 483 | const bool is_enabled = false; | ||
| 484 | |||
| 485 | LOG_WARNING(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled); | ||
| 486 | |||
| 487 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 488 | rb.Push(ResultSuccess); | ||
| 489 | rb.Push(is_enabled); | ||
| 490 | } | ||
| 491 | |||
| 492 | void IHidSystemServer::IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx) { | ||
| 493 | const bool button_pressed = false; | ||
| 494 | |||
| 495 | LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}", | ||
| 496 | button_pressed); // Spams a lot when controller applet is open | ||
| 497 | |||
| 498 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 499 | rb.Push(ResultSuccess); | ||
| 500 | rb.Push(button_pressed); | ||
| 501 | } | ||
| 502 | |||
| 503 | void IHidSystemServer::InitializeFirmwareUpdate(HLERequestContext& ctx) { | ||
| 504 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 505 | |||
| 506 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 507 | rb.Push(ResultSuccess); | ||
| 508 | } | ||
| 509 | |||
| 510 | void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) { | ||
| 511 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 512 | |||
| 513 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 514 | rb.Push(ResultSuccess); | ||
| 515 | } | ||
| 516 | |||
| 517 | void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) { | ||
| 518 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 519 | |||
| 520 | Core::HID::TouchScreenConfigurationForNx touchscreen_config{ | ||
| 521 | .mode = Core::HID::TouchScreenModeForNx::Finger, | ||
| 522 | }; | ||
| 523 | |||
| 524 | if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 && | ||
| 525 | touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) { | ||
| 526 | touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting; | ||
| 527 | } | ||
| 528 | |||
| 529 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 530 | rb.Push(ResultSuccess); | ||
| 531 | rb.PushRaw(touchscreen_config); | ||
| 532 | } | ||
| 533 | |||
| 534 | std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() { | ||
| 535 | resource_manager->Initialize(); | ||
| 536 | return resource_manager; | ||
| 537 | } | ||
| 538 | |||
| 539 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h new file mode 100644 index 000000000..822d5e5b9 --- /dev/null +++ b/src/core/hle/service/hid/hid_system_server.h | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/kernel_helpers.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | class KEvent; | ||
| 15 | } | ||
| 16 | |||
| 17 | namespace Service::HID { | ||
| 18 | class ResourceManager; | ||
| 19 | |||
| 20 | class IHidSystemServer final : public ServiceFramework<IHidSystemServer> { | ||
| 21 | public: | ||
| 22 | explicit IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource); | ||
| 23 | ~IHidSystemServer() override; | ||
| 24 | |||
| 25 | private: | ||
| 26 | void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx); | ||
| 27 | void EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx); | ||
| 28 | void DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx); | ||
| 29 | void GetLastActiveNpad(HLERequestContext& ctx); | ||
| 30 | void ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx); | ||
| 31 | void GetNpadFullKeyGripColor(HLERequestContext& ctx); | ||
| 32 | void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx); | ||
| 33 | void SetSupportedNpadStyleSetAll(HLERequestContext& ctx); | ||
| 34 | void GetAppletDetailedUiType(HLERequestContext& ctx); | ||
| 35 | void GetNpadInterfaceType(HLERequestContext& ctx); | ||
| 36 | void GetNpadLeftRightInterfaceType(HLERequestContext& ctx); | ||
| 37 | void HasBattery(HLERequestContext& ctx); | ||
| 38 | void HasLeftRightBattery(HLERequestContext& ctx); | ||
| 39 | void GetUniquePadsFromNpad(HLERequestContext& ctx); | ||
| 40 | void GetIrSensorState(HLERequestContext& ctx); | ||
| 41 | void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx); | ||
| 42 | void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx); | ||
| 43 | void GetRegisteredDevices(HLERequestContext& ctx); | ||
| 44 | void AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx); | ||
| 45 | void GetUniquePadIds(HLERequestContext& ctx); | ||
| 46 | void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx); | ||
| 47 | void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx); | ||
| 48 | void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx); | ||
| 49 | void InitializeFirmwareUpdate(HLERequestContext& ctx); | ||
| 50 | void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx); | ||
| 51 | void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); | ||
| 52 | |||
| 53 | std::shared_ptr<ResourceManager> GetResourceManager(); | ||
| 54 | |||
| 55 | Kernel::KEvent* acquire_connection_trigger_timeout_event; | ||
| 56 | Kernel::KEvent* acquire_device_registered_event; | ||
| 57 | Kernel::KEvent* joy_detach_event; | ||
| 58 | Kernel::KEvent* unique_pad_connection_event; | ||
| 59 | KernelHelpers::ServiceContext service_context; | ||
| 60 | std::shared_ptr<ResourceManager> resource_manager; | ||
| 61 | }; | ||
| 62 | |||
| 63 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/hid_util.h b/src/core/hle/service/hid/hid_util.h new file mode 100644 index 000000000..b87cc10e3 --- /dev/null +++ b/src/core/hle/service/hid/hid_util.h | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hid/hid_types.h" | ||
| 7 | #include "core/hle/service/hid/errors.h" | ||
| 8 | |||
| 9 | namespace Service::HID { | ||
| 10 | |||
| 11 | constexpr bool IsNpadIdValid(const Core::HID::NpadIdType npad_id) { | ||
| 12 | switch (npad_id) { | ||
| 13 | case Core::HID::NpadIdType::Player1: | ||
| 14 | case Core::HID::NpadIdType::Player2: | ||
| 15 | case Core::HID::NpadIdType::Player3: | ||
| 16 | case Core::HID::NpadIdType::Player4: | ||
| 17 | case Core::HID::NpadIdType::Player5: | ||
| 18 | case Core::HID::NpadIdType::Player6: | ||
| 19 | case Core::HID::NpadIdType::Player7: | ||
| 20 | case Core::HID::NpadIdType::Player8: | ||
| 21 | case Core::HID::NpadIdType::Other: | ||
| 22 | case Core::HID::NpadIdType::Handheld: | ||
| 23 | return true; | ||
| 24 | default: | ||
| 25 | return false; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | constexpr Result IsSixaxisHandleValid(const Core::HID::SixAxisSensorHandle& handle) { | ||
| 30 | const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id)); | ||
| 31 | const bool device_index = handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex; | ||
| 32 | |||
| 33 | if (!npad_id) { | ||
| 34 | return InvalidNpadId; | ||
| 35 | } | ||
| 36 | if (!device_index) { | ||
| 37 | return NpadDeviceIndexOutOfRange; | ||
| 38 | } | ||
| 39 | |||
| 40 | return ResultSuccess; | ||
| 41 | } | ||
| 42 | |||
| 43 | constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle& handle) { | ||
| 44 | switch (handle.npad_type) { | ||
| 45 | case Core::HID::NpadStyleIndex::ProController: | ||
| 46 | case Core::HID::NpadStyleIndex::Handheld: | ||
| 47 | case Core::HID::NpadStyleIndex::JoyconDual: | ||
| 48 | case Core::HID::NpadStyleIndex::JoyconLeft: | ||
| 49 | case Core::HID::NpadStyleIndex::JoyconRight: | ||
| 50 | case Core::HID::NpadStyleIndex::GameCube: | ||
| 51 | case Core::HID::NpadStyleIndex::N64: | ||
| 52 | case Core::HID::NpadStyleIndex::SystemExt: | ||
| 53 | case Core::HID::NpadStyleIndex::System: | ||
| 54 | // These support vibration | ||
| 55 | break; | ||
| 56 | default: | ||
| 57 | return VibrationInvalidStyleIndex; | ||
| 58 | } | ||
| 59 | |||
| 60 | if (!IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id))) { | ||
| 61 | return VibrationInvalidNpadId; | ||
| 62 | } | ||
| 63 | |||
| 64 | if (handle.device_index >= Core::HID::DeviceIndex::MaxDeviceIndex) { | ||
| 65 | return VibrationDeviceIndexOutOfRange; | ||
| 66 | } | ||
| 67 | |||
| 68 | return ResultSuccess; | ||
| 69 | } | ||
| 70 | |||
| 71 | /// Converts a Core::HID::NpadIdType to an array index. | ||
| 72 | constexpr size_t NpadIdTypeToIndex(Core::HID::NpadIdType npad_id_type) { | ||
| 73 | switch (npad_id_type) { | ||
| 74 | case Core::HID::NpadIdType::Player1: | ||
| 75 | return 0; | ||
| 76 | case Core::HID::NpadIdType::Player2: | ||
| 77 | return 1; | ||
| 78 | case Core::HID::NpadIdType::Player3: | ||
| 79 | return 2; | ||
| 80 | case Core::HID::NpadIdType::Player4: | ||
| 81 | return 3; | ||
| 82 | case Core::HID::NpadIdType::Player5: | ||
| 83 | return 4; | ||
| 84 | case Core::HID::NpadIdType::Player6: | ||
| 85 | return 5; | ||
| 86 | case Core::HID::NpadIdType::Player7: | ||
| 87 | return 6; | ||
| 88 | case Core::HID::NpadIdType::Player8: | ||
| 89 | return 7; | ||
| 90 | case Core::HID::NpadIdType::Handheld: | ||
| 91 | return 8; | ||
| 92 | case Core::HID::NpadIdType::Other: | ||
| 93 | return 9; | ||
| 94 | default: | ||
| 95 | return 8; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | /// Converts an array index to a Core::HID::NpadIdType | ||
| 100 | constexpr Core::HID::NpadIdType IndexToNpadIdType(size_t index) { | ||
| 101 | switch (index) { | ||
| 102 | case 0: | ||
| 103 | return Core::HID::NpadIdType::Player1; | ||
| 104 | case 1: | ||
| 105 | return Core::HID::NpadIdType::Player2; | ||
| 106 | case 2: | ||
| 107 | return Core::HID::NpadIdType::Player3; | ||
| 108 | case 3: | ||
| 109 | return Core::HID::NpadIdType::Player4; | ||
| 110 | case 4: | ||
| 111 | return Core::HID::NpadIdType::Player5; | ||
| 112 | case 5: | ||
| 113 | return Core::HID::NpadIdType::Player6; | ||
| 114 | case 6: | ||
| 115 | return Core::HID::NpadIdType::Player7; | ||
| 116 | case 7: | ||
| 117 | return Core::HID::NpadIdType::Player8; | ||
| 118 | case 8: | ||
| 119 | return Core::HID::NpadIdType::Handheld; | ||
| 120 | case 9: | ||
| 121 | return Core::HID::NpadIdType::Other; | ||
| 122 | default: | ||
| 123 | return Core::HID::NpadIdType::Invalid; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | constexpr Core::HID::NpadStyleSet GetStylesetByIndex(std::size_t index) { | ||
| 128 | switch (index) { | ||
| 129 | case 0: | ||
| 130 | return Core::HID::NpadStyleSet::Fullkey; | ||
| 131 | case 1: | ||
| 132 | return Core::HID::NpadStyleSet::Handheld; | ||
| 133 | case 2: | ||
| 134 | return Core::HID::NpadStyleSet::JoyDual; | ||
| 135 | case 3: | ||
| 136 | return Core::HID::NpadStyleSet::JoyLeft; | ||
| 137 | case 4: | ||
| 138 | return Core::HID::NpadStyleSet::JoyRight; | ||
| 139 | case 5: | ||
| 140 | return Core::HID::NpadStyleSet::Palma; | ||
| 141 | default: | ||
| 142 | return Core::HID::NpadStyleSet::None; | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 221c33b86..39b9a4474 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "core/hle/kernel/k_transfer_memory.h" | 12 | #include "core/hle/kernel/k_transfer_memory.h" |
| 13 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/service/hid/errors.h" | 14 | #include "core/hle/service/hid/errors.h" |
| 15 | #include "core/hle/service/hid/hid_util.h" | ||
| 15 | #include "core/hle/service/hid/irs.h" | 16 | #include "core/hle/service/hid/irs.h" |
| 16 | #include "core/hle/service/hid/irsensor/clustering_processor.h" | 17 | #include "core/hle/service/hid/irsensor/clustering_processor.h" |
| 17 | #include "core/hle/service/hid/irsensor/image_transfer_processor.h" | 18 | #include "core/hle/service/hid/irsensor/image_transfer_processor.h" |
| @@ -138,7 +139,7 @@ void IRS::RunMomentProcessor(HLERequestContext& ctx) { | |||
| 138 | 139 | ||
| 139 | if (result.IsSuccess()) { | 140 | if (result.IsSuccess()) { |
| 140 | auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle); | 141 | auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle); |
| 141 | MakeProcessor<MomentProcessor>(parameters.camera_handle, device); | 142 | MakeProcessorWithCoreContext<MomentProcessor>(parameters.camera_handle, device); |
| 142 | auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle); | 143 | auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle); |
| 143 | image_transfer_processor.SetConfig(parameters.processor_config); | 144 | image_transfer_processor.SetConfig(parameters.processor_config); |
| 144 | npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, | 145 | npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, |
| @@ -320,7 +321,7 @@ void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) { | |||
| 320 | } | 321 | } |
| 321 | 322 | ||
| 322 | Core::IrSensor::IrCameraHandle camera_handle{ | 323 | Core::IrSensor::IrCameraHandle camera_handle{ |
| 323 | .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)), | 324 | .npad_id = static_cast<u8>(HID::NpadIdTypeToIndex(npad_id)), |
| 324 | .npad_type = Core::HID::NpadStyleIndex::None, | 325 | .npad_type = Core::HID::NpadStyleIndex::None, |
| 325 | }; | 326 | }; |
| 326 | 327 | ||
| @@ -545,7 +546,7 @@ void IRS::ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx) { | |||
| 545 | 546 | ||
| 546 | Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const { | 547 | Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const { |
| 547 | if (camera_handle.npad_id > | 548 | if (camera_handle.npad_id > |
| 548 | static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) { | 549 | static_cast<u8>(HID::NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) { |
| 549 | return InvalidIrCameraHandle; | 550 | return InvalidIrCameraHandle; |
| 550 | } | 551 | } |
| 551 | if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) { | 552 | if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) { |
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index a8fa19025..c8e6dab17 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h | |||
| @@ -3,15 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/core.h" | ||
| 6 | #include "core/hid/hid_types.h" | 7 | #include "core/hid/hid_types.h" |
| 7 | #include "core/hid/irs_types.h" | 8 | #include "core/hid/irs_types.h" |
| 8 | #include "core/hle/service/hid/irsensor/processor_base.h" | 9 | #include "core/hle/service/hid/irsensor/processor_base.h" |
| 9 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 10 | 11 | ||
| 11 | namespace Core { | ||
| 12 | class System; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace Core::HID { | 12 | namespace Core::HID { |
| 16 | class EmulatedController; | 13 | class EmulatedController; |
| 17 | } // namespace Core::HID | 14 | } // namespace Core::HID |
diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.cpp b/src/core/hle/service/hid/irsensor/clustering_processor.cpp index e2f4ae876..c559eb0d5 100644 --- a/src/core/hle/service/hid/irsensor/clustering_processor.cpp +++ b/src/core/hle/service/hid/irsensor/clustering_processor.cpp | |||
| @@ -3,16 +3,18 @@ | |||
| 3 | 3 | ||
| 4 | #include <queue> | 4 | #include <queue> |
| 5 | 5 | ||
| 6 | #include "core/core.h" | ||
| 7 | #include "core/core_timing.h" | ||
| 6 | #include "core/hid/emulated_controller.h" | 8 | #include "core/hid/emulated_controller.h" |
| 7 | #include "core/hid/hid_core.h" | 9 | #include "core/hid/hid_core.h" |
| 8 | #include "core/hle/service/hid/irsensor/clustering_processor.h" | 10 | #include "core/hle/service/hid/irsensor/clustering_processor.h" |
| 9 | 11 | ||
| 10 | namespace Service::IRS { | 12 | namespace Service::IRS { |
| 11 | ClusteringProcessor::ClusteringProcessor(Core::HID::HIDCore& hid_core_, | 13 | ClusteringProcessor::ClusteringProcessor(Core::System& system_, |
| 12 | Core::IrSensor::DeviceFormat& device_format, | 14 | Core::IrSensor::DeviceFormat& device_format, |
| 13 | std::size_t npad_index) | 15 | std::size_t npad_index) |
| 14 | : device{device_format} { | 16 | : device{device_format}, system{system_} { |
| 15 | npad_device = hid_core_.GetEmulatedControllerByIndex(npad_index); | 17 | npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index); |
| 16 | 18 | ||
| 17 | device.mode = Core::IrSensor::IrSensorMode::ClusteringProcessor; | 19 | device.mode = Core::IrSensor::IrSensorMode::ClusteringProcessor; |
| 18 | device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; | 20 | device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; |
| @@ -48,7 +50,7 @@ void ClusteringProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType ty | |||
| 48 | } | 50 | } |
| 49 | 51 | ||
| 50 | next_state = {}; | 52 | next_state = {}; |
| 51 | const auto camera_data = npad_device->GetCamera(); | 53 | const auto& camera_data = npad_device->GetCamera(); |
| 52 | auto filtered_image = camera_data.data; | 54 | auto filtered_image = camera_data.data; |
| 53 | 55 | ||
| 54 | RemoveLowIntensityData(filtered_image); | 56 | RemoveLowIntensityData(filtered_image); |
| @@ -83,7 +85,7 @@ void ClusteringProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType ty | |||
| 83 | } | 85 | } |
| 84 | 86 | ||
| 85 | next_state.sampling_number = camera_data.sample; | 87 | next_state.sampling_number = camera_data.sample; |
| 86 | next_state.timestamp = next_state.timestamp + 131; | 88 | next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count(); |
| 87 | next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; | 89 | next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; |
| 88 | shared_memory->clustering_lifo.WriteNextEntry(next_state); | 90 | shared_memory->clustering_lifo.WriteNextEntry(next_state); |
| 89 | 91 | ||
| @@ -202,14 +204,14 @@ ClusteringProcessor::ClusteringData ClusteringProcessor::MergeCluster( | |||
| 202 | } | 204 | } |
| 203 | 205 | ||
| 204 | u8 ClusteringProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const { | 206 | u8 ClusteringProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const { |
| 205 | if ((y * width) + x > data.size()) { | 207 | if ((y * width) + x >= data.size()) { |
| 206 | return 0; | 208 | return 0; |
| 207 | } | 209 | } |
| 208 | return data[(y * width) + x]; | 210 | return data[(y * width) + x]; |
| 209 | } | 211 | } |
| 210 | 212 | ||
| 211 | void ClusteringProcessor::SetPixel(std::vector<u8>& data, std::size_t x, std::size_t y, u8 value) { | 213 | void ClusteringProcessor::SetPixel(std::vector<u8>& data, std::size_t x, std::size_t y, u8 value) { |
| 212 | if ((y * width) + x > data.size()) { | 214 | if ((y * width) + x >= data.size()) { |
| 213 | return; | 215 | return; |
| 214 | } | 216 | } |
| 215 | data[(y * width) + x] = value; | 217 | data[(y * width) + x] = value; |
diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.h b/src/core/hle/service/hid/irsensor/clustering_processor.h index dc01a8ea7..83f34734a 100644 --- a/src/core/hle/service/hid/irsensor/clustering_processor.h +++ b/src/core/hle/service/hid/irsensor/clustering_processor.h | |||
| @@ -8,6 +8,10 @@ | |||
| 8 | #include "core/hle/service/hid/irs_ring_lifo.h" | 8 | #include "core/hle/service/hid/irs_ring_lifo.h" |
| 9 | #include "core/hle/service/hid/irsensor/processor_base.h" | 9 | #include "core/hle/service/hid/irsensor/processor_base.h" |
| 10 | 10 | ||
| 11 | namespace Core { | ||
| 12 | class System; | ||
| 13 | } | ||
| 14 | |||
| 11 | namespace Core::HID { | 15 | namespace Core::HID { |
| 12 | class EmulatedController; | 16 | class EmulatedController; |
| 13 | } // namespace Core::HID | 17 | } // namespace Core::HID |
| @@ -15,8 +19,7 @@ class EmulatedController; | |||
| 15 | namespace Service::IRS { | 19 | namespace Service::IRS { |
| 16 | class ClusteringProcessor final : public ProcessorBase { | 20 | class ClusteringProcessor final : public ProcessorBase { |
| 17 | public: | 21 | public: |
| 18 | explicit ClusteringProcessor(Core::HID::HIDCore& hid_core_, | 22 | explicit ClusteringProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format, |
| 19 | Core::IrSensor::DeviceFormat& device_format, | ||
| 20 | std::size_t npad_index); | 23 | std::size_t npad_index); |
| 21 | ~ClusteringProcessor() override; | 24 | ~ClusteringProcessor() override; |
| 22 | 25 | ||
| @@ -106,5 +109,7 @@ private: | |||
| 106 | Core::IrSensor::DeviceFormat& device; | 109 | Core::IrSensor::DeviceFormat& device; |
| 107 | Core::HID::EmulatedController* npad_device; | 110 | Core::HID::EmulatedController* npad_device; |
| 108 | int callback_key{}; | 111 | int callback_key{}; |
| 112 | |||
| 113 | Core::System& system; | ||
| 109 | }; | 114 | }; |
| 110 | } // namespace Service::IRS | 115 | } // namespace Service::IRS |
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp index 803a6277c..22067a591 100644 --- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp +++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp | |||
| @@ -49,7 +49,7 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType | |||
| 49 | return; | 49 | return; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | const auto camera_data = npad_device->GetCamera(); | 52 | const auto& camera_data = npad_device->GetCamera(); |
| 53 | 53 | ||
| 54 | // This indicates how much ambient light is present | 54 | // This indicates how much ambient light is present |
| 55 | processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; | 55 | processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; |
diff --git a/src/core/hle/service/hid/irsensor/moment_processor.cpp b/src/core/hle/service/hid/irsensor/moment_processor.cpp index dbaca420a..cf045bda7 100644 --- a/src/core/hle/service/hid/irsensor/moment_processor.cpp +++ b/src/core/hle/service/hid/irsensor/moment_processor.cpp | |||
| @@ -1,24 +1,137 @@ | |||
| 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/core.h" | ||
| 5 | #include "core/core_timing.h" | ||
| 6 | #include "core/hid/emulated_controller.h" | ||
| 7 | #include "core/hid/hid_core.h" | ||
| 4 | #include "core/hle/service/hid/irsensor/moment_processor.h" | 8 | #include "core/hle/service/hid/irsensor/moment_processor.h" |
| 5 | 9 | ||
| 6 | namespace Service::IRS { | 10 | namespace Service::IRS { |
| 7 | MomentProcessor::MomentProcessor(Core::IrSensor::DeviceFormat& device_format) | 11 | static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Size40x30; |
| 8 | : device(device_format) { | 12 | static constexpr std::size_t ImageWidth = 40; |
| 13 | static constexpr std::size_t ImageHeight = 30; | ||
| 14 | |||
| 15 | MomentProcessor::MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format, | ||
| 16 | std::size_t npad_index) | ||
| 17 | : device(device_format), system{system_} { | ||
| 18 | npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index); | ||
| 19 | |||
| 9 | device.mode = Core::IrSensor::IrSensorMode::MomentProcessor; | 20 | device.mode = Core::IrSensor::IrSensorMode::MomentProcessor; |
| 10 | device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; | 21 | device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; |
| 11 | device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped; | 22 | device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped; |
| 23 | |||
| 24 | shared_memory = std::construct_at( | ||
| 25 | reinterpret_cast<MomentSharedMemory*>(&device_format.state.processor_raw_data)); | ||
| 26 | |||
| 27 | Core::HID::ControllerUpdateCallback engine_callback{ | ||
| 28 | .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); }, | ||
| 29 | .is_npad_service = true, | ||
| 30 | }; | ||
| 31 | callback_key = npad_device->SetCallback(engine_callback); | ||
| 12 | } | 32 | } |
| 13 | 33 | ||
| 14 | MomentProcessor::~MomentProcessor() = default; | 34 | MomentProcessor::~MomentProcessor() { |
| 35 | npad_device->DeleteCallback(callback_key); | ||
| 36 | }; | ||
| 15 | 37 | ||
| 16 | void MomentProcessor::StartProcessor() {} | 38 | void MomentProcessor::StartProcessor() { |
| 39 | device.camera_status = Core::IrSensor::IrCameraStatus::Available; | ||
| 40 | device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready; | ||
| 41 | } | ||
| 17 | 42 | ||
| 18 | void MomentProcessor::SuspendProcessor() {} | 43 | void MomentProcessor::SuspendProcessor() {} |
| 19 | 44 | ||
| 20 | void MomentProcessor::StopProcessor() {} | 45 | void MomentProcessor::StopProcessor() {} |
| 21 | 46 | ||
| 47 | void MomentProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) { | ||
| 48 | if (type != Core::HID::ControllerTriggerType::IrSensor) { | ||
| 49 | return; | ||
| 50 | } | ||
| 51 | |||
| 52 | next_state = {}; | ||
| 53 | const auto& camera_data = npad_device->GetCamera(); | ||
| 54 | |||
| 55 | const auto window_width = static_cast<std::size_t>(current_config.window_of_interest.width); | ||
| 56 | const auto window_height = static_cast<std::size_t>(current_config.window_of_interest.height); | ||
| 57 | const auto window_start_x = static_cast<std::size_t>(current_config.window_of_interest.x); | ||
| 58 | const auto window_start_y = static_cast<std::size_t>(current_config.window_of_interest.y); | ||
| 59 | |||
| 60 | const std::size_t block_width = window_width / Columns; | ||
| 61 | const std::size_t block_height = window_height / Rows; | ||
| 62 | |||
| 63 | for (std::size_t row = 0; row < Rows; row++) { | ||
| 64 | for (std::size_t column = 0; column < Columns; column++) { | ||
| 65 | const size_t x_pos = (column * block_width) + window_start_x; | ||
| 66 | const size_t y_pos = (row * block_height) + window_start_y; | ||
| 67 | auto& statistic = next_state.statistic[column + (row * Columns)]; | ||
| 68 | statistic = GetStatistic(camera_data.data, x_pos, y_pos, block_width, block_height); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | next_state.sampling_number = camera_data.sample; | ||
| 73 | next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count(); | ||
| 74 | next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; | ||
| 75 | shared_memory->moment_lifo.WriteNextEntry(next_state); | ||
| 76 | |||
| 77 | if (!IsProcessorActive()) { | ||
| 78 | StartProcessor(); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | u8 MomentProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const { | ||
| 83 | if ((y * ImageWidth) + x >= data.size()) { | ||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | return data[(y * ImageWidth) + x]; | ||
| 87 | } | ||
| 88 | |||
| 89 | MomentProcessor::MomentStatistic MomentProcessor::GetStatistic(const std::vector<u8>& data, | ||
| 90 | std::size_t start_x, | ||
| 91 | std::size_t start_y, | ||
| 92 | std::size_t width, | ||
| 93 | std::size_t height) const { | ||
| 94 | // The actual implementation is always 320x240 | ||
| 95 | static constexpr std::size_t RealWidth = 320; | ||
| 96 | static constexpr std::size_t RealHeight = 240; | ||
| 97 | static constexpr std::size_t Threshold = 30; | ||
| 98 | MomentStatistic statistic{}; | ||
| 99 | std::size_t active_points{}; | ||
| 100 | |||
| 101 | // Sum all data points on the block that meet with the threshold | ||
| 102 | for (std::size_t y = 0; y < width; y++) { | ||
| 103 | for (std::size_t x = 0; x < height; x++) { | ||
| 104 | const size_t x_pos = x + start_x; | ||
| 105 | const size_t y_pos = y + start_y; | ||
| 106 | const auto pixel = | ||
| 107 | GetPixel(data, x_pos * ImageWidth / RealWidth, y_pos * ImageHeight / RealHeight); | ||
| 108 | |||
| 109 | if (pixel < Threshold) { | ||
| 110 | continue; | ||
| 111 | } | ||
| 112 | |||
| 113 | statistic.average_intensity += pixel; | ||
| 114 | |||
| 115 | statistic.centroid.x += static_cast<float>(x_pos); | ||
| 116 | statistic.centroid.y += static_cast<float>(y_pos); | ||
| 117 | |||
| 118 | active_points++; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | // Return an empty field if no points were available | ||
| 123 | if (active_points == 0) { | ||
| 124 | return {}; | ||
| 125 | } | ||
| 126 | |||
| 127 | // Finally calculate the actual centroid and average intensity | ||
| 128 | statistic.centroid.x /= static_cast<float>(active_points); | ||
| 129 | statistic.centroid.y /= static_cast<float>(active_points); | ||
| 130 | statistic.average_intensity /= static_cast<f32>(width * height); | ||
| 131 | |||
| 132 | return statistic; | ||
| 133 | } | ||
| 134 | |||
| 22 | void MomentProcessor::SetConfig(Core::IrSensor::PackedMomentProcessorConfig config) { | 135 | void MomentProcessor::SetConfig(Core::IrSensor::PackedMomentProcessorConfig config) { |
| 23 | current_config.camera_config.exposure_time = config.camera_config.exposure_time; | 136 | current_config.camera_config.exposure_time = config.camera_config.exposure_time; |
| 24 | current_config.camera_config.gain = config.camera_config.gain; | 137 | current_config.camera_config.gain = config.camera_config.gain; |
| @@ -29,6 +142,8 @@ void MomentProcessor::SetConfig(Core::IrSensor::PackedMomentProcessorConfig conf | |||
| 29 | current_config.preprocess = | 142 | current_config.preprocess = |
| 30 | static_cast<Core::IrSensor::MomentProcessorPreprocess>(config.preprocess); | 143 | static_cast<Core::IrSensor::MomentProcessorPreprocess>(config.preprocess); |
| 31 | current_config.preprocess_intensity_threshold = config.preprocess_intensity_threshold; | 144 | current_config.preprocess_intensity_threshold = config.preprocess_intensity_threshold; |
| 145 | |||
| 146 | npad_device->SetCameraFormat(format); | ||
| 32 | } | 147 | } |
| 33 | 148 | ||
| 34 | } // namespace Service::IRS | 149 | } // namespace Service::IRS |
diff --git a/src/core/hle/service/hid/irsensor/moment_processor.h b/src/core/hle/service/hid/irsensor/moment_processor.h index d4bd22e0f..398cfbdc1 100644 --- a/src/core/hle/service/hid/irsensor/moment_processor.h +++ b/src/core/hle/service/hid/irsensor/moment_processor.h | |||
| @@ -6,12 +6,22 @@ | |||
| 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 "core/hid/irs_types.h" |
| 9 | #include "core/hle/service/hid/irs_ring_lifo.h" | ||
| 9 | #include "core/hle/service/hid/irsensor/processor_base.h" | 10 | #include "core/hle/service/hid/irsensor/processor_base.h" |
| 10 | 11 | ||
| 12 | namespace Core { | ||
| 13 | class System; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Core::HID { | ||
| 17 | class EmulatedController; | ||
| 18 | } // namespace Core::HID | ||
| 19 | |||
| 11 | namespace Service::IRS { | 20 | namespace Service::IRS { |
| 12 | class MomentProcessor final : public ProcessorBase { | 21 | class MomentProcessor final : public ProcessorBase { |
| 13 | public: | 22 | public: |
| 14 | explicit MomentProcessor(Core::IrSensor::DeviceFormat& device_format); | 23 | explicit MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format, |
| 24 | std::size_t npad_index); | ||
| 15 | ~MomentProcessor() override; | 25 | ~MomentProcessor() override; |
| 16 | 26 | ||
| 17 | // Called when the processor is initialized | 27 | // Called when the processor is initialized |
| @@ -27,6 +37,9 @@ public: | |||
| 27 | void SetConfig(Core::IrSensor::PackedMomentProcessorConfig config); | 37 | void SetConfig(Core::IrSensor::PackedMomentProcessorConfig config); |
| 28 | 38 | ||
| 29 | private: | 39 | private: |
| 40 | static constexpr std::size_t Columns = 8; | ||
| 41 | static constexpr std::size_t Rows = 6; | ||
| 42 | |||
| 30 | // This is nn::irsensor::MomentProcessorConfig | 43 | // This is nn::irsensor::MomentProcessorConfig |
| 31 | struct MomentProcessorConfig { | 44 | struct MomentProcessorConfig { |
| 32 | Core::IrSensor::CameraConfig camera_config; | 45 | Core::IrSensor::CameraConfig camera_config; |
| @@ -50,12 +63,29 @@ private: | |||
| 50 | u64 timestamp; | 63 | u64 timestamp; |
| 51 | Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level; | 64 | Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level; |
| 52 | INSERT_PADDING_BYTES(4); | 65 | INSERT_PADDING_BYTES(4); |
| 53 | std::array<MomentStatistic, 0x30> stadistic; | 66 | std::array<MomentStatistic, Columns * Rows> statistic; |
| 54 | }; | 67 | }; |
| 55 | static_assert(sizeof(MomentProcessorState) == 0x258, "MomentProcessorState is an invalid size"); | 68 | static_assert(sizeof(MomentProcessorState) == 0x258, "MomentProcessorState is an invalid size"); |
| 56 | 69 | ||
| 70 | struct MomentSharedMemory { | ||
| 71 | Service::IRS::Lifo<MomentProcessorState, 6> moment_lifo; | ||
| 72 | }; | ||
| 73 | static_assert(sizeof(MomentSharedMemory) == 0xE20, "MomentSharedMemory is an invalid size"); | ||
| 74 | |||
| 75 | void OnControllerUpdate(Core::HID::ControllerTriggerType type); | ||
| 76 | u8 GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const; | ||
| 77 | MomentStatistic GetStatistic(const std::vector<u8>& data, std::size_t start_x, | ||
| 78 | std::size_t start_y, std::size_t width, std::size_t height) const; | ||
| 79 | |||
| 80 | MomentSharedMemory* shared_memory = nullptr; | ||
| 81 | MomentProcessorState next_state{}; | ||
| 82 | |||
| 57 | MomentProcessorConfig current_config{}; | 83 | MomentProcessorConfig current_config{}; |
| 58 | Core::IrSensor::DeviceFormat& device; | 84 | Core::IrSensor::DeviceFormat& device; |
| 85 | Core::HID::EmulatedController* npad_device; | ||
| 86 | int callback_key{}; | ||
| 87 | |||
| 88 | Core::System& system; | ||
| 59 | }; | 89 | }; |
| 60 | 90 | ||
| 61 | } // namespace Service::IRS | 91 | } // namespace Service::IRS |
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp new file mode 100644 index 000000000..e76d4eea9 --- /dev/null +++ b/src/core/hle/service/hid/resource_manager.cpp | |||
| @@ -0,0 +1,241 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "core/core_timing.h" | ||
| 7 | #include "core/hid/hid_core.h" | ||
| 8 | #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" | ||
| 11 | |||
| 12 | #include "core/hle/service/hid/controllers/console_six_axis.h" | ||
| 13 | #include "core/hle/service/hid/controllers/debug_pad.h" | ||
| 14 | #include "core/hle/service/hid/controllers/gesture.h" | ||
| 15 | #include "core/hle/service/hid/controllers/keyboard.h" | ||
| 16 | #include "core/hle/service/hid/controllers/mouse.h" | ||
| 17 | #include "core/hle/service/hid/controllers/npad.h" | ||
| 18 | #include "core/hle/service/hid/controllers/palma.h" | ||
| 19 | #include "core/hle/service/hid/controllers/seven_six_axis.h" | ||
| 20 | #include "core/hle/service/hid/controllers/six_axis.h" | ||
| 21 | #include "core/hle/service/hid/controllers/stubbed.h" | ||
| 22 | #include "core/hle/service/hid/controllers/touchscreen.h" | ||
| 23 | #include "core/hle/service/hid/controllers/xpad.h" | ||
| 24 | |||
| 25 | namespace Service::HID { | ||
| 26 | |||
| 27 | // Updating period for each HID device. | ||
| 28 | // Period time is obtained by measuring the number of samples in a second on HW using a homebrew | ||
| 29 | // Correct npad_update_ns is 4ms this is overclocked to lower input lag | ||
| 30 | constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz) | ||
| 31 | constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz) | ||
| 32 | constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) | ||
| 33 | constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) | ||
| 34 | |||
| 35 | ResourceManager::ResourceManager(Core::System& system_) | ||
| 36 | : system{system_}, service_context{system_, "hid"} {} | ||
| 37 | |||
| 38 | ResourceManager::~ResourceManager() = default; | ||
| 39 | |||
| 40 | void ResourceManager::Initialize() { | ||
| 41 | if (is_initialized) { | ||
| 42 | return; | ||
| 43 | } | ||
| 44 | |||
| 45 | u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer(); | ||
| 46 | debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory); | ||
| 47 | mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory); | ||
| 48 | debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory); | ||
| 49 | keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory); | ||
| 50 | unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory); | ||
| 51 | npad = std::make_shared<NPad>(system.HIDCore(), shared_memory, service_context); | ||
| 52 | gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory); | ||
| 53 | touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory); | ||
| 54 | xpad = std::make_shared<XPad>(system.HIDCore(), shared_memory); | ||
| 55 | |||
| 56 | palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context); | ||
| 57 | |||
| 58 | home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory); | ||
| 59 | sleep_button = std::make_shared<SleepButton>(system.HIDCore(), shared_memory); | ||
| 60 | capture_button = std::make_shared<CaptureButton>(system.HIDCore(), shared_memory); | ||
| 61 | |||
| 62 | six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); | ||
| 63 | console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory); | ||
| 64 | seven_six_axis = std::make_shared<SevenSixAxis>(system); | ||
| 65 | |||
| 66 | home_button->SetCommonHeaderOffset(0x4C00); | ||
| 67 | sleep_button->SetCommonHeaderOffset(0x4E00); | ||
| 68 | capture_button->SetCommonHeaderOffset(0x5000); | ||
| 69 | unique_pad->SetCommonHeaderOffset(0x5A00); | ||
| 70 | debug_mouse->SetCommonHeaderOffset(0x3DC00); | ||
| 71 | |||
| 72 | // Homebrew doesn't try to activate some controllers, so we activate them by default | ||
| 73 | npad->Activate(); | ||
| 74 | six_axis->Activate(); | ||
| 75 | touch_screen->Activate(); | ||
| 76 | |||
| 77 | system.HIDCore().ReloadInputDevices(); | ||
| 78 | is_initialized = true; | ||
| 79 | } | ||
| 80 | std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const { | ||
| 81 | return capture_button; | ||
| 82 | } | ||
| 83 | |||
| 84 | std::shared_ptr<ConsoleSixAxis> ResourceManager::GetConsoleSixAxis() const { | ||
| 85 | return console_six_axis; | ||
| 86 | } | ||
| 87 | |||
| 88 | std::shared_ptr<DebugMouse> ResourceManager::GetDebugMouse() const { | ||
| 89 | return debug_mouse; | ||
| 90 | } | ||
| 91 | |||
| 92 | std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const { | ||
| 93 | return debug_pad; | ||
| 94 | } | ||
| 95 | |||
| 96 | std::shared_ptr<Gesture> ResourceManager::GetGesture() const { | ||
| 97 | return gesture; | ||
| 98 | } | ||
| 99 | |||
| 100 | std::shared_ptr<HomeButton> ResourceManager::GetHomeButton() const { | ||
| 101 | return home_button; | ||
| 102 | } | ||
| 103 | |||
| 104 | std::shared_ptr<Keyboard> ResourceManager::GetKeyboard() const { | ||
| 105 | return keyboard; | ||
| 106 | } | ||
| 107 | |||
| 108 | std::shared_ptr<Mouse> ResourceManager::GetMouse() const { | ||
| 109 | return mouse; | ||
| 110 | } | ||
| 111 | |||
| 112 | std::shared_ptr<NPad> ResourceManager::GetNpad() const { | ||
| 113 | return npad; | ||
| 114 | } | ||
| 115 | |||
| 116 | std::shared_ptr<Palma> ResourceManager::GetPalma() const { | ||
| 117 | return palma; | ||
| 118 | } | ||
| 119 | |||
| 120 | std::shared_ptr<SevenSixAxis> ResourceManager::GetSevenSixAxis() const { | ||
| 121 | return seven_six_axis; | ||
| 122 | } | ||
| 123 | |||
| 124 | std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() const { | ||
| 125 | return six_axis; | ||
| 126 | } | ||
| 127 | |||
| 128 | std::shared_ptr<SleepButton> ResourceManager::GetSleepButton() const { | ||
| 129 | return sleep_button; | ||
| 130 | } | ||
| 131 | |||
| 132 | std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() const { | ||
| 133 | return touch_screen; | ||
| 134 | } | ||
| 135 | |||
| 136 | std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const { | ||
| 137 | return unique_pad; | ||
| 138 | } | ||
| 139 | |||
| 140 | void ResourceManager::UpdateControllers(std::uintptr_t user_data, | ||
| 141 | std::chrono::nanoseconds ns_late) { | ||
| 142 | auto& core_timing = system.CoreTiming(); | ||
| 143 | debug_pad->OnUpdate(core_timing); | ||
| 144 | unique_pad->OnUpdate(core_timing); | ||
| 145 | gesture->OnUpdate(core_timing); | ||
| 146 | touch_screen->OnUpdate(core_timing); | ||
| 147 | palma->OnUpdate(core_timing); | ||
| 148 | home_button->OnUpdate(core_timing); | ||
| 149 | sleep_button->OnUpdate(core_timing); | ||
| 150 | capture_button->OnUpdate(core_timing); | ||
| 151 | xpad->OnUpdate(core_timing); | ||
| 152 | } | ||
| 153 | |||
| 154 | void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | ||
| 155 | auto& core_timing = system.CoreTiming(); | ||
| 156 | npad->OnUpdate(core_timing); | ||
| 157 | } | ||
| 158 | |||
| 159 | void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data, | ||
| 160 | std::chrono::nanoseconds ns_late) { | ||
| 161 | auto& core_timing = system.CoreTiming(); | ||
| 162 | mouse->OnUpdate(core_timing); | ||
| 163 | debug_mouse->OnUpdate(core_timing); | ||
| 164 | keyboard->OnUpdate(core_timing); | ||
| 165 | } | ||
| 166 | |||
| 167 | void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | ||
| 168 | auto& core_timing = system.CoreTiming(); | ||
| 169 | six_axis->OnUpdate(core_timing); | ||
| 170 | seven_six_axis->OnUpdate(core_timing); | ||
| 171 | console_six_axis->OnUpdate(core_timing); | ||
| 172 | } | ||
| 173 | |||
| 174 | IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource) | ||
| 175 | : ServiceFramework{system_, "IAppletResource"} { | ||
| 176 | static const FunctionInfo functions[] = { | ||
| 177 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, | ||
| 178 | }; | ||
| 179 | RegisterHandlers(functions); | ||
| 180 | |||
| 181 | resource->Initialize(); | ||
| 182 | |||
| 183 | // Register update callbacks | ||
| 184 | npad_update_event = Core::Timing::CreateEvent( | ||
| 185 | "HID::UpdatePadCallback", | ||
| 186 | [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) | ||
| 187 | -> std::optional<std::chrono::nanoseconds> { | ||
| 188 | const auto guard = LockService(); | ||
| 189 | resource->UpdateNpad(user_data, ns_late); | ||
| 190 | return std::nullopt; | ||
| 191 | }); | ||
| 192 | default_update_event = Core::Timing::CreateEvent( | ||
| 193 | "HID::UpdateDefaultCallback", | ||
| 194 | [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) | ||
| 195 | -> std::optional<std::chrono::nanoseconds> { | ||
| 196 | const auto guard = LockService(); | ||
| 197 | resource->UpdateControllers(user_data, ns_late); | ||
| 198 | return std::nullopt; | ||
| 199 | }); | ||
| 200 | mouse_keyboard_update_event = Core::Timing::CreateEvent( | ||
| 201 | "HID::UpdateMouseKeyboardCallback", | ||
| 202 | [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) | ||
| 203 | -> std::optional<std::chrono::nanoseconds> { | ||
| 204 | const auto guard = LockService(); | ||
| 205 | resource->UpdateMouseKeyboard(user_data, ns_late); | ||
| 206 | return std::nullopt; | ||
| 207 | }); | ||
| 208 | motion_update_event = Core::Timing::CreateEvent( | ||
| 209 | "HID::UpdateMotionCallback", | ||
| 210 | [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) | ||
| 211 | -> std::optional<std::chrono::nanoseconds> { | ||
| 212 | const auto guard = LockService(); | ||
| 213 | resource->UpdateMotion(user_data, ns_late); | ||
| 214 | return std::nullopt; | ||
| 215 | }); | ||
| 216 | |||
| 217 | system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event); | ||
| 218 | system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns, | ||
| 219 | default_update_event); | ||
| 220 | system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns, | ||
| 221 | mouse_keyboard_update_event); | ||
| 222 | system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns, | ||
| 223 | motion_update_event); | ||
| 224 | } | ||
| 225 | |||
| 226 | IAppletResource::~IAppletResource() { | ||
| 227 | system.CoreTiming().UnscheduleEvent(npad_update_event, 0); | ||
| 228 | system.CoreTiming().UnscheduleEvent(default_update_event, 0); | ||
| 229 | system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0); | ||
| 230 | system.CoreTiming().UnscheduleEvent(motion_update_event, 0); | ||
| 231 | } | ||
| 232 | |||
| 233 | void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { | ||
| 234 | LOG_DEBUG(Service_HID, "called"); | ||
| 235 | |||
| 236 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 237 | rb.Push(ResultSuccess); | ||
| 238 | rb.PushCopyObjects(&system.Kernel().GetHidSharedMem()); | ||
| 239 | } | ||
| 240 | |||
| 241 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h new file mode 100644 index 000000000..2b6a9b5e6 --- /dev/null +++ b/src/core/hle/service/hid/resource_manager.h | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/kernel_helpers.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core::Timing { | ||
| 10 | struct EventType; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::HID { | ||
| 14 | class Controller_Stubbed; | ||
| 15 | class ConsoleSixAxis; | ||
| 16 | class DebugPad; | ||
| 17 | class Gesture; | ||
| 18 | class Keyboard; | ||
| 19 | class Mouse; | ||
| 20 | class NPad; | ||
| 21 | class Palma; | ||
| 22 | class SevenSixAxis; | ||
| 23 | class SixAxis; | ||
| 24 | class TouchScreen; | ||
| 25 | class XPad; | ||
| 26 | |||
| 27 | using CaptureButton = Controller_Stubbed; | ||
| 28 | using DebugMouse = Controller_Stubbed; | ||
| 29 | using HomeButton = Controller_Stubbed; | ||
| 30 | using SleepButton = Controller_Stubbed; | ||
| 31 | using UniquePad = Controller_Stubbed; | ||
| 32 | |||
| 33 | class ResourceManager { | ||
| 34 | |||
| 35 | public: | ||
| 36 | explicit ResourceManager(Core::System& system_); | ||
| 37 | ~ResourceManager(); | ||
| 38 | |||
| 39 | void Initialize(); | ||
| 40 | |||
| 41 | std::shared_ptr<CaptureButton> GetCaptureButton() const; | ||
| 42 | std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; | ||
| 43 | std::shared_ptr<DebugMouse> GetDebugMouse() const; | ||
| 44 | std::shared_ptr<DebugPad> GetDebugPad() const; | ||
| 45 | std::shared_ptr<Gesture> GetGesture() const; | ||
| 46 | std::shared_ptr<HomeButton> GetHomeButton() const; | ||
| 47 | std::shared_ptr<Keyboard> GetKeyboard() const; | ||
| 48 | std::shared_ptr<Mouse> GetMouse() const; | ||
| 49 | std::shared_ptr<NPad> GetNpad() const; | ||
| 50 | std::shared_ptr<Palma> GetPalma() const; | ||
| 51 | std::shared_ptr<SevenSixAxis> GetSevenSixAxis() const; | ||
| 52 | std::shared_ptr<SixAxis> GetSixAxis() const; | ||
| 53 | std::shared_ptr<SleepButton> GetSleepButton() const; | ||
| 54 | std::shared_ptr<TouchScreen> GetTouchScreen() const; | ||
| 55 | std::shared_ptr<UniquePad> GetUniquePad() const; | ||
| 56 | |||
| 57 | void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||
| 58 | void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||
| 59 | void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||
| 60 | void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||
| 61 | |||
| 62 | private: | ||
| 63 | bool is_initialized{false}; | ||
| 64 | |||
| 65 | std::shared_ptr<CaptureButton> capture_button = nullptr; | ||
| 66 | std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; | ||
| 67 | std::shared_ptr<DebugMouse> debug_mouse = nullptr; | ||
| 68 | std::shared_ptr<DebugPad> debug_pad = nullptr; | ||
| 69 | std::shared_ptr<Gesture> gesture = nullptr; | ||
| 70 | std::shared_ptr<HomeButton> home_button = nullptr; | ||
| 71 | std::shared_ptr<Keyboard> keyboard = nullptr; | ||
| 72 | std::shared_ptr<Mouse> mouse = nullptr; | ||
| 73 | std::shared_ptr<NPad> npad = nullptr; | ||
| 74 | std::shared_ptr<Palma> palma = nullptr; | ||
| 75 | std::shared_ptr<SevenSixAxis> seven_six_axis = nullptr; | ||
| 76 | std::shared_ptr<SixAxis> six_axis = nullptr; | ||
| 77 | std::shared_ptr<SleepButton> sleep_button = nullptr; | ||
| 78 | std::shared_ptr<TouchScreen> touch_screen = nullptr; | ||
| 79 | std::shared_ptr<UniquePad> unique_pad = nullptr; | ||
| 80 | std::shared_ptr<XPad> xpad = nullptr; | ||
| 81 | |||
| 82 | // TODO: Create these resources | ||
| 83 | // std::shared_ptr<AudioControl> audio_control = nullptr; | ||
| 84 | // std::shared_ptr<ButtonConfig> button_config = nullptr; | ||
| 85 | // std::shared_ptr<Config> config = nullptr; | ||
| 86 | // std::shared_ptr<Connection> connection = nullptr; | ||
| 87 | // std::shared_ptr<CustomConfig> custom_config = nullptr; | ||
| 88 | // std::shared_ptr<Digitizer> digitizer = nullptr; | ||
| 89 | // std::shared_ptr<Hdls> hdls = nullptr; | ||
| 90 | // std::shared_ptr<PlayReport> play_report = nullptr; | ||
| 91 | // std::shared_ptr<Rail> rail = nullptr; | ||
| 92 | |||
| 93 | Core::System& system; | ||
| 94 | KernelHelpers::ServiceContext service_context; | ||
| 95 | }; | ||
| 96 | |||
| 97 | class IAppletResource final : public ServiceFramework<IAppletResource> { | ||
| 98 | public: | ||
| 99 | explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource); | ||
| 100 | ~IAppletResource() override; | ||
| 101 | |||
| 102 | private: | ||
| 103 | void GetSharedMemoryHandle(HLERequestContext& ctx); | ||
| 104 | |||
| 105 | std::shared_ptr<Core::Timing::EventType> npad_update_event; | ||
| 106 | std::shared_ptr<Core::Timing::EventType> default_update_event; | ||
| 107 | std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; | ||
| 108 | std::shared_ptr<Core::Timing::EventType> motion_update_event; | ||
| 109 | }; | ||
| 110 | |||
| 111 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/ring_lifo.h b/src/core/hle/service/hid/ring_lifo.h index 65eb7ea02..0816784e0 100644 --- a/src/core/hle/service/hid/ring_lifo.h +++ b/src/core/hle/service/hid/ring_lifo.h | |||
| @@ -32,15 +32,15 @@ struct Lifo { | |||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | std::size_t GetPreviousEntryIndex() const { | 34 | std::size_t GetPreviousEntryIndex() const { |
| 35 | return static_cast<size_t>((buffer_tail + total_buffer_count - 1) % total_buffer_count); | 35 | return static_cast<size_t>((buffer_tail + max_buffer_size - 1) % max_buffer_size); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | std::size_t GetNextEntryIndex() const { | 38 | std::size_t GetNextEntryIndex() const { |
| 39 | return static_cast<size_t>((buffer_tail + 1) % total_buffer_count); | 39 | return static_cast<size_t>((buffer_tail + 1) % max_buffer_size); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | void WriteNextEntry(const State& new_state) { | 42 | void WriteNextEntry(const State& new_state) { |
| 43 | if (buffer_count < total_buffer_count - 1) { | 43 | if (buffer_count < static_cast<s64>(max_buffer_size) - 1) { |
| 44 | buffer_count++; | 44 | buffer_count++; |
| 45 | } | 45 | } |
| 46 | buffer_tail = GetNextEntryIndex(); | 46 | buffer_tail = GetNextEntryIndex(); |
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index 7927f8264..961f89a14 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp | |||
| @@ -115,12 +115,20 @@ public: | |||
| 115 | {400, nullptr, "InitializeSystem"}, | 115 | {400, nullptr, "InitializeSystem"}, |
| 116 | {401, nullptr, "FinalizeSystem"}, | 116 | {401, nullptr, "FinalizeSystem"}, |
| 117 | {402, nullptr, "SetOperationMode"}, | 117 | {402, nullptr, "SetOperationMode"}, |
| 118 | {403, nullptr, "InitializeSystem2"}, | 118 | {403, &ISystemLocalCommunicationService::InitializeSystem2, "InitializeSystem2"}, |
| 119 | }; | 119 | }; |
| 120 | // clang-format on | 120 | // clang-format on |
| 121 | 121 | ||
| 122 | RegisterHandlers(functions); | 122 | RegisterHandlers(functions); |
| 123 | } | 123 | } |
| 124 | |||
| 125 | private: | ||
| 126 | void InitializeSystem2(HLERequestContext& ctx) { | ||
| 127 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 128 | |||
| 129 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 130 | rb.Push(ResultSuccess); | ||
| 131 | } | ||
| 124 | }; | 132 | }; |
| 125 | 133 | ||
| 126 | class IUserLocalCommunicationService final | 134 | class IUserLocalCommunicationService final |
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index c73035c77..97b6a9385 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -286,9 +286,14 @@ public: | |||
| 286 | rb.Push(ResultSuccess); | 286 | rb.Push(ResultSuccess); |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | bool ValidateRegionForMap(Kernel::KPageTable& page_table, VAddr start, std::size_t size) const { | 289 | bool ValidateRegionForMap(Kernel::KProcessPageTable& page_table, VAddr start, |
| 290 | std::size_t size) const { | ||
| 290 | const std::size_t padding_size{page_table.GetNumGuardPages() * Kernel::PageSize}; | 291 | const std::size_t padding_size{page_table.GetNumGuardPages() * Kernel::PageSize}; |
| 291 | const auto start_info{page_table.QueryInfo(start - 1)}; | 292 | |
| 293 | Kernel::KMemoryInfo start_info; | ||
| 294 | Kernel::Svc::PageInfo page_info; | ||
| 295 | R_ASSERT( | ||
| 296 | page_table.QueryInfo(std::addressof(start_info), std::addressof(page_info), start - 1)); | ||
| 292 | 297 | ||
| 293 | if (start_info.GetState() != Kernel::KMemoryState::Free) { | 298 | if (start_info.GetState() != Kernel::KMemoryState::Free) { |
| 294 | return {}; | 299 | return {}; |
| @@ -298,7 +303,9 @@ public: | |||
| 298 | return {}; | 303 | return {}; |
| 299 | } | 304 | } |
| 300 | 305 | ||
| 301 | const auto end_info{page_table.QueryInfo(start + size)}; | 306 | Kernel::KMemoryInfo end_info; |
| 307 | R_ASSERT(page_table.QueryInfo(std::addressof(end_info), std::addressof(page_info), | ||
| 308 | start + size)); | ||
| 302 | 309 | ||
| 303 | if (end_info.GetState() != Kernel::KMemoryState::Free) { | 310 | if (end_info.GetState() != Kernel::KMemoryState::Free) { |
| 304 | return {}; | 311 | return {}; |
| @@ -307,7 +314,7 @@ public: | |||
| 307 | return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize()); | 314 | return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize()); |
| 308 | } | 315 | } |
| 309 | 316 | ||
| 310 | Result GetAvailableMapRegion(Kernel::KPageTable& page_table, u64 size, VAddr& out_addr) { | 317 | Result GetAvailableMapRegion(Kernel::KProcessPageTable& page_table, u64 size, VAddr& out_addr) { |
| 311 | size = Common::AlignUp(size, Kernel::PageSize); | 318 | size = Common::AlignUp(size, Kernel::PageSize); |
| 312 | size += page_table.GetNumGuardPages() * Kernel::PageSize * 4; | 319 | size += page_table.GetNumGuardPages() * Kernel::PageSize * 4; |
| 313 | 320 | ||
| @@ -391,12 +398,8 @@ public: | |||
| 391 | 398 | ||
| 392 | if (bss_size) { | 399 | if (bss_size) { |
| 393 | auto block_guard = detail::ScopeExit([&] { | 400 | auto block_guard = detail::ScopeExit([&] { |
| 394 | page_table.UnmapCodeMemory( | 401 | page_table.UnmapCodeMemory(addr + nro_size, bss_addr, bss_size); |
| 395 | addr + nro_size, bss_addr, bss_size, | 402 | page_table.UnmapCodeMemory(addr, nro_addr, nro_size); |
| 396 | Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange); | ||
| 397 | page_table.UnmapCodeMemory( | ||
| 398 | addr, nro_addr, nro_size, | ||
| 399 | Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange); | ||
| 400 | }); | 403 | }); |
| 401 | 404 | ||
| 402 | const Result result{page_table.MapCodeMemory(addr + nro_size, bss_addr, bss_size)}; | 405 | const Result result{page_table.MapCodeMemory(addr + nro_size, bss_addr, bss_size)}; |
| @@ -578,21 +581,17 @@ public: | |||
| 578 | auto& page_table{system.ApplicationProcess()->GetPageTable()}; | 581 | auto& page_table{system.ApplicationProcess()->GetPageTable()}; |
| 579 | 582 | ||
| 580 | if (info.bss_size != 0) { | 583 | if (info.bss_size != 0) { |
| 581 | R_TRY(page_table.UnmapCodeMemory( | 584 | R_TRY(page_table.UnmapCodeMemory(info.nro_address + info.text_size + info.ro_size + |
| 582 | info.nro_address + info.text_size + info.ro_size + info.data_size, info.bss_address, | 585 | info.data_size, |
| 583 | info.bss_size, Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange)); | 586 | info.bss_address, info.bss_size)); |
| 584 | } | 587 | } |
| 585 | 588 | ||
| 586 | R_TRY(page_table.UnmapCodeMemory( | 589 | R_TRY(page_table.UnmapCodeMemory(info.nro_address + info.text_size + info.ro_size, |
| 587 | info.nro_address + info.text_size + info.ro_size, | 590 | info.src_addr + info.text_size + info.ro_size, |
| 588 | info.src_addr + info.text_size + info.ro_size, info.data_size, | 591 | info.data_size)); |
| 589 | Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange)); | 592 | R_TRY(page_table.UnmapCodeMemory(info.nro_address + info.text_size, |
| 590 | R_TRY(page_table.UnmapCodeMemory( | 593 | info.src_addr + info.text_size, info.ro_size)); |
| 591 | info.nro_address + info.text_size, info.src_addr + info.text_size, info.ro_size, | 594 | R_TRY(page_table.UnmapCodeMemory(info.nro_address, info.src_addr, info.text_size)); |
| 592 | Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange)); | ||
| 593 | R_TRY(page_table.UnmapCodeMemory( | ||
| 594 | info.nro_address, info.src_addr, info.text_size, | ||
| 595 | Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange)); | ||
| 596 | return ResultSuccess; | 595 | return ResultSuccess; |
| 597 | } | 596 | } |
| 598 | 597 | ||
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index a71d26157..ad534177d 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hid/hid_types.h" | 8 | #include "core/hid/hid_types.h" |
| 9 | #include "core/hle/kernel/k_event.h" | 9 | #include "core/hle/kernel/k_event.h" |
| 10 | #include "core/hle/service/hid/hid_util.h" | ||
| 10 | #include "core/hle/service/ipc_helpers.h" | 11 | #include "core/hle/service/ipc_helpers.h" |
| 11 | #include "core/hle/service/nfc/common/device.h" | 12 | #include "core/hle/service/nfc/common/device.h" |
| 12 | #include "core/hle/service/nfc/common/device_manager.h" | 13 | #include "core/hle/service/nfc/common/device_manager.h" |
| @@ -24,7 +25,7 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex | |||
| 24 | 25 | ||
| 25 | for (u32 device_index = 0; device_index < devices.size(); device_index++) { | 26 | for (u32 device_index = 0; device_index < devices.size(); device_index++) { |
| 26 | devices[device_index] = | 27 | devices[device_index] = |
| 27 | std::make_shared<NfcDevice>(Core::HID::IndexToNpadIdType(device_index), system, | 28 | std::make_shared<NfcDevice>(HID::IndexToNpadIdType(device_index), system, |
| 28 | service_context, availability_change_event); | 29 | service_context, availability_change_event); |
| 29 | } | 30 | } |
| 30 | 31 | ||
diff --git a/src/core/hle/service/nvdrv/devices/ioctl_serialization.h b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h new file mode 100644 index 000000000..b12bcd138 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h | |||
| @@ -0,0 +1,159 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <span> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "common/concepts.h" | ||
| 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||
| 11 | |||
| 12 | namespace Service::Nvidia::Devices { | ||
| 13 | |||
| 14 | struct IoctlOneArgTraits { | ||
| 15 | template <typename T, typename R, typename A, typename... B> | ||
| 16 | static A GetFirstArgImpl(R (T::*)(A, B...)); | ||
| 17 | }; | ||
| 18 | |||
| 19 | struct IoctlTwoArgTraits { | ||
| 20 | template <typename T, typename R, typename A, typename B, typename... C> | ||
| 21 | static A GetFirstArgImpl(R (T::*)(A, B, C...)); | ||
| 22 | |||
| 23 | template <typename T, typename R, typename A, typename B, typename... C> | ||
| 24 | static B GetSecondArgImpl(R (T::*)(A, B, C...)); | ||
| 25 | }; | ||
| 26 | |||
| 27 | struct Null {}; | ||
| 28 | |||
| 29 | // clang-format off | ||
| 30 | |||
| 31 | template <typename FixedArg, typename VarArg, typename InlInVarArg, typename InlOutVarArg, typename F> | ||
| 32 | NvResult WrapGeneric(F&& callable, std::span<const u8> input, std::span<const u8> inline_input, std::span<u8> output, std::span<u8> inline_output) { | ||
| 33 | constexpr bool HasFixedArg = !std::is_same_v<FixedArg, Null>; | ||
| 34 | constexpr bool HasVarArg = !std::is_same_v<VarArg, Null>; | ||
| 35 | constexpr bool HasInlInVarArg = !std::is_same_v<InlInVarArg, Null>; | ||
| 36 | constexpr bool HasInlOutVarArg = !std::is_same_v<InlOutVarArg, Null>; | ||
| 37 | |||
| 38 | // Declare the fixed-size input value. | ||
| 39 | FixedArg fixed{}; | ||
| 40 | size_t var_offset = 0; | ||
| 41 | |||
| 42 | if constexpr (HasFixedArg) { | ||
| 43 | // Read the fixed-size input value. | ||
| 44 | var_offset = std::min(sizeof(FixedArg), input.size()); | ||
| 45 | if (var_offset > 0) { | ||
| 46 | std::memcpy(&fixed, input.data(), var_offset); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | // Read the variable-sized inputs. | ||
| 51 | const size_t num_var_args = HasVarArg ? ((input.size() - var_offset) / sizeof(VarArg)) : 0; | ||
| 52 | std::vector<VarArg> var_args(num_var_args); | ||
| 53 | if constexpr (HasVarArg) { | ||
| 54 | if (num_var_args > 0) { | ||
| 55 | std::memcpy(var_args.data(), input.data() + var_offset, num_var_args * sizeof(VarArg)); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | const size_t num_inl_in_var_args = HasInlInVarArg ? (inline_input.size() / sizeof(InlInVarArg)) : 0; | ||
| 60 | std::vector<InlInVarArg> inl_in_var_args(num_inl_in_var_args); | ||
| 61 | if constexpr (HasInlInVarArg) { | ||
| 62 | if (num_inl_in_var_args > 0) { | ||
| 63 | std::memcpy(inl_in_var_args.data(), inline_input.data(), num_inl_in_var_args * sizeof(InlInVarArg)); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | // Construct inline output data. | ||
| 68 | const size_t num_inl_out_var_args = HasInlOutVarArg ? (inline_output.size() / sizeof(InlOutVarArg)) : 0; | ||
| 69 | std::vector<InlOutVarArg> inl_out_var_args(num_inl_out_var_args); | ||
| 70 | |||
| 71 | // Perform the call. | ||
| 72 | NvResult result = callable(fixed, var_args, inl_in_var_args, inl_out_var_args); | ||
| 73 | |||
| 74 | // Copy outputs. | ||
| 75 | if constexpr (HasFixedArg) { | ||
| 76 | if (output.size() > 0) { | ||
| 77 | std::memcpy(output.data(), &fixed, std::min(output.size(), sizeof(FixedArg))); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | if constexpr (HasVarArg) { | ||
| 82 | if (num_var_args > 0 && output.size() > var_offset) { | ||
| 83 | const size_t max_var_size = output.size() - var_offset; | ||
| 84 | std::memcpy(output.data() + var_offset, var_args.data(), std::min(max_var_size, num_var_args * sizeof(VarArg))); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | // Copy inline outputs. | ||
| 89 | if constexpr (HasInlOutVarArg) { | ||
| 90 | if (num_inl_out_var_args > 0) { | ||
| 91 | std::memcpy(inline_output.data(), inl_out_var_args.data(), num_inl_out_var_args * sizeof(InlOutVarArg)); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | // We're done. | ||
| 96 | return result; | ||
| 97 | } | ||
| 98 | |||
| 99 | template <typename Self, typename F, typename... Rest> | ||
| 100 | NvResult WrapFixed(Self* self, F&& callable, std::span<const u8> input, std::span<u8> output, Rest&&... rest) { | ||
| 101 | using FixedArg = typename std::remove_reference_t<decltype(IoctlOneArgTraits::GetFirstArgImpl(callable))>; | ||
| 102 | |||
| 103 | const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { | ||
| 104 | return (self->*callable)(fixed, std::forward<Rest>(rest)...); | ||
| 105 | }; | ||
| 106 | |||
| 107 | return WrapGeneric<FixedArg, Null, Null, Null>(std::move(Callable), input, {}, output, {}); | ||
| 108 | } | ||
| 109 | |||
| 110 | template <typename Self, typename F, typename... Rest> | ||
| 111 | NvResult WrapFixedInlOut(Self* self, F&& callable, std::span<const u8> input, std::span<u8> output, std::span<u8> inline_output, Rest&&... rest) { | ||
| 112 | using FixedArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetFirstArgImpl(callable))>; | ||
| 113 | using InlOutVarArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetSecondArgImpl(callable))>::value_type; | ||
| 114 | |||
| 115 | const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { | ||
| 116 | return (self->*callable)(fixed, inl_out, std::forward<Rest>(rest)...); | ||
| 117 | }; | ||
| 118 | |||
| 119 | return WrapGeneric<FixedArg, Null, Null, InlOutVarArg>(std::move(Callable), input, {}, output, inline_output); | ||
| 120 | } | ||
| 121 | |||
| 122 | template <typename Self, typename F, typename... Rest> | ||
| 123 | NvResult WrapVariable(Self* self, F&& callable, std::span<const u8> input, std::span<u8> output, Rest&&... rest) { | ||
| 124 | using VarArg = typename std::remove_reference_t<decltype(IoctlOneArgTraits::GetFirstArgImpl(callable))>::value_type; | ||
| 125 | |||
| 126 | const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { | ||
| 127 | return (self->*callable)(var, std::forward<Rest>(rest)...); | ||
| 128 | }; | ||
| 129 | |||
| 130 | return WrapGeneric<Null, VarArg, Null, Null>(std::move(Callable), input, {}, output, {}); | ||
| 131 | } | ||
| 132 | |||
| 133 | template <typename Self, typename F, typename... Rest> | ||
| 134 | NvResult WrapFixedVariable(Self* self, F&& callable, std::span<const u8> input, std::span<u8> output, Rest&&... rest) { | ||
| 135 | using FixedArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetFirstArgImpl(callable))>; | ||
| 136 | using VarArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetSecondArgImpl(callable))>::value_type; | ||
| 137 | |||
| 138 | const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { | ||
| 139 | return (self->*callable)(fixed, var, std::forward<Rest>(rest)...); | ||
| 140 | }; | ||
| 141 | |||
| 142 | return WrapGeneric<FixedArg, VarArg, Null, Null>(std::move(Callable), input, {}, output, {}); | ||
| 143 | } | ||
| 144 | |||
| 145 | template <typename Self, typename F, typename... Rest> | ||
| 146 | NvResult WrapFixedInlIn(Self* self, F&& callable, std::span<const u8> input, std::span<const u8> inline_input, std::span<u8> output, Rest&&... rest) { | ||
| 147 | using FixedArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetFirstArgImpl(callable))>; | ||
| 148 | using InlInVarArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetSecondArgImpl(callable))>::value_type; | ||
| 149 | |||
| 150 | const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { | ||
| 151 | return (self->*callable)(fixed, inl_in, std::forward<Rest>(rest)...); | ||
| 152 | }; | ||
| 153 | |||
| 154 | return WrapGeneric<FixedArg, Null, InlInVarArg, Null>(std::move(Callable), input, inline_input, output, {}); | ||
| 155 | } | ||
| 156 | |||
| 157 | // clang-format on | ||
| 158 | |||
| 159 | } // namespace Service::Nvidia::Devices | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 7d7bb8687..6b3639008 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/hle/service/nvdrv/core/container.h" | 12 | #include "core/hle/service/nvdrv/core/container.h" |
| 13 | #include "core/hle/service/nvdrv/core/nvmap.h" | 13 | #include "core/hle/service/nvdrv/core/nvmap.h" |
| 14 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 14 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | 15 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" |
| 15 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" | 16 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" |
| 16 | #include "core/hle/service/nvdrv/nvdrv.h" | 17 | #include "core/hle/service/nvdrv/nvdrv.h" |
| @@ -33,21 +34,21 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 33 | case 'A': | 34 | case 'A': |
| 34 | switch (command.cmd) { | 35 | switch (command.cmd) { |
| 35 | case 0x1: | 36 | case 0x1: |
| 36 | return BindChannel(input, output); | 37 | return WrapFixed(this, &nvhost_as_gpu::BindChannel, input, output); |
| 37 | case 0x2: | 38 | case 0x2: |
| 38 | return AllocateSpace(input, output); | 39 | return WrapFixed(this, &nvhost_as_gpu::AllocateSpace, input, output); |
| 39 | case 0x3: | 40 | case 0x3: |
| 40 | return FreeSpace(input, output); | 41 | return WrapFixed(this, &nvhost_as_gpu::FreeSpace, input, output); |
| 41 | case 0x5: | 42 | case 0x5: |
| 42 | return UnmapBuffer(input, output); | 43 | return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output); |
| 43 | case 0x6: | 44 | case 0x6: |
| 44 | return MapBufferEx(input, output); | 45 | return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output); |
| 45 | case 0x8: | 46 | case 0x8: |
| 46 | return GetVARegions(input, output); | 47 | return WrapFixed(this, &nvhost_as_gpu::GetVARegions1, input, output); |
| 47 | case 0x9: | 48 | case 0x9: |
| 48 | return AllocAsEx(input, output); | 49 | return WrapFixed(this, &nvhost_as_gpu::AllocAsEx, input, output); |
| 49 | case 0x14: | 50 | case 0x14: |
| 50 | return Remap(input, output); | 51 | return WrapVariable(this, &nvhost_as_gpu::Remap, input, output); |
| 51 | default: | 52 | default: |
| 52 | break; | 53 | break; |
| 53 | } | 54 | } |
| @@ -72,7 +73,8 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 72 | case 'A': | 73 | case 'A': |
| 73 | switch (command.cmd) { | 74 | switch (command.cmd) { |
| 74 | case 0x8: | 75 | case 0x8: |
| 75 | return GetVARegions(input, output, inline_output); | 76 | return WrapFixedInlOut(this, &nvhost_as_gpu::GetVARegions3, input, output, |
| 77 | inline_output); | ||
| 76 | default: | 78 | default: |
| 77 | break; | 79 | break; |
| 78 | } | 80 | } |
| @@ -87,10 +89,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 87 | void nvhost_as_gpu::OnOpen(DeviceFD fd) {} | 89 | void nvhost_as_gpu::OnOpen(DeviceFD fd) {} |
| 88 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} | 90 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} |
| 89 | 91 | ||
| 90 | NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::span<u8> output) { | 92 | NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { |
| 91 | IoctlAllocAsEx params{}; | ||
| 92 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 93 | |||
| 94 | LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); | 93 | LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); |
| 95 | 94 | ||
| 96 | std::scoped_lock lock(mutex); | 95 | std::scoped_lock lock(mutex); |
| @@ -141,10 +140,7 @@ NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::span<u8> outpu | |||
| 141 | return NvResult::Success; | 140 | return NvResult::Success; |
| 142 | } | 141 | } |
| 143 | 142 | ||
| 144 | NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::span<u8> output) { | 143 | NvResult nvhost_as_gpu::AllocateSpace(IoctlAllocSpace& params) { |
| 145 | IoctlAllocSpace params{}; | ||
| 146 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 147 | |||
| 148 | LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, | 144 | LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, |
| 149 | params.page_size, params.flags); | 145 | params.page_size, params.flags); |
| 150 | 146 | ||
| @@ -194,7 +190,6 @@ NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::span<u8> o | |||
| 194 | .big_pages = params.page_size != VM::YUZU_PAGESIZE, | 190 | .big_pages = params.page_size != VM::YUZU_PAGESIZE, |
| 195 | }; | 191 | }; |
| 196 | 192 | ||
| 197 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 198 | return NvResult::Success; | 193 | return NvResult::Success; |
| 199 | } | 194 | } |
| 200 | 195 | ||
| @@ -222,10 +217,7 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) { | |||
| 222 | mapping_map.erase(offset); | 217 | mapping_map.erase(offset); |
| 223 | } | 218 | } |
| 224 | 219 | ||
| 225 | NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::span<u8> output) { | 220 | NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) { |
| 226 | IoctlFreeSpace params{}; | ||
| 227 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 228 | |||
| 229 | LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset, | 221 | LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset, |
| 230 | params.pages, params.page_size); | 222 | params.pages, params.page_size); |
| 231 | 223 | ||
| @@ -264,18 +256,11 @@ NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::span<u8> outpu | |||
| 264 | return NvResult::BadValue; | 256 | return NvResult::BadValue; |
| 265 | } | 257 | } |
| 266 | 258 | ||
| 267 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 268 | return NvResult::Success; | 259 | return NvResult::Success; |
| 269 | } | 260 | } |
| 270 | 261 | ||
| 271 | NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::span<u8> output) { | 262 | NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries) { |
| 272 | const auto num_entries = input.size() / sizeof(IoctlRemapEntry); | 263 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size()); |
| 273 | |||
| 274 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries); | ||
| 275 | |||
| 276 | std::scoped_lock lock(mutex); | ||
| 277 | entries.resize_destructive(num_entries); | ||
| 278 | std::memcpy(entries.data(), input.data(), input.size()); | ||
| 279 | 264 | ||
| 280 | if (!vm.initialised) { | 265 | if (!vm.initialised) { |
| 281 | return NvResult::BadValue; | 266 | return NvResult::BadValue; |
| @@ -317,14 +302,10 @@ NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::span<u8> output) { | |||
| 317 | } | 302 | } |
| 318 | } | 303 | } |
| 319 | 304 | ||
| 320 | std::memcpy(output.data(), entries.data(), output.size()); | ||
| 321 | return NvResult::Success; | 305 | return NvResult::Success; |
| 322 | } | 306 | } |
| 323 | 307 | ||
| 324 | NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::span<u8> output) { | 308 | NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { |
| 325 | IoctlMapBufferEx params{}; | ||
| 326 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 327 | |||
| 328 | LOG_DEBUG(Service_NVDRV, | 309 | LOG_DEBUG(Service_NVDRV, |
| 329 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" | 310 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" |
| 330 | ", offset={}", | 311 | ", offset={}", |
| @@ -421,14 +402,10 @@ NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::span<u8> out | |||
| 421 | mapping_map[params.offset] = mapping; | 402 | mapping_map[params.offset] = mapping; |
| 422 | } | 403 | } |
| 423 | 404 | ||
| 424 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 425 | return NvResult::Success; | 405 | return NvResult::Success; |
| 426 | } | 406 | } |
| 427 | 407 | ||
| 428 | NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::span<u8> output) { | 408 | NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { |
| 429 | IoctlUnmapBuffer params{}; | ||
| 430 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 431 | |||
| 432 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); | 409 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); |
| 433 | 410 | ||
| 434 | std::scoped_lock lock(mutex); | 411 | std::scoped_lock lock(mutex); |
| @@ -464,9 +441,7 @@ NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::span<u8> out | |||
| 464 | return NvResult::Success; | 441 | return NvResult::Success; |
| 465 | } | 442 | } |
| 466 | 443 | ||
| 467 | NvResult nvhost_as_gpu::BindChannel(std::span<const u8> input, std::span<u8> output) { | 444 | NvResult nvhost_as_gpu::BindChannel(IoctlBindChannel& params) { |
| 468 | IoctlBindChannel params{}; | ||
| 469 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 470 | LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); | 445 | LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); |
| 471 | 446 | ||
| 472 | auto gpu_channel_device = module.GetDevice<nvhost_gpu>(params.fd); | 447 | auto gpu_channel_device = module.GetDevice<nvhost_gpu>(params.fd); |
| @@ -493,10 +468,7 @@ void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) { | |||
| 493 | }; | 468 | }; |
| 494 | } | 469 | } |
| 495 | 470 | ||
| 496 | NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output) { | 471 | NvResult nvhost_as_gpu::GetVARegions1(IoctlGetVaRegions& params) { |
| 497 | IoctlGetVaRegions params{}; | ||
| 498 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 499 | |||
| 500 | LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, | 472 | LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, |
| 501 | params.buf_size); | 473 | params.buf_size); |
| 502 | 474 | ||
| @@ -508,15 +480,10 @@ NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> ou | |||
| 508 | 480 | ||
| 509 | GetVARegionsImpl(params); | 481 | GetVARegionsImpl(params); |
| 510 | 482 | ||
| 511 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 512 | return NvResult::Success; | 483 | return NvResult::Success; |
| 513 | } | 484 | } |
| 514 | 485 | ||
| 515 | NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output, | 486 | NvResult nvhost_as_gpu::GetVARegions3(IoctlGetVaRegions& params, std::span<VaRegion> regions) { |
| 516 | std::span<u8> inline_output) { | ||
| 517 | IoctlGetVaRegions params{}; | ||
| 518 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 519 | |||
| 520 | LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, | 487 | LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, |
| 521 | params.buf_size); | 488 | params.buf_size); |
| 522 | 489 | ||
| @@ -528,9 +495,10 @@ NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> ou | |||
| 528 | 495 | ||
| 529 | GetVARegionsImpl(params); | 496 | GetVARegionsImpl(params); |
| 530 | 497 | ||
| 531 | std::memcpy(output.data(), ¶ms, output.size()); | 498 | const size_t num_regions = std::min(params.regions.size(), regions.size()); |
| 532 | std::memcpy(inline_output.data(), ¶ms.regions[0], sizeof(VaRegion)); | 499 | for (size_t i = 0; i < num_regions; i++) { |
| 533 | std::memcpy(inline_output.data() + sizeof(VaRegion), ¶ms.regions[1], sizeof(VaRegion)); | 500 | regions[i] = params.regions[i]; |
| 501 | } | ||
| 534 | 502 | ||
| 535 | return NvResult::Success; | 503 | return NvResult::Success; |
| 536 | } | 504 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 2af3e1260..932997e75 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -139,18 +139,17 @@ private: | |||
| 139 | static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, | 139 | static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, |
| 140 | "IoctlGetVaRegions is incorrect size"); | 140 | "IoctlGetVaRegions is incorrect size"); |
| 141 | 141 | ||
| 142 | NvResult AllocAsEx(std::span<const u8> input, std::span<u8> output); | 142 | NvResult AllocAsEx(IoctlAllocAsEx& params); |
| 143 | NvResult AllocateSpace(std::span<const u8> input, std::span<u8> output); | 143 | NvResult AllocateSpace(IoctlAllocSpace& params); |
| 144 | NvResult Remap(std::span<const u8> input, std::span<u8> output); | 144 | NvResult Remap(std::span<IoctlRemapEntry> params); |
| 145 | NvResult MapBufferEx(std::span<const u8> input, std::span<u8> output); | 145 | NvResult MapBufferEx(IoctlMapBufferEx& params); |
| 146 | NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output); | 146 | NvResult UnmapBuffer(IoctlUnmapBuffer& params); |
| 147 | NvResult FreeSpace(std::span<const u8> input, std::span<u8> output); | 147 | NvResult FreeSpace(IoctlFreeSpace& params); |
| 148 | NvResult BindChannel(std::span<const u8> input, std::span<u8> output); | 148 | NvResult BindChannel(IoctlBindChannel& params); |
| 149 | 149 | ||
| 150 | void GetVARegionsImpl(IoctlGetVaRegions& params); | 150 | void GetVARegionsImpl(IoctlGetVaRegions& params); |
| 151 | NvResult GetVARegions(std::span<const u8> input, std::span<u8> output); | 151 | NvResult GetVARegions1(IoctlGetVaRegions& params); |
| 152 | NvResult GetVARegions(std::span<const u8> input, std::span<u8> output, | 152 | NvResult GetVARegions3(IoctlGetVaRegions& params, std::span<VaRegion> regions); |
| 153 | std::span<u8> inline_output); | ||
| 154 | 153 | ||
| 155 | void FreeMappingLocked(u64 offset); | 154 | void FreeMappingLocked(u64 offset); |
| 156 | 155 | ||
| @@ -213,7 +212,6 @@ private: | |||
| 213 | bool initialised{}; | 212 | bool initialised{}; |
| 214 | } vm; | 213 | } vm; |
| 215 | std::shared_ptr<Tegra::MemoryManager> gmmu; | 214 | std::shared_ptr<Tegra::MemoryManager> gmmu; |
| 216 | Common::ScratchBuffer<IoctlRemapEntry> entries; | ||
| 217 | 215 | ||
| 218 | // s32 channel{}; | 216 | // s32 channel{}; |
| 219 | // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; | 217 | // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 4d55554b4..b8dd34e24 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "core/hle/kernel/k_event.h" | 14 | #include "core/hle/kernel/k_event.h" |
| 15 | #include "core/hle/service/nvdrv/core/container.h" | 15 | #include "core/hle/service/nvdrv/core/container.h" |
| 16 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" | 16 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" |
| 17 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 17 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" | 18 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" |
| 18 | #include "video_core/gpu.h" | 19 | #include "video_core/gpu.h" |
| 19 | #include "video_core/host1x/host1x.h" | 20 | #include "video_core/host1x/host1x.h" |
| @@ -40,19 +41,19 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inp | |||
| 40 | case 0x0: | 41 | case 0x0: |
| 41 | switch (command.cmd) { | 42 | switch (command.cmd) { |
| 42 | case 0x1b: | 43 | case 0x1b: |
| 43 | return NvOsGetConfigU32(input, output); | 44 | return WrapFixed(this, &nvhost_ctrl::NvOsGetConfigU32, input, output); |
| 44 | case 0x1c: | 45 | case 0x1c: |
| 45 | return IocCtrlClearEventWait(input, output); | 46 | return WrapFixed(this, &nvhost_ctrl::IocCtrlClearEventWait, input, output); |
| 46 | case 0x1d: | 47 | case 0x1d: |
| 47 | return IocCtrlEventWait(input, output, true); | 48 | return WrapFixed(this, &nvhost_ctrl::IocCtrlEventWait, input, output, true); |
| 48 | case 0x1e: | 49 | case 0x1e: |
| 49 | return IocCtrlEventWait(input, output, false); | 50 | return WrapFixed(this, &nvhost_ctrl::IocCtrlEventWait, input, output, false); |
| 50 | case 0x1f: | 51 | case 0x1f: |
| 51 | return IocCtrlEventRegister(input, output); | 52 | return WrapFixed(this, &nvhost_ctrl::IocCtrlEventRegister, input, output); |
| 52 | case 0x20: | 53 | case 0x20: |
| 53 | return IocCtrlEventUnregister(input, output); | 54 | return WrapFixed(this, &nvhost_ctrl::IocCtrlEventUnregister, input, output); |
| 54 | case 0x21: | 55 | case 0x21: |
| 55 | return IocCtrlEventUnregisterBatch(input, output); | 56 | return WrapFixed(this, &nvhost_ctrl::IocCtrlEventUnregisterBatch, input, output); |
| 56 | } | 57 | } |
| 57 | break; | 58 | break; |
| 58 | default: | 59 | default: |
| @@ -79,25 +80,19 @@ void nvhost_ctrl::OnOpen(DeviceFD fd) {} | |||
| 79 | 80 | ||
| 80 | void nvhost_ctrl::OnClose(DeviceFD fd) {} | 81 | void nvhost_ctrl::OnClose(DeviceFD fd) {} |
| 81 | 82 | ||
| 82 | NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::span<u8> output) { | 83 | NvResult nvhost_ctrl::NvOsGetConfigU32(IocGetConfigParams& params) { |
| 83 | IocGetConfigParams params{}; | ||
| 84 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 85 | LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), | 84 | LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), |
| 86 | params.param_str.data()); | 85 | params.param_str.data()); |
| 87 | return NvResult::ConfigVarNotFound; // Returns error on production mode | 86 | return NvResult::ConfigVarNotFound; // Returns error on production mode |
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | NvResult nvhost_ctrl::IocCtrlEventWait(std::span<const u8> input, std::span<u8> output, | 89 | NvResult nvhost_ctrl::IocCtrlEventWait(IocCtrlEventWaitParams& params, bool is_allocation) { |
| 91 | bool is_allocation) { | ||
| 92 | IocCtrlEventWaitParams params{}; | ||
| 93 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 94 | LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_allocation={}", | 90 | LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_allocation={}", |
| 95 | params.fence.id, params.fence.value, params.timeout, is_allocation); | 91 | params.fence.id, params.fence.value, params.timeout, is_allocation); |
| 96 | 92 | ||
| 97 | bool must_unmark_fail = !is_allocation; | 93 | bool must_unmark_fail = !is_allocation; |
| 98 | const u32 event_id = params.value.raw; | 94 | const u32 event_id = params.value.raw; |
| 99 | SCOPE_EXIT({ | 95 | SCOPE_EXIT({ |
| 100 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 101 | if (must_unmark_fail) { | 96 | if (must_unmark_fail) { |
| 102 | events[event_id].fails = 0; | 97 | events[event_id].fails = 0; |
| 103 | } | 98 | } |
| @@ -231,9 +226,7 @@ NvResult nvhost_ctrl::FreeEvent(u32 slot) { | |||
| 231 | return NvResult::Success; | 226 | return NvResult::Success; |
| 232 | } | 227 | } |
| 233 | 228 | ||
| 234 | NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::span<u8> output) { | 229 | NvResult nvhost_ctrl::IocCtrlEventRegister(IocCtrlEventRegisterParams& params) { |
| 235 | IocCtrlEventRegisterParams params{}; | ||
| 236 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 237 | const u32 event_id = params.user_event_id; | 230 | const u32 event_id = params.user_event_id; |
| 238 | LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id); | 231 | LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id); |
| 239 | if (event_id >= MaxNvEvents) { | 232 | if (event_id >= MaxNvEvents) { |
| @@ -252,9 +245,7 @@ NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::span< | |||
| 252 | return NvResult::Success; | 245 | return NvResult::Success; |
| 253 | } | 246 | } |
| 254 | 247 | ||
| 255 | NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::span<u8> output) { | 248 | NvResult nvhost_ctrl::IocCtrlEventUnregister(IocCtrlEventUnregisterParams& params) { |
| 256 | IocCtrlEventUnregisterParams params{}; | ||
| 257 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 258 | const u32 event_id = params.user_event_id & 0x00FF; | 249 | const u32 event_id = params.user_event_id & 0x00FF; |
| 259 | LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id); | 250 | LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id); |
| 260 | 251 | ||
| @@ -262,9 +253,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::spa | |||
| 262 | return FreeEvent(event_id); | 253 | return FreeEvent(event_id); |
| 263 | } | 254 | } |
| 264 | 255 | ||
| 265 | NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, std::span<u8> output) { | 256 | NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(IocCtrlEventUnregisterBatchParams& params) { |
| 266 | IocCtrlEventUnregisterBatchParams params{}; | ||
| 267 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 268 | u64 event_mask = params.user_events; | 257 | u64 event_mask = params.user_events; |
| 269 | LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask); | 258 | LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask); |
| 270 | 259 | ||
| @@ -280,10 +269,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, std | |||
| 280 | return NvResult::Success; | 269 | return NvResult::Success; |
| 281 | } | 270 | } |
| 282 | 271 | ||
| 283 | NvResult nvhost_ctrl::IocCtrlClearEventWait(std::span<const u8> input, std::span<u8> output) { | 272 | NvResult nvhost_ctrl::IocCtrlClearEventWait(IocCtrlEventClearParams& params) { |
| 284 | IocCtrlEventClearParams params{}; | ||
| 285 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 286 | |||
| 287 | u32 event_id = params.event_id.slot; | 273 | u32 event_id = params.event_id.slot; |
| 288 | LOG_DEBUG(Service_NVDRV, "called, event_id: {:X}", event_id); | 274 | LOG_DEBUG(Service_NVDRV, "called, event_id: {:X}", event_id); |
| 289 | 275 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 2efed4862..992124b60 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | |||
| @@ -186,12 +186,12 @@ private: | |||
| 186 | static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, | 186 | static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, |
| 187 | "IocCtrlEventKill is incorrect size"); | 187 | "IocCtrlEventKill is incorrect size"); |
| 188 | 188 | ||
| 189 | NvResult NvOsGetConfigU32(std::span<const u8> input, std::span<u8> output); | 189 | NvResult NvOsGetConfigU32(IocGetConfigParams& params); |
| 190 | NvResult IocCtrlEventWait(std::span<const u8> input, std::span<u8> output, bool is_allocation); | 190 | NvResult IocCtrlEventRegister(IocCtrlEventRegisterParams& params); |
| 191 | NvResult IocCtrlEventRegister(std::span<const u8> input, std::span<u8> output); | 191 | NvResult IocCtrlEventUnregister(IocCtrlEventUnregisterParams& params); |
| 192 | NvResult IocCtrlEventUnregister(std::span<const u8> input, std::span<u8> output); | 192 | NvResult IocCtrlEventUnregisterBatch(IocCtrlEventUnregisterBatchParams& params); |
| 193 | NvResult IocCtrlEventUnregisterBatch(std::span<const u8> input, std::span<u8> output); | 193 | NvResult IocCtrlEventWait(IocCtrlEventWaitParams& params, bool is_allocation); |
| 194 | NvResult IocCtrlClearEventWait(std::span<const u8> input, std::span<u8> output); | 194 | NvResult IocCtrlClearEventWait(IocCtrlEventClearParams& params); |
| 195 | 195 | ||
| 196 | NvResult FreeEvent(u32 slot); | 196 | NvResult FreeEvent(u32 slot); |
| 197 | 197 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 6081d92e9..61a2df121 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 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/core_timing.h" | 8 | #include "core/core_timing.h" |
| 9 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 9 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" | 10 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" |
| 10 | #include "core/hle/service/nvdrv/nvdrv.h" | 11 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 11 | 12 | ||
| @@ -27,23 +28,23 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> | |||
| 27 | case 'G': | 28 | case 'G': |
| 28 | switch (command.cmd) { | 29 | switch (command.cmd) { |
| 29 | case 0x1: | 30 | case 0x1: |
| 30 | return ZCullGetCtxSize(input, output); | 31 | return WrapFixed(this, &nvhost_ctrl_gpu::ZCullGetCtxSize, input, output); |
| 31 | case 0x2: | 32 | case 0x2: |
| 32 | return ZCullGetInfo(input, output); | 33 | return WrapFixed(this, &nvhost_ctrl_gpu::ZCullGetInfo, input, output); |
| 33 | case 0x3: | 34 | case 0x3: |
| 34 | return ZBCSetTable(input, output); | 35 | return WrapFixed(this, &nvhost_ctrl_gpu::ZBCSetTable, input, output); |
| 35 | case 0x4: | 36 | case 0x4: |
| 36 | return ZBCQueryTable(input, output); | 37 | return WrapFixed(this, &nvhost_ctrl_gpu::ZBCQueryTable, input, output); |
| 37 | case 0x5: | 38 | case 0x5: |
| 38 | return GetCharacteristics(input, output); | 39 | return WrapFixed(this, &nvhost_ctrl_gpu::GetCharacteristics1, input, output); |
| 39 | case 0x6: | 40 | case 0x6: |
| 40 | return GetTPCMasks(input, output); | 41 | return WrapFixed(this, &nvhost_ctrl_gpu::GetTPCMasks1, input, output); |
| 41 | case 0x7: | 42 | case 0x7: |
| 42 | return FlushL2(input, output); | 43 | return WrapFixed(this, &nvhost_ctrl_gpu::FlushL2, input, output); |
| 43 | case 0x14: | 44 | case 0x14: |
| 44 | return GetActiveSlotMask(input, output); | 45 | return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output); |
| 45 | case 0x1c: | 46 | case 0x1c: |
| 46 | return GetGpuTime(input, output); | 47 | return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output); |
| 47 | default: | 48 | default: |
| 48 | break; | 49 | break; |
| 49 | } | 50 | } |
| @@ -65,9 +66,11 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> | |||
| 65 | case 'G': | 66 | case 'G': |
| 66 | switch (command.cmd) { | 67 | switch (command.cmd) { |
| 67 | case 0x5: | 68 | case 0x5: |
| 68 | return GetCharacteristics(input, output, inline_output); | 69 | return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetCharacteristics3, input, output, |
| 70 | inline_output); | ||
| 69 | case 0x6: | 71 | case 0x6: |
| 70 | return GetTPCMasks(input, output, inline_output); | 72 | return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetTPCMasks3, input, output, |
| 73 | inline_output); | ||
| 71 | default: | 74 | default: |
| 72 | break; | 75 | break; |
| 73 | } | 76 | } |
| @@ -82,10 +85,8 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> | |||
| 82 | void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} | 85 | void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} |
| 83 | void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} | 86 | void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} |
| 84 | 87 | ||
| 85 | NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::span<u8> output) { | 88 | NvResult nvhost_ctrl_gpu::GetCharacteristics1(IoctlCharacteristics& params) { |
| 86 | LOG_DEBUG(Service_NVDRV, "called"); | 89 | LOG_DEBUG(Service_NVDRV, "called"); |
| 87 | IoctlCharacteristics params{}; | ||
| 88 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 89 | params.gc.arch = 0x120; | 90 | params.gc.arch = 0x120; |
| 90 | params.gc.impl = 0xb; | 91 | params.gc.impl = 0xb; |
| 91 | params.gc.rev = 0xa1; | 92 | params.gc.rev = 0xa1; |
| @@ -123,15 +124,13 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::spa | |||
| 123 | params.gc.gr_compbit_store_base_hw = 0x0; | 124 | params.gc.gr_compbit_store_base_hw = 0x0; |
| 124 | params.gpu_characteristics_buf_size = 0xA0; | 125 | params.gpu_characteristics_buf_size = 0xA0; |
| 125 | params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) | 126 | params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) |
| 126 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 127 | return NvResult::Success; | 127 | return NvResult::Success; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::span<u8> output, | 130 | NvResult nvhost_ctrl_gpu::GetCharacteristics3( |
| 131 | std::span<u8> inline_output) { | 131 | IoctlCharacteristics& params, std::span<IoctlGpuCharacteristics> gpu_characteristics) { |
| 132 | LOG_DEBUG(Service_NVDRV, "called"); | 132 | LOG_DEBUG(Service_NVDRV, "called"); |
| 133 | IoctlCharacteristics params{}; | 133 | |
| 134 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 135 | params.gc.arch = 0x120; | 134 | params.gc.arch = 0x120; |
| 136 | params.gc.impl = 0xb; | 135 | params.gc.impl = 0xb; |
| 137 | params.gc.rev = 0xa1; | 136 | params.gc.rev = 0xa1; |
| @@ -169,70 +168,47 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::spa | |||
| 169 | params.gc.gr_compbit_store_base_hw = 0x0; | 168 | params.gc.gr_compbit_store_base_hw = 0x0; |
| 170 | params.gpu_characteristics_buf_size = 0xA0; | 169 | params.gpu_characteristics_buf_size = 0xA0; |
| 171 | params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) | 170 | params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) |
| 172 | 171 | if (!gpu_characteristics.empty()) { | |
| 173 | std::memcpy(output.data(), ¶ms, output.size()); | 172 | gpu_characteristics.front() = params.gc; |
| 174 | std::memcpy(inline_output.data(), ¶ms.gc, inline_output.size()); | 173 | } |
| 175 | return NvResult::Success; | 174 | return NvResult::Success; |
| 176 | } | 175 | } |
| 177 | 176 | ||
| 178 | NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::span<u8> output) { | 177 | NvResult nvhost_ctrl_gpu::GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params) { |
| 179 | IoctlGpuGetTpcMasksArgs params{}; | ||
| 180 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 181 | LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); | 178 | LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); |
| 182 | if (params.mask_buffer_size != 0) { | 179 | if (params.mask_buffer_size != 0) { |
| 183 | params.tcp_mask = 3; | 180 | params.tcp_mask = 3; |
| 184 | } | 181 | } |
| 185 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 186 | return NvResult::Success; | 182 | return NvResult::Success; |
| 187 | } | 183 | } |
| 188 | 184 | ||
| 189 | NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::span<u8> output, | 185 | NvResult nvhost_ctrl_gpu::GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span<u32> tpc_mask) { |
| 190 | std::span<u8> inline_output) { | ||
| 191 | IoctlGpuGetTpcMasksArgs params{}; | ||
| 192 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 193 | LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); | 186 | LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); |
| 194 | if (params.mask_buffer_size != 0) { | 187 | if (params.mask_buffer_size != 0) { |
| 195 | params.tcp_mask = 3; | 188 | params.tcp_mask = 3; |
| 196 | } | 189 | } |
| 197 | std::memcpy(output.data(), ¶ms, output.size()); | 190 | if (!tpc_mask.empty()) { |
| 198 | std::memcpy(inline_output.data(), ¶ms.tcp_mask, inline_output.size()); | 191 | tpc_mask.front() = params.tcp_mask; |
| 192 | } | ||
| 199 | return NvResult::Success; | 193 | return NvResult::Success; |
| 200 | } | 194 | } |
| 201 | 195 | ||
| 202 | NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::span<u8> output) { | 196 | NvResult nvhost_ctrl_gpu::GetActiveSlotMask(IoctlActiveSlotMask& params) { |
| 203 | LOG_DEBUG(Service_NVDRV, "called"); | 197 | LOG_DEBUG(Service_NVDRV, "called"); |
| 204 | 198 | ||
| 205 | IoctlActiveSlotMask params{}; | ||
| 206 | if (input.size() > 0) { | ||
| 207 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 208 | } | ||
| 209 | params.slot = 0x07; | 199 | params.slot = 0x07; |
| 210 | params.mask = 0x01; | 200 | params.mask = 0x01; |
| 211 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 212 | return NvResult::Success; | 201 | return NvResult::Success; |
| 213 | } | 202 | } |
| 214 | 203 | ||
| 215 | NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output) { | 204 | NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(IoctlZcullGetCtxSize& params) { |
| 216 | LOG_DEBUG(Service_NVDRV, "called"); | 205 | LOG_DEBUG(Service_NVDRV, "called"); |
| 217 | |||
| 218 | IoctlZcullGetCtxSize params{}; | ||
| 219 | if (input.size() > 0) { | ||
| 220 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 221 | } | ||
| 222 | params.size = 0x1; | 206 | params.size = 0x1; |
| 223 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 224 | return NvResult::Success; | 207 | return NvResult::Success; |
| 225 | } | 208 | } |
| 226 | 209 | ||
| 227 | NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::span<u8> output) { | 210 | NvResult nvhost_ctrl_gpu::ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params) { |
| 228 | LOG_DEBUG(Service_NVDRV, "called"); | 211 | LOG_DEBUG(Service_NVDRV, "called"); |
| 229 | |||
| 230 | IoctlNvgpuGpuZcullGetInfoArgs params{}; | ||
| 231 | |||
| 232 | if (input.size() > 0) { | ||
| 233 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 234 | } | ||
| 235 | |||
| 236 | params.width_align_pixels = 0x20; | 212 | params.width_align_pixels = 0x20; |
| 237 | params.height_align_pixels = 0x20; | 213 | params.height_align_pixels = 0x20; |
| 238 | params.pixel_squares_by_aliquots = 0x400; | 214 | params.pixel_squares_by_aliquots = 0x400; |
| @@ -243,53 +219,28 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::span<u8> | |||
| 243 | params.subregion_width_align_pixels = 0x20; | 219 | params.subregion_width_align_pixels = 0x20; |
| 244 | params.subregion_height_align_pixels = 0x40; | 220 | params.subregion_height_align_pixels = 0x40; |
| 245 | params.subregion_count = 0x10; | 221 | params.subregion_count = 0x10; |
| 246 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 247 | return NvResult::Success; | 222 | return NvResult::Success; |
| 248 | } | 223 | } |
| 249 | 224 | ||
| 250 | NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::span<u8> output) { | 225 | NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) { |
| 251 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 226 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 252 | |||
| 253 | IoctlZbcSetTable params{}; | ||
| 254 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 255 | // TODO(ogniK): What does this even actually do? | 227 | // TODO(ogniK): What does this even actually do? |
| 256 | |||
| 257 | // Prevent null pointer being passed as arg 1 | ||
| 258 | if (output.empty()) { | ||
| 259 | LOG_WARNING(Service_NVDRV, "Avoiding passing null pointer to memcpy"); | ||
| 260 | } else { | ||
| 261 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 262 | } | ||
| 263 | return NvResult::Success; | 228 | return NvResult::Success; |
| 264 | } | 229 | } |
| 265 | 230 | ||
| 266 | NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::span<u8> output) { | 231 | NvResult nvhost_ctrl_gpu::ZBCQueryTable(IoctlZbcQueryTable& params) { |
| 267 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 232 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 268 | |||
| 269 | IoctlZbcQueryTable params{}; | ||
| 270 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 271 | // TODO : To implement properly | ||
| 272 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 273 | return NvResult::Success; | 233 | return NvResult::Success; |
| 274 | } | 234 | } |
| 275 | 235 | ||
| 276 | NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::span<u8> output) { | 236 | NvResult nvhost_ctrl_gpu::FlushL2(IoctlFlushL2& params) { |
| 277 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 237 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 278 | |||
| 279 | IoctlFlushL2 params{}; | ||
| 280 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 281 | // TODO : To implement properly | ||
| 282 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 283 | return NvResult::Success; | 238 | return NvResult::Success; |
| 284 | } | 239 | } |
| 285 | 240 | ||
| 286 | NvResult nvhost_ctrl_gpu::GetGpuTime(std::span<const u8> input, std::span<u8> output) { | 241 | NvResult nvhost_ctrl_gpu::GetGpuTime(IoctlGetGpuTime& params) { |
| 287 | LOG_DEBUG(Service_NVDRV, "called"); | 242 | LOG_DEBUG(Service_NVDRV, "called"); |
| 288 | |||
| 289 | IoctlGetGpuTime params{}; | ||
| 290 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 291 | params.gpu_time = static_cast<u64_le>(system.CoreTiming().GetGlobalTimeNs().count()); | 243 | params.gpu_time = static_cast<u64_le>(system.CoreTiming().GetGlobalTimeNs().count()); |
| 292 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 293 | return NvResult::Success; | 244 | return NvResult::Success; |
| 294 | } | 245 | } |
| 295 | 246 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index 97995551c..d170299bd 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | |||
| @@ -151,21 +151,20 @@ private: | |||
| 151 | }; | 151 | }; |
| 152 | static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); | 152 | static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); |
| 153 | 153 | ||
| 154 | NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output); | 154 | NvResult GetCharacteristics1(IoctlCharacteristics& params); |
| 155 | NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output, | 155 | NvResult GetCharacteristics3(IoctlCharacteristics& params, |
| 156 | std::span<u8> inline_output); | 156 | std::span<IoctlGpuCharacteristics> gpu_characteristics); |
| 157 | 157 | ||
| 158 | NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output); | 158 | NvResult GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params); |
| 159 | NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output, | 159 | NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span<u32> tpc_mask); |
| 160 | std::span<u8> inline_output); | 160 | |
| 161 | 161 | NvResult GetActiveSlotMask(IoctlActiveSlotMask& params); | |
| 162 | NvResult GetActiveSlotMask(std::span<const u8> input, std::span<u8> output); | 162 | NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params); |
| 163 | NvResult ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output); | 163 | NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params); |
| 164 | NvResult ZCullGetInfo(std::span<const u8> input, std::span<u8> output); | 164 | NvResult ZBCSetTable(IoctlZbcSetTable& params); |
| 165 | NvResult ZBCSetTable(std::span<const u8> input, std::span<u8> output); | 165 | NvResult ZBCQueryTable(IoctlZbcQueryTable& params); |
| 166 | NvResult ZBCQueryTable(std::span<const u8> input, std::span<u8> output); | 166 | NvResult FlushL2(IoctlFlushL2& params); |
| 167 | NvResult FlushL2(std::span<const u8> input, std::span<u8> output); | 167 | NvResult GetGpuTime(IoctlGetGpuTime& params); |
| 168 | NvResult GetGpuTime(std::span<const u8> input, std::span<u8> output); | ||
| 169 | 168 | ||
| 170 | EventInterface& events_interface; | 169 | EventInterface& events_interface; |
| 171 | 170 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 46a25fcab..b0395c2f0 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "core/hle/service/nvdrv/core/container.h" | 8 | #include "core/hle/service/nvdrv/core/container.h" |
| 9 | #include "core/hle/service/nvdrv/core/nvmap.h" | 9 | #include "core/hle/service/nvdrv/core/nvmap.h" |
| 10 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" | 10 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" |
| 11 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 11 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" | 12 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" |
| 12 | #include "core/hle/service/nvdrv/nvdrv.h" | 13 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 13 | #include "core/memory.h" | 14 | #include "core/memory.h" |
| @@ -52,7 +53,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 52 | case 0x0: | 53 | case 0x0: |
| 53 | switch (command.cmd) { | 54 | switch (command.cmd) { |
| 54 | case 0x3: | 55 | case 0x3: |
| 55 | return GetWaitbase(input, output); | 56 | return WrapFixed(this, &nvhost_gpu::GetWaitbase, input, output); |
| 56 | default: | 57 | default: |
| 57 | break; | 58 | break; |
| 58 | } | 59 | } |
| @@ -60,25 +61,25 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 60 | case 'H': | 61 | case 'H': |
| 61 | switch (command.cmd) { | 62 | switch (command.cmd) { |
| 62 | case 0x1: | 63 | case 0x1: |
| 63 | return SetNVMAPfd(input, output); | 64 | return WrapFixed(this, &nvhost_gpu::SetNVMAPfd, input, output); |
| 64 | case 0x3: | 65 | case 0x3: |
| 65 | return ChannelSetTimeout(input, output); | 66 | return WrapFixed(this, &nvhost_gpu::ChannelSetTimeout, input, output); |
| 66 | case 0x8: | 67 | case 0x8: |
| 67 | return SubmitGPFIFOBase(input, output, false); | 68 | return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, false); |
| 68 | case 0x9: | 69 | case 0x9: |
| 69 | return AllocateObjectContext(input, output); | 70 | return WrapFixed(this, &nvhost_gpu::AllocateObjectContext, input, output); |
| 70 | case 0xb: | 71 | case 0xb: |
| 71 | return ZCullBind(input, output); | 72 | return WrapFixed(this, &nvhost_gpu::ZCullBind, input, output); |
| 72 | case 0xc: | 73 | case 0xc: |
| 73 | return SetErrorNotifier(input, output); | 74 | return WrapFixed(this, &nvhost_gpu::SetErrorNotifier, input, output); |
| 74 | case 0xd: | 75 | case 0xd: |
| 75 | return SetChannelPriority(input, output); | 76 | return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output); |
| 76 | case 0x1a: | 77 | case 0x1a: |
| 77 | return AllocGPFIFOEx2(input, output); | 78 | return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output); |
| 78 | case 0x1b: | 79 | case 0x1b: |
| 79 | return SubmitGPFIFOBase(input, output, true); | 80 | return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true); |
| 80 | case 0x1d: | 81 | case 0x1d: |
| 81 | return ChannelSetTimeslice(input, output); | 82 | return WrapFixed(this, &nvhost_gpu::ChannelSetTimeslice, input, output); |
| 82 | default: | 83 | default: |
| 83 | break; | 84 | break; |
| 84 | } | 85 | } |
| @@ -86,9 +87,9 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 86 | case 'G': | 87 | case 'G': |
| 87 | switch (command.cmd) { | 88 | switch (command.cmd) { |
| 88 | case 0x14: | 89 | case 0x14: |
| 89 | return SetClientData(input, output); | 90 | return WrapFixed(this, &nvhost_gpu::SetClientData, input, output); |
| 90 | case 0x15: | 91 | case 0x15: |
| 91 | return GetClientData(input, output); | 92 | return WrapFixed(this, &nvhost_gpu::GetClientData, input, output); |
| 92 | default: | 93 | default: |
| 93 | break; | 94 | break; |
| 94 | } | 95 | } |
| @@ -104,7 +105,8 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 104 | case 'H': | 105 | case 'H': |
| 105 | switch (command.cmd) { | 106 | switch (command.cmd) { |
| 106 | case 0x1b: | 107 | case 0x1b: |
| 107 | return SubmitGPFIFOBase(input, inline_input, output); | 108 | return WrapFixedInlIn(this, &nvhost_gpu::SubmitGPFIFOBase2, input, inline_input, |
| 109 | output); | ||
| 108 | } | 110 | } |
| 109 | break; | 111 | break; |
| 110 | } | 112 | } |
| @@ -121,63 +123,45 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 121 | void nvhost_gpu::OnOpen(DeviceFD fd) {} | 123 | void nvhost_gpu::OnOpen(DeviceFD fd) {} |
| 122 | void nvhost_gpu::OnClose(DeviceFD fd) {} | 124 | void nvhost_gpu::OnClose(DeviceFD fd) {} |
| 123 | 125 | ||
| 124 | NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) { | 126 | NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { |
| 125 | IoctlSetNvmapFD params{}; | ||
| 126 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 127 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); | 127 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
| 128 | 128 | ||
| 129 | nvmap_fd = params.nvmap_fd; | 129 | nvmap_fd = params.nvmap_fd; |
| 130 | return NvResult::Success; | 130 | return NvResult::Success; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::span<u8> output) { | 133 | NvResult nvhost_gpu::SetClientData(IoctlClientData& params) { |
| 134 | LOG_DEBUG(Service_NVDRV, "called"); | 134 | LOG_DEBUG(Service_NVDRV, "called"); |
| 135 | |||
| 136 | IoctlClientData params{}; | ||
| 137 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 138 | user_data = params.data; | 135 | user_data = params.data; |
| 139 | return NvResult::Success; | 136 | return NvResult::Success; |
| 140 | } | 137 | } |
| 141 | 138 | ||
| 142 | NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::span<u8> output) { | 139 | NvResult nvhost_gpu::GetClientData(IoctlClientData& params) { |
| 143 | LOG_DEBUG(Service_NVDRV, "called"); | 140 | LOG_DEBUG(Service_NVDRV, "called"); |
| 144 | |||
| 145 | IoctlClientData params{}; | ||
| 146 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 147 | params.data = user_data; | 141 | params.data = user_data; |
| 148 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 149 | return NvResult::Success; | 142 | return NvResult::Success; |
| 150 | } | 143 | } |
| 151 | 144 | ||
| 152 | NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::span<u8> output) { | 145 | NvResult nvhost_gpu::ZCullBind(IoctlZCullBind& params) { |
| 153 | std::memcpy(&zcull_params, input.data(), input.size()); | 146 | zcull_params = params; |
| 154 | LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, | 147 | LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, |
| 155 | zcull_params.mode); | 148 | zcull_params.mode); |
| 156 | |||
| 157 | std::memcpy(output.data(), &zcull_params, output.size()); | ||
| 158 | return NvResult::Success; | 149 | return NvResult::Success; |
| 159 | } | 150 | } |
| 160 | 151 | ||
| 161 | NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::span<u8> output) { | 152 | NvResult nvhost_gpu::SetErrorNotifier(IoctlSetErrorNotifier& params) { |
| 162 | IoctlSetErrorNotifier params{}; | ||
| 163 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 164 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset, | 153 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset, |
| 165 | params.size, params.mem); | 154 | params.size, params.mem); |
| 166 | |||
| 167 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 168 | return NvResult::Success; | 155 | return NvResult::Success; |
| 169 | } | 156 | } |
| 170 | 157 | ||
| 171 | NvResult nvhost_gpu::SetChannelPriority(std::span<const u8> input, std::span<u8> output) { | 158 | NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) { |
| 172 | std::memcpy(&channel_priority, input.data(), input.size()); | 159 | channel_priority = params.priority; |
| 173 | LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); | 160 | LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); |
| 174 | |||
| 175 | return NvResult::Success; | 161 | return NvResult::Success; |
| 176 | } | 162 | } |
| 177 | 163 | ||
| 178 | NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> output) { | 164 | NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { |
| 179 | IoctlAllocGpfifoEx2 params{}; | ||
| 180 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 181 | LOG_WARNING(Service_NVDRV, | 165 | LOG_WARNING(Service_NVDRV, |
| 182 | "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " | 166 | "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " |
| 183 | "unk1={:X}, unk2={:X}, unk3={:X}", | 167 | "unk1={:X}, unk2={:X}, unk3={:X}", |
| @@ -193,18 +177,14 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> out | |||
| 193 | 177 | ||
| 194 | params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint); | 178 | params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint); |
| 195 | 179 | ||
| 196 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 197 | return NvResult::Success; | 180 | return NvResult::Success; |
| 198 | } | 181 | } |
| 199 | 182 | ||
| 200 | NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::span<u8> output) { | 183 | NvResult nvhost_gpu::AllocateObjectContext(IoctlAllocObjCtx& params) { |
| 201 | IoctlAllocObjCtx params{}; | ||
| 202 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 203 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, | 184 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, |
| 204 | params.flags); | 185 | params.flags); |
| 205 | 186 | ||
| 206 | params.obj_id = 0x0; | 187 | params.obj_id = 0x0; |
| 207 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 208 | return NvResult::Success; | 188 | return NvResult::Success; |
| 209 | } | 189 | } |
| 210 | 190 | ||
| @@ -248,8 +228,7 @@ static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementW | |||
| 248 | return result; | 228 | return result; |
| 249 | } | 229 | } |
| 250 | 230 | ||
| 251 | NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output, | 231 | NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries) { |
| 252 | Tegra::CommandList&& entries) { | ||
| 253 | LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address, | 232 | LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address, |
| 254 | params.num_entries, params.flags.raw); | 233 | params.num_entries, params.flags.raw); |
| 255 | 234 | ||
| @@ -290,65 +269,55 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> o | |||
| 290 | 269 | ||
| 291 | flags.raw = 0; | 270 | flags.raw = 0; |
| 292 | 271 | ||
| 293 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmitGpfifo)); | ||
| 294 | return NvResult::Success; | 272 | return NvResult::Success; |
| 295 | } | 273 | } |
| 296 | 274 | ||
| 297 | NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<u8> output, | 275 | NvResult nvhost_gpu::SubmitGPFIFOBase1(IoctlSubmitGpfifo& params, |
| 298 | bool kickoff) { | 276 | std::span<Tegra::CommandListHeader> commands, bool kickoff) { |
| 299 | if (input.size() < sizeof(IoctlSubmitGpfifo)) { | 277 | if (params.num_entries > commands.size()) { |
| 300 | UNIMPLEMENTED(); | 278 | UNIMPLEMENTED(); |
| 301 | return NvResult::InvalidSize; | 279 | return NvResult::InvalidSize; |
| 302 | } | 280 | } |
| 303 | IoctlSubmitGpfifo params{}; | ||
| 304 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); | ||
| 305 | Tegra::CommandList entries(params.num_entries); | ||
| 306 | 281 | ||
| 282 | Tegra::CommandList entries(params.num_entries); | ||
| 307 | if (kickoff) { | 283 | if (kickoff) { |
| 308 | system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(), | 284 | system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(), |
| 309 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 285 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 310 | } else { | 286 | } else { |
| 311 | std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)], | 287 | std::memcpy(entries.command_lists.data(), commands.data(), |
| 312 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 288 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 313 | } | 289 | } |
| 314 | 290 | ||
| 315 | return SubmitGPFIFOImpl(params, output, std::move(entries)); | 291 | return SubmitGPFIFOImpl(params, std::move(entries)); |
| 316 | } | 292 | } |
| 317 | 293 | ||
| 318 | NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline, | 294 | NvResult nvhost_gpu::SubmitGPFIFOBase2(IoctlSubmitGpfifo& params, |
| 319 | std::span<u8> output) { | 295 | std::span<const Tegra::CommandListHeader> commands) { |
| 320 | if (input.size() < sizeof(IoctlSubmitGpfifo)) { | 296 | if (params.num_entries > commands.size()) { |
| 321 | UNIMPLEMENTED(); | 297 | UNIMPLEMENTED(); |
| 322 | return NvResult::InvalidSize; | 298 | return NvResult::InvalidSize; |
| 323 | } | 299 | } |
| 324 | IoctlSubmitGpfifo params{}; | 300 | |
| 325 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); | ||
| 326 | Tegra::CommandList entries(params.num_entries); | 301 | Tegra::CommandList entries(params.num_entries); |
| 327 | std::memcpy(entries.command_lists.data(), input_inline.data(), input_inline.size()); | 302 | std::memcpy(entries.command_lists.data(), commands.data(), |
| 328 | return SubmitGPFIFOImpl(params, output, std::move(entries)); | 303 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 304 | return SubmitGPFIFOImpl(params, std::move(entries)); | ||
| 329 | } | 305 | } |
| 330 | 306 | ||
| 331 | NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::span<u8> output) { | 307 | NvResult nvhost_gpu::GetWaitbase(IoctlGetWaitbase& params) { |
| 332 | IoctlGetWaitbase params{}; | ||
| 333 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); | ||
| 334 | LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); | 308 | LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); |
| 335 | 309 | ||
| 336 | params.value = 0; // Seems to be hard coded at 0 | 310 | params.value = 0; // Seems to be hard coded at 0 |
| 337 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 338 | return NvResult::Success; | 311 | return NvResult::Success; |
| 339 | } | 312 | } |
| 340 | 313 | ||
| 341 | NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::span<u8> output) { | 314 | NvResult nvhost_gpu::ChannelSetTimeout(IoctlChannelSetTimeout& params) { |
| 342 | IoctlChannelSetTimeout params{}; | ||
| 343 | std::memcpy(¶ms, input.data(), sizeof(IoctlChannelSetTimeout)); | ||
| 344 | LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout); | 315 | LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout); |
| 345 | 316 | ||
| 346 | return NvResult::Success; | 317 | return NvResult::Success; |
| 347 | } | 318 | } |
| 348 | 319 | ||
| 349 | NvResult nvhost_gpu::ChannelSetTimeslice(std::span<const u8> input, std::span<u8> output) { | 320 | NvResult nvhost_gpu::ChannelSetTimeslice(IoctlSetTimeslice& params) { |
| 350 | IoctlSetTimeslice params{}; | ||
| 351 | std::memcpy(¶ms, input.data(), sizeof(IoctlSetTimeslice)); | ||
| 352 | LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice); | 321 | LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice); |
| 353 | 322 | ||
| 354 | channel_timeslice = params.timeslice; | 323 | channel_timeslice = params.timeslice; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 529c20526..88fd228ff 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -186,23 +186,24 @@ private: | |||
| 186 | u32_le channel_priority{}; | 186 | u32_le channel_priority{}; |
| 187 | u32_le channel_timeslice{}; | 187 | u32_le channel_timeslice{}; |
| 188 | 188 | ||
| 189 | NvResult SetNVMAPfd(std::span<const u8> input, std::span<u8> output); | 189 | NvResult SetNVMAPfd(IoctlSetNvmapFD& params); |
| 190 | NvResult SetClientData(std::span<const u8> input, std::span<u8> output); | 190 | NvResult SetClientData(IoctlClientData& params); |
| 191 | NvResult GetClientData(std::span<const u8> input, std::span<u8> output); | 191 | NvResult GetClientData(IoctlClientData& params); |
| 192 | NvResult ZCullBind(std::span<const u8> input, std::span<u8> output); | 192 | NvResult ZCullBind(IoctlZCullBind& params); |
| 193 | NvResult SetErrorNotifier(std::span<const u8> input, std::span<u8> output); | 193 | NvResult SetErrorNotifier(IoctlSetErrorNotifier& params); |
| 194 | NvResult SetChannelPriority(std::span<const u8> input, std::span<u8> output); | 194 | NvResult SetChannelPriority(IoctlChannelSetPriority& params); |
| 195 | NvResult AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> output); | 195 | NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params); |
| 196 | NvResult AllocateObjectContext(std::span<const u8> input, std::span<u8> output); | 196 | NvResult AllocateObjectContext(IoctlAllocObjCtx& params); |
| 197 | NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output, | 197 | |
| 198 | Tegra::CommandList&& entries); | 198 | NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); |
| 199 | NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<u8> output, | 199 | NvResult SubmitGPFIFOBase1(IoctlSubmitGpfifo& params, |
| 200 | bool kickoff = false); | 200 | std::span<Tegra::CommandListHeader> commands, bool kickoff = false); |
| 201 | NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline, | 201 | NvResult SubmitGPFIFOBase2(IoctlSubmitGpfifo& params, |
| 202 | std::span<u8> output); | 202 | std::span<const Tegra::CommandListHeader> commands); |
| 203 | NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output); | 203 | |
| 204 | NvResult ChannelSetTimeout(std::span<const u8> input, std::span<u8> output); | 204 | NvResult GetWaitbase(IoctlGetWaitbase& params); |
| 205 | NvResult ChannelSetTimeslice(std::span<const u8> input, std::span<u8> output); | 205 | NvResult ChannelSetTimeout(IoctlChannelSetTimeout& params); |
| 206 | NvResult ChannelSetTimeslice(IoctlSetTimeslice& params); | ||
| 206 | 207 | ||
| 207 | EventInterface& events_interface; | 208 | EventInterface& events_interface; |
| 208 | NvCore::Container& core; | 209 | NvCore::Container& core; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index a174442a6..f43914e1b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 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/hle/service/nvdrv/core/container.h" | 8 | #include "core/hle/service/nvdrv/core/container.h" |
| 9 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 9 | #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" | 10 | #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" |
| 10 | #include "video_core/renderer_base.h" | 11 | #include "video_core/renderer_base.h" |
| 11 | 12 | ||
| @@ -25,18 +26,18 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 25 | if (!host1x_file.fd_to_id.contains(fd)) { | 26 | if (!host1x_file.fd_to_id.contains(fd)) { |
| 26 | host1x_file.fd_to_id[fd] = host1x_file.nvdec_next_id++; | 27 | host1x_file.fd_to_id[fd] = host1x_file.nvdec_next_id++; |
| 27 | } | 28 | } |
| 28 | return Submit(fd, input, output); | 29 | return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd); |
| 29 | } | 30 | } |
| 30 | case 0x2: | 31 | case 0x2: |
| 31 | return GetSyncpoint(input, output); | 32 | return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output); |
| 32 | case 0x3: | 33 | case 0x3: |
| 33 | return GetWaitbase(input, output); | 34 | return WrapFixed(this, &nvhost_nvdec::GetWaitbase, input, output); |
| 34 | case 0x7: | 35 | case 0x7: |
| 35 | return SetSubmitTimeout(input, output); | 36 | return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output); |
| 36 | case 0x9: | 37 | case 0x9: |
| 37 | return MapBuffer(input, output); | 38 | return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output); |
| 38 | case 0xa: | 39 | case 0xa: |
| 39 | return UnmapBuffer(input, output); | 40 | return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output); |
| 40 | default: | 41 | default: |
| 41 | break; | 42 | break; |
| 42 | } | 43 | } |
| @@ -44,7 +45,7 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 44 | case 'H': | 45 | case 'H': |
| 45 | switch (command.cmd) { | 46 | switch (command.cmd) { |
| 46 | case 0x1: | 47 | case 0x1: |
| 47 | return SetNVMAPfd(input); | 48 | return WrapFixed(this, &nvhost_nvdec::SetNVMAPfd, input, output); |
| 48 | default: | 49 | default: |
| 49 | break; | 50 | break; |
| 50 | } | 51 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 61649aa4a..74c701b95 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -29,6 +29,9 @@ std::size_t SliceVectors(std::span<const u8> input, std::vector<T>& dst, std::si | |||
| 29 | return 0; | 29 | return 0; |
| 30 | } | 30 | } |
| 31 | const size_t bytes_copied = count * sizeof(T); | 31 | const size_t bytes_copied = count * sizeof(T); |
| 32 | if (input.size() < offset + bytes_copied) { | ||
| 33 | return 0; | ||
| 34 | } | ||
| 32 | std::memcpy(dst.data(), input.data() + offset, bytes_copied); | 35 | std::memcpy(dst.data(), input.data() + offset, bytes_copied); |
| 33 | return bytes_copied; | 36 | return bytes_copied; |
| 34 | } | 37 | } |
| @@ -41,6 +44,9 @@ std::size_t WriteVectors(std::span<u8> dst, const std::vector<T>& src, std::size | |||
| 41 | return 0; | 44 | return 0; |
| 42 | } | 45 | } |
| 43 | const size_t bytes_copied = src.size() * sizeof(T); | 46 | const size_t bytes_copied = src.size() * sizeof(T); |
| 47 | if (dst.size() < offset + bytes_copied) { | ||
| 48 | return 0; | ||
| 49 | } | ||
| 44 | std::memcpy(dst.data() + offset, src.data(), bytes_copied); | 50 | std::memcpy(dst.data() + offset, src.data(), bytes_copied); |
| 45 | return bytes_copied; | 51 | return bytes_copied; |
| 46 | } | 52 | } |
| @@ -63,18 +69,14 @@ nvhost_nvdec_common::~nvhost_nvdec_common() { | |||
| 63 | core.Host1xDeviceFile().syncpts_accumulated.push_back(channel_syncpoint); | 69 | core.Host1xDeviceFile().syncpts_accumulated.push_back(channel_syncpoint); |
| 64 | } | 70 | } |
| 65 | 71 | ||
| 66 | NvResult nvhost_nvdec_common::SetNVMAPfd(std::span<const u8> input) { | 72 | NvResult nvhost_nvdec_common::SetNVMAPfd(IoctlSetNvmapFD& params) { |
| 67 | IoctlSetNvmapFD params{}; | ||
| 68 | std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD)); | ||
| 69 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); | 73 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
| 70 | 74 | ||
| 71 | nvmap_fd = params.nvmap_fd; | 75 | nvmap_fd = params.nvmap_fd; |
| 72 | return NvResult::Success; | 76 | return NvResult::Success; |
| 73 | } | 77 | } |
| 74 | 78 | ||
| 75 | NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output) { | 79 | NvResult nvhost_nvdec_common::Submit(IoctlSubmit& params, std::span<u8> data, DeviceFD fd) { |
| 76 | IoctlSubmit params{}; | ||
| 77 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); | ||
| 78 | LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); | 80 | LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); |
| 79 | 81 | ||
| 80 | // Instantiate param buffers | 82 | // Instantiate param buffers |
| @@ -85,12 +87,12 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std | |||
| 85 | std::vector<u32> fence_thresholds(params.fence_count); | 87 | std::vector<u32> fence_thresholds(params.fence_count); |
| 86 | 88 | ||
| 87 | // Slice input into their respective buffers | 89 | // Slice input into their respective buffers |
| 88 | std::size_t offset = sizeof(IoctlSubmit); | 90 | std::size_t offset = 0; |
| 89 | offset += SliceVectors(input, command_buffers, params.cmd_buffer_count, offset); | 91 | offset += SliceVectors(data, command_buffers, params.cmd_buffer_count, offset); |
| 90 | offset += SliceVectors(input, relocs, params.relocation_count, offset); | 92 | offset += SliceVectors(data, relocs, params.relocation_count, offset); |
| 91 | offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset); | 93 | offset += SliceVectors(data, reloc_shifts, params.relocation_count, offset); |
| 92 | offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset); | 94 | offset += SliceVectors(data, syncpt_increments, params.syncpoint_count, offset); |
| 93 | offset += SliceVectors(input, fence_thresholds, params.fence_count, offset); | 95 | offset += SliceVectors(data, fence_thresholds, params.fence_count, offset); |
| 94 | 96 | ||
| 95 | auto& gpu = system.GPU(); | 97 | auto& gpu = system.GPU(); |
| 96 | if (gpu.UseNvdec()) { | 98 | if (gpu.UseNvdec()) { |
| @@ -108,72 +110,51 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std | |||
| 108 | cmdlist.size() * sizeof(u32)); | 110 | cmdlist.size() * sizeof(u32)); |
| 109 | gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); | 111 | gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); |
| 110 | } | 112 | } |
| 111 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | ||
| 112 | // Some games expect command_buffers to be written back | 113 | // Some games expect command_buffers to be written back |
| 113 | offset = sizeof(IoctlSubmit); | 114 | offset = 0; |
| 114 | offset += WriteVectors(output, command_buffers, offset); | 115 | offset += WriteVectors(data, command_buffers, offset); |
| 115 | offset += WriteVectors(output, relocs, offset); | 116 | offset += WriteVectors(data, relocs, offset); |
| 116 | offset += WriteVectors(output, reloc_shifts, offset); | 117 | offset += WriteVectors(data, reloc_shifts, offset); |
| 117 | offset += WriteVectors(output, syncpt_increments, offset); | 118 | offset += WriteVectors(data, syncpt_increments, offset); |
| 118 | offset += WriteVectors(output, fence_thresholds, offset); | 119 | offset += WriteVectors(data, fence_thresholds, offset); |
| 119 | 120 | ||
| 120 | return NvResult::Success; | 121 | return NvResult::Success; |
| 121 | } | 122 | } |
| 122 | 123 | ||
| 123 | NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::span<u8> output) { | 124 | NvResult nvhost_nvdec_common::GetSyncpoint(IoctlGetSyncpoint& params) { |
| 124 | IoctlGetSyncpoint params{}; | ||
| 125 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); | ||
| 126 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); | 125 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); |
| 127 | |||
| 128 | // const u32 id{NvCore::SyncpointManager::channel_syncpoints[static_cast<u32>(channel_type)]}; | ||
| 129 | params.value = channel_syncpoint; | 126 | params.value = channel_syncpoint; |
| 130 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); | ||
| 131 | |||
| 132 | return NvResult::Success; | 127 | return NvResult::Success; |
| 133 | } | 128 | } |
| 134 | 129 | ||
| 135 | NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::span<u8> output) { | 130 | NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { |
| 136 | IoctlGetWaitbase params{}; | ||
| 137 | LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); | 131 | LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); |
| 138 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); | ||
| 139 | params.value = 0; // Seems to be hard coded at 0 | 132 | params.value = 0; // Seems to be hard coded at 0 |
| 140 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase)); | ||
| 141 | return NvResult::Success; | 133 | return NvResult::Success; |
| 142 | } | 134 | } |
| 143 | 135 | ||
| 144 | NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::span<u8> output) { | 136 | NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries) { |
| 145 | IoctlMapBuffer params{}; | 137 | const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); |
| 146 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); | 138 | for (size_t i = 0; i < num_entries; i++) { |
| 147 | std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); | 139 | entries[i].map_address = nvmap.PinHandle(entries[i].map_handle); |
| 148 | |||
| 149 | SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); | ||
| 150 | |||
| 151 | for (auto& cmd_buffer : cmd_buffer_handles) { | ||
| 152 | cmd_buffer.map_address = nvmap.PinHandle(cmd_buffer.map_handle); | ||
| 153 | } | 140 | } |
| 154 | std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); | ||
| 155 | std::memcpy(output.data() + sizeof(IoctlMapBuffer), cmd_buffer_handles.data(), | ||
| 156 | cmd_buffer_handles.size() * sizeof(MapBufferEntry)); | ||
| 157 | 141 | ||
| 158 | return NvResult::Success; | 142 | return NvResult::Success; |
| 159 | } | 143 | } |
| 160 | 144 | ||
| 161 | NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::span<u8> output) { | 145 | NvResult nvhost_nvdec_common::UnmapBuffer(IoctlMapBuffer& params, |
| 162 | IoctlMapBuffer params{}; | 146 | std::span<MapBufferEntry> entries) { |
| 163 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); | 147 | const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); |
| 164 | std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); | 148 | for (size_t i = 0; i < num_entries; i++) { |
| 165 | 149 | nvmap.UnpinHandle(entries[i].map_handle); | |
| 166 | SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); | 150 | entries[i] = {}; |
| 167 | for (auto& cmd_buffer : cmd_buffer_handles) { | ||
| 168 | nvmap.UnpinHandle(cmd_buffer.map_handle); | ||
| 169 | } | 151 | } |
| 170 | 152 | ||
| 171 | std::memset(output.data(), 0, output.size()); | 153 | params = {}; |
| 172 | return NvResult::Success; | 154 | return NvResult::Success; |
| 173 | } | 155 | } |
| 174 | 156 | ||
| 175 | NvResult nvhost_nvdec_common::SetSubmitTimeout(std::span<const u8> input, std::span<u8> output) { | 157 | NvResult nvhost_nvdec_common::SetSubmitTimeout(u32 timeout) { |
| 176 | std::memcpy(&submit_timeout, input.data(), input.size()); | ||
| 177 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 158 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 178 | return NvResult::Success; | 159 | return NvResult::Success; |
| 179 | } | 160 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h index 9bb573bfe..7ce748e18 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h | |||
| @@ -107,13 +107,13 @@ protected: | |||
| 107 | static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size"); | 107 | static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size"); |
| 108 | 108 | ||
| 109 | /// Ioctl command implementations | 109 | /// Ioctl command implementations |
| 110 | NvResult SetNVMAPfd(std::span<const u8> input); | 110 | NvResult SetNVMAPfd(IoctlSetNvmapFD&); |
| 111 | NvResult Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output); | 111 | NvResult Submit(IoctlSubmit& params, std::span<u8> input, DeviceFD fd); |
| 112 | NvResult GetSyncpoint(std::span<const u8> input, std::span<u8> output); | 112 | NvResult GetSyncpoint(IoctlGetSyncpoint& params); |
| 113 | NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output); | 113 | NvResult GetWaitbase(IoctlGetWaitbase& params); |
| 114 | NvResult MapBuffer(std::span<const u8> input, std::span<u8> output); | 114 | NvResult MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries); |
| 115 | NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output); | 115 | NvResult UnmapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries); |
| 116 | NvResult SetSubmitTimeout(std::span<const u8> input, std::span<u8> output); | 116 | NvResult SetSubmitTimeout(u32 timeout); |
| 117 | 117 | ||
| 118 | Kernel::KEvent* QueryEvent(u32 event_id) override; | 118 | Kernel::KEvent* QueryEvent(u32 event_id) override; |
| 119 | 119 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index a05c8cdae..9e6b86458 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 8 | #include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h" | 9 | #include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h" |
| 9 | 10 | ||
| 10 | namespace Service::Nvidia::Devices { | 11 | namespace Service::Nvidia::Devices { |
| @@ -18,7 +19,7 @@ NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 18 | case 'H': | 19 | case 'H': |
| 19 | switch (command.cmd) { | 20 | switch (command.cmd) { |
| 20 | case 0x1: | 21 | case 0x1: |
| 21 | return SetNVMAPfd(input, output); | 22 | return WrapFixed(this, &nvhost_nvjpg::SetNVMAPfd, input, output); |
| 22 | default: | 23 | default: |
| 23 | break; | 24 | break; |
| 24 | } | 25 | } |
| @@ -46,9 +47,7 @@ NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 46 | void nvhost_nvjpg::OnOpen(DeviceFD fd) {} | 47 | void nvhost_nvjpg::OnOpen(DeviceFD fd) {} |
| 47 | void nvhost_nvjpg::OnClose(DeviceFD fd) {} | 48 | void nvhost_nvjpg::OnClose(DeviceFD fd) {} |
| 48 | 49 | ||
| 49 | NvResult nvhost_nvjpg::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) { | 50 | NvResult nvhost_nvjpg::SetNVMAPfd(IoctlSetNvmapFD& params) { |
| 50 | IoctlSetNvmapFD params{}; | ||
| 51 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 52 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); | 51 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
| 53 | 52 | ||
| 54 | nvmap_fd = params.nvmap_fd; | 53 | nvmap_fd = params.nvmap_fd; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h index 5623e0d47..790c97f6a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h | |||
| @@ -33,7 +33,7 @@ private: | |||
| 33 | 33 | ||
| 34 | s32_le nvmap_fd{}; | 34 | s32_le nvmap_fd{}; |
| 35 | 35 | ||
| 36 | NvResult SetNVMAPfd(std::span<const u8> input, std::span<u8> output); | 36 | NvResult SetNVMAPfd(IoctlSetNvmapFD& params); |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | } // namespace Service::Nvidia::Devices | 39 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index c0b8684c3..87f8d7c22 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 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/hle/service/nvdrv/core/container.h" | 7 | #include "core/hle/service/nvdrv/core/container.h" |
| 8 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 8 | #include "core/hle/service/nvdrv/devices/nvhost_vic.h" | 9 | #include "core/hle/service/nvdrv/devices/nvhost_vic.h" |
| 9 | #include "video_core/renderer_base.h" | 10 | #include "video_core/renderer_base.h" |
| 10 | 11 | ||
| @@ -25,16 +26,16 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 25 | if (!host1x_file.fd_to_id.contains(fd)) { | 26 | if (!host1x_file.fd_to_id.contains(fd)) { |
| 26 | host1x_file.fd_to_id[fd] = host1x_file.vic_next_id++; | 27 | host1x_file.fd_to_id[fd] = host1x_file.vic_next_id++; |
| 27 | } | 28 | } |
| 28 | return Submit(fd, input, output); | 29 | return WrapFixedVariable(this, &nvhost_vic::Submit, input, output, fd); |
| 29 | } | 30 | } |
| 30 | case 0x2: | 31 | case 0x2: |
| 31 | return GetSyncpoint(input, output); | 32 | return WrapFixed(this, &nvhost_vic::GetSyncpoint, input, output); |
| 32 | case 0x3: | 33 | case 0x3: |
| 33 | return GetWaitbase(input, output); | 34 | return WrapFixed(this, &nvhost_vic::GetWaitbase, input, output); |
| 34 | case 0x9: | 35 | case 0x9: |
| 35 | return MapBuffer(input, output); | 36 | return WrapFixedVariable(this, &nvhost_vic::MapBuffer, input, output); |
| 36 | case 0xa: | 37 | case 0xa: |
| 37 | return UnmapBuffer(input, output); | 38 | return WrapFixedVariable(this, &nvhost_vic::UnmapBuffer, input, output); |
| 38 | default: | 39 | default: |
| 39 | break; | 40 | break; |
| 40 | } | 41 | } |
| @@ -42,7 +43,7 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 42 | case 'H': | 43 | case 'H': |
| 43 | switch (command.cmd) { | 44 | switch (command.cmd) { |
| 44 | case 0x1: | 45 | case 0x1: |
| 45 | return SetNVMAPfd(input); | 46 | return WrapFixed(this, &nvhost_vic::SetNVMAPfd, input, output); |
| 46 | default: | 47 | default: |
| 47 | break; | 48 | break; |
| 48 | } | 49 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 968eaa175..71b2e62ec 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "core/hle/kernel/k_process.h" | 13 | #include "core/hle/kernel/k_process.h" |
| 14 | #include "core/hle/service/nvdrv/core/container.h" | 14 | #include "core/hle/service/nvdrv/core/container.h" |
| 15 | #include "core/hle/service/nvdrv/core/nvmap.h" | 15 | #include "core/hle/service/nvdrv/core/nvmap.h" |
| 16 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 16 | #include "core/hle/service/nvdrv/devices/nvmap.h" | 17 | #include "core/hle/service/nvdrv/devices/nvmap.h" |
| 17 | #include "core/memory.h" | 18 | #include "core/memory.h" |
| 18 | 19 | ||
| @@ -31,17 +32,17 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | |||
| 31 | case 0x1: | 32 | case 0x1: |
| 32 | switch (command.cmd) { | 33 | switch (command.cmd) { |
| 33 | case 0x1: | 34 | case 0x1: |
| 34 | return IocCreate(input, output); | 35 | return WrapFixed(this, &nvmap::IocCreate, input, output); |
| 35 | case 0x3: | 36 | case 0x3: |
| 36 | return IocFromId(input, output); | 37 | return WrapFixed(this, &nvmap::IocFromId, input, output); |
| 37 | case 0x4: | 38 | case 0x4: |
| 38 | return IocAlloc(input, output); | 39 | return WrapFixed(this, &nvmap::IocAlloc, input, output); |
| 39 | case 0x5: | 40 | case 0x5: |
| 40 | return IocFree(input, output); | 41 | return WrapFixed(this, &nvmap::IocFree, input, output); |
| 41 | case 0x9: | 42 | case 0x9: |
| 42 | return IocParam(input, output); | 43 | return WrapFixed(this, &nvmap::IocParam, input, output); |
| 43 | case 0xe: | 44 | case 0xe: |
| 44 | return IocGetId(input, output); | 45 | return WrapFixed(this, &nvmap::IocGetId, input, output); |
| 45 | default: | 46 | default: |
| 46 | break; | 47 | break; |
| 47 | } | 48 | } |
| @@ -69,9 +70,7 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, st | |||
| 69 | void nvmap::OnOpen(DeviceFD fd) {} | 70 | void nvmap::OnOpen(DeviceFD fd) {} |
| 70 | void nvmap::OnClose(DeviceFD fd) {} | 71 | void nvmap::OnClose(DeviceFD fd) {} |
| 71 | 72 | ||
| 72 | NvResult nvmap::IocCreate(std::span<const u8> input, std::span<u8> output) { | 73 | NvResult nvmap::IocCreate(IocCreateParams& params) { |
| 73 | IocCreateParams params; | ||
| 74 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 75 | LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); | 74 | LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); |
| 76 | 75 | ||
| 77 | std::shared_ptr<NvCore::NvMap::Handle> handle_description{}; | 76 | std::shared_ptr<NvCore::NvMap::Handle> handle_description{}; |
| @@ -85,13 +84,10 @@ NvResult nvmap::IocCreate(std::span<const u8> input, std::span<u8> output) { | |||
| 85 | params.handle = handle_description->id; | 84 | params.handle = handle_description->id; |
| 86 | LOG_DEBUG(Service_NVDRV, "handle: {}, size: 0x{:X}", handle_description->id, params.size); | 85 | LOG_DEBUG(Service_NVDRV, "handle: {}, size: 0x{:X}", handle_description->id, params.size); |
| 87 | 86 | ||
| 88 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 89 | return NvResult::Success; | 87 | return NvResult::Success; |
| 90 | } | 88 | } |
| 91 | 89 | ||
| 92 | NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) { | 90 | NvResult nvmap::IocAlloc(IocAllocParams& params) { |
| 93 | IocAllocParams params; | ||
| 94 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 95 | LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); | 91 | LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); |
| 96 | 92 | ||
| 97 | if (!params.handle) { | 93 | if (!params.handle) { |
| @@ -133,14 +129,10 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) { | |||
| 133 | handle_description->size, | 129 | handle_description->size, |
| 134 | Kernel::KMemoryPermission::None, true, false) | 130 | Kernel::KMemoryPermission::None, true, false) |
| 135 | .IsSuccess()); | 131 | .IsSuccess()); |
| 136 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 137 | return result; | 132 | return result; |
| 138 | } | 133 | } |
| 139 | 134 | ||
| 140 | NvResult nvmap::IocGetId(std::span<const u8> input, std::span<u8> output) { | 135 | NvResult nvmap::IocGetId(IocGetIdParams& params) { |
| 141 | IocGetIdParams params; | ||
| 142 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 143 | |||
| 144 | LOG_DEBUG(Service_NVDRV, "called"); | 136 | LOG_DEBUG(Service_NVDRV, "called"); |
| 145 | 137 | ||
| 146 | // See the comment in FromId for extra info on this function | 138 | // See the comment in FromId for extra info on this function |
| @@ -157,14 +149,10 @@ NvResult nvmap::IocGetId(std::span<const u8> input, std::span<u8> output) { | |||
| 157 | } | 149 | } |
| 158 | 150 | ||
| 159 | params.id = handle_description->id; | 151 | params.id = handle_description->id; |
| 160 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 161 | return NvResult::Success; | 152 | return NvResult::Success; |
| 162 | } | 153 | } |
| 163 | 154 | ||
| 164 | NvResult nvmap::IocFromId(std::span<const u8> input, std::span<u8> output) { | 155 | NvResult nvmap::IocFromId(IocFromIdParams& params) { |
| 165 | IocFromIdParams params; | ||
| 166 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 167 | |||
| 168 | LOG_DEBUG(Service_NVDRV, "called, id:{}", params.id); | 156 | LOG_DEBUG(Service_NVDRV, "called, id:{}", params.id); |
| 169 | 157 | ||
| 170 | // Handles and IDs are always the same value in nvmap however IDs can be used globally given the | 158 | // Handles and IDs are always the same value in nvmap however IDs can be used globally given the |
| @@ -188,16 +176,12 @@ NvResult nvmap::IocFromId(std::span<const u8> input, std::span<u8> output) { | |||
| 188 | return result; | 176 | return result; |
| 189 | } | 177 | } |
| 190 | params.handle = handle_description->id; | 178 | params.handle = handle_description->id; |
| 191 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 192 | return NvResult::Success; | 179 | return NvResult::Success; |
| 193 | } | 180 | } |
| 194 | 181 | ||
| 195 | NvResult nvmap::IocParam(std::span<const u8> input, std::span<u8> output) { | 182 | NvResult nvmap::IocParam(IocParamParams& params) { |
| 196 | enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; | 183 | enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; |
| 197 | 184 | ||
| 198 | IocParamParams params; | ||
| 199 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 200 | |||
| 201 | LOG_DEBUG(Service_NVDRV, "called type={}", params.param); | 185 | LOG_DEBUG(Service_NVDRV, "called type={}", params.param); |
| 202 | 186 | ||
| 203 | if (!params.handle) { | 187 | if (!params.handle) { |
| @@ -237,14 +221,10 @@ NvResult nvmap::IocParam(std::span<const u8> input, std::span<u8> output) { | |||
| 237 | return NvResult::BadValue; | 221 | return NvResult::BadValue; |
| 238 | } | 222 | } |
| 239 | 223 | ||
| 240 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 241 | return NvResult::Success; | 224 | return NvResult::Success; |
| 242 | } | 225 | } |
| 243 | 226 | ||
| 244 | NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) { | 227 | NvResult nvmap::IocFree(IocFreeParams& params) { |
| 245 | IocFreeParams params; | ||
| 246 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 247 | |||
| 248 | LOG_DEBUG(Service_NVDRV, "called"); | 228 | LOG_DEBUG(Service_NVDRV, "called"); |
| 249 | 229 | ||
| 250 | if (!params.handle) { | 230 | if (!params.handle) { |
| @@ -267,7 +247,6 @@ NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) { | |||
| 267 | // This is possible when there's internal dups or other duplicates. | 247 | // This is possible when there's internal dups or other duplicates. |
| 268 | } | 248 | } |
| 269 | 249 | ||
| 270 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 271 | return NvResult::Success; | 250 | return NvResult::Success; |
| 272 | } | 251 | } |
| 273 | 252 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index 4c0cc71cd..049c11028 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -99,12 +99,12 @@ public: | |||
| 99 | }; | 99 | }; |
| 100 | static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); | 100 | static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); |
| 101 | 101 | ||
| 102 | NvResult IocCreate(std::span<const u8> input, std::span<u8> output); | 102 | NvResult IocCreate(IocCreateParams& params); |
| 103 | NvResult IocAlloc(std::span<const u8> input, std::span<u8> output); | 103 | NvResult IocAlloc(IocAllocParams& params); |
| 104 | NvResult IocGetId(std::span<const u8> input, std::span<u8> output); | 104 | NvResult IocGetId(IocGetIdParams& params); |
| 105 | NvResult IocFromId(std::span<const u8> input, std::span<u8> output); | 105 | NvResult IocFromId(IocFromIdParams& params); |
| 106 | NvResult IocParam(std::span<const u8> input, std::span<u8> output); | 106 | NvResult IocParam(IocParamParams& params); |
| 107 | NvResult IocFree(std::span<const u8> input, std::span<u8> output); | 107 | NvResult IocFree(IocFreeParams& params); |
| 108 | 108 | ||
| 109 | private: | 109 | private: |
| 110 | /// Id to use for the next handle that is created. | 110 | /// Id to use for the next handle that is created. |
diff --git a/src/core/hle/service/nvnflinger/buffer_item.h b/src/core/hle/service/nvnflinger/buffer_item.h index 3da8cc3aa..7fd808f54 100644 --- a/src/core/hle/service/nvnflinger/buffer_item.h +++ b/src/core/hle/service/nvnflinger/buffer_item.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | namespace Service::android { | 16 | namespace Service::android { |
| 17 | 17 | ||
| 18 | struct GraphicBuffer; | 18 | class GraphicBuffer; |
| 19 | 19 | ||
| 20 | class BufferItem final { | 20 | class BufferItem final { |
| 21 | public: | 21 | public: |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp index 51291539d..d91886bed 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | // https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp | 5 | // https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp |
| 6 | 6 | ||
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/hle/service/nvdrv/core/nvmap.h" | ||
| 9 | #include "core/hle/service/nvnflinger/buffer_item.h" | 8 | #include "core/hle/service/nvnflinger/buffer_item.h" |
| 10 | #include "core/hle/service/nvnflinger/buffer_queue_consumer.h" | 9 | #include "core/hle/service/nvnflinger/buffer_queue_consumer.h" |
| 11 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" | 10 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" |
| @@ -14,9 +13,8 @@ | |||
| 14 | 13 | ||
| 15 | namespace Service::android { | 14 | namespace Service::android { |
| 16 | 15 | ||
| 17 | BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_, | 16 | BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_) |
| 18 | Service::Nvidia::NvCore::NvMap& nvmap_) | 17 | : core{std::move(core_)}, slots{core->slots} {} |
| 19 | : core{std::move(core_)}, slots{core->slots}, nvmap(nvmap_) {} | ||
| 20 | 18 | ||
| 21 | BufferQueueConsumer::~BufferQueueConsumer() = default; | 19 | BufferQueueConsumer::~BufferQueueConsumer() = default; |
| 22 | 20 | ||
| @@ -136,8 +134,6 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc | |||
| 136 | 134 | ||
| 137 | slots[slot].buffer_state = BufferState::Free; | 135 | slots[slot].buffer_state = BufferState::Free; |
| 138 | 136 | ||
| 139 | nvmap.FreeHandle(slots[slot].graphic_buffer->BufferId(), true); | ||
| 140 | |||
| 141 | listener = core->connected_producer_listener; | 137 | listener = core->connected_producer_listener; |
| 142 | 138 | ||
| 143 | LOG_DEBUG(Service_Nvnflinger, "releasing slot {}", slot); | 139 | LOG_DEBUG(Service_Nvnflinger, "releasing slot {}", slot); |
| @@ -175,6 +171,25 @@ Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_ | |||
| 175 | return Status::NoError; | 171 | return Status::NoError; |
| 176 | } | 172 | } |
| 177 | 173 | ||
| 174 | Status BufferQueueConsumer::Disconnect() { | ||
| 175 | LOG_DEBUG(Service_Nvnflinger, "called"); | ||
| 176 | |||
| 177 | std::scoped_lock lock{core->mutex}; | ||
| 178 | |||
| 179 | if (core->consumer_listener == nullptr) { | ||
| 180 | LOG_ERROR(Service_Nvnflinger, "no consumer is connected"); | ||
| 181 | return Status::BadValue; | ||
| 182 | } | ||
| 183 | |||
| 184 | core->is_abandoned = true; | ||
| 185 | core->consumer_listener = nullptr; | ||
| 186 | core->queue.clear(); | ||
| 187 | core->FreeAllBuffersLocked(); | ||
| 188 | core->SignalDequeueCondition(); | ||
| 189 | |||
| 190 | return Status::NoError; | ||
| 191 | } | ||
| 192 | |||
| 178 | Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) { | 193 | Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) { |
| 179 | if (out_slot_mask == nullptr) { | 194 | if (out_slot_mask == nullptr) { |
| 180 | LOG_ERROR(Service_Nvnflinger, "out_slot_mask may not be nullptr"); | 195 | LOG_ERROR(Service_Nvnflinger, "out_slot_mask may not be nullptr"); |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_consumer.h b/src/core/hle/service/nvnflinger/buffer_queue_consumer.h index 50ed0bb5f..0a61e8dbd 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_consumer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.h | |||
| @@ -13,10 +13,6 @@ | |||
| 13 | #include "core/hle/service/nvnflinger/buffer_queue_defs.h" | 13 | #include "core/hle/service/nvnflinger/buffer_queue_defs.h" |
| 14 | #include "core/hle/service/nvnflinger/status.h" | 14 | #include "core/hle/service/nvnflinger/status.h" |
| 15 | 15 | ||
| 16 | namespace Service::Nvidia::NvCore { | ||
| 17 | class NvMap; | ||
| 18 | } // namespace Service::Nvidia::NvCore | ||
| 19 | |||
| 20 | namespace Service::android { | 16 | namespace Service::android { |
| 21 | 17 | ||
| 22 | class BufferItem; | 18 | class BufferItem; |
| @@ -25,19 +21,18 @@ class IConsumerListener; | |||
| 25 | 21 | ||
| 26 | class BufferQueueConsumer final { | 22 | class BufferQueueConsumer final { |
| 27 | public: | 23 | public: |
| 28 | explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_, | 24 | explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_); |
| 29 | Service::Nvidia::NvCore::NvMap& nvmap_); | ||
| 30 | ~BufferQueueConsumer(); | 25 | ~BufferQueueConsumer(); |
| 31 | 26 | ||
| 32 | Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present); | 27 | Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present); |
| 33 | Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence); | 28 | Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence); |
| 34 | Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app); | 29 | Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app); |
| 30 | Status Disconnect(); | ||
| 35 | Status GetReleasedBuffers(u64* out_slot_mask); | 31 | Status GetReleasedBuffers(u64* out_slot_mask); |
| 36 | 32 | ||
| 37 | private: | 33 | private: |
| 38 | std::shared_ptr<BufferQueueCore> core; | 34 | std::shared_ptr<BufferQueueCore> core; |
| 39 | BufferQueueDefs::SlotsType& slots; | 35 | BufferQueueDefs::SlotsType& slots; |
| 40 | Service::Nvidia::NvCore::NvMap& nvmap; | ||
| 41 | }; | 36 | }; |
| 42 | 37 | ||
| 43 | } // namespace Service::android | 38 | } // namespace Service::android |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp index ed66f6f5b..4ed5e5978 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp | |||
| @@ -14,24 +14,12 @@ BufferQueueCore::BufferQueueCore() = default; | |||
| 14 | 14 | ||
| 15 | BufferQueueCore::~BufferQueueCore() = default; | 15 | BufferQueueCore::~BufferQueueCore() = default; |
| 16 | 16 | ||
| 17 | void BufferQueueCore::NotifyShutdown() { | ||
| 18 | std::scoped_lock lock{mutex}; | ||
| 19 | |||
| 20 | is_shutting_down = true; | ||
| 21 | |||
| 22 | SignalDequeueCondition(); | ||
| 23 | } | ||
| 24 | |||
| 25 | void BufferQueueCore::SignalDequeueCondition() { | 17 | void BufferQueueCore::SignalDequeueCondition() { |
| 26 | dequeue_possible.store(true); | 18 | dequeue_possible.store(true); |
| 27 | dequeue_condition.notify_all(); | 19 | dequeue_condition.notify_all(); |
| 28 | } | 20 | } |
| 29 | 21 | ||
| 30 | bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk) { | 22 | bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk) { |
| 31 | if (is_shutting_down) { | ||
| 32 | return false; | ||
| 33 | } | ||
| 34 | |||
| 35 | dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); }); | 23 | dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); }); |
| 36 | dequeue_possible.store(false); | 24 | dequeue_possible.store(false); |
| 37 | 25 | ||
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.h b/src/core/hle/service/nvnflinger/buffer_queue_core.h index 9164f08a0..e513d183b 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_core.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_core.h | |||
| @@ -34,8 +34,6 @@ public: | |||
| 34 | BufferQueueCore(); | 34 | BufferQueueCore(); |
| 35 | ~BufferQueueCore(); | 35 | ~BufferQueueCore(); |
| 36 | 36 | ||
| 37 | void NotifyShutdown(); | ||
| 38 | |||
| 39 | private: | 37 | private: |
| 40 | void SignalDequeueCondition(); | 38 | void SignalDequeueCondition(); |
| 41 | bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk); | 39 | bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk); |
| @@ -74,7 +72,6 @@ private: | |||
| 74 | u32 transform_hint{}; | 72 | u32 transform_hint{}; |
| 75 | bool is_allocating{}; | 73 | bool is_allocating{}; |
| 76 | mutable std::condition_variable_any is_allocating_condition; | 74 | mutable std::condition_variable_any is_allocating_condition; |
| 77 | bool is_shutting_down{}; | ||
| 78 | }; | 75 | }; |
| 79 | 76 | ||
| 80 | } // namespace Service::android | 77 | } // namespace Service::android |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index 6e7a49658..5d8762d25 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/service/hle_ipc.h" | 14 | #include "core/hle/service/hle_ipc.h" |
| 15 | #include "core/hle/service/kernel_helpers.h" | 15 | #include "core/hle/service/kernel_helpers.h" |
| 16 | #include "core/hle/service/nvdrv/core/nvmap.h" | ||
| 17 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" | 16 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" |
| 18 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" | 17 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" |
| 19 | #include "core/hle/service/nvnflinger/consumer_listener.h" | 18 | #include "core/hle/service/nvnflinger/consumer_listener.h" |
| @@ -533,8 +532,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, | |||
| 533 | item.is_droppable = core->dequeue_buffer_cannot_block || async; | 532 | item.is_droppable = core->dequeue_buffer_cannot_block || async; |
| 534 | item.swap_interval = swap_interval; | 533 | item.swap_interval = swap_interval; |
| 535 | 534 | ||
| 536 | nvmap.DuplicateHandle(item.graphic_buffer->BufferId(), true); | ||
| 537 | |||
| 538 | sticky_transform = sticky_transform_; | 535 | sticky_transform = sticky_transform_; |
| 539 | 536 | ||
| 540 | if (core->queue.empty()) { | 537 | if (core->queue.empty()) { |
| @@ -744,19 +741,13 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) { | |||
| 744 | return Status::NoError; | 741 | return Status::NoError; |
| 745 | } | 742 | } |
| 746 | 743 | ||
| 747 | // HACK: We are not Android. Remove handle for items in queue, and clear queue. | ||
| 748 | // Allows synchronous destruction of nvmap handles. | ||
| 749 | for (auto& item : core->queue) { | ||
| 750 | nvmap.FreeHandle(item.graphic_buffer->BufferId(), true); | ||
| 751 | } | ||
| 752 | core->queue.clear(); | ||
| 753 | |||
| 754 | switch (api) { | 744 | switch (api) { |
| 755 | case NativeWindowApi::Egl: | 745 | case NativeWindowApi::Egl: |
| 756 | case NativeWindowApi::Cpu: | 746 | case NativeWindowApi::Cpu: |
| 757 | case NativeWindowApi::Media: | 747 | case NativeWindowApi::Media: |
| 758 | case NativeWindowApi::Camera: | 748 | case NativeWindowApi::Camera: |
| 759 | if (core->connected_api == api) { | 749 | if (core->connected_api == api) { |
| 750 | core->queue.clear(); | ||
| 760 | core->FreeAllBuffersLocked(); | 751 | core->FreeAllBuffersLocked(); |
| 761 | core->connected_producer_listener = nullptr; | 752 | core->connected_producer_listener = nullptr; |
| 762 | core->connected_api = NativeWindowApi::NoConnectedApi; | 753 | core->connected_api = NativeWindowApi::NoConnectedApi; |
| @@ -785,7 +776,7 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) { | |||
| 785 | } | 776 | } |
| 786 | 777 | ||
| 787 | Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot, | 778 | Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot, |
| 788 | const std::shared_ptr<GraphicBuffer>& buffer) { | 779 | const std::shared_ptr<NvGraphicBuffer>& buffer) { |
| 789 | LOG_DEBUG(Service_Nvnflinger, "slot {}", slot); | 780 | LOG_DEBUG(Service_Nvnflinger, "slot {}", slot); |
| 790 | 781 | ||
| 791 | if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { | 782 | if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { |
| @@ -796,7 +787,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot, | |||
| 796 | 787 | ||
| 797 | slots[slot] = {}; | 788 | slots[slot] = {}; |
| 798 | slots[slot].fence = Fence::NoFence(); | 789 | slots[slot].fence = Fence::NoFence(); |
| 799 | slots[slot].graphic_buffer = buffer; | 790 | slots[slot].graphic_buffer = std::make_shared<GraphicBuffer>(nvmap, buffer); |
| 800 | slots[slot].frame_number = 0; | 791 | slots[slot].frame_number = 0; |
| 801 | 792 | ||
| 802 | // Most games preallocate a buffer and pass a valid buffer here. However, it is possible for | 793 | // Most games preallocate a buffer and pass a valid buffer here. However, it is possible for |
| @@ -839,7 +830,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u | |||
| 839 | } | 830 | } |
| 840 | case TransactionId::SetPreallocatedBuffer: { | 831 | case TransactionId::SetPreallocatedBuffer: { |
| 841 | const auto slot = parcel_in.Read<s32>(); | 832 | const auto slot = parcel_in.Read<s32>(); |
| 842 | const auto buffer = parcel_in.ReadObject<GraphicBuffer>(); | 833 | const auto buffer = parcel_in.ReadObject<NvGraphicBuffer>(); |
| 843 | 834 | ||
| 844 | status = SetPreallocatedBuffer(slot, buffer); | 835 | status = SetPreallocatedBuffer(slot, buffer); |
| 845 | break; | 836 | break; |
| @@ -867,7 +858,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u | |||
| 867 | 858 | ||
| 868 | status = RequestBuffer(slot, &buf); | 859 | status = RequestBuffer(slot, &buf); |
| 869 | 860 | ||
| 870 | parcel_out.WriteFlattenedObject(buf); | 861 | parcel_out.WriteFlattenedObject<NvGraphicBuffer>(buf.get()); |
| 871 | break; | 862 | break; |
| 872 | } | 863 | } |
| 873 | case TransactionId::QueueBuffer: { | 864 | case TransactionId::QueueBuffer: { |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h index d4201c104..64c17d56c 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h | |||
| @@ -38,6 +38,7 @@ namespace Service::android { | |||
| 38 | 38 | ||
| 39 | class BufferQueueCore; | 39 | class BufferQueueCore; |
| 40 | class IProducerListener; | 40 | class IProducerListener; |
| 41 | struct NvGraphicBuffer; | ||
| 41 | 42 | ||
| 42 | class BufferQueueProducer final : public IBinder { | 43 | class BufferQueueProducer final : public IBinder { |
| 43 | public: | 44 | public: |
| @@ -65,7 +66,7 @@ public: | |||
| 65 | bool producer_controlled_by_app, QueueBufferOutput* output); | 66 | bool producer_controlled_by_app, QueueBufferOutput* output); |
| 66 | 67 | ||
| 67 | Status Disconnect(NativeWindowApi api); | 68 | Status Disconnect(NativeWindowApi api); |
| 68 | Status SetPreallocatedBuffer(s32 slot, const std::shared_ptr<GraphicBuffer>& buffer); | 69 | Status SetPreallocatedBuffer(s32 slot, const std::shared_ptr<NvGraphicBuffer>& buffer); |
| 69 | 70 | ||
| 70 | private: | 71 | private: |
| 71 | BufferQueueProducer(const BufferQueueProducer&) = delete; | 72 | BufferQueueProducer(const BufferQueueProducer&) = delete; |
diff --git a/src/core/hle/service/nvnflinger/buffer_slot.h b/src/core/hle/service/nvnflinger/buffer_slot.h index d8c9dec3b..d25bca049 100644 --- a/src/core/hle/service/nvnflinger/buffer_slot.h +++ b/src/core/hle/service/nvnflinger/buffer_slot.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | namespace Service::android { | 14 | namespace Service::android { |
| 15 | 15 | ||
| 16 | struct GraphicBuffer; | 16 | class GraphicBuffer; |
| 17 | 17 | ||
| 18 | enum class BufferState : u32 { | 18 | enum class BufferState : u32 { |
| 19 | Free = 0, | 19 | Free = 0, |
diff --git a/src/core/hle/service/nvnflinger/buffer_transform_flags.h b/src/core/hle/service/nvnflinger/buffer_transform_flags.h index 67aa5dad6..ffe579718 100644 --- a/src/core/hle/service/nvnflinger/buffer_transform_flags.h +++ b/src/core/hle/service/nvnflinger/buffer_transform_flags.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/common_funcs.h" | ||
| 6 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 7 | 8 | ||
| 8 | namespace Service::android { | 9 | namespace Service::android { |
| @@ -21,5 +22,6 @@ enum class BufferTransformFlags : u32 { | |||
| 21 | /// Rotate source image 270 degrees clockwise | 22 | /// Rotate source image 270 degrees clockwise |
| 22 | Rotate270 = 0x07, | 23 | Rotate270 = 0x07, |
| 23 | }; | 24 | }; |
| 25 | DECLARE_ENUM_FLAG_OPERATORS(BufferTransformFlags); | ||
| 24 | 26 | ||
| 25 | } // namespace Service::android | 27 | } // namespace Service::android |
diff --git a/src/core/hle/service/nvnflinger/consumer_base.cpp b/src/core/hle/service/nvnflinger/consumer_base.cpp index 4dcda8dac..1059e72bf 100644 --- a/src/core/hle/service/nvnflinger/consumer_base.cpp +++ b/src/core/hle/service/nvnflinger/consumer_base.cpp | |||
| @@ -27,6 +27,26 @@ void ConsumerBase::Connect(bool controlled_by_app) { | |||
| 27 | consumer->Connect(shared_from_this(), controlled_by_app); | 27 | consumer->Connect(shared_from_this(), controlled_by_app); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | void ConsumerBase::Abandon() { | ||
| 31 | LOG_DEBUG(Service_Nvnflinger, "called"); | ||
| 32 | |||
| 33 | std::scoped_lock lock{mutex}; | ||
| 34 | |||
| 35 | if (!is_abandoned) { | ||
| 36 | this->AbandonLocked(); | ||
| 37 | is_abandoned = true; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | void ConsumerBase::AbandonLocked() { | ||
| 42 | for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) { | ||
| 43 | this->FreeBufferLocked(i); | ||
| 44 | } | ||
| 45 | // disconnect from the BufferQueue | ||
| 46 | consumer->Disconnect(); | ||
| 47 | consumer = nullptr; | ||
| 48 | } | ||
| 49 | |||
| 30 | void ConsumerBase::FreeBufferLocked(s32 slot_index) { | 50 | void ConsumerBase::FreeBufferLocked(s32 slot_index) { |
| 31 | LOG_DEBUG(Service_Nvnflinger, "slot_index={}", slot_index); | 51 | LOG_DEBUG(Service_Nvnflinger, "slot_index={}", slot_index); |
| 32 | 52 | ||
diff --git a/src/core/hle/service/nvnflinger/consumer_base.h b/src/core/hle/service/nvnflinger/consumer_base.h index 264829414..ea3e9e97a 100644 --- a/src/core/hle/service/nvnflinger/consumer_base.h +++ b/src/core/hle/service/nvnflinger/consumer_base.h | |||
| @@ -24,6 +24,7 @@ class BufferQueueConsumer; | |||
| 24 | class ConsumerBase : public IConsumerListener, public std::enable_shared_from_this<ConsumerBase> { | 24 | class ConsumerBase : public IConsumerListener, public std::enable_shared_from_this<ConsumerBase> { |
| 25 | public: | 25 | public: |
| 26 | void Connect(bool controlled_by_app); | 26 | void Connect(bool controlled_by_app); |
| 27 | void Abandon(); | ||
| 27 | 28 | ||
| 28 | protected: | 29 | protected: |
| 29 | explicit ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_); | 30 | explicit ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_); |
| @@ -34,6 +35,7 @@ protected: | |||
| 34 | void OnBuffersReleased() override; | 35 | void OnBuffersReleased() override; |
| 35 | void OnSidebandStreamChanged() override; | 36 | void OnSidebandStreamChanged() override; |
| 36 | 37 | ||
| 38 | void AbandonLocked(); | ||
| 37 | void FreeBufferLocked(s32 slot_index); | 39 | void FreeBufferLocked(s32 slot_index); |
| 38 | Status AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when); | 40 | Status AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when); |
| 39 | Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer>& graphic_buffer); | 41 | Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer>& graphic_buffer); |
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp index 2e29bc848..d7db24f42 100644 --- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp +++ b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp | |||
| @@ -71,24 +71,17 @@ Result AllocateIoForProcessAddressSpace(Common::ProcessAddress* out_map_address, | |||
| 71 | R_SUCCEED(); | 71 | R_SUCCEED(); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | template <typename T> | ||
| 75 | std::span<u8> SerializeIoc(T& params) { | ||
| 76 | return std::span(reinterpret_cast<u8*>(std::addressof(params)), sizeof(T)); | ||
| 77 | } | ||
| 78 | |||
| 79 | Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, u32 size) { | 74 | Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, u32 size) { |
| 80 | // Create a handle. | 75 | // Create a handle. |
| 81 | Nvidia::Devices::nvmap::IocCreateParams create_in_params{ | 76 | Nvidia::Devices::nvmap::IocCreateParams create_params{ |
| 82 | .size = size, | 77 | .size = size, |
| 83 | .handle = 0, | 78 | .handle = 0, |
| 84 | }; | 79 | }; |
| 85 | Nvidia::Devices::nvmap::IocCreateParams create_out_params{}; | 80 | R_UNLESS(nvmap.IocCreate(create_params) == Nvidia::NvResult::Success, |
| 86 | R_UNLESS(nvmap.IocCreate(SerializeIoc(create_in_params), SerializeIoc(create_out_params)) == | ||
| 87 | Nvidia::NvResult::Success, | ||
| 88 | VI::ResultOperationFailed); | 81 | VI::ResultOperationFailed); |
| 89 | 82 | ||
| 90 | // Assign the output handle. | 83 | // Assign the output handle. |
| 91 | *out_nv_map_handle = create_out_params.handle; | 84 | *out_nv_map_handle = create_params.handle; |
| 92 | 85 | ||
| 93 | // We succeeded. | 86 | // We succeeded. |
| 94 | R_SUCCEED(); | 87 | R_SUCCEED(); |
| @@ -96,13 +89,10 @@ Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, | |||
| 96 | 89 | ||
| 97 | Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) { | 90 | Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) { |
| 98 | // Free the handle. | 91 | // Free the handle. |
| 99 | Nvidia::Devices::nvmap::IocFreeParams free_in_params{ | 92 | Nvidia::Devices::nvmap::IocFreeParams free_params{ |
| 100 | .handle = handle, | 93 | .handle = handle, |
| 101 | }; | 94 | }; |
| 102 | Nvidia::Devices::nvmap::IocFreeParams free_out_params{}; | 95 | R_UNLESS(nvmap.IocFree(free_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); |
| 103 | R_UNLESS(nvmap.IocFree(SerializeIoc(free_in_params), SerializeIoc(free_out_params)) == | ||
| 104 | Nvidia::NvResult::Success, | ||
| 105 | VI::ResultOperationFailed); | ||
| 106 | 96 | ||
| 107 | // We succeeded. | 97 | // We succeeded. |
| 108 | R_SUCCEED(); | 98 | R_SUCCEED(); |
| @@ -111,7 +101,7 @@ Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) { | |||
| 111 | Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer, | 101 | Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer, |
| 112 | u32 size) { | 102 | u32 size) { |
| 113 | // Assign the allocated memory to the handle. | 103 | // Assign the allocated memory to the handle. |
| 114 | Nvidia::Devices::nvmap::IocAllocParams alloc_in_params{ | 104 | Nvidia::Devices::nvmap::IocAllocParams alloc_params{ |
| 115 | .handle = handle, | 105 | .handle = handle, |
| 116 | .heap_mask = 0, | 106 | .heap_mask = 0, |
| 117 | .flags = {}, | 107 | .flags = {}, |
| @@ -119,10 +109,7 @@ Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::Proce | |||
| 119 | .kind = 0, | 109 | .kind = 0, |
| 120 | .address = GetInteger(buffer), | 110 | .address = GetInteger(buffer), |
| 121 | }; | 111 | }; |
| 122 | Nvidia::Devices::nvmap::IocAllocParams alloc_out_params{}; | 112 | R_UNLESS(nvmap.IocAlloc(alloc_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); |
| 123 | R_UNLESS(nvmap.IocAlloc(SerializeIoc(alloc_in_params), SerializeIoc(alloc_out_params)) == | ||
| 124 | Nvidia::NvResult::Success, | ||
| 125 | VI::ResultOperationFailed); | ||
| 126 | 113 | ||
| 127 | // We succeeded. | 114 | // We succeeded. |
| 128 | R_SUCCEED(); | 115 | R_SUCCEED(); |
| @@ -179,7 +166,7 @@ constexpr SharedMemoryPoolLayout SharedBufferPoolLayout = [] { | |||
| 179 | }(); | 166 | }(); |
| 180 | 167 | ||
| 181 | void MakeGraphicBuffer(android::BufferQueueProducer& producer, u32 slot, u32 handle) { | 168 | void MakeGraphicBuffer(android::BufferQueueProducer& producer, u32 slot, u32 handle) { |
| 182 | auto buffer = std::make_shared<android::GraphicBuffer>(); | 169 | auto buffer = std::make_shared<android::NvGraphicBuffer>(); |
| 183 | buffer->width = SharedBufferWidth; | 170 | buffer->width = SharedBufferWidth; |
| 184 | buffer->height = SharedBufferHeight; | 171 | buffer->height = SharedBufferHeight; |
| 185 | buffer->stride = SharedBufferBlockLinearStride; | 172 | buffer->stride = SharedBufferBlockLinearStride; |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp index bebb45eae..0745434c5 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.cpp +++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp | |||
| @@ -47,7 +47,10 @@ void Nvnflinger::SplitVSync(std::stop_token stop_token) { | |||
| 47 | vsync_signal.Wait(); | 47 | vsync_signal.Wait(); |
| 48 | 48 | ||
| 49 | const auto lock_guard = Lock(); | 49 | const auto lock_guard = Lock(); |
| 50 | Compose(); | 50 | |
| 51 | if (!is_abandoned) { | ||
| 52 | Compose(); | ||
| 53 | } | ||
| 51 | } | 54 | } |
| 52 | } | 55 | } |
| 53 | 56 | ||
| @@ -98,7 +101,6 @@ Nvnflinger::~Nvnflinger() { | |||
| 98 | } | 101 | } |
| 99 | 102 | ||
| 100 | ShutdownLayers(); | 103 | ShutdownLayers(); |
| 101 | vsync_thread = {}; | ||
| 102 | 104 | ||
| 103 | if (nvdrv) { | 105 | if (nvdrv) { |
| 104 | nvdrv->Close(disp_fd); | 106 | nvdrv->Close(disp_fd); |
| @@ -106,12 +108,20 @@ Nvnflinger::~Nvnflinger() { | |||
| 106 | } | 108 | } |
| 107 | 109 | ||
| 108 | void Nvnflinger::ShutdownLayers() { | 110 | void Nvnflinger::ShutdownLayers() { |
| 109 | const auto lock_guard = Lock(); | 111 | // Abandon consumers. |
| 110 | for (auto& display : displays) { | 112 | { |
| 111 | for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) { | 113 | const auto lock_guard = Lock(); |
| 112 | display.GetLayer(layer).Core().NotifyShutdown(); | 114 | for (auto& display : displays) { |
| 115 | for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) { | ||
| 116 | display.GetLayer(layer).GetConsumer().Abandon(); | ||
| 117 | } | ||
| 113 | } | 118 | } |
| 119 | |||
| 120 | is_abandoned = true; | ||
| 114 | } | 121 | } |
| 122 | |||
| 123 | // Join the vsync thread, if it exists. | ||
| 124 | vsync_thread = {}; | ||
| 115 | } | 125 | } |
| 116 | 126 | ||
| 117 | void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { | 127 | void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h index 959d8b46b..f5d73acdb 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.h +++ b/src/core/hle/service/nvnflinger/nvnflinger.h | |||
| @@ -140,6 +140,8 @@ private: | |||
| 140 | 140 | ||
| 141 | s32 swap_interval = 1; | 141 | s32 swap_interval = 1; |
| 142 | 142 | ||
| 143 | bool is_abandoned = false; | ||
| 144 | |||
| 143 | /// Event that handles screen composition. | 145 | /// Event that handles screen composition. |
| 144 | std::shared_ptr<Core::Timing::EventType> multi_composition_event; | 146 | std::shared_ptr<Core::Timing::EventType> multi_composition_event; |
| 145 | std::shared_ptr<Core::Timing::EventType> single_composition_event; | 147 | std::shared_ptr<Core::Timing::EventType> single_composition_event; |
diff --git a/src/core/hle/service/nvnflinger/status.h b/src/core/hle/service/nvnflinger/status.h index 7af166c40..3fa0fe15b 100644 --- a/src/core/hle/service/nvnflinger/status.h +++ b/src/core/hle/service/nvnflinger/status.h | |||
| @@ -19,7 +19,7 @@ enum class Status : s32 { | |||
| 19 | Busy = -16, | 19 | Busy = -16, |
| 20 | NoInit = -19, | 20 | NoInit = -19, |
| 21 | BadValue = -22, | 21 | BadValue = -22, |
| 22 | InvalidOperation = -37, | 22 | InvalidOperation = -38, |
| 23 | BufferNeedsReallocation = 1, | 23 | BufferNeedsReallocation = 1, |
| 24 | ReleaseAllBuffers = 2, | 24 | ReleaseAllBuffers = 2, |
| 25 | }; | 25 | }; |
diff --git a/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp b/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp new file mode 100644 index 000000000..ce70946ec --- /dev/null +++ b/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/nvdrv/core/nvmap.h" | ||
| 5 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" | ||
| 6 | |||
| 7 | namespace Service::android { | ||
| 8 | |||
| 9 | static NvGraphicBuffer GetBuffer(std::shared_ptr<NvGraphicBuffer>& buffer) { | ||
| 10 | if (buffer) { | ||
| 11 | return *buffer; | ||
| 12 | } else { | ||
| 13 | return {}; | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | GraphicBuffer::GraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_) | ||
| 18 | : NvGraphicBuffer(width_, height_, format_, usage_), m_nvmap(nullptr) {} | ||
| 19 | |||
| 20 | GraphicBuffer::GraphicBuffer(Service::Nvidia::NvCore::NvMap& nvmap, | ||
| 21 | std::shared_ptr<NvGraphicBuffer> buffer) | ||
| 22 | : NvGraphicBuffer(GetBuffer(buffer)), m_nvmap(std::addressof(nvmap)) { | ||
| 23 | if (this->BufferId() > 0) { | ||
| 24 | m_nvmap->DuplicateHandle(this->BufferId(), true); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | GraphicBuffer::~GraphicBuffer() { | ||
| 29 | if (m_nvmap != nullptr && this->BufferId() > 0) { | ||
| 30 | m_nvmap->FreeHandle(this->BufferId(), true); | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | } // namespace Service::android | ||
diff --git a/src/core/hle/service/nvnflinger/ui/graphic_buffer.h b/src/core/hle/service/nvnflinger/ui/graphic_buffer.h index 3eac5cedd..da430aa75 100644 --- a/src/core/hle/service/nvnflinger/ui/graphic_buffer.h +++ b/src/core/hle/service/nvnflinger/ui/graphic_buffer.h | |||
| @@ -6,16 +6,22 @@ | |||
| 6 | 6 | ||
| 7 | #pragma once | 7 | #pragma once |
| 8 | 8 | ||
| 9 | #include <memory> | ||
| 10 | |||
| 9 | #include "common/common_funcs.h" | 11 | #include "common/common_funcs.h" |
| 10 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 11 | #include "core/hle/service/nvnflinger/pixel_format.h" | 13 | #include "core/hle/service/nvnflinger/pixel_format.h" |
| 12 | 14 | ||
| 15 | namespace Service::Nvidia::NvCore { | ||
| 16 | class NvMap; | ||
| 17 | } // namespace Service::Nvidia::NvCore | ||
| 18 | |||
| 13 | namespace Service::android { | 19 | namespace Service::android { |
| 14 | 20 | ||
| 15 | struct GraphicBuffer final { | 21 | struct NvGraphicBuffer { |
| 16 | constexpr GraphicBuffer() = default; | 22 | constexpr NvGraphicBuffer() = default; |
| 17 | 23 | ||
| 18 | constexpr GraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_) | 24 | constexpr NvGraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_) |
| 19 | : width{static_cast<s32>(width_)}, height{static_cast<s32>(height_)}, format{format_}, | 25 | : width{static_cast<s32>(width_)}, height{static_cast<s32>(height_)}, format{format_}, |
| 20 | usage{static_cast<s32>(usage_)} {} | 26 | usage{static_cast<s32>(usage_)} {} |
| 21 | 27 | ||
| @@ -93,6 +99,17 @@ struct GraphicBuffer final { | |||
| 93 | u32 offset{}; | 99 | u32 offset{}; |
| 94 | INSERT_PADDING_WORDS(60); | 100 | INSERT_PADDING_WORDS(60); |
| 95 | }; | 101 | }; |
| 96 | static_assert(sizeof(GraphicBuffer) == 0x16C, "GraphicBuffer has wrong size"); | 102 | static_assert(sizeof(NvGraphicBuffer) == 0x16C, "NvGraphicBuffer has wrong size"); |
| 103 | |||
| 104 | class GraphicBuffer final : public NvGraphicBuffer { | ||
| 105 | public: | ||
| 106 | explicit GraphicBuffer(u32 width, u32 height, PixelFormat format, u32 usage); | ||
| 107 | explicit GraphicBuffer(Service::Nvidia::NvCore::NvMap& nvmap, | ||
| 108 | std::shared_ptr<NvGraphicBuffer> buffer); | ||
| 109 | ~GraphicBuffer(); | ||
| 110 | |||
| 111 | private: | ||
| 112 | Service::Nvidia::NvCore::NvMap* m_nvmap{}; | ||
| 113 | }; | ||
| 97 | 114 | ||
| 98 | } // namespace Service::android | 115 | } // namespace Service::android |
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index ec3af80af..f5edfdc8b 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp | |||
| @@ -19,19 +19,8 @@ | |||
| 19 | 19 | ||
| 20 | namespace Service::Set { | 20 | namespace Service::Set { |
| 21 | 21 | ||
| 22 | namespace { | 22 | Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system, |
| 23 | constexpr u64 SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET = 0x05; | 23 | GetFirmwareVersionType type) { |
| 24 | |||
| 25 | enum class GetFirmwareVersionType { | ||
| 26 | Version1, | ||
| 27 | Version2, | ||
| 28 | }; | ||
| 29 | |||
| 30 | void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx, | ||
| 31 | GetFirmwareVersionType type) { | ||
| 32 | ASSERT_MSG(ctx.GetWriteBufferSize() == 0x100, | ||
| 33 | "FirmwareVersion output buffer must be 0x100 bytes in size!"); | ||
| 34 | |||
| 35 | constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809; | 24 | constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809; |
| 36 | auto& fsc = system.GetFileSystemController(); | 25 | auto& fsc = system.GetFileSystemController(); |
| 37 | 26 | ||
| @@ -52,39 +41,34 @@ void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx, | |||
| 52 | FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId)); | 41 | FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId)); |
| 53 | } | 42 | } |
| 54 | 43 | ||
| 55 | const auto early_exit_failure = [&ctx](std::string_view desc, Result code) { | 44 | const auto early_exit_failure = [](std::string_view desc, Result code) { |
| 56 | LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", | 45 | LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", |
| 57 | desc); | 46 | desc); |
| 58 | IPC::ResponseBuilder rb{ctx, 2}; | 47 | return code; |
| 59 | rb.Push(code); | ||
| 60 | }; | 48 | }; |
| 61 | 49 | ||
| 62 | const auto ver_file = romfs->GetFile("file"); | 50 | const auto ver_file = romfs->GetFile("file"); |
| 63 | if (ver_file == nullptr) { | 51 | if (ver_file == nullptr) { |
| 64 | early_exit_failure("The system version archive didn't contain the file 'file'.", | 52 | return early_exit_failure("The system version archive didn't contain the file 'file'.", |
| 65 | FileSys::ERROR_INVALID_ARGUMENT); | 53 | FileSys::ERROR_INVALID_ARGUMENT); |
| 66 | return; | ||
| 67 | } | 54 | } |
| 68 | 55 | ||
| 69 | auto data = ver_file->ReadAllBytes(); | 56 | auto data = ver_file->ReadAllBytes(); |
| 70 | if (data.size() != 0x100) { | 57 | if (data.size() != sizeof(FirmwareVersionFormat)) { |
| 71 | early_exit_failure("The system version file 'file' was not the correct size.", | 58 | return early_exit_failure("The system version file 'file' was not the correct size.", |
| 72 | FileSys::ERROR_OUT_OF_BOUNDS); | 59 | FileSys::ERROR_OUT_OF_BOUNDS); |
| 73 | return; | ||
| 74 | } | 60 | } |
| 75 | 61 | ||
| 62 | std::memcpy(&out_firmware, data.data(), sizeof(FirmwareVersionFormat)); | ||
| 63 | |||
| 76 | // If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will | 64 | // If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will |
| 77 | // zero out the REVISION_MINOR field. | 65 | // zero out the REVISION_MINOR field. |
| 78 | if (type == GetFirmwareVersionType::Version1) { | 66 | if (type == GetFirmwareVersionType::Version1) { |
| 79 | data[SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET] = 0; | 67 | out_firmware.revision_minor = 0; |
| 80 | } | 68 | } |
| 81 | 69 | ||
| 82 | ctx.WriteBuffer(data); | 70 | return ResultSuccess; |
| 83 | |||
| 84 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 85 | rb.Push(ResultSuccess); | ||
| 86 | } | 71 | } |
| 87 | } // Anonymous namespace | ||
| 88 | 72 | ||
| 89 | void SET_SYS::SetLanguageCode(HLERequestContext& ctx) { | 73 | void SET_SYS::SetLanguageCode(HLERequestContext& ctx) { |
| 90 | IPC::RequestParser rp{ctx}; | 74 | IPC::RequestParser rp{ctx}; |
| @@ -98,12 +82,32 @@ void SET_SYS::SetLanguageCode(HLERequestContext& ctx) { | |||
| 98 | 82 | ||
| 99 | void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) { | 83 | void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) { |
| 100 | LOG_DEBUG(Service_SET, "called"); | 84 | LOG_DEBUG(Service_SET, "called"); |
| 101 | GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version1); | 85 | |
| 86 | FirmwareVersionFormat firmware_data{}; | ||
| 87 | const auto result = | ||
| 88 | GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version1); | ||
| 89 | |||
| 90 | if (result.IsSuccess()) { | ||
| 91 | ctx.WriteBuffer(firmware_data); | ||
| 92 | } | ||
| 93 | |||
| 94 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 95 | rb.Push(result); | ||
| 102 | } | 96 | } |
| 103 | 97 | ||
| 104 | void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) { | 98 | void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) { |
| 105 | LOG_DEBUG(Service_SET, "called"); | 99 | LOG_DEBUG(Service_SET, "called"); |
| 106 | GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version2); | 100 | |
| 101 | FirmwareVersionFormat firmware_data{}; | ||
| 102 | const auto result = | ||
| 103 | GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version2); | ||
| 104 | |||
| 105 | if (result.IsSuccess()) { | ||
| 106 | ctx.WriteBuffer(firmware_data); | ||
| 107 | } | ||
| 108 | |||
| 109 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 110 | rb.Push(result); | ||
| 107 | } | 111 | } |
| 108 | 112 | ||
| 109 | void SET_SYS::GetAccountSettings(HLERequestContext& ctx) { | 113 | void SET_SYS::GetAccountSettings(HLERequestContext& ctx) { |
| @@ -431,8 +435,7 @@ void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { | |||
| 431 | void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) { | 435 | void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) { |
| 432 | u8 battery_percentage_flag{1}; | 436 | u8 battery_percentage_flag{1}; |
| 433 | 437 | ||
| 434 | LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}", | 438 | LOG_DEBUG(Service_SET, "(STUBBED) called, battery_percentage_flag={}", battery_percentage_flag); |
| 435 | battery_percentage_flag); | ||
| 436 | 439 | ||
| 437 | IPC::ResponseBuilder rb{ctx, 3}; | 440 | IPC::ResponseBuilder rb{ctx, 3}; |
| 438 | rb.Push(ResultSuccess); | 441 | rb.Push(ResultSuccess); |
| @@ -492,6 +495,29 @@ void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) { | |||
| 492 | rb.PushEnum(ChineseTraditionalInputMethod::Unknown0); | 495 | rb.PushEnum(ChineseTraditionalInputMethod::Unknown0); |
| 493 | } | 496 | } |
| 494 | 497 | ||
| 498 | void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) { | ||
| 499 | LOG_DEBUG(Service_SET, "(STUBBED) called"); | ||
| 500 | |||
| 501 | const HomeMenuScheme default_color = { | ||
| 502 | .main = 0xFF323232, | ||
| 503 | .back = 0xFF323232, | ||
| 504 | .sub = 0xFFFFFFFF, | ||
| 505 | .bezel = 0xFFFFFFFF, | ||
| 506 | .extra = 0xFF000000, | ||
| 507 | }; | ||
| 508 | |||
| 509 | IPC::ResponseBuilder rb{ctx, 7}; | ||
| 510 | rb.Push(ResultSuccess); | ||
| 511 | rb.PushRaw(default_color); | ||
| 512 | } | ||
| 513 | |||
| 514 | void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) { | ||
| 515 | LOG_WARNING(Service_SET, "(STUBBED) called"); | ||
| 516 | |||
| 517 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 518 | rb.Push(ResultSuccess); | ||
| 519 | rb.Push(0); | ||
| 520 | } | ||
| 495 | void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) { | 521 | void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) { |
| 496 | LOG_WARNING(Service_SET, "(STUBBED) called"); | 522 | LOG_WARNING(Service_SET, "(STUBBED) called"); |
| 497 | 523 | ||
| @@ -674,7 +700,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||
| 674 | {171, nullptr, "SetChineseTraditionalInputMethod"}, | 700 | {171, nullptr, "SetChineseTraditionalInputMethod"}, |
| 675 | {172, nullptr, "GetPtmCycleCountReliability"}, | 701 | {172, nullptr, "GetPtmCycleCountReliability"}, |
| 676 | {173, nullptr, "SetPtmCycleCountReliability"}, | 702 | {173, nullptr, "SetPtmCycleCountReliability"}, |
| 677 | {174, nullptr, "GetHomeMenuScheme"}, | 703 | {174, &SET_SYS::GetHomeMenuScheme, "GetHomeMenuScheme"}, |
| 678 | {175, nullptr, "GetThemeSettings"}, | 704 | {175, nullptr, "GetThemeSettings"}, |
| 679 | {176, nullptr, "SetThemeSettings"}, | 705 | {176, nullptr, "SetThemeSettings"}, |
| 680 | {177, nullptr, "GetThemeKey"}, | 706 | {177, nullptr, "GetThemeKey"}, |
| @@ -685,7 +711,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||
| 685 | {182, nullptr, "SetT"}, | 711 | {182, nullptr, "SetT"}, |
| 686 | {183, nullptr, "GetPlatformRegion"}, | 712 | {183, nullptr, "GetPlatformRegion"}, |
| 687 | {184, nullptr, "SetPlatformRegion"}, | 713 | {184, nullptr, "SetPlatformRegion"}, |
| 688 | {185, nullptr, "GetHomeMenuSchemeModel"}, | 714 | {185, &SET_SYS::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"}, |
| 689 | {186, nullptr, "GetMemoryUsageRateFlag"}, | 715 | {186, nullptr, "GetMemoryUsageRateFlag"}, |
| 690 | {187, nullptr, "GetTouchScreenMode"}, | 716 | {187, nullptr, "GetTouchScreenMode"}, |
| 691 | {188, nullptr, "SetTouchScreenMode"}, | 717 | {188, nullptr, "SetTouchScreenMode"}, |
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h index c7dba2a9e..5f770fd32 100644 --- a/src/core/hle/service/set/set_sys.h +++ b/src/core/hle/service/set/set_sys.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/uuid.h" | 6 | #include "common/uuid.h" |
| 7 | #include "core/hle/result.h" | ||
| 7 | #include "core/hle/service/service.h" | 8 | #include "core/hle/service/service.h" |
| 8 | #include "core/hle/service/time/clock_types.h" | 9 | #include "core/hle/service/time/clock_types.h" |
| 9 | 10 | ||
| @@ -12,6 +13,29 @@ class System; | |||
| 12 | } | 13 | } |
| 13 | 14 | ||
| 14 | namespace Service::Set { | 15 | namespace Service::Set { |
| 16 | enum class LanguageCode : u64; | ||
| 17 | enum class GetFirmwareVersionType { | ||
| 18 | Version1, | ||
| 19 | Version2, | ||
| 20 | }; | ||
| 21 | |||
| 22 | struct FirmwareVersionFormat { | ||
| 23 | u8 major; | ||
| 24 | u8 minor; | ||
| 25 | u8 micro; | ||
| 26 | INSERT_PADDING_BYTES(1); | ||
| 27 | u8 revision_major; | ||
| 28 | u8 revision_minor; | ||
| 29 | INSERT_PADDING_BYTES(2); | ||
| 30 | std::array<char, 0x20> platform; | ||
| 31 | std::array<u8, 0x40> version_hash; | ||
| 32 | std::array<char, 0x18> display_version; | ||
| 33 | std::array<char, 0x80> display_title; | ||
| 34 | }; | ||
| 35 | static_assert(sizeof(FirmwareVersionFormat) == 0x100, "FirmwareVersionFormat is an invalid size"); | ||
| 36 | |||
| 37 | Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system, | ||
| 38 | GetFirmwareVersionType type); | ||
| 15 | 39 | ||
| 16 | class SET_SYS final : public ServiceFramework<SET_SYS> { | 40 | class SET_SYS final : public ServiceFramework<SET_SYS> { |
| 17 | public: | 41 | public: |
| @@ -269,6 +293,16 @@ private: | |||
| 269 | }; | 293 | }; |
| 270 | static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); | 294 | static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); |
| 271 | 295 | ||
| 296 | /// This is nn::settings::system::HomeMenuScheme | ||
| 297 | struct HomeMenuScheme { | ||
| 298 | u32 main; | ||
| 299 | u32 back; | ||
| 300 | u32 sub; | ||
| 301 | u32 bezel; | ||
| 302 | u32 extra; | ||
| 303 | }; | ||
| 304 | static_assert(sizeof(HomeMenuScheme) == 0x14, "HomeMenuScheme is incorrect size"); | ||
| 305 | |||
| 272 | void SetLanguageCode(HLERequestContext& ctx); | 306 | void SetLanguageCode(HLERequestContext& ctx); |
| 273 | void GetFirmwareVersion(HLERequestContext& ctx); | 307 | void GetFirmwareVersion(HLERequestContext& ctx); |
| 274 | void GetFirmwareVersion2(HLERequestContext& ctx); | 308 | void GetFirmwareVersion2(HLERequestContext& ctx); |
| @@ -305,6 +339,8 @@ private: | |||
| 305 | void GetKeyboardLayout(HLERequestContext& ctx); | 339 | void GetKeyboardLayout(HLERequestContext& ctx); |
| 306 | void GetChineseTraditionalInputMethod(HLERequestContext& ctx); | 340 | void GetChineseTraditionalInputMethod(HLERequestContext& ctx); |
| 307 | void GetFieldTestingFlag(HLERequestContext& ctx); | 341 | void GetFieldTestingFlag(HLERequestContext& ctx); |
| 342 | void GetHomeMenuScheme(HLERequestContext& ctx); | ||
| 343 | void GetHomeMenuSchemeModel(HLERequestContext& ctx); | ||
| 308 | 344 | ||
| 309 | AccountSettings account_settings{ | 345 | AccountSettings account_settings{ |
| 310 | .flags = {}, | 346 | .flags = {}, |
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 85849d5f3..dd652ca42 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp | |||
| @@ -39,6 +39,18 @@ bool IsConnectionBased(Type type) { | |||
| 39 | } | 39 | } |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | template <typename T> | ||
| 43 | T GetValue(std::span<const u8> buffer) { | ||
| 44 | T t{}; | ||
| 45 | std::memcpy(&t, buffer.data(), std::min(sizeof(T), buffer.size())); | ||
| 46 | return t; | ||
| 47 | } | ||
| 48 | |||
| 49 | template <typename T> | ||
| 50 | void PutValue(std::span<u8> buffer, const T& t) { | ||
| 51 | std::memcpy(buffer.data(), &t, std::min(sizeof(T), buffer.size())); | ||
| 52 | } | ||
| 53 | |||
| 42 | } // Anonymous namespace | 54 | } // Anonymous namespace |
| 43 | 55 | ||
| 44 | void BSD::PollWork::Execute(BSD* bsd) { | 56 | void BSD::PollWork::Execute(BSD* bsd) { |
| @@ -316,22 +328,12 @@ void BSD::SetSockOpt(HLERequestContext& ctx) { | |||
| 316 | const s32 fd = rp.Pop<s32>(); | 328 | const s32 fd = rp.Pop<s32>(); |
| 317 | const u32 level = rp.Pop<u32>(); | 329 | const u32 level = rp.Pop<u32>(); |
| 318 | const OptName optname = static_cast<OptName>(rp.Pop<u32>()); | 330 | const OptName optname = static_cast<OptName>(rp.Pop<u32>()); |
| 319 | 331 | const auto optval = ctx.ReadBuffer(); | |
| 320 | const auto buffer = ctx.ReadBuffer(); | ||
| 321 | const u8* optval = buffer.empty() ? nullptr : buffer.data(); | ||
| 322 | size_t optlen = buffer.size(); | ||
| 323 | |||
| 324 | std::array<u64, 2> values; | ||
| 325 | if ((optname == OptName::SNDTIMEO || optname == OptName::RCVTIMEO) && buffer.size() == 8) { | ||
| 326 | std::memcpy(values.data(), buffer.data(), sizeof(values)); | ||
| 327 | optlen = sizeof(values); | ||
| 328 | optval = reinterpret_cast<const u8*>(values.data()); | ||
| 329 | } | ||
| 330 | 332 | ||
| 331 | LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} optlen={}", fd, level, | 333 | LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} optlen={}", fd, level, |
| 332 | static_cast<u32>(optname), optlen); | 334 | static_cast<u32>(optname), optval.size()); |
| 333 | 335 | ||
| 334 | BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optlen, optval)); | 336 | BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval)); |
| 335 | } | 337 | } |
| 336 | 338 | ||
| 337 | void BSD::Shutdown(HLERequestContext& ctx) { | 339 | void BSD::Shutdown(HLERequestContext& ctx) { |
| @@ -521,18 +523,19 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco | |||
| 521 | 523 | ||
| 522 | std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, | 524 | std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, |
| 523 | s32 nfds, s32 timeout) { | 525 | s32 nfds, s32 timeout) { |
| 524 | if (write_buffer.size() < nfds * sizeof(PollFD)) { | 526 | if (nfds <= 0) { |
| 525 | return {-1, Errno::INVAL}; | ||
| 526 | } | ||
| 527 | |||
| 528 | if (nfds == 0) { | ||
| 529 | // When no entries are provided, -1 is returned with errno zero | 527 | // When no entries are provided, -1 is returned with errno zero |
| 530 | return {-1, Errno::SUCCESS}; | 528 | return {-1, Errno::SUCCESS}; |
| 531 | } | 529 | } |
| 530 | if (read_buffer.size() < nfds * sizeof(PollFD)) { | ||
| 531 | return {-1, Errno::INVAL}; | ||
| 532 | } | ||
| 533 | if (write_buffer.size() < nfds * sizeof(PollFD)) { | ||
| 534 | return {-1, Errno::INVAL}; | ||
| 535 | } | ||
| 532 | 536 | ||
| 533 | const size_t length = std::min(read_buffer.size(), write_buffer.size()); | ||
| 534 | std::vector<PollFD> fds(nfds); | 537 | std::vector<PollFD> fds(nfds); |
| 535 | std::memcpy(fds.data(), read_buffer.data(), length); | 538 | std::memcpy(fds.data(), read_buffer.data(), nfds * sizeof(PollFD)); |
| 536 | 539 | ||
| 537 | if (timeout >= 0) { | 540 | if (timeout >= 0) { |
| 538 | const s64 seconds = timeout / 1000; | 541 | const s64 seconds = timeout / 1000; |
| @@ -580,7 +583,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con | |||
| 580 | for (size_t i = 0; i < num; ++i) { | 583 | for (size_t i = 0; i < num; ++i) { |
| 581 | fds[i].revents = Translate(host_pollfds[i].revents); | 584 | fds[i].revents = Translate(host_pollfds[i].revents); |
| 582 | } | 585 | } |
| 583 | std::memcpy(write_buffer.data(), fds.data(), length); | 586 | std::memcpy(write_buffer.data(), fds.data(), nfds * sizeof(PollFD)); |
| 584 | 587 | ||
| 585 | return Translate(result); | 588 | return Translate(result); |
| 586 | } | 589 | } |
| @@ -608,8 +611,7 @@ std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) { | |||
| 608 | new_descriptor.is_connection_based = descriptor.is_connection_based; | 611 | new_descriptor.is_connection_based = descriptor.is_connection_based; |
| 609 | 612 | ||
| 610 | const SockAddrIn guest_addr_in = Translate(result.sockaddr_in); | 613 | const SockAddrIn guest_addr_in = Translate(result.sockaddr_in); |
| 611 | const size_t length = std::min(sizeof(guest_addr_in), write_buffer.size()); | 614 | PutValue(write_buffer, guest_addr_in); |
| 612 | std::memcpy(write_buffer.data(), &guest_addr_in, length); | ||
| 613 | 615 | ||
| 614 | return {new_fd, Errno::SUCCESS}; | 616 | return {new_fd, Errno::SUCCESS}; |
| 615 | } | 617 | } |
| @@ -619,8 +621,7 @@ Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) { | |||
| 619 | return Errno::BADF; | 621 | return Errno::BADF; |
| 620 | } | 622 | } |
| 621 | ASSERT(addr.size() == sizeof(SockAddrIn)); | 623 | ASSERT(addr.size() == sizeof(SockAddrIn)); |
| 622 | SockAddrIn addr_in; | 624 | auto addr_in = GetValue<SockAddrIn>(addr); |
| 623 | std::memcpy(&addr_in, addr.data(), sizeof(addr_in)); | ||
| 624 | 625 | ||
| 625 | return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); | 626 | return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); |
| 626 | } | 627 | } |
| @@ -631,8 +632,7 @@ Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) { | |||
| 631 | } | 632 | } |
| 632 | 633 | ||
| 633 | UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn)); | 634 | UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn)); |
| 634 | SockAddrIn addr_in; | 635 | auto addr_in = GetValue<SockAddrIn>(addr); |
| 635 | std::memcpy(&addr_in, addr.data(), sizeof(addr_in)); | ||
| 636 | 636 | ||
| 637 | return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); | 637 | return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); |
| 638 | } | 638 | } |
| @@ -650,7 +650,7 @@ Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) { | |||
| 650 | 650 | ||
| 651 | ASSERT(write_buffer.size() >= sizeof(guest_addrin)); | 651 | ASSERT(write_buffer.size() >= sizeof(guest_addrin)); |
| 652 | write_buffer.resize(sizeof(guest_addrin)); | 652 | write_buffer.resize(sizeof(guest_addrin)); |
| 653 | std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin)); | 653 | PutValue(write_buffer, guest_addrin); |
| 654 | return Translate(bsd_errno); | 654 | return Translate(bsd_errno); |
| 655 | } | 655 | } |
| 656 | 656 | ||
| @@ -667,7 +667,7 @@ Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) { | |||
| 667 | 667 | ||
| 668 | ASSERT(write_buffer.size() >= sizeof(guest_addrin)); | 668 | ASSERT(write_buffer.size() >= sizeof(guest_addrin)); |
| 669 | write_buffer.resize(sizeof(guest_addrin)); | 669 | write_buffer.resize(sizeof(guest_addrin)); |
| 670 | std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin)); | 670 | PutValue(write_buffer, guest_addrin); |
| 671 | return Translate(bsd_errno); | 671 | return Translate(bsd_errno); |
| 672 | } | 672 | } |
| 673 | 673 | ||
| @@ -725,7 +725,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o | |||
| 725 | optval.size() == sizeof(Errno), { return Errno::INVAL; }, | 725 | optval.size() == sizeof(Errno), { return Errno::INVAL; }, |
| 726 | "Incorrect getsockopt option size"); | 726 | "Incorrect getsockopt option size"); |
| 727 | optval.resize(sizeof(Errno)); | 727 | optval.resize(sizeof(Errno)); |
| 728 | memcpy(optval.data(), &translated_pending_err, sizeof(Errno)); | 728 | PutValue(optval, translated_pending_err); |
| 729 | } | 729 | } |
| 730 | return Translate(getsockopt_err); | 730 | return Translate(getsockopt_err); |
| 731 | } | 731 | } |
| @@ -735,7 +735,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o | |||
| 735 | } | 735 | } |
| 736 | } | 736 | } |
| 737 | 737 | ||
| 738 | Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval) { | 738 | Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) { |
| 739 | if (!IsFileDescriptorValid(fd)) { | 739 | if (!IsFileDescriptorValid(fd)) { |
| 740 | return Errno::BADF; | 740 | return Errno::BADF; |
| 741 | } | 741 | } |
| @@ -748,17 +748,15 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, con | |||
| 748 | Network::SocketBase* const socket = file_descriptors[fd]->socket.get(); | 748 | Network::SocketBase* const socket = file_descriptors[fd]->socket.get(); |
| 749 | 749 | ||
| 750 | if (optname == OptName::LINGER) { | 750 | if (optname == OptName::LINGER) { |
| 751 | ASSERT(optlen == sizeof(Linger)); | 751 | ASSERT(optval.size() == sizeof(Linger)); |
| 752 | Linger linger; | 752 | auto linger = GetValue<Linger>(optval); |
| 753 | std::memcpy(&linger, optval, sizeof(linger)); | ||
| 754 | ASSERT(linger.onoff == 0 || linger.onoff == 1); | 753 | ASSERT(linger.onoff == 0 || linger.onoff == 1); |
| 755 | 754 | ||
| 756 | return Translate(socket->SetLinger(linger.onoff != 0, linger.linger)); | 755 | return Translate(socket->SetLinger(linger.onoff != 0, linger.linger)); |
| 757 | } | 756 | } |
| 758 | 757 | ||
| 759 | ASSERT(optlen == sizeof(u32)); | 758 | ASSERT(optval.size() == sizeof(u32)); |
| 760 | u32 value; | 759 | auto value = GetValue<u32>(optval); |
| 761 | std::memcpy(&value, optval, sizeof(value)); | ||
| 762 | 760 | ||
| 763 | switch (optname) { | 761 | switch (optname) { |
| 764 | case OptName::REUSEADDR: | 762 | case OptName::REUSEADDR: |
| @@ -862,7 +860,7 @@ std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& mess | |||
| 862 | } else { | 860 | } else { |
| 863 | ASSERT(addr.size() == sizeof(SockAddrIn)); | 861 | ASSERT(addr.size() == sizeof(SockAddrIn)); |
| 864 | const SockAddrIn result = Translate(addr_in); | 862 | const SockAddrIn result = Translate(addr_in); |
| 865 | std::memcpy(addr.data(), &result, sizeof(result)); | 863 | PutValue(addr, result); |
| 866 | } | 864 | } |
| 867 | } | 865 | } |
| 868 | 866 | ||
| @@ -886,8 +884,7 @@ std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> mes | |||
| 886 | Network::SockAddrIn* p_addr_in = nullptr; | 884 | Network::SockAddrIn* p_addr_in = nullptr; |
| 887 | if (!addr.empty()) { | 885 | if (!addr.empty()) { |
| 888 | ASSERT(addr.size() == sizeof(SockAddrIn)); | 886 | ASSERT(addr.size() == sizeof(SockAddrIn)); |
| 889 | SockAddrIn guest_addr_in; | 887 | auto guest_addr_in = GetValue<SockAddrIn>(addr); |
| 890 | std::memcpy(&guest_addr_in, addr.data(), sizeof(guest_addr_in)); | ||
| 891 | addr_in = Translate(guest_addr_in); | 888 | addr_in = Translate(guest_addr_in); |
| 892 | p_addr_in = &addr_in; | 889 | p_addr_in = &addr_in; |
| 893 | } | 890 | } |
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index 161f22b9b..4f69d382c 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h | |||
| @@ -163,7 +163,7 @@ private: | |||
| 163 | Errno ListenImpl(s32 fd, s32 backlog); | 163 | Errno ListenImpl(s32 fd, s32 backlog); |
| 164 | std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg); | 164 | std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg); |
| 165 | Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval); | 165 | Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval); |
| 166 | Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval); | 166 | Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval); |
| 167 | Errno ShutdownImpl(s32 fd, s32 how); | 167 | Errno ShutdownImpl(s32 fd, s32 how); |
| 168 | std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message); | 168 | std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message); |
| 169 | std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message, | 169 | std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message, |
diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h index 9fc01ea90..7149fffeb 100644 --- a/src/core/hle/service/time/clock_types.h +++ b/src/core/hle/service/time/clock_types.h | |||
| @@ -11,6 +11,11 @@ | |||
| 11 | #include "core/hle/service/time/errors.h" | 11 | #include "core/hle/service/time/errors.h" |
| 12 | #include "core/hle/service/time/time_zone_types.h" | 12 | #include "core/hle/service/time/time_zone_types.h" |
| 13 | 13 | ||
| 14 | // Defined by WinBase.h on Windows | ||
| 15 | #ifdef GetCurrentTime | ||
| 16 | #undef GetCurrentTime | ||
| 17 | #endif | ||
| 18 | |||
| 14 | namespace Service::Time::Clock { | 19 | namespace Service::Time::Clock { |
| 15 | 20 | ||
| 16 | enum class TimeType : u8 { | 21 | enum class TimeType : u8 { |
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp index f0b5eff8a..d30f49877 100644 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ b/src/core/hle/service/vi/display/vi_display.cpp | |||
| @@ -35,7 +35,7 @@ static BufferQueue CreateBufferQueue(KernelHelpers::ServiceContext& service_cont | |||
| 35 | return { | 35 | return { |
| 36 | buffer_queue_core, | 36 | buffer_queue_core, |
| 37 | std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core, nvmap), | 37 | std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core, nvmap), |
| 38 | std::make_unique<android::BufferQueueConsumer>(buffer_queue_core, nvmap)}; | 38 | std::make_unique<android::BufferQueueConsumer>(buffer_queue_core)}; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | Display::Display(u64 id, std::string name_, | 41 | Display::Display(u64 id, std::string name_, |