From 34635a42c0b3e050e131c857199c474df35ba410 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 17 Nov 2018 17:04:11 -0500 Subject: nvdrv: Stub nvdec/vic ioctls to bypass nvdec movies --- .../hle/service/nvdrv/devices/nvhost_nvdec.cpp | 70 +++++++++++++++++++++- src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | 52 +++++++++++++++- src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | 70 +++++++++++++++++++++- src/core/hle/service/nvdrv/devices/nvhost_vic.h | 50 ++++++++++++++++ 4 files changed, 239 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index bdae8b887..fcb612864 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -22,6 +22,18 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector& input, const std:: switch (static_cast(command.raw)) { case IoctlCommand::IocSetNVMAPfdCommand: return SetNVMAPfd(input, output); + case IoctlCommand::IocSubmit: + return Submit(input, output); + case IoctlCommand::IocGetSyncpoint: + return GetSyncpoint(input, output); + case IoctlCommand::IocGetWaitbase: + return GetWaitbase(input, output); + case IoctlCommand::IocMapBuffer: + return MapBuffer(input, output); + case IoctlCommand::IocMapBufferEx: + return MapBufferEx(input, output); + case IoctlCommand::IocUnmapBufferEx: + return UnmapBufferEx(input, output); } UNIMPLEMENTED_MSG("Unimplemented ioctl"); @@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector& input, const std:: u32 nvhost_nvdec::SetNVMAPfd(const std::vector& input, std::vector& output) { IoctlSetNvmapFD params{}; - std::memcpy(¶ms, input.data(), input.size()); + std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD)); LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); nvmap_fd = params.nvmap_fd; return 0; } +u32 nvhost_nvdec::Submit(const std::vector& input, std::vector& output) { + IoctlSubmit params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); + LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); + return 0; +} + +u32 nvhost_nvdec::GetSyncpoint(const std::vector& input, std::vector& output) { + IoctlGetSyncpoint params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); + LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); + params.value = 0; // Seems to be hard coded at 0 + std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); + return 0; +} + +u32 nvhost_nvdec::GetWaitbase(const std::vector& input, std::vector& output) { + IoctlGetWaitbase params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); + LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); + params.value = 0; // Seems to be hard coded at 0 + std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase)); + return 0; +} + +u32 nvhost_nvdec::MapBuffer(const std::vector& input, std::vector& output) { + IoctlMapBuffer params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); + LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, + params.address_1); + params.address_1 = 0; + params.address_2 = 0; + std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); + return 0; +} + +u32 nvhost_nvdec::MapBufferEx(const std::vector& input, std::vector& output) { + IoctlMapBufferEx params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx)); + LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, + params.address_1); + params.address_1 = 0; + params.address_2 = 0; + std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx)); + return 0; +} + +u32 nvhost_nvdec::UnmapBufferEx(const std::vector& input, std::vector& output) { + IoctlUnmapBufferEx params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); + LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx)); + return 0; +} + } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index cbdac8069..4332db118 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h @@ -23,16 +23,66 @@ public: private: enum class IoctlCommand : u32_le { IocSetNVMAPfdCommand = 0x40044801, + IocSubmit = 0xC0400001, + IocGetSyncpoint = 0xC0080002, + IocGetWaitbase = 0xC0080003, + IocMapBuffer = 0xC01C0009, + IocMapBufferEx = 0xC0A40009, + IocUnmapBufferEx = 0xC0A4000A, }; struct IoctlSetNvmapFD { u32_le nvmap_fd; }; - static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); + static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size"); + + struct IoctlSubmit { + INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure + }; + static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size"); + + struct IoctlGetSyncpoint { + u32 unknown; // seems to be ignored? Nintendo added this + u32 value; + }; + static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size"); + + struct IoctlGetWaitbase { + u32 unknown; // seems to be ignored? Nintendo added this + u32 value; + }; + static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size"); + + struct IoctlMapBuffer { + u32 unknown; + u32 address_1; + u32 address_2; + INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure + }; + static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size"); + + struct IoctlMapBufferEx { + u32 unknown; + u32 address_1; + u32 address_2; + INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure + }; + static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size"); + + struct IoctlUnmapBufferEx { + INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure + }; + static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size"); u32_le nvmap_fd{}; u32 SetNVMAPfd(const std::vector& input, std::vector& output); + u32 Submit(const std::vector& input, std::vector& output); + u32 GetSyncpoint(const std::vector& input, std::vector& output); + u32 GetWaitbase(const std::vector& input, std::vector& output); + u32 MapBuffer(const std::vector& input, std::vector& output); + u32 MapBufferEx(const std::vector& input, std::vector& output); + u32 UnmapBufferEx(const std::vector& input, std::vector& output); }; } // 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 c695b8863..fea363a53 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector& input, const std::ve switch (static_cast(command.raw)) { case IoctlCommand::IocSetNVMAPfdCommand: return SetNVMAPfd(input, output); + case IoctlCommand::IocSubmit: + return Submit(input, output); + case IoctlCommand::IocGetSyncpoint: + return GetSyncpoint(input, output); + case IoctlCommand::IocGetWaitbase: + return GetWaitbase(input, output); + case IoctlCommand::IocMapBuffer: + return MapBuffer(input, output); + case IoctlCommand::IocMapBufferEx: + return MapBuffer(input, output); + case IoctlCommand::IocUnmapBufferEx: + return UnmapBufferEx(input, output); } UNIMPLEMENTED_MSG("Unimplemented ioctl"); @@ -30,11 +42,67 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector& input, const std::ve u32 nvhost_vic::SetNVMAPfd(const std::vector& input, std::vector& output) { IoctlSetNvmapFD params{}; - std::memcpy(¶ms, input.data(), input.size()); + std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD)); LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); nvmap_fd = params.nvmap_fd; return 0; } +u32 nvhost_vic::Submit(const std::vector& input, std::vector& output) { + IoctlSubmit params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); + LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); + return 0; +} + +u32 nvhost_vic::GetSyncpoint(const std::vector& input, std::vector& output) { + IoctlGetSyncpoint params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); + LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); + params.value = 0; // Seems to be hard coded at 0 + std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); + return 0; +} + +u32 nvhost_vic::GetWaitbase(const std::vector& input, std::vector& output) { + IoctlGetWaitbase params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); + LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); + params.value = 0; // Seems to be hard coded at 0 + std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase)); + return 0; +} + +u32 nvhost_vic::MapBuffer(const std::vector& input, std::vector& output) { + IoctlMapBuffer params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); + LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, + params.address_1); + params.address_1 = 0; + params.address_2 = 0; + std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); + return 0; +} + +u32 nvhost_vic::MapBufferEx(const std::vector& input, std::vector& output) { + IoctlMapBufferEx params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx)); + LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, + params.address_1); + params.address_1 = 0; + params.address_2 = 0; + std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx)); + return 0; +} + +u32 nvhost_vic::UnmapBufferEx(const std::vector& input, std::vector& output) { + IoctlUnmapBufferEx params{}; + std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); + LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx)); + return 0; +} + } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index bec32bea1..6854f26dd 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h @@ -23,6 +23,12 @@ public: private: enum class IoctlCommand : u32_le { IocSetNVMAPfdCommand = 0x40044801, + IocSubmit = 0xC0400001, + IocGetSyncpoint = 0xC0080002, + IocGetWaitbase = 0xC0080003, + IocMapBuffer = 0xC01C0009, + IocMapBufferEx = 0xC03C0009, + IocUnmapBufferEx = 0xC03C000A, }; struct IoctlSetNvmapFD { @@ -30,9 +36,53 @@ private: }; static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); + struct IoctlSubmit { + INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure + }; + static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size"); + + struct IoctlGetSyncpoint { + u32 unknown; // seems to be ignored? Nintendo added this + u32 value; + }; + static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size"); + + struct IoctlGetWaitbase { + u32 unknown; // seems to be ignored? Nintendo added this + u32 value; + }; + static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size"); + + struct IoctlMapBuffer { + u32 unknown; + u32 address_1; + u32 address_2; + INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure + }; + static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size"); + + struct IoctlMapBufferEx { + u32 unknown; + u32 address_1; + u32 address_2; + INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure + }; + static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size"); + + struct IoctlUnmapBufferEx { + INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure + }; + static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size"); + u32_le nvmap_fd{}; u32 SetNVMAPfd(const std::vector& input, std::vector& output); + u32 Submit(const std::vector& input, std::vector& output); + u32 GetSyncpoint(const std::vector& input, std::vector& output); + u32 GetWaitbase(const std::vector& input, std::vector& output); + u32 MapBuffer(const std::vector& input, std::vector& output); + u32 MapBufferEx(const std::vector& input, std::vector& output); + u32 UnmapBufferEx(const std::vector& input, std::vector& output); }; } // namespace Service::Nvidia::Devices -- cgit v1.2.3 From 1adf640d372524edd4d4c528c915be9b8b7ff8ab Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 3 May 2020 02:39:37 -0400 Subject: service: nvhost_vic: Ignore Submit commands. --- src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | 4 ++++ src/core/hle/service/nvdrv/devices/nvhost_vic.h | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index fea363a53..9da19ad56 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -53,6 +53,10 @@ u32 nvhost_vic::Submit(const std::vector& input, std::vector& output) { IoctlSubmit params{}; std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + + // Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU + params.command_buffer = {}; + std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index 6854f26dd..a7bb7bbd5 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include "common/common_types.h" #include "common/swap.h" @@ -36,8 +37,20 @@ private: }; static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); + struct IoctlSubmitCommandBuffer { + u32 id; + u32 offset; + u32 count; + }; + static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC, + "IoctlSubmitCommandBuffer is incorrect size"); + struct IoctlSubmit { - INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure + u32 command_buffer_count; + u32 relocations_count; + u32 syncpt_count; + u32 wait_count; + std::array command_buffer; }; static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size"); -- cgit v1.2.3 From 4d4bbe756f94c3bfc2df5265283596ee96cce9f9 Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Tue, 12 May 2020 20:46:14 +0200 Subject: file_sys/nsp: Make SetTicketKeys actually do something Previously, the method wasn't modifying any class state and therefore not having any effects when called. Since this has been the case for a very long time now, I'm not sure if we couldn't just remove this method altogether. --- src/core/file_sys/submission_package.cpp | 61 +++++++++++++++----------------- src/core/file_sys/submission_package.h | 1 + 2 files changed, 30 insertions(+), 32 deletions(-) (limited to 'src/core') diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index 175a8266a..a6637fa39 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -19,38 +19,6 @@ #include "core/loader/loader.h" namespace FileSys { -namespace { -void SetTicketKeys(const std::vector& files) { - auto& keys = Core::Crypto::KeyManager::Instance(); - - for (const auto& ticket_file : files) { - if (ticket_file == nullptr) { - continue; - } - - if (ticket_file->GetExtension() != "tik") { - continue; - } - - if (ticket_file->GetSize() < - Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET + sizeof(Core::Crypto::Key128)) { - continue; - } - - Core::Crypto::Key128 key{}; - ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET); - - // We get the name without the extension in order to create the rights ID. - std::string name_only(ticket_file->GetName()); - name_only.erase(name_only.size() - 4); - - const auto rights_id_raw = Common::HexStringToArray<16>(name_only); - u128 rights_id; - std::memcpy(rights_id.data(), rights_id_raw.data(), sizeof(u128)); - keys.SetKey(Core::Crypto::S128KeyType::Titlekey, key, rights_id[1], rights_id[0]); - } -} -} // Anonymous namespace NSP::NSP(VirtualFile file_) : file(std::move(file_)), status{Loader::ResultStatus::Success}, @@ -232,6 +200,35 @@ VirtualDir NSP::GetParentDirectory() const { return file->GetContainingDirectory(); } +void NSP::SetTicketKeys(const std::vector& files) { + for (const auto& ticket_file : files) { + if (ticket_file == nullptr) { + continue; + } + + if (ticket_file->GetExtension() != "tik") { + continue; + } + + if (ticket_file->GetSize() < + Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET + sizeof(Core::Crypto::Key128)) { + continue; + } + + Core::Crypto::Key128 key{}; + ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET); + + // We get the name without the extension in order to create the rights ID. + std::string name_only(ticket_file->GetName()); + name_only.erase(name_only.size() - 4); + + const auto rights_id_raw = Common::HexStringToArray<16>(name_only); + u128 rights_id; + std::memcpy(rights_id.data(), rights_id_raw.data(), sizeof(u128)); + keys.SetKey(Core::Crypto::S128KeyType::Titlekey, key, rights_id[1], rights_id[0]); + } +} + void NSP::InitializeExeFSAndRomFS(const std::vector& files) { exefs = pfs; diff --git a/src/core/file_sys/submission_package.h b/src/core/file_sys/submission_package.h index cf89de6a9..6d54bd807 100644 --- a/src/core/file_sys/submission_package.h +++ b/src/core/file_sys/submission_package.h @@ -59,6 +59,7 @@ public: VirtualDir GetParentDirectory() const override; private: + void SetTicketKeys(const std::vector& files); void InitializeExeFSAndRomFS(const std::vector& files); void ReadNCAs(const std::vector& files); -- cgit v1.2.3 From 43ce33b6cced1d049f1cef3a9b1fddcfad8aef7c Mon Sep 17 00:00:00 2001 From: M&M Date: Wed, 29 Jul 2020 10:25:37 -0700 Subject: logging/settings: Increase maximum log size to 100 MB and add extended logging option The extended logging option is automatically disabled on boot but can be enabled afterwards, allowing the log file to go up to 1 GB during that session. This commit also fixes a few errors that are present in the general debug menu. --- src/core/settings.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/settings.h b/src/core/settings.h index 3681b5e9d..5a2f852fd 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -498,6 +498,7 @@ struct Values { bool reporting_services; bool quest_flag; bool disable_macro_jit; + bool extended_logging; // Misceallaneous std::string log_filter; -- cgit v1.2.3 From ddff03cff57ae6243de895413caf0a1c0b0e7758 Mon Sep 17 00:00:00 2001 From: german Date: Wed, 23 Sep 2020 17:51:09 -0500 Subject: Use different timing for motion --- .../hle/service/hid/controllers/controller_base.h | 4 + src/core/hle/service/hid/controllers/npad.cpp | 202 +++++++++++++-------- src/core/hle/service/hid/controllers/npad.h | 4 + src/core/hle/service/hid/hid.cpp | 21 ++- src/core/hle/service/hid/hid.h | 2 + 5 files changed, 157 insertions(+), 76 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h index 8bc69c372..f47a9e61c 100644 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ b/src/core/hle/service/hid/controllers/controller_base.h @@ -31,6 +31,10 @@ public: virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) = 0; + // When the controller is requesting a motion update for the shared memory + virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, + std::size_t size) {} + // Called when input devices should be loaded virtual void OnLoadInputDevices() = 0; diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 620386cd1..e34ee519e 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -365,6 +365,135 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } const u32 npad_index = static_cast(i); + RequestPadStateUpdate(npad_index); + auto& pad_state = npad_pad_states[npad_index]; + + auto& main_controller = + npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; + auto& handheld_entry = + npad.handheld_states.npad[npad.handheld_states.common.last_entry_index]; + auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index]; + auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index]; + auto& right_entry = + npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index]; + auto& pokeball_entry = + npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; + auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; + + libnx_entry.connection_status.raw = 0; + libnx_entry.connection_status.IsConnected.Assign(1); + auto& full_sixaxis_entry = + npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; + auto& handheld_sixaxis_entry = + npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index]; + auto& dual_left_sixaxis_entry = + npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index]; + auto& dual_right_sixaxis_entry = + npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index]; + auto& left_sixaxis_entry = + npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index]; + auto& right_sixaxis_entry = + npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index]; + + switch (controller_type) { + case NPadControllerType::None: + UNREACHABLE(); + break; + case NPadControllerType::ProController: + main_controller.connection_status.raw = 0; + main_controller.connection_status.IsConnected.Assign(1); + main_controller.connection_status.IsWired.Assign(1); + main_controller.pad.pad_states.raw = pad_state.pad_states.raw; + main_controller.pad.l_stick = pad_state.l_stick; + main_controller.pad.r_stick = pad_state.r_stick; + + libnx_entry.connection_status.IsWired.Assign(1); + break; + case NPadControllerType::Handheld: + handheld_entry.connection_status.raw = 0; + handheld_entry.connection_status.IsConnected.Assign(1); + handheld_entry.connection_status.IsWired.Assign(1); + handheld_entry.connection_status.IsLeftJoyConnected.Assign(1); + handheld_entry.connection_status.IsRightJoyConnected.Assign(1); + handheld_entry.connection_status.IsLeftJoyWired.Assign(1); + handheld_entry.connection_status.IsRightJoyWired.Assign(1); + handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; + handheld_entry.pad.l_stick = pad_state.l_stick; + handheld_entry.pad.r_stick = pad_state.r_stick; + + libnx_entry.connection_status.IsWired.Assign(1); + libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); + libnx_entry.connection_status.IsRightJoyConnected.Assign(1); + libnx_entry.connection_status.IsLeftJoyWired.Assign(1); + libnx_entry.connection_status.IsRightJoyWired.Assign(1); + break; + case NPadControllerType::JoyDual: + dual_entry.connection_status.raw = 0; + dual_entry.connection_status.IsConnected.Assign(1); + dual_entry.connection_status.IsLeftJoyConnected.Assign(1); + dual_entry.connection_status.IsRightJoyConnected.Assign(1); + dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; + dual_entry.pad.l_stick = pad_state.l_stick; + dual_entry.pad.r_stick = pad_state.r_stick; + + libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); + libnx_entry.connection_status.IsRightJoyConnected.Assign(1); + break; + case NPadControllerType::JoyLeft: + left_entry.connection_status.raw = 0; + left_entry.connection_status.IsConnected.Assign(1); + left_entry.connection_status.IsLeftJoyConnected.Assign(1); + left_entry.pad.pad_states.raw = pad_state.pad_states.raw; + left_entry.pad.l_stick = pad_state.l_stick; + left_entry.pad.r_stick = pad_state.r_stick; + + libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); + break; + case NPadControllerType::JoyRight: + right_entry.connection_status.raw = 0; + right_entry.connection_status.IsConnected.Assign(1); + right_entry.connection_status.IsRightJoyConnected.Assign(1); + right_entry.pad.pad_states.raw = pad_state.pad_states.raw; + right_entry.pad.l_stick = pad_state.l_stick; + right_entry.pad.r_stick = pad_state.r_stick; + + libnx_entry.connection_status.IsRightJoyConnected.Assign(1); + break; + case NPadControllerType::Pokeball: + pokeball_entry.connection_status.raw = 0; + pokeball_entry.connection_status.IsConnected.Assign(1); + pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; + pokeball_entry.pad.l_stick = pad_state.l_stick; + pokeball_entry.pad.r_stick = pad_state.r_stick; + break; + } + + // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate + // any controllers. + libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw; + libnx_entry.pad.l_stick = pad_state.l_stick; + libnx_entry.pad.r_stick = pad_state.r_stick; + + press_state |= static_cast(pad_state.pad_states.raw); + } + std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), + shared_memory_entries.size() * sizeof(NPadEntry)); +} + +void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, + std::size_t data_len) { + if (!IsControllerActivated()) { + return; + } + for (std::size_t i = 0; i < shared_memory_entries.size(); i++) { + auto& npad = shared_memory_entries[i]; + + const auto& controller_type = connected_controllers[i].type; + + if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { + continue; + } + const std::array controller_sixaxes{ &npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left, &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right, @@ -403,9 +532,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } } - RequestPadStateUpdate(npad_index); - auto& pad_state = npad_pad_states[npad_index]; - auto& main_controller = npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; auto& handheld_entry = @@ -418,8 +544,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; - libnx_entry.connection_status.raw = 0; - libnx_entry.connection_status.IsConnected.Assign(1); auto& full_sixaxis_entry = npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; auto& handheld_sixaxis_entry = @@ -438,15 +562,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* UNREACHABLE(); break; case NPadControllerType::ProController: - main_controller.connection_status.raw = 0; - main_controller.connection_status.IsConnected.Assign(1); - main_controller.connection_status.IsWired.Assign(1); - main_controller.pad.pad_states.raw = pad_state.pad_states.raw; - main_controller.pad.l_stick = pad_state.l_stick; - main_controller.pad.r_stick = pad_state.r_stick; - - libnx_entry.connection_status.IsWired.Assign(1); - if (sixaxis_sensors_enabled && motions[i][0]) { full_sixaxis_entry.accel = motion_devices[0].accel; full_sixaxis_entry.gyro = motion_devices[0].gyro; @@ -455,23 +570,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } break; case NPadControllerType::Handheld: - handheld_entry.connection_status.raw = 0; - handheld_entry.connection_status.IsConnected.Assign(1); - handheld_entry.connection_status.IsWired.Assign(1); - handheld_entry.connection_status.IsLeftJoyConnected.Assign(1); - handheld_entry.connection_status.IsRightJoyConnected.Assign(1); - handheld_entry.connection_status.IsLeftJoyWired.Assign(1); - handheld_entry.connection_status.IsRightJoyWired.Assign(1); - handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; - handheld_entry.pad.l_stick = pad_state.l_stick; - handheld_entry.pad.r_stick = pad_state.r_stick; - - libnx_entry.connection_status.IsWired.Assign(1); - libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); - libnx_entry.connection_status.IsRightJoyConnected.Assign(1); - libnx_entry.connection_status.IsLeftJoyWired.Assign(1); - libnx_entry.connection_status.IsRightJoyWired.Assign(1); - if (sixaxis_sensors_enabled && motions[i][0]) { handheld_sixaxis_entry.accel = motion_devices[0].accel; handheld_sixaxis_entry.gyro = motion_devices[0].gyro; @@ -480,17 +578,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } break; case NPadControllerType::JoyDual: - dual_entry.connection_status.raw = 0; - dual_entry.connection_status.IsConnected.Assign(1); - dual_entry.connection_status.IsLeftJoyConnected.Assign(1); - dual_entry.connection_status.IsRightJoyConnected.Assign(1); - dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; - dual_entry.pad.l_stick = pad_state.l_stick; - dual_entry.pad.r_stick = pad_state.r_stick; - - libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); - libnx_entry.connection_status.IsRightJoyConnected.Assign(1); - if (sixaxis_sensors_enabled && motions[i][0]) { // Set motion for the left joycon dual_left_sixaxis_entry.accel = motion_devices[0].accel; @@ -507,15 +594,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } break; case NPadControllerType::JoyLeft: - left_entry.connection_status.raw = 0; - left_entry.connection_status.IsConnected.Assign(1); - left_entry.connection_status.IsLeftJoyConnected.Assign(1); - left_entry.pad.pad_states.raw = pad_state.pad_states.raw; - left_entry.pad.l_stick = pad_state.l_stick; - left_entry.pad.r_stick = pad_state.r_stick; - - libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); - if (sixaxis_sensors_enabled && motions[i][0]) { left_sixaxis_entry.accel = motion_devices[0].accel; left_sixaxis_entry.gyro = motion_devices[0].gyro; @@ -524,15 +602,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } break; case NPadControllerType::JoyRight: - right_entry.connection_status.raw = 0; - right_entry.connection_status.IsConnected.Assign(1); - right_entry.connection_status.IsRightJoyConnected.Assign(1); - right_entry.pad.pad_states.raw = pad_state.pad_states.raw; - right_entry.pad.l_stick = pad_state.l_stick; - right_entry.pad.r_stick = pad_state.r_stick; - - libnx_entry.connection_status.IsRightJoyConnected.Assign(1); - if (sixaxis_sensors_enabled && motions[i][1]) { right_sixaxis_entry.accel = motion_devices[1].accel; right_sixaxis_entry.gyro = motion_devices[1].gyro; @@ -541,21 +610,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } break; case NPadControllerType::Pokeball: - pokeball_entry.connection_status.raw = 0; - pokeball_entry.connection_status.IsConnected.Assign(1); - pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; - pokeball_entry.pad.l_stick = pad_state.l_stick; - pokeball_entry.pad.r_stick = pad_state.r_stick; break; } - - // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate - // any controllers. - libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw; - libnx_entry.pad.l_stick = pad_state.l_stick; - libnx_entry.pad.r_stick = pad_state.r_stick; - - press_state |= static_cast(pad_state.pad_states.raw); } std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), shared_memory_entries.size() * sizeof(NPadEntry)); diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 654d97c3f..0fa7455ba 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -32,6 +32,10 @@ public: // When the controller is requesting an update for the shared memory void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; + // When the controller is requesting a motion update for the shared memory + void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, + std::size_t size) override; + // Called when input devices should be loaded void OnLoadInputDevices() override; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 395e83b3f..9a7e5e265 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -40,7 +40,8 @@ namespace Service::HID { // Updating period for each HID device. // HID is polled every 15ms, this value was derived from // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet -constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) +constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz) +constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz) constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; IAppletResource::IAppletResource(Core::System& system) @@ -79,10 +80,14 @@ IAppletResource::IAppletResource(Core::System& system) [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { UpdateControllers(user_data, ns_late); }); - - // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) + motion_update_event = Core::Timing::CreateEvent( + "HID::MotionPadCallback", + [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { + UpdateMotion(user_data, ns_late); + }); system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); + system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event); ReloadInputDevices(); } @@ -122,6 +127,16 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data, core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); } +void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { + auto& core_timing = system.CoreTiming(); + + for (const auto& controller : controllers) { + controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); + } + + core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event); +} + class IActiveVibrationDeviceList final : public ServiceFramework { public: IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index e04aaf1e9..3cfd72a51 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -65,10 +65,12 @@ private: void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); + void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); std::shared_ptr shared_mem; std::shared_ptr pad_update_event; + std::shared_ptr motion_update_event; Core::System& system; std::array, static_cast(HidController::MaxControllers)> -- cgit v1.2.3 From 3602df7f1f58e1009af1f100892f8a439da7d1b6 Mon Sep 17 00:00:00 2001 From: Morph Date: Thu, 24 Sep 2020 08:55:51 -0400 Subject: submission_package: Fix updates integrated into cartridge images. --- src/core/file_sys/submission_package.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index aab957bf2..07ae90819 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -286,12 +286,31 @@ void NSP::ReadNCAs(const std::vector& files) { } auto next_nca = std::make_shared(std::move(next_file), nullptr, 0); + if (next_nca->GetType() == NCAContentType::Program) { program_status[next_nca->GetTitleId()] = next_nca->GetStatus(); } - if (next_nca->GetStatus() == Loader::ResultStatus::Success || - (next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS && - (next_nca->GetTitleId() & 0x800) != 0)) { + + if (next_nca->GetStatus() != Loader::ResultStatus::Success && + next_nca->GetStatus() != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { + continue; + } + + // If the last 3 hexadecimal digits of the CNMT TitleID is 0x800 or is missing the + // BKTRBaseRomFS, this is an update NCA. Otherwise, this is a base NCA. + if ((cnmt.GetTitleID() & 0x800) != 0 || + next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { + // If the last 3 hexadecimal digits of the NCA's TitleID is between 0x1 and + // 0x7FF, this is a multi-program update NCA. Otherwise, this is a regular + // update NCA. + if ((next_nca->GetTitleId() & 0x7FF) != 0 && + (next_nca->GetTitleId() & 0x800) == 0) { + ncas[next_nca->GetTitleId()][{cnmt.GetType(), rec.type}] = + std::move(next_nca); + } else { + ncas[cnmt.GetTitleID()][{cnmt.GetType(), rec.type}] = std::move(next_nca); + } + } else { ncas[next_nca->GetTitleId()][{cnmt.GetType(), rec.type}] = std::move(next_nca); } } -- cgit v1.2.3 From f3a1bf53f94336b2863baf14eecc714b510fee39 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 00:05:12 -0400 Subject: service: Restore "unused" function Turns out this function is actually used, but within a trace log. --- src/core/hle/service/service.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/core') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 76b3533ec..ba9159ee0 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -72,6 +72,23 @@ namespace Service { +/** + * Creates a function string for logging, complete with the name (or header code, depending + * on what's passed in) the port name, and all the cmd_buff arguments. + */ +[[maybe_unused]] static std::string MakeFunctionString(std::string_view name, + std::string_view port_name, + const u32* cmd_buff) { + // Number of params == bits 0-5 + bits 6-11 + int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); + + std::string function_string = fmt::format("function '{}': port={}", name, port_name); + for (int i = 1; i <= num_params; ++i) { + function_string += fmt::format(", cmd_buff[{}]=0x{:X}", i, cmd_buff[i]); + } + return function_string; +} + ServiceFrameworkBase::ServiceFrameworkBase(const char* service_name, u32 max_sessions, InvokerFn* handler_invoker) : service_name(service_name), max_sessions(max_sessions), handler_invoker(handler_invoker) {} -- cgit v1.2.3 From 3e4a0a13cb2f2e02bdb623d763a63a71c2c5da7a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 19:13:10 -0400 Subject: frontend/controller: Eliminate dependency on the global system instance --- src/core/frontend/applets/controller.cpp | 8 ++++---- src/core/frontend/applets/controller.h | 8 ++++++++ src/core/hle/service/am/applets/applets.cpp | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src/core') diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp index 4505da758..c5d65f2d0 100644 --- a/src/core/frontend/applets/controller.cpp +++ b/src/core/frontend/applets/controller.cpp @@ -4,7 +4,6 @@ #include "common/assert.h" #include "common/logging/log.h" -#include "core/core.h" #include "core/frontend/applets/controller.h" #include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/hid.h" @@ -14,6 +13,9 @@ namespace Core::Frontend { ControllerApplet::~ControllerApplet() = default; +DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_) + : service_manager{service_manager_} {} + DefaultControllerApplet::~DefaultControllerApplet() = default; void DefaultControllerApplet::ReconfigureControllers(std::function callback, @@ -21,9 +23,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function callb LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!"); auto& npad = - Core::System::GetInstance() - .ServiceManager() - .GetService("hid") + service_manager.GetService("hid") ->GetAppletResource() ->GetController(Service::HID::HidController::NPad); diff --git a/src/core/frontend/applets/controller.h b/src/core/frontend/applets/controller.h index a227f15cd..3e49cdbb9 100644 --- a/src/core/frontend/applets/controller.h +++ b/src/core/frontend/applets/controller.h @@ -8,6 +8,10 @@ #include "common/common_types.h" +namespace Service::SM { +class ServiceManager; +} + namespace Core::Frontend { using BorderColor = std::array; @@ -39,10 +43,14 @@ public: class DefaultControllerApplet final : public ControllerApplet { public: + explicit DefaultControllerApplet(Service::SM::ServiceManager& service_manager_); ~DefaultControllerApplet() override; void ReconfigureControllers(std::function callback, ControllerParameters parameters) const override; + +private: + Service::SM::ServiceManager& service_manager; }; } // namespace Core::Frontend diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 4e0800f9a..2b626bb40 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -206,7 +206,8 @@ void AppletManager::SetDefaultAppletFrontendSet() { void AppletManager::SetDefaultAppletsIfMissing() { if (frontend.controller == nullptr) { - frontend.controller = std::make_unique(); + frontend.controller = + std::make_unique(system.ServiceManager()); } if (frontend.e_commerce == nullptr) { -- cgit v1.2.3 From 5c4e23790283f744be75d866318342bddd064234 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 19:15:21 -0400 Subject: core: Mark GetInstance() as deprecated This way it's obvious that this function shouldn't be used in any future code. --- src/core/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/core.h b/src/core/core.h index 83ded63a5..27efe30bb 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -120,7 +120,7 @@ public: * Gets the instance of the System singleton class. * @returns Reference to the instance of the System singleton class. */ - static System& GetInstance() { + [[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance() { return s_instance; } -- cgit v1.2.3 From ab88c2f6112edba35bfa91ee8864e760728d16e8 Mon Sep 17 00:00:00 2001 From: german Date: Fri, 10 Jul 2020 21:20:50 -0500 Subject: First implementation of controller rumble --- src/core/frontend/input.h | 3 +++ src/core/hle/service/hid/controllers/npad.cpp | 25 ++++++++++++++++++------- src/core/hle/service/hid/controllers/npad.h | 2 +- src/core/hle/service/hid/hid.cpp | 8 +++----- 4 files changed, 25 insertions(+), 13 deletions(-) (limited to 'src/core') diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h index 9da0d2829..277b70e53 100644 --- a/src/core/frontend/input.h +++ b/src/core/frontend/input.h @@ -33,6 +33,9 @@ public: virtual bool GetAnalogDirectionStatus(AnalogDirection direction) const { return {}; } + virtual bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const { + return {}; + } }; /// An abstract class template for a factory that can create input devices. diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 620386cd1..83c3beab6 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -609,20 +609,31 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) } } -void Controller_NPad::VibrateController(const std::vector& controller_ids, +void Controller_NPad::VibrateController(const std::vector& controllers, const std::vector& vibrations) { - LOG_DEBUG(Service_HID, "(STUBBED) called"); + LOG_TRACE(Service_HID, "called"); if (!Settings::values.vibration_enabled || !can_controllers_vibrate) { return; } - for (std::size_t i = 0; i < controller_ids.size(); i++) { - std::size_t controller_pos = NPadIdToIndex(static_cast(i)); - if (connected_controllers[controller_pos].is_connected) { - // TODO(ogniK): Vibrate the physical controller + bool success = true; + for (std::size_t i = 0; i < controllers.size(); ++i) { + if (!connected_controllers[i].is_connected) { + continue; + } + using namespace Settings::NativeButton; + const auto& button_state = buttons[i]; + if (button_state[A - BUTTON_HID_BEGIN]) { + if (button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay( + vibrations[0].amp_high, vibrations[0].amp_low, vibrations[0].freq_high, + vibrations[0].freq_low)) { + success = false; + } } } - last_processed_vibration = vibrations.back(); + if (success) { + last_processed_vibration = vibrations.back(); + } } Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 654d97c3f..0cff6821f 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -121,7 +121,7 @@ public: void SetNpadMode(u32 npad_id, NPadAssignments assignment_mode); - void VibrateController(const std::vector& controller_ids, + void VibrateController(const std::vector& controllers, const std::vector& vibrations); Vibration GetLastVibration() const; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 395e83b3f..dc198791d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -802,18 +802,18 @@ void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) { void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto controller_id{rp.Pop()}; + const auto controller{rp.Pop()}; const auto vibration_values{rp.PopRaw()}; const auto applet_resource_user_id{rp.Pop()}; - LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id, + LOG_DEBUG(Service_HID, "called, controller={}, applet_resource_user_id={}", controller, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); applet_resource->GetController(HidController::NPad) - .VibrateController({controller_id}, {vibration_values}); + .VibrateController({controller}, {vibration_values}); } void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) { @@ -831,8 +831,6 @@ void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) { std::memcpy(controller_list.data(), controllers.data(), controllers.size()); std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size()); - std::transform(controller_list.begin(), controller_list.end(), controller_list.begin(), - [](u32 controller_id) { return controller_id - 3; }); applet_resource->GetController(HidController::NPad) .VibrateController(controller_list, vibration_list); -- cgit v1.2.3 From 6380731486e687a0a6b60ac3a1bd68812e538e66 Mon Sep 17 00:00:00 2001 From: Morph Date: Wed, 30 Sep 2020 06:34:08 -0400 Subject: hid: Stub HomeButtonInputProtection service commands - Used in 1-2 Switch. Given that we do not emulate the functionality of the home button yet, we can stub this for now. --- src/core/hle/service/hid/controllers/npad.cpp | 9 +++++++ src/core/hle/service/hid/controllers/npad.h | 3 +++ src/core/hle/service/hid/hid.cpp | 38 +++++++++++++++++++++++++-- src/core/hle/service/hid/hid.h | 2 ++ 4 files changed, 50 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index e34ee519e..548517a1f 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -826,6 +826,15 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { } } +bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const { + return unintended_home_button_input_protection[NPadIdToIndex(npad_id)]; +} + +void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, + u32 npad_id) { + unintended_home_button_input_protection[NPadIdToIndex(npad_id)] = is_protection_enabled; +} + void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { can_controllers_vibrate = can_vibrate; } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 0fa7455ba..cd49f49be 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -146,6 +146,8 @@ public: bool IsSixAxisSensorAtRest() const; void SetSixAxisEnabled(bool six_axis_status); LedPattern GetLedPattern(u32 npad_id); + bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const; + void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id); void SetVibrationEnabled(bool can_vibrate); bool IsVibrationEnabled() const; void ClearAllConnectedControllers(); @@ -387,6 +389,7 @@ private: std::array styleset_changed_events; Vibration last_processed_vibration{}; std::array connected_controllers{}; + std::array unintended_home_button_input_protection{}; GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; bool can_controllers_vibrate{true}; bool sixaxis_sensors_enabled{true}; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 9a7e5e265..eaa7038d9 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -224,8 +224,8 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"}, {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, - {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, - {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, + {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"}, + {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, {134, nullptr, "SetNpadAnalogStickUseCenterClamp"}, {135, nullptr, "SetNpadCaptureButtonAssignment"}, @@ -796,6 +796,40 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { } } +void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto npad_id{rp.Pop()}; + const auto applet_resource_user_id{rp.Pop()}; + + LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id, + applet_resource_user_id); + + auto& controller = applet_resource->GetController(HidController::NPad); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(controller.IsUnintendedHomeButtonInputProtectionEnabled(npad_id)); +} + +void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto unintended_home_button_input_protection{rp.Pop()}; + const auto npad_id{rp.Pop()}; + const auto applet_resource_user_id{rp.Pop()}; + + LOG_WARNING(Service_HID, + "(STUBBED) called, unintended_home_button_input_protection={}, npad_id={}," + "applet_resource_user_id={}", + npad_id, unintended_home_button_input_protection, applet_resource_user_id); + + auto& controller = applet_resource->GetController(HidController::NPad); + controller.SetUnintendedHomeButtonInputProtectionEnabled( + unintended_home_button_input_protection, npad_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop()}; diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 3cfd72a51..820e101c7 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -122,6 +122,8 @@ private: void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); void SwapNpadAssignment(Kernel::HLERequestContext& ctx); + void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx); + void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx); void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); void SendVibrationValue(Kernel::HLERequestContext& ctx); -- cgit v1.2.3 From 9a251339dc5073fd579a319e618e263f3c030081 Mon Sep 17 00:00:00 2001 From: Morph Date: Wed, 30 Sep 2020 07:11:51 -0400 Subject: caps_su: Properly stub SetShimLibraryVersion --- src/core/hle/service/caps/caps_su.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp index fffb2ecf9..e386470f7 100644 --- a/src/core/hle/service/caps/caps_su.cpp +++ b/src/core/hle/service/caps/caps_su.cpp @@ -25,7 +25,12 @@ CAPS_SU::CAPS_SU() : ServiceFramework("caps:su") { CAPS_SU::~CAPS_SU() = default; void CAPS_SU::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Capture, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto library_version{rp.Pop()}; + const auto applet_resource_user_id{rp.Pop()}; + + LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", + library_version, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); -- cgit v1.2.3 From 7d287a6fb01114da166fcbc29e3c57f1df22da57 Mon Sep 17 00:00:00 2001 From: Morph Date: Wed, 30 Sep 2020 07:12:21 -0400 Subject: caps_u: Stub SetShimLibraryVersion - Used in Super Smash Bros. Ultimate --- src/core/hle/service/caps/caps_u.cpp | 15 +++++++++++++-- src/core/hle/service/caps/caps_u.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp index f36d8de2d..8e2b83629 100644 --- a/src/core/hle/service/caps/caps_u.cpp +++ b/src/core/hle/service/caps/caps_u.cpp @@ -31,8 +31,7 @@ public: CAPS_U::CAPS_U() : ServiceFramework("caps:u") { // clang-format off static const FunctionInfo functions[] = { - {31, nullptr, "GetShimLibraryVersion"}, - {32, nullptr, "SetShimLibraryVersion"}, + {32, &CAPS_U::SetShimLibraryVersion, "SetShimLibraryVersion"}, {102, &CAPS_U::GetAlbumContentsFileListForApplication, "GetAlbumContentsFileListForApplication"}, {103, nullptr, "DeleteAlbumContentsFileForApplication"}, {104, nullptr, "GetAlbumContentsFileSizeForApplication"}, @@ -53,6 +52,18 @@ CAPS_U::CAPS_U() : ServiceFramework("caps:u") { CAPS_U::~CAPS_U() = default; +void CAPS_U::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto library_version{rp.Pop()}; + const auto applet_resource_user_id{rp.Pop()}; + + LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", + library_version, applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + void CAPS_U::GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx) { // Takes a type-0x6 output buffer containing an array of ApplicationAlbumFileEntry, a PID, an // u8 ContentType, two s64s, and an u64 AppletResourceUserId. Returns an output u64 for total diff --git a/src/core/hle/service/caps/caps_u.h b/src/core/hle/service/caps/caps_u.h index 689364de4..e04e56bbc 100644 --- a/src/core/hle/service/caps/caps_u.h +++ b/src/core/hle/service/caps/caps_u.h @@ -18,6 +18,7 @@ public: ~CAPS_U() override; private: + void SetShimLibraryVersion(Kernel::HLERequestContext& ctx); void GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx); }; -- cgit v1.2.3 From 91bd2281bf7501804da488cabc5a557860f9aa38 Mon Sep 17 00:00:00 2001 From: Morph Date: Wed, 30 Sep 2020 07:13:39 -0400 Subject: caps_c: Stub SetShimLibraryVersion - Used by caps_su SetShimLibraryVersion --- src/core/hle/service/caps/caps_c.cpp | 16 +++++++++++++++- src/core/hle/service/caps/caps_c.h | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/hle/service/caps/caps_c.cpp b/src/core/hle/service/caps/caps_c.cpp index ab17a187e..a0ee116fa 100644 --- a/src/core/hle/service/caps/caps_c.cpp +++ b/src/core/hle/service/caps/caps_c.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" #include "core/hle/service/caps/caps_c.h" namespace Service::Capture { @@ -47,7 +49,7 @@ CAPS_C::CAPS_C() : ServiceFramework("caps:c") { static const FunctionInfo functions[] = { {1, nullptr, "CaptureRawImage"}, {2, nullptr, "CaptureRawImageWithTimeout"}, - {33, nullptr, "Unknown33"}, + {33, &CAPS_C::SetShimLibraryVersion, "SetShimLibraryVersion"}, {1001, nullptr, "RequestTakingScreenShot"}, {1002, nullptr, "RequestTakingScreenShotWithTimeout"}, {1011, nullptr, "NotifyTakingScreenShotRefused"}, @@ -72,4 +74,16 @@ CAPS_C::CAPS_C() : ServiceFramework("caps:c") { CAPS_C::~CAPS_C() = default; +void CAPS_C::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto library_version{rp.Pop()}; + const auto applet_resource_user_id{rp.Pop()}; + + LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", + library_version, applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + } // namespace Service::Capture diff --git a/src/core/hle/service/caps/caps_c.h b/src/core/hle/service/caps/caps_c.h index a9d028689..b110301d4 100644 --- a/src/core/hle/service/caps/caps_c.h +++ b/src/core/hle/service/caps/caps_c.h @@ -16,6 +16,9 @@ class CAPS_C final : public ServiceFramework { public: explicit CAPS_C(); ~CAPS_C() override; + +private: + void SetShimLibraryVersion(Kernel::HLERequestContext& ctx); }; } // namespace Service::Capture -- cgit v1.2.3 From 283616dbd8e7af7440156da2be0b2e8047a87936 Mon Sep 17 00:00:00 2001 From: german Date: Tue, 29 Sep 2020 19:37:22 -0500 Subject: Stubbed EnableSixAxisSensorFusion --- src/core/hle/service/hid/hid.cpp | 15 ++++++++++++++- src/core/hle/service/hid/hid.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 395e83b3f..6bb79622d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -173,7 +173,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"}, {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"}, {68, nullptr, "IsSixAxisSensorFusionEnabled"}, - {69, nullptr, "EnableSixAxisSensorFusion"}, + {69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"}, {70, nullptr, "SetSixAxisSensorFusionParameters"}, {71, nullptr, "GetSixAxisSensorFusionParameters"}, {72, nullptr, "ResetSixAxisSensorFusionParameters"}, @@ -458,6 +458,19 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } +void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto enable{rp.Pop()}; + const auto handle{rp.Pop()}; + const auto applet_resource_user_id{rp.Pop()}; + + LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle, + applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto handle{rp.Pop()}; diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index e04aaf1e9..b7f6f4aa4 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -97,6 +97,7 @@ private: void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx); void StartSixAxisSensor(Kernel::HLERequestContext& ctx); void StopSixAxisSensor(Kernel::HLERequestContext& ctx); + void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx); void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); -- cgit v1.2.3 From 2f47b2765408aaa0d6617c3afc298dd1da92014e Mon Sep 17 00:00:00 2001 From: german Date: Thu, 1 Oct 2020 19:39:53 -0500 Subject: Only use inputs corresponding to controller type --- src/core/hle/service/hid/controllers/npad.cpp | 107 ++++++++++++++------------ 1 file changed, 58 insertions(+), 49 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index fb007767d..a03af8df4 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -260,7 +260,7 @@ void Controller_NPad::OnRelease() {} void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { const auto controller_idx = NPadIdToIndex(npad_id); - [[maybe_unused]] const auto controller_type = connected_controllers[controller_idx].type; + const auto controller_type = connected_controllers[controller_idx].type; if (!connected_controllers[controller_idx].is_connected) { return; } @@ -276,54 +276,63 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { analog_state[static_cast(JoystickId::Joystick_Right)]->GetStatus(); using namespace Settings::NativeButton; - pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.l_stick_right.Assign( - analog_state[static_cast(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( - Input::AnalogDirection::RIGHT)); - pad_state.l_stick_left.Assign( - analog_state[static_cast(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( - Input::AnalogDirection::LEFT)); - pad_state.l_stick_up.Assign( - analog_state[static_cast(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( - Input::AnalogDirection::UP)); - pad_state.l_stick_down.Assign( - analog_state[static_cast(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( - Input::AnalogDirection::DOWN)); - - pad_state.r_stick_right.Assign( - analog_state[static_cast(JoystickId::Joystick_Right)] - ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT)); - pad_state.r_stick_left.Assign(analog_state[static_cast(JoystickId::Joystick_Right)] - ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT)); - pad_state.r_stick_up.Assign(analog_state[static_cast(JoystickId::Joystick_Right)] - ->GetAnalogDirectionStatus(Input::AnalogDirection::UP)); - pad_state.r_stick_down.Assign(analog_state[static_cast(JoystickId::Joystick_Right)] - ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN)); - - pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); - - lstick_entry.x = static_cast(stick_l_x_f * HID_JOYSTICK_MAX); - lstick_entry.y = static_cast(stick_l_y_f * HID_JOYSTICK_MAX); - rstick_entry.x = static_cast(stick_r_x_f * HID_JOYSTICK_MAX); - rstick_entry.y = static_cast(stick_r_y_f * HID_JOYSTICK_MAX); + if (controller_type != NPadControllerType::JoyLeft) { + pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.r_stick_right.Assign( + analog_state[static_cast(JoystickId::Joystick_Right)] + ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT)); + pad_state.r_stick_left.Assign( + analog_state[static_cast(JoystickId::Joystick_Right)] + ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT)); + pad_state.r_stick_up.Assign( + analog_state[static_cast(JoystickId::Joystick_Right)] + ->GetAnalogDirectionStatus(Input::AnalogDirection::UP)); + pad_state.r_stick_down.Assign( + analog_state[static_cast(JoystickId::Joystick_Right)] + ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN)); + rstick_entry.x = static_cast(stick_r_x_f * HID_JOYSTICK_MAX); + rstick_entry.y = static_cast(stick_r_y_f * HID_JOYSTICK_MAX); + } + + if (controller_type != NPadControllerType::JoyRight) { + pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.l_stick_right.Assign( + analog_state[static_cast(JoystickId::Joystick_Left)] + ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT)); + pad_state.l_stick_left.Assign( + analog_state[static_cast(JoystickId::Joystick_Left)] + ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT)); + pad_state.l_stick_up.Assign( + analog_state[static_cast(JoystickId::Joystick_Left)] + ->GetAnalogDirectionStatus(Input::AnalogDirection::UP)); + pad_state.l_stick_down.Assign( + analog_state[static_cast(JoystickId::Joystick_Left)] + ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN)); + lstick_entry.x = static_cast(stick_l_x_f * HID_JOYSTICK_MAX); + lstick_entry.y = static_cast(stick_l_y_f * HID_JOYSTICK_MAX); + } + + if (controller_type == NPadControllerType::JoyLeft || + controller_type == NPadControllerType::JoyRight) { + pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); + } } void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, -- cgit v1.2.3 From b2608472181e07eccb642c444dbbfadca9dc1bc2 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 12 Oct 2020 17:36:52 -0700 Subject: hle: service: nvdrv: Implement nvhost_as_gpu::FreeSpace. - This is used by Super Mario 3D All-Stars. --- src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 16 ++++++++++++++++ src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | 9 +++++++++ 2 files changed, 25 insertions(+) (limited to 'src/core') 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 39bd2a45b..f2529a12e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -46,6 +46,8 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector& input, const std: return GetVARegions(input, output); case IoctlCommand::IocUnmapBufferCommand: return UnmapBuffer(input, output); + case IoctlCommand::IocFreeSpaceCommand: + return FreeSpace(input, output); default: break; } @@ -91,6 +93,20 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector& input, std::vector& return result; } +u32 nvhost_as_gpu::FreeSpace(const std::vector& input, std::vector& output) { + IoctlFreeSpace params{}; + std::memcpy(¶ms, input.data(), input.size()); + + LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset, + params.pages, params.page_size); + + system.GPU().MemoryManager().Unmap(params.offset, + static_cast(params.pages) * params.page_size); + + std::memcpy(output.data(), ¶ms, output.size()); + return NvErrCodes::Success; +} + u32 nvhost_as_gpu::Remap(const std::vector& input, std::vector& output) { const auto num_entries = input.size() / sizeof(IoctlRemapEntry); 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 9a0cdff0c..fcdb40d93 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -82,6 +82,7 @@ private: IocBindChannelCommand = 0x40044101, IocGetVaRegionsCommand = 0xC0404108, IocUnmapBufferCommand = 0xC0084105, + IocFreeSpaceCommand = 0xC0104103, }; struct IoctlInitalizeEx { @@ -107,6 +108,13 @@ private: }; static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size"); + struct IoctlFreeSpace { + u64_le offset; + u32_le pages; + u32_le page_size; + }; + static_assert(sizeof(IoctlFreeSpace) == 16, "IoctlFreeSpace is incorrect size"); + struct IoctlRemapEntry { u16_le flags; u16_le kind; @@ -162,6 +170,7 @@ private: u32 Remap(const std::vector& input, std::vector& output); u32 MapBufferEx(const std::vector& input, std::vector& output); u32 UnmapBuffer(const std::vector& input, std::vector& output); + u32 FreeSpace(const std::vector& input, std::vector& output); u32 BindChannel(const std::vector& input, std::vector& output); u32 GetVARegions(const std::vector& input, std::vector& output); -- cgit v1.2.3 From 62c6c9f6a6dbc44de5fa8e03187fb34037958d5f Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 12 Oct 2020 18:09:15 -0700 Subject: service: time: Update current time with changes to RTC setting. - This can be used to advance time, e.g. for Pokemon Sword/Shield pokejobs. --- src/core/core.cpp | 15 +- src/core/core.h | 8 + src/core/hle/service/time/time.cpp | 28 +- src/core/hle/service/time/time.h | 9 +- src/core/hle/service/time/time_manager.cpp | 359 +++++++++++++++------ src/core/hle/service/time/time_manager.h | 85 ++--- .../hle/service/time/time_zone_content_manager.cpp | 5 +- .../hle/service/time/time_zone_content_manager.h | 4 +- 8 files changed, 324 insertions(+), 189 deletions(-) (limited to 'src/core') diff --git a/src/core/core.cpp b/src/core/core.cpp index 81e8cc338..fde2ccc09 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -40,6 +40,7 @@ #include "core/hle/service/lm/manager.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" +#include "core/hle/service/time/time_manager.h" #include "core/loader/loader.h" #include "core/memory.h" #include "core/memory/cheat_engine.h" @@ -121,7 +122,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, struct System::Impl { explicit Impl(System& system) : kernel{system}, fs_controller{system}, memory{system}, - cpu_manager{system}, reporter{system}, applet_manager{system} {} + cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {} ResultStatus Run() { status = ResultStatus::Success; @@ -189,6 +190,9 @@ struct System::Impl { return ResultStatus::ErrorVideoCore; } + // Initialize time manager, which must happen after kernel is created + time_manager.Initialize(); + is_powered_on = true; exit_lock = false; @@ -387,6 +391,7 @@ struct System::Impl { /// Service State Service::Glue::ARPManager arp_manager; Service::LM::Manager lm_manager{reporter}; + Service::Time::TimeManager time_manager; /// Service manager std::shared_ptr service_manager; @@ -717,6 +722,14 @@ const Service::LM::Manager& System::GetLogManager() const { return impl->lm_manager; } +Service::Time::TimeManager& System::GetTimeManager() { + return impl->time_manager; +} + +const Service::Time::TimeManager& System::GetTimeManager() const { + return impl->time_manager; +} + void System::SetExitLock(bool locked) { impl->exit_lock = locked; } diff --git a/src/core/core.h b/src/core/core.h index 27efe30bb..6db896bae 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -69,6 +69,10 @@ namespace SM { class ServiceManager; } // namespace SM +namespace Time { +class TimeManager; +} // namespace Time + } // namespace Service namespace Tegra { @@ -361,6 +365,10 @@ public: const Service::LM::Manager& GetLogManager() const; + Service::Time::TimeManager& GetTimeManager(); + + const Service::Time::TimeManager& GetTimeManager() const; + void SetExitLock(bool locked); bool GetExitLock() const; diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index ee4fa4b48..7d0474e0b 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -10,6 +10,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/scheduler.h" #include "core/hle/service/time/interface.h" #include "core/hle/service/time/time.h" @@ -125,7 +126,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( Kernel::Thread* thread, Clock::SystemClockContext user_context, Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) { - auto& time_manager{module->GetTimeManager()}; + auto& time_manager{system.GetTimeManager()}; clock_snapshot.is_automatic_correction_enabled = time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); @@ -182,7 +183,7 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface(module->GetTimeManager().GetStandardUserSystemClockCore(), + rb.PushIpcInterface(system.GetTimeManager().GetStandardUserSystemClockCore(), system); } @@ -190,7 +191,7 @@ void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface(module->GetTimeManager().GetStandardNetworkSystemClockCore(), + rb.PushIpcInterface(system.GetTimeManager().GetStandardNetworkSystemClockCore(), system); } @@ -198,29 +199,28 @@ void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface(module->GetTimeManager().GetStandardSteadyClockCore(), - system); + rb.PushIpcInterface(system.GetTimeManager().GetStandardSteadyClockCore(), system); } void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface(module->GetTimeManager().GetTimeZoneContentManager()); + rb.PushIpcInterface(system.GetTimeManager().GetTimeZoneContentManager()); } void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface(module->GetTimeManager().GetStandardLocalSystemClockCore(), + rb.PushIpcInterface(system.GetTimeManager().GetStandardLocalSystemClockCore(), system); } void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); - auto& clock_core{module->GetTimeManager().GetStandardNetworkSystemClockCore()}; + auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()}; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system)); @@ -229,7 +229,7 @@ void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); - auto& steady_clock_core{module->GetTimeManager().GetStandardSteadyClockCore()}; + auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()}; if (!steady_clock_core.IsInitialized()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ERROR_UNINITIALIZED_CLOCK); @@ -262,8 +262,8 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { Clock::SystemClockContext user_context{}; if (const ResultCode result{ - module->GetTimeManager().GetStandardUserSystemClockCore().GetClockContext( - system, user_context)}; + system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system, + user_context)}; result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -271,7 +271,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { } Clock::SystemClockContext network_context{}; if (const ResultCode result{ - module->GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( + system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( system, network_context)}; result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; @@ -372,7 +372,7 @@ void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& c LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(module->GetTimeManager().GetSharedMemory().GetSharedMemoryHolder()); + rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem())); } Module::Interface::Interface(std::shared_ptr module, Core::System& system, const char* name) @@ -381,7 +381,7 @@ Module::Interface::Interface(std::shared_ptr module, Core::System& syste Module::Interface::~Interface() = default; void InstallInterfaces(Core::System& system) { - auto module{std::make_shared(system)}; + auto module{std::make_shared()}; std::make_shared