diff options
Diffstat (limited to 'src')
74 files changed, 1475 insertions, 1083 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 3d795b57f..e5d3158c8 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -291,9 +291,6 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string | |||
| 291 | // Initialize filesystem. | 291 | // Initialize filesystem. |
| 292 | ConfigureFilesystemProvider(filepath); | 292 | ConfigureFilesystemProvider(filepath); |
| 293 | 293 | ||
| 294 | // Initialize account manager | ||
| 295 | m_profile_manager = std::make_unique<Service::Account::ProfileManager>(); | ||
| 296 | |||
| 297 | // Load the ROM. | 294 | // Load the ROM. |
| 298 | m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath); | 295 | m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath); |
| 299 | if (m_load_result != Core::SystemResultStatus::Success) { | 296 | if (m_load_result != Core::SystemResultStatus::Success) { |
| @@ -736,8 +733,8 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmptyUserDirectory(JNIEnv* | |||
| 736 | auto vfs_nand_dir = EmulationSession::GetInstance().System().GetFilesystem()->OpenDirectory( | 733 | auto vfs_nand_dir = EmulationSession::GetInstance().System().GetFilesystem()->OpenDirectory( |
| 737 | Common::FS::PathToUTF8String(nand_dir), FileSys::Mode::Read); | 734 | Common::FS::PathToUTF8String(nand_dir), FileSys::Mode::Read); |
| 738 | 735 | ||
| 739 | Service::Account::ProfileManager manager; | 736 | const auto user_id = EmulationSession::GetInstance().System().GetProfileManager().GetUser( |
| 740 | const auto user_id = manager.GetUser(static_cast<std::size_t>(0)); | 737 | static_cast<std::size_t>(0)); |
| 741 | ASSERT(user_id); | 738 | ASSERT(user_id); |
| 742 | 739 | ||
| 743 | const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( | 740 | const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( |
diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index 78ef96802..f1457bd1f 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h | |||
| @@ -73,7 +73,6 @@ private: | |||
| 73 | std::atomic<bool> m_is_running = false; | 73 | std::atomic<bool> m_is_running = false; |
| 74 | std::atomic<bool> m_is_paused = false; | 74 | std::atomic<bool> m_is_paused = false; |
| 75 | SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; | 75 | SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; |
| 76 | std::unique_ptr<Service::Account::ProfileManager> m_profile_manager; | ||
| 77 | std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider; | 76 | std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider; |
| 78 | 77 | ||
| 79 | // GPU driver parameters | 78 | // GPU driver parameters |
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp index c3a81f9a9..d2f50432a 100644 --- a/src/common/fs/path_util.cpp +++ b/src/common/fs/path_util.cpp | |||
| @@ -354,18 +354,36 @@ std::string_view RemoveTrailingSlash(std::string_view path) { | |||
| 354 | return path; | 354 | return path; |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | std::vector<std::string> SplitPathComponents(std::string_view filename) { | 357 | template <typename F> |
| 358 | std::string copy(filename); | 358 | static void ForEachPathComponent(std::string_view filename, F&& cb) { |
| 359 | std::replace(copy.begin(), copy.end(), '\\', '/'); | 359 | const char* component_begin = filename.data(); |
| 360 | std::vector<std::string> out; | 360 | const char* const end = component_begin + filename.size(); |
| 361 | 361 | for (const char* it = component_begin; it != end; ++it) { | |
| 362 | std::stringstream stream(copy); | 362 | const char c = *it; |
| 363 | std::string item; | 363 | if (c == '\\' || c == '/') { |
| 364 | while (std::getline(stream, item, '/')) { | 364 | if (component_begin != it) { |
| 365 | out.push_back(std::move(item)); | 365 | cb(std::string_view{component_begin, it}); |
| 366 | } | ||
| 367 | component_begin = it + 1; | ||
| 368 | } | ||
| 366 | } | 369 | } |
| 370 | if (component_begin != end) { | ||
| 371 | cb(std::string_view{component_begin, end}); | ||
| 372 | } | ||
| 373 | } | ||
| 374 | |||
| 375 | std::vector<std::string_view> SplitPathComponents(std::string_view filename) { | ||
| 376 | std::vector<std::string_view> components; | ||
| 377 | ForEachPathComponent(filename, [&](auto component) { components.emplace_back(component); }); | ||
| 378 | |||
| 379 | return components; | ||
| 380 | } | ||
| 381 | |||
| 382 | std::vector<std::string> SplitPathComponentsCopy(std::string_view filename) { | ||
| 383 | std::vector<std::string> components; | ||
| 384 | ForEachPathComponent(filename, [&](auto component) { components.emplace_back(component); }); | ||
| 367 | 385 | ||
| 368 | return out; | 386 | return components; |
| 369 | } | 387 | } |
| 370 | 388 | ||
| 371 | std::string SanitizePath(std::string_view path_, DirectorySeparator directory_separator) { | 389 | std::string SanitizePath(std::string_view path_, DirectorySeparator directory_separator) { |
diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h index 2874ea738..23c8b1359 100644 --- a/src/common/fs/path_util.h +++ b/src/common/fs/path_util.h | |||
| @@ -289,7 +289,11 @@ enum class DirectorySeparator { | |||
| 289 | 289 | ||
| 290 | // Splits the path on '/' or '\' and put the components into a vector | 290 | // Splits the path on '/' or '\' and put the components into a vector |
| 291 | // i.e. "C:\Users\Yuzu\Documents\save.bin" becomes {"C:", "Users", "Yuzu", "Documents", "save.bin" } | 291 | // i.e. "C:\Users\Yuzu\Documents\save.bin" becomes {"C:", "Users", "Yuzu", "Documents", "save.bin" } |
| 292 | [[nodiscard]] std::vector<std::string> SplitPathComponents(std::string_view filename); | 292 | [[nodiscard]] std::vector<std::string_view> SplitPathComponents(std::string_view filename); |
| 293 | |||
| 294 | // Splits the path on '/' or '\' and put the components into a vector | ||
| 295 | // i.e. "C:\Users\Yuzu\Documents\save.bin" becomes {"C:", "Users", "Yuzu", "Documents", "save.bin" } | ||
| 296 | [[nodiscard]] std::vector<std::string> SplitPathComponentsCopy(std::string_view filename); | ||
| 293 | 297 | ||
| 294 | // Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\' | 298 | // Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\' |
| 295 | // depending if directory_separator is BackwardSlash or PlatformDefault and running on windows | 299 | // depending if directory_separator is BackwardSlash or PlatformDefault and running on windows |
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 4bfc64f2d..e540375b8 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp | |||
| @@ -11,10 +11,6 @@ | |||
| 11 | 11 | ||
| 12 | #elif defined(__linux__) || defined(__FreeBSD__) // ^^^ Windows ^^^ vvv Linux vvv | 12 | #elif defined(__linux__) || defined(__FreeBSD__) // ^^^ Windows ^^^ vvv Linux vvv |
| 13 | 13 | ||
| 14 | #ifdef ANDROID | ||
| 15 | #include <android/sharedmem.h> | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #ifndef _GNU_SOURCE | 14 | #ifndef _GNU_SOURCE |
| 19 | #define _GNU_SOURCE | 15 | #define _GNU_SOURCE |
| 20 | #endif | 16 | #endif |
| @@ -193,6 +189,11 @@ public: | |||
| 193 | } | 189 | } |
| 194 | } | 190 | } |
| 195 | 191 | ||
| 192 | bool ClearBackingRegion(size_t physical_offset, size_t length) { | ||
| 193 | // TODO: This does not seem to be possible on Windows. | ||
| 194 | return false; | ||
| 195 | } | ||
| 196 | |||
| 196 | void EnableDirectMappedAddress() { | 197 | void EnableDirectMappedAddress() { |
| 197 | // TODO | 198 | // TODO |
| 198 | UNREACHABLE(); | 199 | UNREACHABLE(); |
| @@ -442,9 +443,7 @@ public: | |||
| 442 | } | 443 | } |
| 443 | 444 | ||
| 444 | // Backing memory initialization | 445 | // Backing memory initialization |
| 445 | #ifdef ANDROID | 446 | #if defined(__FreeBSD__) && __FreeBSD__ < 13 |
| 446 | fd = ASharedMemory_create("HostMemory", backing_size); | ||
| 447 | #elif defined(__FreeBSD__) && __FreeBSD__ < 13 | ||
| 448 | // XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30 | 447 | // XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30 |
| 449 | fd = shm_open(SHM_ANON, O_RDWR, 0600); | 448 | fd = shm_open(SHM_ANON, O_RDWR, 0600); |
| 450 | #else | 449 | #else |
| @@ -455,7 +454,6 @@ public: | |||
| 455 | throw std::bad_alloc{}; | 454 | throw std::bad_alloc{}; |
| 456 | } | 455 | } |
| 457 | 456 | ||
| 458 | #ifndef ANDROID | ||
| 459 | // Defined to extend the file with zeros | 457 | // Defined to extend the file with zeros |
| 460 | int ret = ftruncate(fd, backing_size); | 458 | int ret = ftruncate(fd, backing_size); |
| 461 | if (ret != 0) { | 459 | if (ret != 0) { |
| @@ -463,7 +461,6 @@ public: | |||
| 463 | strerror(errno)); | 461 | strerror(errno)); |
| 464 | throw std::bad_alloc{}; | 462 | throw std::bad_alloc{}; |
| 465 | } | 463 | } |
| 466 | #endif | ||
| 467 | 464 | ||
| 468 | backing_base = static_cast<u8*>( | 465 | backing_base = static_cast<u8*>( |
| 469 | mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); | 466 | mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); |
| @@ -552,6 +549,19 @@ public: | |||
| 552 | ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno)); | 549 | ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno)); |
| 553 | } | 550 | } |
| 554 | 551 | ||
| 552 | bool ClearBackingRegion(size_t physical_offset, size_t length) { | ||
| 553 | #ifdef __linux__ | ||
| 554 | // Set MADV_REMOVE on backing map to destroy it instantly. | ||
| 555 | // This also deletes the area from the backing file. | ||
| 556 | int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE); | ||
| 557 | ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno)); | ||
| 558 | |||
| 559 | return true; | ||
| 560 | #else | ||
| 561 | return false; | ||
| 562 | #endif | ||
| 563 | } | ||
| 564 | |||
| 555 | void EnableDirectMappedAddress() { | 565 | void EnableDirectMappedAddress() { |
| 556 | virtual_base = nullptr; | 566 | virtual_base = nullptr; |
| 557 | } | 567 | } |
| @@ -623,6 +633,10 @@ public: | |||
| 623 | 633 | ||
| 624 | void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {} | 634 | void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {} |
| 625 | 635 | ||
| 636 | bool ClearBackingRegion(size_t physical_offset, size_t length) { | ||
| 637 | return false; | ||
| 638 | } | ||
| 639 | |||
| 626 | void EnableDirectMappedAddress() {} | 640 | void EnableDirectMappedAddress() {} |
| 627 | 641 | ||
| 628 | u8* backing_base{nullptr}; | 642 | u8* backing_base{nullptr}; |
| @@ -698,6 +712,12 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, bool read, bool w | |||
| 698 | impl->Protect(virtual_offset + virtual_base_offset, length, read, write, execute); | 712 | impl->Protect(virtual_offset + virtual_base_offset, length, read, write, execute); |
| 699 | } | 713 | } |
| 700 | 714 | ||
| 715 | void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value) { | ||
| 716 | if (!impl || fill_value != 0 || !impl->ClearBackingRegion(physical_offset, length)) { | ||
| 717 | std::memset(backing_base + physical_offset, fill_value, length); | ||
| 718 | } | ||
| 719 | } | ||
| 720 | |||
| 701 | void HostMemory::EnableDirectMappedAddress() { | 721 | void HostMemory::EnableDirectMappedAddress() { |
| 702 | if (impl) { | 722 | if (impl) { |
| 703 | impl->EnableDirectMappedAddress(); | 723 | impl->EnableDirectMappedAddress(); |
diff --git a/src/common/host_memory.h b/src/common/host_memory.h index cebfacab2..747c5850c 100644 --- a/src/common/host_memory.h +++ b/src/common/host_memory.h | |||
| @@ -48,6 +48,8 @@ public: | |||
| 48 | 48 | ||
| 49 | void EnableDirectMappedAddress(); | 49 | void EnableDirectMappedAddress(); |
| 50 | 50 | ||
| 51 | void ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value); | ||
| 52 | |||
| 51 | [[nodiscard]] u8* BackingBasePointer() noexcept { | 53 | [[nodiscard]] u8* BackingBasePointer() noexcept { |
| 52 | return backing_base; | 54 | return backing_base; |
| 53 | } | 55 | } |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index bffe68bd3..b22c9fd05 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -549,6 +549,11 @@ add_library(core STATIC | |||
| 549 | hle/service/hid/xcd.cpp | 549 | hle/service/hid/xcd.cpp |
| 550 | hle/service/hid/xcd.h | 550 | hle/service/hid/xcd.h |
| 551 | hle/service/hid/errors.h | 551 | hle/service/hid/errors.h |
| 552 | hle/service/hid/controllers/types/debug_pad_types.h | ||
| 553 | hle/service/hid/controllers/types/keyboard_types.h | ||
| 554 | hle/service/hid/controllers/types/mouse_types.h | ||
| 555 | hle/service/hid/controllers/types/npad_types.h | ||
| 556 | hle/service/hid/controllers/types/touch_types.h | ||
| 552 | hle/service/hid/controllers/applet_resource.cpp | 557 | hle/service/hid/controllers/applet_resource.cpp |
| 553 | hle/service/hid/controllers/applet_resource.h | 558 | hle/service/hid/controllers/applet_resource.h |
| 554 | hle/service/hid/controllers/console_six_axis.cpp | 559 | hle/service/hid/controllers/console_six_axis.cpp |
| @@ -569,14 +574,15 @@ add_library(core STATIC | |||
| 569 | hle/service/hid/controllers/palma.h | 574 | hle/service/hid/controllers/palma.h |
| 570 | hle/service/hid/controllers/seven_six_axis.cpp | 575 | hle/service/hid/controllers/seven_six_axis.cpp |
| 571 | hle/service/hid/controllers/seven_six_axis.h | 576 | hle/service/hid/controllers/seven_six_axis.h |
| 577 | hle/service/hid/controllers/shared_memory_format.h | ||
| 578 | hle/service/hid/controllers/shared_memory_holder.cpp | ||
| 579 | hle/service/hid/controllers/shared_memory_holder.h | ||
| 572 | hle/service/hid/controllers/six_axis.cpp | 580 | hle/service/hid/controllers/six_axis.cpp |
| 573 | hle/service/hid/controllers/six_axis.h | 581 | hle/service/hid/controllers/six_axis.h |
| 574 | hle/service/hid/controllers/stubbed.cpp | 582 | hle/service/hid/controllers/stubbed.cpp |
| 575 | hle/service/hid/controllers/stubbed.h | 583 | hle/service/hid/controllers/stubbed.h |
| 576 | hle/service/hid/controllers/touchscreen.cpp | 584 | hle/service/hid/controllers/touchscreen.cpp |
| 577 | hle/service/hid/controllers/touchscreen.h | 585 | hle/service/hid/controllers/touchscreen.h |
| 578 | hle/service/hid/controllers/xpad.cpp | ||
| 579 | hle/service/hid/controllers/xpad.h | ||
| 580 | hle/service/hid/hidbus/hidbus_base.cpp | 586 | hle/service/hid/hidbus/hidbus_base.cpp |
| 581 | hle/service/hid/hidbus/hidbus_base.h | 587 | hle/service/hid/hidbus/hidbus_base.h |
| 582 | hle/service/hid/hidbus/ringcon.cpp | 588 | hle/service/hid/hidbus/ringcon.cpp |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 229cb879c..b14f74976 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include "core/hle/kernel/k_scheduler.h" | 36 | #include "core/hle/kernel/k_scheduler.h" |
| 37 | #include "core/hle/kernel/kernel.h" | 37 | #include "core/hle/kernel/kernel.h" |
| 38 | #include "core/hle/kernel/physical_core.h" | 38 | #include "core/hle/kernel/physical_core.h" |
| 39 | #include "core/hle/service/acc/profile_manager.h" | ||
| 39 | #include "core/hle/service/am/applets/applets.h" | 40 | #include "core/hle/service/am/applets/applets.h" |
| 40 | #include "core/hle/service/apm/apm_controller.h" | 41 | #include "core/hle/service/apm/apm_controller.h" |
| 41 | #include "core/hle/service/filesystem/filesystem.h" | 42 | #include "core/hle/service/filesystem/filesystem.h" |
| @@ -130,8 +131,8 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | |||
| 130 | struct System::Impl { | 131 | struct System::Impl { |
| 131 | explicit Impl(System& system) | 132 | explicit Impl(System& system) |
| 132 | : kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{}, | 133 | : kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{}, |
| 133 | cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system}, | 134 | cpu_manager{system}, reporter{system}, applet_manager{system}, profile_manager{}, |
| 134 | gpu_dirty_memory_write_manager{} { | 135 | time_manager{system}, gpu_dirty_memory_write_manager{} { |
| 135 | memory.SetGPUDirtyManagers(gpu_dirty_memory_write_manager); | 136 | memory.SetGPUDirtyManagers(gpu_dirty_memory_write_manager); |
| 136 | } | 137 | } |
| 137 | 138 | ||
| @@ -532,6 +533,7 @@ struct System::Impl { | |||
| 532 | 533 | ||
| 533 | /// Service State | 534 | /// Service State |
| 534 | Service::Glue::ARPManager arp_manager; | 535 | Service::Glue::ARPManager arp_manager; |
| 536 | Service::Account::ProfileManager profile_manager; | ||
| 535 | Service::Time::TimeManager time_manager; | 537 | Service::Time::TimeManager time_manager; |
| 536 | 538 | ||
| 537 | /// Service manager | 539 | /// Service manager |
| @@ -921,6 +923,14 @@ const Service::APM::Controller& System::GetAPMController() const { | |||
| 921 | return impl->apm_controller; | 923 | return impl->apm_controller; |
| 922 | } | 924 | } |
| 923 | 925 | ||
| 926 | Service::Account::ProfileManager& System::GetProfileManager() { | ||
| 927 | return impl->profile_manager; | ||
| 928 | } | ||
| 929 | |||
| 930 | const Service::Account::ProfileManager& System::GetProfileManager() const { | ||
| 931 | return impl->profile_manager; | ||
| 932 | } | ||
| 933 | |||
| 924 | Service::Time::TimeManager& System::GetTimeManager() { | 934 | Service::Time::TimeManager& System::GetTimeManager() { |
| 925 | return impl->time_manager; | 935 | return impl->time_manager; |
| 926 | } | 936 | } |
diff --git a/src/core/core.h b/src/core/core.h index 05a222f5c..473204db7 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -45,6 +45,10 @@ class Memory; | |||
| 45 | 45 | ||
| 46 | namespace Service { | 46 | namespace Service { |
| 47 | 47 | ||
| 48 | namespace Account { | ||
| 49 | class ProfileManager; | ||
| 50 | } // namespace Account | ||
| 51 | |||
| 48 | namespace AM::Applets { | 52 | namespace AM::Applets { |
| 49 | struct AppletFrontendSet; | 53 | struct AppletFrontendSet; |
| 50 | class AppletManager; | 54 | class AppletManager; |
| @@ -383,6 +387,9 @@ public: | |||
| 383 | [[nodiscard]] Service::APM::Controller& GetAPMController(); | 387 | [[nodiscard]] Service::APM::Controller& GetAPMController(); |
| 384 | [[nodiscard]] const Service::APM::Controller& GetAPMController() const; | 388 | [[nodiscard]] const Service::APM::Controller& GetAPMController() const; |
| 385 | 389 | ||
| 390 | [[nodiscard]] Service::Account::ProfileManager& GetProfileManager(); | ||
| 391 | [[nodiscard]] const Service::Account::ProfileManager& GetProfileManager() const; | ||
| 392 | |||
| 386 | [[nodiscard]] Service::Time::TimeManager& GetTimeManager(); | 393 | [[nodiscard]] Service::Time::TimeManager& GetTimeManager(); |
| 387 | [[nodiscard]] const Service::Time::TimeManager& GetTimeManager() const; | 394 | [[nodiscard]] const Service::Time::TimeManager& GetTimeManager() const; |
| 388 | 395 | ||
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index 639842401..b7105c8ff 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp | |||
| @@ -201,8 +201,6 @@ std::string VfsFile::GetFullPath() const { | |||
| 201 | 201 | ||
| 202 | VirtualFile VfsDirectory::GetFileRelative(std::string_view path) const { | 202 | VirtualFile VfsDirectory::GetFileRelative(std::string_view path) const { |
| 203 | auto vec = Common::FS::SplitPathComponents(path); | 203 | auto vec = Common::FS::SplitPathComponents(path); |
| 204 | vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }), | ||
| 205 | vec.end()); | ||
| 206 | if (vec.empty()) { | 204 | if (vec.empty()) { |
| 207 | return nullptr; | 205 | return nullptr; |
| 208 | } | 206 | } |
| @@ -237,8 +235,6 @@ VirtualFile VfsDirectory::GetFileAbsolute(std::string_view path) const { | |||
| 237 | 235 | ||
| 238 | VirtualDir VfsDirectory::GetDirectoryRelative(std::string_view path) const { | 236 | VirtualDir VfsDirectory::GetDirectoryRelative(std::string_view path) const { |
| 239 | auto vec = Common::FS::SplitPathComponents(path); | 237 | auto vec = Common::FS::SplitPathComponents(path); |
| 240 | vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }), | ||
| 241 | vec.end()); | ||
| 242 | if (vec.empty()) { | 238 | if (vec.empty()) { |
| 243 | // TODO(DarkLordZach): Return this directory if path is '/' or similar. Can't currently | 239 | // TODO(DarkLordZach): Return this directory if path is '/' or similar. Can't currently |
| 244 | // because of const-ness | 240 | // because of const-ness |
| @@ -303,8 +299,6 @@ std::size_t VfsDirectory::GetSize() const { | |||
| 303 | 299 | ||
| 304 | VirtualFile VfsDirectory::CreateFileRelative(std::string_view path) { | 300 | VirtualFile VfsDirectory::CreateFileRelative(std::string_view path) { |
| 305 | auto vec = Common::FS::SplitPathComponents(path); | 301 | auto vec = Common::FS::SplitPathComponents(path); |
| 306 | vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }), | ||
| 307 | vec.end()); | ||
| 308 | if (vec.empty()) { | 302 | if (vec.empty()) { |
| 309 | return nullptr; | 303 | return nullptr; |
| 310 | } | 304 | } |
| @@ -334,8 +328,6 @@ VirtualFile VfsDirectory::CreateFileAbsolute(std::string_view path) { | |||
| 334 | 328 | ||
| 335 | VirtualDir VfsDirectory::CreateDirectoryRelative(std::string_view path) { | 329 | VirtualDir VfsDirectory::CreateDirectoryRelative(std::string_view path) { |
| 336 | auto vec = Common::FS::SplitPathComponents(path); | 330 | auto vec = Common::FS::SplitPathComponents(path); |
| 337 | vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }), | ||
| 338 | vec.end()); | ||
| 339 | if (vec.empty()) { | 331 | if (vec.empty()) { |
| 340 | return nullptr; | 332 | return nullptr; |
| 341 | } | 333 | } |
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 1c706e4d8..cd9b79786 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp | |||
| @@ -268,7 +268,7 @@ void RealVfsFilesystem::RemoveReferenceFromListLocked(FileReference& reference) | |||
| 268 | RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_, | 268 | RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_, |
| 269 | const std::string& path_, Mode perms_, std::optional<u64> size_) | 269 | const std::string& path_, Mode perms_, std::optional<u64> size_) |
| 270 | : base(base_), reference(std::move(reference_)), path(path_), | 270 | : base(base_), reference(std::move(reference_)), path(path_), |
| 271 | parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)), | 271 | parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponentsCopy(path_)), |
| 272 | size(size_), perms(perms_) {} | 272 | size(size_), perms(perms_) {} |
| 273 | 273 | ||
| 274 | RealVfsFile::~RealVfsFile() { | 274 | RealVfsFile::~RealVfsFile() { |
| @@ -276,7 +276,7 @@ RealVfsFile::~RealVfsFile() { | |||
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | std::string RealVfsFile::GetName() const { | 278 | std::string RealVfsFile::GetName() const { |
| 279 | return path_components.back(); | 279 | return path_components.empty() ? "" : std::string(path_components.back()); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | std::size_t RealVfsFile::GetSize() const { | 282 | std::size_t RealVfsFile::GetSize() const { |
| @@ -375,7 +375,7 @@ std::vector<VirtualDir> RealVfsDirectory::IterateEntries<RealVfsDirectory, VfsDi | |||
| 375 | 375 | ||
| 376 | RealVfsDirectory::RealVfsDirectory(RealVfsFilesystem& base_, const std::string& path_, Mode perms_) | 376 | RealVfsDirectory::RealVfsDirectory(RealVfsFilesystem& base_, const std::string& path_, Mode perms_) |
| 377 | : base(base_), path(FS::RemoveTrailingSlash(path_)), parent_path(FS::GetParentPath(path)), | 377 | : base(base_), path(FS::RemoveTrailingSlash(path_)), parent_path(FS::GetParentPath(path)), |
| 378 | path_components(FS::SplitPathComponents(path)), perms(perms_) { | 378 | path_components(FS::SplitPathComponentsCopy(path)), perms(perms_) { |
| 379 | if (!FS::Exists(path) && True(perms & Mode::Write)) { | 379 | if (!FS::Exists(path) && True(perms & Mode::Write)) { |
| 380 | void(FS::CreateDirs(path)); | 380 | void(FS::CreateDirs(path)); |
| 381 | } | 381 | } |
| @@ -464,7 +464,7 @@ bool RealVfsDirectory::IsReadable() const { | |||
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | std::string RealVfsDirectory::GetName() const { | 466 | std::string RealVfsDirectory::GetName() const { |
| 467 | return path_components.back(); | 467 | return path_components.empty() ? "" : std::string(path_components.back()); |
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | VirtualDir RealVfsDirectory::GetParentDirectory() const { | 470 | VirtualDir RealVfsDirectory::GetParentDirectory() const { |
diff --git a/src/core/hid/input_interpreter.cpp b/src/core/hid/input_interpreter.cpp index a6bdd28f2..072f38a68 100644 --- a/src/core/hid/input_interpreter.cpp +++ b/src/core/hid/input_interpreter.cpp | |||
| @@ -20,6 +20,9 @@ InputInterpreter::InputInterpreter(Core::System& system) | |||
| 20 | InputInterpreter::~InputInterpreter() = default; | 20 | InputInterpreter::~InputInterpreter() = default; |
| 21 | 21 | ||
| 22 | void InputInterpreter::PollInput() { | 22 | void InputInterpreter::PollInput() { |
| 23 | if (npad == nullptr) { | ||
| 24 | return; | ||
| 25 | } | ||
| 23 | const auto button_state = npad->GetAndResetPressState(); | 26 | const auto button_state = npad->GetAndResetPressState(); |
| 24 | 27 | ||
| 25 | previous_index = current_index; | 28 | previous_index = current_index; |
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp index 0a973ec8c..d6bd27296 100644 --- a/src/core/hle/kernel/k_memory_manager.cpp +++ b/src/core/hle/kernel/k_memory_manager.cpp | |||
| @@ -421,8 +421,9 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32 | |||
| 421 | } else { | 421 | } else { |
| 422 | // Set all the allocated memory. | 422 | // Set all the allocated memory. |
| 423 | for (const auto& block : *out) { | 423 | for (const auto& block : *out) { |
| 424 | std::memset(m_system.DeviceMemory().GetPointer<void>(block.GetAddress()), fill_pattern, | 424 | m_system.DeviceMemory().buffer.ClearBackingRegion(GetInteger(block.GetAddress()) - |
| 425 | block.GetSize()); | 425 | Core::DramMemoryMap::Base, |
| 426 | block.GetSize(), fill_pattern); | ||
| 426 | } | 427 | } |
| 427 | } | 428 | } |
| 428 | 429 | ||
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 4c416d809..423289145 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp | |||
| @@ -81,6 +81,11 @@ void InvalidateInstructionCache(KernelCore& kernel, AddressType addr, u64 size) | |||
| 81 | } | 81 | } |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void ClearBackingRegion(Core::System& system, KPhysicalAddress addr, u64 size, u32 fill_value) { | ||
| 85 | system.DeviceMemory().buffer.ClearBackingRegion(GetInteger(addr) - Core::DramMemoryMap::Base, | ||
| 86 | size, fill_value); | ||
| 87 | } | ||
| 88 | |||
| 84 | template <typename AddressType> | 89 | template <typename AddressType> |
| 85 | Result InvalidateDataCache(AddressType addr, u64 size) { | 90 | Result InvalidateDataCache(AddressType addr, u64 size) { |
| 86 | R_SUCCEED(); | 91 | R_SUCCEED(); |
| @@ -1363,8 +1368,7 @@ Result KPageTableBase::MapInsecureMemory(KProcessAddress address, size_t size) { | |||
| 1363 | 1368 | ||
| 1364 | // Clear all the newly allocated pages. | 1369 | // Clear all the newly allocated pages. |
| 1365 | for (const auto& it : pg) { | 1370 | for (const auto& it : pg) { |
| 1366 | std::memset(GetHeapVirtualPointer(m_kernel, it.GetAddress()), | 1371 | ClearBackingRegion(m_system, it.GetAddress(), it.GetSize(), m_heap_fill_value); |
| 1367 | static_cast<u32>(m_heap_fill_value), it.GetSize()); | ||
| 1368 | } | 1372 | } |
| 1369 | 1373 | ||
| 1370 | // Lock the table. | 1374 | // Lock the table. |
| @@ -1570,8 +1574,7 @@ Result KPageTableBase::AllocateAndMapPagesImpl(PageLinkedList* page_list, KProce | |||
| 1570 | 1574 | ||
| 1571 | // Clear all pages. | 1575 | // Clear all pages. |
| 1572 | for (const auto& it : pg) { | 1576 | for (const auto& it : pg) { |
| 1573 | std::memset(GetHeapVirtualPointer(m_kernel, it.GetAddress()), | 1577 | ClearBackingRegion(m_system, it.GetAddress(), it.GetSize(), m_heap_fill_value); |
| 1574 | static_cast<u32>(m_heap_fill_value), it.GetSize()); | ||
| 1575 | } | 1578 | } |
| 1576 | 1579 | ||
| 1577 | // Map the pages. | 1580 | // Map the pages. |
| @@ -2159,8 +2162,7 @@ Result KPageTableBase::SetHeapSize(KProcessAddress* out, size_t size) { | |||
| 2159 | 2162 | ||
| 2160 | // Clear all the newly allocated pages. | 2163 | // Clear all the newly allocated pages. |
| 2161 | for (const auto& it : pg) { | 2164 | for (const auto& it : pg) { |
| 2162 | std::memset(GetHeapVirtualPointer(m_kernel, it.GetAddress()), m_heap_fill_value, | 2165 | ClearBackingRegion(m_system, it.GetAddress(), it.GetSize(), m_heap_fill_value); |
| 2163 | it.GetSize()); | ||
| 2164 | } | 2166 | } |
| 2165 | 2167 | ||
| 2166 | // Map the pages. | 2168 | // Map the pages. |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 8cb05ca0b..e479dacde 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -135,7 +135,6 @@ struct KernelCore::Impl { | |||
| 135 | obj = nullptr; | 135 | obj = nullptr; |
| 136 | } | 136 | } |
| 137 | }; | 137 | }; |
| 138 | CleanupObject(hid_shared_mem); | ||
| 139 | CleanupObject(font_shared_mem); | 138 | CleanupObject(font_shared_mem); |
| 140 | CleanupObject(irs_shared_mem); | 139 | CleanupObject(irs_shared_mem); |
| 141 | CleanupObject(time_shared_mem); | 140 | CleanupObject(time_shared_mem); |
| @@ -744,22 +743,16 @@ struct KernelCore::Impl { | |||
| 744 | void InitializeHackSharedMemory(KernelCore& kernel) { | 743 | void InitializeHackSharedMemory(KernelCore& kernel) { |
| 745 | // Setup memory regions for emulated processes | 744 | // Setup memory regions for emulated processes |
| 746 | // TODO(bunnei): These should not be hardcoded regions initialized within the kernel | 745 | // TODO(bunnei): These should not be hardcoded regions initialized within the kernel |
| 747 | constexpr std::size_t hid_size{0x40000}; | ||
| 748 | constexpr std::size_t font_size{0x1100000}; | 746 | constexpr std::size_t font_size{0x1100000}; |
| 749 | constexpr std::size_t irs_size{0x8000}; | 747 | constexpr std::size_t irs_size{0x8000}; |
| 750 | constexpr std::size_t time_size{0x1000}; | 748 | constexpr std::size_t time_size{0x1000}; |
| 751 | constexpr std::size_t hidbus_size{0x1000}; | 749 | constexpr std::size_t hidbus_size{0x1000}; |
| 752 | 750 | ||
| 753 | hid_shared_mem = KSharedMemory::Create(system.Kernel()); | ||
| 754 | font_shared_mem = KSharedMemory::Create(system.Kernel()); | 751 | font_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 755 | irs_shared_mem = KSharedMemory::Create(system.Kernel()); | 752 | irs_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 756 | time_shared_mem = KSharedMemory::Create(system.Kernel()); | 753 | time_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 757 | hidbus_shared_mem = KSharedMemory::Create(system.Kernel()); | 754 | hidbus_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 758 | 755 | ||
| 759 | hid_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, | ||
| 760 | Svc::MemoryPermission::Read, hid_size); | ||
| 761 | KSharedMemory::Register(kernel, hid_shared_mem); | ||
| 762 | |||
| 763 | font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, | 756 | font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, |
| 764 | Svc::MemoryPermission::Read, font_size); | 757 | Svc::MemoryPermission::Read, font_size); |
| 765 | KSharedMemory::Register(kernel, font_shared_mem); | 758 | KSharedMemory::Register(kernel, font_shared_mem); |
| @@ -1190,14 +1183,6 @@ const KSystemResource& KernelCore::GetSystemSystemResource() const { | |||
| 1190 | return *impl->sys_system_resource; | 1183 | return *impl->sys_system_resource; |
| 1191 | } | 1184 | } |
| 1192 | 1185 | ||
| 1193 | Kernel::KSharedMemory& KernelCore::GetHidSharedMem() { | ||
| 1194 | return *impl->hid_shared_mem; | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | const Kernel::KSharedMemory& KernelCore::GetHidSharedMem() const { | ||
| 1198 | return *impl->hid_shared_mem; | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | Kernel::KSharedMemory& KernelCore::GetFontSharedMem() { | 1186 | Kernel::KSharedMemory& KernelCore::GetFontSharedMem() { |
| 1202 | return *impl->font_shared_mem; | 1187 | return *impl->font_shared_mem; |
| 1203 | } | 1188 | } |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 69b5bbd6c..78c88902c 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -239,12 +239,6 @@ public: | |||
| 239 | /// Gets the system resource manager. | 239 | /// Gets the system resource manager. |
| 240 | const KSystemResource& GetSystemSystemResource() const; | 240 | const KSystemResource& GetSystemSystemResource() const; |
| 241 | 241 | ||
| 242 | /// Gets the shared memory object for HID services. | ||
| 243 | Kernel::KSharedMemory& GetHidSharedMem(); | ||
| 244 | |||
| 245 | /// Gets the shared memory object for HID services. | ||
| 246 | const Kernel::KSharedMemory& GetHidSharedMem() const; | ||
| 247 | |||
| 248 | /// Gets the shared memory object for font services. | 242 | /// Gets the shared memory object for font services. |
| 249 | Kernel::KSharedMemory& GetFontSharedMem(); | 243 | Kernel::KSharedMemory& GetFontSharedMem(); |
| 250 | 244 | ||
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 508db7360..780f8c74d 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -104,11 +104,7 @@ Result VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) con | |||
| 104 | const auto components = Common::FS::SplitPathComponents(path); | 104 | const auto components = Common::FS::SplitPathComponents(path); |
| 105 | std::string relative_path; | 105 | std::string relative_path; |
| 106 | for (const auto& component : components) { | 106 | for (const auto& component : components) { |
| 107 | // Skip empty path components | 107 | relative_path = Common::FS::SanitizePath(fmt::format("{}/{}", relative_path, component)); |
| 108 | if (component.empty()) { | ||
| 109 | continue; | ||
| 110 | } | ||
| 111 | relative_path = Common::FS::SanitizePath(relative_path + '/' + component); | ||
| 112 | auto new_dir = backing->CreateSubdirectory(relative_path); | 108 | auto new_dir = backing->CreateSubdirectory(relative_path); |
| 113 | if (new_dir == nullptr) { | 109 | if (new_dir == nullptr) { |
| 114 | // TODO(DarkLordZach): Find a better error code for this | 110 | // TODO(DarkLordZach): Find a better error code for this |
diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/core/hle/service/hid/controllers/applet_resource.cpp index ee60d8b44..c8e74c764 100644 --- a/src/core/hle/service/hid/controllers/applet_resource.cpp +++ b/src/core/hle/service/hid/controllers/applet_resource.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include "core/core.h" | 4 | #include "core/core.h" |
| 5 | #include "core/hle/kernel/k_shared_memory.h" | 5 | #include "core/hle/kernel/k_shared_memory.h" |
| 6 | #include "core/hle/service/hid/controllers/applet_resource.h" | 6 | #include "core/hle/service/hid/controllers/applet_resource.h" |
| 7 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 7 | #include "core/hle/service/hid/errors.h" | 8 | #include "core/hle/service/hid/errors.h" |
| 8 | 9 | ||
| 9 | namespace Service::HID { | 10 | namespace Service::HID { |
| @@ -23,11 +24,24 @@ Result AppletResource::CreateAppletResource(u64 aruid) { | |||
| 23 | return ResultAruidAlreadyRegistered; | 24 | return ResultAruidAlreadyRegistered; |
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | // TODO: Here shared memory is created for the process we don't quite emulate this part so | 27 | auto& shared_memory = shared_memory_holder[index]; |
| 27 | // obtain this pointer from system | 28 | if (!shared_memory.IsMapped()) { |
| 28 | auto& shared_memory = system.Kernel().GetHidSharedMem(); | 29 | const Result result = shared_memory.Initialize(system); |
| 30 | if (result.IsError()) { | ||
| 31 | return result; | ||
| 32 | } | ||
| 33 | if (shared_memory.GetAddress() == nullptr) { | ||
| 34 | shared_memory.Finalize(); | ||
| 35 | return ResultSharedMemoryNotInitialized; | ||
| 36 | } | ||
| 37 | } | ||
| 29 | 38 | ||
| 30 | data[index].shared_memory_handle = &shared_memory; | 39 | auto* shared_memory_format = shared_memory.GetAddress(); |
| 40 | if (shared_memory_format != nullptr) { | ||
| 41 | shared_memory_format->Initialize(); | ||
| 42 | } | ||
| 43 | |||
| 44 | data[index].shared_memory_format = shared_memory_format; | ||
| 31 | data[index].flag.is_assigned.Assign(true); | 45 | data[index].flag.is_assigned.Assign(true); |
| 32 | // TODO: InitializeSixAxisControllerConfig(false); | 46 | // TODO: InitializeSixAxisControllerConfig(false); |
| 33 | active_aruid = aruid; | 47 | active_aruid = aruid; |
| @@ -94,7 +108,7 @@ void AppletResource::UnregisterAppletResourceUserId(u64 aruid) { | |||
| 94 | 108 | ||
| 95 | if (index < AruidIndexMax) { | 109 | if (index < AruidIndexMax) { |
| 96 | if (data[index].flag.is_assigned) { | 110 | if (data[index].flag.is_assigned) { |
| 97 | data[index].shared_memory_handle = nullptr; | 111 | data[index].shared_memory_format = nullptr; |
| 98 | data[index].flag.is_assigned.Assign(false); | 112 | data[index].flag.is_assigned.Assign(false); |
| 99 | } | 113 | } |
| 100 | } | 114 | } |
| @@ -112,6 +126,19 @@ void AppletResource::UnregisterAppletResourceUserId(u64 aruid) { | |||
| 112 | } | 126 | } |
| 113 | } | 127 | } |
| 114 | 128 | ||
| 129 | void AppletResource::FreeAppletResourceId(u64 aruid) { | ||
| 130 | u64 index = GetIndexFromAruid(aruid); | ||
| 131 | if (index >= AruidIndexMax) { | ||
| 132 | return; | ||
| 133 | } | ||
| 134 | |||
| 135 | auto& aruid_data = data[index]; | ||
| 136 | if (aruid_data.flag.is_assigned) { | ||
| 137 | aruid_data.shared_memory_format = nullptr; | ||
| 138 | aruid_data.flag.is_assigned.Assign(false); | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 115 | u64 AppletResource::GetActiveAruid() { | 142 | u64 AppletResource::GetActiveAruid() { |
| 116 | return active_aruid; | 143 | return active_aruid; |
| 117 | } | 144 | } |
| @@ -122,7 +149,18 @@ Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, | |||
| 122 | return ResultAruidNotRegistered; | 149 | return ResultAruidNotRegistered; |
| 123 | } | 150 | } |
| 124 | 151 | ||
| 125 | *out_handle = data[index].shared_memory_handle; | 152 | *out_handle = shared_memory_holder[index].GetHandle(); |
| 153 | return ResultSuccess; | ||
| 154 | } | ||
| 155 | |||
| 156 | Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, | ||
| 157 | u64 aruid) { | ||
| 158 | u64 index = GetIndexFromAruid(aruid); | ||
| 159 | if (index >= AruidIndexMax) { | ||
| 160 | return ResultAruidNotRegistered; | ||
| 161 | } | ||
| 162 | |||
| 163 | *out_shared_memory_format = data[index].shared_memory_format; | ||
| 126 | return ResultSuccess; | 164 | return ResultSuccess; |
| 127 | } | 165 | } |
| 128 | 166 | ||
| @@ -196,4 +234,80 @@ void AppletResource::EnablePalmaBoostMode(u64 aruid, bool is_enabled) { | |||
| 196 | data[index].flag.enable_palma_boost_mode.Assign(is_enabled); | 234 | data[index].flag.enable_palma_boost_mode.Assign(is_enabled); |
| 197 | } | 235 | } |
| 198 | 236 | ||
| 237 | Result AppletResource::RegisterCoreAppletResource() { | ||
| 238 | if (ref_counter == std::numeric_limits<s32>::max() - 1) { | ||
| 239 | return ResultAppletResourceOverflow; | ||
| 240 | } | ||
| 241 | if (ref_counter == 0) { | ||
| 242 | const u64 index = GetIndexFromAruid(0); | ||
| 243 | if (index < AruidIndexMax) { | ||
| 244 | return ResultAruidAlreadyRegistered; | ||
| 245 | } | ||
| 246 | |||
| 247 | std::size_t data_index = AruidIndexMax; | ||
| 248 | for (std::size_t i = 0; i < AruidIndexMax; i++) { | ||
| 249 | if (!data[i].flag.is_initialized) { | ||
| 250 | data_index = i; | ||
| 251 | break; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | if (data_index == AruidIndexMax) { | ||
| 256 | return ResultAruidNoAvailableEntries; | ||
| 257 | } | ||
| 258 | |||
| 259 | AruidData& aruid_data = data[data_index]; | ||
| 260 | |||
| 261 | aruid_data.aruid = 0; | ||
| 262 | aruid_data.flag.is_initialized.Assign(true); | ||
| 263 | aruid_data.flag.enable_pad_input.Assign(true); | ||
| 264 | aruid_data.flag.enable_six_axis_sensor.Assign(true); | ||
| 265 | aruid_data.flag.bit_18.Assign(true); | ||
| 266 | aruid_data.flag.enable_touchscreen.Assign(true); | ||
| 267 | |||
| 268 | data_index = AruidIndexMax; | ||
| 269 | for (std::size_t i = 0; i < AruidIndexMax; i++) { | ||
| 270 | if (registration_list.flag[i] == RegistrationStatus::Initialized) { | ||
| 271 | if (registration_list.aruid[i] != 0) { | ||
| 272 | continue; | ||
| 273 | } | ||
| 274 | data_index = i; | ||
| 275 | break; | ||
| 276 | } | ||
| 277 | if (registration_list.flag[i] == RegistrationStatus::None) { | ||
| 278 | data_index = i; | ||
| 279 | break; | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | Result result = ResultSuccess; | ||
| 284 | |||
| 285 | if (data_index == AruidIndexMax) { | ||
| 286 | result = CreateAppletResource(0); | ||
| 287 | } else { | ||
| 288 | registration_list.flag[data_index] = RegistrationStatus::Initialized; | ||
| 289 | registration_list.aruid[data_index] = 0; | ||
| 290 | } | ||
| 291 | |||
| 292 | if (result.IsError()) { | ||
| 293 | UnregisterAppletResourceUserId(0); | ||
| 294 | return result; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | ref_counter++; | ||
| 298 | return ResultSuccess; | ||
| 299 | } | ||
| 300 | |||
| 301 | Result AppletResource::UnregisterCoreAppletResource() { | ||
| 302 | if (ref_counter == 0) { | ||
| 303 | return ResultAppletResourceNotInitialized; | ||
| 304 | } | ||
| 305 | |||
| 306 | if (--ref_counter == 0) { | ||
| 307 | UnregisterAppletResourceUserId(0); | ||
| 308 | } | ||
| 309 | |||
| 310 | return ResultSuccess; | ||
| 311 | } | ||
| 312 | |||
| 199 | } // namespace Service::HID | 313 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/applet_resource.h b/src/core/hle/service/hid/controllers/applet_resource.h index 3dcec2898..e7991f93a 100644 --- a/src/core/hle/service/hid/controllers/applet_resource.h +++ b/src/core/hle/service/hid/controllers/applet_resource.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "common/bit_field.h" | 8 | #include "common/bit_field.h" |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/hle/result.h" | 10 | #include "core/hle/result.h" |
| 11 | #include "core/hle/service/hid/controllers/shared_memory_holder.h" | ||
| 11 | 12 | ||
| 12 | namespace Core { | 13 | namespace Core { |
| 13 | class System; | 14 | class System; |
| @@ -18,6 +19,8 @@ class KSharedMemory; | |||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | namespace Service::HID { | 21 | namespace Service::HID { |
| 22 | struct SharedMemoryFormat; | ||
| 23 | |||
| 21 | class AppletResource { | 24 | class AppletResource { |
| 22 | public: | 25 | public: |
| 23 | explicit AppletResource(Core::System& system_); | 26 | explicit AppletResource(Core::System& system_); |
| @@ -28,8 +31,11 @@ public: | |||
| 28 | Result RegisterAppletResourceUserId(u64 aruid, bool enable_input); | 31 | Result RegisterAppletResourceUserId(u64 aruid, bool enable_input); |
| 29 | void UnregisterAppletResourceUserId(u64 aruid); | 32 | void UnregisterAppletResourceUserId(u64 aruid); |
| 30 | 33 | ||
| 34 | void FreeAppletResourceId(u64 aruid); | ||
| 35 | |||
| 31 | u64 GetActiveAruid(); | 36 | u64 GetActiveAruid(); |
| 32 | Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); | 37 | Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); |
| 38 | Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid); | ||
| 33 | 39 | ||
| 34 | u64 GetIndexFromAruid(u64 aruid); | 40 | u64 GetIndexFromAruid(u64 aruid); |
| 35 | 41 | ||
| @@ -42,6 +48,9 @@ public: | |||
| 42 | void SetIsPalmaConnectable(u64 aruid, bool is_connectable); | 48 | void SetIsPalmaConnectable(u64 aruid, bool is_connectable); |
| 43 | void EnablePalmaBoostMode(u64 aruid, bool is_enabled); | 49 | void EnablePalmaBoostMode(u64 aruid, bool is_enabled); |
| 44 | 50 | ||
| 51 | Result RegisterCoreAppletResource(); | ||
| 52 | Result UnregisterCoreAppletResource(); | ||
| 53 | |||
| 45 | private: | 54 | private: |
| 46 | static constexpr std::size_t AruidIndexMax = 0x20; | 55 | static constexpr std::size_t AruidIndexMax = 0x20; |
| 47 | 56 | ||
| @@ -75,12 +84,14 @@ private: | |||
| 75 | struct AruidData { | 84 | struct AruidData { |
| 76 | DataStatusFlag flag{}; | 85 | DataStatusFlag flag{}; |
| 77 | u64 aruid{}; | 86 | u64 aruid{}; |
| 78 | Kernel::KSharedMemory* shared_memory_handle{nullptr}; | 87 | SharedMemoryFormat* shared_memory_format{nullptr}; |
| 79 | }; | 88 | }; |
| 80 | 89 | ||
| 81 | u64 active_aruid{}; | 90 | u64 active_aruid{}; |
| 82 | AruidRegisterList registration_list{}; | 91 | AruidRegisterList registration_list{}; |
| 83 | std::array<AruidData, AruidIndexMax> data{}; | 92 | std::array<AruidData, AruidIndexMax> data{}; |
| 93 | std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{}; | ||
| 94 | s32 ref_counter{}; | ||
| 84 | 95 | ||
| 85 | Core::System& system; | 96 | Core::System& system; |
| 86 | }; | 97 | }; |
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp index b2bf1d78d..3961d2b5f 100644 --- a/src/core/hle/service/hid/controllers/console_six_axis.cpp +++ b/src/core/hle/service/hid/controllers/console_six_axis.cpp | |||
| @@ -1,23 +1,18 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/core_timing.h" | 4 | #include "core/core_timing.h" |
| 6 | #include "core/hid/emulated_console.h" | 5 | #include "core/hid/emulated_console.h" |
| 7 | #include "core/hid/hid_core.h" | 6 | #include "core/hid/hid_core.h" |
| 8 | #include "core/hle/service/hid/controllers/console_six_axis.h" | 7 | #include "core/hle/service/hid/controllers/console_six_axis.h" |
| 9 | #include "core/memory.h" | 8 | #include "core/hle/service/hid/controllers/shared_memory_format.h" |
| 10 | 9 | ||
| 11 | namespace Service::HID { | 10 | namespace Service::HID { |
| 12 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; | ||
| 13 | 11 | ||
| 14 | ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 12 | ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, |
| 15 | : ControllerBase{hid_core_} { | 13 | ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory) |
| 14 | : ControllerBase{hid_core_}, shared_memory{console_shared_memory} { | ||
| 16 | console = hid_core.GetEmulatedConsole(); | 15 | console = hid_core.GetEmulatedConsole(); |
| 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size, | ||
| 18 | "ConsoleSharedMemory is bigger than the shared memory"); | ||
| 19 | shared_memory = std::construct_at( | ||
| 20 | reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 21 | } | 16 | } |
| 22 | 17 | ||
| 23 | ConsoleSixAxis::~ConsoleSixAxis() = default; | 18 | ConsoleSixAxis::~ConsoleSixAxis() = default; |
| @@ -33,10 +28,10 @@ void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 33 | 28 | ||
| 34 | const auto motion_status = console->GetMotion(); | 29 | const auto motion_status = console->GetMotion(); |
| 35 | 30 | ||
| 36 | shared_memory->sampling_number++; | 31 | shared_memory.sampling_number++; |
| 37 | shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; | 32 | shared_memory.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; |
| 38 | shared_memory->verticalization_error = motion_status.verticalization_error; | 33 | shared_memory.verticalization_error = motion_status.verticalization_error; |
| 39 | shared_memory->gyro_bias = motion_status.gyro_bias; | 34 | shared_memory.gyro_bias = motion_status.gyro_bias; |
| 40 | } | 35 | } |
| 41 | 36 | ||
| 42 | } // namespace Service::HID | 37 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h index 5b7c6a29a..3d1c9ce23 100644 --- a/src/core/hle/service/hid/controllers/console_six_axis.h +++ b/src/core/hle/service/hid/controllers/console_six_axis.h | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/vector_math.h" | ||
| 7 | #include "core/hle/service/hid/controllers/controller_base.h" | 6 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 8 | 7 | ||
| 9 | namespace Core::HID { | 8 | namespace Core::HID { |
| @@ -11,9 +10,12 @@ class EmulatedConsole; | |||
| 11 | } // namespace Core::HID | 10 | } // namespace Core::HID |
| 12 | 11 | ||
| 13 | namespace Service::HID { | 12 | namespace Service::HID { |
| 13 | struct ConsoleSixAxisSensorSharedMemoryFormat; | ||
| 14 | |||
| 14 | class ConsoleSixAxis final : public ControllerBase { | 15 | class ConsoleSixAxis final : public ControllerBase { |
| 15 | public: | 16 | public: |
| 16 | explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 17 | explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, |
| 18 | ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory); | ||
| 17 | ~ConsoleSixAxis() override; | 19 | ~ConsoleSixAxis() override; |
| 18 | 20 | ||
| 19 | // Called when the controller is initialized | 21 | // Called when the controller is initialized |
| @@ -26,18 +28,7 @@ public: | |||
| 26 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 28 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 27 | 29 | ||
| 28 | private: | 30 | private: |
| 29 | // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat | 31 | ConsoleSixAxisSensorSharedMemoryFormat& shared_memory; |
| 30 | struct ConsoleSharedMemory { | ||
| 31 | u64 sampling_number{}; | ||
| 32 | bool is_seven_six_axis_sensor_at_rest{}; | ||
| 33 | INSERT_PADDING_BYTES(3); // padding | ||
| 34 | f32 verticalization_error{}; | ||
| 35 | Common::Vec3f gyro_bias{}; | ||
| 36 | INSERT_PADDING_BYTES(4); // padding | ||
| 37 | }; | ||
| 38 | static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); | ||
| 39 | |||
| 40 | ConsoleSharedMemory* shared_memory = nullptr; | ||
| 41 | Core::HID::EmulatedConsole* console = nullptr; | 32 | Core::HID::EmulatedConsole* console = nullptr; |
| 42 | }; | 33 | }; |
| 43 | } // namespace Service::HID | 34 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h index 9a44ee41e..4326c7821 100644 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ b/src/core/hle/service/hid/controllers/controller_base.h | |||
| @@ -39,9 +39,6 @@ public: | |||
| 39 | 39 | ||
| 40 | bool IsControllerActivated() const; | 40 | bool IsControllerActivated() const; |
| 41 | 41 | ||
| 42 | static const std::size_t hid_entry_count = 17; | ||
| 43 | static const std::size_t shared_memory_size = 0x40000; | ||
| 44 | |||
| 45 | protected: | 42 | protected: |
| 46 | bool is_activated{false}; | 43 | bool is_activated{false}; |
| 47 | 44 | ||
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index 9de19ebfc..7d2370b4f 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp | |||
| @@ -1,24 +1,19 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <cstring> | ||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "common/settings.h" | 4 | #include "common/settings.h" |
| 7 | #include "core/core_timing.h" | 5 | #include "core/core_timing.h" |
| 8 | #include "core/hid/emulated_controller.h" | 6 | #include "core/hid/emulated_controller.h" |
| 9 | #include "core/hid/hid_core.h" | 7 | #include "core/hid/hid_core.h" |
| 10 | #include "core/hid/hid_types.h" | 8 | #include "core/hid/hid_types.h" |
| 11 | #include "core/hle/service/hid/controllers/debug_pad.h" | 9 | #include "core/hle/service/hid/controllers/debug_pad.h" |
| 10 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 12 | 11 | ||
| 13 | namespace Service::HID { | 12 | namespace Service::HID { |
| 14 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; | 13 | |
| 15 | 14 | DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, | |
| 16 | DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 15 | DebugPadSharedMemoryFormat& debug_pad_shared_memory) |
| 17 | : ControllerBase{hid_core_} { | 16 | : ControllerBase{hid_core_}, shared_memory{debug_pad_shared_memory} { |
| 18 | static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size, | ||
| 19 | "DebugPadSharedMemory is bigger than the shared memory"); | ||
| 20 | shared_memory = std::construct_at( | ||
| 21 | reinterpret_cast<DebugPadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 22 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); | 17 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); |
| 23 | } | 18 | } |
| 24 | 19 | ||
| @@ -30,12 +25,12 @@ void DebugPad::OnRelease() {} | |||
| 30 | 25 | ||
| 31 | void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 26 | void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 32 | if (!IsControllerActivated()) { | 27 | if (!IsControllerActivated()) { |
| 33 | shared_memory->debug_pad_lifo.buffer_count = 0; | 28 | shared_memory.debug_pad_lifo.buffer_count = 0; |
| 34 | shared_memory->debug_pad_lifo.buffer_tail = 0; | 29 | shared_memory.debug_pad_lifo.buffer_tail = 0; |
| 35 | return; | 30 | return; |
| 36 | } | 31 | } |
| 37 | 32 | ||
| 38 | const auto& last_entry = shared_memory->debug_pad_lifo.ReadCurrentEntry().state; | 33 | const auto& last_entry = shared_memory.debug_pad_lifo.ReadCurrentEntry().state; |
| 39 | next_state.sampling_number = last_entry.sampling_number + 1; | 34 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 40 | 35 | ||
| 41 | if (Settings::values.debug_pad_enabled) { | 36 | if (Settings::values.debug_pad_enabled) { |
| @@ -49,7 +44,7 @@ void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 49 | next_state.r_stick = stick_state.right; | 44 | next_state.r_stick = stick_state.right; |
| 50 | } | 45 | } |
| 51 | 46 | ||
| 52 | shared_memory->debug_pad_lifo.WriteNextEntry(next_state); | 47 | shared_memory.debug_pad_lifo.WriteNextEntry(next_state); |
| 53 | } | 48 | } |
| 54 | 49 | ||
| 55 | } // namespace Service::HID | 50 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index 5566dba77..8ab29eca8 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h | |||
| @@ -3,21 +3,24 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/bit_field.h" | ||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "core/hle/service/hid/controllers/controller_base.h" | 6 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 9 | #include "core/hle/service/hid/ring_lifo.h" | 7 | #include "core/hle/service/hid/controllers/types/debug_pad_types.h" |
| 10 | 8 | ||
| 11 | namespace Core::HID { | 9 | namespace Core::HID { |
| 12 | class EmulatedController; | 10 | class HIDCore; |
| 13 | struct DebugPadButton; | 11 | } |
| 14 | struct AnalogStickState; | 12 | |
| 15 | } // namespace Core::HID | 13 | namespace Core::Timing { |
| 14 | class CoreTiming; | ||
| 15 | } | ||
| 16 | 16 | ||
| 17 | namespace Service::HID { | 17 | namespace Service::HID { |
| 18 | struct DebugPadSharedMemoryFormat; | ||
| 19 | |||
| 18 | class DebugPad final : public ControllerBase { | 20 | class DebugPad final : public ControllerBase { |
| 19 | public: | 21 | public: |
| 20 | explicit DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 22 | explicit DebugPad(Core::HID::HIDCore& hid_core_, |
| 23 | DebugPadSharedMemoryFormat& debug_pad_shared_memory); | ||
| 21 | ~DebugPad() override; | 24 | ~DebugPad() override; |
| 22 | 25 | ||
| 23 | // Called when the controller is initialized | 26 | // Called when the controller is initialized |
| @@ -30,35 +33,8 @@ public: | |||
| 30 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 33 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 31 | 34 | ||
| 32 | private: | 35 | private: |
| 33 | // This is nn::hid::DebugPadAttribute | ||
| 34 | struct DebugPadAttribute { | ||
| 35 | union { | ||
| 36 | u32 raw{}; | ||
| 37 | BitField<0, 1, u32> connected; | ||
| 38 | }; | ||
| 39 | }; | ||
| 40 | static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size"); | ||
| 41 | |||
| 42 | // This is nn::hid::DebugPadState | ||
| 43 | struct DebugPadState { | ||
| 44 | s64 sampling_number{}; | ||
| 45 | DebugPadAttribute attribute{}; | ||
| 46 | Core::HID::DebugPadButton pad_state{}; | ||
| 47 | Core::HID::AnalogStickState r_stick{}; | ||
| 48 | Core::HID::AnalogStickState l_stick{}; | ||
| 49 | }; | ||
| 50 | static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); | ||
| 51 | |||
| 52 | struct DebugPadSharedMemory { | ||
| 53 | // This is nn::hid::detail::DebugPadLifo | ||
| 54 | Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{}; | ||
| 55 | static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); | ||
| 56 | INSERT_PADDING_WORDS(0x4E); | ||
| 57 | }; | ||
| 58 | static_assert(sizeof(DebugPadSharedMemory) == 0x400, "DebugPadSharedMemory is an invalid size"); | ||
| 59 | |||
| 60 | DebugPadState next_state{}; | 36 | DebugPadState next_state{}; |
| 61 | DebugPadSharedMemory* shared_memory = nullptr; | 37 | DebugPadSharedMemoryFormat& shared_memory; |
| 62 | Core::HID::EmulatedController* controller = nullptr; | 38 | Core::HID::EmulatedController* controller = nullptr; |
| 63 | }; | 39 | }; |
| 64 | } // namespace Service::HID | 40 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index 59b2ec73c..f658005f6 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp | |||
| @@ -1,17 +1,15 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "common/math_util.h" | 4 | #include "common/math_util.h" |
| 6 | #include "common/settings.h" | 5 | #include "common/settings.h" |
| 7 | #include "core/core_timing.h" | ||
| 8 | #include "core/frontend/emu_window.h" | 6 | #include "core/frontend/emu_window.h" |
| 7 | #include "core/hid/emulated_console.h" | ||
| 9 | #include "core/hid/hid_core.h" | 8 | #include "core/hid/hid_core.h" |
| 10 | #include "core/hle/service/hid/controllers/gesture.h" | 9 | #include "core/hle/service/hid/controllers/gesture.h" |
| 10 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 11 | 11 | ||
| 12 | namespace Service::HID { | 12 | namespace Service::HID { |
| 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00; | ||
| 14 | |||
| 15 | // HW is around 700, value is set to 400 to make it easier to trigger with mouse | 13 | // HW is around 700, value is set to 400 to make it easier to trigger with mouse |
| 16 | constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s | 14 | constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s |
| 17 | constexpr f32 angle_threshold = 0.015f; // Threshold in radians | 15 | constexpr f32 angle_threshold = 0.015f; // Threshold in radians |
| @@ -23,19 +21,15 @@ constexpr f32 Square(s32 num) { | |||
| 23 | return static_cast<f32>(num * num); | 21 | return static_cast<f32>(num * num); |
| 24 | } | 22 | } |
| 25 | 23 | ||
| 26 | Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 24 | Gesture::Gesture(Core::HID::HIDCore& hid_core_, GestureSharedMemoryFormat& gesture_shared_memory) |
| 27 | : ControllerBase(hid_core_) { | 25 | : ControllerBase(hid_core_), shared_memory{gesture_shared_memory} { |
| 28 | static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size, | ||
| 29 | "GestureSharedMemory is bigger than the shared memory"); | ||
| 30 | shared_memory = std::construct_at( | ||
| 31 | reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 32 | console = hid_core.GetEmulatedConsole(); | 26 | console = hid_core.GetEmulatedConsole(); |
| 33 | } | 27 | } |
| 34 | Gesture::~Gesture() = default; | 28 | Gesture::~Gesture() = default; |
| 35 | 29 | ||
| 36 | void Gesture::OnInit() { | 30 | void Gesture::OnInit() { |
| 37 | shared_memory->gesture_lifo.buffer_count = 0; | 31 | shared_memory.gesture_lifo.buffer_count = 0; |
| 38 | shared_memory->gesture_lifo.buffer_tail = 0; | 32 | shared_memory.gesture_lifo.buffer_tail = 0; |
| 39 | force_update = true; | 33 | force_update = true; |
| 40 | } | 34 | } |
| 41 | 35 | ||
| @@ -43,8 +37,8 @@ void Gesture::OnRelease() {} | |||
| 43 | 37 | ||
| 44 | void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 38 | void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 45 | if (!IsControllerActivated()) { | 39 | if (!IsControllerActivated()) { |
| 46 | shared_memory->gesture_lifo.buffer_count = 0; | 40 | shared_memory.gesture_lifo.buffer_count = 0; |
| 47 | shared_memory->gesture_lifo.buffer_tail = 0; | 41 | shared_memory.gesture_lifo.buffer_tail = 0; |
| 48 | return; | 42 | return; |
| 49 | } | 43 | } |
| 50 | 44 | ||
| @@ -52,7 +46,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 52 | 46 | ||
| 53 | GestureProperties gesture = GetGestureProperties(); | 47 | GestureProperties gesture = GetGestureProperties(); |
| 54 | f32 time_difference = | 48 | f32 time_difference = |
| 55 | static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) / | 49 | static_cast<f32>(shared_memory.gesture_lifo.timestamp - last_update_timestamp) / |
| 56 | (1000 * 1000 * 1000); | 50 | (1000 * 1000 * 1000); |
| 57 | 51 | ||
| 58 | // Only update if necessary | 52 | // Only update if necessary |
| @@ -60,7 +54,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 60 | return; | 54 | return; |
| 61 | } | 55 | } |
| 62 | 56 | ||
| 63 | last_update_timestamp = shared_memory->gesture_lifo.timestamp; | 57 | last_update_timestamp = shared_memory.gesture_lifo.timestamp; |
| 64 | UpdateGestureSharedMemory(gesture, time_difference); | 58 | UpdateGestureSharedMemory(gesture, time_difference); |
| 65 | } | 59 | } |
| 66 | 60 | ||
| @@ -103,7 +97,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif | |||
| 103 | GestureType type = GestureType::Idle; | 97 | GestureType type = GestureType::Idle; |
| 104 | GestureAttribute attributes{}; | 98 | GestureAttribute attributes{}; |
| 105 | 99 | ||
| 106 | const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state; | 100 | const auto& last_entry = shared_memory.gesture_lifo.ReadCurrentEntry().state; |
| 107 | 101 | ||
| 108 | // Reset next state to default | 102 | // Reset next state to default |
| 109 | next_state.sampling_number = last_entry.sampling_number + 1; | 103 | next_state.sampling_number = last_entry.sampling_number + 1; |
| @@ -133,7 +127,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif | |||
| 133 | next_state.points = gesture.points; | 127 | next_state.points = gesture.points; |
| 134 | last_gesture = gesture; | 128 | last_gesture = gesture; |
| 135 | 129 | ||
| 136 | shared_memory->gesture_lifo.WriteNextEntry(next_state); | 130 | shared_memory.gesture_lifo.WriteNextEntry(next_state); |
| 137 | } | 131 | } |
| 138 | 132 | ||
| 139 | void Gesture::NewGesture(GestureProperties& gesture, GestureType& type, | 133 | void Gesture::NewGesture(GestureProperties& gesture, GestureType& type, |
| @@ -305,11 +299,11 @@ void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_ | |||
| 305 | next_state.direction = GestureDirection::Up; | 299 | next_state.direction = GestureDirection::Up; |
| 306 | } | 300 | } |
| 307 | 301 | ||
| 308 | const Gesture::GestureState& Gesture::GetLastGestureEntry() const { | 302 | const GestureState& Gesture::GetLastGestureEntry() const { |
| 309 | return shared_memory->gesture_lifo.ReadCurrentEntry().state; | 303 | return shared_memory.gesture_lifo.ReadCurrentEntry().state; |
| 310 | } | 304 | } |
| 311 | 305 | ||
| 312 | Gesture::GestureProperties Gesture::GetGestureProperties() { | 306 | GestureProperties Gesture::GetGestureProperties() { |
| 313 | GestureProperties gesture; | 307 | GestureProperties gesture; |
| 314 | std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; | 308 | std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; |
| 315 | const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), | 309 | const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), |
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index 4c6f8ee07..41fdfcd03 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h | |||
| @@ -4,17 +4,22 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include "common/bit_field.h" | 7 | |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "common/point.h" | ||
| 10 | #include "core/hid/emulated_console.h" | ||
| 11 | #include "core/hle/service/hid/controllers/controller_base.h" | 9 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 12 | #include "core/hle/service/hid/ring_lifo.h" | 10 | #include "core/hle/service/hid/controllers/types/touch_types.h" |
| 11 | |||
| 12 | namespace Core::HID { | ||
| 13 | class EmulatedConsole; | ||
| 14 | } | ||
| 13 | 15 | ||
| 14 | namespace Service::HID { | 16 | namespace Service::HID { |
| 17 | struct GestureSharedMemoryFormat; | ||
| 18 | |||
| 15 | class Gesture final : public ControllerBase { | 19 | class Gesture final : public ControllerBase { |
| 16 | public: | 20 | public: |
| 17 | explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 21 | explicit Gesture(Core::HID::HIDCore& hid_core_, |
| 22 | GestureSharedMemoryFormat& gesture_shared_memory); | ||
| 18 | ~Gesture() override; | 23 | ~Gesture() override; |
| 19 | 24 | ||
| 20 | // Called when the controller is initialized | 25 | // Called when the controller is initialized |
| @@ -27,79 +32,6 @@ public: | |||
| 27 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 32 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 28 | 33 | ||
| 29 | private: | 34 | private: |
| 30 | static constexpr size_t MAX_FINGERS = 16; | ||
| 31 | static constexpr size_t MAX_POINTS = 4; | ||
| 32 | |||
| 33 | // This is nn::hid::GestureType | ||
| 34 | enum class GestureType : u32 { | ||
| 35 | Idle, // Nothing touching the screen | ||
| 36 | Complete, // Set at the end of a touch event | ||
| 37 | Cancel, // Set when the number of fingers change | ||
| 38 | Touch, // A finger just touched the screen | ||
| 39 | Press, // Set if last type is touch and the finger hasn't moved | ||
| 40 | Tap, // Fast press then release | ||
| 41 | Pan, // All points moving together across the screen | ||
| 42 | Swipe, // Fast press movement and release of a single point | ||
| 43 | Pinch, // All points moving away/closer to the midpoint | ||
| 44 | Rotate, // All points rotating from the midpoint | ||
| 45 | }; | ||
| 46 | |||
| 47 | // This is nn::hid::GestureDirection | ||
| 48 | enum class GestureDirection : u32 { | ||
| 49 | None, | ||
| 50 | Left, | ||
| 51 | Up, | ||
| 52 | Right, | ||
| 53 | Down, | ||
| 54 | }; | ||
| 55 | |||
| 56 | // This is nn::hid::GestureAttribute | ||
| 57 | struct GestureAttribute { | ||
| 58 | union { | ||
| 59 | u32 raw{}; | ||
| 60 | |||
| 61 | BitField<4, 1, u32> is_new_touch; | ||
| 62 | BitField<8, 1, u32> is_double_tap; | ||
| 63 | }; | ||
| 64 | }; | ||
| 65 | static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); | ||
| 66 | |||
| 67 | // This is nn::hid::GestureState | ||
| 68 | struct GestureState { | ||
| 69 | s64 sampling_number{}; | ||
| 70 | s64 detection_count{}; | ||
| 71 | GestureType type{GestureType::Idle}; | ||
| 72 | GestureDirection direction{GestureDirection::None}; | ||
| 73 | Common::Point<s32> pos{}; | ||
| 74 | Common::Point<s32> delta{}; | ||
| 75 | f32 vel_x{}; | ||
| 76 | f32 vel_y{}; | ||
| 77 | GestureAttribute attributes{}; | ||
| 78 | f32 scale{}; | ||
| 79 | f32 rotation_angle{}; | ||
| 80 | s32 point_count{}; | ||
| 81 | std::array<Common::Point<s32>, 4> points{}; | ||
| 82 | }; | ||
| 83 | static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); | ||
| 84 | |||
| 85 | struct GestureProperties { | ||
| 86 | std::array<Common::Point<s32>, MAX_POINTS> points{}; | ||
| 87 | std::size_t active_points{}; | ||
| 88 | Common::Point<s32> mid_point{}; | ||
| 89 | s64 detection_count{}; | ||
| 90 | u64 delta_time{}; | ||
| 91 | f32 average_distance{}; | ||
| 92 | f32 angle{}; | ||
| 93 | }; | ||
| 94 | |||
| 95 | struct GestureSharedMemory { | ||
| 96 | // This is nn::hid::detail::GestureLifo | ||
| 97 | Lifo<GestureState, hid_entry_count> gesture_lifo{}; | ||
| 98 | static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); | ||
| 99 | INSERT_PADDING_WORDS(0x3E); | ||
| 100 | }; | ||
| 101 | static_assert(sizeof(GestureSharedMemory) == 0x800, "GestureSharedMemory is an invalid size"); | ||
| 102 | |||
| 103 | // Reads input from all available input engines | 35 | // Reads input from all available input engines |
| 104 | void ReadTouchInput(); | 36 | void ReadTouchInput(); |
| 105 | 37 | ||
| @@ -142,7 +74,7 @@ private: | |||
| 142 | GestureProperties GetGestureProperties(); | 74 | GestureProperties GetGestureProperties(); |
| 143 | 75 | ||
| 144 | GestureState next_state{}; | 76 | GestureState next_state{}; |
| 145 | GestureSharedMemory* shared_memory = nullptr; | 77 | GestureSharedMemoryFormat& shared_memory; |
| 146 | Core::HID::EmulatedConsole* console = nullptr; | 78 | Core::HID::EmulatedConsole* console = nullptr; |
| 147 | 79 | ||
| 148 | std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; | 80 | std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; |
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index ddb1b0ba4..871e5036a 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp | |||
| @@ -1,23 +1,18 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <cstring> | ||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "common/settings.h" | 4 | #include "common/settings.h" |
| 7 | #include "core/core_timing.h" | 5 | #include "core/core_timing.h" |
| 8 | #include "core/hid/emulated_devices.h" | 6 | #include "core/hid/emulated_devices.h" |
| 9 | #include "core/hid/hid_core.h" | 7 | #include "core/hid/hid_core.h" |
| 10 | #include "core/hle/service/hid/controllers/keyboard.h" | 8 | #include "core/hle/service/hid/controllers/keyboard.h" |
| 9 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 11 | 10 | ||
| 12 | namespace Service::HID { | 11 | namespace Service::HID { |
| 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; | 12 | |
| 14 | 13 | Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, | |
| 15 | Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 14 | KeyboardSharedMemoryFormat& keyboard_shared_memory) |
| 16 | : ControllerBase{hid_core_} { | 15 | : ControllerBase{hid_core_}, shared_memory{keyboard_shared_memory} { |
| 17 | static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size, | ||
| 18 | "KeyboardSharedMemory is bigger than the shared memory"); | ||
| 19 | shared_memory = std::construct_at( | ||
| 20 | reinterpret_cast<KeyboardSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 21 | emulated_devices = hid_core.GetEmulatedDevices(); | 16 | emulated_devices = hid_core.GetEmulatedDevices(); |
| 22 | } | 17 | } |
| 23 | 18 | ||
| @@ -29,12 +24,12 @@ void Keyboard::OnRelease() {} | |||
| 29 | 24 | ||
| 30 | void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 25 | void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 31 | if (!IsControllerActivated()) { | 26 | if (!IsControllerActivated()) { |
| 32 | shared_memory->keyboard_lifo.buffer_count = 0; | 27 | shared_memory.keyboard_lifo.buffer_count = 0; |
| 33 | shared_memory->keyboard_lifo.buffer_tail = 0; | 28 | shared_memory.keyboard_lifo.buffer_tail = 0; |
| 34 | return; | 29 | return; |
| 35 | } | 30 | } |
| 36 | 31 | ||
| 37 | const auto& last_entry = shared_memory->keyboard_lifo.ReadCurrentEntry().state; | 32 | const auto& last_entry = shared_memory.keyboard_lifo.ReadCurrentEntry().state; |
| 38 | next_state.sampling_number = last_entry.sampling_number + 1; | 33 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 39 | 34 | ||
| 40 | if (Settings::values.keyboard_enabled) { | 35 | if (Settings::values.keyboard_enabled) { |
| @@ -46,7 +41,7 @@ void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 46 | next_state.attribute.is_connected.Assign(1); | 41 | next_state.attribute.is_connected.Assign(1); |
| 47 | } | 42 | } |
| 48 | 43 | ||
| 49 | shared_memory->keyboard_lifo.WriteNextEntry(next_state); | 44 | shared_memory.keyboard_lifo.WriteNextEntry(next_state); |
| 50 | } | 45 | } |
| 51 | 46 | ||
| 52 | } // namespace Service::HID | 47 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 172ec1309..4d72171b9 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h | |||
| @@ -3,20 +3,16 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "core/hle/service/hid/controllers/controller_base.h" | 6 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 8 | #include "core/hle/service/hid/ring_lifo.h" | 7 | #include "core/hle/service/hid/controllers/types/keyboard_types.h" |
| 9 | |||
| 10 | namespace Core::HID { | ||
| 11 | class EmulatedDevices; | ||
| 12 | struct KeyboardModifier; | ||
| 13 | struct KeyboardKey; | ||
| 14 | } // namespace Core::HID | ||
| 15 | 8 | ||
| 16 | namespace Service::HID { | 9 | namespace Service::HID { |
| 10 | struct KeyboardSharedMemoryFormat; | ||
| 11 | |||
| 17 | class Keyboard final : public ControllerBase { | 12 | class Keyboard final : public ControllerBase { |
| 18 | public: | 13 | public: |
| 19 | explicit Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 14 | explicit Keyboard(Core::HID::HIDCore& hid_core_, |
| 15 | KeyboardSharedMemoryFormat& keyboard_shared_memory); | ||
| 20 | ~Keyboard() override; | 16 | ~Keyboard() override; |
| 21 | 17 | ||
| 22 | // Called when the controller is initialized | 18 | // Called when the controller is initialized |
| @@ -29,25 +25,8 @@ public: | |||
| 29 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 25 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 30 | 26 | ||
| 31 | private: | 27 | private: |
| 32 | // This is nn::hid::detail::KeyboardState | ||
| 33 | struct KeyboardState { | ||
| 34 | s64 sampling_number{}; | ||
| 35 | Core::HID::KeyboardModifier modifier{}; | ||
| 36 | Core::HID::KeyboardAttribute attribute{}; | ||
| 37 | Core::HID::KeyboardKey key{}; | ||
| 38 | }; | ||
| 39 | static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); | ||
| 40 | |||
| 41 | struct KeyboardSharedMemory { | ||
| 42 | // This is nn::hid::detail::KeyboardLifo | ||
| 43 | Lifo<KeyboardState, hid_entry_count> keyboard_lifo{}; | ||
| 44 | static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); | ||
| 45 | INSERT_PADDING_WORDS(0xA); | ||
| 46 | }; | ||
| 47 | static_assert(sizeof(KeyboardSharedMemory) == 0x400, "KeyboardSharedMemory is an invalid size"); | ||
| 48 | |||
| 49 | KeyboardState next_state{}; | 28 | KeyboardState next_state{}; |
| 50 | KeyboardSharedMemory* shared_memory = nullptr; | 29 | KeyboardSharedMemoryFormat& shared_memory; |
| 51 | Core::HID::EmulatedDevices* emulated_devices = nullptr; | 30 | Core::HID::EmulatedDevices* emulated_devices = nullptr; |
| 52 | }; | 31 | }; |
| 53 | } // namespace Service::HID | 32 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 6e5a04e34..de5b2c804 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp | |||
| @@ -1,22 +1,17 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <cstring> | ||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "core/core_timing.h" | 4 | #include "core/core_timing.h" |
| 7 | #include "core/frontend/emu_window.h" | 5 | #include "core/frontend/emu_window.h" |
| 8 | #include "core/hid/emulated_devices.h" | 6 | #include "core/hid/emulated_devices.h" |
| 9 | #include "core/hid/hid_core.h" | 7 | #include "core/hid/hid_core.h" |
| 10 | #include "core/hle/service/hid/controllers/mouse.h" | 8 | #include "core/hle/service/hid/controllers/mouse.h" |
| 9 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 11 | 10 | ||
| 12 | namespace Service::HID { | 11 | namespace Service::HID { |
| 13 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; | ||
| 14 | 12 | ||
| 15 | Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { | 13 | Mouse::Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory) |
| 16 | static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size, | 14 | : ControllerBase{hid_core_}, shared_memory{mouse_shared_memory} { |
| 17 | "MouseSharedMemory is bigger than the shared memory"); | ||
| 18 | shared_memory = std::construct_at( | ||
| 19 | reinterpret_cast<MouseSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 20 | emulated_devices = hid_core.GetEmulatedDevices(); | 15 | emulated_devices = hid_core.GetEmulatedDevices(); |
| 21 | } | 16 | } |
| 22 | 17 | ||
| @@ -27,14 +22,14 @@ void Mouse::OnRelease() {} | |||
| 27 | 22 | ||
| 28 | void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 23 | void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 29 | if (!IsControllerActivated()) { | 24 | if (!IsControllerActivated()) { |
| 30 | shared_memory->mouse_lifo.buffer_count = 0; | 25 | shared_memory.mouse_lifo.buffer_count = 0; |
| 31 | shared_memory->mouse_lifo.buffer_tail = 0; | 26 | shared_memory.mouse_lifo.buffer_tail = 0; |
| 32 | return; | 27 | return; |
| 33 | } | 28 | } |
| 34 | 29 | ||
| 35 | next_state = {}; | 30 | next_state = {}; |
| 36 | 31 | ||
| 37 | const auto& last_entry = shared_memory->mouse_lifo.ReadCurrentEntry().state; | 32 | const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state; |
| 38 | next_state.sampling_number = last_entry.sampling_number + 1; | 33 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 39 | 34 | ||
| 40 | if (Settings::values.mouse_enabled) { | 35 | if (Settings::values.mouse_enabled) { |
| @@ -53,7 +48,7 @@ void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 53 | next_state.button = mouse_button_state; | 48 | next_state.button = mouse_button_state; |
| 54 | } | 49 | } |
| 55 | 50 | ||
| 56 | shared_memory->mouse_lifo.WriteNextEntry(next_state); | 51 | shared_memory.mouse_lifo.WriteNextEntry(next_state); |
| 57 | } | 52 | } |
| 58 | 53 | ||
| 59 | } // namespace Service::HID | 54 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index a80f3823f..363f316a5 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h | |||
| @@ -3,9 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "core/hle/service/hid/controllers/controller_base.h" | 6 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 8 | #include "core/hle/service/hid/ring_lifo.h" | ||
| 9 | 7 | ||
| 10 | namespace Core::HID { | 8 | namespace Core::HID { |
| 11 | class EmulatedDevices; | 9 | class EmulatedDevices; |
| @@ -14,9 +12,11 @@ struct AnalogStickState; | |||
| 14 | } // namespace Core::HID | 12 | } // namespace Core::HID |
| 15 | 13 | ||
| 16 | namespace Service::HID { | 14 | namespace Service::HID { |
| 15 | struct MouseSharedMemoryFormat; | ||
| 16 | |||
| 17 | class Mouse final : public ControllerBase { | 17 | class Mouse final : public ControllerBase { |
| 18 | public: | 18 | public: |
| 19 | explicit Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 19 | explicit Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory); |
| 20 | ~Mouse() override; | 20 | ~Mouse() override; |
| 21 | 21 | ||
| 22 | // Called when the controller is initialized | 22 | // Called when the controller is initialized |
| @@ -29,17 +29,9 @@ public: | |||
| 29 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 29 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 30 | 30 | ||
| 31 | private: | 31 | private: |
| 32 | struct MouseSharedMemory { | ||
| 33 | // This is nn::hid::detail::MouseLifo | ||
| 34 | Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{}; | ||
| 35 | static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); | ||
| 36 | INSERT_PADDING_WORDS(0x2C); | ||
| 37 | }; | ||
| 38 | static_assert(sizeof(MouseSharedMemory) == 0x400, "MouseSharedMemory is an invalid size"); | ||
| 39 | |||
| 40 | Core::HID::MouseState next_state{}; | 32 | Core::HID::MouseState next_state{}; |
| 41 | Core::HID::AnalogStickState last_mouse_wheel_state{}; | 33 | Core::HID::AnalogStickState last_mouse_wheel_state{}; |
| 42 | MouseSharedMemory* shared_memory = nullptr; | 34 | MouseSharedMemoryFormat& shared_memory; |
| 43 | Core::HID::EmulatedDevices* emulated_devices = nullptr; | 35 | Core::HID::EmulatedDevices* emulated_devices = nullptr; |
| 44 | }; | 36 | }; |
| 45 | } // namespace Service::HID | 37 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 08ee9de9c..53a737cf5 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -17,12 +17,12 @@ | |||
| 17 | #include "core/hle/kernel/k_event.h" | 17 | #include "core/hle/kernel/k_event.h" |
| 18 | #include "core/hle/kernel/k_readable_event.h" | 18 | #include "core/hle/kernel/k_readable_event.h" |
| 19 | #include "core/hle/service/hid/controllers/npad.h" | 19 | #include "core/hle/service/hid/controllers/npad.h" |
| 20 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 20 | #include "core/hle/service/hid/errors.h" | 21 | #include "core/hle/service/hid/errors.h" |
| 21 | #include "core/hle/service/hid/hid_util.h" | 22 | #include "core/hle/service/hid/hid_util.h" |
| 22 | #include "core/hle/service/kernel_helpers.h" | 23 | #include "core/hle/service/kernel_helpers.h" |
| 23 | 24 | ||
| 24 | namespace Service::HID { | 25 | namespace Service::HID { |
| 25 | constexpr std::size_t NPAD_OFFSET = 0x9A00; | ||
| 26 | constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ | 26 | constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ |
| 27 | Core::HID::NpadIdType::Player1, Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3, | 27 | Core::HID::NpadIdType::Player1, Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3, |
| 28 | Core::HID::NpadIdType::Player4, Core::HID::NpadIdType::Player5, Core::HID::NpadIdType::Player6, | 28 | Core::HID::NpadIdType::Player4, Core::HID::NpadIdType::Player5, Core::HID::NpadIdType::Player6, |
| @@ -30,14 +30,12 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ | |||
| 30 | Core::HID::NpadIdType::Handheld, | 30 | Core::HID::NpadIdType::Handheld, |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | 33 | NPad::NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format, |
| 34 | KernelHelpers::ServiceContext& service_context_) | 34 | KernelHelpers::ServiceContext& service_context_) |
| 35 | : ControllerBase{hid_core_}, service_context{service_context_} { | 35 | : ControllerBase{hid_core_}, service_context{service_context_} { |
| 36 | static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size); | ||
| 37 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 36 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| 38 | auto& controller = controller_data[i]; | 37 | auto& controller = controller_data[i]; |
| 39 | controller.shared_memory = std::construct_at(reinterpret_cast<NpadInternalState*>( | 38 | controller.shared_memory = &npad_shared_memory_format.npad_entry[i].internal_state; |
| 40 | raw_shared_memory_ + NPAD_OFFSET + (i * sizeof(NpadInternalState)))); | ||
| 41 | controller.device = hid_core.GetEmulatedControllerByIndex(i); | 39 | controller.device = hid_core.GetEmulatedControllerByIndex(i); |
| 42 | controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = | 40 | controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = |
| 43 | Core::HID::DEFAULT_VIBRATION_VALUE; | 41 | Core::HID::DEFAULT_VIBRATION_VALUE; |
| @@ -617,7 +615,7 @@ void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { | |||
| 617 | hold_type = joy_hold_type; | 615 | hold_type = joy_hold_type; |
| 618 | } | 616 | } |
| 619 | 617 | ||
| 620 | NPad::NpadJoyHoldType NPad::GetHoldType() const { | 618 | NpadJoyHoldType NPad::GetHoldType() const { |
| 621 | return hold_type; | 619 | return hold_type; |
| 622 | } | 620 | } |
| 623 | 621 | ||
| @@ -630,7 +628,7 @@ void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_m | |||
| 630 | handheld_activation_mode = activation_mode; | 628 | handheld_activation_mode = activation_mode; |
| 631 | } | 629 | } |
| 632 | 630 | ||
| 633 | NPad::NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { | 631 | NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { |
| 634 | return handheld_activation_mode; | 632 | return handheld_activation_mode; |
| 635 | } | 633 | } |
| 636 | 634 | ||
| @@ -638,7 +636,7 @@ void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) { | |||
| 638 | communication_mode = communication_mode_; | 636 | communication_mode = communication_mode_; |
| 639 | } | 637 | } |
| 640 | 638 | ||
| 641 | NPad::NpadCommunicationMode NPad::GetNpadCommunicationMode() const { | 639 | NpadCommunicationMode NPad::GetNpadCommunicationMode() const { |
| 642 | return communication_mode; | 640 | return communication_mode; |
| 643 | } | 641 | } |
| 644 | 642 | ||
| @@ -978,27 +976,27 @@ Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( | |||
| 978 | return ResultSuccess; | 976 | return ResultSuccess; |
| 979 | } | 977 | } |
| 980 | 978 | ||
| 981 | NPad::SixAxisLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) { | 979 | NpadSixAxisSensorLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) { |
| 982 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo; | 980 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo; |
| 983 | } | 981 | } |
| 984 | 982 | ||
| 985 | NPad::SixAxisLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) { | 983 | NpadSixAxisSensorLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) { |
| 986 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo; | 984 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo; |
| 987 | } | 985 | } |
| 988 | 986 | ||
| 989 | NPad::SixAxisLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) { | 987 | NpadSixAxisSensorLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) { |
| 990 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo; | 988 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo; |
| 991 | } | 989 | } |
| 992 | 990 | ||
| 993 | NPad::SixAxisLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) { | 991 | NpadSixAxisSensorLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) { |
| 994 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo; | 992 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo; |
| 995 | } | 993 | } |
| 996 | 994 | ||
| 997 | NPad::SixAxisLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) { | 995 | NpadSixAxisSensorLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) { |
| 998 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo; | 996 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo; |
| 999 | } | 997 | } |
| 1000 | 998 | ||
| 1001 | NPad::SixAxisLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) { | 999 | NpadSixAxisSensorLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) { |
| 1002 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo; | 1000 | return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo; |
| 1003 | } | 1001 | } |
| 1004 | 1002 | ||
| @@ -1343,7 +1341,7 @@ const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( | |||
| 1343 | } | 1341 | } |
| 1344 | } | 1342 | } |
| 1345 | 1343 | ||
| 1346 | NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { | 1344 | AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { |
| 1347 | const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory; | 1345 | const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory; |
| 1348 | 1346 | ||
| 1349 | return { | 1347 | return { |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 9167c93f0..4e2412356 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -8,12 +8,10 @@ | |||
| 8 | #include <mutex> | 8 | #include <mutex> |
| 9 | #include <span> | 9 | #include <span> |
| 10 | 10 | ||
| 11 | #include "common/bit_field.h" | ||
| 12 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 13 | |||
| 14 | #include "core/hid/hid_types.h" | 12 | #include "core/hid/hid_types.h" |
| 15 | #include "core/hle/service/hid/controllers/controller_base.h" | 13 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 16 | #include "core/hle/service/hid/ring_lifo.h" | 14 | #include "core/hle/service/hid/controllers/types/npad_types.h" |
| 17 | 15 | ||
| 18 | namespace Core::HID { | 16 | namespace Core::HID { |
| 19 | class EmulatedController; | 17 | class EmulatedController; |
| @@ -32,10 +30,13 @@ class ServiceContext; | |||
| 32 | union Result; | 30 | union Result; |
| 33 | 31 | ||
| 34 | namespace Service::HID { | 32 | namespace Service::HID { |
| 33 | struct NpadInternalState; | ||
| 34 | struct NpadSixAxisSensorLifo; | ||
| 35 | struct NpadSharedMemoryFormat; | ||
| 35 | 36 | ||
| 36 | class NPad final : public ControllerBase { | 37 | class NPad final : public ControllerBase { |
| 37 | public: | 38 | public: |
| 38 | explicit NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | 39 | explicit NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format, |
| 39 | KernelHelpers::ServiceContext& service_context_); | 40 | KernelHelpers::ServiceContext& service_context_); |
| 40 | ~NPad() override; | 41 | ~NPad() override; |
| 41 | 42 | ||
| @@ -48,89 +49,6 @@ public: | |||
| 48 | // When the controller is requesting an update for the shared memory | 49 | // When the controller is requesting an update for the shared memory |
| 49 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 50 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 50 | 51 | ||
| 51 | // This is nn::hid::NpadJoyHoldType | ||
| 52 | enum class NpadJoyHoldType : u64 { | ||
| 53 | Vertical = 0, | ||
| 54 | Horizontal = 1, | ||
| 55 | }; | ||
| 56 | |||
| 57 | // This is nn::hid::NpadJoyAssignmentMode | ||
| 58 | enum class NpadJoyAssignmentMode : u32 { | ||
| 59 | Dual = 0, | ||
| 60 | Single = 1, | ||
| 61 | }; | ||
| 62 | |||
| 63 | // This is nn::hid::NpadJoyDeviceType | ||
| 64 | enum class NpadJoyDeviceType : s64 { | ||
| 65 | Left = 0, | ||
| 66 | Right = 1, | ||
| 67 | }; | ||
| 68 | |||
| 69 | // This is nn::hid::NpadHandheldActivationMode | ||
| 70 | enum class NpadHandheldActivationMode : u64 { | ||
| 71 | Dual = 0, | ||
| 72 | Single = 1, | ||
| 73 | None = 2, | ||
| 74 | MaxActivationMode = 3, | ||
| 75 | }; | ||
| 76 | |||
| 77 | // This is nn::hid::system::AppletFooterUiAttributesSet | ||
| 78 | struct AppletFooterUiAttributes { | ||
| 79 | INSERT_PADDING_BYTES(0x4); | ||
| 80 | }; | ||
| 81 | |||
| 82 | // This is nn::hid::system::AppletFooterUiType | ||
| 83 | enum class AppletFooterUiType : u8 { | ||
| 84 | None = 0, | ||
| 85 | HandheldNone = 1, | ||
| 86 | HandheldJoyConLeftOnly = 2, | ||
| 87 | HandheldJoyConRightOnly = 3, | ||
| 88 | HandheldJoyConLeftJoyConRight = 4, | ||
| 89 | JoyDual = 5, | ||
| 90 | JoyDualLeftOnly = 6, | ||
| 91 | JoyDualRightOnly = 7, | ||
| 92 | JoyLeftHorizontal = 8, | ||
| 93 | JoyLeftVertical = 9, | ||
| 94 | JoyRightHorizontal = 10, | ||
| 95 | JoyRightVertical = 11, | ||
| 96 | SwitchProController = 12, | ||
| 97 | CompatibleProController = 13, | ||
| 98 | CompatibleJoyCon = 14, | ||
| 99 | LarkHvc1 = 15, | ||
| 100 | LarkHvc2 = 16, | ||
| 101 | LarkNesLeft = 17, | ||
| 102 | LarkNesRight = 18, | ||
| 103 | Lucia = 19, | ||
| 104 | Verification = 20, | ||
| 105 | Lagon = 21, | ||
| 106 | }; | ||
| 107 | |||
| 108 | using AppletFooterUiVariant = u8; | ||
| 109 | |||
| 110 | // This is "nn::hid::system::AppletDetailedUiType". | ||
| 111 | struct AppletDetailedUiType { | ||
| 112 | AppletFooterUiVariant ui_variant; | ||
| 113 | INSERT_PADDING_BYTES(0x2); | ||
| 114 | AppletFooterUiType footer; | ||
| 115 | }; | ||
| 116 | static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); | ||
| 117 | // This is nn::hid::NpadCommunicationMode | ||
| 118 | enum class NpadCommunicationMode : u64 { | ||
| 119 | Mode_5ms = 0, | ||
| 120 | Mode_10ms = 1, | ||
| 121 | Mode_15ms = 2, | ||
| 122 | Default = 3, | ||
| 123 | }; | ||
| 124 | |||
| 125 | enum class NpadRevision : u32 { | ||
| 126 | Revision0 = 0, | ||
| 127 | Revision1 = 1, | ||
| 128 | Revision2 = 2, | ||
| 129 | Revision3 = 3, | ||
| 130 | }; | ||
| 131 | |||
| 132 | using SixAxisLifo = Lifo<Core::HID::SixAxisSensorState, hid_entry_count>; | ||
| 133 | |||
| 134 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); | 52 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); |
| 135 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; | 53 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; |
| 136 | 54 | ||
| @@ -188,12 +106,12 @@ public: | |||
| 188 | Result ResetIsSixAxisSensorDeviceNewlyAssigned( | 106 | Result ResetIsSixAxisSensorDeviceNewlyAssigned( |
| 189 | const Core::HID::SixAxisSensorHandle& sixaxis_handle); | 107 | const Core::HID::SixAxisSensorHandle& sixaxis_handle); |
| 190 | 108 | ||
| 191 | SixAxisLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id); | 109 | NpadSixAxisSensorLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id); |
| 192 | SixAxisLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id); | 110 | NpadSixAxisSensorLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id); |
| 193 | SixAxisLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id); | 111 | NpadSixAxisSensorLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id); |
| 194 | SixAxisLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id); | 112 | NpadSixAxisSensorLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id); |
| 195 | SixAxisLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id); | 113 | NpadSixAxisSensorLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id); |
| 196 | SixAxisLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id); | 114 | NpadSixAxisSensorLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id); |
| 197 | 115 | ||
| 198 | Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; | 116 | Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; |
| 199 | Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, | 117 | Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, |
| @@ -221,214 +139,6 @@ public: | |||
| 221 | AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); | 139 | AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); |
| 222 | 140 | ||
| 223 | private: | 141 | private: |
| 224 | static constexpr std::size_t NPAD_COUNT = 10; | ||
| 225 | |||
| 226 | // This is nn::hid::detail::ColorAttribute | ||
| 227 | enum class ColorAttribute : u32 { | ||
| 228 | Ok = 0, | ||
| 229 | ReadError = 1, | ||
| 230 | NoController = 2, | ||
| 231 | }; | ||
| 232 | static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size"); | ||
| 233 | |||
| 234 | // This is nn::hid::detail::NpadFullKeyColorState | ||
| 235 | struct NpadFullKeyColorState { | ||
| 236 | ColorAttribute attribute{ColorAttribute::NoController}; | ||
| 237 | Core::HID::NpadControllerColor fullkey{}; | ||
| 238 | }; | ||
| 239 | static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); | ||
| 240 | |||
| 241 | // This is nn::hid::detail::NpadJoyColorState | ||
| 242 | struct NpadJoyColorState { | ||
| 243 | ColorAttribute attribute{ColorAttribute::NoController}; | ||
| 244 | Core::HID::NpadControllerColor left{}; | ||
| 245 | Core::HID::NpadControllerColor right{}; | ||
| 246 | }; | ||
| 247 | static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); | ||
| 248 | |||
| 249 | // This is nn::hid::NpadAttribute | ||
| 250 | struct NpadAttribute { | ||
| 251 | union { | ||
| 252 | u32 raw{}; | ||
| 253 | BitField<0, 1, u32> is_connected; | ||
| 254 | BitField<1, 1, u32> is_wired; | ||
| 255 | BitField<2, 1, u32> is_left_connected; | ||
| 256 | BitField<3, 1, u32> is_left_wired; | ||
| 257 | BitField<4, 1, u32> is_right_connected; | ||
| 258 | BitField<5, 1, u32> is_right_wired; | ||
| 259 | }; | ||
| 260 | }; | ||
| 261 | static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size"); | ||
| 262 | |||
| 263 | // This is nn::hid::NpadFullKeyState | ||
| 264 | // This is nn::hid::NpadHandheldState | ||
| 265 | // This is nn::hid::NpadJoyDualState | ||
| 266 | // This is nn::hid::NpadJoyLeftState | ||
| 267 | // This is nn::hid::NpadJoyRightState | ||
| 268 | // This is nn::hid::NpadPalmaState | ||
| 269 | // This is nn::hid::NpadSystemExtState | ||
| 270 | struct NPadGenericState { | ||
| 271 | s64_le sampling_number{}; | ||
| 272 | Core::HID::NpadButtonState npad_buttons{}; | ||
| 273 | Core::HID::AnalogStickState l_stick{}; | ||
| 274 | Core::HID::AnalogStickState r_stick{}; | ||
| 275 | NpadAttribute connection_status{}; | ||
| 276 | INSERT_PADDING_BYTES(4); // Reserved | ||
| 277 | }; | ||
| 278 | static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); | ||
| 279 | |||
| 280 | // This is nn::hid::server::NpadGcTriggerState | ||
| 281 | struct NpadGcTriggerState { | ||
| 282 | s64 sampling_number{}; | ||
| 283 | s32 l_analog{}; | ||
| 284 | s32 r_analog{}; | ||
| 285 | }; | ||
| 286 | static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); | ||
| 287 | |||
| 288 | // This is nn::hid::NpadSystemProperties | ||
| 289 | struct NPadSystemProperties { | ||
| 290 | union { | ||
| 291 | s64 raw{}; | ||
| 292 | BitField<0, 1, s64> is_charging_joy_dual; | ||
| 293 | BitField<1, 1, s64> is_charging_joy_left; | ||
| 294 | BitField<2, 1, s64> is_charging_joy_right; | ||
| 295 | BitField<3, 1, s64> is_powered_joy_dual; | ||
| 296 | BitField<4, 1, s64> is_powered_joy_left; | ||
| 297 | BitField<5, 1, s64> is_powered_joy_right; | ||
| 298 | BitField<9, 1, s64> is_system_unsupported_button; | ||
| 299 | BitField<10, 1, s64> is_system_ext_unsupported_button; | ||
| 300 | BitField<11, 1, s64> is_vertical; | ||
| 301 | BitField<12, 1, s64> is_horizontal; | ||
| 302 | BitField<13, 1, s64> use_plus; | ||
| 303 | BitField<14, 1, s64> use_minus; | ||
| 304 | BitField<15, 1, s64> use_directional_buttons; | ||
| 305 | }; | ||
| 306 | }; | ||
| 307 | static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); | ||
| 308 | |||
| 309 | // This is nn::hid::NpadSystemButtonProperties | ||
| 310 | struct NpadSystemButtonProperties { | ||
| 311 | union { | ||
| 312 | s32 raw{}; | ||
| 313 | BitField<0, 1, s32> is_home_button_protection_enabled; | ||
| 314 | }; | ||
| 315 | }; | ||
| 316 | static_assert(sizeof(NpadSystemButtonProperties) == 0x4, | ||
| 317 | "NPadButtonProperties is an invalid size"); | ||
| 318 | |||
| 319 | // This is nn::hid::system::DeviceType | ||
| 320 | struct DeviceType { | ||
| 321 | union { | ||
| 322 | u32 raw{}; | ||
| 323 | BitField<0, 1, s32> fullkey; | ||
| 324 | BitField<1, 1, s32> debug_pad; | ||
| 325 | BitField<2, 1, s32> handheld_left; | ||
| 326 | BitField<3, 1, s32> handheld_right; | ||
| 327 | BitField<4, 1, s32> joycon_left; | ||
| 328 | BitField<5, 1, s32> joycon_right; | ||
| 329 | BitField<6, 1, s32> palma; | ||
| 330 | BitField<7, 1, s32> lark_hvc_left; | ||
| 331 | BitField<8, 1, s32> lark_hvc_right; | ||
| 332 | BitField<9, 1, s32> lark_nes_left; | ||
| 333 | BitField<10, 1, s32> lark_nes_right; | ||
| 334 | BitField<11, 1, s32> handheld_lark_hvc_left; | ||
| 335 | BitField<12, 1, s32> handheld_lark_hvc_right; | ||
| 336 | BitField<13, 1, s32> handheld_lark_nes_left; | ||
| 337 | BitField<14, 1, s32> handheld_lark_nes_right; | ||
| 338 | BitField<15, 1, s32> lucia; | ||
| 339 | BitField<16, 1, s32> lagon; | ||
| 340 | BitField<17, 1, s32> lager; | ||
| 341 | BitField<31, 1, s32> system; | ||
| 342 | }; | ||
| 343 | }; | ||
| 344 | |||
| 345 | // This is nn::hid::detail::NfcXcdDeviceHandleStateImpl | ||
| 346 | struct NfcXcdDeviceHandleStateImpl { | ||
| 347 | u64 handle{}; | ||
| 348 | bool is_available{}; | ||
| 349 | bool is_activated{}; | ||
| 350 | INSERT_PADDING_BYTES(0x6); // Reserved | ||
| 351 | u64 sampling_number{}; | ||
| 352 | }; | ||
| 353 | static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, | ||
| 354 | "NfcXcdDeviceHandleStateImpl is an invalid size"); | ||
| 355 | |||
| 356 | // This is nn::hid::NpadLarkType | ||
| 357 | enum class NpadLarkType : u32 { | ||
| 358 | Invalid, | ||
| 359 | H1, | ||
| 360 | H2, | ||
| 361 | NL, | ||
| 362 | NR, | ||
| 363 | }; | ||
| 364 | |||
| 365 | // This is nn::hid::NpadLuciaType | ||
| 366 | enum class NpadLuciaType : u32 { | ||
| 367 | Invalid, | ||
| 368 | J, | ||
| 369 | E, | ||
| 370 | U, | ||
| 371 | }; | ||
| 372 | |||
| 373 | // This is nn::hid::NpadLagonType | ||
| 374 | enum class NpadLagonType : u32 { | ||
| 375 | Invalid, | ||
| 376 | }; | ||
| 377 | |||
| 378 | // This is nn::hid::NpadLagerType | ||
| 379 | enum class NpadLagerType : u32 { | ||
| 380 | Invalid, | ||
| 381 | J, | ||
| 382 | E, | ||
| 383 | U, | ||
| 384 | }; | ||
| 385 | |||
| 386 | // This is nn::hid::detail::NpadInternalState | ||
| 387 | struct NpadInternalState { | ||
| 388 | Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; | ||
| 389 | NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; | ||
| 390 | NpadFullKeyColorState fullkey_color{}; | ||
| 391 | NpadJoyColorState joycon_color{}; | ||
| 392 | Lifo<NPadGenericState, hid_entry_count> fullkey_lifo{}; | ||
| 393 | Lifo<NPadGenericState, hid_entry_count> handheld_lifo{}; | ||
| 394 | Lifo<NPadGenericState, hid_entry_count> joy_dual_lifo{}; | ||
| 395 | Lifo<NPadGenericState, hid_entry_count> joy_left_lifo{}; | ||
| 396 | Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{}; | ||
| 397 | Lifo<NPadGenericState, hid_entry_count> palma_lifo{}; | ||
| 398 | Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{}; | ||
| 399 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{}; | ||
| 400 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{}; | ||
| 401 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{}; | ||
| 402 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{}; | ||
| 403 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{}; | ||
| 404 | Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{}; | ||
| 405 | DeviceType device_type{}; | ||
| 406 | INSERT_PADDING_BYTES(0x4); // Reserved | ||
| 407 | NPadSystemProperties system_properties{}; | ||
| 408 | NpadSystemButtonProperties button_properties{}; | ||
| 409 | Core::HID::NpadBatteryLevel battery_level_dual{}; | ||
| 410 | Core::HID::NpadBatteryLevel battery_level_left{}; | ||
| 411 | Core::HID::NpadBatteryLevel battery_level_right{}; | ||
| 412 | AppletFooterUiAttributes applet_footer_attributes{}; | ||
| 413 | AppletFooterUiType applet_footer_type{AppletFooterUiType::None}; | ||
| 414 | INSERT_PADDING_BYTES(0x5B); // Reserved | ||
| 415 | INSERT_PADDING_BYTES(0x20); // Unknown | ||
| 416 | Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{}; | ||
| 417 | NpadLarkType lark_type_l_and_main{}; | ||
| 418 | NpadLarkType lark_type_r{}; | ||
| 419 | NpadLuciaType lucia_type{}; | ||
| 420 | NpadLagonType lagon_type{}; | ||
| 421 | NpadLagerType lager_type{}; | ||
| 422 | Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; | ||
| 423 | Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; | ||
| 424 | Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; | ||
| 425 | Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; | ||
| 426 | Core::HID::SixAxisSensorProperties sixaxis_left_properties; | ||
| 427 | Core::HID::SixAxisSensorProperties sixaxis_right_properties; | ||
| 428 | INSERT_PADDING_BYTES(0xc06); // Unknown | ||
| 429 | }; | ||
| 430 | static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size"); | ||
| 431 | |||
| 432 | struct VibrationData { | 142 | struct VibrationData { |
| 433 | bool device_mounted{}; | 143 | bool device_mounted{}; |
| 434 | Core::HID::VibrationValue latest_vibration_value{}; | 144 | Core::HID::VibrationValue latest_vibration_value{}; |
| @@ -479,7 +189,7 @@ private: | |||
| 479 | 189 | ||
| 480 | std::atomic<u64> press_state{}; | 190 | std::atomic<u64> press_state{}; |
| 481 | 191 | ||
| 482 | std::array<NpadControllerData, NPAD_COUNT> controller_data{}; | 192 | std::array<NpadControllerData, NpadCount> controller_data{}; |
| 483 | KernelHelpers::ServiceContext& service_context; | 193 | KernelHelpers::ServiceContext& service_context; |
| 484 | std::mutex mutex; | 194 | std::mutex mutex; |
| 485 | std::vector<Core::HID::NpadIdType> supported_npad_id_types{}; | 195 | std::vector<Core::HID::NpadIdType> supported_npad_id_types{}; |
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp index 588ff9d62..aa0454b5e 100644 --- a/src/core/hle/service/hid/controllers/palma.cpp +++ b/src/core/hle/service/hid/controllers/palma.cpp | |||
| @@ -12,8 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Service::HID { | 13 | namespace Service::HID { |
| 14 | 14 | ||
| 15 | Palma::Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | 15 | Palma::Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_) |
| 16 | KernelHelpers::ServiceContext& service_context_) | ||
| 17 | : ControllerBase{hid_core_}, service_context{service_context_} { | 16 | : ControllerBase{hid_core_}, service_context{service_context_} { |
| 18 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); | 17 | controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); |
| 19 | operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); | 18 | operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); |
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h index a6047f36a..73884230d 100644 --- a/src/core/hle/service/hid/controllers/palma.h +++ b/src/core/hle/service/hid/controllers/palma.h | |||
| @@ -97,8 +97,7 @@ public: | |||
| 97 | static_assert(sizeof(PalmaConnectionHandle) == 0x8, | 97 | static_assert(sizeof(PalmaConnectionHandle) == 0x8, |
| 98 | "PalmaConnectionHandle has incorrect size."); | 98 | "PalmaConnectionHandle has incorrect size."); |
| 99 | 99 | ||
| 100 | explicit Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | 100 | explicit Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_); |
| 101 | KernelHelpers::ServiceContext& service_context_); | ||
| 102 | ~Palma() override; | 101 | ~Palma() override; |
| 103 | 102 | ||
| 104 | // Called when the controller is initialized | 103 | // Called when the controller is initialized |
diff --git a/src/core/hle/service/hid/controllers/shared_memory_format.h b/src/core/hle/service/hid/controllers/shared_memory_format.h new file mode 100644 index 000000000..2986c113e --- /dev/null +++ b/src/core/hle/service/hid/controllers/shared_memory_format.h | |||
| @@ -0,0 +1,240 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_funcs.h" | ||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "common/vector_math.h" | ||
| 9 | #include "core/hid/hid_types.h" | ||
| 10 | #include "core/hle/service/hid//controllers/types/debug_pad_types.h" | ||
| 11 | #include "core/hle/service/hid//controllers/types/keyboard_types.h" | ||
| 12 | #include "core/hle/service/hid//controllers/types/mouse_types.h" | ||
| 13 | #include "core/hle/service/hid//controllers/types/npad_types.h" | ||
| 14 | #include "core/hle/service/hid//controllers/types/touch_types.h" | ||
| 15 | #include "core/hle/service/hid/ring_lifo.h" | ||
| 16 | |||
| 17 | namespace Service::HID { | ||
| 18 | static const std::size_t HidEntryCount = 17; | ||
| 19 | |||
| 20 | struct CommonHeader { | ||
| 21 | s64 timestamp{}; | ||
| 22 | s64 total_entry_count{}; | ||
| 23 | s64 last_entry_index{}; | ||
| 24 | s64 entry_count{}; | ||
| 25 | }; | ||
| 26 | static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); | ||
| 27 | |||
| 28 | // This is nn::hid::detail::DebugPadSharedMemoryFormat | ||
| 29 | struct DebugPadSharedMemoryFormat { | ||
| 30 | // This is nn::hid::detail::DebugPadLifo | ||
| 31 | Lifo<DebugPadState, HidEntryCount> debug_pad_lifo{}; | ||
| 32 | static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); | ||
| 33 | INSERT_PADDING_WORDS(0x4E); | ||
| 34 | }; | ||
| 35 | static_assert(sizeof(DebugPadSharedMemoryFormat) == 0x400, | ||
| 36 | "DebugPadSharedMemoryFormat is an invalid size"); | ||
| 37 | |||
| 38 | // This is nn::hid::detail::TouchScreenSharedMemoryFormat | ||
| 39 | struct TouchScreenSharedMemoryFormat { | ||
| 40 | // This is nn::hid::detail::TouchScreenLifo | ||
| 41 | Lifo<TouchScreenState, HidEntryCount> touch_screen_lifo{}; | ||
| 42 | static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); | ||
| 43 | INSERT_PADDING_WORDS(0xF2); | ||
| 44 | }; | ||
| 45 | static_assert(sizeof(TouchScreenSharedMemoryFormat) == 0x3000, | ||
| 46 | "TouchScreenSharedMemoryFormat is an invalid size"); | ||
| 47 | |||
| 48 | // This is nn::hid::detail::MouseSharedMemoryFormat | ||
| 49 | struct MouseSharedMemoryFormat { | ||
| 50 | // This is nn::hid::detail::MouseLifo | ||
| 51 | Lifo<Core::HID::MouseState, HidEntryCount> mouse_lifo{}; | ||
| 52 | static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); | ||
| 53 | INSERT_PADDING_WORDS(0x2C); | ||
| 54 | }; | ||
| 55 | static_assert(sizeof(MouseSharedMemoryFormat) == 0x400, | ||
| 56 | "MouseSharedMemoryFormat is an invalid size"); | ||
| 57 | |||
| 58 | // This is nn::hid::detail::KeyboardSharedMemoryFormat | ||
| 59 | struct KeyboardSharedMemoryFormat { | ||
| 60 | // This is nn::hid::detail::KeyboardLifo | ||
| 61 | Lifo<KeyboardState, HidEntryCount> keyboard_lifo{}; | ||
| 62 | static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); | ||
| 63 | INSERT_PADDING_WORDS(0xA); | ||
| 64 | }; | ||
| 65 | static_assert(sizeof(KeyboardSharedMemoryFormat) == 0x400, | ||
| 66 | "KeyboardSharedMemoryFormat is an invalid size"); | ||
| 67 | |||
| 68 | // This is nn::hid::detail::DigitizerSharedMemoryFormat | ||
| 69 | struct DigitizerSharedMemoryFormat { | ||
| 70 | CommonHeader header; | ||
| 71 | INSERT_PADDING_BYTES(0xFE0); | ||
| 72 | }; | ||
| 73 | static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000, | ||
| 74 | "DigitizerSharedMemoryFormat is an invalid size"); | ||
| 75 | |||
| 76 | // This is nn::hid::detail::HomeButtonSharedMemoryFormat | ||
| 77 | struct HomeButtonSharedMemoryFormat { | ||
| 78 | CommonHeader header; | ||
| 79 | INSERT_PADDING_BYTES(0x1E0); | ||
| 80 | }; | ||
| 81 | static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200, | ||
| 82 | "HomeButtonSharedMemoryFormat is an invalid size"); | ||
| 83 | |||
| 84 | // This is nn::hid::detail::SleepButtonSharedMemoryFormat | ||
| 85 | struct SleepButtonSharedMemoryFormat { | ||
| 86 | CommonHeader header; | ||
| 87 | INSERT_PADDING_BYTES(0x1E0); | ||
| 88 | }; | ||
| 89 | static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200, | ||
| 90 | "SleepButtonSharedMemoryFormat is an invalid size"); | ||
| 91 | |||
| 92 | // This is nn::hid::detail::CaptureButtonSharedMemoryFormat | ||
| 93 | struct CaptureButtonSharedMemoryFormat { | ||
| 94 | CommonHeader header; | ||
| 95 | INSERT_PADDING_BYTES(0x1E0); | ||
| 96 | }; | ||
| 97 | static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200, | ||
| 98 | "CaptureButtonSharedMemoryFormat is an invalid size"); | ||
| 99 | |||
| 100 | // This is nn::hid::detail::InputDetectorSharedMemoryFormat | ||
| 101 | struct InputDetectorSharedMemoryFormat { | ||
| 102 | CommonHeader header; | ||
| 103 | INSERT_PADDING_BYTES(0x7E0); | ||
| 104 | }; | ||
| 105 | static_assert(sizeof(InputDetectorSharedMemoryFormat) == 0x800, | ||
| 106 | "InputDetectorSharedMemoryFormat is an invalid size"); | ||
| 107 | |||
| 108 | // This is nn::hid::detail::UniquePadSharedMemoryFormat | ||
| 109 | struct UniquePadSharedMemoryFormat { | ||
| 110 | CommonHeader header; | ||
| 111 | INSERT_PADDING_BYTES(0x3FE0); | ||
| 112 | }; | ||
| 113 | static_assert(sizeof(UniquePadSharedMemoryFormat) == 0x4000, | ||
| 114 | "UniquePadSharedMemoryFormat is an invalid size"); | ||
| 115 | |||
| 116 | // This is nn::hid::detail::NpadSixAxisSensorLifo | ||
| 117 | struct NpadSixAxisSensorLifo { | ||
| 118 | Lifo<Core::HID::SixAxisSensorState, HidEntryCount> lifo; | ||
| 119 | }; | ||
| 120 | |||
| 121 | // This is nn::hid::detail::NpadInternalState | ||
| 122 | struct NpadInternalState { | ||
| 123 | Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; | ||
| 124 | NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; | ||
| 125 | NpadFullKeyColorState fullkey_color{}; | ||
| 126 | NpadJoyColorState joycon_color{}; | ||
| 127 | Lifo<NPadGenericState, HidEntryCount> fullkey_lifo{}; | ||
| 128 | Lifo<NPadGenericState, HidEntryCount> handheld_lifo{}; | ||
| 129 | Lifo<NPadGenericState, HidEntryCount> joy_dual_lifo{}; | ||
| 130 | Lifo<NPadGenericState, HidEntryCount> joy_left_lifo{}; | ||
| 131 | Lifo<NPadGenericState, HidEntryCount> joy_right_lifo{}; | ||
| 132 | Lifo<NPadGenericState, HidEntryCount> palma_lifo{}; | ||
| 133 | Lifo<NPadGenericState, HidEntryCount> system_ext_lifo{}; | ||
| 134 | NpadSixAxisSensorLifo sixaxis_fullkey_lifo{}; | ||
| 135 | NpadSixAxisSensorLifo sixaxis_handheld_lifo{}; | ||
| 136 | NpadSixAxisSensorLifo sixaxis_dual_left_lifo{}; | ||
| 137 | NpadSixAxisSensorLifo sixaxis_dual_right_lifo{}; | ||
| 138 | NpadSixAxisSensorLifo sixaxis_left_lifo{}; | ||
| 139 | NpadSixAxisSensorLifo sixaxis_right_lifo{}; | ||
| 140 | DeviceType device_type{}; | ||
| 141 | INSERT_PADDING_BYTES(0x4); // Reserved | ||
| 142 | NPadSystemProperties system_properties{}; | ||
| 143 | NpadSystemButtonProperties button_properties{}; | ||
| 144 | Core::HID::NpadBatteryLevel battery_level_dual{}; | ||
| 145 | Core::HID::NpadBatteryLevel battery_level_left{}; | ||
| 146 | Core::HID::NpadBatteryLevel battery_level_right{}; | ||
| 147 | AppletFooterUiAttributes applet_footer_attributes{}; | ||
| 148 | AppletFooterUiType applet_footer_type{AppletFooterUiType::None}; | ||
| 149 | INSERT_PADDING_BYTES(0x5B); // Reserved | ||
| 150 | INSERT_PADDING_BYTES(0x20); // Unknown | ||
| 151 | Lifo<NpadGcTriggerState, HidEntryCount> gc_trigger_lifo{}; | ||
| 152 | NpadLarkType lark_type_l_and_main{}; | ||
| 153 | NpadLarkType lark_type_r{}; | ||
| 154 | NpadLuciaType lucia_type{}; | ||
| 155 | NpadLagerType lager_type{}; | ||
| 156 | Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; | ||
| 157 | Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; | ||
| 158 | Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; | ||
| 159 | Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; | ||
| 160 | Core::HID::SixAxisSensorProperties sixaxis_left_properties; | ||
| 161 | Core::HID::SixAxisSensorProperties sixaxis_right_properties; | ||
| 162 | }; | ||
| 163 | static_assert(sizeof(NpadInternalState) == 0x43F8, "NpadInternalState is an invalid size"); | ||
| 164 | |||
| 165 | // This is nn::hid::detail::NpadSharedMemoryEntry | ||
| 166 | struct NpadSharedMemoryEntry { | ||
| 167 | NpadInternalState internal_state; | ||
| 168 | INSERT_PADDING_BYTES(0xC08); | ||
| 169 | }; | ||
| 170 | static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is an invalid size"); | ||
| 171 | |||
| 172 | // This is nn::hid::detail::NpadSharedMemoryFormat | ||
| 173 | struct NpadSharedMemoryFormat { | ||
| 174 | std::array<NpadSharedMemoryEntry, NpadCount> npad_entry; | ||
| 175 | }; | ||
| 176 | static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000, | ||
| 177 | "NpadSharedMemoryFormat is an invalid size"); | ||
| 178 | |||
| 179 | // This is nn::hid::detail::GestureSharedMemoryFormat | ||
| 180 | struct GestureSharedMemoryFormat { | ||
| 181 | // This is nn::hid::detail::GestureLifo | ||
| 182 | Lifo<GestureState, HidEntryCount> gesture_lifo{}; | ||
| 183 | static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); | ||
| 184 | INSERT_PADDING_WORDS(0x3E); | ||
| 185 | }; | ||
| 186 | static_assert(sizeof(GestureSharedMemoryFormat) == 0x800, | ||
| 187 | "GestureSharedMemoryFormat is an invalid size"); | ||
| 188 | |||
| 189 | // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat | ||
| 190 | struct ConsoleSixAxisSensorSharedMemoryFormat { | ||
| 191 | u64 sampling_number{}; | ||
| 192 | bool is_seven_six_axis_sensor_at_rest{}; | ||
| 193 | INSERT_PADDING_BYTES(3); // padding | ||
| 194 | f32 verticalization_error{}; | ||
| 195 | Common::Vec3f gyro_bias{}; | ||
| 196 | INSERT_PADDING_BYTES(4); // padding | ||
| 197 | }; | ||
| 198 | static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20, | ||
| 199 | "ConsoleSixAxisSensorSharedMemoryFormat is an invalid size"); | ||
| 200 | |||
| 201 | // This is nn::hid::detail::SharedMemoryFormat | ||
| 202 | struct SharedMemoryFormat { | ||
| 203 | void Initialize() {} | ||
| 204 | |||
| 205 | DebugPadSharedMemoryFormat debug_pad; | ||
| 206 | TouchScreenSharedMemoryFormat touch_screen; | ||
| 207 | MouseSharedMemoryFormat mouse; | ||
| 208 | KeyboardSharedMemoryFormat keyboard; | ||
| 209 | DigitizerSharedMemoryFormat digitizer; | ||
| 210 | HomeButtonSharedMemoryFormat home_button; | ||
| 211 | SleepButtonSharedMemoryFormat sleep_button; | ||
| 212 | CaptureButtonSharedMemoryFormat capture_button; | ||
| 213 | InputDetectorSharedMemoryFormat input_detector; | ||
| 214 | UniquePadSharedMemoryFormat unique_pad; | ||
| 215 | NpadSharedMemoryFormat npad; | ||
| 216 | GestureSharedMemoryFormat gesture; | ||
| 217 | ConsoleSixAxisSensorSharedMemoryFormat console; | ||
| 218 | INSERT_PADDING_BYTES(0x19E0); | ||
| 219 | MouseSharedMemoryFormat debug_mouse; | ||
| 220 | INSERT_PADDING_BYTES(0x2000); | ||
| 221 | }; | ||
| 222 | static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset"); | ||
| 223 | static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset"); | ||
| 224 | static_assert(offsetof(SharedMemoryFormat, mouse) == 0x3400, "mouse has wrong offset"); | ||
| 225 | static_assert(offsetof(SharedMemoryFormat, keyboard) == 0x3800, "keyboard has wrong offset"); | ||
| 226 | static_assert(offsetof(SharedMemoryFormat, digitizer) == 0x3C00, "digitizer has wrong offset"); | ||
| 227 | static_assert(offsetof(SharedMemoryFormat, home_button) == 0x4C00, "home_button has wrong offset"); | ||
| 228 | static_assert(offsetof(SharedMemoryFormat, sleep_button) == 0x4E00, | ||
| 229 | "sleep_button has wrong offset"); | ||
| 230 | static_assert(offsetof(SharedMemoryFormat, capture_button) == 0x5000, | ||
| 231 | "capture_button has wrong offset"); | ||
| 232 | static_assert(offsetof(SharedMemoryFormat, input_detector) == 0x5200, | ||
| 233 | "input_detector has wrong offset"); | ||
| 234 | static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offset"); | ||
| 235 | static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset"); | ||
| 236 | static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset"); | ||
| 237 | static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset"); | ||
| 238 | static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size"); | ||
| 239 | |||
| 240 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp new file mode 100644 index 000000000..51581188e --- /dev/null +++ b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/hle/kernel/k_shared_memory.h" | ||
| 6 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 7 | #include "core/hle/service/hid/controllers/shared_memory_holder.h" | ||
| 8 | #include "core/hle/service/hid/errors.h" | ||
| 9 | |||
| 10 | namespace Service::HID { | ||
| 11 | SharedMemoryHolder::SharedMemoryHolder() {} | ||
| 12 | |||
| 13 | SharedMemoryHolder::~SharedMemoryHolder() { | ||
| 14 | Finalize(); | ||
| 15 | } | ||
| 16 | |||
| 17 | Result SharedMemoryHolder::Initialize(Core::System& system) { | ||
| 18 | shared_memory = Kernel::KSharedMemory::Create(system.Kernel()); | ||
| 19 | const Result result = shared_memory->Initialize( | ||
| 20 | system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None, | ||
| 21 | Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat)); | ||
| 22 | if (result.IsError()) { | ||
| 23 | return result; | ||
| 24 | } | ||
| 25 | Kernel::KSharedMemory::Register(system.Kernel(), shared_memory); | ||
| 26 | |||
| 27 | is_created = true; | ||
| 28 | is_mapped = true; | ||
| 29 | address = std::construct_at(reinterpret_cast<SharedMemoryFormat*>(shared_memory->GetPointer())); | ||
| 30 | return ResultSuccess; | ||
| 31 | } | ||
| 32 | |||
| 33 | void SharedMemoryHolder::Finalize() { | ||
| 34 | if (address != nullptr) { | ||
| 35 | shared_memory->Close(); | ||
| 36 | } | ||
| 37 | is_created = false; | ||
| 38 | is_mapped = false; | ||
| 39 | address = nullptr; | ||
| 40 | } | ||
| 41 | |||
| 42 | bool SharedMemoryHolder::IsMapped() { | ||
| 43 | return is_mapped; | ||
| 44 | } | ||
| 45 | |||
| 46 | SharedMemoryFormat* SharedMemoryHolder::GetAddress() { | ||
| 47 | return address; | ||
| 48 | } | ||
| 49 | |||
| 50 | Kernel::KSharedMemory* SharedMemoryHolder::GetHandle() { | ||
| 51 | return shared_memory; | ||
| 52 | } | ||
| 53 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.h b/src/core/hle/service/hid/controllers/shared_memory_holder.h new file mode 100644 index 000000000..943407c00 --- /dev/null +++ b/src/core/hle/service/hid/controllers/shared_memory_holder.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/result.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | class KSharedMemory; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Service::HID { | ||
| 17 | struct SharedMemoryFormat; | ||
| 18 | |||
| 19 | // This is nn::hid::detail::SharedMemoryHolder | ||
| 20 | class SharedMemoryHolder { | ||
| 21 | public: | ||
| 22 | SharedMemoryHolder(); | ||
| 23 | ~SharedMemoryHolder(); | ||
| 24 | |||
| 25 | Result Initialize(Core::System& system); | ||
| 26 | void Finalize(); | ||
| 27 | |||
| 28 | bool IsMapped(); | ||
| 29 | SharedMemoryFormat* GetAddress(); | ||
| 30 | Kernel::KSharedMemory* GetHandle(); | ||
| 31 | |||
| 32 | private: | ||
| 33 | bool is_owner{}; | ||
| 34 | bool is_created{}; | ||
| 35 | bool is_mapped{}; | ||
| 36 | INSERT_PADDING_BYTES(0x5); | ||
| 37 | Kernel::KSharedMemory* shared_memory; | ||
| 38 | INSERT_PADDING_BYTES(0x38); | ||
| 39 | SharedMemoryFormat* address = nullptr; | ||
| 40 | }; | ||
| 41 | // Correct size is 0x50 bytes | ||
| 42 | static_assert(sizeof(SharedMemoryHolder) == 0x50, "SharedMemoryHolder is an invalid size"); | ||
| 43 | |||
| 44 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp index 3d24a5c04..36b72f9ea 100644 --- a/src/core/hle/service/hid/controllers/six_axis.cpp +++ b/src/core/hle/service/hid/controllers/six_axis.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "core/hid/emulated_controller.h" | 6 | #include "core/hid/emulated_controller.h" |
| 7 | #include "core/hid/hid_core.h" | 7 | #include "core/hid/hid_core.h" |
| 8 | #include "core/hle/service/hid/controllers/npad.h" | 8 | #include "core/hle/service/hid/controllers/npad.h" |
| 9 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 9 | #include "core/hle/service/hid/controllers/six_axis.h" | 10 | #include "core/hle/service/hid/controllers/six_axis.h" |
| 10 | #include "core/hle/service/hid/errors.h" | 11 | #include "core/hle/service/hid/errors.h" |
| 11 | #include "core/hle/service/hid/hid_util.h" | 12 | #include "core/hle/service/hid/hid_util.h" |
| @@ -132,30 +133,30 @@ void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 132 | } | 133 | } |
| 133 | 134 | ||
| 134 | sixaxis_fullkey_state.sampling_number = | 135 | sixaxis_fullkey_state.sampling_number = |
| 135 | sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; | 136 | sixaxis_fullkey_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 136 | sixaxis_handheld_state.sampling_number = | 137 | sixaxis_handheld_state.sampling_number = |
| 137 | sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; | 138 | sixaxis_handheld_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 138 | sixaxis_dual_left_state.sampling_number = | 139 | sixaxis_dual_left_state.sampling_number = |
| 139 | sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | 140 | sixaxis_dual_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 140 | sixaxis_dual_right_state.sampling_number = | 141 | sixaxis_dual_right_state.sampling_number = |
| 141 | sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | 142 | sixaxis_dual_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 142 | sixaxis_left_lifo_state.sampling_number = | 143 | sixaxis_left_lifo_state.sampling_number = |
| 143 | sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | 144 | sixaxis_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 144 | sixaxis_right_lifo_state.sampling_number = | 145 | sixaxis_right_lifo_state.sampling_number = |
| 145 | sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | 146 | sixaxis_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 146 | 147 | ||
| 147 | if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { | 148 | if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { |
| 148 | // This buffer only is updated on handheld on HW | 149 | // This buffer only is updated on handheld on HW |
| 149 | sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); | 150 | sixaxis_handheld_lifo.lifo.WriteNextEntry(sixaxis_handheld_state); |
| 150 | } else { | 151 | } else { |
| 151 | // Handheld doesn't update this buffer on HW | 152 | // Handheld doesn't update this buffer on HW |
| 152 | sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); | 153 | sixaxis_fullkey_lifo.lifo.WriteNextEntry(sixaxis_fullkey_state); |
| 153 | } | 154 | } |
| 154 | 155 | ||
| 155 | sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); | 156 | sixaxis_dual_left_lifo.lifo.WriteNextEntry(sixaxis_dual_left_state); |
| 156 | sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); | 157 | sixaxis_dual_right_lifo.lifo.WriteNextEntry(sixaxis_dual_right_state); |
| 157 | sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); | 158 | sixaxis_left_lifo.lifo.WriteNextEntry(sixaxis_left_lifo_state); |
| 158 | sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); | 159 | sixaxis_right_lifo.lifo.WriteNextEntry(sixaxis_right_lifo_state); |
| 159 | } | 160 | } |
| 160 | } | 161 | } |
| 161 | 162 | ||
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp index 9e2f3ab21..e2a5f5d79 100644 --- a/src/core/hle/service/hid/controllers/stubbed.cpp +++ b/src/core/hle/service/hid/controllers/stubbed.cpp | |||
| @@ -1,18 +1,15 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <cstring> | ||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "core/core_timing.h" | 4 | #include "core/core_timing.h" |
| 7 | #include "core/hid/hid_core.h" | 5 | #include "core/hle/service/hid/controllers/shared_memory_format.h" |
| 8 | #include "core/hle/service/hid/controllers/stubbed.h" | 6 | #include "core/hle/service/hid/controllers/stubbed.h" |
| 9 | 7 | ||
| 10 | namespace Service::HID { | 8 | namespace Service::HID { |
| 11 | 9 | ||
| 12 | Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 10 | Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, |
| 13 | : ControllerBase{hid_core_} { | 11 | CommonHeader& ring_lifo_header) |
| 14 | raw_shared_memory = raw_shared_memory_; | 12 | : ControllerBase{hid_core_}, header{ring_lifo_header} {} |
| 15 | } | ||
| 16 | 13 | ||
| 17 | Controller_Stubbed::~Controller_Stubbed() = default; | 14 | Controller_Stubbed::~Controller_Stubbed() = default; |
| 18 | 15 | ||
| @@ -25,18 +22,10 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 25 | return; | 22 | return; |
| 26 | } | 23 | } |
| 27 | 24 | ||
| 28 | CommonHeader header{}; | ||
| 29 | header.timestamp = core_timing.GetGlobalTimeNs().count(); | 25 | header.timestamp = core_timing.GetGlobalTimeNs().count(); |
| 30 | header.total_entry_count = 17; | 26 | header.total_entry_count = 17; |
| 31 | header.entry_count = 0; | 27 | header.entry_count = 0; |
| 32 | header.last_entry_index = 0; | 28 | header.last_entry_index = 0; |
| 33 | |||
| 34 | std::memcpy(raw_shared_memory + common_offset, &header, sizeof(CommonHeader)); | ||
| 35 | } | ||
| 36 | |||
| 37 | void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) { | ||
| 38 | common_offset = off; | ||
| 39 | smart_update = true; | ||
| 40 | } | 29 | } |
| 41 | 30 | ||
| 42 | } // namespace Service::HID | 31 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h index 1483a968e..d2052fb17 100644 --- a/src/core/hle/service/hid/controllers/stubbed.h +++ b/src/core/hle/service/hid/controllers/stubbed.h | |||
| @@ -3,13 +3,14 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "core/hle/service/hid/controllers/controller_base.h" | 6 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 8 | 7 | ||
| 9 | namespace Service::HID { | 8 | namespace Service::HID { |
| 9 | struct CommonHeader; | ||
| 10 | |||
| 10 | class Controller_Stubbed final : public ControllerBase { | 11 | class Controller_Stubbed final : public ControllerBase { |
| 11 | public: | 12 | public: |
| 12 | explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 13 | explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, CommonHeader& ring_lifo_header); |
| 13 | ~Controller_Stubbed() override; | 14 | ~Controller_Stubbed() override; |
| 14 | 15 | ||
| 15 | // Called when the controller is initialized | 16 | // Called when the controller is initialized |
| @@ -21,19 +22,8 @@ public: | |||
| 21 | // When the controller is requesting an update for the shared memory | 22 | // When the controller is requesting an update for the shared memory |
| 22 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 23 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 23 | 24 | ||
| 24 | void SetCommonHeaderOffset(std::size_t off); | ||
| 25 | |||
| 26 | private: | 25 | private: |
| 27 | struct CommonHeader { | 26 | CommonHeader& header; |
| 28 | s64 timestamp{}; | ||
| 29 | s64 total_entry_count{}; | ||
| 30 | s64 last_entry_index{}; | ||
| 31 | s64 entry_count{}; | ||
| 32 | }; | ||
| 33 | static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); | ||
| 34 | |||
| 35 | u8* raw_shared_memory = nullptr; | ||
| 36 | bool smart_update{}; | 27 | bool smart_update{}; |
| 37 | std::size_t common_offset{}; | ||
| 38 | }; | 28 | }; |
| 39 | } // namespace Service::HID | 29 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index fcd973414..469750006 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp | |||
| @@ -2,26 +2,22 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <algorithm> | 4 | #include <algorithm> |
| 5 | #include <cstring> | ||
| 6 | #include "common/common_types.h" | 5 | #include "common/common_types.h" |
| 7 | #include "common/settings.h" | 6 | #include "common/settings.h" |
| 8 | #include "core/core.h" | ||
| 9 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 10 | #include "core/frontend/emu_window.h" | 8 | #include "core/frontend/emu_window.h" |
| 11 | #include "core/hid/emulated_console.h" | 9 | #include "core/hid/emulated_console.h" |
| 12 | #include "core/hid/hid_core.h" | 10 | #include "core/hid/hid_core.h" |
| 11 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 13 | #include "core/hle/service/hid/controllers/touchscreen.h" | 12 | #include "core/hle/service/hid/controllers/touchscreen.h" |
| 14 | 13 | ||
| 15 | namespace Service::HID { | 14 | namespace Service::HID { |
| 16 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; | ||
| 17 | 15 | ||
| 18 | TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | 16 | TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, |
| 19 | : ControllerBase{hid_core_}, touchscreen_width(Layout::ScreenUndocked::Width), | 17 | TouchScreenSharedMemoryFormat& touch_shared_memory) |
| 18 | : ControllerBase{hid_core_}, shared_memory{touch_shared_memory}, | ||
| 19 | touchscreen_width(Layout::ScreenUndocked::Width), | ||
| 20 | touchscreen_height(Layout::ScreenUndocked::Height) { | 20 | touchscreen_height(Layout::ScreenUndocked::Height) { |
| 21 | static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size, | ||
| 22 | "TouchSharedMemory is bigger than the shared memory"); | ||
| 23 | shared_memory = std::construct_at( | ||
| 24 | reinterpret_cast<TouchSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 25 | console = hid_core.GetEmulatedConsole(); | 21 | console = hid_core.GetEmulatedConsole(); |
| 26 | } | 22 | } |
| 27 | 23 | ||
| @@ -32,11 +28,11 @@ void TouchScreen::OnInit() {} | |||
| 32 | void TouchScreen::OnRelease() {} | 28 | void TouchScreen::OnRelease() {} |
| 33 | 29 | ||
| 34 | void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 30 | void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 35 | shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); | 31 | shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); |
| 36 | 32 | ||
| 37 | if (!IsControllerActivated()) { | 33 | if (!IsControllerActivated()) { |
| 38 | shared_memory->touch_screen_lifo.buffer_count = 0; | 34 | shared_memory.touch_screen_lifo.buffer_count = 0; |
| 39 | shared_memory->touch_screen_lifo.buffer_tail = 0; | 35 | shared_memory.touch_screen_lifo.buffer_tail = 0; |
| 40 | return; | 36 | return; |
| 41 | } | 37 | } |
| 42 | 38 | ||
| @@ -86,7 +82,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 86 | static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); | 82 | static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); |
| 87 | 83 | ||
| 88 | const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count()); | 84 | const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count()); |
| 89 | const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state; | 85 | const auto& last_entry = shared_memory.touch_screen_lifo.ReadCurrentEntry().state; |
| 90 | 86 | ||
| 91 | next_state.sampling_number = last_entry.sampling_number + 1; | 87 | next_state.sampling_number = last_entry.sampling_number + 1; |
| 92 | next_state.entry_count = static_cast<s32>(active_fingers_count); | 88 | next_state.entry_count = static_cast<s32>(active_fingers_count); |
| @@ -118,7 +114,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 118 | } | 114 | } |
| 119 | } | 115 | } |
| 120 | 116 | ||
| 121 | shared_memory->touch_screen_lifo.WriteNextEntry(next_state); | 117 | shared_memory.touch_screen_lifo.WriteNextEntry(next_state); |
| 122 | } | 118 | } |
| 123 | 119 | ||
| 124 | void TouchScreen::SetTouchscreenDimensions(u32 width, u32 height) { | 120 | void TouchScreen::SetTouchscreenDimensions(u32 width, u32 height) { |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 79f026a81..5b6305bfc 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h | |||
| @@ -3,20 +3,23 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/common_funcs.h" | 6 | #include <array> |
| 7 | #include "common/common_types.h" | 7 | |
| 8 | #include "core/hid/hid_types.h" | 8 | #include "core/hid/hid_types.h" |
| 9 | #include "core/hle/service/hid/controllers/controller_base.h" | 9 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 10 | #include "core/hle/service/hid/ring_lifo.h" | 10 | #include "core/hle/service/hid/controllers/types/touch_types.h" |
| 11 | 11 | ||
| 12 | namespace Core::HID { | 12 | namespace Core::HID { |
| 13 | class EmulatedConsole; | 13 | class EmulatedConsole; |
| 14 | } // namespace Core::HID | 14 | } // namespace Core::HID |
| 15 | 15 | ||
| 16 | namespace Service::HID { | 16 | namespace Service::HID { |
| 17 | struct TouchScreenSharedMemoryFormat; | ||
| 18 | |||
| 17 | class TouchScreen final : public ControllerBase { | 19 | class TouchScreen final : public ControllerBase { |
| 18 | public: | 20 | public: |
| 19 | explicit TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | 21 | explicit TouchScreen(Core::HID::HIDCore& hid_core_, |
| 22 | TouchScreenSharedMemoryFormat& touch_shared_memory); | ||
| 20 | ~TouchScreen() override; | 23 | ~TouchScreen() override; |
| 21 | 24 | ||
| 22 | // Called when the controller is initialized | 25 | // Called when the controller is initialized |
| @@ -31,27 +34,8 @@ public: | |||
| 31 | void SetTouchscreenDimensions(u32 width, u32 height); | 34 | void SetTouchscreenDimensions(u32 width, u32 height); |
| 32 | 35 | ||
| 33 | private: | 36 | private: |
| 34 | static constexpr std::size_t MAX_FINGERS = 16; | ||
| 35 | |||
| 36 | // This is nn::hid::TouchScreenState | ||
| 37 | struct TouchScreenState { | ||
| 38 | s64 sampling_number{}; | ||
| 39 | s32 entry_count{}; | ||
| 40 | INSERT_PADDING_BYTES(4); // Reserved | ||
| 41 | std::array<Core::HID::TouchState, MAX_FINGERS> states{}; | ||
| 42 | }; | ||
| 43 | static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); | ||
| 44 | |||
| 45 | struct TouchSharedMemory { | ||
| 46 | // This is nn::hid::detail::TouchScreenLifo | ||
| 47 | Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{}; | ||
| 48 | static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); | ||
| 49 | INSERT_PADDING_WORDS(0xF2); | ||
| 50 | }; | ||
| 51 | static_assert(sizeof(TouchSharedMemory) == 0x3000, "TouchSharedMemory is an invalid size"); | ||
| 52 | |||
| 53 | TouchScreenState next_state{}; | 37 | TouchScreenState next_state{}; |
| 54 | TouchSharedMemory* shared_memory = nullptr; | 38 | TouchScreenSharedMemoryFormat& shared_memory; |
| 55 | Core::HID::EmulatedConsole* console = nullptr; | 39 | Core::HID::EmulatedConsole* console = nullptr; |
| 56 | 40 | ||
| 57 | std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{}; | 41 | std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{}; |
diff --git a/src/core/hle/service/hid/controllers/types/debug_pad_types.h b/src/core/hle/service/hid/controllers/types/debug_pad_types.h new file mode 100644 index 000000000..a96171b62 --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/debug_pad_types.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/bit_field.h" | ||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "core/hid/hid_types.h" | ||
| 9 | |||
| 10 | namespace Service::HID { | ||
| 11 | |||
| 12 | // This is nn::hid::DebugPadAttribute | ||
| 13 | struct DebugPadAttribute { | ||
| 14 | union { | ||
| 15 | u32 raw{}; | ||
| 16 | BitField<0, 1, u32> connected; | ||
| 17 | }; | ||
| 18 | }; | ||
| 19 | static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size"); | ||
| 20 | |||
| 21 | // This is nn::hid::DebugPadState | ||
| 22 | struct DebugPadState { | ||
| 23 | s64 sampling_number{}; | ||
| 24 | DebugPadAttribute attribute{}; | ||
| 25 | Core::HID::DebugPadButton pad_state{}; | ||
| 26 | Core::HID::AnalogStickState r_stick{}; | ||
| 27 | Core::HID::AnalogStickState l_stick{}; | ||
| 28 | }; | ||
| 29 | static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); | ||
| 30 | |||
| 31 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/types/gesture_types.h b/src/core/hle/service/hid/controllers/types/gesture_types.h new file mode 100644 index 000000000..b4f034cd3 --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/gesture_types.h | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <array> | ||
| 7 | #include "common/bit_field.h" | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "common/point.h" | ||
| 10 | |||
| 11 | namespace Service::HID { | ||
| 12 | static constexpr size_t MAX_FINGERS = 16; | ||
| 13 | static constexpr size_t MAX_POINTS = 4; | ||
| 14 | |||
| 15 | // This is nn::hid::GestureType | ||
| 16 | enum class GestureType : u32 { | ||
| 17 | Idle, // Nothing touching the screen | ||
| 18 | Complete, // Set at the end of a touch event | ||
| 19 | Cancel, // Set when the number of fingers change | ||
| 20 | Touch, // A finger just touched the screen | ||
| 21 | Press, // Set if last type is touch and the finger hasn't moved | ||
| 22 | Tap, // Fast press then release | ||
| 23 | Pan, // All points moving together across the screen | ||
| 24 | Swipe, // Fast press movement and release of a single point | ||
| 25 | Pinch, // All points moving away/closer to the midpoint | ||
| 26 | Rotate, // All points rotating from the midpoint | ||
| 27 | }; | ||
| 28 | |||
| 29 | // This is nn::hid::GestureDirection | ||
| 30 | enum class GestureDirection : u32 { | ||
| 31 | None, | ||
| 32 | Left, | ||
| 33 | Up, | ||
| 34 | Right, | ||
| 35 | Down, | ||
| 36 | }; | ||
| 37 | |||
| 38 | // This is nn::hid::GestureAttribute | ||
| 39 | struct GestureAttribute { | ||
| 40 | union { | ||
| 41 | u32 raw{}; | ||
| 42 | |||
| 43 | BitField<4, 1, u32> is_new_touch; | ||
| 44 | BitField<8, 1, u32> is_double_tap; | ||
| 45 | }; | ||
| 46 | }; | ||
| 47 | static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); | ||
| 48 | |||
| 49 | // This is nn::hid::GestureState | ||
| 50 | struct GestureState { | ||
| 51 | s64 sampling_number{}; | ||
| 52 | s64 detection_count{}; | ||
| 53 | GestureType type{GestureType::Idle}; | ||
| 54 | GestureDirection direction{GestureDirection::None}; | ||
| 55 | Common::Point<s32> pos{}; | ||
| 56 | Common::Point<s32> delta{}; | ||
| 57 | f32 vel_x{}; | ||
| 58 | f32 vel_y{}; | ||
| 59 | GestureAttribute attributes{}; | ||
| 60 | f32 scale{}; | ||
| 61 | f32 rotation_angle{}; | ||
| 62 | s32 point_count{}; | ||
| 63 | std::array<Common::Point<s32>, 4> points{}; | ||
| 64 | }; | ||
| 65 | static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); | ||
| 66 | |||
| 67 | struct GestureProperties { | ||
| 68 | std::array<Common::Point<s32>, MAX_POINTS> points{}; | ||
| 69 | std::size_t active_points{}; | ||
| 70 | Common::Point<s32> mid_point{}; | ||
| 71 | s64 detection_count{}; | ||
| 72 | u64 delta_time{}; | ||
| 73 | f32 average_distance{}; | ||
| 74 | f32 angle{}; | ||
| 75 | }; | ||
| 76 | |||
| 77 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/types/keyboard_types.h b/src/core/hle/service/hid/controllers/types/keyboard_types.h new file mode 100644 index 000000000..f44a536b9 --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/keyboard_types.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "core/hid/hid_types.h" | ||
| 8 | |||
| 9 | namespace Service::HID { | ||
| 10 | |||
| 11 | // This is nn::hid::detail::KeyboardState | ||
| 12 | struct KeyboardState { | ||
| 13 | s64 sampling_number{}; | ||
| 14 | Core::HID::KeyboardModifier modifier{}; | ||
| 15 | Core::HID::KeyboardAttribute attribute{}; | ||
| 16 | Core::HID::KeyboardKey key{}; | ||
| 17 | }; | ||
| 18 | static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); | ||
| 19 | |||
| 20 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/types/mouse_types.h b/src/core/hle/service/hid/controllers/types/mouse_types.h new file mode 100644 index 000000000..8bd6e167c --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/mouse_types.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_types.h" | ||
| 7 | |||
| 8 | namespace Service::HID {} // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/types/npad_types.h b/src/core/hle/service/hid/controllers/types/npad_types.h new file mode 100644 index 000000000..a5ce2562b --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/npad_types.h | |||
| @@ -0,0 +1,254 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/bit_field.h" | ||
| 7 | #include "common/common_funcs.h" | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/hid/hid_types.h" | ||
| 10 | |||
| 11 | namespace Service::HID { | ||
| 12 | static constexpr std::size_t NpadCount = 10; | ||
| 13 | |||
| 14 | // This is nn::hid::NpadJoyHoldType | ||
| 15 | enum class NpadJoyHoldType : u64 { | ||
| 16 | Vertical = 0, | ||
| 17 | Horizontal = 1, | ||
| 18 | }; | ||
| 19 | |||
| 20 | // This is nn::hid::NpadJoyAssignmentMode | ||
| 21 | enum class NpadJoyAssignmentMode : u32 { | ||
| 22 | Dual = 0, | ||
| 23 | Single = 1, | ||
| 24 | }; | ||
| 25 | |||
| 26 | // This is nn::hid::NpadJoyDeviceType | ||
| 27 | enum class NpadJoyDeviceType : s64 { | ||
| 28 | Left = 0, | ||
| 29 | Right = 1, | ||
| 30 | }; | ||
| 31 | |||
| 32 | // This is nn::hid::NpadHandheldActivationMode | ||
| 33 | enum class NpadHandheldActivationMode : u64 { | ||
| 34 | Dual = 0, | ||
| 35 | Single = 1, | ||
| 36 | None = 2, | ||
| 37 | MaxActivationMode = 3, | ||
| 38 | }; | ||
| 39 | |||
| 40 | // This is nn::hid::system::AppletFooterUiAttributesSet | ||
| 41 | struct AppletFooterUiAttributes { | ||
| 42 | INSERT_PADDING_BYTES(0x4); | ||
| 43 | }; | ||
| 44 | |||
| 45 | // This is nn::hid::system::AppletFooterUiType | ||
| 46 | enum class AppletFooterUiType : u8 { | ||
| 47 | None = 0, | ||
| 48 | HandheldNone = 1, | ||
| 49 | HandheldJoyConLeftOnly = 2, | ||
| 50 | HandheldJoyConRightOnly = 3, | ||
| 51 | HandheldJoyConLeftJoyConRight = 4, | ||
| 52 | JoyDual = 5, | ||
| 53 | JoyDualLeftOnly = 6, | ||
| 54 | JoyDualRightOnly = 7, | ||
| 55 | JoyLeftHorizontal = 8, | ||
| 56 | JoyLeftVertical = 9, | ||
| 57 | JoyRightHorizontal = 10, | ||
| 58 | JoyRightVertical = 11, | ||
| 59 | SwitchProController = 12, | ||
| 60 | CompatibleProController = 13, | ||
| 61 | CompatibleJoyCon = 14, | ||
| 62 | LarkHvc1 = 15, | ||
| 63 | LarkHvc2 = 16, | ||
| 64 | LarkNesLeft = 17, | ||
| 65 | LarkNesRight = 18, | ||
| 66 | Lucia = 19, | ||
| 67 | Verification = 20, | ||
| 68 | Lagon = 21, | ||
| 69 | }; | ||
| 70 | |||
| 71 | using AppletFooterUiVariant = u8; | ||
| 72 | |||
| 73 | // This is "nn::hid::system::AppletDetailedUiType". | ||
| 74 | struct AppletDetailedUiType { | ||
| 75 | AppletFooterUiVariant ui_variant; | ||
| 76 | INSERT_PADDING_BYTES(0x2); | ||
| 77 | AppletFooterUiType footer; | ||
| 78 | }; | ||
| 79 | static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); | ||
| 80 | // This is nn::hid::NpadCommunicationMode | ||
| 81 | enum class NpadCommunicationMode : u64 { | ||
| 82 | Mode_5ms = 0, | ||
| 83 | Mode_10ms = 1, | ||
| 84 | Mode_15ms = 2, | ||
| 85 | Default = 3, | ||
| 86 | }; | ||
| 87 | |||
| 88 | enum class NpadRevision : u32 { | ||
| 89 | Revision0 = 0, | ||
| 90 | Revision1 = 1, | ||
| 91 | Revision2 = 2, | ||
| 92 | Revision3 = 3, | ||
| 93 | }; | ||
| 94 | |||
| 95 | // This is nn::hid::detail::ColorAttribute | ||
| 96 | enum class ColorAttribute : u32 { | ||
| 97 | Ok = 0, | ||
| 98 | ReadError = 1, | ||
| 99 | NoController = 2, | ||
| 100 | }; | ||
| 101 | static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size"); | ||
| 102 | |||
| 103 | // This is nn::hid::detail::NpadFullKeyColorState | ||
| 104 | struct NpadFullKeyColorState { | ||
| 105 | ColorAttribute attribute{ColorAttribute::NoController}; | ||
| 106 | Core::HID::NpadControllerColor fullkey{}; | ||
| 107 | }; | ||
| 108 | static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); | ||
| 109 | |||
| 110 | // This is nn::hid::detail::NpadJoyColorState | ||
| 111 | struct NpadJoyColorState { | ||
| 112 | ColorAttribute attribute{ColorAttribute::NoController}; | ||
| 113 | Core::HID::NpadControllerColor left{}; | ||
| 114 | Core::HID::NpadControllerColor right{}; | ||
| 115 | }; | ||
| 116 | static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); | ||
| 117 | |||
| 118 | // This is nn::hid::NpadAttribute | ||
| 119 | struct NpadAttribute { | ||
| 120 | union { | ||
| 121 | u32 raw{}; | ||
| 122 | BitField<0, 1, u32> is_connected; | ||
| 123 | BitField<1, 1, u32> is_wired; | ||
| 124 | BitField<2, 1, u32> is_left_connected; | ||
| 125 | BitField<3, 1, u32> is_left_wired; | ||
| 126 | BitField<4, 1, u32> is_right_connected; | ||
| 127 | BitField<5, 1, u32> is_right_wired; | ||
| 128 | }; | ||
| 129 | }; | ||
| 130 | static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size"); | ||
| 131 | |||
| 132 | // This is nn::hid::NpadFullKeyState | ||
| 133 | // This is nn::hid::NpadHandheldState | ||
| 134 | // This is nn::hid::NpadJoyDualState | ||
| 135 | // This is nn::hid::NpadJoyLeftState | ||
| 136 | // This is nn::hid::NpadJoyRightState | ||
| 137 | // This is nn::hid::NpadPalmaState | ||
| 138 | // This is nn::hid::NpadSystemExtState | ||
| 139 | struct NPadGenericState { | ||
| 140 | s64_le sampling_number{}; | ||
| 141 | Core::HID::NpadButtonState npad_buttons{}; | ||
| 142 | Core::HID::AnalogStickState l_stick{}; | ||
| 143 | Core::HID::AnalogStickState r_stick{}; | ||
| 144 | NpadAttribute connection_status{}; | ||
| 145 | INSERT_PADDING_BYTES(4); // Reserved | ||
| 146 | }; | ||
| 147 | static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); | ||
| 148 | |||
| 149 | // This is nn::hid::server::NpadGcTriggerState | ||
| 150 | struct NpadGcTriggerState { | ||
| 151 | s64 sampling_number{}; | ||
| 152 | s32 l_analog{}; | ||
| 153 | s32 r_analog{}; | ||
| 154 | }; | ||
| 155 | static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); | ||
| 156 | |||
| 157 | // This is nn::hid::NpadSystemProperties | ||
| 158 | struct NPadSystemProperties { | ||
| 159 | union { | ||
| 160 | s64 raw{}; | ||
| 161 | BitField<0, 1, s64> is_charging_joy_dual; | ||
| 162 | BitField<1, 1, s64> is_charging_joy_left; | ||
| 163 | BitField<2, 1, s64> is_charging_joy_right; | ||
| 164 | BitField<3, 1, s64> is_powered_joy_dual; | ||
| 165 | BitField<4, 1, s64> is_powered_joy_left; | ||
| 166 | BitField<5, 1, s64> is_powered_joy_right; | ||
| 167 | BitField<9, 1, s64> is_system_unsupported_button; | ||
| 168 | BitField<10, 1, s64> is_system_ext_unsupported_button; | ||
| 169 | BitField<11, 1, s64> is_vertical; | ||
| 170 | BitField<12, 1, s64> is_horizontal; | ||
| 171 | BitField<13, 1, s64> use_plus; | ||
| 172 | BitField<14, 1, s64> use_minus; | ||
| 173 | BitField<15, 1, s64> use_directional_buttons; | ||
| 174 | }; | ||
| 175 | }; | ||
| 176 | static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); | ||
| 177 | |||
| 178 | // This is nn::hid::NpadSystemButtonProperties | ||
| 179 | struct NpadSystemButtonProperties { | ||
| 180 | union { | ||
| 181 | s32 raw{}; | ||
| 182 | BitField<0, 1, s32> is_home_button_protection_enabled; | ||
| 183 | }; | ||
| 184 | }; | ||
| 185 | static_assert(sizeof(NpadSystemButtonProperties) == 0x4, "NPadButtonProperties is an invalid size"); | ||
| 186 | |||
| 187 | // This is nn::hid::system::DeviceType | ||
| 188 | struct DeviceType { | ||
| 189 | union { | ||
| 190 | u32 raw{}; | ||
| 191 | BitField<0, 1, s32> fullkey; | ||
| 192 | BitField<1, 1, s32> debug_pad; | ||
| 193 | BitField<2, 1, s32> handheld_left; | ||
| 194 | BitField<3, 1, s32> handheld_right; | ||
| 195 | BitField<4, 1, s32> joycon_left; | ||
| 196 | BitField<5, 1, s32> joycon_right; | ||
| 197 | BitField<6, 1, s32> palma; | ||
| 198 | BitField<7, 1, s32> lark_hvc_left; | ||
| 199 | BitField<8, 1, s32> lark_hvc_right; | ||
| 200 | BitField<9, 1, s32> lark_nes_left; | ||
| 201 | BitField<10, 1, s32> lark_nes_right; | ||
| 202 | BitField<11, 1, s32> handheld_lark_hvc_left; | ||
| 203 | BitField<12, 1, s32> handheld_lark_hvc_right; | ||
| 204 | BitField<13, 1, s32> handheld_lark_nes_left; | ||
| 205 | BitField<14, 1, s32> handheld_lark_nes_right; | ||
| 206 | BitField<15, 1, s32> lucia; | ||
| 207 | BitField<16, 1, s32> lagon; | ||
| 208 | BitField<17, 1, s32> lager; | ||
| 209 | BitField<31, 1, s32> system; | ||
| 210 | }; | ||
| 211 | }; | ||
| 212 | |||
| 213 | // This is nn::hid::detail::NfcXcdDeviceHandleStateImpl | ||
| 214 | struct NfcXcdDeviceHandleStateImpl { | ||
| 215 | u64 handle{}; | ||
| 216 | bool is_available{}; | ||
| 217 | bool is_activated{}; | ||
| 218 | INSERT_PADDING_BYTES(0x6); // Reserved | ||
| 219 | u64 sampling_number{}; | ||
| 220 | }; | ||
| 221 | static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, | ||
| 222 | "NfcXcdDeviceHandleStateImpl is an invalid size"); | ||
| 223 | |||
| 224 | // This is nn::hid::NpadLarkType | ||
| 225 | enum class NpadLarkType : u32 { | ||
| 226 | Invalid, | ||
| 227 | H1, | ||
| 228 | H2, | ||
| 229 | NL, | ||
| 230 | NR, | ||
| 231 | }; | ||
| 232 | |||
| 233 | // This is nn::hid::NpadLuciaType | ||
| 234 | enum class NpadLuciaType : u32 { | ||
| 235 | Invalid, | ||
| 236 | J, | ||
| 237 | E, | ||
| 238 | U, | ||
| 239 | }; | ||
| 240 | |||
| 241 | // This is nn::hid::NpadLagonType | ||
| 242 | enum class NpadLagonType : u32 { | ||
| 243 | Invalid, | ||
| 244 | }; | ||
| 245 | |||
| 246 | // This is nn::hid::NpadLagerType | ||
| 247 | enum class NpadLagerType : u32 { | ||
| 248 | Invalid, | ||
| 249 | J, | ||
| 250 | E, | ||
| 251 | U, | ||
| 252 | }; | ||
| 253 | |||
| 254 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/types/touch_types.h b/src/core/hle/service/hid/controllers/types/touch_types.h new file mode 100644 index 000000000..efeaa796d --- /dev/null +++ b/src/core/hle/service/hid/controllers/types/touch_types.h | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <array> | ||
| 7 | |||
| 8 | #include <array> | ||
| 9 | #include "common/bit_field.h" | ||
| 10 | #include "common/common_funcs.h" | ||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "common/point.h" | ||
| 13 | #include "core/hid/hid_types.h" | ||
| 14 | |||
| 15 | namespace Service::HID { | ||
| 16 | static constexpr std::size_t MAX_FINGERS = 16; | ||
| 17 | static constexpr size_t MAX_POINTS = 4; | ||
| 18 | |||
| 19 | // This is nn::hid::GestureType | ||
| 20 | enum class GestureType : u32 { | ||
| 21 | Idle, // Nothing touching the screen | ||
| 22 | Complete, // Set at the end of a touch event | ||
| 23 | Cancel, // Set when the number of fingers change | ||
| 24 | Touch, // A finger just touched the screen | ||
| 25 | Press, // Set if last type is touch and the finger hasn't moved | ||
| 26 | Tap, // Fast press then release | ||
| 27 | Pan, // All points moving together across the screen | ||
| 28 | Swipe, // Fast press movement and release of a single point | ||
| 29 | Pinch, // All points moving away/closer to the midpoint | ||
| 30 | Rotate, // All points rotating from the midpoint | ||
| 31 | }; | ||
| 32 | |||
| 33 | // This is nn::hid::GestureDirection | ||
| 34 | enum class GestureDirection : u32 { | ||
| 35 | None, | ||
| 36 | Left, | ||
| 37 | Up, | ||
| 38 | Right, | ||
| 39 | Down, | ||
| 40 | }; | ||
| 41 | |||
| 42 | // This is nn::hid::GestureAttribute | ||
| 43 | struct GestureAttribute { | ||
| 44 | union { | ||
| 45 | u32 raw{}; | ||
| 46 | |||
| 47 | BitField<4, 1, u32> is_new_touch; | ||
| 48 | BitField<8, 1, u32> is_double_tap; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); | ||
| 52 | |||
| 53 | // This is nn::hid::GestureState | ||
| 54 | struct GestureState { | ||
| 55 | s64 sampling_number{}; | ||
| 56 | s64 detection_count{}; | ||
| 57 | GestureType type{GestureType::Idle}; | ||
| 58 | GestureDirection direction{GestureDirection::None}; | ||
| 59 | Common::Point<s32> pos{}; | ||
| 60 | Common::Point<s32> delta{}; | ||
| 61 | f32 vel_x{}; | ||
| 62 | f32 vel_y{}; | ||
| 63 | GestureAttribute attributes{}; | ||
| 64 | f32 scale{}; | ||
| 65 | f32 rotation_angle{}; | ||
| 66 | s32 point_count{}; | ||
| 67 | std::array<Common::Point<s32>, 4> points{}; | ||
| 68 | }; | ||
| 69 | static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); | ||
| 70 | |||
| 71 | struct GestureProperties { | ||
| 72 | std::array<Common::Point<s32>, MAX_POINTS> points{}; | ||
| 73 | std::size_t active_points{}; | ||
| 74 | Common::Point<s32> mid_point{}; | ||
| 75 | s64 detection_count{}; | ||
| 76 | u64 delta_time{}; | ||
| 77 | f32 average_distance{}; | ||
| 78 | f32 angle{}; | ||
| 79 | }; | ||
| 80 | |||
| 81 | // This is nn::hid::TouchScreenState | ||
| 82 | struct TouchScreenState { | ||
| 83 | s64 sampling_number{}; | ||
| 84 | s32 entry_count{}; | ||
| 85 | INSERT_PADDING_BYTES(4); // Reserved | ||
| 86 | std::array<Core::HID::TouchState, MAX_FINGERS> states{}; | ||
| 87 | }; | ||
| 88 | static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); | ||
| 89 | |||
| 90 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp deleted file mode 100644 index 0aaed1fa7..000000000 --- a/src/core/hle/service/hid/controllers/xpad.cpp +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <cstring> | ||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "core/core_timing.h" | ||
| 7 | #include "core/hid/hid_core.h" | ||
| 8 | #include "core/hle/service/hid/controllers/xpad.h" | ||
| 9 | |||
| 10 | namespace Service::HID { | ||
| 11 | constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; | ||
| 12 | |||
| 13 | XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { | ||
| 14 | static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size, | ||
| 15 | "XpadSharedMemory is bigger than the shared memory"); | ||
| 16 | shared_memory = std::construct_at( | ||
| 17 | reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||
| 18 | } | ||
| 19 | XPad::~XPad() = default; | ||
| 20 | |||
| 21 | void XPad::OnInit() {} | ||
| 22 | |||
| 23 | void XPad::OnRelease() {} | ||
| 24 | |||
| 25 | void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||
| 26 | if (!IsControllerActivated()) { | ||
| 27 | shared_memory->basic_xpad_lifo.buffer_count = 0; | ||
| 28 | shared_memory->basic_xpad_lifo.buffer_tail = 0; | ||
| 29 | return; | ||
| 30 | } | ||
| 31 | |||
| 32 | const auto& last_entry = shared_memory->basic_xpad_lifo.ReadCurrentEntry().state; | ||
| 33 | next_state.sampling_number = last_entry.sampling_number + 1; | ||
| 34 | // TODO(ogniK): Update xpad states | ||
| 35 | |||
| 36 | shared_memory->basic_xpad_lifo.WriteNextEntry(next_state); | ||
| 37 | } | ||
| 38 | |||
| 39 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h deleted file mode 100644 index 9e63a317a..000000000 --- a/src/core/hle/service/hid/controllers/xpad.h +++ /dev/null | |||
| @@ -1,112 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/bit_field.h" | ||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "core/hid/hid_types.h" | ||
| 9 | #include "core/hle/service/hid/controllers/controller_base.h" | ||
| 10 | #include "core/hle/service/hid/ring_lifo.h" | ||
| 11 | |||
| 12 | namespace Service::HID { | ||
| 13 | class XPad final : public ControllerBase { | ||
| 14 | public: | ||
| 15 | explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||
| 16 | ~XPad() override; | ||
| 17 | |||
| 18 | // Called when the controller is initialized | ||
| 19 | void OnInit() override; | ||
| 20 | |||
| 21 | // When the controller is released | ||
| 22 | void OnRelease() override; | ||
| 23 | |||
| 24 | // When the controller is requesting an update for the shared memory | ||
| 25 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||
| 26 | |||
| 27 | private: | ||
| 28 | // This is nn::hid::BasicXpadAttributeSet | ||
| 29 | struct BasicXpadAttributeSet { | ||
| 30 | union { | ||
| 31 | u32 raw{}; | ||
| 32 | BitField<0, 1, u32> is_connected; | ||
| 33 | BitField<1, 1, u32> is_wired; | ||
| 34 | BitField<2, 1, u32> is_left_connected; | ||
| 35 | BitField<3, 1, u32> is_left_wired; | ||
| 36 | BitField<4, 1, u32> is_right_connected; | ||
| 37 | BitField<5, 1, u32> is_right_wired; | ||
| 38 | }; | ||
| 39 | }; | ||
| 40 | static_assert(sizeof(BasicXpadAttributeSet) == 4, "BasicXpadAttributeSet is an invalid size"); | ||
| 41 | |||
| 42 | // This is nn::hid::BasicXpadButtonSet | ||
| 43 | struct BasicXpadButtonSet { | ||
| 44 | union { | ||
| 45 | u32 raw{}; | ||
| 46 | // Button states | ||
| 47 | BitField<0, 1, u32> a; | ||
| 48 | BitField<1, 1, u32> b; | ||
| 49 | BitField<2, 1, u32> x; | ||
| 50 | BitField<3, 1, u32> y; | ||
| 51 | BitField<4, 1, u32> l_stick; | ||
| 52 | BitField<5, 1, u32> r_stick; | ||
| 53 | BitField<6, 1, u32> l; | ||
| 54 | BitField<7, 1, u32> r; | ||
| 55 | BitField<8, 1, u32> zl; | ||
| 56 | BitField<9, 1, u32> zr; | ||
| 57 | BitField<10, 1, u32> plus; | ||
| 58 | BitField<11, 1, u32> minus; | ||
| 59 | |||
| 60 | // D-Pad | ||
| 61 | BitField<12, 1, u32> d_left; | ||
| 62 | BitField<13, 1, u32> d_up; | ||
| 63 | BitField<14, 1, u32> d_right; | ||
| 64 | BitField<15, 1, u32> d_down; | ||
| 65 | |||
| 66 | // Left JoyStick | ||
| 67 | BitField<16, 1, u32> l_stick_left; | ||
| 68 | BitField<17, 1, u32> l_stick_up; | ||
| 69 | BitField<18, 1, u32> l_stick_right; | ||
| 70 | BitField<19, 1, u32> l_stick_down; | ||
| 71 | |||
| 72 | // Right JoyStick | ||
| 73 | BitField<20, 1, u32> r_stick_left; | ||
| 74 | BitField<21, 1, u32> r_stick_up; | ||
| 75 | BitField<22, 1, u32> r_stick_right; | ||
| 76 | BitField<23, 1, u32> r_stick_down; | ||
| 77 | |||
| 78 | // Not always active? | ||
| 79 | BitField<24, 1, u32> left_sl; | ||
| 80 | BitField<25, 1, u32> left_sr; | ||
| 81 | |||
| 82 | BitField<26, 1, u32> right_sl; | ||
| 83 | BitField<27, 1, u32> right_sr; | ||
| 84 | |||
| 85 | BitField<28, 1, u32> palma; | ||
| 86 | BitField<30, 1, u32> handheld_left_b; | ||
| 87 | }; | ||
| 88 | }; | ||
| 89 | static_assert(sizeof(BasicXpadButtonSet) == 4, "BasicXpadButtonSet is an invalid size"); | ||
| 90 | |||
| 91 | // This is nn::hid::detail::BasicXpadState | ||
| 92 | struct BasicXpadState { | ||
| 93 | s64 sampling_number{}; | ||
| 94 | BasicXpadAttributeSet attributes{}; | ||
| 95 | BasicXpadButtonSet pad_states{}; | ||
| 96 | Core::HID::AnalogStickState l_stick{}; | ||
| 97 | Core::HID::AnalogStickState r_stick{}; | ||
| 98 | }; | ||
| 99 | static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size"); | ||
| 100 | |||
| 101 | struct XpadSharedMemory { | ||
| 102 | // This is nn::hid::detail::BasicXpadLifo | ||
| 103 | Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{}; | ||
| 104 | static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size"); | ||
| 105 | INSERT_PADDING_WORDS(0x4E); | ||
| 106 | }; | ||
| 107 | static_assert(sizeof(XpadSharedMemory) == 0x400, "XpadSharedMemory is an invalid size"); | ||
| 108 | |||
| 109 | BasicXpadState next_state{}; | ||
| 110 | XpadSharedMemory* shared_memory = nullptr; | ||
| 111 | }; | ||
| 112 | } // namespace Service::HID | ||
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index f00cb831f..6dc976fe1 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h | |||
| @@ -20,6 +20,9 @@ constexpr Result InvalidNpadId{ErrorModule::HID, 709}; | |||
| 20 | constexpr Result NpadNotConnected{ErrorModule::HID, 710}; | 20 | constexpr Result NpadNotConnected{ErrorModule::HID, 710}; |
| 21 | constexpr Result InvalidArraySize{ErrorModule::HID, 715}; | 21 | constexpr Result InvalidArraySize{ErrorModule::HID, 715}; |
| 22 | 22 | ||
| 23 | constexpr Result ResultAppletResourceOverflow{ErrorModule::HID, 1041}; | ||
| 24 | constexpr Result ResultAppletResourceNotInitialized{ErrorModule::HID, 1042}; | ||
| 25 | constexpr Result ResultSharedMemoryNotInitialized{ErrorModule::HID, 1043}; | ||
| 23 | constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044}; | 26 | constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044}; |
| 24 | constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046}; | 27 | constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046}; |
| 25 | constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047}; | 28 | constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047}; |
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index e0f4051aa..de24b0401 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include "core/hle/service/hid/controllers/seven_six_axis.h" | 28 | #include "core/hle/service/hid/controllers/seven_six_axis.h" |
| 29 | #include "core/hle/service/hid/controllers/six_axis.h" | 29 | #include "core/hle/service/hid/controllers/six_axis.h" |
| 30 | #include "core/hle/service/hid/controllers/touchscreen.h" | 30 | #include "core/hle/service/hid/controllers/touchscreen.h" |
| 31 | #include "core/hle/service/hid/controllers/types/npad_types.h" | ||
| 31 | 32 | ||
| 32 | namespace Service::HID { | 33 | namespace Service::HID { |
| 33 | 34 | ||
| @@ -222,16 +223,14 @@ void IHidServer::CreateAppletResource(HLERequestContext& ctx) { | |||
| 222 | IPC::RequestParser rp{ctx}; | 223 | IPC::RequestParser rp{ctx}; |
| 223 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 224 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| 224 | 225 | ||
| 225 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 226 | |||
| 227 | Result result = GetResourceManager()->CreateAppletResource(applet_resource_user_id); | 226 | Result result = GetResourceManager()->CreateAppletResource(applet_resource_user_id); |
| 228 | if (result.IsSuccess()) { | 227 | |
| 229 | result = GetResourceManager()->GetNpad()->Activate(applet_resource_user_id); | 228 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, result=0x{:X}", |
| 230 | } | 229 | applet_resource_user_id, result.raw); |
| 231 | 230 | ||
| 232 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 231 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 233 | rb.Push(result); | 232 | rb.Push(result); |
| 234 | rb.PushIpcInterface<IAppletResource>(system, resource_manager); | 233 | rb.PushIpcInterface<IAppletResource>(system, resource_manager, applet_resource_user_id); |
| 235 | } | 234 | } |
| 236 | 235 | ||
| 237 | void IHidServer::ActivateDebugPad(HLERequestContext& ctx) { | 236 | void IHidServer::ActivateDebugPad(HLERequestContext& ctx) { |
| @@ -1101,7 +1100,7 @@ void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) { | |||
| 1101 | void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { | 1100 | void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { |
| 1102 | IPC::RequestParser rp{ctx}; | 1101 | IPC::RequestParser rp{ctx}; |
| 1103 | struct Parameters { | 1102 | struct Parameters { |
| 1104 | NPad::NpadRevision revision; | 1103 | NpadRevision revision; |
| 1105 | INSERT_PADDING_WORDS_NOINIT(1); | 1104 | INSERT_PADDING_WORDS_NOINIT(1); |
| 1106 | u64 applet_resource_user_id; | 1105 | u64 applet_resource_user_id; |
| 1107 | }; | 1106 | }; |
| @@ -1124,7 +1123,7 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { | |||
| 1124 | void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) { | 1123 | void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) { |
| 1125 | IPC::RequestParser rp{ctx}; | 1124 | IPC::RequestParser rp{ctx}; |
| 1126 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 1125 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| 1127 | const auto hold_type{rp.PopEnum<NPad::NpadJoyHoldType>()}; | 1126 | const auto hold_type{rp.PopEnum<NpadJoyHoldType>()}; |
| 1128 | 1127 | ||
| 1129 | GetResourceManager()->GetNpad()->SetHoldType(hold_type); | 1128 | GetResourceManager()->GetNpad()->SetHoldType(hold_type); |
| 1130 | 1129 | ||
| @@ -1159,8 +1158,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) | |||
| 1159 | 1158 | ||
| 1160 | Core::HID::NpadIdType new_npad_id{}; | 1159 | Core::HID::NpadIdType new_npad_id{}; |
| 1161 | auto controller = GetResourceManager()->GetNpad(); | 1160 | auto controller = GetResourceManager()->GetNpad(); |
| 1162 | controller->SetNpadMode(new_npad_id, parameters.npad_id, NPad::NpadJoyDeviceType::Left, | 1161 | controller->SetNpadMode(new_npad_id, parameters.npad_id, NpadJoyDeviceType::Left, |
| 1163 | NPad::NpadJoyAssignmentMode::Single); | 1162 | NpadJoyAssignmentMode::Single); |
| 1164 | 1163 | ||
| 1165 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | 1164 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, |
| 1166 | parameters.applet_resource_user_id); | 1165 | parameters.applet_resource_user_id); |
| @@ -1175,7 +1174,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { | |||
| 1175 | Core::HID::NpadIdType npad_id; | 1174 | Core::HID::NpadIdType npad_id; |
| 1176 | INSERT_PADDING_WORDS_NOINIT(1); | 1175 | INSERT_PADDING_WORDS_NOINIT(1); |
| 1177 | u64 applet_resource_user_id; | 1176 | u64 applet_resource_user_id; |
| 1178 | NPad::NpadJoyDeviceType npad_joy_device_type; | 1177 | NpadJoyDeviceType npad_joy_device_type; |
| 1179 | }; | 1178 | }; |
| 1180 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | 1179 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); |
| 1181 | 1180 | ||
| @@ -1184,7 +1183,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { | |||
| 1184 | Core::HID::NpadIdType new_npad_id{}; | 1183 | Core::HID::NpadIdType new_npad_id{}; |
| 1185 | auto controller = GetResourceManager()->GetNpad(); | 1184 | auto controller = GetResourceManager()->GetNpad(); |
| 1186 | controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | 1185 | controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, |
| 1187 | NPad::NpadJoyAssignmentMode::Single); | 1186 | NpadJoyAssignmentMode::Single); |
| 1188 | 1187 | ||
| 1189 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | 1188 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", |
| 1190 | parameters.npad_id, parameters.applet_resource_user_id, | 1189 | parameters.npad_id, parameters.applet_resource_user_id, |
| @@ -1207,7 +1206,7 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) { | |||
| 1207 | 1206 | ||
| 1208 | Core::HID::NpadIdType new_npad_id{}; | 1207 | Core::HID::NpadIdType new_npad_id{}; |
| 1209 | auto controller = GetResourceManager()->GetNpad(); | 1208 | auto controller = GetResourceManager()->GetNpad(); |
| 1210 | controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NPad::NpadJoyAssignmentMode::Dual); | 1209 | controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NpadJoyAssignmentMode::Dual); |
| 1211 | 1210 | ||
| 1212 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | 1211 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, |
| 1213 | parameters.applet_resource_user_id); // Spams a lot when controller applet is open | 1212 | parameters.applet_resource_user_id); // Spams a lot when controller applet is open |
| @@ -1259,7 +1258,7 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) { | |||
| 1259 | void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) { | 1258 | void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) { |
| 1260 | IPC::RequestParser rp{ctx}; | 1259 | IPC::RequestParser rp{ctx}; |
| 1261 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 1260 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| 1262 | const auto activation_mode{rp.PopEnum<NPad::NpadHandheldActivationMode>()}; | 1261 | const auto activation_mode{rp.PopEnum<NpadHandheldActivationMode>()}; |
| 1263 | 1262 | ||
| 1264 | GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode); | 1263 | GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode); |
| 1265 | 1264 | ||
| @@ -1351,7 +1350,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext | |||
| 1351 | Core::HID::NpadIdType npad_id; | 1350 | Core::HID::NpadIdType npad_id; |
| 1352 | INSERT_PADDING_WORDS_NOINIT(1); | 1351 | INSERT_PADDING_WORDS_NOINIT(1); |
| 1353 | u64 applet_resource_user_id; | 1352 | u64 applet_resource_user_id; |
| 1354 | NPad::NpadJoyDeviceType npad_joy_device_type; | 1353 | NpadJoyDeviceType npad_joy_device_type; |
| 1355 | }; | 1354 | }; |
| 1356 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | 1355 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); |
| 1357 | 1356 | ||
| @@ -1361,7 +1360,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext | |||
| 1361 | auto controller = GetResourceManager()->GetNpad(); | 1360 | auto controller = GetResourceManager()->GetNpad(); |
| 1362 | const auto is_reassigned = | 1361 | const auto is_reassigned = |
| 1363 | controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | 1362 | controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, |
| 1364 | NPad::NpadJoyAssignmentMode::Single); | 1363 | NpadJoyAssignmentMode::Single); |
| 1365 | 1364 | ||
| 1366 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | 1365 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", |
| 1367 | parameters.npad_id, parameters.applet_resource_user_id, | 1366 | parameters.npad_id, parameters.applet_resource_user_id, |
| @@ -2317,7 +2316,7 @@ void IHidServer::SetDisallowedPalmaConnection(HLERequestContext& ctx) { | |||
| 2317 | void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) { | 2316 | void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) { |
| 2318 | IPC::RequestParser rp{ctx}; | 2317 | IPC::RequestParser rp{ctx}; |
| 2319 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 2318 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| 2320 | const auto communication_mode{rp.PopEnum<NPad::NpadCommunicationMode>()}; | 2319 | const auto communication_mode{rp.PopEnum<NpadCommunicationMode>()}; |
| 2321 | 2320 | ||
| 2322 | GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode); | 2321 | GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode); |
| 2323 | 2322 | ||
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index 4d33456a3..5cc88c4a1 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "core/hle/service/hid/controllers/npad.h" | 5 | #include "core/hle/service/hid/controllers/npad.h" |
| 6 | #include "core/hle/service/hid/controllers/palma.h" | 6 | #include "core/hle/service/hid/controllers/palma.h" |
| 7 | #include "core/hle/service/hid/controllers/touchscreen.h" | 7 | #include "core/hle/service/hid/controllers/touchscreen.h" |
| 8 | #include "core/hle/service/hid/controllers/types/npad_types.h" | ||
| 8 | #include "core/hle/service/hid/errors.h" | 9 | #include "core/hle/service/hid/errors.h" |
| 9 | #include "core/hle/service/hid/hid_system_server.h" | 10 | #include "core/hle/service/hid/hid_system_server.h" |
| 10 | #include "core/hle/service/hid/resource_manager.h" | 11 | #include "core/hle/service/hid/resource_manager.h" |
| @@ -328,7 +329,7 @@ void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) { | |||
| 328 | LOG_DEBUG(Service_HID, "called, npad_id_type={}", | 329 | LOG_DEBUG(Service_HID, "called, npad_id_type={}", |
| 329 | npad_id_type); // Spams a lot when controller applet is running | 330 | npad_id_type); // Spams a lot when controller applet is running |
| 330 | 331 | ||
| 331 | const NPad::AppletDetailedUiType detailed_ui_type = | 332 | const AppletDetailedUiType detailed_ui_type = |
| 332 | GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type); | 333 | GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type); |
| 333 | 334 | ||
| 334 | IPC::ResponseBuilder rb{ctx, 3}; | 335 | IPC::ResponseBuilder rb{ctx, 3}; |
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp index 60d4ef71f..6c6cbd802 100644 --- a/src/core/hle/service/hid/resource_manager.cpp +++ b/src/core/hle/service/hid/resource_manager.cpp | |||
| @@ -18,10 +18,10 @@ | |||
| 18 | #include "core/hle/service/hid/controllers/npad.h" | 18 | #include "core/hle/service/hid/controllers/npad.h" |
| 19 | #include "core/hle/service/hid/controllers/palma.h" | 19 | #include "core/hle/service/hid/controllers/palma.h" |
| 20 | #include "core/hle/service/hid/controllers/seven_six_axis.h" | 20 | #include "core/hle/service/hid/controllers/seven_six_axis.h" |
| 21 | #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||
| 21 | #include "core/hle/service/hid/controllers/six_axis.h" | 22 | #include "core/hle/service/hid/controllers/six_axis.h" |
| 22 | #include "core/hle/service/hid/controllers/stubbed.h" | 23 | #include "core/hle/service/hid/controllers/stubbed.h" |
| 23 | #include "core/hle/service/hid/controllers/touchscreen.h" | 24 | #include "core/hle/service/hid/controllers/touchscreen.h" |
| 24 | #include "core/hle/service/hid/controllers/xpad.h" | ||
| 25 | 25 | ||
| 26 | namespace Service::HID { | 26 | namespace Service::HID { |
| 27 | 27 | ||
| @@ -45,40 +45,43 @@ void ResourceManager::Initialize() { | |||
| 45 | return; | 45 | return; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer(); | 48 | system.HIDCore().ReloadInputDevices(); |
| 49 | debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory); | 49 | is_initialized = true; |
| 50 | mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory); | 50 | } |
| 51 | debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory); | 51 | |
| 52 | keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory); | 52 | void ResourceManager::InitializeController(u64 aruid) { |
| 53 | unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory); | 53 | SharedMemoryFormat* shared_memory = nullptr; |
| 54 | npad = std::make_shared<NPad>(system.HIDCore(), shared_memory, service_context); | 54 | const auto result = applet_resource->GetSharedMemoryFormat(&shared_memory, aruid); |
| 55 | gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory); | 55 | if (result.IsError()) { |
| 56 | touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory); | 56 | return; |
| 57 | xpad = std::make_shared<XPad>(system.HIDCore(), shared_memory); | 57 | } |
| 58 | 58 | ||
| 59 | palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context); | 59 | debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory->debug_pad); |
| 60 | mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory->mouse); | ||
| 61 | debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory->debug_mouse); | ||
| 62 | keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory->keyboard); | ||
| 63 | unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory->unique_pad.header); | ||
| 64 | npad = std::make_shared<NPad>(system.HIDCore(), shared_memory->npad, service_context); | ||
| 65 | gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory->gesture); | ||
| 66 | touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory->touch_screen); | ||
| 60 | 67 | ||
| 61 | home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory); | 68 | palma = std::make_shared<Palma>(system.HIDCore(), service_context); |
| 62 | sleep_button = std::make_shared<SleepButton>(system.HIDCore(), shared_memory); | 69 | |
| 63 | capture_button = std::make_shared<CaptureButton>(system.HIDCore(), shared_memory); | 70 | home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory->home_button.header); |
| 71 | sleep_button = | ||
| 72 | std::make_shared<SleepButton>(system.HIDCore(), shared_memory->sleep_button.header); | ||
| 73 | capture_button = | ||
| 74 | std::make_shared<CaptureButton>(system.HIDCore(), shared_memory->capture_button.header); | ||
| 75 | digitizer = std::make_shared<Digitizer>(system.HIDCore(), shared_memory->digitizer.header); | ||
| 64 | 76 | ||
| 65 | six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); | 77 | six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); |
| 66 | console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory); | 78 | console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory->console); |
| 67 | seven_six_axis = std::make_shared<SevenSixAxis>(system); | 79 | seven_six_axis = std::make_shared<SevenSixAxis>(system); |
| 68 | 80 | ||
| 69 | home_button->SetCommonHeaderOffset(0x4C00); | ||
| 70 | sleep_button->SetCommonHeaderOffset(0x4E00); | ||
| 71 | capture_button->SetCommonHeaderOffset(0x5000); | ||
| 72 | unique_pad->SetCommonHeaderOffset(0x5A00); | ||
| 73 | debug_mouse->SetCommonHeaderOffset(0x3DC00); | ||
| 74 | |||
| 75 | // Homebrew doesn't try to activate some controllers, so we activate them by default | 81 | // Homebrew doesn't try to activate some controllers, so we activate them by default |
| 76 | npad->Activate(); | 82 | npad->Activate(); |
| 77 | six_axis->Activate(); | 83 | six_axis->Activate(); |
| 78 | touch_screen->Activate(); | 84 | touch_screen->Activate(); |
| 79 | |||
| 80 | system.HIDCore().ReloadInputDevices(); | ||
| 81 | is_initialized = true; | ||
| 82 | } | 85 | } |
| 83 | 86 | ||
| 84 | std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const { | 87 | std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const { |
| @@ -101,6 +104,10 @@ std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const { | |||
| 101 | return debug_pad; | 104 | return debug_pad; |
| 102 | } | 105 | } |
| 103 | 106 | ||
| 107 | std::shared_ptr<Digitizer> ResourceManager::GetDigitizer() const { | ||
| 108 | return digitizer; | ||
| 109 | } | ||
| 110 | |||
| 104 | std::shared_ptr<Gesture> ResourceManager::GetGesture() const { | 111 | std::shared_ptr<Gesture> ResourceManager::GetGesture() const { |
| 105 | return gesture; | 112 | return gesture; |
| 106 | } | 113 | } |
| @@ -146,8 +153,38 @@ std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const { | |||
| 146 | } | 153 | } |
| 147 | 154 | ||
| 148 | Result ResourceManager::CreateAppletResource(u64 aruid) { | 155 | Result ResourceManager::CreateAppletResource(u64 aruid) { |
| 156 | if (aruid == 0) { | ||
| 157 | const auto result = RegisterCoreAppletResource(); | ||
| 158 | if (result.IsError()) { | ||
| 159 | return result; | ||
| 160 | } | ||
| 161 | return GetNpad()->Activate(); | ||
| 162 | } | ||
| 163 | |||
| 164 | const auto result = CreateAppletResourceImpl(aruid); | ||
| 165 | if (result.IsError()) { | ||
| 166 | return result; | ||
| 167 | } | ||
| 168 | return GetNpad()->Activate(aruid); | ||
| 169 | } | ||
| 170 | |||
| 171 | Result ResourceManager::CreateAppletResourceImpl(u64 aruid) { | ||
| 172 | std::scoped_lock lock{shared_mutex}; | ||
| 173 | const auto result = applet_resource->CreateAppletResource(aruid); | ||
| 174 | if (result.IsSuccess()) { | ||
| 175 | InitializeController(aruid); | ||
| 176 | } | ||
| 177 | return result; | ||
| 178 | } | ||
| 179 | |||
| 180 | Result ResourceManager::RegisterCoreAppletResource() { | ||
| 149 | std::scoped_lock lock{shared_mutex}; | 181 | std::scoped_lock lock{shared_mutex}; |
| 150 | return applet_resource->CreateAppletResource(aruid); | 182 | return applet_resource->RegisterCoreAppletResource(); |
| 183 | } | ||
| 184 | |||
| 185 | Result ResourceManager::UnregisterCoreAppletResource() { | ||
| 186 | std::scoped_lock lock{shared_mutex}; | ||
| 187 | return applet_resource->UnregisterCoreAppletResource(); | ||
| 151 | } | 188 | } |
| 152 | 189 | ||
| 153 | Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) { | 190 | Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) { |
| @@ -165,6 +202,11 @@ Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle | |||
| 165 | return applet_resource->GetSharedMemoryHandle(out_handle, aruid); | 202 | return applet_resource->GetSharedMemoryHandle(out_handle, aruid); |
| 166 | } | 203 | } |
| 167 | 204 | ||
| 205 | void ResourceManager::FreeAppletResourceId(u64 aruid) { | ||
| 206 | std::scoped_lock lock{shared_mutex}; | ||
| 207 | applet_resource->FreeAppletResourceId(aruid); | ||
| 208 | } | ||
| 209 | |||
| 168 | void ResourceManager::EnableInput(u64 aruid, bool is_enabled) { | 210 | void ResourceManager::EnableInput(u64 aruid, bool is_enabled) { |
| 169 | std::scoped_lock lock{shared_mutex}; | 211 | std::scoped_lock lock{shared_mutex}; |
| 170 | applet_resource->EnableInput(aruid, is_enabled); | 212 | applet_resource->EnableInput(aruid, is_enabled); |
| @@ -189,6 +231,7 @@ void ResourceManager::UpdateControllers(std::uintptr_t user_data, | |||
| 189 | std::chrono::nanoseconds ns_late) { | 231 | std::chrono::nanoseconds ns_late) { |
| 190 | auto& core_timing = system.CoreTiming(); | 232 | auto& core_timing = system.CoreTiming(); |
| 191 | debug_pad->OnUpdate(core_timing); | 233 | debug_pad->OnUpdate(core_timing); |
| 234 | digitizer->OnUpdate(core_timing); | ||
| 192 | unique_pad->OnUpdate(core_timing); | 235 | unique_pad->OnUpdate(core_timing); |
| 193 | gesture->OnUpdate(core_timing); | 236 | gesture->OnUpdate(core_timing); |
| 194 | touch_screen->OnUpdate(core_timing); | 237 | touch_screen->OnUpdate(core_timing); |
| @@ -196,7 +239,6 @@ void ResourceManager::UpdateControllers(std::uintptr_t user_data, | |||
| 196 | home_button->OnUpdate(core_timing); | 239 | home_button->OnUpdate(core_timing); |
| 197 | sleep_button->OnUpdate(core_timing); | 240 | sleep_button->OnUpdate(core_timing); |
| 198 | capture_button->OnUpdate(core_timing); | 241 | capture_button->OnUpdate(core_timing); |
| 199 | xpad->OnUpdate(core_timing); | ||
| 200 | } | 242 | } |
| 201 | 243 | ||
| 202 | void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | 244 | void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { |
| @@ -219,8 +261,10 @@ void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanose | |||
| 219 | console_six_axis->OnUpdate(core_timing); | 261 | console_six_axis->OnUpdate(core_timing); |
| 220 | } | 262 | } |
| 221 | 263 | ||
| 222 | IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource) | 264 | IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource, |
| 223 | : ServiceFramework{system_, "IAppletResource"}, resource_manager{resource} { | 265 | u64 applet_resource_user_id) |
| 266 | : ServiceFramework{system_, "IAppletResource"}, aruid{applet_resource_user_id}, | ||
| 267 | resource_manager{resource} { | ||
| 224 | static const FunctionInfo functions[] = { | 268 | static const FunctionInfo functions[] = { |
| 225 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, | 269 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, |
| 226 | }; | 270 | }; |
| @@ -274,14 +318,14 @@ IAppletResource::~IAppletResource() { | |||
| 274 | system.CoreTiming().UnscheduleEvent(default_update_event, 0); | 318 | system.CoreTiming().UnscheduleEvent(default_update_event, 0); |
| 275 | system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0); | 319 | system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0); |
| 276 | system.CoreTiming().UnscheduleEvent(motion_update_event, 0); | 320 | system.CoreTiming().UnscheduleEvent(motion_update_event, 0); |
| 321 | resource_manager->FreeAppletResourceId(aruid); | ||
| 277 | } | 322 | } |
| 278 | 323 | ||
| 279 | void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { | 324 | void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { |
| 280 | LOG_DEBUG(Service_HID, "called"); | ||
| 281 | |||
| 282 | Kernel::KSharedMemory* handle; | 325 | Kernel::KSharedMemory* handle; |
| 283 | const u64 applet_resource_user_id = resource_manager->GetAppletResource()->GetActiveAruid(); | 326 | const auto result = resource_manager->GetSharedMemoryHandle(&handle, aruid); |
| 284 | const auto result = resource_manager->GetSharedMemoryHandle(&handle, applet_resource_user_id); | 327 | |
| 328 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, result=0x{:X}", aruid, result.raw); | ||
| 285 | 329 | ||
| 286 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 330 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 287 | rb.Push(result); | 331 | rb.Push(result); |
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h index a78e2b729..5ad7cb564 100644 --- a/src/core/hle/service/hid/resource_manager.h +++ b/src/core/hle/service/hid/resource_manager.h | |||
| @@ -31,10 +31,10 @@ class Palma; | |||
| 31 | class SevenSixAxis; | 31 | class SevenSixAxis; |
| 32 | class SixAxis; | 32 | class SixAxis; |
| 33 | class TouchScreen; | 33 | class TouchScreen; |
| 34 | class XPad; | ||
| 35 | 34 | ||
| 36 | using CaptureButton = Controller_Stubbed; | 35 | using CaptureButton = Controller_Stubbed; |
| 37 | using DebugMouse = Controller_Stubbed; | 36 | using DebugMouse = Mouse; |
| 37 | using Digitizer = Controller_Stubbed; | ||
| 38 | using HomeButton = Controller_Stubbed; | 38 | using HomeButton = Controller_Stubbed; |
| 39 | using SleepButton = Controller_Stubbed; | 39 | using SleepButton = Controller_Stubbed; |
| 40 | using UniquePad = Controller_Stubbed; | 40 | using UniquePad = Controller_Stubbed; |
| @@ -46,12 +46,14 @@ public: | |||
| 46 | ~ResourceManager(); | 46 | ~ResourceManager(); |
| 47 | 47 | ||
| 48 | void Initialize(); | 48 | void Initialize(); |
| 49 | void InitializeController(u64 aruid); | ||
| 49 | 50 | ||
| 50 | std::shared_ptr<AppletResource> GetAppletResource() const; | 51 | std::shared_ptr<AppletResource> GetAppletResource() const; |
| 51 | std::shared_ptr<CaptureButton> GetCaptureButton() const; | 52 | std::shared_ptr<CaptureButton> GetCaptureButton() const; |
| 52 | std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; | 53 | std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; |
| 53 | std::shared_ptr<DebugMouse> GetDebugMouse() const; | 54 | std::shared_ptr<DebugMouse> GetDebugMouse() const; |
| 54 | std::shared_ptr<DebugPad> GetDebugPad() const; | 55 | std::shared_ptr<DebugPad> GetDebugPad() const; |
| 56 | std::shared_ptr<Digitizer> GetDigitizer() const; | ||
| 55 | std::shared_ptr<Gesture> GetGesture() const; | 57 | std::shared_ptr<Gesture> GetGesture() const; |
| 56 | std::shared_ptr<HomeButton> GetHomeButton() const; | 58 | std::shared_ptr<HomeButton> GetHomeButton() const; |
| 57 | std::shared_ptr<Keyboard> GetKeyboard() const; | 59 | std::shared_ptr<Keyboard> GetKeyboard() const; |
| @@ -66,10 +68,13 @@ public: | |||
| 66 | 68 | ||
| 67 | Result CreateAppletResource(u64 aruid); | 69 | Result CreateAppletResource(u64 aruid); |
| 68 | 70 | ||
| 71 | Result RegisterCoreAppletResource(); | ||
| 72 | Result UnregisterCoreAppletResource(); | ||
| 69 | Result RegisterAppletResourceUserId(u64 aruid, bool bool_value); | 73 | Result RegisterAppletResourceUserId(u64 aruid, bool bool_value); |
| 70 | void UnregisterAppletResourceUserId(u64 aruid); | 74 | void UnregisterAppletResourceUserId(u64 aruid); |
| 71 | 75 | ||
| 72 | Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); | 76 | Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); |
| 77 | void FreeAppletResourceId(u64 aruid); | ||
| 73 | 78 | ||
| 74 | void EnableInput(u64 aruid, bool is_enabled); | 79 | void EnableInput(u64 aruid, bool is_enabled); |
| 75 | void EnableSixAxisSensor(u64 aruid, bool is_enabled); | 80 | void EnableSixAxisSensor(u64 aruid, bool is_enabled); |
| @@ -82,6 +87,8 @@ public: | |||
| 82 | void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | 87 | void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); |
| 83 | 88 | ||
| 84 | private: | 89 | private: |
| 90 | Result CreateAppletResourceImpl(u64 aruid); | ||
| 91 | |||
| 85 | bool is_initialized{false}; | 92 | bool is_initialized{false}; |
| 86 | 93 | ||
| 87 | mutable std::mutex shared_mutex; | 94 | mutable std::mutex shared_mutex; |
| @@ -91,6 +98,7 @@ private: | |||
| 91 | std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; | 98 | std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; |
| 92 | std::shared_ptr<DebugMouse> debug_mouse = nullptr; | 99 | std::shared_ptr<DebugMouse> debug_mouse = nullptr; |
| 93 | std::shared_ptr<DebugPad> debug_pad = nullptr; | 100 | std::shared_ptr<DebugPad> debug_pad = nullptr; |
| 101 | std::shared_ptr<Digitizer> digitizer = nullptr; | ||
| 94 | std::shared_ptr<Gesture> gesture = nullptr; | 102 | std::shared_ptr<Gesture> gesture = nullptr; |
| 95 | std::shared_ptr<HomeButton> home_button = nullptr; | 103 | std::shared_ptr<HomeButton> home_button = nullptr; |
| 96 | std::shared_ptr<Keyboard> keyboard = nullptr; | 104 | std::shared_ptr<Keyboard> keyboard = nullptr; |
| @@ -102,7 +110,6 @@ private: | |||
| 102 | std::shared_ptr<SleepButton> sleep_button = nullptr; | 110 | std::shared_ptr<SleepButton> sleep_button = nullptr; |
| 103 | std::shared_ptr<TouchScreen> touch_screen = nullptr; | 111 | std::shared_ptr<TouchScreen> touch_screen = nullptr; |
| 104 | std::shared_ptr<UniquePad> unique_pad = nullptr; | 112 | std::shared_ptr<UniquePad> unique_pad = nullptr; |
| 105 | std::shared_ptr<XPad> xpad = nullptr; | ||
| 106 | 113 | ||
| 107 | // TODO: Create these resources | 114 | // TODO: Create these resources |
| 108 | // std::shared_ptr<AudioControl> audio_control = nullptr; | 115 | // std::shared_ptr<AudioControl> audio_control = nullptr; |
| @@ -121,7 +128,8 @@ private: | |||
| 121 | 128 | ||
| 122 | class IAppletResource final : public ServiceFramework<IAppletResource> { | 129 | class IAppletResource final : public ServiceFramework<IAppletResource> { |
| 123 | public: | 130 | public: |
| 124 | explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource); | 131 | explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource, |
| 132 | u64 applet_resource_user_id); | ||
| 125 | ~IAppletResource() override; | 133 | ~IAppletResource() override; |
| 126 | 134 | ||
| 127 | private: | 135 | private: |
| @@ -132,6 +140,7 @@ private: | |||
| 132 | std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; | 140 | std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; |
| 133 | std::shared_ptr<Core::Timing::EventType> motion_update_event; | 141 | std::shared_ptr<Core::Timing::EventType> motion_update_event; |
| 134 | 142 | ||
| 143 | u64 aruid; | ||
| 135 | std::shared_ptr<ResourceManager> resource_manager; | 144 | std::shared_ptr<ResourceManager> resource_manager; |
| 136 | }; | 145 | }; |
| 137 | 146 | ||
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 6c8427b0d..0fbb43057 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp | |||
| @@ -240,7 +240,7 @@ private: | |||
| 240 | return ret; | 240 | return ret; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | Result ReadImpl(std::vector<u8>* out_data, size_t size) { | 243 | Result ReadImpl(std::vector<u8>* out_data) { |
| 244 | ASSERT_OR_EXECUTE(did_handshake, { return ResultInternalError; }); | 244 | ASSERT_OR_EXECUTE(did_handshake, { return ResultInternalError; }); |
| 245 | size_t actual_size{}; | 245 | size_t actual_size{}; |
| 246 | Result res = backend->Read(&actual_size, *out_data); | 246 | Result res = backend->Read(&actual_size, *out_data); |
| @@ -326,8 +326,8 @@ private: | |||
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | void Read(HLERequestContext& ctx) { | 328 | void Read(HLERequestContext& ctx) { |
| 329 | std::vector<u8> output_bytes; | 329 | std::vector<u8> output_bytes(ctx.GetWriteBufferSize()); |
| 330 | const Result res = ReadImpl(&output_bytes, ctx.GetWriteBufferSize()); | 330 | const Result res = ReadImpl(&output_bytes); |
| 331 | IPC::ResponseBuilder rb{ctx, 3}; | 331 | IPC::ResponseBuilder rb{ctx, 3}; |
| 332 | rb.Push(res); | 332 | rb.Push(res); |
| 333 | if (res == ResultSuccess) { | 333 | if (res == ResultSuccess) { |
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index db30ba598..3fc4024dc 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp | |||
| @@ -62,7 +62,7 @@ u64 StandardVmCallbacks::HidKeysDown() { | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | const auto applet_resource = hid->GetResourceManager(); | 64 | const auto applet_resource = hid->GetResourceManager(); |
| 65 | if (applet_resource == nullptr) { | 65 | if (applet_resource == nullptr || applet_resource->GetNpad() == nullptr) { |
| 66 | LOG_WARNING(CheatEngine, | 66 | LOG_WARNING(CheatEngine, |
| 67 | "Attempted to read input state, but applet resource is not initialized!"); | 67 | "Attempted to read input state, but applet resource is not initialized!"); |
| 68 | return 0; | 68 | return 0; |
diff --git a/src/tests/video_core/memory_tracker.cpp b/src/tests/video_core/memory_tracker.cpp index 618793668..2dbff21af 100644 --- a/src/tests/video_core/memory_tracker.cpp +++ b/src/tests/video_core/memory_tracker.cpp | |||
| @@ -23,13 +23,13 @@ constexpr VAddr c = 16 * HIGH_PAGE_SIZE; | |||
| 23 | 23 | ||
| 24 | class RasterizerInterface { | 24 | class RasterizerInterface { |
| 25 | public: | 25 | public: |
| 26 | void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | 26 | void UpdatePagesCachedCount(VAddr addr, u64 size, bool cache) { |
| 27 | const u64 page_start{addr >> Core::Memory::YUZU_PAGEBITS}; | 27 | const u64 page_start{addr >> Core::Memory::YUZU_PAGEBITS}; |
| 28 | const u64 page_end{(addr + size + Core::Memory::YUZU_PAGESIZE - 1) >> | 28 | const u64 page_end{(addr + size + Core::Memory::YUZU_PAGESIZE - 1) >> |
| 29 | Core::Memory::YUZU_PAGEBITS}; | 29 | Core::Memory::YUZU_PAGEBITS}; |
| 30 | for (u64 page = page_start; page < page_end; ++page) { | 30 | for (u64 page = page_start; page < page_end; ++page) { |
| 31 | int& value = page_table[page]; | 31 | int& value = page_table[page]; |
| 32 | value += delta; | 32 | value += (cache ? 1 : -1); |
| 33 | if (value < 0) { | 33 | if (value < 0) { |
| 34 | throw std::logic_error{"negative page"}; | 34 | throw std::logic_error{"negative page"}; |
| 35 | } | 35 | } |
| @@ -546,4 +546,4 @@ TEST_CASE("MemoryTracker: Cached write downloads") { | |||
| 546 | REQUIRE(!memory_track->IsRegionGpuModified(c + PAGE, PAGE)); | 546 | REQUIRE(!memory_track->IsRegionGpuModified(c + PAGE, PAGE)); |
| 547 | memory_track->MarkRegionAsCpuModified(c, WORD); | 547 | memory_track->MarkRegionAsCpuModified(c, WORD); |
| 548 | REQUIRE(rasterizer.Count() == 0); | 548 | REQUIRE(rasterizer.Count() == 0); |
| 549 | } \ No newline at end of file | 549 | } |
diff --git a/src/video_core/buffer_cache/word_manager.h b/src/video_core/buffer_cache/word_manager.h index a336bde41..95b752055 100644 --- a/src/video_core/buffer_cache/word_manager.h +++ b/src/video_core/buffer_cache/word_manager.h | |||
| @@ -473,7 +473,7 @@ private: | |||
| 473 | VAddr addr = cpu_addr + word_index * BYTES_PER_WORD; | 473 | VAddr addr = cpu_addr + word_index * BYTES_PER_WORD; |
| 474 | IteratePages(changed_bits, [&](size_t offset, size_t size) { | 474 | IteratePages(changed_bits, [&](size_t offset, size_t size) { |
| 475 | rasterizer->UpdatePagesCachedCount(addr + offset * BYTES_PER_PAGE, | 475 | rasterizer->UpdatePagesCachedCount(addr + offset * BYTES_PER_PAGE, |
| 476 | size * BYTES_PER_PAGE, add_to_rasterizer ? 1 : -1); | 476 | size * BYTES_PER_PAGE, add_to_rasterizer); |
| 477 | }); | 477 | }); |
| 478 | } | 478 | } |
| 479 | 479 | ||
diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp index f200a650f..3c9477f6e 100644 --- a/src/video_core/rasterizer_accelerated.cpp +++ b/src/video_core/rasterizer_accelerated.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <atomic> | 4 | #include <atomic> |
| 5 | 5 | ||
| 6 | #include "common/alignment.h" | ||
| 6 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 7 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 8 | #include "common/div_ceil.h" | 9 | #include "common/div_ceil.h" |
| @@ -11,61 +12,65 @@ | |||
| 11 | 12 | ||
| 12 | namespace VideoCore { | 13 | namespace VideoCore { |
| 13 | 14 | ||
| 15 | static constexpr u16 IdentityValue = 1; | ||
| 16 | |||
| 14 | using namespace Core::Memory; | 17 | using namespace Core::Memory; |
| 15 | 18 | ||
| 16 | RasterizerAccelerated::RasterizerAccelerated(Memory& cpu_memory_) | 19 | RasterizerAccelerated::RasterizerAccelerated(Memory& cpu_memory_) : map{}, cpu_memory{cpu_memory_} { |
| 17 | : cached_pages(std::make_unique<CachedPages>()), cpu_memory{cpu_memory_} {} | 20 | // We are tracking CPU memory, which cannot map more than 39 bits. |
| 21 | const VAddr start_address = 0; | ||
| 22 | const VAddr end_address = (1ULL << 39); | ||
| 23 | const IntervalType address_space_interval(start_address, end_address); | ||
| 24 | const auto value = std::make_pair(address_space_interval, IdentityValue); | ||
| 25 | |||
| 26 | map.add(value); | ||
| 27 | } | ||
| 18 | 28 | ||
| 19 | RasterizerAccelerated::~RasterizerAccelerated() = default; | 29 | RasterizerAccelerated::~RasterizerAccelerated() = default; |
| 20 | 30 | ||
| 21 | void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | 31 | void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, bool cache) { |
| 22 | u64 uncache_begin = 0; | 32 | std::scoped_lock lk{map_lock}; |
| 23 | u64 cache_begin = 0; | ||
| 24 | u64 uncache_bytes = 0; | ||
| 25 | u64 cache_bytes = 0; | ||
| 26 | |||
| 27 | std::atomic_thread_fence(std::memory_order_acquire); | ||
| 28 | const u64 page_end = Common::DivCeil(addr + size, YUZU_PAGESIZE); | ||
| 29 | for (u64 page = addr >> YUZU_PAGEBITS; page != page_end; ++page) { | ||
| 30 | std::atomic_uint16_t& count = cached_pages->at(page >> 2).Count(page); | ||
| 31 | |||
| 32 | if (delta > 0) { | ||
| 33 | ASSERT_MSG(count.load(std::memory_order::relaxed) < UINT16_MAX, "Count may overflow!"); | ||
| 34 | } else if (delta < 0) { | ||
| 35 | ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!"); | ||
| 36 | } else { | ||
| 37 | ASSERT_MSG(false, "Delta must be non-zero!"); | ||
| 38 | } | ||
| 39 | 33 | ||
| 40 | // Adds or subtracts 1, as count is a unsigned 8-bit value | 34 | // Align sizes. |
| 41 | count.fetch_add(static_cast<u16>(delta), std::memory_order_release); | 35 | addr = Common::AlignDown(addr, YUZU_PAGESIZE); |
| 42 | 36 | size = Common::AlignUp(size, YUZU_PAGESIZE); | |
| 43 | // Assume delta is either -1 or 1 | 37 | |
| 44 | if (count.load(std::memory_order::relaxed) == 0) { | 38 | // Declare the overall interval we are going to operate on. |
| 45 | if (uncache_bytes == 0) { | 39 | const VAddr start_address = addr; |
| 46 | uncache_begin = page; | 40 | const VAddr end_address = addr + size; |
| 47 | } | 41 | const IntervalType modification_range(start_address, end_address); |
| 48 | uncache_bytes += YUZU_PAGESIZE; | 42 | |
| 49 | } else if (uncache_bytes > 0) { | 43 | // Find the boundaries of where to iterate. |
| 50 | cpu_memory.RasterizerMarkRegionCached(uncache_begin << YUZU_PAGEBITS, uncache_bytes, | 44 | const auto lower = map.lower_bound(modification_range); |
| 51 | false); | 45 | const auto upper = map.upper_bound(modification_range); |
| 52 | uncache_bytes = 0; | 46 | |
| 53 | } | 47 | // Iterate over the contained intervals. |
| 54 | if (count.load(std::memory_order::relaxed) == 1 && delta > 0) { | 48 | for (auto it = lower; it != upper; it++) { |
| 55 | if (cache_bytes == 0) { | 49 | // Intersect interval range with modification range. |
| 56 | cache_begin = page; | 50 | const auto current_range = modification_range & it->first; |
| 57 | } | 51 | |
| 58 | cache_bytes += YUZU_PAGESIZE; | 52 | // Calculate the address and size to operate over. |
| 59 | } else if (cache_bytes > 0) { | 53 | const auto current_addr = current_range.lower(); |
| 60 | cpu_memory.RasterizerMarkRegionCached(cache_begin << YUZU_PAGEBITS, cache_bytes, true); | 54 | const auto current_size = current_range.upper() - current_addr; |
| 61 | cache_bytes = 0; | 55 | |
| 56 | // Get the current value of the range. | ||
| 57 | const auto value = it->second; | ||
| 58 | |||
| 59 | if (cache && value == IdentityValue) { | ||
| 60 | // If we are going to cache, and the value is not yet referenced, then cache this range. | ||
| 61 | cpu_memory.RasterizerMarkRegionCached(current_addr, current_size, true); | ||
| 62 | } else if (!cache && value == IdentityValue + 1) { | ||
| 63 | // If we are going to uncache, and this is the last reference, then uncache this range. | ||
| 64 | cpu_memory.RasterizerMarkRegionCached(current_addr, current_size, false); | ||
| 62 | } | 65 | } |
| 63 | } | 66 | } |
| 64 | if (uncache_bytes > 0) { | 67 | |
| 65 | cpu_memory.RasterizerMarkRegionCached(uncache_begin << YUZU_PAGEBITS, uncache_bytes, false); | 68 | // Update the set. |
| 66 | } | 69 | const auto value = std::make_pair(modification_range, IdentityValue); |
| 67 | if (cache_bytes > 0) { | 70 | if (cache) { |
| 68 | cpu_memory.RasterizerMarkRegionCached(cache_begin << YUZU_PAGEBITS, cache_bytes, true); | 71 | map.add(value); |
| 72 | } else { | ||
| 73 | map.subtract(value); | ||
| 69 | } | 74 | } |
| 70 | } | 75 | } |
| 71 | 76 | ||
diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h index e6c0ea87a..f1968f186 100644 --- a/src/video_core/rasterizer_accelerated.h +++ b/src/video_core/rasterizer_accelerated.h | |||
| @@ -3,8 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <mutex> |
| 7 | #include <atomic> | 7 | #include <boost/icl/interval_map.hpp> |
| 8 | 8 | ||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "video_core/rasterizer_interface.h" | 10 | #include "video_core/rasterizer_interface.h" |
| @@ -21,28 +21,17 @@ public: | |||
| 21 | explicit RasterizerAccelerated(Core::Memory::Memory& cpu_memory_); | 21 | explicit RasterizerAccelerated(Core::Memory::Memory& cpu_memory_); |
| 22 | ~RasterizerAccelerated() override; | 22 | ~RasterizerAccelerated() override; |
| 23 | 23 | ||
| 24 | void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override; | 24 | void UpdatePagesCachedCount(VAddr addr, u64 size, bool cache) override; |
| 25 | 25 | ||
| 26 | private: | 26 | private: |
| 27 | class CacheEntry final { | 27 | using PageIndex = VAddr; |
| 28 | public: | 28 | using PageReferenceCount = u16; |
| 29 | CacheEntry() = default; | ||
| 30 | 29 | ||
| 31 | std::atomic_uint16_t& Count(std::size_t page) { | 30 | using IntervalMap = boost::icl::interval_map<PageIndex, PageReferenceCount>; |
| 32 | return values[page & 3]; | 31 | using IntervalType = IntervalMap::interval_type; |
| 33 | } | ||
| 34 | 32 | ||
| 35 | const std::atomic_uint16_t& Count(std::size_t page) const { | 33 | IntervalMap map; |
| 36 | return values[page & 3]; | 34 | std::mutex map_lock; |
| 37 | } | ||
| 38 | |||
| 39 | private: | ||
| 40 | std::array<std::atomic_uint16_t, 4> values{}; | ||
| 41 | }; | ||
| 42 | static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!"); | ||
| 43 | |||
| 44 | using CachedPages = std::array<CacheEntry, 0x2000000>; | ||
| 45 | std::unique_ptr<CachedPages> cached_pages; | ||
| 46 | Core::Memory::Memory& cpu_memory; | 35 | Core::Memory::Memory& cpu_memory; |
| 47 | }; | 36 | }; |
| 48 | 37 | ||
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index af1469147..fd42d26b5 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -162,7 +162,7 @@ public: | |||
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | /// Increase/decrease the number of object in pages touching the specified region | 164 | /// Increase/decrease the number of object in pages touching the specified region |
| 165 | virtual void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {} | 165 | virtual void UpdatePagesCachedCount(VAddr addr, u64 size, bool cache) {} |
| 166 | 166 | ||
| 167 | /// Initialize disk cached resources for the game being emulated | 167 | /// Initialize disk cached resources for the game being emulated |
| 168 | virtual void LoadDiskResources(u64 title_id, std::stop_token stop_loading, | 168 | virtual void LoadDiskResources(u64 title_id, std::stop_token stop_loading, |
diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp index e81cd031b..a109f9cbe 100644 --- a/src/video_core/shader_cache.cpp +++ b/src/video_core/shader_cache.cpp | |||
| @@ -132,7 +132,7 @@ void ShaderCache::Register(std::unique_ptr<ShaderInfo> data, VAddr addr, size_t | |||
| 132 | 132 | ||
| 133 | storage.push_back(std::move(data)); | 133 | storage.push_back(std::move(data)); |
| 134 | 134 | ||
| 135 | rasterizer.UpdatePagesCachedCount(addr, size, 1); | 135 | rasterizer.UpdatePagesCachedCount(addr, size, true); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | void ShaderCache::InvalidatePagesInRegion(VAddr addr, size_t size) { | 138 | void ShaderCache::InvalidatePagesInRegion(VAddr addr, size_t size) { |
| @@ -209,7 +209,7 @@ void ShaderCache::UnmarkMemory(Entry* entry) { | |||
| 209 | 209 | ||
| 210 | const VAddr addr = entry->addr_start; | 210 | const VAddr addr = entry->addr_start; |
| 211 | const size_t size = entry->addr_end - addr; | 211 | const size_t size = entry->addr_end - addr; |
| 212 | rasterizer.UpdatePagesCachedCount(addr, size, -1); | 212 | rasterizer.UpdatePagesCachedCount(addr, size, false); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | void ShaderCache::RemoveShadersFromStorage(std::span<ShaderInfo*> removed_shaders) { | 215 | void ShaderCache::RemoveShadersFromStorage(std::span<ShaderInfo*> removed_shaders) { |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 0d5a1709f..d7941f6a4 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -2080,7 +2080,7 @@ void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) { | |||
| 2080 | ASSERT(False(image.flags & ImageFlagBits::Tracked)); | 2080 | ASSERT(False(image.flags & ImageFlagBits::Tracked)); |
| 2081 | image.flags |= ImageFlagBits::Tracked; | 2081 | image.flags |= ImageFlagBits::Tracked; |
| 2082 | if (False(image.flags & ImageFlagBits::Sparse)) { | 2082 | if (False(image.flags & ImageFlagBits::Sparse)) { |
| 2083 | rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1); | 2083 | rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, true); |
| 2084 | return; | 2084 | return; |
| 2085 | } | 2085 | } |
| 2086 | if (True(image.flags & ImageFlagBits::Registered)) { | 2086 | if (True(image.flags & ImageFlagBits::Registered)) { |
| @@ -2091,13 +2091,13 @@ void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) { | |||
| 2091 | const auto& map = slot_map_views[map_view_id]; | 2091 | const auto& map = slot_map_views[map_view_id]; |
| 2092 | const VAddr cpu_addr = map.cpu_addr; | 2092 | const VAddr cpu_addr = map.cpu_addr; |
| 2093 | const std::size_t size = map.size; | 2093 | const std::size_t size = map.size; |
| 2094 | rasterizer.UpdatePagesCachedCount(cpu_addr, size, 1); | 2094 | rasterizer.UpdatePagesCachedCount(cpu_addr, size, true); |
| 2095 | } | 2095 | } |
| 2096 | return; | 2096 | return; |
| 2097 | } | 2097 | } |
| 2098 | ForEachSparseSegment(image, | 2098 | ForEachSparseSegment(image, |
| 2099 | [this]([[maybe_unused]] GPUVAddr gpu_addr, VAddr cpu_addr, size_t size) { | 2099 | [this]([[maybe_unused]] GPUVAddr gpu_addr, VAddr cpu_addr, size_t size) { |
| 2100 | rasterizer.UpdatePagesCachedCount(cpu_addr, size, 1); | 2100 | rasterizer.UpdatePagesCachedCount(cpu_addr, size, true); |
| 2101 | }); | 2101 | }); |
| 2102 | } | 2102 | } |
| 2103 | 2103 | ||
| @@ -2106,7 +2106,7 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) { | |||
| 2106 | ASSERT(True(image.flags & ImageFlagBits::Tracked)); | 2106 | ASSERT(True(image.flags & ImageFlagBits::Tracked)); |
| 2107 | image.flags &= ~ImageFlagBits::Tracked; | 2107 | image.flags &= ~ImageFlagBits::Tracked; |
| 2108 | if (False(image.flags & ImageFlagBits::Sparse)) { | 2108 | if (False(image.flags & ImageFlagBits::Sparse)) { |
| 2109 | rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, -1); | 2109 | rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, false); |
| 2110 | return; | 2110 | return; |
| 2111 | } | 2111 | } |
| 2112 | ASSERT(True(image.flags & ImageFlagBits::Registered)); | 2112 | ASSERT(True(image.flags & ImageFlagBits::Registered)); |
| @@ -2117,7 +2117,7 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) { | |||
| 2117 | const auto& map = slot_map_views[map_view_id]; | 2117 | const auto& map = slot_map_views[map_view_id]; |
| 2118 | const VAddr cpu_addr = map.cpu_addr; | 2118 | const VAddr cpu_addr = map.cpu_addr; |
| 2119 | const std::size_t size = map.size; | 2119 | const std::size_t size = map.size; |
| 2120 | rasterizer.UpdatePagesCachedCount(cpu_addr, size, -1); | 2120 | rasterizer.UpdatePagesCachedCount(cpu_addr, size, false); |
| 2121 | } | 2121 | } |
| 2122 | } | 2122 | } |
| 2123 | 2123 | ||
diff --git a/src/yuzu/applets/qt_profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp index 1f3f23038..79162a491 100644 --- a/src/yuzu/applets/qt_profile_select.cpp +++ b/src/yuzu/applets/qt_profile_select.cpp | |||
| @@ -14,6 +14,8 @@ | |||
| 14 | #include "common/fs/path_util.h" | 14 | #include "common/fs/path_util.h" |
| 15 | #include "common/string_util.h" | 15 | #include "common/string_util.h" |
| 16 | #include "core/constants.h" | 16 | #include "core/constants.h" |
| 17 | #include "core/core.h" | ||
| 18 | #include "core/hle/service/acc/profile_manager.h" | ||
| 17 | #include "yuzu/applets/qt_profile_select.h" | 19 | #include "yuzu/applets/qt_profile_select.h" |
| 18 | #include "yuzu/main.h" | 20 | #include "yuzu/main.h" |
| 19 | #include "yuzu/util/controller_navigation.h" | 21 | #include "yuzu/util/controller_navigation.h" |
| @@ -47,9 +49,9 @@ QPixmap GetIcon(Common::UUID uuid) { | |||
| 47 | } // Anonymous namespace | 49 | } // Anonymous namespace |
| 48 | 50 | ||
| 49 | QtProfileSelectionDialog::QtProfileSelectionDialog( | 51 | QtProfileSelectionDialog::QtProfileSelectionDialog( |
| 50 | Core::HID::HIDCore& hid_core, QWidget* parent, | 52 | Core::System& system, QWidget* parent, |
| 51 | const Core::Frontend::ProfileSelectParameters& parameters) | 53 | const Core::Frontend::ProfileSelectParameters& parameters) |
| 52 | : QDialog(parent), profile_manager(std::make_unique<Service::Account::ProfileManager>()) { | 54 | : QDialog(parent), profile_manager{system.GetProfileManager()} { |
| 53 | outer_layout = new QVBoxLayout; | 55 | outer_layout = new QVBoxLayout; |
| 54 | 56 | ||
| 55 | instruction_label = new QLabel(); | 57 | instruction_label = new QLabel(); |
| @@ -68,7 +70,7 @@ QtProfileSelectionDialog::QtProfileSelectionDialog( | |||
| 68 | tree_view = new QTreeView; | 70 | tree_view = new QTreeView; |
| 69 | item_model = new QStandardItemModel(tree_view); | 71 | item_model = new QStandardItemModel(tree_view); |
| 70 | tree_view->setModel(item_model); | 72 | tree_view->setModel(item_model); |
| 71 | controller_navigation = new ControllerNavigation(hid_core, this); | 73 | controller_navigation = new ControllerNavigation(system.HIDCore(), this); |
| 72 | 74 | ||
| 73 | tree_view->setAlternatingRowColors(true); | 75 | tree_view->setAlternatingRowColors(true); |
| 74 | tree_view->setSelectionMode(QHeaderView::SingleSelection); | 76 | tree_view->setSelectionMode(QHeaderView::SingleSelection); |
| @@ -106,10 +108,10 @@ QtProfileSelectionDialog::QtProfileSelectionDialog( | |||
| 106 | SelectUser(tree_view->currentIndex()); | 108 | SelectUser(tree_view->currentIndex()); |
| 107 | }); | 109 | }); |
| 108 | 110 | ||
| 109 | const auto& profiles = profile_manager->GetAllUsers(); | 111 | const auto& profiles = profile_manager.GetAllUsers(); |
| 110 | for (const auto& user : profiles) { | 112 | for (const auto& user : profiles) { |
| 111 | Service::Account::ProfileBase profile{}; | 113 | Service::Account::ProfileBase profile{}; |
| 112 | if (!profile_manager->GetProfileBase(user, profile)) | 114 | if (!profile_manager.GetProfileBase(user, profile)) |
| 113 | continue; | 115 | continue; |
| 114 | 116 | ||
| 115 | const auto username = Common::StringFromFixedZeroTerminatedBuffer( | 117 | const auto username = Common::StringFromFixedZeroTerminatedBuffer( |
| @@ -134,7 +136,7 @@ QtProfileSelectionDialog::~QtProfileSelectionDialog() { | |||
| 134 | 136 | ||
| 135 | int QtProfileSelectionDialog::exec() { | 137 | int QtProfileSelectionDialog::exec() { |
| 136 | // Skip profile selection when there's only one. | 138 | // Skip profile selection when there's only one. |
| 137 | if (profile_manager->GetUserCount() == 1) { | 139 | if (profile_manager.GetUserCount() == 1) { |
| 138 | user_index = 0; | 140 | user_index = 0; |
| 139 | return QDialog::Accepted; | 141 | return QDialog::Accepted; |
| 140 | } | 142 | } |
diff --git a/src/yuzu/applets/qt_profile_select.h b/src/yuzu/applets/qt_profile_select.h index 99056e274..607f1777c 100644 --- a/src/yuzu/applets/qt_profile_select.h +++ b/src/yuzu/applets/qt_profile_select.h | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | #include <QDialog> | 7 | #include <QDialog> |
| 8 | #include <QList> | 8 | #include <QList> |
| 9 | #include "core/frontend/applets/profile_select.h" | 9 | #include "core/frontend/applets/profile_select.h" |
| 10 | #include "core/hle/service/acc/profile_manager.h" | ||
| 11 | 10 | ||
| 12 | class ControllerNavigation; | 11 | class ControllerNavigation; |
| 13 | class GMainWindow; | 12 | class GMainWindow; |
| @@ -20,15 +19,19 @@ class QStandardItemModel; | |||
| 20 | class QTreeView; | 19 | class QTreeView; |
| 21 | class QVBoxLayout; | 20 | class QVBoxLayout; |
| 22 | 21 | ||
| 23 | namespace Core::HID { | 22 | namespace Core { |
| 24 | class HIDCore; | 23 | class System; |
| 25 | } // namespace Core::HID | 24 | } |
| 25 | |||
| 26 | namespace Service::Account { | ||
| 27 | class ProfileManager; | ||
| 28 | } | ||
| 26 | 29 | ||
| 27 | class QtProfileSelectionDialog final : public QDialog { | 30 | class QtProfileSelectionDialog final : public QDialog { |
| 28 | Q_OBJECT | 31 | Q_OBJECT |
| 29 | 32 | ||
| 30 | public: | 33 | public: |
| 31 | explicit QtProfileSelectionDialog(Core::HID::HIDCore& hid_core, QWidget* parent, | 34 | explicit QtProfileSelectionDialog(Core::System& system, QWidget* parent, |
| 32 | const Core::Frontend::ProfileSelectParameters& parameters); | 35 | const Core::Frontend::ProfileSelectParameters& parameters); |
| 33 | ~QtProfileSelectionDialog() override; | 36 | ~QtProfileSelectionDialog() override; |
| 34 | 37 | ||
| @@ -58,7 +61,7 @@ private: | |||
| 58 | QScrollArea* scroll_area; | 61 | QScrollArea* scroll_area; |
| 59 | QDialogButtonBox* buttons; | 62 | QDialogButtonBox* buttons; |
| 60 | 63 | ||
| 61 | std::unique_ptr<Service::Account::ProfileManager> profile_manager; | 64 | Service::Account::ProfileManager& profile_manager; |
| 62 | ControllerNavigation* controller_navigation = nullptr; | 65 | ControllerNavigation* controller_navigation = nullptr; |
| 63 | }; | 66 | }; |
| 64 | 67 | ||
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 22b51f39c..d842b0135 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui | |||
| @@ -381,7 +381,7 @@ | |||
| 381 | <item row="5" column="0"> | 381 | <item row="5" column="0"> |
| 382 | <widget class="QCheckBox" name="disable_buffer_reorder"> | 382 | <widget class="QCheckBox" name="disable_buffer_reorder"> |
| 383 | <property name="toolTip"> | 383 | <property name="toolTip"> |
| 384 | <string><html><head/><body><p>When checked, disables reording of mapped memory uploads which allows to associate uploads with specific draws. May reduce performance in some cases.</p></body></html></string> | 384 | <string><html><head/><body><p>When checked, disables reordering of mapped memory uploads which allows to associate uploads with specific draws. May reduce performance in some cases.</p></body></html></string> |
| 385 | </property> | 385 | </property> |
| 386 | <property name="text"> | 386 | <property name="text"> |
| 387 | <string>Disable Buffer Reorder</string> | 387 | <string>Disable Buffer Reorder</string> |
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index 6d2219bf5..fa5f383d6 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp | |||
| @@ -76,9 +76,9 @@ QString GetProfileUsernameFromUser(QWidget* parent, const QString& description_t | |||
| 76 | } | 76 | } |
| 77 | } // Anonymous namespace | 77 | } // Anonymous namespace |
| 78 | 78 | ||
| 79 | ConfigureProfileManager::ConfigureProfileManager(const Core::System& system_, QWidget* parent) | 79 | ConfigureProfileManager::ConfigureProfileManager(Core::System& system_, QWidget* parent) |
| 80 | : QWidget(parent), ui{std::make_unique<Ui::ConfigureProfileManager>()}, | 80 | : QWidget(parent), ui{std::make_unique<Ui::ConfigureProfileManager>()}, |
| 81 | profile_manager(std::make_unique<Service::Account::ProfileManager>()), system{system_} { | 81 | profile_manager{system_.GetProfileManager()}, system{system_} { |
| 82 | ui->setupUi(this); | 82 | ui->setupUi(this); |
| 83 | 83 | ||
| 84 | tree_view = new QTreeView; | 84 | tree_view = new QTreeView; |
| @@ -149,10 +149,10 @@ void ConfigureProfileManager::SetConfiguration() { | |||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | void ConfigureProfileManager::PopulateUserList() { | 151 | void ConfigureProfileManager::PopulateUserList() { |
| 152 | const auto& profiles = profile_manager->GetAllUsers(); | 152 | const auto& profiles = profile_manager.GetAllUsers(); |
| 153 | for (const auto& user : profiles) { | 153 | for (const auto& user : profiles) { |
| 154 | Service::Account::ProfileBase profile{}; | 154 | Service::Account::ProfileBase profile{}; |
| 155 | if (!profile_manager->GetProfileBase(user, profile)) | 155 | if (!profile_manager.GetProfileBase(user, profile)) |
| 156 | continue; | 156 | continue; |
| 157 | 157 | ||
| 158 | const auto username = Common::StringFromFixedZeroTerminatedBuffer( | 158 | const auto username = Common::StringFromFixedZeroTerminatedBuffer( |
| @@ -167,11 +167,11 @@ void ConfigureProfileManager::PopulateUserList() { | |||
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | void ConfigureProfileManager::UpdateCurrentUser() { | 169 | void ConfigureProfileManager::UpdateCurrentUser() { |
| 170 | ui->pm_add->setEnabled(profile_manager->GetUserCount() < Service::Account::MAX_USERS); | 170 | ui->pm_add->setEnabled(profile_manager.GetUserCount() < Service::Account::MAX_USERS); |
| 171 | 171 | ||
| 172 | const auto& current_user = profile_manager->GetUser(Settings::values.current_user.GetValue()); | 172 | const auto& current_user = profile_manager.GetUser(Settings::values.current_user.GetValue()); |
| 173 | ASSERT(current_user); | 173 | ASSERT(current_user); |
| 174 | const auto username = GetAccountUsername(*profile_manager, *current_user); | 174 | const auto username = GetAccountUsername(profile_manager, *current_user); |
| 175 | 175 | ||
| 176 | scene->clear(); | 176 | scene->clear(); |
| 177 | scene->addPixmap( | 177 | scene->addPixmap( |
| @@ -187,11 +187,11 @@ void ConfigureProfileManager::ApplyConfiguration() { | |||
| 187 | 187 | ||
| 188 | void ConfigureProfileManager::SelectUser(const QModelIndex& index) { | 188 | void ConfigureProfileManager::SelectUser(const QModelIndex& index) { |
| 189 | Settings::values.current_user = | 189 | Settings::values.current_user = |
| 190 | std::clamp<s32>(index.row(), 0, static_cast<s32>(profile_manager->GetUserCount() - 1)); | 190 | std::clamp<s32>(index.row(), 0, static_cast<s32>(profile_manager.GetUserCount() - 1)); |
| 191 | 191 | ||
| 192 | UpdateCurrentUser(); | 192 | UpdateCurrentUser(); |
| 193 | 193 | ||
| 194 | ui->pm_remove->setEnabled(profile_manager->GetUserCount() >= 2); | 194 | ui->pm_remove->setEnabled(profile_manager.GetUserCount() >= 2); |
| 195 | ui->pm_rename->setEnabled(true); | 195 | ui->pm_rename->setEnabled(true); |
| 196 | ui->pm_set_image->setEnabled(true); | 196 | ui->pm_set_image->setEnabled(true); |
| 197 | } | 197 | } |
| @@ -204,18 +204,18 @@ void ConfigureProfileManager::AddUser() { | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | const auto uuid = Common::UUID::MakeRandom(); | 206 | const auto uuid = Common::UUID::MakeRandom(); |
| 207 | profile_manager->CreateNewUser(uuid, username.toStdString()); | 207 | profile_manager.CreateNewUser(uuid, username.toStdString()); |
| 208 | 208 | ||
| 209 | item_model->appendRow(new QStandardItem{GetIcon(uuid), FormatUserEntryText(username, uuid)}); | 209 | item_model->appendRow(new QStandardItem{GetIcon(uuid), FormatUserEntryText(username, uuid)}); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | void ConfigureProfileManager::RenameUser() { | 212 | void ConfigureProfileManager::RenameUser() { |
| 213 | const auto user = tree_view->currentIndex().row(); | 213 | const auto user = tree_view->currentIndex().row(); |
| 214 | const auto uuid = profile_manager->GetUser(user); | 214 | const auto uuid = profile_manager.GetUser(user); |
| 215 | ASSERT(uuid); | 215 | ASSERT(uuid); |
| 216 | 216 | ||
| 217 | Service::Account::ProfileBase profile{}; | 217 | Service::Account::ProfileBase profile{}; |
| 218 | if (!profile_manager->GetProfileBase(*uuid, profile)) | 218 | if (!profile_manager.GetProfileBase(*uuid, profile)) |
| 219 | return; | 219 | return; |
| 220 | 220 | ||
| 221 | const auto new_username = GetProfileUsernameFromUser(this, tr("Enter a new username:")); | 221 | const auto new_username = GetProfileUsernameFromUser(this, tr("Enter a new username:")); |
| @@ -227,7 +227,7 @@ void ConfigureProfileManager::RenameUser() { | |||
| 227 | std::fill(profile.username.begin(), profile.username.end(), '\0'); | 227 | std::fill(profile.username.begin(), profile.username.end(), '\0'); |
| 228 | std::copy(username_std.begin(), username_std.end(), profile.username.begin()); | 228 | std::copy(username_std.begin(), username_std.end(), profile.username.begin()); |
| 229 | 229 | ||
| 230 | profile_manager->SetProfileBase(*uuid, profile); | 230 | profile_manager.SetProfileBase(*uuid, profile); |
| 231 | 231 | ||
| 232 | item_model->setItem( | 232 | item_model->setItem( |
| 233 | user, 0, | 233 | user, 0, |
| @@ -238,9 +238,9 @@ void ConfigureProfileManager::RenameUser() { | |||
| 238 | 238 | ||
| 239 | void ConfigureProfileManager::ConfirmDeleteUser() { | 239 | void ConfigureProfileManager::ConfirmDeleteUser() { |
| 240 | const auto index = tree_view->currentIndex().row(); | 240 | const auto index = tree_view->currentIndex().row(); |
| 241 | const auto uuid = profile_manager->GetUser(index); | 241 | const auto uuid = profile_manager.GetUser(index); |
| 242 | ASSERT(uuid); | 242 | ASSERT(uuid); |
| 243 | const auto username = GetAccountUsername(*profile_manager, *uuid); | 243 | const auto username = GetAccountUsername(profile_manager, *uuid); |
| 244 | 244 | ||
| 245 | confirm_dialog->SetInfo(username, *uuid, [this, uuid]() { DeleteUser(*uuid); }); | 245 | confirm_dialog->SetInfo(username, *uuid, [this, uuid]() { DeleteUser(*uuid); }); |
| 246 | confirm_dialog->show(); | 246 | confirm_dialog->show(); |
| @@ -252,7 +252,7 @@ void ConfigureProfileManager::DeleteUser(const Common::UUID& uuid) { | |||
| 252 | } | 252 | } |
| 253 | UpdateCurrentUser(); | 253 | UpdateCurrentUser(); |
| 254 | 254 | ||
| 255 | if (!profile_manager->RemoveUser(uuid)) { | 255 | if (!profile_manager.RemoveUser(uuid)) { |
| 256 | return; | 256 | return; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| @@ -265,7 +265,7 @@ void ConfigureProfileManager::DeleteUser(const Common::UUID& uuid) { | |||
| 265 | 265 | ||
| 266 | void ConfigureProfileManager::SetUserImage() { | 266 | void ConfigureProfileManager::SetUserImage() { |
| 267 | const auto index = tree_view->currentIndex().row(); | 267 | const auto index = tree_view->currentIndex().row(); |
| 268 | const auto uuid = profile_manager->GetUser(index); | 268 | const auto uuid = profile_manager.GetUser(index); |
| 269 | ASSERT(uuid); | 269 | ASSERT(uuid); |
| 270 | 270 | ||
| 271 | const auto file = QFileDialog::getOpenFileName(this, tr("Select User Image"), QString(), | 271 | const auto file = QFileDialog::getOpenFileName(this, tr("Select User Image"), QString(), |
| @@ -317,7 +317,7 @@ void ConfigureProfileManager::SetUserImage() { | |||
| 317 | } | 317 | } |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | const auto username = GetAccountUsername(*profile_manager, *uuid); | 320 | const auto username = GetAccountUsername(profile_manager, *uuid); |
| 321 | item_model->setItem(index, 0, | 321 | item_model->setItem(index, 0, |
| 322 | new QStandardItem{GetIcon(*uuid), FormatUserEntryText(username, *uuid)}); | 322 | new QStandardItem{GetIcon(*uuid), FormatUserEntryText(username, *uuid)}); |
| 323 | UpdateCurrentUser(); | 323 | UpdateCurrentUser(); |
diff --git a/src/yuzu/configuration/configure_profile_manager.h b/src/yuzu/configuration/configure_profile_manager.h index c4b1a334e..39560fdd9 100644 --- a/src/yuzu/configuration/configure_profile_manager.h +++ b/src/yuzu/configuration/configure_profile_manager.h | |||
| @@ -52,7 +52,7 @@ class ConfigureProfileManager : public QWidget { | |||
| 52 | Q_OBJECT | 52 | Q_OBJECT |
| 53 | 53 | ||
| 54 | public: | 54 | public: |
| 55 | explicit ConfigureProfileManager(const Core::System& system_, QWidget* parent = nullptr); | 55 | explicit ConfigureProfileManager(Core::System& system_, QWidget* parent = nullptr); |
| 56 | ~ConfigureProfileManager() override; | 56 | ~ConfigureProfileManager() override; |
| 57 | 57 | ||
| 58 | void ApplyConfiguration(); | 58 | void ApplyConfiguration(); |
| @@ -85,7 +85,6 @@ private: | |||
| 85 | std::unique_ptr<Ui::ConfigureProfileManager> ui; | 85 | std::unique_ptr<Ui::ConfigureProfileManager> ui; |
| 86 | bool enabled = false; | 86 | bool enabled = false; |
| 87 | 87 | ||
| 88 | std::unique_ptr<Service::Account::ProfileManager> profile_manager; | 88 | Service::Account::ProfileManager& profile_manager; |
| 89 | |||
| 90 | const Core::System& system; | 89 | const Core::System& system; |
| 91 | }; | 90 | }; |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index b056c3717..f31ed7ebb 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -346,7 +346,7 @@ GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulk | |||
| 346 | SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue()); | 346 | SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue()); |
| 347 | discord_rpc->Update(); | 347 | discord_rpc->Update(); |
| 348 | 348 | ||
| 349 | play_time_manager = std::make_unique<PlayTime::PlayTimeManager>(); | 349 | play_time_manager = std::make_unique<PlayTime::PlayTimeManager>(system->GetProfileManager()); |
| 350 | 350 | ||
| 351 | system->GetRoomNetwork().Init(); | 351 | system->GetRoomNetwork().Init(); |
| 352 | 352 | ||
| @@ -526,8 +526,7 @@ GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulk | |||
| 526 | continue; | 526 | continue; |
| 527 | } | 527 | } |
| 528 | 528 | ||
| 529 | const Service::Account::ProfileManager manager; | 529 | if (!system->GetProfileManager().UserExistsIndex(selected_user)) { |
| 530 | if (!manager.UserExistsIndex(selected_user)) { | ||
| 531 | LOG_ERROR(Frontend, "Selected user doesn't exist"); | 530 | LOG_ERROR(Frontend, "Selected user doesn't exist"); |
| 532 | continue; | 531 | continue; |
| 533 | } | 532 | } |
| @@ -691,7 +690,7 @@ void GMainWindow::ControllerSelectorRequestExit() { | |||
| 691 | 690 | ||
| 692 | void GMainWindow::ProfileSelectorSelectProfile( | 691 | void GMainWindow::ProfileSelectorSelectProfile( |
| 693 | const Core::Frontend::ProfileSelectParameters& parameters) { | 692 | const Core::Frontend::ProfileSelectParameters& parameters) { |
| 694 | profile_select_applet = new QtProfileSelectionDialog(system->HIDCore(), this, parameters); | 693 | profile_select_applet = new QtProfileSelectionDialog(*system, this, parameters); |
| 695 | SCOPE_EXIT({ | 694 | SCOPE_EXIT({ |
| 696 | profile_select_applet->deleteLater(); | 695 | profile_select_applet->deleteLater(); |
| 697 | profile_select_applet = nullptr; | 696 | profile_select_applet = nullptr; |
| @@ -706,8 +705,8 @@ void GMainWindow::ProfileSelectorSelectProfile( | |||
| 706 | return; | 705 | return; |
| 707 | } | 706 | } |
| 708 | 707 | ||
| 709 | const Service::Account::ProfileManager manager; | 708 | const auto uuid = system->GetProfileManager().GetUser( |
| 710 | const auto uuid = manager.GetUser(static_cast<std::size_t>(profile_select_applet->GetIndex())); | 709 | static_cast<std::size_t>(profile_select_applet->GetIndex())); |
| 711 | if (!uuid.has_value()) { | 710 | if (!uuid.has_value()) { |
| 712 | emit ProfileSelectorFinishedSelection(std::nullopt); | 711 | emit ProfileSelectorFinishedSelection(std::nullopt); |
| 713 | return; | 712 | return; |
| @@ -1856,7 +1855,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p | |||
| 1856 | 1855 | ||
| 1857 | bool GMainWindow::SelectAndSetCurrentUser( | 1856 | bool GMainWindow::SelectAndSetCurrentUser( |
| 1858 | const Core::Frontend::ProfileSelectParameters& parameters) { | 1857 | const Core::Frontend::ProfileSelectParameters& parameters) { |
| 1859 | QtProfileSelectionDialog dialog(system->HIDCore(), this, parameters); | 1858 | QtProfileSelectionDialog dialog(*system, this, parameters); |
| 1860 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | | 1859 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | |
| 1861 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); | 1860 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); |
| 1862 | dialog.setWindowModality(Qt::WindowModal); | 1861 | dialog.setWindowModality(Qt::WindowModal); |
| @@ -2271,7 +2270,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 2271 | .display_options = {}, | 2270 | .display_options = {}, |
| 2272 | .purpose = Service::AM::Applets::UserSelectionPurpose::General, | 2271 | .purpose = Service::AM::Applets::UserSelectionPurpose::General, |
| 2273 | }; | 2272 | }; |
| 2274 | QtProfileSelectionDialog dialog(system->HIDCore(), this, parameters); | 2273 | QtProfileSelectionDialog dialog(*system, this, parameters); |
| 2275 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | | 2274 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | |
| 2276 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); | 2275 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); |
| 2277 | dialog.setWindowModality(Qt::WindowModal); | 2276 | dialog.setWindowModality(Qt::WindowModal); |
| @@ -2288,8 +2287,8 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 2288 | return; | 2287 | return; |
| 2289 | } | 2288 | } |
| 2290 | 2289 | ||
| 2291 | Service::Account::ProfileManager manager; | 2290 | const auto user_id = |
| 2292 | const auto user_id = manager.GetUser(static_cast<std::size_t>(index)); | 2291 | system->GetProfileManager().GetUser(static_cast<std::size_t>(index)); |
| 2293 | ASSERT(user_id); | 2292 | ASSERT(user_id); |
| 2294 | 2293 | ||
| 2295 | const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( | 2294 | const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( |
diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp index 603e9ae3d..41692c05b 100644 --- a/src/yuzu/multiplayer/lobby.cpp +++ b/src/yuzu/multiplayer/lobby.cpp | |||
| @@ -27,9 +27,9 @@ | |||
| 27 | Lobby::Lobby(QWidget* parent, QStandardItemModel* list, | 27 | Lobby::Lobby(QWidget* parent, QStandardItemModel* list, |
| 28 | std::shared_ptr<Core::AnnounceMultiplayerSession> session, Core::System& system_) | 28 | std::shared_ptr<Core::AnnounceMultiplayerSession> session, Core::System& system_) |
| 29 | : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), | 29 | : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), |
| 30 | ui(std::make_unique<Ui::Lobby>()), announce_multiplayer_session(session), | 30 | ui(std::make_unique<Ui::Lobby>()), |
| 31 | profile_manager(std::make_unique<Service::Account::ProfileManager>()), system{system_}, | 31 | announce_multiplayer_session(session), system{system_}, room_network{ |
| 32 | room_network{system.GetRoomNetwork()} { | 32 | system.GetRoomNetwork()} { |
| 33 | ui->setupUi(this); | 33 | ui->setupUi(this); |
| 34 | 34 | ||
| 35 | // setup the watcher for background connections | 35 | // setup the watcher for background connections |
| @@ -299,14 +299,15 @@ void Lobby::OnRefreshLobby() { | |||
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | std::string Lobby::GetProfileUsername() { | 301 | std::string Lobby::GetProfileUsername() { |
| 302 | const auto& current_user = profile_manager->GetUser(Settings::values.current_user.GetValue()); | 302 | const auto& current_user = |
| 303 | system.GetProfileManager().GetUser(Settings::values.current_user.GetValue()); | ||
| 303 | Service::Account::ProfileBase profile{}; | 304 | Service::Account::ProfileBase profile{}; |
| 304 | 305 | ||
| 305 | if (!current_user.has_value()) { | 306 | if (!current_user.has_value()) { |
| 306 | return ""; | 307 | return ""; |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 309 | if (!profile_manager->GetProfileBase(*current_user, profile)) { | 310 | if (!system.GetProfileManager().GetProfileBase(*current_user, profile)) { |
| 310 | return ""; | 311 | return ""; |
| 311 | } | 312 | } |
| 312 | 313 | ||
diff --git a/src/yuzu/multiplayer/lobby.h b/src/yuzu/multiplayer/lobby.h index 2674ae7c3..e78c9cae3 100644 --- a/src/yuzu/multiplayer/lobby.h +++ b/src/yuzu/multiplayer/lobby.h | |||
| @@ -24,10 +24,6 @@ namespace Core { | |||
| 24 | class System; | 24 | class System; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | namespace Service::Account { | ||
| 28 | class ProfileManager; | ||
| 29 | } | ||
| 30 | |||
| 31 | /** | 27 | /** |
| 32 | * Listing of all public games pulled from services. The lobby should be simple enough for users to | 28 | * Listing of all public games pulled from services. The lobby should be simple enough for users to |
| 33 | * find the game they want to play, and join it. | 29 | * find the game they want to play, and join it. |
| @@ -103,7 +99,6 @@ private: | |||
| 103 | 99 | ||
| 104 | QFutureWatcher<AnnounceMultiplayerRoom::RoomList> room_list_watcher; | 100 | QFutureWatcher<AnnounceMultiplayerRoom::RoomList> room_list_watcher; |
| 105 | std::weak_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session; | 101 | std::weak_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session; |
| 106 | std::unique_ptr<Service::Account::ProfileManager> profile_manager; | ||
| 107 | QFutureWatcher<void>* watcher; | 102 | QFutureWatcher<void>* watcher; |
| 108 | Validation validation; | 103 | Validation validation; |
| 109 | Core::System& system; | 104 | Core::System& system; |
diff --git a/src/yuzu/play_time_manager.cpp b/src/yuzu/play_time_manager.cpp index 155c36b7d..94c99274d 100644 --- a/src/yuzu/play_time_manager.cpp +++ b/src/yuzu/play_time_manager.cpp | |||
| @@ -20,8 +20,8 @@ struct PlayTimeElement { | |||
| 20 | PlayTime play_time; | 20 | PlayTime play_time; |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | std::optional<std::filesystem::path> GetCurrentUserPlayTimePath() { | 23 | std::optional<std::filesystem::path> GetCurrentUserPlayTimePath( |
| 24 | const Service::Account::ProfileManager manager; | 24 | const Service::Account::ProfileManager& manager) { |
| 25 | const auto uuid = manager.GetUser(static_cast<s32>(Settings::values.current_user)); | 25 | const auto uuid = manager.GetUser(static_cast<s32>(Settings::values.current_user)); |
| 26 | if (!uuid.has_value()) { | 26 | if (!uuid.has_value()) { |
| 27 | return std::nullopt; | 27 | return std::nullopt; |
| @@ -30,8 +30,9 @@ std::optional<std::filesystem::path> GetCurrentUserPlayTimePath() { | |||
| 30 | uuid->RawString().append(".bin"); | 30 | uuid->RawString().append(".bin"); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | [[nodiscard]] bool ReadPlayTimeFile(PlayTimeDatabase& out_play_time_db) { | 33 | [[nodiscard]] bool ReadPlayTimeFile(PlayTimeDatabase& out_play_time_db, |
| 34 | const auto filename = GetCurrentUserPlayTimePath(); | 34 | const Service::Account::ProfileManager& manager) { |
| 35 | const auto filename = GetCurrentUserPlayTimePath(manager); | ||
| 35 | 36 | ||
| 36 | if (!filename.has_value()) { | 37 | if (!filename.has_value()) { |
| 37 | LOG_ERROR(Frontend, "Failed to get current user path"); | 38 | LOG_ERROR(Frontend, "Failed to get current user path"); |
| @@ -66,8 +67,9 @@ std::optional<std::filesystem::path> GetCurrentUserPlayTimePath() { | |||
| 66 | return true; | 67 | return true; |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | [[nodiscard]] bool WritePlayTimeFile(const PlayTimeDatabase& play_time_db) { | 70 | [[nodiscard]] bool WritePlayTimeFile(const PlayTimeDatabase& play_time_db, |
| 70 | const auto filename = GetCurrentUserPlayTimePath(); | 71 | const Service::Account::ProfileManager& manager) { |
| 72 | const auto filename = GetCurrentUserPlayTimePath(manager); | ||
| 71 | 73 | ||
| 72 | if (!filename.has_value()) { | 74 | if (!filename.has_value()) { |
| 73 | LOG_ERROR(Frontend, "Failed to get current user path"); | 75 | LOG_ERROR(Frontend, "Failed to get current user path"); |
| @@ -96,8 +98,9 @@ std::optional<std::filesystem::path> GetCurrentUserPlayTimePath() { | |||
| 96 | 98 | ||
| 97 | } // namespace | 99 | } // namespace |
| 98 | 100 | ||
| 99 | PlayTimeManager::PlayTimeManager() { | 101 | PlayTimeManager::PlayTimeManager(Service::Account::ProfileManager& profile_manager) |
| 100 | if (!ReadPlayTimeFile(database)) { | 102 | : manager{profile_manager} { |
| 103 | if (!ReadPlayTimeFile(database, manager)) { | ||
| 101 | LOG_ERROR(Frontend, "Failed to read play time database! Resetting to default."); | 104 | LOG_ERROR(Frontend, "Failed to read play time database! Resetting to default."); |
| 102 | } | 105 | } |
| 103 | } | 106 | } |
| @@ -142,7 +145,7 @@ void PlayTimeManager::AutoTimestamp(std::stop_token stop_token) { | |||
| 142 | } | 145 | } |
| 143 | 146 | ||
| 144 | void PlayTimeManager::Save() { | 147 | void PlayTimeManager::Save() { |
| 145 | if (!WritePlayTimeFile(database)) { | 148 | if (!WritePlayTimeFile(database, manager)) { |
| 146 | LOG_ERROR(Frontend, "Failed to update play time database!"); | 149 | LOG_ERROR(Frontend, "Failed to update play time database!"); |
| 147 | } | 150 | } |
| 148 | } | 151 | } |
diff --git a/src/yuzu/play_time_manager.h b/src/yuzu/play_time_manager.h index 5f96f3447..1714b9131 100644 --- a/src/yuzu/play_time_manager.h +++ b/src/yuzu/play_time_manager.h | |||
| @@ -11,6 +11,10 @@ | |||
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "common/polyfill_thread.h" | 12 | #include "common/polyfill_thread.h" |
| 13 | 13 | ||
| 14 | namespace Service::Account { | ||
| 15 | class ProfileManager; | ||
| 16 | } | ||
| 17 | |||
| 14 | namespace PlayTime { | 18 | namespace PlayTime { |
| 15 | 19 | ||
| 16 | using ProgramId = u64; | 20 | using ProgramId = u64; |
| @@ -19,7 +23,7 @@ using PlayTimeDatabase = std::map<ProgramId, PlayTime>; | |||
| 19 | 23 | ||
| 20 | class PlayTimeManager { | 24 | class PlayTimeManager { |
| 21 | public: | 25 | public: |
| 22 | explicit PlayTimeManager(); | 26 | explicit PlayTimeManager(Service::Account::ProfileManager& profile_manager); |
| 23 | ~PlayTimeManager(); | 27 | ~PlayTimeManager(); |
| 24 | 28 | ||
| 25 | YUZU_NON_COPYABLE(PlayTimeManager); | 29 | YUZU_NON_COPYABLE(PlayTimeManager); |
| @@ -32,11 +36,13 @@ public: | |||
| 32 | void Stop(); | 36 | void Stop(); |
| 33 | 37 | ||
| 34 | private: | 38 | private: |
| 39 | void AutoTimestamp(std::stop_token stop_token); | ||
| 40 | void Save(); | ||
| 41 | |||
| 35 | PlayTimeDatabase database; | 42 | PlayTimeDatabase database; |
| 36 | u64 running_program_id; | 43 | u64 running_program_id; |
| 37 | std::jthread play_time_thread; | 44 | std::jthread play_time_thread; |
| 38 | void AutoTimestamp(std::stop_token stop_token); | 45 | Service::Account::ProfileManager& manager; |
| 39 | void Save(); | ||
| 40 | }; | 46 | }; |
| 41 | 47 | ||
| 42 | QString ReadablePlayTime(qulonglong time_seconds); | 48 | QString ReadablePlayTime(qulonglong time_seconds); |