From b178c9a3492ea6c0db63f708beecd3dfb3d921fe Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 15 Apr 2020 22:10:40 -0400 Subject: decoder/image: Fix incorrect G24R8 component sizes in GetComponentSize() The components' sizes were mismatched. This corrects that. --- src/video_core/shader/decode/image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 0dd7a1196..7f94dacc8 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -201,10 +201,10 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { return 0; case TextureFormat::G24R8: if (component == 0) { - return 8; + return 24; } if (component == 1) { - return 24; + return 8; } return 0; case TextureFormat::G8R8: -- cgit v1.2.3 From 24620bc4ea9ca59a757b7f07ca912f6645c5b8ef Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 15 Apr 2020 22:26:47 -0400 Subject: decode/image: Fix typo in assert in GetComponentSize() --- src/video_core/shader/decode/image.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 7f94dacc8..08ebca38b 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -119,7 +119,7 @@ ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor, } break; } - UNIMPLEMENTED_MSG("texture format not implement={}", format); + UNIMPLEMENTED_MSG("Texture format not implemented={}", format); return ComponentType::FLOAT; } @@ -212,7 +212,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { case TextureFormat::G4R4: return (component == 0 || component == 1) ? 4 : 0; default: - UNIMPLEMENTED_MSG("texture format not implement={}", format); + UNIMPLEMENTED_MSG("Texture format not implemented={}", format); return 0; } } @@ -249,7 +249,7 @@ std::size_t GetImageComponentMask(TextureFormat format) { case TextureFormat::R1: return std::size_t{R}; default: - UNIMPLEMENTED_MSG("texture format not implement={}", format); + UNIMPLEMENTED_MSG("Texture format not implemented={}", format); return std::size_t{R | G | B | A}; } } -- cgit v1.2.3 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') 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') 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') 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 29a0ca23918092d252f440b2f55f68bb3c991366 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 29 Jun 2020 02:34:17 -0300 Subject: renderer_vulkan: Create a Vulkan 1.0 instance when 1.1 is not available This commit doesn't make yuzu compatible with Vulkan 1.0 yet, it only creates an 1.0 instance. --- src/video_core/renderer_vulkan/renderer_vulkan.cpp | 5 ++++- src/video_core/renderer_vulkan/wrapper.cpp | 23 ++++++++++++++++++---- src/video_core/renderer_vulkan/wrapper.h | 4 +++- 3 files changed, 26 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 6e49699d0..6f9eadbeb 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -180,7 +180,10 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc } } - vk::Instance instance = vk::Instance::Create(layers, extensions, dld); + // Limit the maximum version of Vulkan to avoid using untested version. + const u32 version = std::min(vk::AvailableVersion(dld), static_cast(VK_API_VERSION_1_1)); + + vk::Instance instance = vk::Instance::Create(version, layers, extensions, dld); if (!instance) { LOG_ERROR(Render_Vulkan, "Failed to create Vulkan instance"); return {}; diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp index 013865aa4..56055af1b 100644 --- a/src/video_core/renderer_vulkan/wrapper.cpp +++ b/src/video_core/renderer_vulkan/wrapper.cpp @@ -10,6 +10,7 @@ #include #include "common/common_types.h" +#include "common/logging/log.h" #include "video_core/renderer_vulkan/wrapper.h" @@ -375,18 +376,17 @@ VkResult Free(VkDevice device, VkCommandPool handle, Span buffe return VK_SUCCESS; } -Instance Instance::Create(Span layers, Span extensions, +Instance Instance::Create(u32 version, Span layers, Span extensions, InstanceDispatch& dld) noexcept { - static constexpr VkApplicationInfo application_info{ + const VkApplicationInfo application_info{ .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .pNext = nullptr, .pApplicationName = "yuzu Emulator", .applicationVersion = VK_MAKE_VERSION(0, 1, 0), .pEngineName = "yuzu Emulator", .engineVersion = VK_MAKE_VERSION(0, 1, 0), - .apiVersion = VK_API_VERSION_1_1, + .apiVersion = version, }; - const VkInstanceCreateInfo ci{ .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pNext = nullptr, @@ -775,6 +775,21 @@ VkPhysicalDeviceMemoryProperties PhysicalDevice::GetMemoryProperties() const noe return properties; } +u32 AvailableVersion(const InstanceDispatch& dld) noexcept { + PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion; + if (!Proc(vkEnumerateInstanceVersion, dld, "vkEnumerateInstanceVersion")) { + // If the procedure is not found, Vulkan 1.0 is assumed + return VK_API_VERSION_1_0; + } + u32 version; + if (const VkResult result = vkEnumerateInstanceVersion(&version); result != VK_SUCCESS) { + LOG_ERROR(Render_Vulkan, "vkEnumerateInstanceVersion returned {}, assuming Vulkan 1.1", + ToString(result)); + return VK_API_VERSION_1_1; + } + return version; +} + std::optional> EnumerateInstanceExtensionProperties( const InstanceDispatch& dld) { u32 num; diff --git a/src/video_core/renderer_vulkan/wrapper.h b/src/video_core/renderer_vulkan/wrapper.h index b9d3fedc1..748a94d2f 100644 --- a/src/video_core/renderer_vulkan/wrapper.h +++ b/src/video_core/renderer_vulkan/wrapper.h @@ -563,7 +563,7 @@ class Instance : public Handle { public: /// Creates a Vulkan instance. Use "operator bool" for error handling. - static Instance Create(Span layers, Span extensions, + static Instance Create(u32 version, Span layers, Span extensions, InstanceDispatch& dld) noexcept; /// Enumerates physical devices. @@ -1048,6 +1048,8 @@ private: const DeviceDispatch* dld; }; +u32 AvailableVersion(const InstanceDispatch& dld) noexcept; + std::optional> EnumerateInstanceExtensionProperties( const InstanceDispatch& dld); -- cgit v1.2.3 From c5a78f4480369ad6325c51549509361c10d2cea5 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 29 Jun 2020 02:48:29 -0300 Subject: vk_device: Use Vulkan 1.0 properly Enable the required capabilities to use Vulkan 1.0 without validation errors and disable those that are not compatible with it. --- src/video_core/renderer_vulkan/renderer_vulkan.cpp | 19 +++--- src/video_core/renderer_vulkan/renderer_vulkan.h | 2 + src/video_core/renderer_vulkan/vk_device.cpp | 73 +++++++++++----------- src/video_core/renderer_vulkan/vk_device.h | 12 +++- .../renderer_vulkan/vk_shader_decompiler.cpp | 12 +++- 5 files changed, 66 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 6f9eadbeb..7ffc90cd0 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -92,9 +92,9 @@ Common::DynamicLibrary OpenVulkanLibrary() { return library; } -vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatch& dld, - WindowSystemType window_type = WindowSystemType::Headless, - bool enable_layers = false) { +std::pair CreateInstance( + Common::DynamicLibrary& library, vk::InstanceDispatch& dld, + WindowSystemType window_type = WindowSystemType::Headless, bool enable_layers = false) { if (!library.IsOpen()) { LOG_ERROR(Render_Vulkan, "Vulkan library not available"); return {}; @@ -191,7 +191,7 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc if (!vk::Load(*instance, dld)) { LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers"); } - return instance; + return std::make_pair(std::move(instance), version); } std::string GetReadableVersion(u32 version) { @@ -289,8 +289,8 @@ bool RendererVulkan::TryPresent(int /*timeout_ms*/) { bool RendererVulkan::Init() { library = OpenVulkanLibrary(); - instance = CreateInstance(library, dld, render_window.GetWindowInfo().type, - Settings::values.renderer_debug); + std::tie(instance, instance_version) = CreateInstance( + library, dld, render_window.GetWindowInfo().type, Settings::values.renderer_debug); if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) { return false; } @@ -423,7 +423,8 @@ bool RendererVulkan::PickDevices() { return false; } - device = std::make_unique(*instance, physical_device, *surface, dld); + device = + std::make_unique(*instance, instance_version, physical_device, *surface, dld); return device->Create(); } @@ -433,7 +434,7 @@ void RendererVulkan::Report() const { const std::string driver_version = GetDriverVersion(*device); const std::string driver_name = fmt::format("{} {}", vendor_name, driver_version); - const std::string api_version = GetReadableVersion(device->GetApiVersion()); + const std::string api_version = GetReadableVersion(device->ApiVersion()); const std::string extensions = BuildCommaSeparatedExtensions(device->GetAvailableExtensions()); @@ -453,7 +454,7 @@ void RendererVulkan::Report() const { std::vector RendererVulkan::EnumerateDevices() { vk::InstanceDispatch dld; Common::DynamicLibrary library = OpenVulkanLibrary(); - vk::Instance instance = CreateInstance(library, dld); + vk::Instance instance = CreateInstance(library, dld).first; if (!instance) { return {}; } diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 522b5bff8..9617a93e9 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -63,6 +63,8 @@ private: vk::InstanceDispatch dld; vk::Instance instance; + u32 instance_version{}; + vk::SurfaceKHR surface; VKScreenInfo screen_info; diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp index ebcfaa0e3..90916ee0e 100644 --- a/src/video_core/renderer_vulkan/vk_device.cpp +++ b/src/video_core/renderer_vulkan/vk_device.cpp @@ -38,6 +38,9 @@ constexpr std::array Depth16UnormS8_UINT{ constexpr std::array REQUIRED_EXTENSIONS{ VK_KHR_SWAPCHAIN_EXTENSION_NAME, + VK_KHR_MAINTENANCE1_EXTENSION_NAME, + VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, + VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_16BIT_STORAGE_EXTENSION_NAME, VK_KHR_8BIT_STORAGE_EXTENSION_NAME, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, @@ -171,10 +174,10 @@ std::unordered_map GetFormatProperties( } // Anonymous namespace -VKDevice::VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface, - const vk::InstanceDispatch& dld) - : dld{dld}, physical{physical}, properties{physical.GetProperties()}, - format_properties{GetFormatProperties(physical, dld)} { +VKDevice::VKDevice(VkInstance instance_, u32 instance_version_, vk::PhysicalDevice physical_, + VkSurfaceKHR surface, const vk::InstanceDispatch& dld_) + : dld{dld_}, physical{physical_}, properties{physical.GetProperties()}, + instance_version{instance_version_}, format_properties{GetFormatProperties(physical, dld)} { SetupFamilies(surface); SetupFeatures(); } @@ -565,20 +568,6 @@ bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) { std::vector VKDevice::LoadExtensions() { std::vector extensions; - const auto Test = [&](const VkExtensionProperties& extension, - std::optional> status, const char* name, - bool push) { - if (extension.extensionName != std::string_view(name)) { - return; - } - if (push) { - extensions.push_back(name); - } - if (status) { - status->get() = true; - } - }; - extensions.reserve(7 + REQUIRED_EXTENSIONS.size()); extensions.insert(extensions.begin(), REQUIRED_EXTENSIONS.begin(), REQUIRED_EXTENSIONS.end()); @@ -587,28 +576,36 @@ std::vector VKDevice::LoadExtensions() { bool has_ext_transform_feedback{}; bool has_ext_custom_border_color{}; bool has_ext_extended_dynamic_state{}; - for (const auto& extension : physical.EnumerateDeviceExtensionProperties()) { - Test(extension, nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true); - Test(extension, khr_uniform_buffer_standard_layout, + for (const VkExtensionProperties& extension : physical.EnumerateDeviceExtensionProperties()) { + const auto test = [&](std::optional> status, const char* name, + bool push) { + if (extension.extensionName != std::string_view(name)) { + return; + } + if (push) { + extensions.push_back(name); + } + if (status) { + status->get() = true; + } + }; + test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true); + test(khr_uniform_buffer_standard_layout, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); - Test(extension, has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, - false); - Test(extension, ext_depth_range_unrestricted, - VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); - Test(extension, ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); - Test(extension, ext_shader_viewport_index_layer, - VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, true); - Test(extension, has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, - false); - Test(extension, has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, - false); - Test(extension, has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, - false); - Test(extension, has_ext_extended_dynamic_state, - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); + test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); + test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); + test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); + test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, + true); + test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false); + test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false); + test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); + if (instance_version >= VK_API_VERSION_1_1) { + test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false); + } if (Settings::values.renderer_debug) { - Test(extension, nv_device_diagnostics_config, - VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, true); + test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, + true); } } diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h index 26a233db1..4286673d9 100644 --- a/src/video_core/renderer_vulkan/vk_device.h +++ b/src/video_core/renderer_vulkan/vk_device.h @@ -24,8 +24,8 @@ const u32 GuestWarpSize = 32; /// Handles data specific to a physical device. class VKDevice final { public: - explicit VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface, - const vk::InstanceDispatch& dld); + explicit VKDevice(VkInstance instance, u32 instance_version, vk::PhysicalDevice physical, + VkSurfaceKHR surface, const vk::InstanceDispatch& dld); ~VKDevice(); /// Initializes the device. Returns true on success. @@ -82,8 +82,13 @@ public: return present_family; } + /// Returns the current instance Vulkan API version in Vulkan-formatted version numbers. + u32 InstanceApiVersion() const { + return instance_version; + } + /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers. - u32 GetApiVersion() const { + u32 ApiVersion() const { return properties.apiVersion; } @@ -239,6 +244,7 @@ private: vk::Device logical; ///< Logical device. vk::Queue graphics_queue; ///< Main graphics queue. vk::Queue present_queue; ///< Main present queue. + u32 instance_version{}; ///< Vulkan onstance version. u32 graphics_family{}; ///< Main graphics queue family index. u32 present_family{}; ///< Main present queue family index. VkDriverIdKHR driver_id{}; ///< Driver ID. diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index cd7d7a4e4..a20452b87 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp @@ -272,12 +272,19 @@ bool IsPrecise(Operation operand) { return false; } +u32 ShaderVersion(const VKDevice& device) { + if (device.InstanceApiVersion() < VK_API_VERSION_1_1) { + return 0x00010000; + } + return 0x00010300; +} + class SPIRVDecompiler final : public Sirit::Module { public: explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage, const Registry& registry, const Specialization& specialization) - : Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()}, - registry{registry}, specialization{specialization} { + : Module(ShaderVersion(device)), device{device}, ir{ir}, stage{stage}, + header{ir.GetHeader()}, registry{registry}, specialization{specialization} { if (stage != ShaderType::Compute) { transform_feedback = BuildTransformFeedback(registry.GetGraphicsInfo()); } @@ -293,6 +300,7 @@ public: AddCapability(spv::Capability::DrawParameters); AddCapability(spv::Capability::SubgroupBallotKHR); AddCapability(spv::Capability::SubgroupVoteKHR); + AddExtension("SPV_KHR_16bit_storage"); AddExtension("SPV_KHR_shader_ballot"); AddExtension("SPV_KHR_subgroup_vote"); AddExtension("SPV_KHR_storage_buffer_storage_class"); -- 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/common/logging/backend.cpp | 14 +++++++-- src/core/settings.h | 1 + src/yuzu/configuration/config.cpp | 2 ++ src/yuzu/configuration/configure_debug.cpp | 2 ++ src/yuzu/configuration/configure_debug.ui | 46 ++++++++++++++++++++++++------ 5 files changed, 54 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 62cfde397..fdb2e52fa 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -23,6 +23,7 @@ #include "common/logging/text_formatter.h" #include "common/string_util.h" #include "common/threadsafe_queue.h" +#include "core/settings.h" namespace Log { @@ -152,10 +153,19 @@ FileBackend::FileBackend(const std::string& filename) void FileBackend::Write(const Entry& entry) { // prevent logs from going over the maximum size (in case its spamming and the user doesn't // know) - constexpr std::size_t MAX_BYTES_WRITTEN = 50 * 1024L * 1024L; - if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) { + constexpr std::size_t MAX_BYTES_WRITTEN = 100 * 1024 * 1024; + constexpr std::size_t MAX_BYTES_WRITTEN_EXTENDED = 1024 * 1024 * 1024; + + if (!file.IsOpen()) { + return; + } + + if (Settings::values.extended_logging && bytes_written > MAX_BYTES_WRITTEN_EXTENDED) { + return; + } else if (!Settings::values.extended_logging && bytes_written > MAX_BYTES_WRITTEN) { return; } + bytes_written += file.WriteString(FormatLogMessage(entry).append(1, '\n')); if (entry.log_level >= Level::Error) { file.Flush(); 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; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 7af974d8d..1d4816d34 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -523,6 +523,8 @@ void Config::ReadDebuggingValues() { Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool(); Settings::values.disable_macro_jit = ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool(); + Settings::values.extended_logging = + ReadSetting(QStringLiteral("extended_logging"), false).toBool(); qt_config->endGroup(); } diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 2bfe2c306..027099ab7 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -41,6 +41,7 @@ void ConfigureDebug::SetConfiguration() { ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit); + ui->extended_logging->setChecked(Settings::values.extended_logging); } void ConfigureDebug::ApplyConfiguration() { @@ -53,6 +54,7 @@ void ConfigureDebug::ApplyConfiguration() { Settings::values.quest_flag = ui->quest_flag->isChecked(); Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); + Settings::values.extended_logging = ui->extended_logging->isChecked(); Debugger::ToggleConsole(); Log::Filter filter; filter.ParseFilterString(Settings::values.log_filter); diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 9d6feb9f7..6f94fe304 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -90,7 +90,7 @@ - Show Log Console (Windows Only) + Show Log in Console @@ -103,6 +103,34 @@ + + + + true + + + When checked, the max size of the log increases from 100 MB to 1 GB + + + Enable Extended Logging + + + + + + + + true + + + + This will be reset automatically when yuzu closes. + + + 20 + + + @@ -115,7 +143,7 @@ - + Arguments String @@ -140,8 +168,8 @@ true - - When checked, the graphics API enters in a slower debugging mode + + When checked, the graphics API enters a slower debugging mode Enable Graphics Debugging @@ -153,8 +181,8 @@ true - - When checked, it disables the macro Just In Time compiler. Enabled this makes games run slower + + When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower Disable Macro JIT @@ -169,7 +197,7 @@ Dump - + @@ -178,7 +206,7 @@ - + true @@ -200,7 +228,7 @@ Advanced - + -- cgit v1.2.3 From ffeb4ef83e731bb54a82080749ca22a263466788 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 23 Sep 2020 15:06:21 -0400 Subject: shader/registry: Make use of designated initializers where applicable Same behavior, less repetition. --- src/video_core/shader/registry.cpp | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/video_core/shader/registry.cpp b/src/video_core/shader/registry.cpp index cdf274e54..de9a3df90 100644 --- a/src/video_core/shader/registry.cpp +++ b/src/video_core/shader/registry.cpp @@ -24,31 +24,33 @@ GraphicsInfo MakeGraphicsInfo(ShaderType shader_stage, ConstBufferEngineInterfac if (shader_stage == ShaderType::Compute) { return {}; } - auto& graphics = static_cast(engine); - - GraphicsInfo info; - info.tfb_layouts = graphics.regs.tfb_layouts; - info.tfb_varying_locs = graphics.regs.tfb_varying_locs; - info.primitive_topology = graphics.regs.draw.topology; - info.tessellation_primitive = graphics.regs.tess_mode.prim; - info.tessellation_spacing = graphics.regs.tess_mode.spacing; - info.tfb_enabled = graphics.regs.tfb_enabled; - info.tessellation_clockwise = graphics.regs.tess_mode.cw; - return info; + + auto& graphics = dynamic_cast(engine); + + return { + .tfb_layouts = graphics.regs.tfb_layouts, + .tfb_varying_locs = graphics.regs.tfb_varying_locs, + .primitive_topology = graphics.regs.draw.topology, + .tessellation_primitive = graphics.regs.tess_mode.prim, + .tessellation_spacing = graphics.regs.tess_mode.spacing, + .tfb_enabled = graphics.regs.tfb_enabled != 0, + .tessellation_clockwise = graphics.regs.tess_mode.cw.Value() != 0, + }; } ComputeInfo MakeComputeInfo(ShaderType shader_stage, ConstBufferEngineInterface& engine) { if (shader_stage != ShaderType::Compute) { return {}; } - auto& compute = static_cast(engine); + + auto& compute = dynamic_cast(engine); const auto& launch = compute.launch_description; - ComputeInfo info; - info.workgroup_size = {launch.block_dim_x, launch.block_dim_y, launch.block_dim_z}; - info.local_memory_size_in_words = launch.local_pos_alloc; - info.shared_memory_size_in_words = launch.shared_alloc; - return info; + return { + .workgroup_size = {launch.block_dim_x, launch.block_dim_y, launch.block_dim_z}, + .shared_memory_size_in_words = launch.shared_alloc, + .local_memory_size_in_words = launch.local_pos_alloc, + }; } } // Anonymous namespace -- cgit v1.2.3 From cd6f4f7eed24d8562fbc8daec424e5a816ce6233 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 23 Sep 2020 15:08:31 -0400 Subject: shader/registry: Remove unnecessary namespace qualifiers Using statements already make these unnecessary. --- src/video_core/shader/registry.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/video_core/shader/registry.cpp b/src/video_core/shader/registry.cpp index de9a3df90..3cf922002 100644 --- a/src/video_core/shader/registry.cpp +++ b/src/video_core/shader/registry.cpp @@ -55,12 +55,11 @@ ComputeInfo MakeComputeInfo(ShaderType shader_stage, ConstBufferEngineInterface& } // Anonymous namespace -Registry::Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info) +Registry::Registry(ShaderType shader_stage, const SerializedRegistryInfo& info) : stage{shader_stage}, stored_guest_driver_profile{info.guest_driver_profile}, bound_buffer{info.bound_buffer}, graphics_info{info.graphics}, compute_info{info.compute} {} -Registry::Registry(Tegra::Engines::ShaderType shader_stage, - Tegra::Engines::ConstBufferEngineInterface& engine) +Registry::Registry(ShaderType shader_stage, ConstBufferEngineInterface& engine) : stage{shader_stage}, engine{&engine}, bound_buffer{engine.GetBoundBuffer()}, graphics_info{MakeGraphicsInfo(shader_stage, engine)}, compute_info{MakeComputeInfo( shader_stage, engine)} {} @@ -115,8 +114,7 @@ std::optional Registry::ObtainSeparateSampler return value; } -std::optional Registry::ObtainBindlessSampler(u32 buffer, - u32 offset) { +std::optional Registry::ObtainBindlessSampler(u32 buffer, u32 offset) { const std::pair key = {buffer, offset}; const auto iter = bindless_samplers.find(key); if (iter != bindless_samplers.end()) { -- cgit v1.2.3 From 77532ebde3be78aa9a5471c496784d0151453289 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 23 Sep 2020 15:10:25 -0400 Subject: shader/registry: Silence a -Wshadow warning --- src/video_core/shader/registry.cpp | 8 ++++---- src/video_core/shader/registry.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/video_core/shader/registry.cpp b/src/video_core/shader/registry.cpp index 3cf922002..148d91fcb 100644 --- a/src/video_core/shader/registry.cpp +++ b/src/video_core/shader/registry.cpp @@ -59,10 +59,10 @@ Registry::Registry(ShaderType shader_stage, const SerializedRegistryInfo& info) : stage{shader_stage}, stored_guest_driver_profile{info.guest_driver_profile}, bound_buffer{info.bound_buffer}, graphics_info{info.graphics}, compute_info{info.compute} {} -Registry::Registry(ShaderType shader_stage, ConstBufferEngineInterface& engine) - : stage{shader_stage}, engine{&engine}, bound_buffer{engine.GetBoundBuffer()}, - graphics_info{MakeGraphicsInfo(shader_stage, engine)}, compute_info{MakeComputeInfo( - shader_stage, engine)} {} +Registry::Registry(ShaderType shader_stage, ConstBufferEngineInterface& engine_) + : stage{shader_stage}, engine{&engine_}, bound_buffer{engine_.GetBoundBuffer()}, + graphics_info{MakeGraphicsInfo(shader_stage, engine_)}, compute_info{MakeComputeInfo( + shader_stage, engine_)} {} Registry::~Registry() = default; diff --git a/src/video_core/shader/registry.h b/src/video_core/shader/registry.h index 231206765..4bebefdde 100644 --- a/src/video_core/shader/registry.h +++ b/src/video_core/shader/registry.h @@ -94,7 +94,7 @@ public: explicit Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info); explicit Registry(Tegra::Engines::ShaderType shader_stage, - Tegra::Engines::ConstBufferEngineInterface& engine); + Tegra::Engines::ConstBufferEngineInterface& engine_); ~Registry(); -- 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') 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 67af0323f0599585825895144bcfcaea0e10bf46 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 23 Sep 2020 21:38:05 -0300 Subject: video_core: Fix instances where msbuild always regenerated host shaders When HEADER_GENERATOR was included in the DEPENDS section of custom commands, msbuild assumed this was always modified. Changing this file is not common so we can remove it from there. --- src/video_core/host_shaders/CMakeLists.txt | 17 +++++------------ src/video_core/host_shaders/StringShaderHeader.cmake | 2 ++ 2 files changed, 7 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index aa62363a7..c157724a9 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt @@ -1,23 +1,16 @@ -set(SHADER_FILES +set(SHADER_SOURCES opengl_present.frag opengl_present.vert ) set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) -set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) - set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) -add_custom_command( - OUTPUT - ${SHADER_DIR} - COMMAND - ${CMAKE_COMMAND} -E make_directory ${SHADER_DIR} -) +set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) -foreach(FILENAME IN ITEMS ${SHADER_FILES}) +foreach(FILENAME IN ITEMS ${SHADER_SOURCES}) string(REPLACE "." "_" SHADER_NAME ${FILENAME}) set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) set(HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h) @@ -29,8 +22,8 @@ foreach(FILENAME IN ITEMS ${SHADER_FILES}) MAIN_DEPENDENCY ${SOURCE_FILE} DEPENDS - ${HEADER_GENERATOR} ${INPUT_FILE} + # HEADER_GENERATOR should be included here but msbuild seems to assume it's always modified ) set(SHADER_HEADERS ${SHADER_HEADERS} ${HEADER_FILE}) endforeach() @@ -39,5 +32,5 @@ add_custom_target(host_shaders DEPENDS ${SHADER_HEADERS} SOURCES - ${SHADER_FILES} + ${SHADER_SOURCES} ) diff --git a/src/video_core/host_shaders/StringShaderHeader.cmake b/src/video_core/host_shaders/StringShaderHeader.cmake index 368bce0ed..c0fc49768 100644 --- a/src/video_core/host_shaders/StringShaderHeader.cmake +++ b/src/video_core/host_shaders/StringShaderHeader.cmake @@ -8,4 +8,6 @@ string(TOUPPER ${CONTENTS_NAME} CONTENTS_NAME) file(READ ${SOURCE_FILE} CONTENTS) +get_filename_component(OUTPUT_DIR ${HEADER_FILE} DIRECTORY) +make_directory(${OUTPUT_DIR}) configure_file(${INPUT_FILE} ${HEADER_FILE} @ONLY) -- cgit v1.2.3 From e3a615a6162460a1eb865a5a78ae9d229a16eb58 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 24 Sep 2020 13:21:22 -0400 Subject: arithmetic_integer_immediate: Make use of std::move where applicable Same behavior, minus any redundant atomic reference count increments and decrements. --- .../shader/decode/arithmetic_integer_immediate.cpp | 35 ++++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/video_core/shader/decode/arithmetic_integer_immediate.cpp b/src/video_core/shader/decode/arithmetic_integer_immediate.cpp index 73880db0e..2a30aab2b 100644 --- a/src/video_core/shader/decode/arithmetic_integer_immediate.cpp +++ b/src/video_core/shader/decode/arithmetic_integer_immediate.cpp @@ -28,23 +28,26 @@ u32 ShaderIR::DecodeArithmeticIntegerImmediate(NodeBlock& bb, u32 pc) { case OpCode::Id::IADD32I: { UNIMPLEMENTED_IF_MSG(instr.iadd32i.saturate, "IADD32I saturation is not implemented"); - op_a = GetOperandAbsNegInteger(op_a, false, instr.iadd32i.negate_a, true); + op_a = GetOperandAbsNegInteger(std::move(op_a), false, instr.iadd32i.negate_a != 0, true); - const Node value = Operation(OperationCode::IAdd, PRECISE, op_a, op_b); + Node value = Operation(OperationCode::IAdd, PRECISE, std::move(op_a), std::move(op_b)); - SetInternalFlagsFromInteger(bb, value, instr.op_32.generates_cc); - SetRegister(bb, instr.gpr0, value); + SetInternalFlagsFromInteger(bb, value, instr.op_32.generates_cc != 0); + SetRegister(bb, instr.gpr0, std::move(value)); break; } case OpCode::Id::LOP32I: { - if (instr.alu.lop32i.invert_a) - op_a = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_a); + if (instr.alu.lop32i.invert_a) { + op_a = Operation(OperationCode::IBitwiseNot, NO_PRECISE, std::move(op_a)); + } - if (instr.alu.lop32i.invert_b) - op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_b); + if (instr.alu.lop32i.invert_b) { + op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, std::move(op_b)); + } - WriteLogicOperation(bb, instr.gpr0, instr.alu.lop32i.operation, op_a, op_b, - PredicateResultMode::None, Pred::UnusedIndex, instr.op_32.generates_cc); + WriteLogicOperation(bb, instr.gpr0, instr.alu.lop32i.operation, std::move(op_a), + std::move(op_b), PredicateResultMode::None, Pred::UnusedIndex, + instr.op_32.generates_cc != 0); break; } default: @@ -58,14 +61,14 @@ u32 ShaderIR::DecodeArithmeticIntegerImmediate(NodeBlock& bb, u32 pc) { void ShaderIR::WriteLogicOperation(NodeBlock& bb, Register dest, LogicOperation logic_op, Node op_a, Node op_b, PredicateResultMode predicate_mode, Pred predicate, bool sets_cc) { - const Node result = [&]() { + Node result = [&] { switch (logic_op) { case LogicOperation::And: - return Operation(OperationCode::IBitwiseAnd, PRECISE, op_a, op_b); + return Operation(OperationCode::IBitwiseAnd, PRECISE, std::move(op_a), std::move(op_b)); case LogicOperation::Or: - return Operation(OperationCode::IBitwiseOr, PRECISE, op_a, op_b); + return Operation(OperationCode::IBitwiseOr, PRECISE, std::move(op_a), std::move(op_b)); case LogicOperation::Xor: - return Operation(OperationCode::IBitwiseXor, PRECISE, op_a, op_b); + return Operation(OperationCode::IBitwiseXor, PRECISE, std::move(op_a), std::move(op_b)); case LogicOperation::PassB: return op_b; default: @@ -84,8 +87,8 @@ void ShaderIR::WriteLogicOperation(NodeBlock& bb, Register dest, LogicOperation return; case PredicateResultMode::NotZero: { // Set the predicate to true if the result is not zero. - const Node compare = Operation(OperationCode::LogicalINotEqual, result, Immediate(0)); - SetPredicate(bb, static_cast(predicate), compare); + Node compare = Operation(OperationCode::LogicalINotEqual, std::move(result), Immediate(0)); + SetPredicate(bb, static_cast(predicate), std::move(compare)); break; } default: -- cgit v1.2.3 From 3602df7f1f58e1009af1f100892f8a439da7d1b6 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> 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') 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') 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 e0f2db437650c33e797bb33ee51c753a3c14fe86 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 00:12:45 -0400 Subject: vk_command_pool: Add missing header guard --- src/video_core/renderer_vulkan/vk_command_pool.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/vk_command_pool.h b/src/video_core/renderer_vulkan/vk_command_pool.h index 3aee239b9..fb98f72fc 100644 --- a/src/video_core/renderer_vulkan/vk_command_pool.h +++ b/src/video_core/renderer_vulkan/vk_command_pool.h @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma once + #include #include -- cgit v1.2.3 From 4ed4bba3050584cfe3e31a4bcc694c818c5baf2d Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 00:14:10 -0400 Subject: vk_command_pool: Make use of override on destructor --- src/video_core/renderer_vulkan/vk_command_pool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/vk_command_pool.h b/src/video_core/renderer_vulkan/vk_command_pool.h index fb98f72fc..92d8a9f4d 100644 --- a/src/video_core/renderer_vulkan/vk_command_pool.h +++ b/src/video_core/renderer_vulkan/vk_command_pool.h @@ -18,7 +18,7 @@ class VKDevice; class CommandPool final : public ResourcePool { public: explicit CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device); - virtual ~CommandPool(); + ~CommandPool() override; void Allocate(size_t begin, size_t end) override; -- cgit v1.2.3 From 940d85241bbd1f7fdbd65373e4c80b10025f8b1b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 00:15:50 -0400 Subject: vk_command_pool: Move definition of Pool into the cpp file Allows the implementation details to be changed without recompiling any files that include this header. --- src/video_core/renderer_vulkan/vk_command_pool.cpp | 5 +++++ src/video_core/renderer_vulkan/vk_command_pool.h | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/vk_command_pool.cpp b/src/video_core/renderer_vulkan/vk_command_pool.cpp index f1abd4b1a..6339f4fe0 100644 --- a/src/video_core/renderer_vulkan/vk_command_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_command_pool.cpp @@ -12,6 +12,11 @@ namespace Vulkan { constexpr size_t COMMAND_BUFFER_POOL_SIZE = 0x1000; +struct CommandPool::Pool { + vk::CommandPool handle; + vk::CommandBuffers cmdbufs; +}; + CommandPool::CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device) : ResourcePool(master_semaphore, COMMAND_BUFFER_POOL_SIZE), device{device} {} diff --git a/src/video_core/renderer_vulkan/vk_command_pool.h b/src/video_core/renderer_vulkan/vk_command_pool.h index 92d8a9f4d..b9cb3fb5d 100644 --- a/src/video_core/renderer_vulkan/vk_command_pool.h +++ b/src/video_core/renderer_vulkan/vk_command_pool.h @@ -25,10 +25,7 @@ public: VkCommandBuffer Commit(); private: - struct Pool { - vk::CommandPool handle; - vk::CommandBuffers cmdbufs; - }; + struct Pool; const VKDevice& device; std::vector pools; -- cgit v1.2.3 From 111852a9831a57b9ce19299ebf28f1e1e6b61914 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 00:27:08 -0400 Subject: effect_context: Make use of explicit where applicable While we're at it we can make the destructor of the base class virtual to ensure that any polymorphism issues never occur. --- src/audio_core/effect_context.h | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h index 2f2da72dd..c2d2aa3ba 100644 --- a/src/audio_core/effect_context.h +++ b/src/audio_core/effect_context.h @@ -166,13 +166,13 @@ public: std::array raw; }; }; - static_assert(sizeof(EffectInfo::InParams) == 0xc0, "InParams is an invalid size"); + static_assert(sizeof(InParams) == 0xc0, "InParams is an invalid size"); struct OutParams { UsageStatus status{}; INSERT_PADDING_BYTES(15); }; - static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size"); + static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size"); }; struct AuxAddress { @@ -184,8 +184,8 @@ struct AuxAddress { class EffectBase { public: - EffectBase(EffectType effect_type); - ~EffectBase(); + explicit EffectBase(EffectType effect_type); + virtual ~EffectBase(); virtual void Update(EffectInfo::InParams& in_params) = 0; virtual void UpdateForCommandGeneration() = 0; @@ -206,8 +206,7 @@ protected: template class EffectGeneric : public EffectBase { public: - EffectGeneric(EffectType effect_type) : EffectBase::EffectBase(effect_type) {} - ~EffectGeneric() = default; + explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {} T& GetParams() { return internal_params; @@ -224,7 +223,7 @@ private: class EffectStubbed : public EffectBase { public: explicit EffectStubbed(); - ~EffectStubbed(); + ~EffectStubbed() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -233,7 +232,7 @@ public: class EffectI3dl2Reverb : public EffectGeneric { public: explicit EffectI3dl2Reverb(); - ~EffectI3dl2Reverb(); + ~EffectI3dl2Reverb() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -245,7 +244,7 @@ private: class EffectBiquadFilter : public EffectGeneric { public: explicit EffectBiquadFilter(); - ~EffectBiquadFilter(); + ~EffectBiquadFilter() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -254,7 +253,7 @@ public: class EffectAuxInfo : public EffectGeneric { public: explicit EffectAuxInfo(); - ~EffectAuxInfo(); + ~EffectAuxInfo() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -275,7 +274,7 @@ private: class EffectDelay : public EffectGeneric { public: explicit EffectDelay(); - ~EffectDelay(); + ~EffectDelay() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -287,7 +286,7 @@ private: class EffectBufferMixer : public EffectGeneric { public: explicit EffectBufferMixer(); - ~EffectBufferMixer(); + ~EffectBufferMixer() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -296,7 +295,7 @@ public: class EffectReverb : public EffectGeneric { public: explicit EffectReverb(); - ~EffectReverb(); + ~EffectReverb() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; -- cgit v1.2.3 From 8b4ecf22d485958f69ecbd2fa4ca55d9ce393826 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 00:28:35 -0400 Subject: audio_core: Resolve sign conversion warnings While were at it, we can also enable sign conversion warnings and other common warnings as errors to prevent these from creeping back into the codebase. --- src/audio_core/CMakeLists.txt | 10 ++++++++++ src/audio_core/command_generator.cpp | 12 ++++++------ src/audio_core/effect_context.cpp | 8 ++++---- src/audio_core/effect_context.h | 8 ++++---- src/audio_core/info_updater.cpp | 7 +++---- src/audio_core/mix_context.cpp | 4 ++-- src/audio_core/splitter_context.cpp | 6 +++--- src/audio_core/voice_context.cpp | 4 ++-- 8 files changed, 34 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index cb00ef60e..6a7075f73 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -44,6 +44,16 @@ add_library(audio_core STATIC create_target_directory_groups(audio_core) +if (NOT MSVC) + target_compile_options(audio_core PRIVATE + -Werror=ignored-qualifiers + -Werror=implicit-fallthrough + -Werror=reorder + -Werror=sign-compare + -Werror=unused-variable + ) +endif() + target_link_libraries(audio_core PUBLIC common core) target_link_libraries(audio_core PRIVATE SoundTouch) diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index 8f7da49e6..7f2597257 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp @@ -152,7 +152,7 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) { if (!destination_data->IsConfigured()) { continue; } - if (destination_data->GetMixId() >= mix_context.GetCount()) { + if (destination_data->GetMixId() >= static_cast(mix_context.GetCount())) { continue; } @@ -435,7 +435,7 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf GetMixBuffer(output_index), worker_params.sample_count, offset, write_count); memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); - if (samples_read != worker_params.sample_count && + if (samples_read != static_cast(worker_params.sample_count) && samples_read <= params.sample_count) { std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read); } @@ -611,7 +611,8 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) { const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId()); const auto& dest_in_params = dest_mix.GetInParams(); const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset; - for (std::size_t i = 0; i < dest_in_params.buffer_count; i++) { + for (std::size_t i = 0; i < static_cast(dest_in_params.buffer_count); + i++) { const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i); if (mixed_volume != 0.0f) { GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume, @@ -704,7 +705,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s std::vector buffer(samples_processed * channel_count); memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); - for (std::size_t i = 0; i < samples_processed; i++) { + for (std::size_t i = 0; i < static_cast(samples_processed); i++) { sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; } } @@ -789,7 +790,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s position_in_frame += 2; // Decode entire frame - if (remaining_samples >= SAMPLES_PER_FRAME) { + if (remaining_samples >= static_cast(SAMPLES_PER_FRAME)) { for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) { // Sample 1 @@ -866,7 +867,6 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o const auto resample_rate = static_cast( static_cast(in_params.sample_rate) / static_cast(target_sample_rate) * static_cast(static_cast(in_params.pitch * 32768.0f))); - auto* output_base = output; if (dsp_state.fraction + sample_count * resample_rate > static_cast(SCALED_MIX_BUFFER_SIZE - 4ULL)) { return; diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp index adfec3df5..4d9cdf524 100644 --- a/src/audio_core/effect_context.cpp +++ b/src/audio_core/effect_context.cpp @@ -184,19 +184,19 @@ void EffectAuxInfo::UpdateForCommandGeneration() { } } -const VAddr EffectAuxInfo::GetSendInfo() const { +VAddr EffectAuxInfo::GetSendInfo() const { return send_info; } -const VAddr EffectAuxInfo::GetSendBuffer() const { +VAddr EffectAuxInfo::GetSendBuffer() const { return send_buffer; } -const VAddr EffectAuxInfo::GetRecvInfo() const { +VAddr EffectAuxInfo::GetRecvInfo() const { return recv_info; } -const VAddr EffectAuxInfo::GetRecvBuffer() const { +VAddr EffectAuxInfo::GetRecvBuffer() const { return recv_buffer; } diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h index c2d2aa3ba..2c4ce53ef 100644 --- a/src/audio_core/effect_context.h +++ b/src/audio_core/effect_context.h @@ -257,10 +257,10 @@ public: void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; - const VAddr GetSendInfo() const; - const VAddr GetSendBuffer() const; - const VAddr GetRecvInfo() const; - const VAddr GetRecvBuffer() const; + VAddr GetSendInfo() const; + VAddr GetSendBuffer() const; + VAddr GetRecvInfo() const; + VAddr GetRecvBuffer() const; private: VAddr send_info{}; diff --git a/src/audio_core/info_updater.cpp b/src/audio_core/info_updater.cpp index f53ce21a5..2940e53a9 100644 --- a/src/audio_core/info_updater.cpp +++ b/src/audio_core/info_updater.cpp @@ -64,7 +64,6 @@ bool InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& in_behavior_info) { } bool InfoUpdater::UpdateMemoryPools(std::vector& memory_pool_info) { - const auto force_mapping = behavior_info.IsMemoryPoolForceMappingEnabled(); const auto memory_pool_count = memory_pool_info.size(); const auto total_memory_pool_in = sizeof(ServerMemoryPoolInfo::InParams) * memory_pool_count; const auto total_memory_pool_out = sizeof(ServerMemoryPoolInfo::OutParams) * memory_pool_count; @@ -174,7 +173,7 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, } // Voice states for each channel std::array voice_states{}; - ASSERT(in_params.id < voice_count); + ASSERT(static_cast(in_params.id) < voice_count); // Grab our current voice info auto& voice_info = voice_context.GetInfo(static_cast(in_params.id)); @@ -352,8 +351,8 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf for (std::size_t i = 0; i < mix_count; i++) { const auto& in = mix_in_params[i]; total_buffer_count += in.buffer_count; - if (in.dest_mix_id > mix_count && in.dest_mix_id != AudioCommon::NO_MIX && - in.mix_id != AudioCommon::FINAL_MIX) { + if (static_cast(in.dest_mix_id) > mix_count && + in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) { LOG_ERROR( Audio, "Invalid mix destination, mix_id={:X}, dest_mix_id={:X}, mix_buffer_count={:X}", diff --git a/src/audio_core/mix_context.cpp b/src/audio_core/mix_context.cpp index 042891490..4bca72eb0 100644 --- a/src/audio_core/mix_context.cpp +++ b/src/audio_core/mix_context.cpp @@ -53,7 +53,7 @@ void MixContext::UpdateDistancesFromFinalMix() { auto mix_id = in_params.mix_id; // Needs to be referenced out of scope s32 distance_to_final_mix{AudioCommon::FINAL_MIX}; - for (; distance_to_final_mix < info_count; distance_to_final_mix++) { + for (; distance_to_final_mix < static_cast(info_count); distance_to_final_mix++) { if (mix_id == AudioCommon::FINAL_MIX) { // If we're at the final mix, we're done break; @@ -77,7 +77,7 @@ void MixContext::UpdateDistancesFromFinalMix() { } // If we're out of range for our distance, mark it as no final mix - if (distance_to_final_mix >= info_count) { + if (distance_to_final_mix >= static_cast(info_count)) { distance_to_final_mix = AudioCommon::NO_FINAL_MIX; } diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp index 79bb2f516..f21b53147 100644 --- a/src/audio_core/splitter_context.cpp +++ b/src/audio_core/splitter_context.cpp @@ -306,7 +306,7 @@ bool SplitterContext::UpdateInfo(const std::vector& input, std::size_t& inpu break; } - if (header.send_id < 0 || header.send_id > info_count) { + if (header.send_id < 0 || static_cast(header.send_id) > info_count) { LOG_ERROR(Audio, "Bad splitter data id"); break; } @@ -348,7 +348,7 @@ bool SplitterContext::UpdateData(const std::vector& input, std::size_t& inpu break; } - if (header.splitter_id < 0 || header.splitter_id > data_count) { + if (header.splitter_id < 0 || static_cast(header.splitter_id) > data_count) { LOG_ERROR(Audio, "Bad splitter data id"); break; } @@ -434,7 +434,7 @@ const std::vector& NodeStates::GetIndexList() const { } void NodeStates::PushTsortResult(s32 index) { - ASSERT(index < node_count); + ASSERT(index < static_cast(node_count)); index_list[index_pos++] = index; } diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp index 1d8f69844..863ac9267 100644 --- a/src/audio_core/voice_context.cpp +++ b/src/audio_core/voice_context.cpp @@ -488,11 +488,11 @@ s32 VoiceContext::DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer, // Fast path if (channel_count == 1) { - for (std::size_t i = 0; i < samples_processed; i++) { + for (std::ptrdiff_t i = 0; i < samples_processed; i++) { output_buffer[i] = buffer_data[i]; } } else { - for (std::size_t i = 0; i < samples_processed; i++) { + for (std::ptrdiff_t i = 0; i < samples_processed; i++) { output_buffer[i] = buffer_data[i * channel_count + channel]; } } -- cgit v1.2.3 From 966966dc0260077b9e607995e1930afa1a2ecc40 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 13:19:39 -0400 Subject: audio_core: Remove unnecessary inclusions Same behavior, but removes header dependencies where they don't need to be. --- src/audio_core/audio_renderer.cpp | 5 +---- src/audio_core/audio_renderer.h | 1 - src/audio_core/command_generator.h | 1 - src/audio_core/common.h | 1 + src/audio_core/stream.cpp | 1 - 5 files changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 56dc892b1..a7e851bb8 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -3,16 +3,13 @@ // Refer to the license.txt file included. #include -#include "audio_core/algorithm/interpolate.h" + #include "audio_core/audio_out.h" #include "audio_core/audio_renderer.h" -#include "audio_core/codec.h" #include "audio_core/common.h" #include "audio_core/info_updater.h" #include "audio_core/voice_context.h" -#include "common/assert.h" #include "common/logging/log.h" -#include "core/core.h" #include "core/hle/kernel/writable_event.h" #include "core/memory.h" #include "core/settings.h" diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h index 2bca795ba..2fd93e058 100644 --- a/src/audio_core/audio_renderer.h +++ b/src/audio_core/audio_renderer.h @@ -21,7 +21,6 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" -#include "core/hle/kernel/object.h" #include "core/hle/result.h" namespace Core::Timing { diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h index 967d24078..53e57748b 100644 --- a/src/audio_core/command_generator.h +++ b/src/audio_core/command_generator.h @@ -7,7 +7,6 @@ #include #include "audio_core/common.h" #include "audio_core/voice_context.h" -#include "common/common_funcs.h" #include "common/common_types.h" namespace Core::Memory { diff --git a/src/audio_core/common.h b/src/audio_core/common.h index 72ebce221..7b4a1e9e8 100644 --- a/src/audio_core/common.h +++ b/src/audio_core/common.h @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #pragma once + #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index cb33926bc..4bbb1e0c4 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -12,7 +12,6 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core_timing.h" -#include "core/core_timing_util.h" #include "core/settings.h" namespace AudioCore { -- cgit v1.2.3 From 7c0908f301867b7f8667d7720094a3ad3616dd53 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 14:18:09 -0400 Subject: codec: Make lookup table static constexpr Allows compilers to elide needing to push these values on the stack every time the function is called. --- src/audio_core/codec.cpp | 5 +++-- src/audio_core/codec.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp index c5a0d98ce..2fb91c13a 100644 --- a/src/audio_core/codec.cpp +++ b/src/audio_core/codec.cpp @@ -16,8 +16,9 @@ std::vector DecodeADPCM(const u8* const data, std::size_t size, const ADPCM constexpr std::size_t FRAME_LEN = 8; constexpr std::size_t SAMPLES_PER_FRAME = 14; - constexpr std::array SIGNED_NIBBLES = { - {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; + static constexpr std::array SIGNED_NIBBLES{ + 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1, + }; const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; const std::size_t ret_size = diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h index ef2ce01a8..9507abb1b 100644 --- a/src/audio_core/codec.h +++ b/src/audio_core/codec.h @@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array; * @param state ADPCM state, this is updated with new state * @return Decoded stereo signed PCM16 data, sample_count in length */ -std::vector DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff, +std::vector DecodeADPCM(const u8* data, std::size_t size, const ADPCM_Coeff& coeff, ADPCMState& state); }; // namespace AudioCore::Codec -- cgit v1.2.3 From 407393130589abe4d68ab7e144a4a74fe58e1b5a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 17:09:59 -0400 Subject: cubeb_sink: Use static_cast instead of reinterpret_cast in DataCallback() Conversions from void* to the proper data type are well-defined and supported by static_cast. We don't need to use reinterpret_cast here. --- src/audio_core/cubeb_sink.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 83c06c0ed..eb82791f6 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -192,8 +192,8 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels, long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, void* output_buffer, long num_frames) { - CubebSinkStream* impl = static_cast(user_data); - u8* buffer = reinterpret_cast(output_buffer); + auto* impl = static_cast(user_data); + auto* buffer = static_cast(output_buffer); if (!impl) { return {}; -- cgit v1.2.3 From dc83ca8914222230873c6a3b6056d8f9c183f42c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 17:14:02 -0400 Subject: behavior_info: Fix typo Renerer -> Renderer --- src/audio_core/behavior_info.cpp | 6 +++--- src/audio_core/behavior_info.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/audio_core/behavior_info.cpp b/src/audio_core/behavior_info.cpp index 5d62adb0b..3c2e3e6f1 100644 --- a/src/audio_core/behavior_info.cpp +++ b/src/audio_core/behavior_info.cpp @@ -57,15 +57,15 @@ bool BehaviorInfo::IsLongSizePreDelaySupported() const { return AudioCommon::IsRevisionSupported(3, user_revision); } -bool BehaviorInfo::IsAudioRenererProcessingTimeLimit80PercentSupported() const { +bool BehaviorInfo::IsAudioRendererProcessingTimeLimit80PercentSupported() const { return AudioCommon::IsRevisionSupported(5, user_revision); } -bool BehaviorInfo::IsAudioRenererProcessingTimeLimit75PercentSupported() const { +bool BehaviorInfo::IsAudioRendererProcessingTimeLimit75PercentSupported() const { return AudioCommon::IsRevisionSupported(4, user_revision); } -bool BehaviorInfo::IsAudioRenererProcessingTimeLimit70PercentSupported() const { +bool BehaviorInfo::IsAudioRendererProcessingTimeLimit70PercentSupported() const { return AudioCommon::IsRevisionSupported(1, user_revision); } diff --git a/src/audio_core/behavior_info.h b/src/audio_core/behavior_info.h index 50948e8df..512a4ebe3 100644 --- a/src/audio_core/behavior_info.h +++ b/src/audio_core/behavior_info.h @@ -49,9 +49,9 @@ public: bool IsAdpcmLoopContextBugFixed() const; bool IsSplitterSupported() const; bool IsLongSizePreDelaySupported() const; - bool IsAudioRenererProcessingTimeLimit80PercentSupported() const; - bool IsAudioRenererProcessingTimeLimit75PercentSupported() const; - bool IsAudioRenererProcessingTimeLimit70PercentSupported() const; + bool IsAudioRendererProcessingTimeLimit80PercentSupported() const; + bool IsAudioRendererProcessingTimeLimit75PercentSupported() const; + bool IsAudioRendererProcessingTimeLimit70PercentSupported() const; bool IsElapsedFrameCountSupported() const; bool IsMemoryPoolForceMappingEnabled() const; bool IsFlushVoiceWaveBuffersSupported() const; -- cgit v1.2.3 From ca26fd0f4297bc5cdf495c5304ed0bd9737f40b2 Mon Sep 17 00:00:00 2001 From: lat9nq Date: Fri, 25 Sep 2020 17:42:59 -0400 Subject: vk_stream_buffer: Fix initializing Vulkan with NVIDIA on Linux The previous fix only partially solved the issue, as only certain GPUs that needed 9 or less MiB subtracted would work (i.e. GTX 980 Ti, GT 730). This takes from DXVK's example to divide `heap_size` by 2 to determine `allocable_size`. Additionally tested on my Quadro K4200, which previously required setting it to 12 to boot. --- src/video_core/renderer_vulkan/vk_stream_buffer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp index 5218c875b..1b59612b9 100644 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp +++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp @@ -120,7 +120,8 @@ void VKStreamBuffer::CreateBuffers(VkBufferUsageFlags usage) { // Substract from the preferred heap size some bytes to avoid getting out of memory. const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size; - const VkDeviceSize allocable_size = heap_size - 9 * 1024 * 1024; + // As per DXVK's example, using `heap_size / 2` + const VkDeviceSize allocable_size = heap_size / 2; buffer = device.GetLogical().CreateBuffer({ .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, -- cgit v1.2.3 From 90c61411640c049c6a5c376782b37d94f949f1f5 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 18:30:49 -0400 Subject: command_generator: Make lookup table static constexpr Allows compilers to elide needing to push these values on the stack every time the function is called. --- src/audio_core/command_generator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index 8f7da49e6..07c932e93 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp @@ -726,8 +726,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s return 0; } - constexpr std::array SIGNED_NIBBLES = { - {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; + static constexpr std::array SIGNED_NIBBLES{ + 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1, + }; constexpr std::size_t FRAME_LEN = 8; constexpr std::size_t NIBBLES_PER_SAMPLE = 16; -- cgit v1.2.3 From 03b574ae2272fc8465e7d38f21b198fcb1885186 Mon Sep 17 00:00:00 2001 From: german Date: Thu, 17 Sep 2020 20:26:34 -0500 Subject: Add random motion input to SDL --- src/input_common/motion_input.cpp | 32 +++++++ src/input_common/motion_input.h | 3 + src/input_common/sdl/sdl_impl.cpp | 190 ++++++++++++++++++++++++++++++++++++++ src/input_common/sdl/sdl_impl.h | 2 + src/input_common/udp/client.cpp | 8 +- 5 files changed, 230 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/input_common/motion_input.cpp b/src/input_common/motion_input.cpp index 22a849866..b99d3497f 100644 --- a/src/input_common/motion_input.cpp +++ b/src/input_common/motion_input.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included +#include #include "common/math_util.h" #include "input_common/motion_input.h" @@ -159,6 +160,37 @@ Common::Vec3f MotionInput::GetRotations() const { return rotations; } +Input::MotionStatus MotionInput::GetMotion() const { + const Common::Vec3f gyroscope = GetGyroscope(); + const Common::Vec3f accelerometer = GetAcceleration(); + const Common::Vec3f rotation = GetRotations(); + const std::array orientation = GetOrientation(); + return {accelerometer, gyroscope, rotation, orientation}; +} + +Input::MotionStatus MotionInput::GetRandomMotion(int accel_magnitude, int gyro_magnitude) const { + std::random_device device; + std::mt19937 gen(device()); + std::uniform_int_distribution distribution(-1000, 1000); + const Common::Vec3f gyroscope = { + distribution(gen) * 0.001f, + distribution(gen) * 0.001f, + distribution(gen) * 0.001f, + }; + const Common::Vec3f accelerometer = { + distribution(gen) * 0.001f, + distribution(gen) * 0.001f, + distribution(gen) * 0.001f, + }; + const Common::Vec3f rotation = {}; + const std::array orientation = { + Common::Vec3f{1.0f, 0, 0}, + Common::Vec3f{0, 1.0f, 0}, + Common::Vec3f{0, 0, 1.0f}, + }; + return {accelerometer * accel_magnitude, gyroscope * gyro_magnitude, rotation, orientation}; +} + void MotionInput::ResetOrientation() { if (!reset_enabled) { return; diff --git a/src/input_common/motion_input.h b/src/input_common/motion_input.h index 54b4439d9..12b7d0d3f 100644 --- a/src/input_common/motion_input.h +++ b/src/input_common/motion_input.h @@ -7,6 +7,7 @@ #include "common/common_types.h" #include "common/quaternion.h" #include "common/vector_math.h" +#include "core/frontend/input.h" namespace InputCommon { @@ -37,6 +38,8 @@ public: Common::Vec3f GetGyroscope() const; Common::Vec3f GetRotations() const; Common::Quaternion GetQuaternion() const; + Input::MotionStatus GetMotion() const; + Input::MotionStatus GetRandomMotion(int accel_magnitude, int gyro_magnitude) const; bool IsMoving(f32 sensitivity) const; bool IsCalibrated(f32 sensitivity) const; diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index a9e676f4b..0b0095978 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -21,6 +21,7 @@ #include "common/param_package.h" #include "common/threadsafe_queue.h" #include "core/frontend/input.h" +#include "input_common/motion_input.h" #include "input_common/sdl/sdl_impl.h" #include "input_common/settings.h" @@ -95,6 +96,10 @@ public: return std::make_tuple(x, y); } + const InputCommon::MotionInput& GetMotion() const { + return motion; + } + void SetHat(int hat, Uint8 direction) { std::lock_guard lock{mutex}; state.hats.insert_or_assign(hat, direction); @@ -142,6 +147,9 @@ private: std::unique_ptr sdl_joystick; std::unique_ptr sdl_controller; mutable std::mutex mutex; + + // motion is initalized without PID values as motion input is not aviable for SDL2 + InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f}; }; std::shared_ptr SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) { @@ -386,6 +394,68 @@ private: const float range; }; +class SDLDirectionMotion final : public Input::MotionDevice { +public: + explicit SDLDirectionMotion(std::shared_ptr joystick_, int hat_, Uint8 direction_) + : joystick(std::move(joystick_)), hat(hat_), direction(direction_) {} + + Input::MotionStatus GetStatus() const override { + if (joystick->GetHatDirection(hat, direction)) { + return joystick->GetMotion().GetRandomMotion(2, 6); + } + return joystick->GetMotion().GetRandomMotion(0, 0); + } + +private: + std::shared_ptr joystick; + int hat; + Uint8 direction; +}; + +class SDLAxisMotion final : public Input::MotionDevice { +public: + explicit SDLAxisMotion(std::shared_ptr joystick_, int axis_, float threshold_, + bool trigger_if_greater_) + : joystick(std::move(joystick_)), axis(axis_), threshold(threshold_), + trigger_if_greater(trigger_if_greater_) {} + + Input::MotionStatus GetStatus() const override { + const float axis_value = joystick->GetAxis(axis, 1.0f); + bool trigger = axis_value < threshold; + if (trigger_if_greater) { + trigger = axis_value > threshold; + } + + if (trigger) { + return joystick->GetMotion().GetRandomMotion(2, 6); + } + return joystick->GetMotion().GetRandomMotion(0, 0); + } + +private: + std::shared_ptr joystick; + int axis; + float threshold; + bool trigger_if_greater; +}; + +class SDLButtonMotion final : public Input::MotionDevice { +public: + explicit SDLButtonMotion(std::shared_ptr joystick_, int button_) + : joystick(std::move(joystick_)), button(button_) {} + + Input::MotionStatus GetStatus() const override { + if (joystick->GetButton(button)) { + return joystick->GetMotion().GetRandomMotion(2, 6); + } + return joystick->GetMotion().GetRandomMotion(0, 0); + } + +private: + std::shared_ptr joystick; + int button; +}; + /// A button device factory that creates button devices from SDL joystick class SDLButtonFactory final : public Input::Factory { public: @@ -492,12 +562,78 @@ private: SDLState& state; }; +/// A motion device factory that creates motion devices from SDL joystick +class SDLMotionFactory final : public Input::Factory { +public: + explicit SDLMotionFactory(SDLState& state_) : state(state_) {} + /** + * Creates motion device from joystick axes + * @param params contains parameters for creating the device: + * - "guid": the guid of the joystick to bind + * - "port": the nth joystick of the same type + */ + std::unique_ptr Create(const Common::ParamPackage& params) override { + const std::string guid = params.Get("guid", "0"); + const int port = params.Get("port", 0); + + auto joystick = state.GetSDLJoystickByGUID(guid, port); + + if (params.Has("hat")) { + const int hat = params.Get("hat", 0); + const std::string direction_name = params.Get("direction", ""); + Uint8 direction; + if (direction_name == "up") { + direction = SDL_HAT_UP; + } else if (direction_name == "down") { + direction = SDL_HAT_DOWN; + } else if (direction_name == "left") { + direction = SDL_HAT_LEFT; + } else if (direction_name == "right") { + direction = SDL_HAT_RIGHT; + } else { + direction = 0; + } + // This is necessary so accessing GetHat with hat won't crash + joystick->SetHat(hat, SDL_HAT_CENTERED); + return std::make_unique(joystick, hat, direction); + } + + if (params.Has("axis")) { + const int axis = params.Get("axis", 0); + const float threshold = params.Get("threshold", 0.5f); + const std::string direction_name = params.Get("direction", ""); + bool trigger_if_greater; + if (direction_name == "+") { + trigger_if_greater = true; + } else if (direction_name == "-") { + trigger_if_greater = false; + } else { + trigger_if_greater = true; + LOG_ERROR(Input, "Unknown direction {}", direction_name); + } + // This is necessary so accessing GetAxis with axis won't crash + joystick->SetAxis(axis, 0); + return std::make_unique(joystick, axis, threshold, trigger_if_greater); + } + + const int button = params.Get("button", 0); + // This is necessary so accessing GetButton with button won't crash + joystick->SetButton(button, false); + return std::make_unique(joystick, button); + } + +private: + SDLState& state; +}; + SDLState::SDLState() { using namespace Input; analog_factory = std::make_shared(*this); button_factory = std::make_shared(*this); + motion_factory = std::make_shared(*this); RegisterFactory("sdl", analog_factory); RegisterFactory("sdl", button_factory); + RegisterFactory("sdl", motion_factory); // If the frontend is going to manage the event loop, then we dont start one here start_thread = !SDL_WasInit(SDL_INIT_JOYSTICK); @@ -533,6 +669,7 @@ SDLState::~SDLState() { using namespace Input; UnregisterFactory("sdl"); UnregisterFactory("sdl"); + UnregisterFactory("sdl"); CloseJoysticks(); SDL_DelEventWatch(&SDLEventWatcher, this); @@ -644,6 +781,27 @@ Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Eve return {}; } +Common::ParamPackage SDLEventToMotionParamPackage(SDLState& state, const SDL_Event& event) { + switch (event.type) { + case SDL_JOYAXISMOTION: { + const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); + return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), + event.jaxis.axis, event.jaxis.value); + } + case SDL_JOYBUTTONUP: { + const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); + return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), + event.jbutton.button); + } + case SDL_JOYHATMOTION: { + const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); + return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), + event.jhat.hat, event.jhat.value); + } + } + return {}; +} + Common::ParamPackage BuildParamPackageForBinding(int port, const std::string& guid, const SDL_GameControllerButtonBind& binding) { switch (binding.bindType) { @@ -809,6 +967,35 @@ public: } }; +class SDLMotionPoller final : public SDLPoller { +public: + explicit SDLMotionPoller(SDLState& state_) : SDLPoller(state_) {} + + Common::ParamPackage GetNextInput() override { + SDL_Event event; + while (state.event_queue.Pop(event)) { + const auto package = FromEvent(event); + if (package) { + return *package; + } + } + return {}; + } + [[nodiscard]] std::optional FromEvent(const SDL_Event& event) const { + switch (event.type) { + case SDL_JOYAXISMOTION: + if (std::abs(event.jaxis.value / 32767.0) < 0.5) { + break; + } + [[fallthrough]]; + case SDL_JOYBUTTONUP: + case SDL_JOYHATMOTION: + return {SDLEventToMotionParamPackage(state, event)}; + } + return std::nullopt; + } +}; + /** * Attempts to match the press to a controller joy axis (left/right stick) and if a match * isn't found, checks if the event matches anything from SDLButtonPoller and uses that @@ -900,6 +1087,9 @@ SDLState::Pollers SDLState::GetPollers(InputCommon::Polling::DeviceType type) { case InputCommon::Polling::DeviceType::Button: pollers.emplace_back(std::make_unique(*this)); break; + case InputCommon::Polling::DeviceType::Motion: + pollers.emplace_back(std::make_unique(*this)); + break; } return pollers; diff --git a/src/input_common/sdl/sdl_impl.h b/src/input_common/sdl/sdl_impl.h index bd19ba61d..b9bb4dc56 100644 --- a/src/input_common/sdl/sdl_impl.h +++ b/src/input_common/sdl/sdl_impl.h @@ -21,6 +21,7 @@ namespace InputCommon::SDL { class SDLAnalogFactory; class SDLButtonFactory; +class SDLMotionFactory; class SDLJoystick; class SDLState : public State { @@ -71,6 +72,7 @@ private: std::shared_ptr button_factory; std::shared_ptr analog_factory; + std::shared_ptr motion_factory; bool start_thread = false; std::atomic initialized = false; diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp index 2b6a68d4b..b6323d56f 100644 --- a/src/input_common/udp/client.cpp +++ b/src/input_common/udp/client.cpp @@ -219,14 +219,10 @@ void Client::OnPadData(Response::PadData data) { clients[client].motion.SetGyroscope(raw_gyroscope / 312.0f); clients[client].motion.UpdateRotation(time_difference); clients[client].motion.UpdateOrientation(time_difference); - Common::Vec3f gyroscope = clients[client].motion.GetGyroscope(); - Common::Vec3f accelerometer = clients[client].motion.GetAcceleration(); - Common::Vec3f rotation = clients[client].motion.GetRotations(); - std::array orientation = clients[client].motion.GetOrientation(); { std::lock_guard guard(clients[client].status.update_mutex); - clients[client].status.motion_status = {accelerometer, gyroscope, rotation, orientation}; + clients[client].status.motion_status = clients[client].motion.GetMotion(); // TODO: add a setting for "click" touch. Click touch refers to a device that differentiates // between a simple "tap" and a hard press that causes the touch screen to click. @@ -250,6 +246,8 @@ void Client::OnPadData(Response::PadData data) { clients[client].status.touch_status = {x, y, is_active}; if (configuring) { + const Common::Vec3f gyroscope = clients[client].motion.GetGyroscope(); + const Common::Vec3f accelerometer = clients[client].motion.GetAcceleration(); UpdateYuzuSettings(client, accelerometer, gyroscope, is_active); } } -- cgit v1.2.3 From 297823239026d1b5487f9b07f63646ca4a2e3a79 Mon Sep 17 00:00:00 2001 From: german Date: Fri, 25 Sep 2020 17:58:27 -0500 Subject: Add random motion input to keyboard --- src/input_common/CMakeLists.txt | 2 ++ src/input_common/main.cpp | 4 ++++ src/input_common/motion_from_button.cpp | 34 +++++++++++++++++++++++++++++++++ src/input_common/motion_from_button.h | 25 ++++++++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 src/input_common/motion_from_button.cpp create mode 100644 src/input_common/motion_from_button.h (limited to 'src') diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index 09361e37e..c84685214 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -7,6 +7,8 @@ add_library(input_common STATIC main.h motion_emu.cpp motion_emu.h + motion_from_button.cpp + motion_from_button.h motion_input.cpp motion_input.h settings.cpp diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index 8da829132..3d97d95f7 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp @@ -11,6 +11,7 @@ #include "input_common/keyboard.h" #include "input_common/main.h" #include "input_common/motion_emu.h" +#include "input_common/motion_from_button.h" #include "input_common/touch_from_button.h" #include "input_common/udp/client.h" #include "input_common/udp/udp.h" @@ -32,6 +33,8 @@ struct InputSubsystem::Impl { Input::RegisterFactory("keyboard", keyboard); Input::RegisterFactory("analog_from_button", std::make_shared()); + Input::RegisterFactory("keyboard", + std::make_shared()); motion_emu = std::make_shared(); Input::RegisterFactory("motion_emu", motion_emu); Input::RegisterFactory("touch_from_button", @@ -50,6 +53,7 @@ struct InputSubsystem::Impl { void Shutdown() { Input::UnregisterFactory("keyboard"); + Input::UnregisterFactory("keyboard"); keyboard.reset(); Input::UnregisterFactory("analog_from_button"); Input::UnregisterFactory("motion_emu"); diff --git a/src/input_common/motion_from_button.cpp b/src/input_common/motion_from_button.cpp new file mode 100644 index 000000000..9d459f963 --- /dev/null +++ b/src/input_common/motion_from_button.cpp @@ -0,0 +1,34 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "input_common/motion_from_button.h" +#include "input_common/motion_input.h" + +namespace InputCommon { + +class MotionKey final : public Input::MotionDevice { +public: + using Button = std::unique_ptr; + + MotionKey(Button key_) : key(std::move(key_)) {} + + Input::MotionStatus GetStatus() const override { + + if (key->GetStatus()) { + return motion.GetRandomMotion(2, 6); + } + return motion.GetRandomMotion(0, 0); + } + +private: + Button key; + InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f}; +}; + +std::unique_ptr MotionFromButton::Create(const Common::ParamPackage& params) { + auto key = Input::CreateDevice(params.Serialize()); + return std::make_unique(std::move(key)); +} + +} // namespace InputCommon diff --git a/src/input_common/motion_from_button.h b/src/input_common/motion_from_button.h new file mode 100644 index 000000000..a959046fb --- /dev/null +++ b/src/input_common/motion_from_button.h @@ -0,0 +1,25 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/frontend/input.h" + +namespace InputCommon { + +/** + * An motion device factory that takes a keyboard button and uses it as a random + * motion device. + */ +class MotionFromButton final : public Input::Factory { +public: + /** + * Creates an motion device from button devices + * @param params contains parameters for creating the device: + * - "key": a serialized ParamPackage for creating a button device + */ + std::unique_ptr Create(const Common::ParamPackage& params) override; +}; + +} // namespace InputCommon -- 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') 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') 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 86e4aa81e9e5a7857ee6b56c83a4e55c4c98ed5a Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sat, 26 Sep 2020 06:55:47 -0400 Subject: main: Allow applets to display on top while fullscreen Using the Qt::WindowStaysOnTopHint flag allows these dialogs to show up on top while running in fullscreen. However, if yuzu goes out of focus (by alt-tabbing or otherwise), this flag does not seem to have an effect. --- src/yuzu/main.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 6a2a88dd8..e3de0f0e1 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -288,8 +288,8 @@ GMainWindow::~GMainWindow() { void GMainWindow::ControllerSelectorReconfigureControllers( const Core::Frontend::ControllerParameters& parameters) { QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get()); - dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | - Qt::WindowSystemMenuHint); + dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | + Qt::WindowTitleHint | Qt::WindowSystemMenuHint); dialog.setWindowModality(Qt::WindowModal); dialog.exec(); @@ -307,8 +307,9 @@ void GMainWindow::ProfileSelectorSelectProfile() { int index = 0; if (manager.GetUserCount() != 1) { QtProfileSelectionDialog dialog(this); - dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | - Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); + dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | + Qt::WindowTitleHint | Qt::WindowSystemMenuHint | + Qt::WindowCloseButtonHint); dialog.setWindowModality(Qt::WindowModal); if (dialog.exec() == QDialog::Rejected) { @@ -331,8 +332,9 @@ void GMainWindow::ProfileSelectorSelectProfile() { void GMainWindow::SoftwareKeyboardGetText( const Core::Frontend::SoftwareKeyboardParameters& parameters) { QtSoftwareKeyboardDialog dialog(this, parameters); - dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | - Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); + dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | + Qt::WindowTitleHint | Qt::WindowSystemMenuHint | + Qt::WindowCloseButtonHint); dialog.setWindowModality(Qt::WindowModal); if (dialog.exec() == QDialog::Rejected) { -- cgit v1.2.3 From 9d665cb8dbc560e5f5492d34aeab4bf41b9353d3 Mon Sep 17 00:00:00 2001 From: lat9nq Date: Mon, 28 Sep 2020 20:28:47 -0400 Subject: CMakeLists: fix for finding zstd on linux-mingw --- src/common/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 5d54516eb..ea0191c4b 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -192,4 +192,4 @@ create_target_directory_groups(common) find_package(Boost 1.71 COMPONENTS context headers REQUIRED) target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile) -target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd xbyak) +target_link_libraries(common PRIVATE lz4::lz4 zstd xbyak) -- cgit v1.2.3 From 2cbce77b925c4320d90d5845563928a838c3372c Mon Sep 17 00:00:00 2001 From: lat9nq Date: Mon, 28 Sep 2020 21:11:39 -0400 Subject: CMakeLists: use system zstd on Linux From what I understand, this tells CMake to use the system, not conan, version of zstd. Required to build on the coming MinGW Docker container. --- src/common/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index ea0191c4b..0fb5d9708 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -192,4 +192,9 @@ create_target_directory_groups(common) find_package(Boost 1.71 COMPONENTS context headers REQUIRED) target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile) -target_link_libraries(common PRIVATE lz4::lz4 zstd xbyak) +target_link_libraries(common PRIVATE lz4::lz4 xbyak) +if (MSVC) + target_link_libraries(common PRIVATE zstd::zstd) +else() + target_link_libraries(common PRIVATE zstd) +endif() -- 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 +++--- src/input_common/sdl/sdl_impl.cpp | 39 ++++++++++++++++++++++++++- 5 files changed, 63 insertions(+), 14 deletions(-) (limited to 'src') 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); diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index a9e676f4b..27a96c18b 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,33 @@ public: return state.axes.at(axis) / (32767.0f * range); } + bool RumblePlay(f32 amp_low, f32 amp_high, int time) { + const u16 raw_amp_low = static_cast(amp_low * 0xFFFF); + const u16 raw_amp_high = static_cast(amp_high * 0xFFFF); + // Lower drastically the number of state changes + if (raw_amp_low >> 11 == last_state_rumble_low >> 11 && + raw_amp_high >> 11 == last_state_rumble_high >> 11) { + if (raw_amp_low + raw_amp_high != 0 || + last_state_rumble_low + last_state_rumble_high == 0) { + return false; + } + } + // Don't change state if last vibration was < 20ms + const auto now = std::chrono::system_clock::now(); + if (std::chrono::duration_cast(now - last_vibration) < + std::chrono::milliseconds(20)) { + return raw_amp_low + raw_amp_high == 0; + } + + last_vibration = now; + last_state_rumble_low = raw_amp_low; + last_state_rumble_high = raw_amp_high; + if (sdl_joystick) { + SDL_JoystickRumble(sdl_joystick.get(), raw_amp_low, raw_amp_high, time); + } + return false; + } + std::tuple GetAnalog(int axis_x, int axis_y, float range) const { float x = GetAxis(axis_x, range); float y = GetAxis(axis_y, range); @@ -139,6 +167,9 @@ private: } state; std::string guid; int port; + u16 last_state_rumble_high; + u16 last_state_rumble_low; + std::chrono::time_point last_vibration; std::unique_ptr sdl_joystick; std::unique_ptr sdl_controller; mutable std::mutex mutex; @@ -207,7 +238,7 @@ void SDLState::InitJoystick(int joystick_index) { sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); } if (!sdl_joystick) { - LOG_ERROR(Input, "failed to open joystick {}", joystick_index); + LOG_ERROR(Input, "Failed to open joystick {}", joystick_index); return; } const std::string guid = GetGUID(sdl_joystick); @@ -303,6 +334,12 @@ public: return joystick->GetButton(button); } + bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override { + const f32 new_amp_low = pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f)); + const f32 new_amp_high = pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f)); + return joystick->RumblePlay(new_amp_low, new_amp_high, 250); + } + private: std::shared_ptr joystick; int button; -- cgit v1.2.3 From ae6df703f5e15548b7dd076d5763adee547d6444 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 29 Sep 2020 16:22:50 -0300 Subject: qt/game_list: Give GameListSearchField::KeyReleaseEater a parent This fixes a memory leak as KeyReleaseEater's destructor was never called. --- src/yuzu/game_list.cpp | 5 +++-- src/yuzu/game_list_p.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index a9738e298..70d865112 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -25,7 +25,8 @@ #include "yuzu/main.h" #include "yuzu/uisettings.h" -GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {} +GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent) + : QObject(parent), gamelist{gamelist} {} // EventFilter in order to process systemkeys while editing the searchfield bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { @@ -116,7 +117,7 @@ void GameListSearchField::setFocus() { } GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { - auto* const key_release_eater = new KeyReleaseEater(parent); + auto* const key_release_eater = new KeyReleaseEater(parent, this); layout_filter = new QHBoxLayout; layout_filter->setMargin(8); label_filter = new QLabel; diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index 92779a9c7..248855aff 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -330,7 +330,7 @@ public: private: class KeyReleaseEater : public QObject { public: - explicit KeyReleaseEater(GameList* gamelist); + explicit KeyReleaseEater(GameList* gamelist, QObject* parent = nullptr); private: GameList* gamelist = nullptr; -- cgit v1.2.3 From 771a9c21cc2f401cb9fd653cefcfe9da78b8f1a7 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 29 Sep 2020 16:19:37 -0300 Subject: common/wall_clock: Add virtual destructors From -fsanitize=address, this code wasn't calling the proper destructor. Adding virtual destructors for each inherited class and the base class fixes this bug. While we are at it, mark the functions as final. --- src/common/wall_clock.cpp | 2 +- src/common/wall_clock.h | 2 ++ src/common/x64/native_clock.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp index 3afbdb898..7a20e95b7 100644 --- a/src/common/wall_clock.cpp +++ b/src/common/wall_clock.cpp @@ -15,7 +15,7 @@ namespace Common { using base_timer = std::chrono::steady_clock; using base_time_point = std::chrono::time_point; -class StandardWallClock : public WallClock { +class StandardWallClock final : public WallClock { public: StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency) : WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) { diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h index 5db30083d..bc7adfbf8 100644 --- a/src/common/wall_clock.h +++ b/src/common/wall_clock.h @@ -13,6 +13,8 @@ namespace Common { class WallClock { public: + virtual ~WallClock() = default; + /// Returns current wall time in nanoseconds [[nodiscard]] virtual std::chrono::nanoseconds GetTimeNS() = 0; diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index 891a3bbfd..7c503df26 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h @@ -12,7 +12,7 @@ namespace Common { namespace X64 { -class NativeClock : public WallClock { +class NativeClock final : public WallClock { public: NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency); -- cgit v1.2.3 From d7843b8ef2449a6af0bfd31b32bddae35bf99f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Locatti?= <42481638+goldenx86@users.noreply.github.com> Date: Wed, 30 Sep 2020 03:13:38 -0300 Subject: Remove ext_extended_dynamic_state blacklist Latest AMD 20.9.2 driver fixed this, there's no reason to keep it blocked, as the previous stable signed driver release doesn't include the extension. --- src/video_core/renderer_vulkan/vk_device.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp index 05e31f1de..3d8d3213d 100644 --- a/src/video_core/renderer_vulkan/vk_device.cpp +++ b/src/video_core/renderer_vulkan/vk_device.cpp @@ -388,14 +388,6 @@ bool VKDevice::Create() { CollectTelemetryParameters(); - if (ext_extended_dynamic_state && driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR) { - // AMD's proprietary driver supports VK_EXT_extended_dynamic_state but the field - // seems to be bugged. Blacklisting it for now. - LOG_WARNING(Render_Vulkan, - "Blacklisting AMD proprietary from VK_EXT_extended_dynamic_state"); - ext_extended_dynamic_state = false; - } - graphics_queue = logical.GetQueue(graphics_family); present_queue = logical.GetQueue(present_family); -- cgit v1.2.3 From 6ee1a784b8af5725b65e87cf0d7d87586a1873d1 Mon Sep 17 00:00:00 2001 From: Lukas Senionis Date: Sat, 26 Sep 2020 11:32:28 +0300 Subject: Reduce the "shake" requirements when configuring UDP. --- src/input_common/udp/client.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp index 2b6a68d4b..cf72f6fef 100644 --- a/src/input_common/udp/client.cpp +++ b/src/input_common/udp/client.cpp @@ -274,18 +274,22 @@ void Client::Reset() { void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3& acc, const Common::Vec3& gyro, bool touch) { + if (gyro.Length() > 0.2f) { + LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {}), touch={}", + client, gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2], touch); + } UDPPadStatus pad; if (touch) { pad.touch = PadTouch::Click; pad_queue[client].Push(pad); } for (size_t i = 0; i < 3; ++i) { - if (gyro[i] > 6.0f || gyro[i] < -6.0f) { + if (gyro[i] > 5.0f || gyro[i] < -5.0f) { pad.motion = static_cast(i); pad.motion_value = gyro[i]; pad_queue[client].Push(pad); } - if (acc[i] > 2.0f || acc[i] < -2.0f) { + if (acc[i] > 1.75f || acc[i] < -1.75f) { pad.motion = static_cast(i + 3); pad.motion_value = acc[i]; pad_queue[client].Push(pad); -- cgit v1.2.3 From 6380731486e687a0a6b60ac3a1bd68812e538e66 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> 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') 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 <39850852+Morph1984@users.noreply.github.com> 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') 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 <39850852+Morph1984@users.noreply.github.com> 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') 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 <39850852+Morph1984@users.noreply.github.com> 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') 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') 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') 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 2a24b1c9734a916e9a14579d4c550c84e83039b8 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 2 Oct 2020 21:19:35 -0300 Subject: video_core: Enforce -Wunused-variable and -Wunused-but-set-variable --- src/video_core/CMakeLists.txt | 8 +++++++- src/video_core/engines/maxwell_dma.cpp | 2 -- src/video_core/renderer_opengl/gl_device.cpp | 1 - 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index da9e9fdda..2be455679 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -273,5 +273,11 @@ endif() if (MSVC) target_compile_options(video_core PRIVATE /we4267) else() - target_compile_options(video_core PRIVATE -Werror=conversion -Wno-error=sign-conversion -Werror=switch) + target_compile_options(video_core PRIVATE + -Werror=conversion + -Wno-error=sign-conversion + -Werror=switch + -Werror=unused-variable + -Werror=unused-but-set-variable + ) endif() diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index e88290754..8fa359d0a 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -114,8 +114,6 @@ void MaxwellDMA::CopyBlockLinearToPitch() { const u32 block_depth = src_params.block_size.depth; const size_t src_size = CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth); - const size_t src_layer_size = - CalculateSize(true, bytes_per_pixel, width, height, 1, block_height, block_depth); if (read_buffer.size() < src_size) { read_buffer.resize(src_size); diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index e7d95149f..a94e4f72e 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp @@ -193,7 +193,6 @@ bool IsASTCSupported() { Device::Device() : max_uniform_buffers{BuildMaxUniformBuffers()}, base_bindings{BuildBaseBindings()} { const std::string_view vendor = reinterpret_cast(glGetString(GL_VENDOR)); - const std::string_view renderer = reinterpret_cast(glGetString(GL_RENDERER)); const std::string_view version = reinterpret_cast(glGetString(GL_VERSION)); const std::vector extensions = GetExtensions(); -- cgit v1.2.3 From a220d8799ed332c1d8f2231b18079b1210511bcd Mon Sep 17 00:00:00 2001 From: german Date: Sat, 3 Oct 2020 22:22:01 -0500 Subject: Add compatibility with only accelerometer and auto calibrate for drift --- src/input_common/motion_input.cpp | 112 ++++++++++++++++++++++++++++++++++---- src/input_common/motion_input.h | 6 +- 2 files changed, 106 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/input_common/motion_input.cpp b/src/input_common/motion_input.cpp index 22a849866..d3e736044 100644 --- a/src/input_common/motion_input.cpp +++ b/src/input_common/motion_input.cpp @@ -16,8 +16,16 @@ void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) { void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) { gyro = gyroscope - gyro_drift; + + // Auto adjust drift to minimize drift + if (!IsMoving(0.1f)) { + gyro_drift = (gyro_drift * 0.9999f) + (gyroscope * 0.0001f); + } + if (gyro.Length2() < gyro_threshold) { gyro = {}; + } else { + only_accelerometer = false; } } @@ -49,7 +57,7 @@ bool MotionInput::IsCalibrated(f32 sensitivity) const { return real_error.Length() < sensitivity; } -void MotionInput::UpdateRotation(u64 elapsed_time) { +void MotionInput::UpdateRotation(const u64 elapsed_time) { const f32 sample_period = elapsed_time / 1000000.0f; if (sample_period > 0.1f) { return; @@ -57,7 +65,7 @@ void MotionInput::UpdateRotation(u64 elapsed_time) { rotations += gyro * sample_period; } -void MotionInput::UpdateOrientation(u64 elapsed_time) { +void MotionInput::UpdateOrientation(const u64 elapsed_time) { if (!IsCalibrated(0.1f)) { ResetOrientation(); } @@ -68,7 +76,7 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) { f32 q4 = quat.xyz[2]; const f32 sample_period = elapsed_time / 1000000.0f; - // ignore invalid elapsed time + // Ignore invalid elapsed time if (sample_period > 0.1f) { return; } @@ -80,6 +88,13 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) { rad_gyro.y = -swap; rad_gyro.z = -rad_gyro.z; + // Clear gyro values if there is no gyro present + if (only_accelerometer) { + rad_gyro.x = 0; + rad_gyro.y = 0; + rad_gyro.z = 0; + } + // Ignore drift correction if acceleration is not reliable if (accel.Length() >= 0.75f && accel.Length() <= 1.25f) { const f32 ax = -normal_accel.x; @@ -92,8 +107,11 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) { const f32 vz = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4; // Error is cross product between estimated direction and measured direction of gravity - const Common::Vec3f new_real_error = {az * vx - ax * vz, ay * vz - az * vy, - ax * vy - ay * vx}; + const Common::Vec3f new_real_error = { + az * vx - ax * vz, + ay * vz - az * vy, + ax * vy - ay * vx, + }; derivative_error = new_real_error - real_error; real_error = new_real_error; @@ -106,9 +124,22 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) { } // Apply feedback terms - rad_gyro += kp * real_error; - rad_gyro += ki * integral_error; - rad_gyro += kd * derivative_error; + if (!only_accelerometer) { + rad_gyro += kp * real_error; + rad_gyro += ki * integral_error; + rad_gyro += kd * derivative_error; + } else { + // Give more weight to acelerometer values to compensate for the lack of gyro + rad_gyro += 35.0f * kp * real_error; + rad_gyro += 10.0f * ki * integral_error; + rad_gyro += 10.0f * kd * derivative_error; + + // Emulate gyro values for games that need them + gyro.x = -rad_gyro.y; + gyro.y = rad_gyro.x; + gyro.z = -rad_gyro.z; + UpdateRotation(elapsed_time); + } } const f32 gx = rad_gyro.y; @@ -143,6 +174,67 @@ std::array MotionInput::GetOrientation() const { Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10])}; } +void MotionInput::SetOrientationFromAccelerometer() { + int iterations = 0; + const f32 sample_period = 0.015f; + + const auto normal_accel = accel.Normalized(); + const f32 ax = -normal_accel.x; + const f32 ay = normal_accel.y; + const f32 az = -normal_accel.z; + + while (!IsCalibrated(0.01f) && ++iterations < 100) { + // Short name local variable for readability + f32 q1 = quat.w; + f32 q2 = quat.xyz[0]; + f32 q3 = quat.xyz[1]; + f32 q4 = quat.xyz[2]; + + Common::Vec3f rad_gyro = {}; + const f32 ax = -normal_accel.x; + const f32 ay = normal_accel.y; + const f32 az = -normal_accel.z; + + // Estimated direction of gravity + const f32 vx = 2.0f * (q2 * q4 - q1 * q3); + const f32 vy = 2.0f * (q1 * q2 + q3 * q4); + const f32 vz = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4; + + // Error is cross product between estimated direction and measured direction of gravity + const Common::Vec3f new_real_error = { + az * vx - ax * vz, + ay * vz - az * vy, + ax * vy - ay * vx, + }; + + derivative_error = new_real_error - real_error; + real_error = new_real_error; + + rad_gyro += 10.0f * kp * real_error; + rad_gyro += 5.0f * ki * integral_error; + rad_gyro += 10.0f * kd * derivative_error; + + const f32 gx = rad_gyro.y; + const f32 gy = rad_gyro.x; + const f32 gz = rad_gyro.z; + + // Integrate rate of change of quaternion + const f32 pa = q2; + const f32 pb = q3; + const f32 pc = q4; + q1 = q1 + (-q2 * gx - q3 * gy - q4 * gz) * (0.5f * sample_period); + q2 = pa + (q1 * gx + pb * gz - pc * gy) * (0.5f * sample_period); + q3 = pb + (q1 * gy - pa * gz + pc * gx) * (0.5f * sample_period); + q4 = pc + (q1 * gz + pa * gy - pb * gx) * (0.5f * sample_period); + + quat.w = q1; + quat.xyz[0] = q2; + quat.xyz[1] = q3; + quat.xyz[2] = q4; + quat = quat.Normalized(); + } +} + Common::Vec3f MotionInput::GetAcceleration() const { return accel; } @@ -160,17 +252,17 @@ Common::Vec3f MotionInput::GetRotations() const { } void MotionInput::ResetOrientation() { - if (!reset_enabled) { + if (!reset_enabled || only_accelerometer) { return; } if (!IsMoving(0.5f) && accel.z <= -0.9f) { ++reset_counter; if (reset_counter > 900) { - // TODO: calculate quaternion from gravity vector quat.w = 0; quat.xyz[0] = 0; quat.xyz[1] = 0; quat.xyz[2] = -1; + SetOrientationFromAccelerometer(); integral_error = {}; reset_counter = 0; } diff --git a/src/input_common/motion_input.h b/src/input_common/motion_input.h index 54b4439d9..f6c1fece7 100644 --- a/src/input_common/motion_input.h +++ b/src/input_common/motion_input.h @@ -29,8 +29,8 @@ public: void EnableReset(bool reset); void ResetRotations(); - void UpdateRotation(u64 elapsed_time); - void UpdateOrientation(u64 elapsed_time); + void UpdateRotation(const u64 elapsed_time); + void UpdateOrientation(const u64 elapsed_time); std::array GetOrientation() const; Common::Vec3f GetAcceleration() const; @@ -43,6 +43,7 @@ public: private: void ResetOrientation(); + void SetOrientationFromAccelerometer(); // PID constants const f32 kp; @@ -63,6 +64,7 @@ private: f32 gyro_threshold = 0.0f; u32 reset_counter = 0; bool reset_enabled = true; + bool only_accelerometer = true; }; } // namespace InputCommon -- cgit v1.2.3 From a54aee290ff8f94d1fefc70121512dbc46f6c190 Mon Sep 17 00:00:00 2001 From: german Date: Sun, 4 Oct 2020 18:15:53 -0500 Subject: Address comments --- src/input_common/motion_input.cpp | 76 +++++++++++++++++++-------------------- src/input_common/motion_input.h | 4 +-- 2 files changed, 40 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/input_common/motion_input.cpp b/src/input_common/motion_input.cpp index d3e736044..182a2869a 100644 --- a/src/input_common/motion_input.cpp +++ b/src/input_common/motion_input.cpp @@ -57,7 +57,7 @@ bool MotionInput::IsCalibrated(f32 sensitivity) const { return real_error.Length() < sensitivity; } -void MotionInput::UpdateRotation(const u64 elapsed_time) { +void MotionInput::UpdateRotation(u64 elapsed_time) { const f32 sample_period = elapsed_time / 1000000.0f; if (sample_period > 0.1f) { return; @@ -65,7 +65,7 @@ void MotionInput::UpdateRotation(const u64 elapsed_time) { rotations += gyro * sample_period; } -void MotionInput::UpdateOrientation(const u64 elapsed_time) { +void MotionInput::UpdateOrientation(u64 elapsed_time) { if (!IsCalibrated(0.1f)) { ResetOrientation(); } @@ -174,6 +174,42 @@ std::array MotionInput::GetOrientation() const { Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10])}; } +Common::Vec3f MotionInput::GetAcceleration() const { + return accel; +} + +Common::Vec3f MotionInput::GetGyroscope() const { + return gyro; +} + +Common::Quaternion MotionInput::GetQuaternion() const { + return quat; +} + +Common::Vec3f MotionInput::GetRotations() const { + return rotations; +} + +void MotionInput::ResetOrientation() { + if (!reset_enabled || only_accelerometer) { + return; + } + if (!IsMoving(0.5f) && accel.z <= -0.9f) { + ++reset_counter; + if (reset_counter > 900) { + quat.w = 0; + quat.xyz[0] = 0; + quat.xyz[1] = 0; + quat.xyz[2] = -1; + SetOrientationFromAccelerometer(); + integral_error = {}; + reset_counter = 0; + } + } else { + reset_counter = 0; + } +} + void MotionInput::SetOrientationFromAccelerometer() { int iterations = 0; const f32 sample_period = 0.015f; @@ -234,40 +270,4 @@ void MotionInput::SetOrientationFromAccelerometer() { quat = quat.Normalized(); } } - -Common::Vec3f MotionInput::GetAcceleration() const { - return accel; -} - -Common::Vec3f MotionInput::GetGyroscope() const { - return gyro; -} - -Common::Quaternion MotionInput::GetQuaternion() const { - return quat; -} - -Common::Vec3f MotionInput::GetRotations() const { - return rotations; -} - -void MotionInput::ResetOrientation() { - if (!reset_enabled || only_accelerometer) { - return; - } - if (!IsMoving(0.5f) && accel.z <= -0.9f) { - ++reset_counter; - if (reset_counter > 900) { - quat.w = 0; - quat.xyz[0] = 0; - quat.xyz[1] = 0; - quat.xyz[2] = -1; - SetOrientationFromAccelerometer(); - integral_error = {}; - reset_counter = 0; - } - } else { - reset_counter = 0; - } -} } // namespace InputCommon diff --git a/src/input_common/motion_input.h b/src/input_common/motion_input.h index f6c1fece7..c90ee64e5 100644 --- a/src/input_common/motion_input.h +++ b/src/input_common/motion_input.h @@ -29,8 +29,8 @@ public: void EnableReset(bool reset); void ResetRotations(); - void UpdateRotation(const u64 elapsed_time); - void UpdateOrientation(const u64 elapsed_time); + void UpdateRotation(u64 elapsed_time); + void UpdateOrientation(u64 elapsed_time); std::array GetOrientation() const; Common::Vec3f GetAcceleration() const; -- cgit v1.2.3 From cd3e959f237352f863e16ce7ca94f837c4f611db Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 7 Oct 2020 17:13:20 -0300 Subject: renderer_vulkan/wrapper: Fix physical device sorting The old code had a sort function that was invalid and it didn't work as expected when the base vector had a different order (e.g. renderdoc was attached). This sorts devices as expected and fixes a debug assert on MSVC. --- src/video_core/renderer_vulkan/wrapper.cpp | 48 ++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp index 1fb14e190..2598440fb 100644 --- a/src/video_core/renderer_vulkan/wrapper.cpp +++ b/src/video_core/renderer_vulkan/wrapper.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -17,21 +18,42 @@ namespace Vulkan::vk { namespace { +template +void SortPhysicalDevices(std::vector& devices, const InstanceDispatch& dld, + Func&& func) { + // Calling GetProperties calls Vulkan more than needed. But they are supposed to be cheap + // functions. + std::stable_sort(devices.begin(), devices.end(), + [&dld, &func](VkPhysicalDevice lhs, VkPhysicalDevice rhs) { + return func(vk::PhysicalDevice(lhs, dld).GetProperties(), + vk::PhysicalDevice(rhs, dld).GetProperties()); + }); +} + +void SortPhysicalDevicesPerVendor(std::vector& devices, + const InstanceDispatch& dld, + std::initializer_list vendor_ids) { + for (auto it = vendor_ids.end(); it != vendor_ids.begin();) { + --it; + SortPhysicalDevices(devices, dld, [id = *it](const auto& lhs, const auto& rhs) { + return lhs.vendorID == id && rhs.vendorID != id; + }); + } +} + void SortPhysicalDevices(std::vector& devices, const InstanceDispatch& dld) { - std::stable_sort(devices.begin(), devices.end(), [&](auto lhs, auto rhs) { - // This will call Vulkan more than needed, but these calls are cheap. - const auto lhs_properties = vk::PhysicalDevice(lhs, dld).GetProperties(); - const auto rhs_properties = vk::PhysicalDevice(rhs, dld).GetProperties(); - - // Prefer discrete GPUs, Nvidia over AMD, AMD over Intel, Intel over the rest. - const bool preferred = - (lhs_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && - rhs_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) || - (lhs_properties.vendorID == 0x10DE && rhs_properties.vendorID != 0x10DE) || - (lhs_properties.vendorID == 0x1002 && rhs_properties.vendorID != 0x1002) || - (lhs_properties.vendorID == 0x8086 && rhs_properties.vendorID != 0x8086); - return !preferred; + // Sort by name, this will set a base and make GPUs with higher numbers appear first + // (e.g. GTX 1650 will intentionally be listed before a GTX 1080). + SortPhysicalDevices(devices, dld, [](const auto& lhs, const auto& rhs) { + return std::string_view{lhs.deviceName} > std::string_view{rhs.deviceName}; + }); + // Prefer discrete over non-discrete + SortPhysicalDevices(devices, dld, [](const auto& lhs, const auto& rhs) { + return lhs.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && + rhs.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; }); + // Prefer Nvidia over AMD, AMD over Intel, Intel over the rest. + SortPhysicalDevicesPerVendor(devices, dld, {0x10DE, 0x1002, 0x8086}); } template -- cgit v1.2.3 From dffaffaac1eb633d5907202df1ca0dbf338a6095 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 7 Oct 2020 23:17:46 -0300 Subject: shader/texture: Implement CUBE texture type for TMML and fix arrays TMML takes an array argument that has no known meaning, this one appears as the first component in gpr8 followed by s, t and r. Skip this component when arrays are being used. Also implement CUBE texture types. - Used by Pikmin 3: Deluxe Demo. --- src/video_core/shader/decode/texture.cpp | 41 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index a03b50e39..4e932a4b6 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -292,33 +292,36 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { break; } - std::vector coords; - - // TODO: Add coordinates for different samplers once other texture types are implemented. - switch (texture_type) { - case TextureType::Texture1D: - coords.push_back(GetRegister(instr.gpr8)); - break; - case TextureType::Texture2D: - coords.push_back(GetRegister(instr.gpr8.Value() + 0)); - coords.push_back(GetRegister(instr.gpr8.Value() + 1)); - break; - default: - UNIMPLEMENTED_MSG("Unhandled texture type {}", static_cast(texture_type)); + const u64 base_index = is_array ? 1 : 0; + const u64 num_components = [texture_type] { + switch (texture_type) { + case TextureType::Texture1D: + return 1; + case TextureType::Texture2D: + return 2; + case TextureType::TextureCube: + return 3; + default: + UNIMPLEMENTED_MSG("Unhandled texture type {}", static_cast(texture_type)); + return 2; + } + }(); + // TODO: What's the array component used for? - // Fallback to interpreting as a 2D texture for now - coords.push_back(GetRegister(instr.gpr8.Value() + 0)); - coords.push_back(GetRegister(instr.gpr8.Value() + 1)); + std::vector coords; + coords.reserve(num_components); + for (u64 component = 0; component < num_components; ++component) { + coords.push_back(GetRegister(instr.gpr8.Value() + base_index + component)); } + u32 indexer = 0; for (u32 element = 0; element < 2; ++element) { if (!instr.tmml.IsComponentEnabled(element)) { continue; } - auto params = coords; MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element, index_var}; - const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); - SetTemporary(bb, indexer++, value); + Node value = Operation(OperationCode::TextureQueryLod, meta, coords); + SetTemporary(bb, indexer++, std::move(value)); } for (u32 i = 0; i < indexer; ++i) { SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); -- cgit v1.2.3 From 0120e5b1d97f1ebbdd23eed359804221eb697ad2 Mon Sep 17 00:00:00 2001 From: goldenx86 Date: Thu, 8 Oct 2020 21:17:08 -0300 Subject: vk_device: Block VK_EXT_extended_dynamic_state for RDNA devices RDNA devices seem to crash when using VK_EXT_extended_dynamic_state in the latest 20.9.2 proprietary Windows drivers. As a workaround, for now we block device names corresponding to current RDNA released products. --- src/video_core/renderer_vulkan/vk_device.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp index 3d8d3213d..1f057b43b 100644 --- a/src/video_core/renderer_vulkan/vk_device.cpp +++ b/src/video_core/renderer_vulkan/vk_device.cpp @@ -79,6 +79,21 @@ VkFormatFeatureFlags GetFormatFeatures(VkFormatProperties properties, FormatType } } +[[nodiscard]] bool IsRDNA(std::string_view device_name, VkDriverIdKHR driver_id) { + static constexpr std::array RDNA_DEVICES{ + "5700", + "5600", + "5500", + "5300", + }; + if (driver_id != VK_DRIVER_ID_AMD_PROPRIETARY_KHR) { + return false; + } + return std::any_of(RDNA_DEVICES.begin(), RDNA_DEVICES.end(), [device_name](const char* name) { + return device_name.find(name) != std::string_view::npos; + }); +} + std::unordered_map GetFormatProperties( vk::PhysicalDevice physical, const vk::InstanceDispatch& dld) { static constexpr std::array formats{ @@ -388,6 +403,15 @@ bool VKDevice::Create() { CollectTelemetryParameters(); + if (ext_extended_dynamic_state && IsRDNA(properties.deviceName, driver_id)) { + // AMD's proprietary driver supports VK_EXT_extended_dynamic_state but on RDNA devices it + // seems to cause stability issues + LOG_WARNING( + Render_Vulkan, + "Blacklisting AMD proprietary on RDNA devices from VK_EXT_extended_dynamic_state"); + ext_extended_dynamic_state = false; + } + graphics_queue = logical.GetQueue(graphics_family); present_queue = logical.GetQueue(present_family); -- cgit v1.2.3 From e1600b0962c78302b05d4b98d75245b980a03831 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 2 Oct 2020 21:24:22 -0300 Subject: video_core: Enforce -Wclass-memaccess --- src/video_core/CMakeLists.txt | 1 + src/video_core/engines/shader_header.h | 13 ++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 2be455679..3df54816d 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -279,5 +279,6 @@ else() -Werror=switch -Werror=unused-variable -Werror=unused-but-set-variable + -Werror=class-memaccess ) endif() diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h index 72e2a33d5..ceec05459 100644 --- a/src/video_core/engines/shader_header.h +++ b/src/video_core/engines/shader_header.h @@ -41,30 +41,30 @@ struct Header { BitField<26, 1, u32> does_load_or_store; BitField<27, 1, u32> does_fp64; BitField<28, 4, u32> stream_out_mask; - } common0{}; + } common0; union { BitField<0, 24, u32> shader_local_memory_low_size; BitField<24, 8, u32> per_patch_attribute_count; - } common1{}; + } common1; union { BitField<0, 24, u32> shader_local_memory_high_size; BitField<24, 8, u32> threads_per_input_primitive; - } common2{}; + } common2; union { BitField<0, 24, u32> shader_local_memory_crs_size; BitField<24, 4, OutputTopology> output_topology; BitField<28, 4, u32> reserved; - } common3{}; + } common3; union { BitField<0, 12, u32> max_output_vertices; BitField<12, 8, u32> store_req_start; // NOTE: not used by geometry shaders. BitField<20, 4, u32> reserved; BitField<24, 8, u32> store_req_end; // NOTE: not used by geometry shaders. - } common4{}; + } common4; union { struct { @@ -145,7 +145,7 @@ struct Header { } } ps; - std::array raw{}; + std::array raw; }; u64 GetLocalMemorySize() const { @@ -153,7 +153,6 @@ struct Header { (common2.shader_local_memory_high_size << 24)); } }; - static_assert(sizeof(Header) == 0x50, "Incorrect structure size"); } // namespace Tegra::Shader -- 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') 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 +- src/yuzu/configuration/configure_system.cpp | 26 +- 9 files changed, 341 insertions(+), 198 deletions(-) (limited to 'src') 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