diff --git a/README.md b/README.md index 73a08fb1a..d630f548f 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2765. +This is the source code for early-access 2768. ## Legal Notice diff --git a/dist/qt_themes/default/style.qss b/dist/qt_themes/default/style.qss index f0908a7f1..12e681648 100755 --- a/dist/qt_themes/default/style.qss +++ b/dist/qt_themes/default/style.qss @@ -58,6 +58,19 @@ QPushButton#GPUStatusBarButton:!checked { color: #109010; } +QPushButton#DockingStatusBarButton { + min-width: 0px; + color: #000000; + border: 1px solid transparent; + background-color: transparent; + padding: 0px 3px 0px 3px; + text-align: center; +} + +QPushButton#DockingStatusBarButton:hover { + border: 1px solid #76797C; +} + QPushButton#buttonRefreshDevices { min-width: 21px; min-height: 21px; diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss index dac2dba86..63a636ae6 100755 --- a/dist/qt_themes/qdarkstyle/style.qss +++ b/dist/qt_themes/qdarkstyle/style.qss @@ -1304,6 +1304,19 @@ QPushButton#GPUStatusBarButton:!checked { color: #40dd40; } +QPushButton#DockingStatusBarButton { + min-width: 0px; + color: #ffffff; + border: 1px solid transparent; + background-color: transparent; + padding: 0px 3px 0px 3px; + text-align: center; +} + +QPushButton#DockingStatusBarButton:hover { + border: 1px solid #76797C; +} + QPushButton#buttonRefreshDevices { min-width: 23px; min-height: 23px; diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss index 032d05ec6..49b05c8ba 100755 --- a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss +++ b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss @@ -2207,6 +2207,19 @@ QPushButton#GPUStatusBarButton:!checked { color: #40dd40; } +QPushButton#DockingStatusBarButton { + min-width: 0px; + color: #ffffff; + border: 1px solid transparent; + background-color: transparent; + padding: 0px 3px 0px 3px; + text-align: center; +} + +QPushButton#DockingStatusBarButton:hover { + border: 1px solid #76797C; +} + QPushButton#buttonRefreshDevices { min-width: 19px; min-height: 19px; diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp index fd3cbfd94..4ae40ec8e 100755 --- a/src/core/hle/kernel/k_code_memory.cpp +++ b/src/core/hle/kernel/k_code_memory.cpp @@ -27,23 +27,18 @@ ResultCode KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr auto& page_table = m_owner->PageTable(); // Construct the page group. - m_page_group = - KPageLinkedList(page_table.GetPhysicalAddr(addr), Common::DivideUp(size, PageSize)); + m_page_group = {}; // Lock the memory. - R_TRY(page_table.LockForCodeMemory(addr, size)) + R_TRY(page_table.LockForCodeMemory(&m_page_group, addr, size)) // Clear the memory. - // - // FIXME: this ends up clobbering address ranges outside the scope of the mapping within - // guest memory, and is not specifically required if the guest program is correctly - // written, so disable until this is further investigated. - // - // for (const auto& block : m_page_group.Nodes()) { - // std::memset(device_memory.GetPointer(block.GetAddress()), 0xFF, block.GetSize()); - // } + for (const auto& block : m_page_group.Nodes()) { + std::memset(device_memory.GetPointer(block.GetAddress()), 0xFF, block.GetSize()); + } // Set remaining tracking members. + m_owner->Open(); m_address = addr; m_is_initialized = true; m_is_owner_mapped = false; @@ -57,8 +52,14 @@ void KCodeMemory::Finalize() { // Unlock. if (!m_is_mapped && !m_is_owner_mapped) { const size_t size = m_page_group.GetNumPages() * PageSize; - m_owner->PageTable().UnlockForCodeMemory(m_address, size); + m_owner->PageTable().UnlockForCodeMemory(m_address, size, m_page_group); } + + // Close the page group. + m_page_group = {}; + + // Close our reference to our owner. + m_owner->Close(); } ResultCode KCodeMemory::Map(VAddr address, size_t size) { @@ -118,7 +119,8 @@ ResultCode KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermis k_perm = KMemoryPermission::UserReadExecute; break; default: - break; + // Already validated by ControlCodeMemory svc + UNREACHABLE(); } // Map the memory. diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 9b0285fde..504e22cb9 100755 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp @@ -542,6 +542,95 @@ ResultCode KPageTable::MakePageGroup(KPageLinkedList& pg, VAddr addr, size_t num return ResultSuccess; } +bool KPageTable::IsValidPageGroup(const KPageLinkedList& pg_ll, VAddr addr, size_t num_pages) { + ASSERT(this->IsLockedByCurrentThread()); + + const size_t size = num_pages * PageSize; + const auto& pg = pg_ll.Nodes(); + const auto& memory_layout = system.Kernel().MemoryLayout(); + + // Empty groups are necessarily invalid. + if (pg.empty()) { + return false; + } + + // We're going to validate that the group we'd expect is the group we see. + auto cur_it = pg.begin(); + PAddr cur_block_address = cur_it->GetAddress(); + size_t cur_block_pages = cur_it->GetNumPages(); + + auto UpdateCurrentIterator = [&]() { + if (cur_block_pages == 0) { + if ((++cur_it) == pg.end()) { + return false; + } + + cur_block_address = cur_it->GetAddress(); + cur_block_pages = cur_it->GetNumPages(); + } + return true; + }; + + // Begin traversal. + Common::PageTable::TraversalContext context; + Common::PageTable::TraversalEntry next_entry; + if (!page_table_impl.BeginTraversal(next_entry, context, addr)) { + return false; + } + + // Prepare tracking variables. + PAddr cur_addr = next_entry.phys_addr; + size_t cur_size = next_entry.block_size - (cur_addr & (next_entry.block_size - 1)); + size_t tot_size = cur_size; + + // Iterate, comparing expected to actual. + while (tot_size < size) { + if (!page_table_impl.ContinueTraversal(next_entry, context)) { + return false; + } + + if (next_entry.phys_addr != (cur_addr + cur_size)) { + const size_t cur_pages = cur_size / PageSize; + + if (!IsHeapPhysicalAddress(memory_layout, cur_addr)) { + return false; + } + + if (!UpdateCurrentIterator()) { + return false; + } + + if (cur_block_address != cur_addr || cur_block_pages < cur_pages) { + return false; + } + + cur_block_address += cur_size; + cur_block_pages -= cur_pages; + cur_addr = next_entry.phys_addr; + cur_size = next_entry.block_size; + } else { + cur_size += next_entry.block_size; + } + + tot_size += next_entry.block_size; + } + + // Ensure we compare the right amount for the last block. + if (tot_size > size) { + cur_size -= (tot_size - size); + } + + if (!IsHeapPhysicalAddress(memory_layout, cur_addr)) { + return false; + } + + if (!UpdateCurrentIterator()) { + return false; + } + + return cur_block_address == cur_addr && cur_block_pages == (cur_size / PageSize); +} + ResultCode KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table, VAddr src_addr) { KScopedLightLock lk(general_lock); @@ -1687,22 +1776,22 @@ ResultCode KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) return ResultSuccess; } -ResultCode KPageTable::LockForCodeMemory(VAddr addr, std::size_t size) { +ResultCode KPageTable::LockForCodeMemory(KPageLinkedList* out, VAddr addr, std::size_t size) { return this->LockMemoryAndOpen( - nullptr, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, - KMemoryState::FlagCanCodeMemory, KMemoryPermission::All, KMemoryPermission::UserReadWrite, - KMemoryAttribute::All, KMemoryAttribute::None, + out, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory, + KMemoryPermission::All, KMemoryPermission::UserReadWrite, KMemoryAttribute::All, + KMemoryAttribute::None, static_cast(KMemoryPermission::NotMapped | KMemoryPermission::KernelReadWrite), KMemoryAttribute::Locked); } -ResultCode KPageTable::UnlockForCodeMemory(VAddr addr, std::size_t size) { - return this->UnlockMemory(addr, size, KMemoryState::FlagCanCodeMemory, - KMemoryState::FlagCanCodeMemory, KMemoryPermission::None, - KMemoryPermission::None, KMemoryAttribute::All, - KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, - KMemoryAttribute::Locked, nullptr); +ResultCode KPageTable::UnlockForCodeMemory(VAddr addr, std::size_t size, + const KPageLinkedList& pg) { + return this->UnlockMemory( + addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory, + KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::All, + KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, KMemoryAttribute::Locked, &pg); } ResultCode KPageTable::InitializeMemoryLayout(VAddr start, VAddr end) { @@ -2121,7 +2210,7 @@ ResultCode KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_ // Check the page group. if (pg != nullptr) { - UNIMPLEMENTED_MSG("PageGroup support is unimplemented!"); + R_UNLESS(this->IsValidPageGroup(*pg, addr, num_pages), ResultInvalidMemoryRegion); } // Decide on new perm and attr. diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 52a93ce86..6312eb682 100755 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h @@ -72,8 +72,8 @@ public: KMemoryPermission perm, PAddr map_addr = 0); ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size); ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size); - ResultCode LockForCodeMemory(VAddr addr, std::size_t size); - ResultCode UnlockForCodeMemory(VAddr addr, std::size_t size); + ResultCode LockForCodeMemory(KPageLinkedList* out, VAddr addr, std::size_t size); + ResultCode UnlockForCodeMemory(VAddr addr, std::size_t size, const KPageLinkedList& pg); ResultCode MakeAndOpenPageGroup(KPageLinkedList* out, VAddr address, size_t num_pages, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, @@ -178,6 +178,7 @@ private: const KPageLinkedList* pg); ResultCode MakePageGroup(KPageLinkedList& pg, VAddr addr, size_t num_pages); + bool IsValidPageGroup(const KPageLinkedList& pg, VAddr addr, size_t num_pages); bool IsLockedByCurrentThread() const { return general_lock.IsLockedByCurrentThread(); diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 4ca779d80..9259ca15e 100755 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -189,7 +189,7 @@ if (ENABLE_QT_TRANSLATION) # Update source TS file if enabled if (GENERATE_QT_TRANSLATION) get_target_property(SRCS yuzu SOURCES) - qt5_create_translation(QM_FILES + qt_create_translation(QM_FILES ${SRCS} ${UIS} ${YUZU_QT_LANGUAGES}/en.ts @@ -205,7 +205,7 @@ if (ENABLE_QT_TRANSLATION) list(REMOVE_ITEM LANGUAGES_TS ${YUZU_QT_LANGUAGES}/en.ts) # Compile TS files to QM files - qt5_add_translation(LANGUAGES_QM ${LANGUAGES_TS}) + qt_add_translation(LANGUAGES_QM ${LANGUAGES_TS}) # Build a QRC file from the QM file list set(LANGUAGES_QRC ${CMAKE_CURRENT_BINARY_DIR}/languages.qrc) @@ -217,7 +217,7 @@ if (ENABLE_QT_TRANSLATION) file(APPEND ${LANGUAGES_QRC} "") # Add the QRC file to package in all QM files - qt5_add_resources(LANGUAGES ${LANGUAGES_QRC}) + qt_add_resources(LANGUAGES ${LANGUAGES_QRC}) else() set(LANGUAGES) endif() @@ -238,7 +238,11 @@ if (APPLE) set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) elseif(WIN32) # compile as a win32 gui application instead of a console application - target_link_libraries(yuzu PRIVATE Qt5::WinMain) + if (QT_VERSION VERSION_GREATER 6) + target_link_libraries(yuzu PRIVATE Qt6::EntryPointPrivate) + else() + target_link_libraries(yuzu PRIVATE Qt5::WinMain) + endif() if(MSVC) set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS") elseif(MINGW) @@ -249,7 +253,7 @@ endif() create_target_directory_groups(yuzu) target_link_libraries(yuzu PRIVATE common core input_common video_core) -target_link_libraries(yuzu PRIVATE Boost::boost glad Qt5::Widgets) +target_link_libraries(yuzu PRIVATE Boost::boost glad Qt::Widgets) target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include) @@ -257,7 +261,7 @@ if (NOT WIN32) target_include_directories(yuzu PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) endif() if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - target_link_libraries(yuzu PRIVATE Qt5::DBus) + target_link_libraries(yuzu PRIVATE Qt::DBus) endif() target_compile_definitions(yuzu PRIVATE @@ -293,7 +297,7 @@ if (USE_DISCORD_PRESENCE) endif() if (YUZU_USE_QT_WEB_ENGINE) - target_link_libraries(yuzu PRIVATE Qt5::WebEngineCore Qt5::WebEngineWidgets) + target_link_libraries(yuzu PRIVATE Qt::WebEngineCore Qt::WebEngineWidgets) target_compile_definitions(yuzu PRIVATE -DYUZU_USE_QT_WEB_ENGINE) endif () diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index aae2de2f8..bde465485 100755 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -752,7 +752,7 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, center_x, center_y); if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) { - QCursor::setPos(mapToGlobal({center_x, center_y})); + QCursor::setPos(mapToGlobal(QPoint{center_x, center_y})); } emit MouseActivity(); diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 87c559e7a..d01538039 100755 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -20,7 +21,6 @@ class GRenderWindow; class GMainWindow; class QKeyEvent; -class QStringList; namespace Core { enum class SystemResultStatus : u32; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 9a938d272..9df4752be 100755 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -71,28 +71,28 @@ const std::array Config::default_ringcon_analogs{{ // UISetting::values.shortcuts, which is alphabetically ordered. // clang-format off const std::array Config::default_hotkeys{{ - {QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}}, - {QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}}, - {QStringLiteral("Audio Volume Up"), QStringLiteral("Main Window"), {QStringLiteral("+"), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}}, - {QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}}, - {QStringLiteral("Change Adapting Filter"), QStringLiteral("Main Window"), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}}, - {QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}}, - {QStringLiteral("Change GPU Accuracy"), QStringLiteral("Main Window"), {QStringLiteral("F9"), QStringLiteral("Home+R"), Qt::ApplicationShortcut}}, - {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), QStringLiteral("Home+Plus"), Qt::WindowShortcut}}, - {QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), QStringLiteral(""), Qt::WindowShortcut}}, - {QStringLiteral("Exit yuzu"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), QStringLiteral("Home+Minus"), Qt::WindowShortcut}}, - {QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut}}, - {QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut}}, - {QStringLiteral("Load/Remove Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut}}, - {QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut}}, - {QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut}}, - {QStringLiteral("TAS Record"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut}}, - {QStringLiteral("TAS Reset"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut}}, - {QStringLiteral("TAS Start/Stop"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut}}, - {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), QStringLiteral(""), Qt::WindowShortcut}}, - {QStringLiteral("Toggle Framerate Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+U"), QStringLiteral("Home+Y"), Qt::ApplicationShortcut}}, - {QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F9"), QStringLiteral(""), Qt::ApplicationShortcut}}, - {QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), QStringLiteral(""), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("+"), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change GPU Accuracy")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F9"), QStringLiteral("Home+R"), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Continue/Pause Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F4"), QStringLiteral("Home+Plus"), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Esc"), QStringLiteral(""), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit yuzu")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+Q"), QStringLiteral("Home+Minus"), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Filter Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F"), QStringLiteral(""), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Framerate Limit")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+U"), QStringLiteral("Home+Y"), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Mouse Panning")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F9"), QStringLiteral(""), Qt::ApplicationShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Status Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+S"), QStringLiteral(""), Qt::WindowShortcut}}, }}; // clang-format on diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp index 6679e9c53..edf0893c4 100755 --- a/src/yuzu/configuration/configure_hotkeys.cpp +++ b/src/yuzu/configuration/configure_hotkeys.cpp @@ -61,14 +61,18 @@ ConfigureHotkeys::~ConfigureHotkeys() = default; void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) { for (const auto& group : registry.hotkey_groups) { - auto* parent_item = new QStandardItem(group.first); + auto* parent_item = + new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(group.first))); parent_item->setEditable(false); + parent_item->setData(group.first); for (const auto& hotkey : group.second) { - auto* action = new QStandardItem(hotkey.first); + auto* action = + new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(hotkey.first))); auto* keyseq = new QStandardItem(hotkey.second.keyseq.toString(QKeySequence::NativeText)); auto* controller_keyseq = new QStandardItem(hotkey.second.controller_keyseq); action->setEditable(false); + action->setData(hotkey.first); keyseq->setEditable(false); controller_keyseq->setEditable(false); parent_item->appendRow({action, keyseq, controller_keyseq}); @@ -93,6 +97,16 @@ void ConfigureHotkeys::RetranslateUI() { ui->retranslateUi(this); model->setHorizontalHeaderLabels({tr("Action"), tr("Hotkey"), tr("Controller Hotkey")}); + for (int key_id = 0; key_id < model->rowCount(); key_id++) { + QStandardItem* parent = model->item(key_id, 0); + parent->setText( + QCoreApplication::translate("Hotkeys", qPrintable(parent->data().toString()))); + for (int key_column_id = 0; key_column_id < parent->rowCount(); key_column_id++) { + QStandardItem* action = parent->child(key_column_id, name_column); + action->setText( + QCoreApplication::translate("Hotkeys", qPrintable(action->data().toString()))); + } + } } void ConfigureHotkeys::Configure(QModelIndex index) { @@ -273,10 +287,10 @@ void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) { const QStandardItem* controller_keyseq = parent->child(key_column_id, controller_column); for (auto& [group, sub_actions] : registry.hotkey_groups) { - if (group != parent->text()) + if (group != parent->data()) continue; for (auto& [action_name, hotkey] : sub_actions) { - if (action_name != action->text()) + if (action_name != action->data()) continue; hotkey.keyseq = QKeySequence(keyseq->text()); hotkey.controller_keyseq = controller_keyseq->text(); diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp index 27559c37b..c313b0919 100755 --- a/src/yuzu/configuration/configure_motion_touch.cpp +++ b/src/yuzu/configuration/configure_motion_touch.cpp @@ -151,6 +151,8 @@ void ConfigureMotionTouch::ConnectEvents() { &ConfigureMotionTouch::OnConfigureTouchCalibration); connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this, &ConfigureMotionTouch::OnConfigureTouchFromButton); + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, + &ConfigureMotionTouch::ApplyConfiguration); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, [this] { if (CanCloseDialog()) { reject(); diff --git a/src/yuzu/configuration/configure_motion_touch.ui b/src/yuzu/configuration/configure_motion_touch.ui index c75a84ae4..0237fae54 100755 --- a/src/yuzu/configuration/configure_motion_touch.ui +++ b/src/yuzu/configuration/configure_motion_touch.ui @@ -293,22 +293,5 @@ - - - buttonBox - accepted() - ConfigureMotionTouch - ApplyConfiguration() - - - 20 - 20 - - - 20 - 20 - - - - + diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 19aa589f9..ecebb0fb7 100755 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -130,8 +130,7 @@ void ConfigureSystem::ApplyConfiguration() { // Guard if during game and set to game-specific value if (Settings::values.rng_seed.UsingGlobal()) { if (ui->rng_seed_checkbox->isChecked()) { - Settings::values.rng_seed.SetValue( - ui->rng_seed_edit->text().toULongLong(nullptr, 16)); + Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16)); } else { Settings::values.rng_seed.SetValue(std::nullopt); } @@ -142,8 +141,7 @@ void ConfigureSystem::ApplyConfiguration() { case ConfigurationShared::CheckState::Off: Settings::values.rng_seed.SetGlobal(false); if (ui->rng_seed_checkbox->isChecked()) { - Settings::values.rng_seed.SetValue( - ui->rng_seed_edit->text().toULongLong(nullptr, 16)); + Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16)); } else { Settings::values.rng_seed.SetValue(std::nullopt); } diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 4a6d74a7e..d13530a5b 100755 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -483,7 +483,7 @@ void GameList::DonePopulating(const QStringList& watch_list) { // Also artificially caps the watcher to a certain number of directories constexpr int LIMIT_WATCH_DIRECTORIES = 5000; constexpr int SLICE_SIZE = 25; - int len = std::min(watch_list.length(), LIMIT_WATCH_DIRECTORIES); + int len = std::min(static_cast(watch_list.size()), LIMIT_WATCH_DIRECTORIES); for (int i = 0; i < len; i += SLICE_SIZE) { watcher->addPaths(watch_list.mid(i, i + SLICE_SIZE)); QCoreApplication::processEvents(); diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index edfb946a8..e273744fd 100755 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -183,7 +183,7 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size void LoadingScreen::paintEvent(QPaintEvent* event) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); QWidget::paintEvent(event); diff --git a/src/yuzu/loading_screen.h b/src/yuzu/loading_screen.h index 7c960ee72..17045595d 100755 --- a/src/yuzu/loading_screen.h +++ b/src/yuzu/loading_screen.h @@ -7,6 +7,7 @@ #include #include #include +#include #if !QT_CONFIG(movie) #define YUZU_QT_MOVIE_MISSING 1 @@ -88,4 +89,6 @@ private: std::size_t slow_shader_first_value = 0; }; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Q_DECLARE_METATYPE(VideoCore::LoadCallbackStage); +#endif diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 4fdd8acd2..4d7634184 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -870,12 +870,11 @@ void GMainWindow::InitializeWidgets() { // Setup Dock button dock_status_button = new QPushButton(); - dock_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton")); + dock_status_button->setObjectName(QStringLiteral("DockingStatusBarButton")); dock_status_button->setFocusPolicy(Qt::NoFocus); connect(dock_status_button, &QPushButton::clicked, this, &GMainWindow::OnToggleDockedMode); - dock_status_button->setText(tr("DOCK")); dock_status_button->setCheckable(true); - dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); + UpdateDockedButton(); statusBar()->insertPermanentWidget(0, dock_status_button); gpu_accuracy_button = new QPushButton(); @@ -1630,7 +1629,7 @@ void GMainWindow::StoreRecentFile(const QString& filename) { void GMainWindow::UpdateRecentFiles() { const int num_recent_files = - std::min(UISettings::values.recent_files.size(), max_recent_files_item); + std::min(static_cast(UISettings::values.recent_files.size()), max_recent_files_item); for (int i = 0; i < num_recent_files; i++) { const QString text = QStringLiteral("&%1. %2").arg(i + 1).arg( @@ -2909,7 +2908,7 @@ void GMainWindow::OnToggleDockedMode() { } Settings::values.use_docked_mode.SetValue(!is_docked); - dock_status_button->setChecked(!is_docked); + UpdateDockedButton(); OnDockedModeChanged(is_docked, !is_docked, *system); } @@ -3275,6 +3274,12 @@ void GMainWindow::UpdateGPUAccuracyButton() { } } +void GMainWindow::UpdateDockedButton() { + const bool is_docked = Settings::values.use_docked_mode.GetValue(); + dock_status_button->setChecked(is_docked); + dock_status_button->setText(is_docked ? tr("DOCKED") : tr("HANDHELD")); +} + void GMainWindow::UpdateFilterText() { const auto filter = Settings::values.scaling_filter.GetValue(); switch (filter) { @@ -3318,10 +3323,10 @@ void GMainWindow::UpdateAAText() { } void GMainWindow::UpdateStatusButtons() { - dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() == Settings::RendererBackend::Vulkan); UpdateGPUAccuracyButton(); + UpdateDockedButton(); UpdateFilterText(); UpdateAAText(); } @@ -3372,7 +3377,7 @@ void GMainWindow::CenterMouseCursor() { const int center_x = render_window->width() / 2; const int center_y = render_window->height() / 2; - QCursor::setPos(mapToGlobal({center_x, center_y})); + QCursor::setPos(mapToGlobal(QPoint{center_x, center_y})); } void GMainWindow::OnMouseActivity() { diff --git a/src/yuzu/main.h b/src/yuzu/main.h index b399e9b01..600647015 100755 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -320,6 +320,7 @@ private: void MigrateConfigFiles(); void UpdateWindowTitle(std::string_view title_name = {}, std::string_view title_version = {}, std::string_view gpu_vendor = {}); + void UpdateDockedButton(); void UpdateFilterText(); void UpdateAAText(); void UpdateStatusBar();