diff --git a/.ci/windows/install-msvc.ps1 b/.ci/windows/install-msvc.ps1 index b88f727ed8..788b2848ad 100755 --- a/.ci/windows/install-msvc.ps1 +++ b/.ci/windows/install-msvc.ps1 @@ -10,7 +10,7 @@ if (-not ([bool](net session 2>$null))) { } $VSVer = "17" -$ExeFile = "vs_BuildTools.exe" +$ExeFile = "vs_community.exe" $Uri = "https://aka.ms/vs/$VSVer/release/$ExeFile" $Destination = "./$ExeFile" @@ -19,21 +19,39 @@ $WebClient = New-Object System.Net.WebClient $WebClient.DownloadFile($Uri, $Destination) Write-Host "Finished downloading $ExeFile" -$VSROOT = "C:/VSBuildTools/$VSVer" $Arguments = @( - "--installPath `"$VSROOT`"", # set custom installation path - "--quiet", # suppress UI - "--wait", # wait for installation to complete - "--norestart", # prevent automatic restart - "--add Microsoft.VisualStudio.Workload.VCTools", # add C++ build tools workload - "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64", # add core x86/x64 C++ tools - "--add Microsoft.VisualStudio.Component.Windows10SDK.19041" # add specific Windows SDK + "--quiet", # Suppress installer UI + "--wait", # Wait for installation to complete + "--norestart", # Prevent automatic restart + "--force", # Force installation even if components are already installed + "--add Microsoft.VisualStudio.Workload.NativeDesktop", # Desktop development with C++ + "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64", # Core C++ compiler/tools for x86/x64 + "--add Microsoft.VisualStudio.Component.Windows11SDK.26100",# Windows 11 SDK (26100) + "--add Microsoft.VisualStudio.Component.Windows10SDK.19041",# Windows 10 SDK (19041) + "--add Microsoft.VisualStudio.Component.VC.Llvm.Clang", # LLVM Clang compiler + "--add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", # LLVM Clang integration toolset + "--add Microsoft.VisualStudio.Component.Windows11SDK.22621",# Windows 11 SDK (22621) + "--add Microsoft.VisualStudio.Component.VC.CMake.Project", # CMake project support + "--add Microsoft.VisualStudio.ComponentGroup.VC.Tools.142.x86.x64", # VC++ 14.2 toolset + "--add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang" # LLVM Clang for native desktop ) Write-Host "Installing Visual Studio Build Tools" -$InstallProcess = Start-Process -FilePath $Destination -NoNewWindow -PassThru -Wait -ArgumentList $Arguments -$ExitCode = $InstallProcess.ExitCode +$InstallProcess = Start-Process -FilePath $Destination -NoNewWindow -PassThru -ArgumentList $Arguments +# Spinner while installing +$Spinner = "|/-\" +$i = 0 +while (-not $InstallProcess.HasExited) { + Write-Host -NoNewline ("`rInstalling... " + $Spinner[$i % $Spinner.Length]) + Start-Sleep -Milliseconds 250 + $i++ +} + +# Clear spinner line +Write-Host "`rSetup completed! " + +$ExitCode = $InstallProcess.ExitCode if ($ExitCode -ne 0) { Write-Host "Error installing Visual Studio Build Tools (Error: $ExitCode)" Exit $ExitCode diff --git a/CMakeLists.txt b/CMakeLists.txt index 411de4620b..a9ff2e9458 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,73 +139,93 @@ endif() # Set bundled sdl2/qt as dependent options. # On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion -CMAKE_DEPENDENT_OPTION(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" OFF) +cmake_dependent_option(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" OFF) + +if (ENABLE_SDL2) + # TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system + cmake_dependent_option(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" OFF "NOT MSVC" OFF) + option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}") +endif() + +option(ENABLE_QT "Enable the Qt frontend" ON) +option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF) +option(ENABLE_QT_UPDATE_CHECKER "Enable update checker for the Qt frontend" OFF) +cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF) +option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF) +option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) +set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundled Qt libraries") + +option(ENABLE_CUBEB "Enables the cubeb audio backend" ON) set(EXT_DEFAULT OFF) - if (MSVC OR ANDROID) set(EXT_DEFAULT ON) endif() +option(YUZU_USE_CPM "Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched." ${EXT_DEFAULT}) -CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" ${EXT_DEFAULT} "ENABLE_SDL2;NOT MSVC" OFF) +option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT}) +cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from source" OFF "NOT WIN32 AND NOT ANDROID" OFF) cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "NOT ANDROID" OFF) cmake_dependent_option(ENABLE_OPENGL "Enable OpenGL" ON "NOT WIN32 OR NOT ARCHITECTURE_arm64" OFF) mark_as_advanced(FORCE ENABLE_OPENGL) -option(ENABLE_QT "Enable the Qt frontend" ON) -option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF) -option(ENABLE_QT_UPDATE_CHECKER "Enable update checker for the Qt frontend" OFF) - -CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF) - -option(YUZU_USE_CPM "Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched." ${EXT_DEFAULT}) - option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) option(ENABLE_WIFI_SCAN "Enable WiFi scanning" OFF) -option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT}) -cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from source" OFF "NOT WIN32 AND NOT ANDROID" OFF) - -option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF) - -option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) - -set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundled Qt libraries") - -option(ENABLE_CUBEB "Enables the cubeb audio backend" ON) - -CMAKE_DEPENDENT_OPTION(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF "ENABLE_QT" OFF) +cmake_dependent_option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF "ENABLE_QT" OFF) option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}") -option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ${EXT_DEFAULT}) +option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF) +if (YUZU_USE_PRECOMPILED_HEADERS) + message(STATUS "Using Precompiled Headers.") + set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON) +endif() +option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF) +if(YUZU_ENABLE_LTO) + include(CheckIPOSupported) + check_ipo_supported(RESULT COMPILER_SUPPORTS_LTO) + if(NOT COMPILER_SUPPORTS_LTO) + message(FATAL_ERROR "Your compiler does not support interprocedural optimization (IPO). Re-run CMake with -DYUZU_ENABLE_LTO=OFF.") + endif() + set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ${COMPILER_SUPPORTS_LTO}) +endif() +option(USE_CCACHE "Use ccache for compilation" OFF) +set(CCACHE_PATH "ccache" CACHE STRING "Path to ccache binary") +if(USE_CCACHE) + find_program(CCACHE_BINARY ${CCACHE_PATH}) + if(CCACHE_BINARY) + message(STATUS "Found ccache at: ${CCACHE_BINARY}") + set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_BINARY}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_BINARY}) + if (YUZU_USE_PRECOMPILED_HEADERS) + message(FATAL_ERROR "Precompiled headers are incompatible with ccache. Re-run CMake with -DYUZU_USE_PRECOMPILED_HEADERS=OFF.") + endif() + else() + message(WARNING "USE_CCACHE enabled, but no executable found at: ${CCACHE_PATH}") + endif() +endif() # TODO(crueter): CI this? option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON) -# TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system -CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "ENABLE_SDL2" OFF) +cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF) +cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF) -CMAKE_DEPENDENT_OPTION(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF) +cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "ENABLE_SDL2;NOT ANDROID" OFF) -CMAKE_DEPENDENT_OPTION(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF) - -CMAKE_DEPENDENT_OPTION(YUZU_CMD "Compile the eden-cli executable" ON "ENABLE_SDL2;NOT ANDROID" OFF) - -CMAKE_DEPENDENT_OPTION(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF) - -option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF) +cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF) option(YUZU_DOWNLOAD_TIME_ZONE_DATA "Always download time zone binaries" ON) - -CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "NOT WIN32" OFF) - -CMAKE_DEPENDENT_OPTION(USE_SYSTEM_MOLTENVK "Use the system MoltenVK lib (instead of the bundled one)" OFF "APPLE" OFF) - set(YUZU_TZDB_PATH "" CACHE STRING "Path to a pre-downloaded timezone database") +cmake_dependent_option(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "LINUX" OFF) + +cmake_dependent_option(YUZU_USE_BUNDLED_MOLTENVK "Download bundled MoltenVK lib" ON "APPLE" OFF) + option(YUZU_DISABLE_LLVM "Disable LLVM (useful for CI)" OFF) set(DEFAULT_ENABLE_OPENSSL ON) @@ -218,15 +238,12 @@ if (ANDROID OR WIN32 OR APPLE OR PLATFORM_SUN) # your own copy of it. set(DEFAULT_ENABLE_OPENSSL OFF) endif() - if (ENABLE_WEB_SERVICE) set(DEFAULT_ENABLE_OPENSSL ON) endif() - option(ENABLE_OPENSSL "Enable OpenSSL backend for ISslConnection" ${DEFAULT_ENABLE_OPENSSL}) - if (ENABLE_OPENSSL) - CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_OPENSSL "Download bundled OpenSSL build" "${MSVC}" "NOT ANDROID" ON) + cmake_dependent_option(YUZU_USE_BUNDLED_OPENSSL "Download bundled OpenSSL build" "${MSVC}" "NOT ANDROID" ON) endif() if (ANDROID AND YUZU_DOWNLOAD_ANDROID_VVL) @@ -253,21 +270,6 @@ if (ANDROID) set(CMAKE_POLICY_VERSION_MINIMUM 3.5) # Workaround for Oboe endif() -if (YUZU_USE_PRECOMPILED_HEADERS) - if (MSVC AND CCACHE) - # buildcache does not properly cache PCH files, leading to compilation errors. - # See https://github.com/mbitsnbites/buildcache/discussions/230 - message(WARNING "buildcache does not properly support Precompiled Headers. Disabling PCH") - set(DYNARMIC_USE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE) - set(YUZU_USE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE) - endif() -endif() - -if (YUZU_USE_PRECOMPILED_HEADERS) - message(STATUS "Using Precompiled Headers.") - set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON) -endif() - # Default to a Release build get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE) @@ -310,12 +312,25 @@ endif() if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX)) set(HAS_NCE 1) add_compile_definitions(HAS_NCE=1) + find_package(oaknut 2.0.1) endif() if (YUZU_ROOM) add_compile_definitions(YUZU_ROOM) endif() +if (ANDROID OR PLATFORM_FREEBSD OR PLATFORM_OPENBSD OR PLATFORM_SUN OR APPLE) + if(CXX_APPLE OR CXX_CLANG) + # libc++ has stop_token and jthread as experimental + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexperimental-library") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexperimental-library") + else() + # Uses glibc, mostly? + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCPP_ENABLE_EXPERIMENTAL=1") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LIBCPP_ENABLE_EXPERIMENTAL=1") + endif() +endif() + # Build/optimization presets if (PLATFORM_LINUX OR CXX_CLANG) if (ARCHITECTURE_x86_64) @@ -883,18 +898,46 @@ if (MSVC AND CXX_CLANG) link_libraries(llvm-mingw-runtime) endif() -if (YUZU_USE_FASTER_LD AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # We will assume that if the compiler is GCC, it will attempt to use ld.bfd by default. - # Try to pick a faster linker. - find_program(LLD lld) - find_program(MOLD mold) +#[[ + search order: + - gold (GCC only) - the best, generally, but unfortunately not packaged anymore + - mold (GCC only) - generally does well on GCC + - ldd - preferred on clang + - bfd - the final fallback + - If none are found (macOS uses ld.prime, etc) just use the default linker +]] +if (YUZU_USE_FASTER_LD) + find_program(LINKER_BFD bfd) + if (LINKER_BFD) + set(LINKER bfd) + endif() - if (MOLD AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1") - message(NOTICE "Selecting mold as linker") - add_link_options("-fuse-ld=mold") - elseif (LLD) - message(NOTICE "Selecting lld as linker") - add_link_options("-fuse-ld=lld") + find_program(LINKER_LLD lld) + if (LINKER_LLD) + set(LINKER lld) + endif() + + if (CXX_GCC) + find_program(LINKER_MOLD mold) + if (LINKER_MOLD AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1") + set(LINKER mold) + endif() + + find_program(LINKER_GOLD gold) + if (LINKER_GOLD) + set(LINKER gold) + endif() + endif() + + if (LINKER) + message(NOTICE "Selecting ${LINKER} as linker") + add_link_options("-fuse-ld=${LINKER}") + else() + message(WARNING "No faster linker found--using default") + endif() + + if (LINKER STREQUAL "lld" AND CXX_GCC) + message(WARNING "Using lld on GCC may cause issues with certain LTO settings. If the program fails to compile, disable YUZU_USE_FASTER_LD, or install mold or GNU gold.") endif() endif() diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake index 6c4afc03be..f6e3aaa4ad 100644 --- a/CMakeModules/DownloadExternals.cmake +++ b/CMakeModules/DownloadExternals.cmake @@ -10,6 +10,7 @@ function(download_bundled_external remote_path lib_name cpm_key prefix_var versi set(package_base_url "https://github.com/eden-emulator/") set(package_repo "no_platform") set(package_extension "no_platform") + set(CACHE_KEY "") # TODO(crueter): Need to convert ffmpeg to a CI. if (WIN32 OR FORCE_WIN_ARCHIVES) @@ -33,8 +34,9 @@ function(download_bundled_external remote_path lib_name cpm_key prefix_var versi else() message(FATAL_ERROR "No package available for this platform") endif() - set(package_url "${package_base_url}${package_repo}") - set(full_url ${package_url}${remote_path}${lib_name}${package_extension}) + string(CONCAT package_url "${package_base_url}" "${package_repo}") + string(CONCAT full_url "${package_url}" "${remote_path}" "${lib_name}" "${package_extension}") + message(STATUS "Resolved bundled URL: ${full_url}") # TODO(crueter): DELETE THIS ENTIRELY, GLORY BE TO THE CI! AddPackage( @@ -47,26 +49,12 @@ function(download_bundled_external remote_path lib_name cpm_key prefix_var versi # TODO(crueter): hash ) - set(${prefix_var} "${${cpm_key}_SOURCE_DIR}" PARENT_SCOPE) - message(STATUS "Using bundled binaries at ${${cpm_key}_SOURCE_DIR}") -endfunction() - -function(download_moltenvk_external platform version) - set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK") - set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar") - if (NOT EXISTS ${MOLTENVK_DIR}) - if (NOT EXISTS ${MOLTENVK_TAR}) - file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/download/${version}/MoltenVK-${platform}.tar - ${MOLTENVK_TAR} SHOW_PROGRESS) - endif() - - execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${MOLTENVK_TAR}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals") + if (DEFINED ${cpm_key}_SOURCE_DIR) + set(${prefix_var} "${${cpm_key}_SOURCE_DIR}" PARENT_SCOPE) + message(STATUS "Using bundled binaries at ${${cpm_key}_SOURCE_DIR}") + else() + message(FATAL_ERROR "AddPackage did not set ${cpm_key}_SOURCE_DIR") endif() - - # Add the MoltenVK library path to the prefix so find_library can locate it. - list(APPEND CMAKE_PREFIX_PATH "${MOLTENVK_DIR}/MoltenVK/dylib/${platform}") - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE) endfunction() # Determine installation parameters for OS, architecture, and compiler @@ -108,7 +96,7 @@ function(determine_qt_parameters target host_out type_out arch_out arch_path_out set(host "linux") set(type "desktop") set(arch "linux_gcc_64") - set(arch_path "linux") + set(arch_path "gcc_64") endif() set(${host_out} "${host}" PARENT_SCOPE) @@ -143,56 +131,79 @@ function(download_qt_configuration prefix_out target host type arch arch_path ba set(install_args -c "${CURRENT_MODULE_DIR}/aqt_config.ini") if (tool) set(prefix "${base_path}/Tools") - set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target}) + list(APPEND install_args install-tool --outputdir "${base_path}" "${host}" desktop "${target}") else() set(prefix "${base_path}/${target}/${arch_path}") - set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} -m qt_base) + list(APPEND install_args install-qt --outputdir "${base_path}" "${host}" "${type}" "${target}" "${arch}" -m qt_base) if (YUZU_USE_QT_MULTIMEDIA) - set(install_args ${install_args} qtmultimedia) + list(APPEND install_args qtmultimedia) endif() if (YUZU_USE_QT_WEB_ENGINE) - set(install_args ${install_args} qtpositioning qtwebchannel qtwebengine) + list(APPEND install_args qtpositioning qtwebchannel qtwebengine) endif() - if (NOT ${YUZU_QT_MIRROR} STREQUAL "") + if (NOT "${YUZU_QT_MIRROR}" STREQUAL "") message(STATUS "Using Qt mirror ${YUZU_QT_MIRROR}") - set(install_args ${install_args} -b ${YUZU_QT_MIRROR}) + list(APPEND install_args -b "${YUZU_QT_MIRROR}") endif() endif() - message(STATUS "Install Args ${install_args}") + message(STATUS "Install Args: ${install_args}") + if (NOT EXISTS "${prefix}") message(STATUS "Downloading Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path}") set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.3.0") if (WIN32) set(aqt_path "${base_path}/aqt.exe") if (NOT EXISTS "${aqt_path}") - file(DOWNLOAD - ${AQT_PREBUILD_BASE_URL}/aqt.exe - ${aqt_path} SHOW_PROGRESS) + file(DOWNLOAD "${AQT_PREBUILD_BASE_URL}/aqt.exe" "${aqt_path}" SHOW_PROGRESS) + endif() + execute_process(COMMAND "${aqt_path}" ${install_args} + WORKING_DIRECTORY "${base_path}" + RESULT_VARIABLE aqt_res + OUTPUT_VARIABLE aqt_out + ERROR_VARIABLE aqt_err) + if (NOT aqt_res EQUAL 0) + message(FATAL_ERROR "aqt.exe failed: ${aqt_err}") endif() - execute_process(COMMAND ${aqt_path} ${install_args} - WORKING_DIRECTORY ${base_path}) elseif (APPLE) set(aqt_path "${base_path}/aqt-macos") if (NOT EXISTS "${aqt_path}") - file(DOWNLOAD - ${AQT_PREBUILD_BASE_URL}/aqt-macos - ${aqt_path} SHOW_PROGRESS) + file(DOWNLOAD "${AQT_PREBUILD_BASE_URL}/aqt-macos" "${aqt_path}" SHOW_PROGRESS) + endif() + execute_process(COMMAND chmod +x "${aqt_path}") + execute_process(COMMAND "${aqt_path}" ${install_args} + WORKING_DIRECTORY "${base_path}" + RESULT_VARIABLE aqt_res + ERROR_VARIABLE aqt_err) + if (NOT aqt_res EQUAL 0) + message(FATAL_ERROR "aqt-macos failed: ${aqt_err}") endif() - execute_process(COMMAND chmod +x ${aqt_path}) - execute_process(COMMAND ${aqt_path} ${install_args} - WORKING_DIRECTORY ${base_path}) else() + find_program(PYTHON3_EXECUTABLE python3) + if (NOT PYTHON3_EXECUTABLE) + message(FATAL_ERROR "python3 is required to install Qt using aqt (pip mode).") + endif() set(aqt_install_path "${base_path}/aqt") file(MAKE_DIRECTORY "${aqt_install_path}") - execute_process(COMMAND python3 -m pip install --target=${aqt_install_path} aqtinstall - WORKING_DIRECTORY ${base_path}) - execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args} - WORKING_DIRECTORY ${base_path}) + execute_process(COMMAND "${PYTHON3_EXECUTABLE}" -m pip install --target="${aqt_install_path}" aqtinstall + WORKING_DIRECTORY "${base_path}" + RESULT_VARIABLE pip_res + ERROR_VARIABLE pip_err) + if (NOT pip_res EQUAL 0) + message(FATAL_ERROR "pip install aqtinstall failed: ${pip_err}") + endif() + + execute_process(COMMAND "${CMAKE_COMMAND}" -E env PYTHONPATH="${aqt_install_path}" "${PYTHON3_EXECUTABLE}" -m aqt ${install_args} + WORKING_DIRECTORY "${base_path}" + RESULT_VARIABLE aqt_res + ERROR_VARIABLE aqt_err) + if (NOT aqt_res EQUAL 0) + message(FATAL_ERROR "aqt (python) failed: ${aqt_err}") + endif() endif() message(STATUS "Downloaded Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path} to ${prefix}") @@ -210,7 +221,7 @@ endfunction() function(download_qt target) determine_qt_parameters("${target}" host type arch arch_path host_type host_arch host_arch_path) - get_external_prefix(qt base_path) + set(base_path "${CMAKE_BINARY_DIR}/externals/qt") file(MAKE_DIRECTORY "${base_path}") download_qt_configuration(prefix "${target}" "${host}" "${type}" "${arch}" "${arch_path}" "${base_path}") @@ -227,26 +238,34 @@ function(download_qt target) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE) endfunction() -function(download_moltenvk) -set(MOLTENVK_PLATFORM "macOS") +function(download_moltenvk version platform) + if(NOT version) + message(FATAL_ERROR "download_moltenvk: version argument is required") + endif() + if(NOT platform) + message(FATAL_ERROR "download_moltenvk: platform argument is required") + endif() -set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK") -set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar") -if (NOT EXISTS ${MOLTENVK_DIR}) -if (NOT EXISTS ${MOLTENVK_TAR}) - file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/download/v1.2.10-rc2/MoltenVK-all.tar - ${MOLTENVK_TAR} SHOW_PROGRESS) -endif() + set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK") + set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar") -execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${MOLTENVK_TAR}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals") -endif() + if(NOT EXISTS "${MOLTENVK_DIR}") + if(NOT EXISTS "${MOLTENVK_TAR}") + file(DOWNLOAD "https://github.com/KhronosGroup/MoltenVK/releases/download/${version}/MoltenVK-${platform}.tar" + "${MOLTENVK_TAR}" SHOW_PROGRESS) + endif() -# Add the MoltenVK library path to the prefix so find_library can locate it. -list(APPEND CMAKE_PREFIX_PATH "${MOLTENVK_DIR}/MoltenVK/dylib/${MOLTENVK_PLATFORM}") -set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE) + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xf "${MOLTENVK_TAR}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals" + RESULT_VARIABLE tar_res + ERROR_VARIABLE tar_err + ) + if(NOT tar_res EQUAL 0) + message(FATAL_ERROR "Extracting MoltenVK failed: ${tar_err}") + endif() + endif() + list(APPEND CMAKE_PREFIX_PATH "${MOLTENVK_DIR}/MoltenVK/dylib/${platform}") + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE) endfunction() -function(get_external_prefix lib_name prefix_var) - set(${prefix_var} "${CMAKE_BINARY_DIR}/externals/${lib_name}" PARENT_SCOPE) -endfunction() diff --git a/CMakeModules/Findsirit.cmake b/CMakeModules/Findsirit.cmake deleted file mode 100644 index 83b81b09c5..0000000000 --- a/CMakeModules/Findsirit.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -include(FindPackageHandleStandardArgs) - -find_package(PkgConfig QUIET) -pkg_search_module(sirit QUIET IMPORTED_TARGET sirit) -find_package_handle_standard_args(sirit - REQUIRED_VARS sirit_LINK_LIBRARIES - VERSION_VAR sirit_VERSION -) diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake index 2d7081b7db..1ae608c085 100644 --- a/CMakeModules/GenerateSCMRev.cmake +++ b/CMakeModules/GenerateSCMRev.cmake @@ -31,7 +31,11 @@ set(GIT_DESC ${BUILD_VERSION}) set(REPO_NAME "Eden") set(BUILD_ID ${GIT_REFSPEC}) set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ") - set(CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") +# Auto-updater metadata! Must somewhat mirror GitHub API endpoint +set(BUILD_AUTO_UPDATE_WEBSITE "https://github.com") +set(BUILD_AUTO_UPDATE_API "http://api.github.com") +set(BUILD_AUTO_UPDATE_REPO "eden-emulator/Releases") + configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY) diff --git a/dist/icons/controller/applet_dual_joycon.png b/dist/icons/controller/applet_dual_joycon.png index 32e0a04ae5..f1701453a9 100644 Binary files a/dist/icons/controller/applet_dual_joycon.png and b/dist/icons/controller/applet_dual_joycon.png differ diff --git a/dist/icons/controller/applet_dual_joycon_dark.png b/dist/icons/controller/applet_dual_joycon_dark.png index 6adc663561..da9367b5f3 100644 Binary files a/dist/icons/controller/applet_dual_joycon_dark.png and b/dist/icons/controller/applet_dual_joycon_dark.png differ diff --git a/dist/icons/controller/applet_dual_joycon_dark_disabled.png b/dist/icons/controller/applet_dual_joycon_dark_disabled.png index 208603ee78..a4d38b633d 100644 Binary files a/dist/icons/controller/applet_dual_joycon_dark_disabled.png and b/dist/icons/controller/applet_dual_joycon_dark_disabled.png differ diff --git a/dist/icons/controller/applet_dual_joycon_disabled.png b/dist/icons/controller/applet_dual_joycon_disabled.png index 43950618da..f3cb35bbdd 100644 Binary files a/dist/icons/controller/applet_dual_joycon_disabled.png and b/dist/icons/controller/applet_dual_joycon_disabled.png differ diff --git a/dist/icons/controller/applet_dual_joycon_midnight.png b/dist/icons/controller/applet_dual_joycon_midnight.png index c7edea8a35..e3f42bb99b 100644 Binary files a/dist/icons/controller/applet_dual_joycon_midnight.png and b/dist/icons/controller/applet_dual_joycon_midnight.png differ diff --git a/dist/icons/controller/applet_dual_joycon_midnight_disabled.png b/dist/icons/controller/applet_dual_joycon_midnight_disabled.png index ee1aafc858..ac5cf51179 100644 Binary files a/dist/icons/controller/applet_dual_joycon_midnight_disabled.png and b/dist/icons/controller/applet_dual_joycon_midnight_disabled.png differ diff --git a/dist/icons/controller/applet_handheld.png b/dist/icons/controller/applet_handheld.png index 7f8dd22275..c16361b913 100644 Binary files a/dist/icons/controller/applet_handheld.png and b/dist/icons/controller/applet_handheld.png differ diff --git a/dist/icons/controller/applet_handheld_dark.png b/dist/icons/controller/applet_handheld_dark.png index 41f6d7aea9..a994041fd5 100644 Binary files a/dist/icons/controller/applet_handheld_dark.png and b/dist/icons/controller/applet_handheld_dark.png differ diff --git a/dist/icons/controller/applet_handheld_dark_disabled.png b/dist/icons/controller/applet_handheld_dark_disabled.png index 5a136ddd1d..6a083a60e1 100644 Binary files a/dist/icons/controller/applet_handheld_dark_disabled.png and b/dist/icons/controller/applet_handheld_dark_disabled.png differ diff --git a/dist/icons/controller/applet_handheld_disabled.png b/dist/icons/controller/applet_handheld_disabled.png index 53f8ce7adc..1ebda184e9 100644 Binary files a/dist/icons/controller/applet_handheld_disabled.png and b/dist/icons/controller/applet_handheld_disabled.png differ diff --git a/dist/icons/controller/applet_handheld_midnight.png b/dist/icons/controller/applet_handheld_midnight.png index 7188b91545..5183f4bb69 100644 Binary files a/dist/icons/controller/applet_handheld_midnight.png and b/dist/icons/controller/applet_handheld_midnight.png differ diff --git a/dist/icons/controller/applet_handheld_midnight_disabled.png b/dist/icons/controller/applet_handheld_midnight_disabled.png index 6ccfc32536..4021d05a1d 100644 Binary files a/dist/icons/controller/applet_handheld_midnight_disabled.png and b/dist/icons/controller/applet_handheld_midnight_disabled.png differ diff --git a/dist/icons/controller/applet_pro_controller.png b/dist/icons/controller/applet_pro_controller.png index e322588558..d6b49c3be2 100644 Binary files a/dist/icons/controller/applet_pro_controller.png and b/dist/icons/controller/applet_pro_controller.png differ diff --git a/dist/icons/controller/applet_pro_controller_dark.png b/dist/icons/controller/applet_pro_controller_dark.png index c122b7b11e..5f411af617 100644 Binary files a/dist/icons/controller/applet_pro_controller_dark.png and b/dist/icons/controller/applet_pro_controller_dark.png differ diff --git a/dist/icons/controller/applet_pro_controller_midnight.png b/dist/icons/controller/applet_pro_controller_midnight.png index 622e57fa13..1749c68162 100644 Binary files a/dist/icons/controller/applet_pro_controller_midnight.png and b/dist/icons/controller/applet_pro_controller_midnight.png differ diff --git a/dist/icons/controller/applet_single_joycon_left.png b/dist/icons/controller/applet_single_joycon_left.png index 47c44d43a7..e0ab49e6e6 100644 Binary files a/dist/icons/controller/applet_single_joycon_left.png and b/dist/icons/controller/applet_single_joycon_left.png differ diff --git a/dist/icons/controller/applet_single_joycon_left_dark.png b/dist/icons/controller/applet_single_joycon_left_dark.png index 69530b69ce..0ca0661a63 100644 Binary files a/dist/icons/controller/applet_single_joycon_left_dark.png and b/dist/icons/controller/applet_single_joycon_left_dark.png differ diff --git a/dist/icons/controller/applet_single_joycon_left_dark_disabled.png b/dist/icons/controller/applet_single_joycon_left_dark_disabled.png index cfe4b1475c..d602f99f00 100644 Binary files a/dist/icons/controller/applet_single_joycon_left_dark_disabled.png and b/dist/icons/controller/applet_single_joycon_left_dark_disabled.png differ diff --git a/dist/icons/controller/applet_single_joycon_left_disabled.png b/dist/icons/controller/applet_single_joycon_left_disabled.png index c0102dc20c..8014f80093 100644 Binary files a/dist/icons/controller/applet_single_joycon_left_disabled.png and b/dist/icons/controller/applet_single_joycon_left_disabled.png differ diff --git a/dist/icons/controller/applet_single_joycon_left_midnight.png b/dist/icons/controller/applet_single_joycon_left_midnight.png index 56522bccb3..14fad854a6 100644 Binary files a/dist/icons/controller/applet_single_joycon_left_midnight.png and b/dist/icons/controller/applet_single_joycon_left_midnight.png differ diff --git a/dist/icons/controller/applet_single_joycon_left_midnight_disabled.png b/dist/icons/controller/applet_single_joycon_left_midnight_disabled.png index 62434c188d..29acc86547 100644 Binary files a/dist/icons/controller/applet_single_joycon_left_midnight_disabled.png and b/dist/icons/controller/applet_single_joycon_left_midnight_disabled.png differ diff --git a/dist/icons/controller/applet_single_joycon_right.png b/dist/icons/controller/applet_single_joycon_right.png index b0d4fba906..0270668d04 100644 Binary files a/dist/icons/controller/applet_single_joycon_right.png and b/dist/icons/controller/applet_single_joycon_right.png differ diff --git a/dist/icons/controller/applet_single_joycon_right_dark.png b/dist/icons/controller/applet_single_joycon_right_dark.png index af26cce4bb..5e49cad49e 100644 Binary files a/dist/icons/controller/applet_single_joycon_right_dark.png and b/dist/icons/controller/applet_single_joycon_right_dark.png differ diff --git a/dist/icons/controller/applet_single_joycon_right_dark_disabled.png b/dist/icons/controller/applet_single_joycon_right_dark_disabled.png index b33efab42a..93a7d6cc92 100644 Binary files a/dist/icons/controller/applet_single_joycon_right_dark_disabled.png and b/dist/icons/controller/applet_single_joycon_right_dark_disabled.png differ diff --git a/dist/icons/controller/applet_single_joycon_right_disabled.png b/dist/icons/controller/applet_single_joycon_right_disabled.png index 01ca383226..caee64b747 100644 Binary files a/dist/icons/controller/applet_single_joycon_right_disabled.png and b/dist/icons/controller/applet_single_joycon_right_disabled.png differ diff --git a/dist/icons/controller/applet_single_joycon_right_midnight.png b/dist/icons/controller/applet_single_joycon_right_midnight.png index 5bf70e21e1..dc3be54eef 100644 Binary files a/dist/icons/controller/applet_single_joycon_right_midnight.png and b/dist/icons/controller/applet_single_joycon_right_midnight.png differ diff --git a/dist/icons/controller/applet_single_joycon_right_midnight_disabled.png b/dist/icons/controller/applet_single_joycon_right_midnight_disabled.png index e6693b0270..9b539dcb69 100644 Binary files a/dist/icons/controller/applet_single_joycon_right_midnight_disabled.png and b/dist/icons/controller/applet_single_joycon_right_midnight_disabled.png differ diff --git a/dist/icons/overlay/arrow_left.png b/dist/icons/overlay/arrow_left.png index a5d4fecfe6..00eaf6f279 100644 Binary files a/dist/icons/overlay/arrow_left.png and b/dist/icons/overlay/arrow_left.png differ diff --git a/dist/icons/overlay/arrow_left_dark.png b/dist/icons/overlay/arrow_left_dark.png index f73672a591..c84e33ead4 100644 Binary files a/dist/icons/overlay/arrow_left_dark.png and b/dist/icons/overlay/arrow_left_dark.png differ diff --git a/dist/icons/overlay/arrow_right.png b/dist/icons/overlay/arrow_right.png index e47ee94bd8..44308c5918 100644 Binary files a/dist/icons/overlay/arrow_right.png and b/dist/icons/overlay/arrow_right.png differ diff --git a/dist/icons/overlay/arrow_right_dark.png b/dist/icons/overlay/arrow_right_dark.png index 91cf83d2c5..7a6e2a62e2 100644 Binary files a/dist/icons/overlay/arrow_right_dark.png and b/dist/icons/overlay/arrow_right_dark.png differ diff --git a/dist/icons/overlay/button_A_dark.png b/dist/icons/overlay/button_A_dark.png index d6b5514fab..20f4869f01 100644 Binary files a/dist/icons/overlay/button_A_dark.png and b/dist/icons/overlay/button_A_dark.png differ diff --git a/dist/icons/overlay/button_B_dark.png b/dist/icons/overlay/button_B_dark.png index 3acbeddcd6..981aadb1d4 100644 Binary files a/dist/icons/overlay/button_B_dark.png and b/dist/icons/overlay/button_B_dark.png differ diff --git a/dist/icons/overlay/button_L.png b/dist/icons/overlay/button_L.png index 77838369ee..5acf8a242e 100644 Binary files a/dist/icons/overlay/button_L.png and b/dist/icons/overlay/button_L.png differ diff --git a/dist/icons/overlay/button_L_dark.png b/dist/icons/overlay/button_L_dark.png index c96a5e8681..59a08da1bb 100644 Binary files a/dist/icons/overlay/button_L_dark.png and b/dist/icons/overlay/button_L_dark.png differ diff --git a/dist/icons/overlay/button_R.png b/dist/icons/overlay/button_R.png index 4e55539544..f4b97b23fb 100644 Binary files a/dist/icons/overlay/button_R.png and b/dist/icons/overlay/button_R.png differ diff --git a/dist/icons/overlay/button_R_dark.png b/dist/icons/overlay/button_R_dark.png index ed13199c4a..c66203ee9b 100644 Binary files a/dist/icons/overlay/button_R_dark.png and b/dist/icons/overlay/button_R_dark.png differ diff --git a/dist/icons/overlay/button_X_dark.png b/dist/icons/overlay/button_X_dark.png index b2c83d0c11..4c80f373bf 100644 Binary files a/dist/icons/overlay/button_X_dark.png and b/dist/icons/overlay/button_X_dark.png differ diff --git a/dist/icons/overlay/button_Y_dark.png b/dist/icons/overlay/button_Y_dark.png index 0f3e4df25f..661eb5b43d 100644 Binary files a/dist/icons/overlay/button_Y_dark.png and b/dist/icons/overlay/button_Y_dark.png differ diff --git a/dist/icons/overlay/button_minus.png b/dist/icons/overlay/button_minus.png index 7b315fe79d..10ec120e95 100644 Binary files a/dist/icons/overlay/button_minus.png and b/dist/icons/overlay/button_minus.png differ diff --git a/dist/icons/overlay/button_minus_dark.png b/dist/icons/overlay/button_minus_dark.png index 6dfcdc1b5f..7d33559b76 100644 Binary files a/dist/icons/overlay/button_minus_dark.png and b/dist/icons/overlay/button_minus_dark.png differ diff --git a/dist/icons/overlay/button_plus.png b/dist/icons/overlay/button_plus.png index 4d8090d7db..fa625fd178 100644 Binary files a/dist/icons/overlay/button_plus.png and b/dist/icons/overlay/button_plus.png differ diff --git a/dist/icons/overlay/button_plus_dark.png b/dist/icons/overlay/button_plus_dark.png index abe8b9c95c..3faf46e033 100644 Binary files a/dist/icons/overlay/button_plus_dark.png and b/dist/icons/overlay/button_plus_dark.png differ diff --git a/dist/icons/overlay/button_press_stick_dark.png b/dist/icons/overlay/button_press_stick_dark.png index 757d0ab292..4953738737 100644 Binary files a/dist/icons/overlay/button_press_stick_dark.png and b/dist/icons/overlay/button_press_stick_dark.png differ diff --git a/dist/icons/overlay/controller_single_joycon_left_a.png b/dist/icons/overlay/controller_single_joycon_left_a.png index e0f5c2ad4f..e4dac234a2 100644 Binary files a/dist/icons/overlay/controller_single_joycon_left_a.png and b/dist/icons/overlay/controller_single_joycon_left_a.png differ diff --git a/dist/icons/overlay/controller_single_joycon_left_a_dark.png b/dist/icons/overlay/controller_single_joycon_left_a_dark.png index 53e04781e6..fa36ee03f9 100644 Binary files a/dist/icons/overlay/controller_single_joycon_left_a_dark.png and b/dist/icons/overlay/controller_single_joycon_left_a_dark.png differ diff --git a/dist/icons/overlay/controller_single_joycon_left_b.png b/dist/icons/overlay/controller_single_joycon_left_b.png index 7429450a33..bafa4847d4 100644 Binary files a/dist/icons/overlay/controller_single_joycon_left_b.png and b/dist/icons/overlay/controller_single_joycon_left_b.png differ diff --git a/dist/icons/overlay/controller_single_joycon_left_b_dark.png b/dist/icons/overlay/controller_single_joycon_left_b_dark.png index 3bd97a8eb6..df06dc4ec6 100644 Binary files a/dist/icons/overlay/controller_single_joycon_left_b_dark.png and b/dist/icons/overlay/controller_single_joycon_left_b_dark.png differ diff --git a/dist/icons/overlay/controller_single_joycon_left_x.png b/dist/icons/overlay/controller_single_joycon_left_x.png index 4615172a33..27a5310424 100644 Binary files a/dist/icons/overlay/controller_single_joycon_left_x.png and b/dist/icons/overlay/controller_single_joycon_left_x.png differ diff --git a/dist/icons/overlay/controller_single_joycon_left_x_dark.png b/dist/icons/overlay/controller_single_joycon_left_x_dark.png index 119e3091af..4074a22f06 100644 Binary files a/dist/icons/overlay/controller_single_joycon_left_x_dark.png and b/dist/icons/overlay/controller_single_joycon_left_x_dark.png differ diff --git a/dist/icons/overlay/controller_single_joycon_left_y.png b/dist/icons/overlay/controller_single_joycon_left_y.png index 24421d8b91..6f53699c50 100644 Binary files a/dist/icons/overlay/controller_single_joycon_left_y.png and b/dist/icons/overlay/controller_single_joycon_left_y.png differ diff --git a/dist/icons/overlay/osk_button_B.png b/dist/icons/overlay/osk_button_B.png index 2664b5923b..b572d5d7b9 100644 Binary files a/dist/icons/overlay/osk_button_B.png and b/dist/icons/overlay/osk_button_B.png differ diff --git a/dist/icons/overlay/osk_button_B_dark.png b/dist/icons/overlay/osk_button_B_dark.png index 1bd3745719..c92c41887c 100644 Binary files a/dist/icons/overlay/osk_button_B_dark.png and b/dist/icons/overlay/osk_button_B_dark.png differ diff --git a/dist/icons/overlay/osk_button_B_dark_disabled.png b/dist/icons/overlay/osk_button_B_dark_disabled.png index 3b88e393cb..df992e6d94 100644 Binary files a/dist/icons/overlay/osk_button_B_dark_disabled.png and b/dist/icons/overlay/osk_button_B_dark_disabled.png differ diff --git a/dist/icons/overlay/osk_button_B_disabled.png b/dist/icons/overlay/osk_button_B_disabled.png index 0f35cd8f26..ead1fa0423 100644 Binary files a/dist/icons/overlay/osk_button_B_disabled.png and b/dist/icons/overlay/osk_button_B_disabled.png differ diff --git a/dist/icons/overlay/osk_button_Y.png b/dist/icons/overlay/osk_button_Y.png index 2cd1934818..0a10b01b64 100644 Binary files a/dist/icons/overlay/osk_button_Y.png and b/dist/icons/overlay/osk_button_Y.png differ diff --git a/dist/icons/overlay/osk_button_Y_dark.png b/dist/icons/overlay/osk_button_Y_dark.png index 0cce567d3f..71e578002a 100644 Binary files a/dist/icons/overlay/osk_button_Y_dark.png and b/dist/icons/overlay/osk_button_Y_dark.png differ diff --git a/dist/icons/overlay/osk_button_Y_dark_disabled.png b/dist/icons/overlay/osk_button_Y_dark_disabled.png index de619efa32..279cde5418 100644 Binary files a/dist/icons/overlay/osk_button_Y_dark_disabled.png and b/dist/icons/overlay/osk_button_Y_dark_disabled.png differ diff --git a/dist/icons/overlay/osk_button_Y_disabled.png b/dist/icons/overlay/osk_button_Y_disabled.png index 8d607bc121..6cb53245ad 100644 Binary files a/dist/icons/overlay/osk_button_Y_disabled.png and b/dist/icons/overlay/osk_button_Y_disabled.png differ diff --git a/dist/icons/overlay/osk_button_plus.png b/dist/icons/overlay/osk_button_plus.png index 9f97874192..b87bc71161 100644 Binary files a/dist/icons/overlay/osk_button_plus.png and b/dist/icons/overlay/osk_button_plus.png differ diff --git a/dist/icons/overlay/osk_button_plus_dark.png b/dist/icons/overlay/osk_button_plus_dark.png index dbe7b0c66c..7701651085 100644 Binary files a/dist/icons/overlay/osk_button_plus_dark.png and b/dist/icons/overlay/osk_button_plus_dark.png differ diff --git a/dist/icons/overlay/osk_button_plus_dark_disabled.png b/dist/icons/overlay/osk_button_plus_dark_disabled.png index a79af6501c..fe53a66e71 100644 Binary files a/dist/icons/overlay/osk_button_plus_dark_disabled.png and b/dist/icons/overlay/osk_button_plus_dark_disabled.png differ diff --git a/dist/icons/overlay/osk_button_plus_disabled.png b/dist/icons/overlay/osk_button_plus_disabled.png index 52ace8ecae..72ddf6e824 100644 Binary files a/dist/icons/overlay/osk_button_plus_disabled.png and b/dist/icons/overlay/osk_button_plus_disabled.png differ diff --git a/dist/icons/overlay/osk_button_shift_lock_off.png b/dist/icons/overlay/osk_button_shift_lock_off.png index b506f456fc..91259b2b86 100644 Binary files a/dist/icons/overlay/osk_button_shift_lock_off.png and b/dist/icons/overlay/osk_button_shift_lock_off.png differ diff --git a/dist/icons/overlay/osk_button_shift_lock_on.png b/dist/icons/overlay/osk_button_shift_lock_on.png index eaa4e98ed0..48003eb77a 100644 Binary files a/dist/icons/overlay/osk_button_shift_lock_on.png and b/dist/icons/overlay/osk_button_shift_lock_on.png differ diff --git a/dist/icons/overlay/osk_button_shift_on_dark.png b/dist/icons/overlay/osk_button_shift_on_dark.png index 58e0d9cf41..484d74e302 100644 Binary files a/dist/icons/overlay/osk_button_shift_on_dark.png and b/dist/icons/overlay/osk_button_shift_on_dark.png differ diff --git a/dist/qt_themes/colorful/icons/16x16/checked.png b/dist/qt_themes/colorful/icons/16x16/checked.png index b9e64e9e08..0694e3d405 100644 Binary files a/dist/qt_themes/colorful/icons/16x16/checked.png and b/dist/qt_themes/colorful/icons/16x16/checked.png differ diff --git a/dist/qt_themes/colorful/icons/16x16/info.png b/dist/qt_themes/colorful/icons/16x16/info.png index 8b9330f4c8..e7ffc60830 100644 Binary files a/dist/qt_themes/colorful/icons/16x16/info.png and b/dist/qt_themes/colorful/icons/16x16/info.png differ diff --git a/dist/qt_themes/colorful/icons/256x256/plus_folder.png b/dist/qt_themes/colorful/icons/256x256/plus_folder.png index 760fe6245e..31471e3a2a 100644 Binary files a/dist/qt_themes/colorful/icons/256x256/plus_folder.png and b/dist/qt_themes/colorful/icons/256x256/plus_folder.png differ diff --git a/dist/qt_themes/colorful/icons/48x48/chip.png b/dist/qt_themes/colorful/icons/48x48/chip.png index 6fa1589995..42b016592e 100644 Binary files a/dist/qt_themes/colorful/icons/48x48/chip.png and b/dist/qt_themes/colorful/icons/48x48/chip.png differ diff --git a/dist/qt_themes/colorful/icons/48x48/folder.png b/dist/qt_themes/colorful/icons/48x48/folder.png index 498de4c629..f4d459b053 100644 Binary files a/dist/qt_themes/colorful/icons/48x48/folder.png and b/dist/qt_themes/colorful/icons/48x48/folder.png differ diff --git a/dist/qt_themes/colorful/icons/48x48/list-add.png b/dist/qt_themes/colorful/icons/48x48/list-add.png index 74e4882aae..27a6f47c97 100644 Binary files a/dist/qt_themes/colorful/icons/48x48/list-add.png and b/dist/qt_themes/colorful/icons/48x48/list-add.png differ diff --git a/dist/qt_themes/colorful/icons/48x48/sd_card.png b/dist/qt_themes/colorful/icons/48x48/sd_card.png index 652d61bc32..fcc4c2a5fa 100644 Binary files a/dist/qt_themes/colorful/icons/48x48/sd_card.png and b/dist/qt_themes/colorful/icons/48x48/sd_card.png differ diff --git a/dist/qt_themes/colorful/icons/48x48/star.png b/dist/qt_themes/colorful/icons/48x48/star.png index 19d55a0a80..2ff57696d4 100644 Binary files a/dist/qt_themes/colorful/icons/48x48/star.png and b/dist/qt_themes/colorful/icons/48x48/star.png differ diff --git a/dist/qt_themes/default/icons/256x256/eden.png b/dist/qt_themes/default/icons/256x256/eden.png index 32a2eebe8b..c0d7d8e37c 100644 Binary files a/dist/qt_themes/default/icons/256x256/eden.png and b/dist/qt_themes/default/icons/256x256/eden.png differ diff --git a/dist/qt_themes/default/icons/256x256/eden_named.png b/dist/qt_themes/default/icons/256x256/eden_named.png index c77d32c380..e4944d624d 100644 Binary files a/dist/qt_themes/default/icons/256x256/eden_named.png and b/dist/qt_themes/default/icons/256x256/eden_named.png differ diff --git a/dist/qt_themes/default/icons/48x48/bad_folder.png b/dist/qt_themes/default/icons/48x48/bad_folder.png index 364ec646f6..b0cc440b84 100644 Binary files a/dist/qt_themes/default/icons/48x48/bad_folder.png and b/dist/qt_themes/default/icons/48x48/bad_folder.png differ diff --git a/dist/qt_themes/default/icons/48x48/list-add.png b/dist/qt_themes/default/icons/48x48/list-add.png index fd8a06132c..ce34ce5522 100644 Binary files a/dist/qt_themes/default/icons/48x48/list-add.png and b/dist/qt_themes/default/icons/48x48/list-add.png differ diff --git a/dist/qt_themes/default/icons/48x48/sd_card.png b/dist/qt_themes/default/icons/48x48/sd_card.png index 6bcb7f6b1d..083566404b 100644 Binary files a/dist/qt_themes/default/icons/48x48/sd_card.png and b/dist/qt_themes/default/icons/48x48/sd_card.png differ diff --git a/dist/qt_themes/qdarkstyle/icons/16x16/lock.png b/dist/qt_themes/qdarkstyle/icons/16x16/lock.png index 7e63927b2c..d187110ab3 100644 Binary files a/dist/qt_themes/qdarkstyle/icons/16x16/lock.png and b/dist/qt_themes/qdarkstyle/icons/16x16/lock.png differ diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/bad_folder.png b/dist/qt_themes/qdarkstyle/icons/48x48/bad_folder.png index 245f96c7ba..42fee9ced2 100644 Binary files a/dist/qt_themes/qdarkstyle/icons/48x48/bad_folder.png and b/dist/qt_themes/qdarkstyle/icons/48x48/bad_folder.png differ diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/chip.png b/dist/qt_themes/qdarkstyle/icons/48x48/chip.png index db0cadac13..9a727e7451 100644 Binary files a/dist/qt_themes/qdarkstyle/icons/48x48/chip.png and b/dist/qt_themes/qdarkstyle/icons/48x48/chip.png differ diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/list-add.png b/dist/qt_themes/qdarkstyle/icons/48x48/list-add.png index 8fbe780116..fdc39d6ba4 100644 Binary files a/dist/qt_themes/qdarkstyle/icons/48x48/list-add.png and b/dist/qt_themes/qdarkstyle/icons/48x48/list-add.png differ diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/sd_card.png b/dist/qt_themes/qdarkstyle/icons/48x48/sd_card.png index 15e5e40245..d03d13a379 100644 Binary files a/dist/qt_themes/qdarkstyle/icons/48x48/sd_card.png and b/dist/qt_themes/qdarkstyle/icons/48x48/sd_card.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/Hmovetoolbar.png b/dist/qt_themes/qdarkstyle/rc/Hmovetoolbar.png index cead99ed10..a0782ef97a 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/Hmovetoolbar.png and b/dist/qt_themes/qdarkstyle/rc/Hmovetoolbar.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/Vmovetoolbar.png b/dist/qt_themes/qdarkstyle/rc/Vmovetoolbar.png index 512edcecd6..25db314c17 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/Vmovetoolbar.png and b/dist/qt_themes/qdarkstyle/rc/Vmovetoolbar.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png index 830cfee656..56e8c49849 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png and b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png index cb63cc2fac..8ddbdabd4c 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png and b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png index 671be273b0..6111a28fc9 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png and b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked.png b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked.png index 2159aca9a1..166f5aa049 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked.png and b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_disabled.png b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_disabled.png index ade721e81b..789a03b356 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_disabled.png and b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_focus.png b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_focus.png index e4258cc470..4b6981b268 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_focus.png and b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_focus.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/close-hover.png b/dist/qt_themes/qdarkstyle/rc/close-hover.png index 657943a668..afddf97a79 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/close-hover.png and b/dist/qt_themes/qdarkstyle/rc/close-hover.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/close-pressed.png b/dist/qt_themes/qdarkstyle/rc/close-pressed.png index 937d005983..605ac0e6bf 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/close-pressed.png and b/dist/qt_themes/qdarkstyle/rc/close-pressed.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/close.png b/dist/qt_themes/qdarkstyle/rc/close.png index bc0f576109..3f843b8bcc 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/close.png and b/dist/qt_themes/qdarkstyle/rc/close.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/radio_checked.png b/dist/qt_themes/qdarkstyle/rc/radio_checked.png index 235e6b0ba7..edaf3f2228 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/radio_checked.png and b/dist/qt_themes/qdarkstyle/rc/radio_checked.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/radio_checked_disabled.png b/dist/qt_themes/qdarkstyle/rc/radio_checked_disabled.png index bf0051ede5..f2a4ce1df3 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/radio_checked_disabled.png and b/dist/qt_themes/qdarkstyle/rc/radio_checked_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/radio_checked_focus.png b/dist/qt_themes/qdarkstyle/rc/radio_checked_focus.png index 700c6b525e..d6b540408d 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/radio_checked_focus.png and b/dist/qt_themes/qdarkstyle/rc/radio_checked_focus.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/radio_unchecked.png b/dist/qt_themes/qdarkstyle/rc/radio_unchecked.png index 9a4def65c6..f69d92df09 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/radio_unchecked.png and b/dist/qt_themes/qdarkstyle/rc/radio_unchecked.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/radio_unchecked_disabled.png b/dist/qt_themes/qdarkstyle/rc/radio_unchecked_disabled.png index 6ece890e75..c3f29da053 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/radio_unchecked_disabled.png and b/dist/qt_themes/qdarkstyle/rc/radio_unchecked_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/radio_unchecked_focus.png b/dist/qt_themes/qdarkstyle/rc/radio_unchecked_focus.png index 564e022d33..81323f4150 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/radio_unchecked_focus.png and b/dist/qt_themes/qdarkstyle/rc/radio_unchecked_focus.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-end.png b/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-end.png index cb5d3b51f8..a50d541878 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-end.png and b/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-end.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/stylesheet-vline.png b/dist/qt_themes/qdarkstyle/rc/stylesheet-vline.png index 87536cce16..baf9bd8437 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/stylesheet-vline.png and b/dist/qt_themes/qdarkstyle/rc/stylesheet-vline.png differ diff --git a/dist/qt_themes/qdarkstyle/rc/undock.png b/dist/qt_themes/qdarkstyle/rc/undock.png index 88691d7795..b7975a2b89 100644 Binary files a/dist/qt_themes/qdarkstyle/rc/undock.png and b/dist/qt_themes/qdarkstyle/rc/undock.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hmovetoolbar.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hmovetoolbar.png index cead99ed10..a0782ef97a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hmovetoolbar.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hmovetoolbar.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vmovetoolbar.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vmovetoolbar.png index 512edcecd6..25db314c17 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vmovetoolbar.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vmovetoolbar.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down.png index c4e6894ba9..76232456f6 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down@2x.png index bb8cbed0d6..4238e31d73 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled.png index aa1d06c084..f286fb7605 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled@2x.png index 86bf434b84..924f9951f9 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus.png index 1c42ee8f6a..310cdf0ae3 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus@2x.png index 7374637c5e..c1fa23192d 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed.png index 8139ee3e83..87cef99e61 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed@2x.png index 5e9d225ff6..47b87f55aa 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left.png index ef929fdf04..e71a93cf0e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left@2x.png index c8923d6f4c..37362f331e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled.png index 9c69561a7f..67cbd8c203 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled@2x.png index e521143121..c33c0e50a4 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus.png index a1f0704550..58daf567b5 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus@2x.png index c4267e856b..59d58ab753 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed.png index bd706cbdd6..54ab848e87 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed@2x.png index 341b2e5410..a61de7f5ff 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right.png index 4f33885057..649da834ba 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right@2x.png index 94b2609658..a16fe6d1ee 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled.png index 0fbc6b04c5..3d7f3c080e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled@2x.png index 8e9272a5b9..723de13ce1 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus.png index 7649409451..a0c45d83b0 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus@2x.png index 6d52b5fa37..a34b45b35a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed.png index a5f04522a6..a6bdecbf28 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed@2x.png index 6f6a8130c1..b650e3271b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up.png index 61d7574a4d..751c95411b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up@2x.png index d711fae16a..b5375c7cb2 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled.png index 18e8ecd8d3..fde7ba3f01 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled@2x.png index fb4defb522..c09291ab13 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus.png index a7acd9b668..3dadfe4220 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus@2x.png index 9cd982a1d4..0ed72401e7 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed.png index 390a80e21b..fac7fdb9e8 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed@2x.png index dd352cff39..70689f752a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon.png index 37a6158cc4..492cc2724e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon@2x.png index e6e5cb9160..19fbf8d5af 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled.png index 37a6158cc4..492cc2724e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled@2x.png index e6e5cb9160..19fbf8d5af 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus.png index 37a6158cc4..492cc2724e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus@2x.png index e6e5cb9160..19fbf8d5af 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed.png index 37a6158cc4..492cc2724e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed@2x.png index e6e5cb9160..19fbf8d5af 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed.png index 53e2c51f57..df389d19fa 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed@2x.png index 06cdefa5f1..606f905309 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled.png index 5106a1438b..43d7b70185 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled@2x.png index 180bae9e61..86dbc5bc69 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus.png index c227f9f71c..c530d0ee3c 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus@2x.png index ad23d0d332..954592f027 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed.png index 90845a81fa..4e7831ed41 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed@2x.png index 60aaeb7fb3..61b924e9f2 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end.png index 08b5559b21..4372be7a06 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end@2x.png index ae6dbe9913..a5c0485530 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled.png index 027a8894a6..e748e2e728 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled@2x.png index 43c1b0c769..fe12891a7e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus.png index fdb3160bb8..7a283b46b9 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus@2x.png index 3ca8904498..c1a173e418 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed.png index 1c2432dd4b..12afd7b17a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed@2x.png index af0f8fa5a9..cb781ab4dc 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line.png index a3a564e447..5bdb43fd41 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line@2x.png index 1dbf71fc72..b5dced34e2 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled.png index ecc7e6d932..d0ad0e07ec 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled@2x.png index adc6446c97..4bd61d377b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus.png index 0037f175ad..08ec6d12fe 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus@2x.png index cb257a9143..53a3164aa3 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed.png index 2d08565278..4d1e85a178 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed@2x.png index 803708fb45..102b287c28 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more.png index 31b6cee873..e676e28e46 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more@2x.png index f1f7a67f16..7bf47a36af 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled.png index d4b6049055..f9b714eba9 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled@2x.png index 3ef752108d..212b56ec5d 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus.png index 943c13d0b2..8a74cad89c 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus@2x.png index 9f53ef1fa5..6b3c2b8fbb 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed.png index 9037ed3b3f..dafad3dcf3 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed@2x.png index 675d52c761..b1a5d22842 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open.png index 0861d0bc76..b9e2719214 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open@2x.png index 8850f7367b..541786551f 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled.png index b6c80243b6..0f2e2e6cbf 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled@2x.png index 15ce9f2650..cbd1f2823f 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus.png index eadb0962a5..c7f8089abb 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus@2x.png index 7dfcbbe8ab..5d08b01c8c 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed.png index 2b22e8d08d..361b1bff04 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed@2x.png index 269a0cbee8..bde4b37e8d 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked.png index e7ed080810..2a698618b5 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked@2x.png index 35f2ade589..eebc45b172 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png index 512b0a3e4c..414e315d04 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled@2x.png index 557383ec88..fc7973ccb6 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png index 0b90412f29..1a9894a616 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus@2x.png index 7aee03cbb2..d2f515b4cd 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed.png index 3d4c869b79..8b5d23177b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed@2x.png index bfbc14b94d..0279f750f5 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png index c21ab99bfb..158038aa55 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate@2x.png index 2fc29cee62..cf63ceab7f 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled.png index 1d3c214923..b8602ab3c7 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled@2x.png index bb8e7a7477..0aecf329a5 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png index 13ca4a7a40..2f3a5c098d 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus@2x.png index 3907eb8d46..3f5e08f884 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed.png index 12f83ceba3..34fc686b9c 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed@2x.png index 5ff4f66298..344d2fe47b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked.png index e2da452faa..f569143fe8 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked@2x.png index 3732d5406e..883cd95814 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png index c2e30c690a..de85ec5e87 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled@2x.png index c4bddb6eb1..eac24e56b7 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png index c57f04d9f8..ee8eb5650a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus@2x.png index 1776ad0486..6421b2f75c 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed.png index be41236e1b..54f7917304 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed@2x.png index b1ad7c72fe..136d9f6b77 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-hover.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-hover.png index 657943a668..afddf97a79 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-hover.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-hover.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-pressed.png index 937d005983..605ac0e6bf 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close.png index bc0f576109..3f843b8bcc 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal@2x.png index c229ac963d..41a3a1ef0a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled@2x.png index a4713c565e..12f07fbb9d 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus@2x.png index 84397efdbf..0c26376506 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed@2x.png index 140552e4ff..a6aeed8754 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical.png index a3a564e447..5bdb43fd41 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical@2x.png index 1dbf71fc72..b5dced34e2 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled.png index ecc7e6d932..d0ad0e07ec 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled@2x.png index adc6446c97..4bd61d377b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus.png index 0037f175ad..08ec6d12fe 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus@2x.png index cb257a9143..53a3164aa3 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed.png index 2d08565278..4d1e85a178 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed@2x.png index 803708fb45..102b287c28 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked.png index 6f1fd6ca69..4e5cc4445b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked@2x.png index 228ffdbf21..94f0939ba1 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled.png index 27788530d1..74fd0faae7 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled@2x.png index 930bfaf70d..ee6fab7c00 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus.png index ca8e8bc9a7..183930162f 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus@2x.png index aa0f1152be..4fd15f7f7d 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed.png index 6e391a0ff3..24ecf6781d 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed@2x.png index 0512731ae5..f816f32387 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked.png index 763306bdcc..391acb69e8 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked@2x.png index 28b6a07842..8bae28f3fb 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png index fc0b12f781..300d86068a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled@2x.png index d31f2b4b9d..16d595ccee 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png index 9c87b01e49..edd78cb43b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus@2x.png index 4b4c7321dd..7ab8c79fba 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed.png index 709e316336..9046c4b764 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed@2x.png index b014de5f01..a6c3cd9b0f 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png index cb5d3b51f8..a50d541878 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-vline.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-vline.png index 87536cce16..baf9bd8437 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-vline.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-vline.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal.png index 012ea2dfb1..fd0cf328b4 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal@2x.png index 520c34f98d..0b07144fdd 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled.png index 1f91df98fd..bba0cf74b7 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled@2x.png index 738008f92e..3162df8c18 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus.png index 999b3c7d82..fd021e97ec 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus@2x.png index f8e40b7d19..d9aae5ecdd 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed.png index c31b69deb6..1e170e9a73 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed@2x.png index 2f4cb41c7e..bedb94a89e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical@2x.png index 90a5caee37..ab7e0a52f1 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled.png index 2d240edb52..e2e2afce86 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled@2x.png index fd1df30f11..7eccab8513 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus.png index 58cda1f805..82b2482ef5 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus@2x.png index 9222b4fd8e..66504f977f 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed.png index e7d6419261..013bc2d3f0 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed@2x.png index 9c438faf42..6ad8b47f16 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal.png index 3c0acbdcc0..71f79e7c18 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal@2x.png index fb4e24c88f..4049b34530 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled.png index 32f7e8ca6f..eb5944bba0 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled@2x.png index f7bec188bb..12df69aad9 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus.png index 91c19d65c3..d05adc4a58 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus@2x.png index c4829918d6..70556d96c7 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed.png index 7a7f917374..1ade9619f5 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed@2x.png index d65773b487..1c2f542ecf 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical@2x.png index fe97c0de36..4cced09e9b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled@2x.png index 7acc6d33ea..7975862422 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus.png index 6e3c121433..a0c764d010 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus@2x.png index cac3a56c28..1088091c5e 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed.png index b777784b88..dd8529c4b6 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed@2x.png index 7ed878fd3f..11007b6fca 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/undock.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/undock.png index 88691d7795..b7975a2b89 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/undock.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/undock.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close.png index 6f55c3ae77..72af3edd36 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close@2x.png index ff644f2e81..41a82e7a5b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled.png index 22694e31dd..6e5f534d55 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled@2x.png index ebc97db707..d6d3a6127c 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus.png index f017eda31f..23b0129b85 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus@2x.png index 5a354d7963..f1f2a8271a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed.png index 04b922dd08..a7924de6f9 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed@2x.png index 58c0bf592c..92e7a86e2b 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip.png index 0528049bbd..a5b556fefa 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip@2x.png index 1ca1b073c9..e2a91a6b57 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled.png index 15f55c0560..509c335897 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled@2x.png index 33a4588e8e..cb18102c61 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus.png index 06e76c31f2..ef4abe6215 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus@2x.png index 58c2d06e4f..f4b7479e71 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed.png index b3a566cdb9..9a365bfc3f 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed@2x.png index e9da940497..e299648d08 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize.png index f609816153..6f85fb6489 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize@2x.png index 30f728f022..2a53538b34 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled.png index 29db1c9b18..e498972494 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled@2x.png index 1572ca2fea..063c8f635d 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus.png index cb592f5988..561039af1a 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus@2x.png index 6f6465169d..1f0c2e1b90 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed.png index 6962440ace..c1cb9fcb77 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed@2x.png index cb028272b8..588baf4336 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock.png index 616da991a5..70c4dbcad5 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock@2x.png index 511036bf2d..db805412b5 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled.png index a2b3d25b23..0156d0be80 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled@2x.png index 638ec8104a..ce1909f2c4 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus.png index ae6dc4a606..746a4d1909 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus@2x.png index d06dd1eac8..603d3966cc 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus@2x.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed.png index e9142ded2c..0b6fc91950 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed.png differ diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed@2x.png index a597420f36..736707afc1 100644 Binary files a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed@2x.png and b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed@2x.png differ diff --git a/docs/Deps.md b/docs/Deps.md index cfc6f0365b..573d1fe14a 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -4,8 +4,8 @@ To build Eden, you MUST have a C++ compiler. * On Linux, this is usually [GCC](https://gcc.gnu.org/) 11+ or [Clang](https://clang.llvm.org/) v14+ - GCC 12 also requires Clang 14+ * On Windows, this is either: - - **[MSVC](https://visualstudio.microsoft.com/downloads/)**, - * *A convenience script to install the **minimal** version (Visual Build Tools) is provided in `.ci/windows/install-msvc.ps1`* + - **[MSVC](https://visualstudio.microsoft.com/downloads/)** (you should select *Community* option), + * *A convenience script to install the Visual Community Studio 2022 with necessary tools is provided in `.ci/windows/install-msvc.ps1`* - clang-cl - can be downloaded from the MSVC installer, - or **[MSYS2](https://www.msys2.org)** * On macOS, this is Apple Clang @@ -101,7 +101,7 @@ sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glsl Ubuntu, Debian, Mint Linux ```sh -sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev +sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2t64 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev vulkan-utility-libraries-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev ``` * Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. @@ -211,4 +211,4 @@ Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/l ## All Done -You may now return to the **[root build guide](Build.md)**. \ No newline at end of file +You may now return to the **[root build guide](Build.md)**. diff --git a/docs/Development.md b/docs/Development.md index d170818d10..c223409243 100644 --- a/docs/Development.md +++ b/docs/Development.md @@ -36,6 +36,28 @@ Pull requests are only to be merged by core developers when properly tested and - Maintainers are permitted to change namespaces at will. - Commits within PRs are not required to be namespaced, but it is highly recommended. +## Adding new settings + +When adding new settings, use `tr("Setting:")` if the setting is meant to be a field, otherwise use `tr("Setting")` if the setting is meant to be a Yes/No or checkmark type of setting, see [this short style guide](https://learn.microsoft.com/en-us/style-guide/punctuation/colons#in-ui). + +- The majority of software must work with the default option selected for such setting. Unless the setting significantly degrades performance. +- Debug settings must never be turned on by default. +- Provide reasonable bounds (for example, a setting controlling the amount of VRAM should never be 0). +- The description of the setting must be short and concise, if the setting "does a lot of things" consider splitting the setting into multiple if possible. +- Try to avoid excessive/redundant explainations "recommended for most users and games" can just be "(recommended)". +- Try to not write "slow/fast" options unless it clearly degrades/increases performance for a given case, as most options may modify behaviour that result in different metrics accross different systems. If for example the option is an "accuracy" option, writing "High" is sufficient to imply "Slow". No need to write "High (Slow)". + +Some examples: +- "[...] negatively affecting image quality", "[...] degrading image quality": Same wording but with less filler. +- "[...] this may cause some glitches or crashes in some games", "[...] this may cause soft-crashes": Crashes implies there may be glitches (as crashes are technically a form of a fatal glitch). The entire sentence is structured as "may cause [...] on some games", which is redundant, because "may cause [...] in games" has the same semantic meaning ("may" is a chance that it will occur on "some" given set). +- "FIFO Relaxed is similar to FIFO [...]", "FIFO Relaxed [...]": The name already implies similarity. +- "[...] but may also reduce performance in some cases", "[...] but may degrade performance": Again, "some cases" and "may" implies there is a probability. +- "[...] it can [...] in some cases", "[...] it can [...]": Implied probability. + +Before adding a new setting, consider: +- Does the piece of code that the setting pertains to, make a significant difference if it's on/off? +- Can it be auto-detected? + # IDE setup ## VSCode @@ -69,6 +91,18 @@ cmake --build /tmp/ramdisk -- -j32 sudo umount /tmp/ramdisk ``` +# Assets and large files + +A general rule of thumb, before uploading files: +- PNG files: Use [optipng](https://web.archive.org/web/20240325055059/https://optipng.sourceforge.net/). +- SVG files: Use [svgo](https://github.com/svg/svgo). + +May not be used but worth mentioning nonethless: +- OGG files: Use [OptiVorbis](https://github.com/OptiVorbis/OptiVorbis). +- Video files: Use ffmpeg, preferably re-encode as AV1. + +# Debugging + ## Debugging (host code) Ignoring SIGSEGV when debugging in host: diff --git a/docs/Options.md b/docs/Options.md index d19aab63f6..3dd84ea645 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -31,7 +31,7 @@ Notes: * Currently, build fails without this - `YUZU_USE_FASTER_LD` (ON) Check if a faster linker is available * Only available on UNIX -- `USE_SYSTEM_MOLTENVK` (OFF, macOS only) Use the system MoltenVK lib (instead of the bundled one) +- `YUZU_USE_BUNDLED_MOLTENVK` (ON, macOS only) Download bundled MoltenVK lib) - `YUZU_TZDB_PATH` (string) Path to a pre-downloaded timezone database (useful for nixOS) - `ENABLE_OPENSSL` (ON for Linux and *BSD) Enable OpenSSL backend for the ssl service * Always enabled if the web service is enabled diff --git a/docs/img/creator-1.png b/docs/img/creator-1.png index 14d679cfbb..3e43ee7eca 100644 Binary files a/docs/img/creator-1.png and b/docs/img/creator-1.png differ diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 283da76743..dcafc8f97d 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -10,7 +10,7 @@ "repo": "eden-emulator/sirit", "sha": "db1f1e8ab5", "hash": "73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05", - "find_args": "MODULE", + "find_args": "CONFIG", "options": [ "SIRIT_USE_SYSTEM_SPIRV_HEADERS ON" ] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 184b049d06..88470c4c42 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -141,7 +141,7 @@ else() -Wno-missing-field-initializers ) - if (CXX_CLANG OR CXX_ICC) # Clang or AppleClang + if (CXX_CLANG OR CXX_ICC OR CXX_APPLE) # Clang, AppleClang, or Intel C++ if (NOT MSVC) add_compile_options( -Werror=shadow-uncaptured-local diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index c76b5e7162..e8d8141711 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -59,7 +59,7 @@ android { defaultConfig { // TODO If this is ever modified, change application_id in strings.xml applicationId = "dev.eden.eden_emulator" - minSdk = 30 + minSdk = 28 targetSdk = 36 versionName = getGitVersion() @@ -175,12 +175,10 @@ android { "-DYUZU_USE_CPM=ON", "-DCPMUTIL_FORCE_BUNDLED=ON", "-DYUZU_USE_BUNDLED_FFMPEG=ON", - "-DYUZU_ENABLE_LTO=ON", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", "-DBUILD_TESTING=OFF", "-DYUZU_TESTS=OFF", - "-DDYNARMIC_TESTS=OFF", - "-DDYNARMIC_ENABLE_LTO=ON" + "-DDYNARMIC_TESTS=OFF" ) abiFilters("arm64-v8a") diff --git a/src/android/app/src/main/AndroidManifest.xml b/src/android/app/src/main/AndroidManifest.xml index d31deaa355..45c5dfef8c 100644 --- a/src/android/app/src/main/AndroidManifest.xml +++ b/src/android/app/src/main/AndroidManifest.xml @@ -27,6 +27,8 @@ SPDX-License-Identifier: GPL-3.0-or-later + + @@ -93,6 +95,10 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + + + when (event.action) { + MotionEvent.ACTION_DOWN -> { + touchDownTime = System.currentTimeMillis() + // show overlay immediately on touch and cancel timer + if (!emulationViewModel.drawerOpen.value) { + fragment.handler.removeCallbacksAndMessages(null) + fragment.showOverlay() + } + } + MotionEvent.ACTION_UP -> { + if (!emulationViewModel.drawerOpen.value) { + val touchDuration = System.currentTimeMillis() - touchDownTime + + if (touchDuration <= maxTapDuration) { + fragment.handleScreenTap(false) + } else { + // just start the auto-hide timer without toggling visibility + fragment.handleScreenTap(true) + } + } + } + } + } + + return super.dispatchTouchEvent(event) + } + fun onEmulationStarted() { emulationViewModel.setEmulationStarted(true) } @@ -511,6 +559,12 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { companion object { const val EXTRA_SELECTED_GAME = "SelectedGame" + fun stopForegroundService(activity: Activity) { + val startIntent = Intent(activity, ForegroundService::class.java) + startIntent.action = ForegroundService.ACTION_STOP + activity.startForegroundService(startIntent) + } + fun launch(activity: AppCompatActivity, game: Game) { val launcher = Intent(activity, EmulationActivity::class.java) launcher.putExtra(EXTRA_SELECTED_GAME, game) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 3c5b9003de..638e1101db 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -55,6 +55,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { FRAME_INTERPOLATION("frame_interpolation"), // FRAME_SKIPPING("frame_skipping"), + ENABLE_INPUT_OVERLAY_AUTO_HIDE("enable_input_overlay_auto_hide"), + PERF_OVERLAY_BACKGROUND("perf_overlay_background"), SHOW_PERFORMANCE_OVERLAY("show_performance_overlay"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt index 21aad8b5d1..d5556a337b 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt @@ -59,7 +59,8 @@ enum class IntSetting(override val key: String) : AbstractIntSetting { OFFLINE_WEB_APPLET("offline_web_applet_mode"), LOGIN_SHARE_APPLET("login_share_applet_mode"), WIFI_WEB_AUTH_APPLET("wifi_web_auth_applet_mode"), - MY_PAGE_APPLET("my_page_applet_mode") + MY_PAGE_APPLET("my_page_applet_mode"), + INPUT_OVERLAY_AUTO_HIDE("input_overlay_auto_hide") ; override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt index a52f582031..454d0e4807 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt @@ -12,6 +12,7 @@ object Settings { SECTION_SYSTEM(R.string.preferences_system), SECTION_RENDERER(R.string.preferences_graphics), SECTION_PERFORMANCE_STATS(R.string.stats_overlay_options), + SECTION_INPUT_OVERLAY(R.string.input_overlay_options), SECTION_SOC_OVERLAY(R.string.soc_overlay_options), SECTION_AUDIO(R.string.preferences_audio), SECTION_INPUT(R.string.preferences_controls), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 1f2ba81a73..5f7f7a43f9 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -96,6 +96,7 @@ abstract class SettingsItem( const val TYPE_INT_SINGLE_CHOICE = 9 const val TYPE_INPUT_PROFILE = 10 const val TYPE_STRING_INPUT = 11 + const val TYPE_SPINBOX = 12 const val FASTMEM_COMBINED = "fastmem_combined" @@ -385,6 +386,22 @@ abstract class SettingsItem( warningMessage = R.string.warning_resolution ) ) + put( + SwitchSetting( + BooleanSetting.ENABLE_INPUT_OVERLAY_AUTO_HIDE, + titleId = R.string.enable_input_overlay_auto_hide, + ) + ) + put( + SpinBoxSetting( + IntSetting.INPUT_OVERLAY_AUTO_HIDE, + titleId = R.string.overlay_auto_hide, + descriptionId = R.string.overlay_auto_hide_description, + min = 1, + max = 999, + valueHint = R.string.seconds + ) + ) put( SwitchSetting( diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SpinBoxSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SpinBoxSetting.kt new file mode 100644 index 0000000000..0b0d01dfe0 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SpinBoxSetting.kt @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +package org.yuzu.yuzu_emu.features.settings.model.view + +import androidx.annotation.StringRes +import org.yuzu.yuzu_emu.features.settings.model.AbstractByteSetting +import org.yuzu.yuzu_emu.features.settings.model.AbstractFloatSetting +import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting +import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting +import org.yuzu.yuzu_emu.features.settings.model.AbstractShortSetting + +class SpinBoxSetting( + setting: AbstractSetting, + @StringRes titleId: Int = 0, + titleString: String = "", + @StringRes descriptionId: Int = 0, + descriptionString: String = "", + val valueHint: Int, + val min: Int, + val max: Int +) : SettingsItem(setting, titleId, titleString, descriptionId, descriptionString) { + override val type = TYPE_SPINBOX + + fun getSelectedValue(needsGlobal: Boolean = false) = + when (setting) { + is AbstractByteSetting -> setting.getByte(needsGlobal).toInt() + is AbstractShortSetting -> setting.getShort(needsGlobal).toInt() + is AbstractIntSetting -> setting.getInt(needsGlobal) + is AbstractFloatSetting -> setting.getFloat(needsGlobal).toInt() + else -> 0 + } + + fun setSelectedValue(value: Int) = + when (setting) { + is AbstractByteSetting -> setting.setByte(value.toByte()) + is AbstractShortSetting -> setting.setShort(value.toShort()) + is AbstractFloatSetting -> setting.setFloat(value.toFloat()) + else -> (setting as AbstractIntSetting).setInt(value) + } +} \ No newline at end of file diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt index 500ac6e66e..bdc51b7070 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later package org.yuzu.yuzu_emu.features.settings.ui @@ -61,6 +61,10 @@ class SettingsAdapter( SliderViewHolder(ListItemSettingBinding.inflate(inflater), this) } + SettingsItem.TYPE_SPINBOX -> { + SpinBoxViewHolder(ListItemSettingBinding.inflate(inflater), this) + } + SettingsItem.TYPE_SUBMENU -> { SubmenuViewHolder(ListItemSettingBinding.inflate(inflater), this) } @@ -191,6 +195,14 @@ class SettingsAdapter( position ).show(fragment.childFragmentManager, SettingsDialogFragment.TAG) } + fun onSpinBoxClick(item: SpinBoxSetting, position: Int) { + SettingsDialogFragment.newInstance( + settingsViewModel, + item, + SettingsItem.TYPE_SPINBOX, + position + ).show(fragment.childFragmentManager, SettingsDialogFragment.TAG) + } fun onSubmenuClick(item: SubmenuSetting) { val action = SettingsNavigationDirections.actionGlobalSettingsFragment(item.menuKey, null) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt index dc9f561eca..2a97f15892 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt @@ -14,6 +14,7 @@ import android.text.TextWatcher import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels @@ -22,6 +23,7 @@ import com.google.android.material.slider.Slider import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.databinding.DialogEditTextBinding import org.yuzu.yuzu_emu.databinding.DialogSliderBinding +import org.yuzu.yuzu_emu.databinding.DialogSpinboxBinding import org.yuzu.yuzu_emu.features.input.NativeInput import org.yuzu.yuzu_emu.features.input.model.AnalogDirection import org.yuzu.yuzu_emu.features.settings.model.view.AnalogInputSetting @@ -30,6 +32,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.IntSingleChoiceSetting import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting +import org.yuzu.yuzu_emu.features.settings.model.view.SpinBoxSetting import org.yuzu.yuzu_emu.features.settings.model.view.StringInputSetting import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting import org.yuzu.yuzu_emu.utils.ParamPackage @@ -46,6 +49,7 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener private lateinit var sliderBinding: DialogSliderBinding private lateinit var stringInputBinding: DialogEditTextBinding + private lateinit var spinboxBinding: DialogSpinboxBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -142,6 +146,76 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener .create() } + SettingsItem.TYPE_SPINBOX -> { + spinboxBinding = DialogSpinboxBinding.inflate(layoutInflater) + val item = settingsViewModel.clickedItem as SpinBoxSetting + + val currentValue = item.getSelectedValue() + spinboxBinding.editValue.setText(currentValue.toString()) + spinboxBinding.textInputLayout.hint = getString(item.valueHint) + + val dialog = MaterialAlertDialogBuilder(requireContext()) + .setTitle(item.title) + .setView(spinboxBinding.root) + .setPositiveButton(android.R.string.ok, this) + .setNegativeButton(android.R.string.cancel, defaultCancelListener) + .create() + + val updateButtonState = { enabled: Boolean -> + dialog.setOnShowListener { dialogInterface -> + (dialogInterface as AlertDialog).getButton(DialogInterface.BUTTON_POSITIVE)?.isEnabled = enabled + } + if (dialog.isShowing) { + dialog.getButton(DialogInterface.BUTTON_POSITIVE)?.isEnabled = enabled + } + } + + val updateValidity = { value: Int -> + val isValid = value in item.min..item.max + if (isValid) { + spinboxBinding.textInputLayout.error = null + } else { + spinboxBinding.textInputLayout.error = getString( + if (value < item.min) R.string.value_too_low else R.string.value_too_high, + if (value < item.min) item.min else item.max + ) + } + updateButtonState(isValid) + } + + spinboxBinding.buttonDecrement.setOnClickListener { + val current = spinboxBinding.editValue.text.toString().toIntOrNull() ?: currentValue + val newValue = current - 1 + spinboxBinding.editValue.setText(newValue.toString()) + updateValidity(newValue) + } + + spinboxBinding.buttonIncrement.setOnClickListener { + val current = spinboxBinding.editValue.text.toString().toIntOrNull() ?: currentValue + val newValue = current + 1 + spinboxBinding.editValue.setText(newValue.toString()) + updateValidity(newValue) + } + + spinboxBinding.editValue.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} + override fun afterTextChanged(s: Editable?) { + val value = s.toString().toIntOrNull() + if (value != null) { + updateValidity(value) + } else { + spinboxBinding.textInputLayout.error = getString(R.string.invalid_value) + updateButtonState(false) + } + } + }) + + updateValidity(currentValue) + + dialog + } + SettingsItem.TYPE_STRING_INPUT -> { stringInputBinding = DialogEditTextBinding.inflate(layoutInflater) val item = settingsViewModel.clickedItem as StringInputSetting @@ -281,6 +355,14 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener sliderSetting.setSelectedValue(settingsViewModel.sliderProgress.value) } + is SpinBoxSetting -> { + val spinBoxSetting = settingsViewModel.clickedItem as SpinBoxSetting + val value = spinboxBinding.editValue.text.toString().toIntOrNull() + if (value != null && value in spinBoxSetting.min..spinBoxSetting.max) { + spinBoxSetting.setSelectedValue(value) + } + } + is StringInputSetting -> { val stringInputSetting = settingsViewModel.clickedItem as StringInputSetting stringInputSetting.setSelectedValue( diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 14d62ceec3..715baec72f 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -97,6 +97,7 @@ class SettingsFragmentPresenter( MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl) MenuTag.SECTION_PERFORMANCE_STATS -> addPerformanceOverlaySettings(sl) MenuTag.SECTION_SOC_OVERLAY -> addSocOverlaySettings(sl) + MenuTag.SECTION_INPUT_OVERLAY -> addInputOverlaySettings(sl) MenuTag.SECTION_AUDIO -> addAudioSettings(sl) MenuTag.SECTION_INPUT -> addInputSettings(sl) MenuTag.SECTION_INPUT_PLAYER_ONE -> addInputPlayer(sl, 0) @@ -156,6 +157,14 @@ class SettingsFragmentPresenter( menuKey = MenuTag.SECTION_SOC_OVERLAY ) ) + add( + SubmenuSetting( + titleId = R.string.input_overlay_options, + iconId = R.drawable.ic_controller, + descriptionId = R.string.input_overlay_options_description, + menuKey = MenuTag.SECTION_INPUT_OVERLAY + ) + ) } add( SubmenuSetting( @@ -264,6 +273,13 @@ class SettingsFragmentPresenter( } } + private fun addInputOverlaySettings(sl: ArrayList) { + sl.apply { + add(BooleanSetting.ENABLE_INPUT_OVERLAY_AUTO_HIDE.key) + add(IntSetting.INPUT_OVERLAY_AUTO_HIDE.key) + } + } + private fun addSocOverlaySettings(sl: ArrayList) { sl.apply { add(HeaderSetting(R.string.stats_overlay_customization)) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SpinBoxViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SpinBoxViewHolder.kt new file mode 100644 index 0000000000..1f9a16b798 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SpinBoxViewHolder.kt @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +package org.yuzu.yuzu_emu.features.settings.ui.viewholder + +import android.view.View +import org.yuzu.yuzu_emu.R +import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding +import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem +import org.yuzu.yuzu_emu.features.settings.model.view.SpinBoxSetting +import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter +import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible + +class SpinBoxViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : + SettingViewHolder(binding.root, adapter) { + private lateinit var setting: SpinBoxSetting + + override fun bind(item: SettingsItem) { + setting = item as SpinBoxSetting + binding.textSettingName.text = setting.title + binding.textSettingDescription.setVisible(item.description.isNotEmpty()) + binding.textSettingDescription.text = setting.description + binding.textSettingValue.setVisible(true) + binding.textSettingValue.text = setting.getSelectedValue().toString() + + binding.buttonClear.setVisible(setting.clearable) + binding.buttonClear.setOnClickListener { + adapter.onClearClick(setting, bindingAdapterPosition) + } + + setStyle(setting.isEditable, binding) + } + override fun onClick(clicked: View) { + if (setting.isEditable) { + adapter.onSpinBoxClick(setting, bindingAdapterPosition) + } + } + override fun onLongClick(clicked: View): Boolean { + if (setting.isEditable) { + return adapter.onLongClick(setting, bindingAdapterPosition) + } + return false + } +} \ No newline at end of file diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index 8162098caa..b2d6135372 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt @@ -96,6 +96,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { private var perfStatsUpdater: (() -> Unit)? = null private var socUpdater: (() -> Unit)? = null + val handler = Handler(Looper.getMainLooper()) + private var isOverlayVisible = true + private var _binding: FragmentEmulationBinding? = null private val binding get() = _binding!! @@ -452,7 +455,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { /** * Ask user if they want to launch with default settings when custom settings fail */ - private suspend fun askUserToLaunchWithDefaultSettings(gameTitle: String, errorMessage: String): Boolean { + private suspend fun askUserToLaunchWithDefaultSettings( + gameTitle: String, + errorMessage: String + ): Boolean { return suspendCoroutine { continuation -> requireActivity().runOnUiThread { MaterialAlertDialogBuilder(requireContext()) @@ -728,6 +734,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { updateShowStatsOverlay() updateSocOverlay() + initializeOverlayAutoHide() + // Re update binding when the specs values get initialized properly binding.inGameMenu.getHeaderView(0).apply { val titleView = findViewById(R.id.text_game_title) @@ -917,6 +925,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { updatePauseMenuEntry(emulationState.isPaused) } } + + // if the overlay auto-hide setting is changed while paused, + // we need to reinitialize the auto-hide timer + initializeOverlayAutoHide() + } private fun resetInputOverlay() { @@ -924,6 +937,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { IntSetting.OVERLAY_OPACITY.reset() binding.surfaceInputOverlay.post { binding.surfaceInputOverlay.resetLayoutVisibilityAndPlacement() + binding.surfaceInputOverlay.resetIndividualControlScale() } } @@ -1034,7 +1048,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { val status = batteryIntent?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) val isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || - status == BatteryManager.BATTERY_STATUS_FULL + status == BatteryManager.BATTERY_STATUS_FULL if (isCharging) { sb.append(" ${getString(R.string.charging)}") @@ -1546,6 +1560,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { .setNeutralButton(R.string.slider_default) { _: DialogInterface?, _: Int -> setControlScale(50) setControlOpacity(100) + binding.surfaceInputOverlay.resetIndividualControlScale() } .show() } @@ -1726,4 +1741,61 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { private val perfStatsUpdateHandler = Handler(Looper.myLooper()!!) private val socUpdateHandler = Handler(Looper.myLooper()!!) } -} \ No newline at end of file + + private fun startOverlayAutoHideTimer(seconds: Int) { + handler.removeCallbacksAndMessages(null) + + handler.postDelayed({ + if (isOverlayVisible) { + hideOverlay() + } + }, seconds * 1000L) + } + + fun handleScreenTap(isLongTap: Boolean) { + val autoHideSeconds = IntSetting.INPUT_OVERLAY_AUTO_HIDE.getInt() + val shouldProceed = BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean() && BooleanSetting.ENABLE_INPUT_OVERLAY_AUTO_HIDE.getBoolean() + + if (!shouldProceed) { + return + } + + // failsafe + if (autoHideSeconds == 0) { + showOverlay() + return + } + + if (!isOverlayVisible && !isLongTap) { + showOverlay() + } + + startOverlayAutoHideTimer(autoHideSeconds) + } + + private fun initializeOverlayAutoHide() { + val autoHideSeconds = IntSetting.INPUT_OVERLAY_AUTO_HIDE.getInt() + val autoHideEnabled = BooleanSetting.ENABLE_INPUT_OVERLAY_AUTO_HIDE.getBoolean() + val showOverlay = BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean() + + if (autoHideEnabled && showOverlay) { + showOverlay() + startOverlayAutoHideTimer(autoHideSeconds) + } + } + + + fun showOverlay() { + if (!isOverlayVisible) { + isOverlayVisible = true + ViewUtils.showView(binding.surfaceInputOverlay, 500) + } + } + + private fun hideOverlay() { + if (isOverlayVisible) { + isOverlayVisible = false + ViewUtils.hideView(binding.surfaceInputOverlay, 500) + } + } +} diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt index 737e035840..9f050a5053 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later package org.yuzu.yuzu_emu.overlay @@ -13,6 +13,8 @@ import android.graphics.Rect import android.graphics.drawable.Drawable import android.graphics.drawable.VectorDrawable import android.os.Build +import android.os.Handler +import android.os.Looper import android.util.AttributeSet import android.view.HapticFeedbackConstants import android.view.MotionEvent @@ -52,6 +54,12 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : private var dpadBeingConfigured: InputOverlayDrawableDpad? = null private var joystickBeingConfigured: InputOverlayDrawableJoystick? = null + private var scaleDialog: OverlayScaleDialog? = null + private var touchStartX = 0f + private var touchStartY = 0f + private var hasMoved = false + private val moveThreshold = 20f + private lateinit var windowInsets: WindowInsets var layout = OverlayLayout.Landscape @@ -254,23 +262,44 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : ) { buttonBeingConfigured = button buttonBeingConfigured!!.onConfigureTouch(event) + touchStartX = event.getX(pointerIndex) + touchStartY = event.getY(pointerIndex) + hasMoved = false } MotionEvent.ACTION_MOVE -> if (buttonBeingConfigured != null) { - buttonBeingConfigured!!.onConfigureTouch(event) - invalidate() - return true + val moveDistance = kotlin.math.sqrt( + (event.getX(pointerIndex) - touchStartX).let { it * it } + + (event.getY(pointerIndex) - touchStartY).let { it * it } + ) + + if (moveDistance > moveThreshold) { + hasMoved = true + buttonBeingConfigured!!.onConfigureTouch(event) + invalidate() + return true + } } MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> if (buttonBeingConfigured === button) { - // Persist button position by saving new place. - saveControlPosition( - buttonBeingConfigured!!.overlayControlData.id, - buttonBeingConfigured!!.bounds.centerX(), - buttonBeingConfigured!!.bounds.centerY(), - layout - ) + if (!hasMoved) { + showScaleDialog( + buttonBeingConfigured, + null, + null, + fingerPositionX, + fingerPositionY + ) + } else { + saveControlPosition( + buttonBeingConfigured!!.overlayControlData.id, + buttonBeingConfigured!!.bounds.centerX(), + buttonBeingConfigured!!.bounds.centerY(), + individuaScale = buttonBeingConfigured!!.overlayControlData.individualScale, + layout + ) + } buttonBeingConfigured = null } } @@ -287,23 +316,46 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : ) { dpadBeingConfigured = dpad dpadBeingConfigured!!.onConfigureTouch(event) + touchStartX = event.getX(pointerIndex) + touchStartY = event.getY(pointerIndex) + hasMoved = false } MotionEvent.ACTION_MOVE -> if (dpadBeingConfigured != null) { - dpadBeingConfigured!!.onConfigureTouch(event) - invalidate() - return true + val moveDistance = kotlin.math.sqrt( + (event.getX(pointerIndex) - touchStartX).let { it * it } + + (event.getY(pointerIndex) - touchStartY).let { it * it } + ) + + if (moveDistance > moveThreshold) { + hasMoved = true + dpadBeingConfigured!!.onConfigureTouch(event) + invalidate() + return true + } } MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> if (dpadBeingConfigured === dpad) { - // Persist button position by saving new place. - saveControlPosition( - OverlayControl.COMBINED_DPAD.id, - dpadBeingConfigured!!.bounds.centerX(), - dpadBeingConfigured!!.bounds.centerY(), - layout - ) + if (!hasMoved) { + // This was a click, show scale dialog for dpad + showScaleDialog( + null, + dpadBeingConfigured, + null, + fingerPositionX, + fingerPositionY + ) + } else { + // This was a move, save position + saveControlPosition( + OverlayControl.COMBINED_DPAD.id, + dpadBeingConfigured!!.bounds.centerX(), + dpadBeingConfigured!!.bounds.centerY(), + individuaScale = dpadBeingConfigured!!.individualScale, + layout + ) + } dpadBeingConfigured = null } } @@ -317,21 +369,43 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : ) { joystickBeingConfigured = joystick joystickBeingConfigured!!.onConfigureTouch(event) + touchStartX = event.getX(pointerIndex) + touchStartY = event.getY(pointerIndex) + hasMoved = false } MotionEvent.ACTION_MOVE -> if (joystickBeingConfigured != null) { - joystickBeingConfigured!!.onConfigureTouch(event) - invalidate() + val moveDistance = kotlin.math.sqrt( + (event.getX(pointerIndex) - touchStartX).let { it * it } + + (event.getY(pointerIndex) - touchStartY).let { it * it } + ) + + if (moveDistance > moveThreshold) { + hasMoved = true + joystickBeingConfigured!!.onConfigureTouch(event) + invalidate() + } } MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> if (joystickBeingConfigured != null) { - saveControlPosition( - joystickBeingConfigured!!.prefId, - joystickBeingConfigured!!.bounds.centerX(), - joystickBeingConfigured!!.bounds.centerY(), - layout - ) + if (!hasMoved) { + showScaleDialog( + null, + null, + joystickBeingConfigured, + fingerPositionX, + fingerPositionY + ) + } else { + saveControlPosition( + joystickBeingConfigured!!.prefId, + joystickBeingConfigured!!.bounds.centerX(), + joystickBeingConfigured!!.bounds.centerY(), + individuaScale = joystickBeingConfigured!!.individualScale, + layout + ) + } joystickBeingConfigured = null } } @@ -607,25 +681,117 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : invalidate() } - private fun saveControlPosition(id: String, x: Int, y: Int, layout: OverlayLayout) { + private fun saveControlPosition( + id: String, + x: Int, + y: Int, + individuaScale: Float, + layout: OverlayLayout + ) { val windowSize = getSafeScreenSize(context, Pair(measuredWidth, measuredHeight)) val min = windowSize.first val max = windowSize.second val overlayControlData = NativeConfig.getOverlayControlData() val data = overlayControlData.firstOrNull { it.id == id } val newPosition = Pair((x - min.x).toDouble() / max.x, (y - min.y).toDouble() / max.y) + when (layout) { OverlayLayout.Landscape -> data?.landscapePosition = newPosition OverlayLayout.Portrait -> data?.portraitPosition = newPosition OverlayLayout.Foldable -> data?.foldablePosition = newPosition + } + + data?.individualScale = individuaScale + NativeConfig.setOverlayControlData(overlayControlData) } fun setIsInEditMode(editMode: Boolean) { inEditMode = editMode + if (!editMode) { + scaleDialog?.dismiss() + scaleDialog = null + } } + private fun showScaleDialog( + button: InputOverlayDrawableButton?, + dpad: InputOverlayDrawableDpad?, + joystick: InputOverlayDrawableJoystick?, + x: Int, y: Int + ) { + val overlayControlData = NativeConfig.getOverlayControlData() + // prevent dialog from being spam opened + scaleDialog?.dismiss() + + + when { + button != null -> { + val buttonData = + overlayControlData.firstOrNull { it.id == button.overlayControlData.id } + if (buttonData != null) { + scaleDialog = + OverlayScaleDialog(context, button.overlayControlData) { newScale -> + saveControlPosition( + button.overlayControlData.id, + button.bounds.centerX(), + button.bounds.centerY(), + individuaScale = newScale, + layout + ) + refreshControls() + } + + scaleDialog?.showDialog(x,y, button.bounds.width(), button.bounds.height()) + + } + } + + dpad != null -> { + val dpadData = + overlayControlData.firstOrNull { it.id == OverlayControl.COMBINED_DPAD.id } + if (dpadData != null) { + scaleDialog = OverlayScaleDialog(context, dpadData) { newScale -> + saveControlPosition( + OverlayControl.COMBINED_DPAD.id, + dpad.bounds.centerX(), + dpad.bounds.centerY(), + newScale, + layout + ) + + refreshControls() + } + + scaleDialog?.showDialog(x,y, dpad.bounds.width(), dpad.bounds.height()) + + } + } + + joystick != null -> { + val joystickData = overlayControlData.firstOrNull { it.id == joystick.prefId } + if (joystickData != null) { + scaleDialog = OverlayScaleDialog(context, joystickData) { newScale -> + saveControlPosition( + joystick.prefId, + joystick.bounds.centerX(), + joystick.bounds.centerY(), + individuaScale = newScale, + layout + ) + + refreshControls() + } + + scaleDialog?.showDialog(x,y, joystick.bounds.width(), joystick.bounds.height()) + + } + } + } + } + + /** * Applies and saves all default values for the overlay */ @@ -664,12 +830,24 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : val overlayControlData = NativeConfig.getOverlayControlData() overlayControlData.forEach { it.enabled = OverlayControl.from(it.id)?.defaultVisibility == true + it.individualScale = OverlayControl.from(it.id)?.defaultIndividualScaleResource!! } NativeConfig.setOverlayControlData(overlayControlData) refreshControls() } + fun resetIndividualControlScale() { + val overlayControlData = NativeConfig.getOverlayControlData() + overlayControlData.forEach { data -> + val defaultControlData = OverlayControl.from(data.id) ?: return@forEach + data.individualScale = defaultControlData.defaultIndividualScaleResource + } + NativeConfig.setOverlayControlData(overlayControlData) + NativeConfig.saveGlobalConfig() + refreshControls() + } + private fun defaultOverlayPositionByLayout(layout: OverlayLayout) { val overlayControlData = NativeConfig.getOverlayControlData() for (data in overlayControlData) { @@ -860,6 +1038,9 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : scale *= (IntSetting.OVERLAY_SCALE.getInt() + 50).toFloat() scale /= 100f + // Apply individual scale + scale *= overlayControlData.individualScale + // Initialize the InputOverlayDrawableButton. val defaultStateBitmap = getBitmap(context, defaultResId, scale) val pressedStateBitmap = getBitmap(context, pressedResId, scale) @@ -922,11 +1103,20 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : // Resources handle for fetching the initial Drawable resource. val res = context.resources + // Get the dpad control data for individual scale + val overlayControlData = NativeConfig.getOverlayControlData() + val dpadData = overlayControlData.firstOrNull { it.id == OverlayControl.COMBINED_DPAD.id } + // Decide scale based on button ID and user preference var scale = 0.25f scale *= (IntSetting.OVERLAY_SCALE.getInt() + 50).toFloat() scale /= 100f + // Apply individual scale + if (dpadData != null) { + scale *= dpadData.individualScale + } + // Initialize the InputOverlayDrawableDpad. val defaultStateBitmap = getBitmap(context, defaultResId, scale) @@ -1000,6 +1190,9 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : scale *= (IntSetting.OVERLAY_SCALE.getInt() + 50).toFloat() scale /= 100f + // Apply individual scale + scale *= overlayControlData.individualScale + // Initialize the InputOverlayDrawableJoystick. val bitmapOuter = getBitmap(context, resOuter, scale) val bitmapInnerDefault = getBitmap(context, defaultResInner, 1.0f) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.kt index 0cb6ff2440..01f07e4f36 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableDpad.kt @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later package org.yuzu.yuzu_emu.overlay @@ -42,6 +42,8 @@ class InputOverlayDrawableDpad( val width: Int val height: Int + var individualScale: Float = 1.0f + private val defaultStateBitmap: BitmapDrawable private val pressedOneDirectionStateBitmap: BitmapDrawable private val pressedTwoDirectionsStateBitmap: BitmapDrawable diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt index 4b07107fca..bc3ff15b21 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later package org.yuzu.yuzu_emu.overlay @@ -51,6 +51,8 @@ class InputOverlayDrawableJoystick( val width: Int val height: Int + var individualScale: Float = 1.0f + private var opacity: Int = 0 private var virtBounds: Rect diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/OverlayScaleDialog.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/OverlayScaleDialog.kt new file mode 100644 index 0000000000..f489ef3b7c --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/OverlayScaleDialog.kt @@ -0,0 +1,124 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +package org.yuzu.yuzu_emu.overlay + +import android.app.Dialog +import android.content.Context +import android.view.Gravity +import android.view.LayoutInflater +import android.view.WindowManager +import android.widget.TextView +import com.google.android.material.button.MaterialButton +import com.google.android.material.slider.Slider +import org.yuzu.yuzu_emu.R +import org.yuzu.yuzu_emu.overlay.model.OverlayControlData + +class OverlayScaleDialog( + context: Context, + private val overlayControlData: OverlayControlData, + private val onScaleChanged: (Float) -> Unit +) : Dialog(context) { + + private var currentScale = overlayControlData.individualScale + private val originalScale = overlayControlData.individualScale + private lateinit var scaleValueText: TextView + private lateinit var scaleSlider: Slider + + init { + setupDialog() + } + + private fun setupDialog() { + val view = LayoutInflater.from(context).inflate(R.layout.dialog_overlay_scale, null) + setContentView(view) + + window?.setBackgroundDrawable(null) + + window?.apply { + attributes = attributes.apply { + flags = flags and WindowManager.LayoutParams.FLAG_DIM_BEHIND.inv() + flags = flags or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + } + } + + scaleValueText = view.findViewById(R.id.scaleValueText) + scaleSlider = view.findViewById(R.id.scaleSlider) + val resetButton = view.findViewById(R.id.resetButton) + val confirmButton = view.findViewById(R.id.confirmButton) + val cancelButton = view.findViewById(R.id.cancelButton) + + scaleValueText.text = String.format("%.1fx", currentScale) + scaleSlider.value = currentScale + + scaleSlider.addOnChangeListener { _, value, input -> + if (input) { + currentScale = value + scaleValueText.text = String.format("%.1fx", currentScale) + } + } + + scaleSlider.addOnSliderTouchListener(object : Slider.OnSliderTouchListener { + override fun onStartTrackingTouch(slider: Slider) { + // pass + } + + override fun onStopTrackingTouch(slider: Slider) { + onScaleChanged(currentScale) + } + }) + + resetButton.setOnClickListener { + currentScale = 1.0f + scaleSlider.value = 1.0f + scaleValueText.text = String.format("%.1fx", currentScale) + onScaleChanged(currentScale) + } + + confirmButton.setOnClickListener { + overlayControlData.individualScale = currentScale + //slider value is already saved on touch dispatch but just to be sure + onScaleChanged(currentScale) + dismiss() + } + + // both cancel button and back gesture should revert the scale change + cancelButton.setOnClickListener { + onScaleChanged(originalScale) + dismiss() + } + + setOnCancelListener { + onScaleChanged(originalScale) + dismiss() + } + } + + fun showDialog(anchorX: Int, anchorY: Int, anchorHeight: Int, anchorWidth: Int) { + show() + + show() + + // TODO: this calculation is a bit rough, improve it later on + window?.let { window -> + val layoutParams = window.attributes + layoutParams.gravity = Gravity.TOP or Gravity.START + + val density = context.resources.displayMetrics.density + val dialogWidthPx = (320 * density).toInt() + val dialogHeightPx = (400 * density).toInt() // set your estimated dialog height + + val screenHeight = context.resources.displayMetrics.heightPixels + + + layoutParams.x = anchorX + anchorWidth / 2 - dialogWidthPx / 2 + layoutParams.y = anchorY + anchorHeight / 2 - dialogHeightPx / 2 + layoutParams.width = dialogWidthPx + + + window.attributes = layoutParams + } + + } + +} \ No newline at end of file diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControl.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControl.kt index a0eeadf4bc..10cc547d0b 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControl.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControl.kt @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later package org.yuzu.yuzu_emu.overlay.model @@ -12,126 +12,144 @@ enum class OverlayControl( val defaultVisibility: Boolean, @IntegerRes val defaultLandscapePositionResources: Pair, @IntegerRes val defaultPortraitPositionResources: Pair, - @IntegerRes val defaultFoldablePositionResources: Pair + @IntegerRes val defaultFoldablePositionResources: Pair, + val defaultIndividualScaleResource: Float, ) { BUTTON_A( "button_a", true, Pair(R.integer.BUTTON_A_X, R.integer.BUTTON_A_Y), Pair(R.integer.BUTTON_A_X_PORTRAIT, R.integer.BUTTON_A_Y_PORTRAIT), - Pair(R.integer.BUTTON_A_X_FOLDABLE, R.integer.BUTTON_A_Y_FOLDABLE) + Pair(R.integer.BUTTON_A_X_FOLDABLE, R.integer.BUTTON_A_Y_FOLDABLE), + 1.0f ), BUTTON_B( "button_b", true, Pair(R.integer.BUTTON_B_X, R.integer.BUTTON_B_Y), Pair(R.integer.BUTTON_B_X_PORTRAIT, R.integer.BUTTON_B_Y_PORTRAIT), - Pair(R.integer.BUTTON_B_X_FOLDABLE, R.integer.BUTTON_B_Y_FOLDABLE) + Pair(R.integer.BUTTON_B_X_FOLDABLE, R.integer.BUTTON_B_Y_FOLDABLE), + 1.0f ), BUTTON_X( "button_x", true, Pair(R.integer.BUTTON_X_X, R.integer.BUTTON_X_Y), Pair(R.integer.BUTTON_X_X_PORTRAIT, R.integer.BUTTON_X_Y_PORTRAIT), - Pair(R.integer.BUTTON_X_X_FOLDABLE, R.integer.BUTTON_X_Y_FOLDABLE) + Pair(R.integer.BUTTON_X_X_FOLDABLE, R.integer.BUTTON_X_Y_FOLDABLE), + 1.0f ), BUTTON_Y( "button_y", true, Pair(R.integer.BUTTON_Y_X, R.integer.BUTTON_Y_Y), Pair(R.integer.BUTTON_Y_X_PORTRAIT, R.integer.BUTTON_Y_Y_PORTRAIT), - Pair(R.integer.BUTTON_Y_X_FOLDABLE, R.integer.BUTTON_Y_Y_FOLDABLE) + Pair(R.integer.BUTTON_Y_X_FOLDABLE, R.integer.BUTTON_Y_Y_FOLDABLE), + 1.0f ), BUTTON_PLUS( "button_plus", true, Pair(R.integer.BUTTON_PLUS_X, R.integer.BUTTON_PLUS_Y), Pair(R.integer.BUTTON_PLUS_X_PORTRAIT, R.integer.BUTTON_PLUS_Y_PORTRAIT), - Pair(R.integer.BUTTON_PLUS_X_FOLDABLE, R.integer.BUTTON_PLUS_Y_FOLDABLE) + Pair(R.integer.BUTTON_PLUS_X_FOLDABLE, R.integer.BUTTON_PLUS_Y_FOLDABLE), + 1.0f ), BUTTON_MINUS( "button_minus", true, Pair(R.integer.BUTTON_MINUS_X, R.integer.BUTTON_MINUS_Y), Pair(R.integer.BUTTON_MINUS_X_PORTRAIT, R.integer.BUTTON_MINUS_Y_PORTRAIT), - Pair(R.integer.BUTTON_MINUS_X_FOLDABLE, R.integer.BUTTON_MINUS_Y_FOLDABLE) + Pair(R.integer.BUTTON_MINUS_X_FOLDABLE, R.integer.BUTTON_MINUS_Y_FOLDABLE), + 1.0f ), BUTTON_HOME( "button_home", false, Pair(R.integer.BUTTON_HOME_X, R.integer.BUTTON_HOME_Y), Pair(R.integer.BUTTON_HOME_X_PORTRAIT, R.integer.BUTTON_HOME_Y_PORTRAIT), - Pair(R.integer.BUTTON_HOME_X_FOLDABLE, R.integer.BUTTON_HOME_Y_FOLDABLE) + Pair(R.integer.BUTTON_HOME_X_FOLDABLE, R.integer.BUTTON_HOME_Y_FOLDABLE), + 1.0f ), BUTTON_CAPTURE( "button_capture", false, Pair(R.integer.BUTTON_CAPTURE_X, R.integer.BUTTON_CAPTURE_Y), Pair(R.integer.BUTTON_CAPTURE_X_PORTRAIT, R.integer.BUTTON_CAPTURE_Y_PORTRAIT), - Pair(R.integer.BUTTON_CAPTURE_X_FOLDABLE, R.integer.BUTTON_CAPTURE_Y_FOLDABLE) + Pair(R.integer.BUTTON_CAPTURE_X_FOLDABLE, R.integer.BUTTON_CAPTURE_Y_FOLDABLE), + 1.0f ), BUTTON_L( "button_l", true, Pair(R.integer.BUTTON_L_X, R.integer.BUTTON_L_Y), Pair(R.integer.BUTTON_L_X_PORTRAIT, R.integer.BUTTON_L_Y_PORTRAIT), - Pair(R.integer.BUTTON_L_X_FOLDABLE, R.integer.BUTTON_L_Y_FOLDABLE) + Pair(R.integer.BUTTON_L_X_FOLDABLE, R.integer.BUTTON_L_Y_FOLDABLE), + 1.0f ), BUTTON_R( "button_r", true, Pair(R.integer.BUTTON_R_X, R.integer.BUTTON_R_Y), Pair(R.integer.BUTTON_R_X_PORTRAIT, R.integer.BUTTON_R_Y_PORTRAIT), - Pair(R.integer.BUTTON_R_X_FOLDABLE, R.integer.BUTTON_R_Y_FOLDABLE) + Pair(R.integer.BUTTON_R_X_FOLDABLE, R.integer.BUTTON_R_Y_FOLDABLE), + 1.0f ), BUTTON_ZL( "button_zl", true, Pair(R.integer.BUTTON_ZL_X, R.integer.BUTTON_ZL_Y), Pair(R.integer.BUTTON_ZL_X_PORTRAIT, R.integer.BUTTON_ZL_Y_PORTRAIT), - Pair(R.integer.BUTTON_ZL_X_FOLDABLE, R.integer.BUTTON_ZL_Y_FOLDABLE) + Pair(R.integer.BUTTON_ZL_X_FOLDABLE, R.integer.BUTTON_ZL_Y_FOLDABLE), + 1.0f ), BUTTON_ZR( "button_zr", true, Pair(R.integer.BUTTON_ZR_X, R.integer.BUTTON_ZR_Y), Pair(R.integer.BUTTON_ZR_X_PORTRAIT, R.integer.BUTTON_ZR_Y_PORTRAIT), - Pair(R.integer.BUTTON_ZR_X_FOLDABLE, R.integer.BUTTON_ZR_Y_FOLDABLE) + Pair(R.integer.BUTTON_ZR_X_FOLDABLE, R.integer.BUTTON_ZR_Y_FOLDABLE), + 1.0f ), BUTTON_STICK_L( "button_stick_l", true, Pair(R.integer.BUTTON_STICK_L_X, R.integer.BUTTON_STICK_L_Y), Pair(R.integer.BUTTON_STICK_L_X_PORTRAIT, R.integer.BUTTON_STICK_L_Y_PORTRAIT), - Pair(R.integer.BUTTON_STICK_L_X_FOLDABLE, R.integer.BUTTON_STICK_L_Y_FOLDABLE) + Pair(R.integer.BUTTON_STICK_L_X_FOLDABLE, R.integer.BUTTON_STICK_L_Y_FOLDABLE), + 1.0f ), BUTTON_STICK_R( "button_stick_r", true, Pair(R.integer.BUTTON_STICK_R_X, R.integer.BUTTON_STICK_R_Y), Pair(R.integer.BUTTON_STICK_R_X_PORTRAIT, R.integer.BUTTON_STICK_R_Y_PORTRAIT), - Pair(R.integer.BUTTON_STICK_R_X_FOLDABLE, R.integer.BUTTON_STICK_R_Y_FOLDABLE) + Pair(R.integer.BUTTON_STICK_R_X_FOLDABLE, R.integer.BUTTON_STICK_R_Y_FOLDABLE), + 1.0f ), STICK_L( "stick_l", true, Pair(R.integer.STICK_L_X, R.integer.STICK_L_Y), Pair(R.integer.STICK_L_X_PORTRAIT, R.integer.STICK_L_Y_PORTRAIT), - Pair(R.integer.STICK_L_X_FOLDABLE, R.integer.STICK_L_Y_FOLDABLE) + Pair(R.integer.STICK_L_X_FOLDABLE, R.integer.STICK_L_Y_FOLDABLE), + 1.0f ), STICK_R( "stick_r", true, Pair(R.integer.STICK_R_X, R.integer.STICK_R_Y), Pair(R.integer.STICK_R_X_PORTRAIT, R.integer.STICK_R_Y_PORTRAIT), - Pair(R.integer.STICK_R_X_FOLDABLE, R.integer.STICK_R_Y_FOLDABLE) + Pair(R.integer.STICK_R_X_FOLDABLE, R.integer.STICK_R_Y_FOLDABLE), + 1.0f ), COMBINED_DPAD( "combined_dpad", true, Pair(R.integer.COMBINED_DPAD_X, R.integer.COMBINED_DPAD_Y), Pair(R.integer.COMBINED_DPAD_X_PORTRAIT, R.integer.COMBINED_DPAD_Y_PORTRAIT), - Pair(R.integer.COMBINED_DPAD_X_FOLDABLE, R.integer.COMBINED_DPAD_Y_FOLDABLE) + Pair(R.integer.COMBINED_DPAD_X_FOLDABLE, R.integer.COMBINED_DPAD_Y_FOLDABLE), + 1.0f ); fun getDefaultPositionForLayout(layout: OverlayLayout): Pair { @@ -173,7 +191,8 @@ enum class OverlayControl( defaultVisibility, getDefaultPositionForLayout(OverlayLayout.Landscape), getDefaultPositionForLayout(OverlayLayout.Portrait), - getDefaultPositionForLayout(OverlayLayout.Foldable) + getDefaultPositionForLayout(OverlayLayout.Foldable), + defaultIndividualScaleResource ) companion object { diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControlData.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControlData.kt index 26cfeb1db5..6cc5a59c98 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControlData.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControlData.kt @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later package org.yuzu.yuzu_emu.overlay.model @@ -8,7 +8,8 @@ data class OverlayControlData( var enabled: Boolean, var landscapePosition: Pair, var portraitPosition: Pair, - var foldablePosition: Pair + var foldablePosition: Pair, + var individualScale: Float ) { fun positionFromLayout(layout: OverlayLayout): Pair = when (layout) { diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index cfed4d08ec..956d93a4eb 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt @@ -48,6 +48,7 @@ import java.io.BufferedOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipInputStream import androidx.core.content.edit +import org.yuzu.yuzu_emu.activities.EmulationActivity import kotlin.text.compareTo class MainActivity : AppCompatActivity(), ThemeProvider { @@ -188,6 +189,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider { if (it) checkKeys() } + // Dismiss previous notifications (should not happen unless a crash occurred) + EmulationActivity.stopForegroundService(this) + setInsets() } @@ -293,6 +297,11 @@ class MainActivity : AppCompatActivity(), ThemeProvider { themeId = resId } + override fun onDestroy() { + EmulationActivity.stopForegroundService(this) + super.onDestroy() + } + val getGamesDirectory = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { result -> if (result != null) { diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt index de0794a17f..5325f688b6 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later package org.yuzu.yuzu_emu.utils @@ -170,7 +170,8 @@ object DirectoryInitialization { buttonEnabled, Pair(landscapeXPosition, landscapeYPosition), Pair(portraitXPosition, portraitYPosition), - Pair(foldableXPosition, foldableYPosition) + Pair(foldableXPosition, foldableYPosition), + OverlayControl.map[buttonId]?.defaultIndividualScaleResource ?: 1.0f ) overlayControlDataMap[buttonId] = controlData setOverlayData = true diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ForegroundService.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ForegroundService.kt new file mode 100644 index 0000000000..c181656d99 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ForegroundService.kt @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +package org.yuzu.yuzu_emu.utils + +import android.app.PendingIntent +import android.app.Service +import android.content.Intent +import android.os.IBinder +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import org.yuzu.yuzu_emu.R +import org.yuzu.yuzu_emu.activities.EmulationActivity + +/** + * A service that shows a permanent notification in the background to avoid the app getting + * cleared from memory by the system. + */ +class ForegroundService : Service() { + companion object { + const val EMULATION_RUNNING_NOTIFICATION = 0x1000 + + const val ACTION_STOP = "stop" + } + + private fun showRunningNotification() { + // Intent is used to resume emulation if the notification is clicked + val contentIntent = PendingIntent.getActivity( + this, + 0, + Intent(this, EmulationActivity::class.java), + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + ) + val builder = + NotificationCompat.Builder(this, getString(R.string.app_notification_channel_id)) + .setSmallIcon(R.drawable.ic_stat_notification_logo) + .setContentTitle(getString(R.string.app_name)) + .setContentText(getString(R.string.app_notification_running)) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setOngoing(true) + .setVibrate(null) + .setSound(null) + .setContentIntent(contentIntent) + startForeground(EMULATION_RUNNING_NOTIFICATION, builder.build()) + } + + override fun onBind(intent: Intent): IBinder? { + return null + } + + override fun onCreate() { + showRunningNotification() + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (intent?.action == ACTION_STOP) { + try { + NotificationManagerCompat.from(this).cancel(EMULATION_RUNNING_NOTIFICATION) + stopForeground(STOP_FOREGROUND_REMOVE) + } catch (e: Exception) { + Log.error("Failed to stop foreground service") + } + stopSelfResult(startId) + return START_NOT_STICKY + } + + if (intent != null) { + showRunningNotification() + } + return START_STICKY + } + + override fun onDestroy() = + NotificationManagerCompat.from(this).cancel(EMULATION_RUNNING_NOTIFICATION) +} diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt index 8a66ebf11f..2c35e7349a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt @@ -19,6 +19,7 @@ import org.yuzu.yuzu_emu.adapters.GameAdapter import androidx.core.view.doOnNextLayout import org.yuzu.yuzu_emu.YuzuApplication import androidx.preference.PreferenceManager +import androidx.core.view.WindowInsetsCompat /** * CarouselRecyclerView encapsulates all carousel logic for the games UI. @@ -205,8 +206,8 @@ class CarouselRecyclerView @JvmOverloads constructor( if (enabled) { useCustomDrawingOrder = true - val insets = rootWindowInsets - val bottomInset = insets?.getInsets(android.view.WindowInsets.Type.systemBars())?.bottom ?: 0 + val insets = rootWindowInsets?.let { WindowInsetsCompat.toWindowInsetsCompat(it, this) } + val bottomInset = insets?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: 0 val internalFactor = resources.getFraction(R.fraction.carousel_card_size_factor, 1, 1) val userFactor = preferences.getFloat(CAROUSEL_CARD_SIZE_FACTOR, internalFactor).coerceIn( 0f, diff --git a/src/android/app/src/main/jni/android_config.cpp b/src/android/app/src/main/jni/android_config.cpp index a79a64afbb..41ac680d6b 100644 --- a/src/android/app/src/main/jni/android_config.cpp +++ b/src/android/app/src/main/jni/android_config.cpp @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later #include #include @@ -103,6 +103,7 @@ void AndroidConfig::ReadOverlayValues() { ReadDoubleSetting(std::string("foldable\\x_position")); control_data.foldable_position.second = ReadDoubleSetting(std::string("foldable\\y_position")); + control_data.individual_scale = static_cast(ReadDoubleSetting(std::string("individual_scale"))); AndroidSettings::values.overlay_control_data.push_back(control_data); } EndArray(); @@ -255,6 +256,7 @@ void AndroidConfig::SaveOverlayValues() { control_data.foldable_position.first); WriteDoubleSetting(std::string("foldable\\y_position"), control_data.foldable_position.second); + WriteDoubleSetting(std::string("individual_scale"), static_cast(control_data.individual_scale)); } EndArray(); diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index cd18f1e5b3..c9e59ce105 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h @@ -24,6 +24,7 @@ namespace AndroidSettings { std::pair landscape_position; std::pair portrait_position; std::pair foldable_position; + float individual_scale; }; struct Values { @@ -79,6 +80,15 @@ namespace AndroidSettings { Settings::Category::Overlay, Settings::Specialization::Paired, true, true}; + Settings::Setting enable_input_overlay_auto_hide{linkage, false, + "enable_input_overlay_auto_hide", + Settings::Category::Overlay, + Settings::Specialization::Default, true, + true,}; + + Settings::Setting input_overlay_auto_hide{linkage, 5, "input_overlay_auto_hide", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, &enable_input_overlay_auto_hide}; Settings::Setting perf_overlay_background{linkage, false, "perf_overlay_background", Settings::Category::Overlay, Settings::Specialization::Default, true, diff --git a/src/android/app/src/main/jni/native_config.cpp b/src/android/app/src/main/jni/native_config.cpp index 0b26280c6c..e6021ed217 100644 --- a/src/android/app/src/main/jni/native_config.cpp +++ b/src/android/app/src/main/jni/native_config.cpp @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later #include @@ -369,7 +369,9 @@ jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getOverlayControlData(JN env->NewObject(Common::Android::GetOverlayControlDataClass(), Common::Android::GetOverlayControlDataConstructor(), Common::Android::ToJString(env, control_data.id), control_data.enabled, - jlandscapePosition, jportraitPosition, jfoldablePosition); + jlandscapePosition, jportraitPosition, jfoldablePosition, + control_data.individual_scale); + env->SetObjectArrayElement(joverlayControlDataArray, i, jcontrolData); } return joverlayControlDataArray; @@ -418,9 +420,12 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setOverlayControlData( env, env->GetObjectField(jfoldablePosition, Common::Android::GetPairSecondField()))); + float individual_scale = static_cast(env->GetFloatField( + joverlayControlData, Common::Android::GetOverlayControlDataIndividualScaleField())); + AndroidSettings::values.overlay_control_data.push_back(AndroidSettings::OverlayControlData{ Common::Android::GetJString(env, jidString), enabled, landscape_position, - portrait_position, foldable_position}); + portrait_position, foldable_position, individual_scale}); } } diff --git a/src/android/app/src/main/res/drawable-hdpi/ic_stat_notification_logo.png b/src/android/app/src/main/res/drawable-hdpi/ic_stat_notification_logo.png index 5f82432397..7ea5c71380 100644 Binary files a/src/android/app/src/main/res/drawable-hdpi/ic_stat_notification_logo.png and b/src/android/app/src/main/res/drawable-hdpi/ic_stat_notification_logo.png differ diff --git a/src/android/app/src/main/res/drawable-xhdpi/ic_stat_notification_logo.png b/src/android/app/src/main/res/drawable-xhdpi/ic_stat_notification_logo.png index 9c80904a86..d1b8f5d358 100644 Binary files a/src/android/app/src/main/res/drawable-xhdpi/ic_stat_notification_logo.png and b/src/android/app/src/main/res/drawable-xhdpi/ic_stat_notification_logo.png differ diff --git a/src/android/app/src/main/res/drawable-xhdpi/tv_banner.png b/src/android/app/src/main/res/drawable-xhdpi/tv_banner.png index d1541d8ec6..1b6ee05b59 100644 Binary files a/src/android/app/src/main/res/drawable-xhdpi/tv_banner.png and b/src/android/app/src/main/res/drawable-xhdpi/tv_banner.png differ diff --git a/src/android/app/src/main/res/drawable-xxhdpi/ic_stat_notification_logo.png b/src/android/app/src/main/res/drawable-xxhdpi/ic_stat_notification_logo.png index 63ef14ce0f..1d01126b30 100644 Binary files a/src/android/app/src/main/res/drawable-xxhdpi/ic_stat_notification_logo.png and b/src/android/app/src/main/res/drawable-xxhdpi/ic_stat_notification_logo.png differ diff --git a/src/android/app/src/main/res/drawable/ic_icon_bg.png b/src/android/app/src/main/res/drawable/ic_icon_bg.png index 30b29a32d8..7da2c6a1a3 100644 Binary files a/src/android/app/src/main/res/drawable/ic_icon_bg.png and b/src/android/app/src/main/res/drawable/ic_icon_bg.png differ diff --git a/src/android/app/src/main/res/drawable/ic_icon_bg_orig.png b/src/android/app/src/main/res/drawable/ic_icon_bg_orig.png index 9ebc6ce17c..18325c031a 100644 Binary files a/src/android/app/src/main/res/drawable/ic_icon_bg_orig.png and b/src/android/app/src/main/res/drawable/ic_icon_bg_orig.png differ diff --git a/src/android/app/src/main/res/layout/dialog_overlay_scale.xml b/src/android/app/src/main/res/layout/dialog_overlay_scale.xml new file mode 100644 index 0000000000..9e047f211e --- /dev/null +++ b/src/android/app/src/main/res/layout/dialog_overlay_scale.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/android/app/src/main/res/layout/dialog_spinbox.xml b/src/android/app/src/main/res/layout/dialog_spinbox.xml new file mode 100644 index 0000000000..2f18ab750d --- /dev/null +++ b/src/android/app/src/main/res/layout/dialog_spinbox.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 08ca53ad81..1b66c191d3 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -251,7 +251,9 @@ @string/scaling_filter_nearest_neighbor @string/scaling_filter_bilinear @string/scaling_filter_bicubic + @string/scaling_filter_spline1 @string/scaling_filter_gaussian + @string/scaling_filter_lanczos @string/scaling_filter_scale_force @string/scaling_filter_fsr @string/scaling_filter_area @@ -265,6 +267,8 @@ 4 5 6 + 7 + 8 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index d108907212..e13130de9a 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -8,6 +8,29 @@ noticesAndErrors Shows notifications when something goes wrong. Notification permission not granted! + Eden + Eden + Eden Switch emulator notifications + Eden is Running + Seconds + + + Increment + Decrement + Value + Value must be at least %1$d + Value must be at most %1$d + Invalid value + + + + Overlay Auto Hide + Automatically hide the touch controls overlay after the specified time of inactivity. + Enable Overlay Auto Hide + + Input Overlay + Configure on-screen controls + (Enhanced) @@ -849,6 +872,7 @@ Touchscreen Lock drawer Unlock drawer + Reset Loading settings… @@ -859,12 +883,12 @@ Abort Continue System Archive Not Found - %s is missing. Please dump your system archives.\nContinuing emulation may result in crashes and bugs. + %s is missing. Please dump your system archives.\nContinuing emulation may result in crashes. A system archive Save/Load Error Fatal Error - A fatal error occurred. Check the log for details.\nContinuing emulation may result in crashes and bugs. - Turning off this setting will significantly reduce emulation performance! For the best experience, it is recommended that you leave this setting enabled. + A fatal error occurred. Check the log for details.\nContinuing emulation may result in crashes. + Turning off this setting will significantly degrade performance. It"s recommended that you leave this setting enabled. Device RAM: %1$s\nRecommended: %2$s %1$s %2$s No bootable game present! @@ -935,12 +959,12 @@ Normal High - Extreme (Slow) + Extreme Default - Unsafe (fast) - Safe (stable) + Unsafe + Safe ASTC Decoding Method @@ -986,7 +1010,9 @@ Nearest Neighbor Bilinear Bicubic + Spline-1 Gaussian + Lanczos ScaleForce AMD FidelityFX™ Super Resolution Area diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp index 3dae6069f7..20f6cda3a2 100644 --- a/src/audio_core/renderer/behavior/info_updater.cpp +++ b/src/audio_core/renderer/behavior/info_updater.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/effect/reverb.cpp b/src/audio_core/renderer/command/effect/reverb.cpp index 46b85b8945..87eab1adda 100644 --- a/src/audio_core/renderer/command/effect/reverb.cpp +++ b/src/audio_core/renderer/command/effect/reverb.cpp @@ -191,8 +191,6 @@ static void InitializeReverbEffect(const ReverbInfo::ParameterVersion2& params, const auto center_delay_time{(5 * delay).to_uint_floor()}; state.center_delay_line.Initialize(center_delay_time, 1.0f); - UpdateReverbEffectParameter(params, state); - for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) { std::ranges::fill(state.fdn_delay_lines[i].buffer, 0); std::ranges::fill(state.decay_delay_lines[i].buffer, 0); diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp index 4d7f0c1d5d..b75d743494 100644 --- a/src/audio_core/sink/sink_stream.cpp +++ b/src/audio_core/sink/sink_stream.cpp @@ -293,8 +293,7 @@ void SinkStream::WaitFreeSpace(std::stop_token stop_token) { release_cv.wait_for(lk, std::chrono::milliseconds(5), [this]() { return paused || queued_buffers < max_queue_size; }); if (queued_buffers > max_queue_size + 3) { - Common::CondvarWait(release_cv, lk, stop_token, - [this] { return paused || queued_buffers < max_queue_size; }); + release_cv.wait(lk, stop_token, [this] { return paused || queued_buffers < max_queue_size; }); } } diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 665143900a..96ea429e5a 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -32,7 +32,6 @@ add_library( atomic_ops.h bit_cast.h bit_field.h - bit_set.h bit_util.h bounded_threadsafe_queue.h cityhash.cpp @@ -97,8 +96,6 @@ add_library( memory_detect.h multi_level_page_table.cpp multi_level_page_table.h - nvidia_flags.cpp - nvidia_flags.h overflow.h page_table.cpp page_table.h diff --git a/src/common/android/id_cache.cpp b/src/common/android/id_cache.cpp index e0edd006a5..1198833996 100644 --- a/src/common/android/id_cache.cpp +++ b/src/common/android/id_cache.cpp @@ -1,7 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -// SPDX-FileCopyrightText: 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #include @@ -49,6 +46,7 @@ static jclass s_overlay_control_data_class; static jmethodID s_overlay_control_data_constructor; static jfieldID s_overlay_control_data_id_field; static jfieldID s_overlay_control_data_enabled_field; +static jfieldID s_overlay_control_data_individual_scale_field; static jfieldID s_overlay_control_data_landscape_position_field; static jfieldID s_overlay_control_data_portrait_position_field; static jfieldID s_overlay_control_data_foldable_position_field; @@ -244,6 +242,10 @@ namespace Common::Android { return s_overlay_control_data_enabled_field; } + jfieldID GetOverlayControlDataIndividualScaleField() { + return s_overlay_control_data_individual_scale_field; + } + jfieldID GetOverlayControlDataLandscapePositionField() { return s_overlay_control_data_landscape_position_field; } @@ -494,7 +496,7 @@ namespace Common::Android { reinterpret_cast(env->NewGlobalRef(overlay_control_data_class)); s_overlay_control_data_constructor = env->GetMethodID(overlay_control_data_class, "", - "(Ljava/lang/String;ZLkotlin/Pair;Lkotlin/Pair;Lkotlin/Pair;)V"); + "(Ljava/lang/String;ZLkotlin/Pair;Lkotlin/Pair;Lkotlin/Pair;F)V"); s_overlay_control_data_id_field = env->GetFieldID(overlay_control_data_class, "id", "Ljava/lang/String;"); s_overlay_control_data_enabled_field = @@ -505,6 +507,8 @@ namespace Common::Android { env->GetFieldID(overlay_control_data_class, "portraitPosition", "Lkotlin/Pair;"); s_overlay_control_data_foldable_position_field = env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;"); + s_overlay_control_data_individual_scale_field = + env->GetFieldID(overlay_control_data_class, "individualScale", "F"); env->DeleteLocalRef(overlay_control_data_class); const jclass patch_class = env->FindClass("org/yuzu/yuzu_emu/model/Patch"); diff --git a/src/common/android/id_cache.h b/src/common/android/id_cache.h index c56ffcf5c6..6b48f471b7 100644 --- a/src/common/android/id_cache.h +++ b/src/common/android/id_cache.h @@ -1,7 +1,4 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -// SPDX-FileCopyrightText: 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once @@ -67,6 +64,7 @@ jclass GetOverlayControlDataClass(); jmethodID GetOverlayControlDataConstructor(); jfieldID GetOverlayControlDataIdField(); jfieldID GetOverlayControlDataEnabledField(); +jfieldID GetOverlayControlDataIndividualScaleField(); jfieldID GetOverlayControlDataLandscapePositionField(); jfieldID GetOverlayControlDataPortraitPositionField(); jfieldID GetOverlayControlDataFoldablePositionField(); diff --git a/src/common/bit_set.h b/src/common/bit_set.h deleted file mode 100644 index 74754504be..0000000000 --- a/src/common/bit_set.h +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -#include "common/alignment.h" -#include "common/bit_util.h" -#include "common/common_types.h" - -namespace Common { - -namespace impl { - -template -class BitSet { - -public: - constexpr BitSet() = default; - - constexpr void SetBit(size_t i) { - this->words[i / FlagsPerWord] |= GetBitMask(i % FlagsPerWord); - } - - constexpr void ClearBit(size_t i) { - this->words[i / FlagsPerWord] &= ~GetBitMask(i % FlagsPerWord); - } - - constexpr size_t CountLeadingZero() const { - for (size_t i = 0; i < NumWords; i++) { - if (this->words[i]) { - return FlagsPerWord * i + CountLeadingZeroImpl(this->words[i]); - } - } - return FlagsPerWord * NumWords; - } - - constexpr size_t GetNextSet(size_t n) const { - for (size_t i = (n + 1) / FlagsPerWord; i < NumWords; i++) { - Storage word = this->words[i]; - if (!IsAligned(n + 1, FlagsPerWord)) { - word &= GetBitMask(n % FlagsPerWord) - 1; - } - if (word) { - return FlagsPerWord * i + CountLeadingZeroImpl(word); - } - } - return FlagsPerWord * NumWords; - } - -private: - static_assert(std::is_unsigned_v); - static_assert(sizeof(Storage) <= sizeof(u64)); - - static constexpr size_t FlagsPerWord = BitSize(); - static constexpr size_t NumWords = AlignUp(N, FlagsPerWord) / FlagsPerWord; - - static constexpr auto CountLeadingZeroImpl(Storage word) { - return std::countl_zero(static_cast(word)) - - (BitSize() - FlagsPerWord); - } - - static constexpr Storage GetBitMask(size_t bit) { - return Storage(1) << (FlagsPerWord - 1 - bit); - } - - std::array words{}; -}; - -} // namespace impl - -template -using BitSet8 = impl::BitSet; - -template -using BitSet16 = impl::BitSet; - -template -using BitSet32 = impl::BitSet; - -template -using BitSet64 = impl::BitSet; - -} // namespace Common diff --git a/src/common/bounded_threadsafe_queue.h b/src/common/bounded_threadsafe_queue.h index b36fc1de96..80f32e2553 100644 --- a/src/common/bounded_threadsafe_queue.h +++ b/src/common/bounded_threadsafe_queue.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -123,7 +126,7 @@ private: } else if constexpr (Mode == PopMode::WaitWithStopToken) { // Wait until the queue is not empty. std::unique_lock lock{consumer_cv_mutex}; - Common::CondvarWait(consumer_cv, lock, stop_token, [this, read_index] { + consumer_cv.wait(lock, stop_token, [this, read_index] { return read_index != m_write_index.load(std::memory_order::acquire); }); if (stop_token.stop_requested()) { diff --git a/src/common/fs/file.cpp b/src/common/fs/file.cpp index b0b25eb432..722ba41949 100644 --- a/src/common/fs/file.cpp +++ b/src/common/fs/file.cpp @@ -3,6 +3,7 @@ #include +#include "common/assert.h" #include "common/fs/file.h" #include "common/fs/fs.h" #ifdef ANDROID diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp index 318f311891..a095e0c239 100644 --- a/src/common/fs/path_util.cpp +++ b/src/common/fs/path_util.cpp @@ -9,6 +9,7 @@ #include #include +#include "common/assert.h" #include "common/fs/fs.h" #ifdef ANDROID #include "common/fs/fs_android.h" diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 2e36d59569..3838c12903 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -56,6 +56,16 @@ #include "common/host_memory.h" #include "common/logging/log.h" +#if defined(__ANDROID__) && __ANDROID_API__ < 30 +#include +#ifndef MFD_CLOEXEC +#define MFD_CLOEXEC 0x0001U +#endif +static int memfd_create(const char* name, unsigned int flags) { + return syscall(__NR_memfd_create, name, flags); +} +#endif + namespace Common { constexpr size_t PageAlignment = 0x1000; diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 4621771090..c2cbf3f4a5 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -39,9 +39,17 @@ namespace Common::Log { namespace { -/** - * Interface for logging backends. - */ +/// @brief Trims up to and including the last of ../, ..\, src/, src\ in a string +/// do not be fooled this isn't generating new strings on .rodata :) +constexpr const char* TrimSourcePath(std::string_view source) { + const auto rfind = [source](const std::string_view match) { + return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size()); + }; + auto idx = (std::max)({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")}); + return source.data() + idx; +} + +/// @brief Interface for logging backends. class Backend { public: virtual ~Backend() = default; @@ -53,9 +61,7 @@ public: virtual void Flush() = 0; }; -/** - * Backend that writes to stderr and with color - */ +/// @brief Backend that writes to stderr and with color class ColorConsoleBackend final : public Backend { public: explicit ColorConsoleBackend() = default; @@ -84,9 +90,7 @@ private: std::atomic_bool enabled{false}; }; -/** - * Backend that writes to a file passed into the constructor - */ +/// @brief Backend that writes to a file passed into the constructor class FileBackend final : public Backend { public: explicit FileBackend(const std::filesystem::path& filename) { @@ -248,13 +252,14 @@ public: color_console_backend.SetEnabled(enabled); } + bool CanPushEntry(Class log_class, Level log_level) const noexcept { + return filter.CheckMessage(log_class, log_level); + } + void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, - const char* function, std::string&& message) { - if (!filter.CheckMessage(log_class, log_level)) { - return; - } + const char* function, std::string&& message) noexcept { message_queue.EmplaceWait( - CreateEntry(log_class, log_level, filename, line_num, function, std::move(message))); + CreateEntry(log_class, log_level, TrimSourcePath(filename), line_num, function, std::move(message))); } private: @@ -368,8 +373,9 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, unsigned int line_num, const char* function, fmt::string_view format, const fmt::format_args& args) { if (!initialization_in_progress_suppress_logging) { - Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, - fmt::vformat(format, args)); + auto& instance = Impl::Instance(); + if (instance.CanPushEntry(log_class, log_level)) + instance.PushEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args)); } } } // namespace Common::Log diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 4e3a614a45..813e812780 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -9,22 +12,20 @@ namespace Common::Log { namespace { template Level GetLevelByName(const It begin, const It end) { - for (u8 i = 0; i < static_cast(Level::Count); ++i) { - const char* level_name = GetLevelName(static_cast(i)); - if (Common::ComparePartialString(begin, end, level_name)) { - return static_cast(i); - } + for (u32 i = 0; i < u32(Level::Count); ++i) { + const char* level_name = GetLevelName(Level(i)); + if (Common::ComparePartialString(begin, end, level_name)) + return Level(i); } return Level::Count; } template Class GetClassByName(const It begin, const It end) { - for (u8 i = 0; i < static_cast(Class::Count); ++i) { - const char* level_name = GetLogClassName(static_cast(i)); - if (Common::ComparePartialString(begin, end, level_name)) { - return static_cast(i); - } + for (u32 i = 0; i < u32(Class::Count); ++i) { + const char* level_name = GetLogClassName(Class(i)); + if (Common::ComparePartialString(begin, end, level_name)) + return Class(i); } return Class::Count; } @@ -229,13 +230,12 @@ void Filter::ParseFilterString(std::string_view filter_view) { } bool Filter::CheckMessage(Class log_class, Level level) const { - return static_cast(level) >= - static_cast(class_levels[static_cast(log_class)]); + return u8(level) >= u8(class_levels[std::size_t(log_class)]); } bool Filter::IsDebug() const { return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) { - return static_cast(l) <= static_cast(Level::Debug); + return u8(l) <= u8(Level::Debug); }); } diff --git a/src/common/logging/log.h b/src/common/logging/log.h index bd7a7d7f49..7b23b59aab 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -16,15 +16,6 @@ namespace Common::Log { -// trims up to and including the last of ../, ..\, src/, src\ in a string -constexpr const char* TrimSourcePath(std::string_view source) { - const auto rfind = [source](const std::string_view match) { - return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size()); - }; - auto idx = (std::max)({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")}); - return source.data() + idx; -} - /// Logs a message to the global logger, using fmt void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, unsigned int line_num, const char* function, fmt::string_view format, @@ -42,7 +33,7 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig #ifdef _DEBUG #define LOG_TRACE(log_class, ...) \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __FILE__, __LINE__, __func__, \ __VA_ARGS__) #else #define LOG_TRACE(log_class, fmt, ...) (void(0)) @@ -50,21 +41,21 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig #define LOG_DEBUG(log_class, ...) \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __FILE__, __LINE__, __func__, \ __VA_ARGS__) #define LOG_INFO(log_class, ...) \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __FILE__, __LINE__, __func__, \ __VA_ARGS__) #define LOG_WARNING(log_class, ...) \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __FILE__, __LINE__, __func__, \ __VA_ARGS__) #define LOG_ERROR(log_class, ...) \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __FILE__, __LINE__, __func__, \ __VA_ARGS__) #define LOG_CRITICAL(log_class, ...) \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __FILE__, __LINE__, __func__, \ __VA_ARGS__) diff --git a/src/common/nvidia_flags.cpp b/src/common/nvidia_flags.cpp deleted file mode 100644 index baca31b0ac..0000000000 --- a/src/common/nvidia_flags.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include - -#include - -#include "common/fs/fs.h" -#include "common/fs/path_util.h" -#include "common/nvidia_flags.h" - -namespace Common { - -void ConfigureNvidiaEnvironmentFlags() { -#ifdef _WIN32 - const auto nvidia_shader_dir = - Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir) / "nvidia"; - - if (!Common::FS::CreateDirs(nvidia_shader_dir)) { - return; - } - - const auto windows_path_string = - Common::FS::PathToUTF8String(nvidia_shader_dir.lexically_normal()); - - void(_putenv(fmt::format("__GL_SHADER_DISK_CACHE_PATH={}", windows_path_string).c_str())); - void(_putenv("__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1")); - void(_putenv("__GL_THREADED_OPTIMIZATIONS=1")); -#endif -} - -} // namespace Common diff --git a/src/common/nvidia_flags.h b/src/common/nvidia_flags.h deleted file mode 100644 index 8c3b1bfb92..0000000000 --- a/src/common/nvidia_flags.h +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -namespace Common { - -/// Configure platform specific flags for Nvidia's driver -void ConfigureNvidiaEnvironmentFlags(); - -} // namespace Common diff --git a/src/common/polyfill_thread.h b/src/common/polyfill_thread.h index 12e59a8939..0d3c963d25 100644 --- a/src/common/polyfill_thread.h +++ b/src/common/polyfill_thread.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -7,23 +10,13 @@ #pragma once -#include - -#ifdef __cpp_lib_jthread - #include #include -#include #include #include namespace Common { -template -void CondvarWait(Condvar& cv, std::unique_lock& lk, std::stop_token token, Pred&& pred) { - cv.wait(lk, token, std::forward(pred)); -} - template bool StoppableTimedWait(std::stop_token token, const std::chrono::duration& rel_time) { std::condition_variable_any cv; @@ -35,341 +28,3 @@ bool StoppableTimedWait(std::stop_token token, const std::chrono::duration -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace std { -namespace polyfill { - -using stop_state_callback = size_t; - -class stop_state { -public: - stop_state() = default; - ~stop_state() = default; - - bool request_stop() { - unique_lock lk{m_lock}; - - if (m_stop_requested) { - // Already set, nothing to do. - return false; - } - - // Mark stop requested. - m_stop_requested = true; - - while (!m_callbacks.empty()) { - // Get an iterator to the first element. - const auto it = m_callbacks.begin(); - - // Move the callback function out of the map. - function f; - swap(it->second, f); - - // Erase the now-empty map element. - m_callbacks.erase(it); - - // Run the callback. - if (f) { - f(); - } - } - - return true; - } - - bool stop_requested() const { - unique_lock lk{m_lock}; - return m_stop_requested; - } - - stop_state_callback insert_callback(function f) { - unique_lock lk{m_lock}; - - if (m_stop_requested) { - // Stop already requested. Don't insert anything, - // just run the callback synchronously. - if (f) { - f(); - } - return 0; - } - - // Insert the callback. - stop_state_callback ret = ++m_next_callback; - m_callbacks.emplace(ret, std::move(f)); - return ret; - } - - void remove_callback(stop_state_callback cb) { - unique_lock lk{m_lock}; - m_callbacks.erase(cb); - } - -private: - mutable recursive_mutex m_lock; - map> m_callbacks; - stop_state_callback m_next_callback{0}; - bool m_stop_requested{false}; -}; - -} // namespace polyfill - -class stop_token; -class stop_source; -struct nostopstate_t { - explicit nostopstate_t() = default; -}; -inline constexpr nostopstate_t nostopstate{}; - -template -class stop_callback; - -class stop_token { -public: - stop_token() noexcept = default; - - stop_token(const stop_token&) noexcept = default; - stop_token(stop_token&&) noexcept = default; - stop_token& operator=(const stop_token&) noexcept = default; - stop_token& operator=(stop_token&&) noexcept = default; - ~stop_token() = default; - - void swap(stop_token& other) noexcept { - m_stop_state.swap(other.m_stop_state); - } - - [[nodiscard]] bool stop_requested() const noexcept { - return m_stop_state && m_stop_state->stop_requested(); - } - [[nodiscard]] bool stop_possible() const noexcept { - return m_stop_state != nullptr; - } - -private: - friend class stop_source; - template - friend class stop_callback; - stop_token(shared_ptr stop_state) : m_stop_state(std::move(stop_state)) {} - -private: - shared_ptr m_stop_state; -}; - -class stop_source { -public: - stop_source() : m_stop_state(make_shared()) {} - explicit stop_source(nostopstate_t) noexcept {} - - stop_source(const stop_source&) noexcept = default; - stop_source(stop_source&&) noexcept = default; - stop_source& operator=(const stop_source&) noexcept = default; - stop_source& operator=(stop_source&&) noexcept = default; - ~stop_source() = default; - void swap(stop_source& other) noexcept { - m_stop_state.swap(other.m_stop_state); - } - - [[nodiscard]] stop_token get_token() const noexcept { - return stop_token(m_stop_state); - } - [[nodiscard]] bool stop_possible() const noexcept { - return m_stop_state != nullptr; - } - [[nodiscard]] bool stop_requested() const noexcept { - return m_stop_state && m_stop_state->stop_requested(); - } - bool request_stop() noexcept { - return m_stop_state && m_stop_state->request_stop(); - } - -private: - friend class jthread; - explicit stop_source(shared_ptr stop_state) - : m_stop_state(std::move(stop_state)) {} - -private: - shared_ptr m_stop_state; -}; - -template -class stop_callback { - static_assert(is_nothrow_destructible_v); - static_assert(is_invocable_v); - -public: - using callback_type = Callback; - - template - requires constructible_from - explicit stop_callback(const stop_token& st, - C&& cb) noexcept(is_nothrow_constructible_v) - : m_stop_state(st.m_stop_state) { - if (m_stop_state) { - m_callback = m_stop_state->insert_callback(std::move(cb)); - } - } - template - requires constructible_from - explicit stop_callback(stop_token&& st, - C&& cb) noexcept(is_nothrow_constructible_v) - : m_stop_state(std::move(st.m_stop_state)) { - if (m_stop_state) { - m_callback = m_stop_state->insert_callback(std::move(cb)); - } - } - ~stop_callback() { - if (m_stop_state && m_callback) { - m_stop_state->remove_callback(m_callback); - } - } - - stop_callback(const stop_callback&) = delete; - stop_callback(stop_callback&&) = delete; - stop_callback& operator=(const stop_callback&) = delete; - stop_callback& operator=(stop_callback&&) = delete; - -private: - shared_ptr m_stop_state; - polyfill::stop_state_callback m_callback; -}; - -template -stop_callback(stop_token, Callback) -> stop_callback; - -class jthread { -public: - using id = thread::id; - using native_handle_type = thread::native_handle_type; - - jthread() noexcept = default; - - template , jthread>>> - explicit jthread(F&& f, Args&&... args) - : m_stop_state(make_shared()), - m_thread(make_thread(std::forward(f), std::forward(args)...)) {} - - ~jthread() { - if (joinable()) { - request_stop(); - join(); - } - } - - jthread(const jthread&) = delete; - jthread(jthread&&) noexcept = default; - jthread& operator=(const jthread&) = delete; - - jthread& operator=(jthread&& other) noexcept { - m_thread.swap(other.m_thread); - m_stop_state.swap(other.m_stop_state); - return *this; - } - - void swap(jthread& other) noexcept { - m_thread.swap(other.m_thread); - m_stop_state.swap(other.m_stop_state); - } - [[nodiscard]] bool joinable() const noexcept { - return m_thread.joinable(); - } - void join() { - m_thread.join(); - } - void detach() { - m_thread.detach(); - m_stop_state.reset(); - } - - [[nodiscard]] id get_id() const noexcept { - return m_thread.get_id(); - } - [[nodiscard]] native_handle_type native_handle() { - return m_thread.native_handle(); - } - [[nodiscard]] stop_source get_stop_source() noexcept { - return stop_source(m_stop_state); - } - [[nodiscard]] stop_token get_stop_token() const noexcept { - return stop_source(m_stop_state).get_token(); - } - bool request_stop() noexcept { - return get_stop_source().request_stop(); - } - [[nodiscard]] static unsigned int hardware_concurrency() noexcept { - return thread::hardware_concurrency(); - } - -private: - template - thread make_thread(F&& f, Args&&... args) { - if constexpr (is_invocable_v, stop_token, decay_t...>) { - return thread(std::forward(f), get_stop_token(), std::forward(args)...); - } else { - return thread(std::forward(f), std::forward(args)...); - } - } - - shared_ptr m_stop_state; - thread m_thread; -}; - -} // namespace std - -namespace Common { - -template -void CondvarWait(Condvar& cv, std::unique_lock& lk, std::stop_token token, Pred pred) { - if (token.stop_requested()) { - return; - } - - std::stop_callback callback(token, [&] { - { std::scoped_lock lk2{*lk.mutex()}; } - cv.notify_all(); - }); - - cv.wait(lk, [&] { return pred() || token.stop_requested(); }); -} - -template -bool StoppableTimedWait(std::stop_token token, const std::chrono::duration& rel_time) { - if (token.stop_requested()) { - return false; - } - - bool stop_requested = false; - std::condition_variable cv; - std::mutex m; - - std::stop_callback cb(token, [&] { - // Wake up the waiting thread. - { - std::scoped_lock lk{m}; - stop_requested = true; - } - cv.notify_one(); - }); - - // Perform the timed wait. - std::unique_lock lk{m}; - return !cv.wait_for(lk, rel_time, [&] { return stop_requested; }); -} - -} // namespace Common - -#endif diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in index 1630ceae83..60c9c119f9 100644 --- a/src/common/scm_rev.cpp.in +++ b/src/common/scm_rev.cpp.in @@ -18,6 +18,9 @@ #define TITLE_BAR_FORMAT_RUNNING "@TITLE_BAR_FORMAT_RUNNING@" #define IS_DEV_BUILD @IS_DEV_BUILD@ #define COMPILER_ID "@CXX_COMPILER@" +#define BUILD_AUTO_UPDATE_WEBSITE "@BUILD_AUTO_UPDATE_WEBSITE@" +#define BUILD_AUTO_UPDATE_API "@BUILD_AUTO_UPDATE_API@" +#define BUILD_AUTO_UPDATE_REPO "@BUILD_AUTO_UPDATE_REPO@" namespace Common { @@ -34,4 +37,8 @@ constexpr const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING; constexpr const char g_compiler_id[] = COMPILER_ID; constexpr const bool g_is_dev_build = IS_DEV_BUILD; +constexpr const char g_build_auto_update_website[] = BUILD_AUTO_UPDATE_WEBSITE; +constexpr const char g_build_auto_update_api[] = BUILD_AUTO_UPDATE_API; +constexpr const char g_build_auto_update_repo[] = BUILD_AUTO_UPDATE_REPO; + } // namespace Common diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h index 8f48241557..b89de95a3d 100644 --- a/src/common/scm_rev.h +++ b/src/common/scm_rev.h @@ -21,5 +21,8 @@ extern const char g_title_bar_format_running[]; extern const char g_shader_cache_version[]; extern const char g_compiler_id[]; extern const bool g_is_dev_build; +extern const char g_build_auto_update_website[]; +extern const char g_build_auto_update_api[]; +extern const char g_build_auto_update_repo[]; } // namespace Common diff --git a/src/common/settings.h b/src/common/settings.h index 8605445837..891bde608c 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -178,7 +178,7 @@ struct Values { SwitchableSetting audio_input_device_id{ linkage, "auto", "input_device", Category::Audio, Specialization::RuntimeList}; SwitchableSetting sound_index{ - linkage, AudioMode::Stereo, AudioMode::Mono, AudioMode::Surround, + linkage, AudioMode::Stereo, "sound_index", Category::SystemAudio, Specialization::Default, true, true}; SwitchableSetting volume{linkage, @@ -199,8 +199,6 @@ struct Values { SwitchableSetting use_multi_core{linkage, true, "use_multi_core", Category::Core}; SwitchableSetting memory_layout_mode{linkage, MemoryLayout::Memory_4Gb, - MemoryLayout::Memory_4Gb, - MemoryLayout::Memory_12Gb, "memory_layout_mode", Category::Core, Specialization::Default, @@ -240,9 +238,8 @@ struct Values { #endif "cpu_backend", Category::Cpu}; - SwitchableSetting cpu_accuracy{linkage, CpuAccuracy::Auto, - CpuAccuracy::Auto, CpuAccuracy::Paranoid, - "cpu_accuracy", Category::Cpu}; + SwitchableSetting cpu_accuracy{linkage, CpuAccuracy::Auto, + "cpu_accuracy", Category::Cpu}; SwitchableSetting use_fast_cpu_time{linkage, false, @@ -324,10 +321,10 @@ struct Values { // Renderer SwitchableSetting renderer_backend{ - linkage, RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, + linkage, RendererBackend::Vulkan, "backend", Category::Renderer}; SwitchableSetting shader_backend{ - linkage, ShaderBackend::SpirV, ShaderBackend::Glsl, ShaderBackend::SpirV, + linkage, ShaderBackend::SpirV, "shader_backend", Category::Renderer, Specialization::RuntimeList}; SwitchableSetting vulkan_device{linkage, 0, "vulkan_device", Category::Renderer, Specialization::RuntimeList}; @@ -342,8 +339,6 @@ struct Values { Category::Renderer}; SwitchableSetting optimize_spirv_output{linkage, SpirvOptimizeMode::Never, - SpirvOptimizeMode::Never, - SpirvOptimizeMode::Always, "optimize_spirv_output", Category::Renderer}; SwitchableSetting use_asynchronous_gpu_emulation{ @@ -354,12 +349,10 @@ struct Values { #else AstcDecodeMode::Gpu, #endif - AstcDecodeMode::Cpu, - AstcDecodeMode::CpuAsynchronous, "accelerate_astc", Category::Renderer}; SwitchableSetting vsync_mode{ - linkage, VSyncMode::Fifo, VSyncMode::Immediate, VSyncMode::FifoRelaxed, + linkage, VSyncMode::Fifo, "use_vsync", Category::Renderer, Specialization::RuntimeList, true, true}; SwitchableSetting nvdec_emulation{linkage, NvdecEmulation::Gpu, @@ -372,8 +365,6 @@ struct Values { #else FullscreenMode::Exclusive, #endif - FullscreenMode::Borderless, - FullscreenMode::Exclusive, "fullscreen_mode", Category::Renderer, Specialization::Default, @@ -381,8 +372,6 @@ struct Values { true}; SwitchableSetting aspect_ratio{linkage, AspectRatio::R16_9, - AspectRatio::R16_9, - AspectRatio::Stretch, "aspect_ratio", Category::Renderer, Specialization::Default, @@ -430,8 +419,6 @@ struct Values { #else GpuAccuracy::High, #endif - GpuAccuracy::Normal, - GpuAccuracy::Extreme, "gpu_accuracy", Category::RendererAdvanced, Specialization::Default, @@ -442,8 +429,6 @@ struct Values { SwitchableSetting dma_accuracy{linkage, DmaAccuracy::Default, - DmaAccuracy::Default, - DmaAccuracy::Safe, "dma_accuracy", Category::RendererAdvanced, Specialization::Default, @@ -456,20 +441,14 @@ struct Values { #else AnisotropyMode::Automatic, #endif - AnisotropyMode::Automatic, - AnisotropyMode::X16, "max_anisotropy", Category::RendererAdvanced}; SwitchableSetting astc_recompression{linkage, AstcRecompression::Uncompressed, - AstcRecompression::Uncompressed, - AstcRecompression::Bc3, "astc_recompression", Category::RendererAdvanced}; SwitchableSetting vram_usage_mode{linkage, VramUsageMode::Conservative, - VramUsageMode::Conservative, - VramUsageMode::Aggressive, "vram_usage_mode", Category::RendererAdvanced}; SwitchableSetting skip_cpu_inner_invalidation{linkage, @@ -595,14 +574,10 @@ struct Values { // System SwitchableSetting language_index{linkage, Language::EnglishAmerican, - Language::Japanese, - Language::Serbian, "language_index", Category::System}; - SwitchableSetting region_index{linkage, Region::Usa, Region::Japan, - Region::Taiwan, "region_index", Category::System}; - SwitchableSetting time_zone_index{linkage, TimeZone::Auto, - TimeZone::Auto, TimeZone::Zulu, + SwitchableSetting region_index{linkage, Region::Usa, "region_index", Category::System}; + SwitchableSetting time_zone_index{linkage, TimeZone::Auto, "time_zone_index", Category::System}; // Measured in seconds since epoch SwitchableSetting custom_rtc_enabled{ diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index ebfa4ceb9e..0e5a08d845 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -10,6 +10,7 @@ #pragma once #include +#include #include #include #include "common/common_types.h" @@ -18,8 +19,10 @@ namespace Settings { template struct EnumMetadata { - static std::vector> Canonicalizations(); + static std::vector> Canonicalizations(); static u32 Index(); + static constexpr T GetFirst(); + static constexpr T GetLast(); }; #define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__)) @@ -69,138 +72,101 @@ struct EnumMetadata { #define PAIR_1(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_2(N, __VA_ARGS__)) #define PAIR(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_1(N, __VA_ARGS__)) -#define ENUM(NAME, ...) \ - enum class NAME : u32 { __VA_ARGS__ }; \ - template <> \ - inline std::vector> EnumMetadata::Canonicalizations() { \ - return {PAIR(NAME, __VA_ARGS__)}; \ - } \ - template <> \ - inline u32 EnumMetadata::Index() { \ - return __COUNTER__; \ +#define PP_HEAD(A, ...) A + +#define ENUM(NAME, ...) \ + enum class NAME : u32 { __VA_ARGS__ }; \ + template<> inline std::vector> EnumMetadata::Canonicalizations() { \ + return {PAIR(NAME, __VA_ARGS__)}; \ + } \ + template<> inline u32 EnumMetadata::Index() { \ + return __COUNTER__; \ + } \ + template<> inline constexpr NAME EnumMetadata::GetFirst() { \ + return NAME::PP_HEAD(__VA_ARGS__); \ + } \ + template<> inline constexpr NAME EnumMetadata::GetLast() { \ + return (std::vector>{PAIR(NAME, __VA_ARGS__)}).back().second; \ } // AudioEngine must be specified discretely due to having existing but slightly different // canonicalizations // TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id -enum class AudioEngine : u32 { - Auto, - Cubeb, - Sdl2, - Null, - Oboe, -}; - -template <> -inline std::vector> -EnumMetadata::Canonicalizations() { +enum class AudioEngine : u32 { Auto, Cubeb, Sdl2, Null, Oboe, }; +template<> +inline std::vector> EnumMetadata::Canonicalizations() { return { {"auto", AudioEngine::Auto}, {"cubeb", AudioEngine::Cubeb}, {"sdl2", AudioEngine::Sdl2}, {"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe}, }; } - -template <> +/// @brief This is just a sufficiently large number that is more than the number of other enums declared here +template<> inline u32 EnumMetadata::Index() { - // This is just a sufficiently large number that is more than the number of other enums declared - // here return 100; } +template<> +inline constexpr AudioEngine EnumMetadata::GetFirst() { + return AudioEngine::Auto; +} +template<> +inline constexpr AudioEngine EnumMetadata::GetLast() { + return AudioEngine::Oboe; +} ENUM(AudioMode, Mono, Stereo, Surround); +static_assert(EnumMetadata::GetFirst() == AudioMode::Mono); +static_assert(EnumMetadata::GetLast() == AudioMode::Surround); ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch, Portuguese, Russian, Taiwanese, EnglishBritish, FrenchCanadian, SpanishLatin, ChineseSimplified, ChineseTraditional, PortugueseBrazilian, Serbian); - ENUM(Region, Japan, Usa, Europe, Australia, China, Korea, Taiwan); - ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt, Gb, GbEire, Gmt, - GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica, - Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt, - Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu); - + GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica, + Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt, + Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu); ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16); - ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous); - ENUM(AstcRecompression, Uncompressed, Bc1, Bc3); - ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed); - ENUM(VramUsageMode, Conservative, Aggressive); - ENUM(RendererBackend, OpenGL, Vulkan, Null); - ENUM(ShaderBackend, Glsl, Glasm, SpirV); - ENUM(GpuAccuracy, Normal, High, Extreme); - ENUM(DmaAccuracy, Default, Unsafe, Safe); - ENUM(CpuBackend, Dynarmic, Nce); - ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid); - ENUM(CpuClock, Boost, Fast) - ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb); - ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); - ENUM(FullscreenMode, Borderless, Exclusive); - ENUM(NvdecEmulation, Off, Cpu, Gpu); - -ENUM(ResolutionSetup, - Res1_4X, - Res1_2X, - Res3_4X, - Res1X, - Res3_2X, - Res2X, - Res3X, - Res4X, - Res5X, - Res6X, - Res7X, - Res8X); - +ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X); ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum); - ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); - ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); - ENUM(ConsoleMode, Handheld, Docked); - ENUM(AppletMode, HLE, LLE); - ENUM(SpirvOptimizeMode, Never, OnLoad, Always); - ENUM(GpuOverclock, Low, Medium, High) - ENUM(TemperatureUnits, Celsius, Fahrenheit) template -inline std::string CanonicalizeEnum(Type id) { +inline std::string_view CanonicalizeEnum(Type id) { const auto group = EnumMetadata::Canonicalizations(); - for (auto& [name, value] : group) { - if (value == id) { + for (auto& [name, value] : group) + if (value == id) return name; - } - } return "unknown"; } template inline Type ToEnum(const std::string& canonicalization) { const auto group = EnumMetadata::Canonicalizations(); - for (auto& [name, value] : group) { - if (name == canonicalization) { + for (auto& [name, value] : group) + if (name == canonicalization) return value; - } - } return {}; } } // namespace Settings diff --git a/src/common/settings_setting.h b/src/common/settings_setting.h index 0aba2e11c9..a7e6bb6168 100644 --- a/src/common/settings_setting.h +++ b/src/common/settings_setting.h @@ -72,10 +72,17 @@ public: u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, BasicSetting* other_setting_ = nullptr) requires(ranged) - : BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization_, - other_setting_), + : BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization_, other_setting_), value{default_val}, default_value{default_val}, maximum{max_val}, minimum{min_val} {} + explicit Setting(Linkage& linkage, const Type& default_val, + const std::string& name, Category category_, + u32 specialization_ = Specialization::Default, bool save_ = true, + bool runtime_modifiable_ = false, BasicSetting* other_setting_ = nullptr) + requires(ranged && std::is_enum_v) + : BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization_, other_setting_), + value{default_val}, default_value{default_val}, maximum{EnumMetadata::GetLast()}, minimum{EnumMetadata::GetFirst()} {} + /** * Returns a reference to the setting's value. * @@ -119,9 +126,6 @@ protected: return value_.has_value() ? std::to_string(*value_) : "none"; } else if constexpr (std::is_same_v) { return value_ ? "true" : "false"; - } else if constexpr (std::is_same_v) { - // Compatibility with old AudioEngine setting being a string - return CanonicalizeEnum(value_); } else if constexpr (std::is_floating_point_v) { return fmt::format("{:f}", value_); } else if constexpr (std::is_enum_v) { @@ -207,7 +211,7 @@ public: [[nodiscard]] std::string Canonicalize() const override final { if constexpr (std::is_enum_v) { - return CanonicalizeEnum(this->GetValue()); + return std::string{CanonicalizeEnum(this->GetValue())}; } else { return ToString(this->GetValue()); } @@ -288,41 +292,32 @@ public: * @param other_setting_ A second Setting to associate to this one in metadata */ template - explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, - Category category_, u32 specialization_ = Specialization::Default, - bool save_ = true, bool runtime_modifiable_ = false, - typename std::enable_if::type other_setting_ = nullptr) - : Setting{ - linkage, default_val, name, category_, specialization_, - save_, runtime_modifiable_, other_setting_} { + explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, Category category_, u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, T* other_setting_ = nullptr) requires(!ranged) + : Setting{ linkage, default_val, name, category_, specialization_, save_, runtime_modifiable_, other_setting_} { linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); }); } virtual ~SwitchableSetting() = default; - /** - * Sets a default value, minimum value, maximum value, and label. - * - * @param linkage Setting registry - * @param default_val Initial value of the setting, and default value of the setting - * @param min_val Sets the minimum allowed value of the setting - * @param max_val Sets the maximum allowed value of the setting - * @param name Label for the setting - * @param category_ Category of the setting AKA INI group - * @param specialization_ Suggestion for how frontend implementations represent this in a config - * @param save_ Suggests that this should or should not be saved to a frontend config file - * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded - * @param other_setting_ A second Setting to associate to this one in metadata - */ + /// @brief Sets a default value, minimum value, maximum value, and label. + /// @param linkage Setting registry + /// @param default_val Initial value of the setting, and default value of the setting + /// @param min_val Sets the minimum allowed value of the setting + /// @param max_val Sets the maximum allowed value of the setting + /// @param name Label for the setting + /// @param category_ Category of the setting AKA INI group + /// @param specialization_ Suggestion for how frontend implementations represent this in a config + /// @param save_ Suggests that this should or should not be saved to a frontend config file + /// @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded + /// @param other_setting_ A second Setting to associate to this one in metadata template - explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, - const Type& max_val, const std::string& name, Category category_, - u32 specialization_ = Specialization::Default, bool save_ = true, - bool runtime_modifiable_ = false, - typename std::enable_if::type other_setting_ = nullptr) - : Setting{linkage, default_val, min_val, - max_val, name, category_, - specialization_, save_, runtime_modifiable_, - other_setting_} { + explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, const Type& max_val, const std::string& name, Category category_, u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, T* other_setting_ = nullptr) requires(ranged) + : Setting{linkage, default_val, min_val, max_val, name, category_, specialization_, save_, runtime_modifiable_, other_setting_} { + linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); }); + } + + template + explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, Category category_, u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, T* other_setting_ = nullptr) requires(ranged) + : Setting{linkage, default_val, EnumMetadata::GetFirst(), EnumMetadata::GetLast(), name, category_, specialization_, save_, runtime_modifiable_, other_setting_} { linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); }); } diff --git a/src/common/thread.h b/src/common/thread.h index c6976fb6cd..5ab495baaa 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2013 Dolphin Emulator Project // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -80,7 +83,7 @@ public: condvar.notify_all(); return true; } else { - CondvarWait(condvar, lk, token, + condvar.wait(lk, token, [this, current_generation] { return current_generation != generation; }); return !token.stop_requested(); } diff --git a/src/common/thread_worker.h b/src/common/thread_worker.h index 260ad44e45..6ec9d6a2bd 100644 --- a/src/common/thread_worker.h +++ b/src/common/thread_worker.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -47,8 +50,8 @@ public: if (requests.empty()) { wait_condition.notify_all(); } - Common::CondvarWait(condition, lock, stop_token, - [this] { return !requests.empty(); }); + condition.wait(lock, stop_token, + [this] { return !requests.empty(); }); if (stop_token.stop_requested()) { break; } diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h index 2ef1da0644..f9fc0ca171 100644 --- a/src/common/threadsafe_queue.h +++ b/src/common/threadsafe_queue.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2010 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -99,7 +102,11 @@ public: T PopWait(std::stop_token stop_token) { if (Empty()) { std::unique_lock lock{cv_mutex}; - Common::CondvarWait(cv, lock, stop_token, [this] { return !Empty(); }); + if constexpr (with_stop_token) { + cv.wait(lock, stop_token, [this] { return !Empty(); }); + } else { + cv.wait(lock, [this] { return !Empty(); }); + } } if (stop_token.stop_requested()) { return T{}; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 6b64ab7820..62dab070e3 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1224,7 +1224,7 @@ if (HAS_NCE) arm/nce/patcher.h arm/nce/visitor_base.h ) - target_link_libraries(core PRIVATE merry::mcl merry::oaknut) + target_link_libraries(core PRIVATE merry::oaknut) endif() if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) @@ -1274,8 +1274,4 @@ if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(core PRIVATE precompiled_headers.h) endif() -if (YUZU_ENABLE_LTO) - set_property(TARGET core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) -endif() - create_target_directory_groups(core) diff --git a/src/core/arm/nce/patcher.h b/src/core/arm/nce/patcher.h index 7f54608e3f..31b122477f 100644 --- a/src/core/arm/nce/patcher.h +++ b/src/core/arm/nce/patcher.h @@ -27,11 +27,11 @@ template <> struct std::hash { size_t operator()(const PatchCacheKey& key) const { // Simple XOR hash of first few bytes - size_t hash = 0; + size_t hash_ = 0; for (size_t i = 0; i < key.module_id.size(); ++i) { - hash ^= static_cast(key.module_id[i]) << ((i % sizeof(size_t)) * 8); + hash_ ^= static_cast(key.module_id[i]) << ((i % sizeof(size_t)) * 8); } - return hash ^ std::hash{}(key.offset); + return hash_ ^ std::hash{}(key.offset); } }; diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index edd25644ac..4e3313f83c 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -38,9 +38,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca) reader = std::make_shared(); if (Result rc = reader->Initialize(file, GetCryptoConfiguration(), GetNcaCompressionConfiguration()); R_FAILED(rc)) { - if (rc != ResultInvalidNcaSignature) { - LOG_ERROR(Loader, "File reader errored out during header read: {:#x}", rc.GetInnerValue()); - } status = Loader::ResultStatus::ErrorBadNCAHeader; return; } @@ -85,7 +82,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca) for (s32 i = 0; i < fs_count; i++) { NcaFsHeaderReader header_reader; if (Result rc = fs.OpenStorage(&filesystems[i], &header_reader, i); R_FAILED(rc)) { - LOG_DEBUG(Loader, "File reader errored out during read of section {}: {:#x}", i, rc.GetInnerValue()); status = Loader::ResultStatus::ErrorBadNCAHeader; return; } diff --git a/src/core/file_sys/fssystem/fs_types.h b/src/core/file_sys/fssystem/fs_types.h index 43aeaf447b..f11b7f1dae 100644 --- a/src/core/file_sys/fssystem/fs_types.h +++ b/src/core/file_sys/fssystem/fs_types.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp index 25036b02c1..d496d58cec 100644 --- a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp +++ b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp @@ -1049,13 +1049,11 @@ Result NcaFileSystemDriver::CreatePatchMetaStorage( ASSERT(out_aes_ctr_ex_meta != nullptr); ASSERT(out_indirect_meta != nullptr); ASSERT(base_storage != nullptr); - //ASSERT(patch_info.HasAesCtrExTable()); - //ASSERT(patch_info.HasIndirectTable()); ASSERT(Common::IsAligned(patch_info.aes_ctr_ex_size, NcaHeader::XtsBlockSize)); // Validate patch info extents. - R_UNLESS(patch_info.indirect_size > 0, ResultInvalidNcaPatchInfoIndirectSize); - R_UNLESS(patch_info.aes_ctr_ex_size >= 0, ResultInvalidNcaPatchInfoAesCtrExSize); + R_UNLESS(patch_info.aes_ctr_ex_size >= 0 && patch_info.HasAesCtrExTable(), ResultInvalidNcaPatchInfoAesCtrExSize); + R_UNLESS(patch_info.indirect_size > 0 && patch_info.HasIndirectTable(), ResultInvalidNcaPatchInfoIndirectSize); R_UNLESS(patch_info.indirect_size + patch_info.indirect_offset <= patch_info.aes_ctr_ex_offset, ResultInvalidNcaPatchInfoAesCtrExOffset); R_UNLESS(patch_info.aes_ctr_ex_offset + patch_info.aes_ctr_ex_size <= @@ -1333,10 +1331,30 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl( R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset, ResultRomNcaInvalidIntegrityLayerInfoOffset); } - storage_info[level_hash_info.max_layers - 1] - = std::make_shared(std::move(base_storage), - layer_info.size, - last_layer_info_offset); + + switch (level_hash_info.max_layers - 1) { + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::MasterStorage: + storage_info.SetMasterHashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer1Storage: + storage_info.SetLayer1HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer2Storage: + storage_info.SetLayer2HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer3Storage: + storage_info.SetLayer3HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer4Storage: + storage_info.SetLayer4HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer5Storage: + storage_info.SetLayer5HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::DataStorage: + storage_info.SetDataStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + } // Make the integrity romfs storage. auto integrity_storage = std::make_shared(); diff --git a/src/core/hle/kernel/k_priority_queue.h b/src/core/hle/kernel/k_priority_queue.h index 26677ec65c..99347b5aef 100644 --- a/src/core/hle/kernel/k_priority_queue.h +++ b/src/core/hle/kernel/k_priority_queue.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -5,10 +8,12 @@ #include #include +#include #include +#include +#include "common/alignment.h" #include "common/assert.h" -#include "common/bit_set.h" #include "common/common_types.h" #include "common/concepts.h" @@ -159,7 +164,7 @@ public: } if (m_queues[priority].PushBack(core, member)) { - m_available_priorities[core].SetBit(priority); + m_available_priorities[core].set(std::size_t(priority)); } } @@ -172,7 +177,7 @@ public: } if (m_queues[priority].PushFront(core, member)) { - m_available_priorities[core].SetBit(priority); + m_available_priorities[core].set(std::size_t(priority)); } } @@ -185,14 +190,19 @@ public: } if (m_queues[priority].Remove(core, member)) { - m_available_priorities[core].ClearBit(priority); + m_available_priorities[core].reset(std::size_t(priority)); } } constexpr Member* GetFront(s32 core) const { ASSERT(IsValidCore(core)); - const s32 priority = static_cast(m_available_priorities[core].CountLeadingZero()); + const s32 priority = s32([](auto const& e) { + for (size_t i = 0; i < e.size(); ++i) + if (e[i]) + return i; + return e.size(); + }(m_available_priorities[core])); if (priority <= LowestPriority) { return m_queues[priority].GetFront(core); } else { @@ -211,16 +221,22 @@ public: } } + template + constexpr size_t GetNextSet(std::bitset const& bit, size_t n) const { + for (size_t i = n + 1; i < bit.size(); i++) + if (bit[i]) + return i; + return bit.size(); + } + constexpr Member* GetNext(s32 core, const Member* member) const { ASSERT(IsValidCore(core)); Member* next = member->GetPriorityQueueEntry(core).GetNext(); if (next == nullptr) { - const s32 priority = static_cast( - m_available_priorities[core].GetNextSet(member->GetPriority())); - if (priority <= LowestPriority) { + s32 priority = s32(GetNextSet(m_available_priorities[core], member->GetPriority())); + if (priority <= LowestPriority) next = m_queues[priority].GetFront(core); - } } return next; } @@ -250,7 +266,7 @@ public: private: std::array m_queues{}; - std::array, NumCores> m_available_priorities{}; + std::array, NumCores> m_available_priorities{}; }; private: diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index 6cc8cdf741..ad84f39dc7 100644 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h @@ -8,6 +8,7 @@ #include #include +#include #include "common/math_util.h" #include "core/hle/service/apm/apm_controller.h" @@ -23,6 +24,7 @@ #include "core/hle/service/am/hid_registration.h" #include "core/hle/service/am/lifecycle_manager.h" #include "core/hle/service/am/process_holder.h" +#include "core/hle/service/am/service/storage.h" namespace Service::AM { @@ -97,6 +99,9 @@ struct Applet { std::deque> preselected_user_launch_parameter{}; std::deque> friend_invitation_storage_channel{}; + // Context Stack + std::stack> context_stack{}; + // Caller applet std::weak_ptr caller_applet{}; std::shared_ptr caller_applet_broker{}; diff --git a/src/core/hle/service/am/service/process_winding_controller.cpp b/src/core/hle/service/am/service/process_winding_controller.cpp index 10df830d70..30529de550 100644 --- a/src/core/hle/service/am/service/process_winding_controller.cpp +++ b/src/core/hle/service/am/service/process_winding_controller.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -15,12 +18,12 @@ IProcessWindingController::IProcessWindingController(Core::System& system_, static const FunctionInfo functions[] = { {0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"}, {11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"}, - {21, nullptr, "PushContext"}, - {22, nullptr, "PopContext"}, - {23, nullptr, "CancelWindingReservation"}, - {30, nullptr, "WindAndDoReserved"}, - {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"}, - {41, nullptr, "ReserveToStartAndWait"}, + {21, D<&IProcessWindingController::PushContext>, "PushContext"}, + {22, D<&IProcessWindingController::PopContext>, "PopContext"}, + {23, D<&IProcessWindingController::CancelWindingReservation>, "CancelWindingReservation"}, + {30, D<&IProcessWindingController::WindAndDoReserved>, "WindAndDoReserved"}, + {40, D<&IProcessWindingController::ReserveToStartAndWaitAndUnwindThis>, "ReserveToStartAndWaitAndUnwindThis"}, + {41, D<&IProcessWindingController::ReserveToStartAndWait>, "ReserveToStartAndWait"}, }; // clang-format on @@ -51,4 +54,43 @@ Result IProcessWindingController::OpenCallingLibraryApplet( R_SUCCEED(); } +Result IProcessWindingController::PushContext(SharedPointer context) { + LOG_INFO(Service_AM, "called"); + m_applet->context_stack.push(context); + R_SUCCEED(); +} + +Result IProcessWindingController::PopContext(Out> out_context) { + LOG_INFO(Service_AM, "called"); + + if (m_applet->context_stack.empty()) { + LOG_ERROR(Service_AM, "Context stack is empty"); + R_THROW(ResultUnknown); + } + + *out_context = m_applet->context_stack.top(); + m_applet->context_stack.pop(); + R_SUCCEED(); +} + +Result IProcessWindingController::CancelWindingReservation() { + LOG_WARNING(Service_AM, "STUBBED"); + R_SUCCEED(); +} + +Result IProcessWindingController::WindAndDoReserved() { + LOG_WARNING(Service_AM, "STUBBED"); + R_SUCCEED(); +} + +Result IProcessWindingController::ReserveToStartAndWaitAndUnwindThis() { + LOG_WARNING(Service_AM, "STUBBED"); + R_SUCCEED(); +} + +Result IProcessWindingController::ReserveToStartAndWait() { + LOG_WARNING(Service_AM, "STUBBED"); + R_SUCCEED(); +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/service/process_winding_controller.h b/src/core/hle/service/am/service/process_winding_controller.h index 4408af1f1d..0d53223033 100644 --- a/src/core/hle/service/am/service/process_winding_controller.h +++ b/src/core/hle/service/am/service/process_winding_controller.h @@ -1,8 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once +#include "core/hle/service/am/service/storage.h" #include "core/hle/service/am/am_types.h" #include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" @@ -21,6 +25,12 @@ private: Result GetLaunchReason(Out out_launch_reason); Result OpenCallingLibraryApplet( Out> out_calling_library_applet); + Result PushContext(SharedPointer in_context); + Result PopContext(Out> out_context); + Result CancelWindingReservation(); + Result WindAndDoReserved(); + Result ReserveToStartAndWaitAndUnwindThis(); + Result ReserveToStartAndWait(); const std::shared_ptr m_applet; }; diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp index 1db02b88fd..1b58cbea27 100644 --- a/src/core/hle/service/am/service/self_controller.cpp +++ b/src/core/hle/service/am/service/self_controller.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -67,6 +70,7 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr {110, nullptr, "SetApplicationAlbumUserData"}, {120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"}, {130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"}, + {230, D<&ISelfController::Unknown230>, "Unknown230"}, {1000, nullptr, "GetDebugStorageChannel"}, }; // clang-format on @@ -404,4 +408,12 @@ Result ISelfController::SetRecordVolumeMuted(bool muted) { R_SUCCEED(); } +Result ISelfController::Unknown230(u32 in_val, Out out_val) { + LOG_WARNING(Service_AM, "(STUBBED) called, in_val={}", in_val); + + *out_val = 0; + + R_SUCCEED(); +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h index eca083cfe5..86cd9f1118 100644 --- a/src/core/hle/service/am/service/self_controller.h +++ b/src/core/hle/service/am/service/self_controller.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -63,6 +66,7 @@ private: Result SetAlbumImageTakenNotificationEnabled(bool enabled); Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); Result SetRecordVolumeMuted(bool muted); + Result Unknown230(u32 in_val, Out out_val); Kernel::KProcess* const m_process; const std::shared_ptr m_applet; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index de4197c52d..f7d6c33f77 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -135,8 +135,8 @@ NvResult nvhost_nvdec_common::GetSyncpoint(IoctlGetSyncpoint& params) { } NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { - LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); - params.value = 0; // Seems to be hard coded at 0 + LOG_DEBUG(Service_NVDRV, "called WAITBASE"); + params.value = 0; return NvResult::Success; } diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index b07bd3e58e..68d73f0a59 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -53,6 +53,19 @@ enum class NetDbError : s32 { NoData = 4, }; +static const constexpr std::array blockedDomains = {"srv.nintendo.net", + "battle.net", + "microsoft.com", + "mojang.com", + "xboxlive.com", + "minecraftservices.com"}; + +static bool IsBlockedHost(const std::string& host) { + return std::any_of( + blockedDomains.begin(), blockedDomains.end(), + [&host](const std::string& domain) { return host.find(domain) != std::string::npos; }); +} + static NetDbError GetAddrInfoErrorToNetDbError(GetAddrInfoError result) { // These combinations have been verified on console (but are not // exhaustive). @@ -154,7 +167,7 @@ static std::pair GetHostByNameRequestImpl(HLERequestConte // For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions. // Prevent resolution of Nintendo servers - if (host.find("srv.nintendo.net") != std::string::npos) { + if (IsBlockedHost(host)) { LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); return {0, GetAddrInfoError::AGAIN}; } @@ -271,7 +284,7 @@ static std::pair GetAddrInfoRequestImpl(HLERequestContext const std::string host = Common::StringFromBuffer(host_buffer); // Prevent resolution of Nintendo servers - if (host.find("srv.nintendo.net") != std::string::npos) { + if (IsBlockedHost(host)) { LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); return {0, GetAddrInfoError::AGAIN}; } @@ -359,5 +372,4 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) { rb.Push(ResultSuccess); rb.Push(0); // bsd errno } - } // namespace Service::Sockets diff --git a/src/core/hle/service/ssl/ssl_backend_openssl.cpp b/src/core/hle/service/ssl/ssl_backend_openssl.cpp index 5714e6f3c5..795b69a873 100644 --- a/src/core/hle/service/ssl/ssl_backend_openssl.cpp +++ b/src/core/hle/service/ssl/ssl_backend_openssl.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -286,7 +289,7 @@ Result CheckOpenSSLErrors() { msg.append(data); } Common::Log::FmtLogMessage(Common::Log::Class::Service_SSL, Common::Log::Level::Error, - Common::Log::TrimSourcePath(file), line, func, "OpenSSL: {}", + file, line, func, "OpenSSL: {}", msg); } return ResultInternalError; diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index 9e6bd25913..58efcac747 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -374,7 +374,7 @@ endif() target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS}) target_link_libraries(dynarmic - PRIVATE + PUBLIC fmt::fmt merry::mcl ) diff --git a/src/dynarmic/src/dynarmic/interface/optimization_flags.h b/src/dynarmic/src/dynarmic/interface/optimization_flags.h index 743d902767..9e58197b47 100644 --- a/src/dynarmic/src/dynarmic/interface/optimization_flags.h +++ b/src/dynarmic/src/dynarmic/interface/optimization_flags.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2020 MerryMage * SPDX-License-Identifier: 0BSD @@ -34,6 +37,8 @@ enum class OptimizationFlag : std::uint32_t { MiscIROpt = 0x00000020, /// Optimize for code speed rather than for code size (this serves well for tight loops) CodeSpeed = 0x00000040, + /// Disable verification passes + DisableVerification = 0x00000080, /// This is an UNSAFE optimization that reduces accuracy of fused multiply-add operations. /// This unfuses fused instructions to improve performance on host CPUs without FMA support. diff --git a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp index 844e29023c..e9175f0e6b 100644 --- a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp +++ b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp @@ -1491,9 +1491,9 @@ void Optimize(IR::Block& block, const A32::UserConfig& conf, const Optimization: Optimization::DeadCodeElimination(block); } Optimization::IdentityRemovalPass(block); - //if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { + if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { Optimization::VerificationPass(block); - //} + } } void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization::PolyfillOptions& polyfill_options) { @@ -1511,9 +1511,9 @@ void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization: if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) [[likely]] { Optimization::A64MergeInterpretBlocksPass(block, conf.callbacks); } - //if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { + if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { Optimization::VerificationPass(block); - //} + } } } // namespace Dynarmic::Optimization diff --git a/src/dynarmic/tests/A32/fuzz_arm.cpp b/src/dynarmic/tests/A32/fuzz_arm.cpp index 087ce54813..bef473a491 100644 --- a/src/dynarmic/tests/A32/fuzz_arm.cpp +++ b/src/dynarmic/tests/A32/fuzz_arm.cpp @@ -24,6 +24,7 @@ #include "../rand_int.h" #include "../unicorn_emu/a32_unicorn.h" #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/fp/fpsr.h" #include "dynarmic/common/llvm_disassemble.h" @@ -46,7 +47,7 @@ using namespace Dynarmic; template bool AnyLocationDescriptorForTerminalHas(IR::Terminal terminal, Fn fn) { - return Common::VisitVariant(terminal, [&](auto t) -> bool { + return boost::apply_visitor([&](auto t) -> bool { using T = std::decay_t; if constexpr (std::is_same_v) { return false; @@ -72,7 +73,7 @@ bool AnyLocationDescriptorForTerminalHas(IR::Terminal terminal, Fn fn) { ASSERT_MSG(false, "Invalid terminal type"); return false; } - }); + }, terminal); } bool ShouldTestInst(u32 instruction, u32 pc, bool is_thumb, bool is_last_inst, A32::ITState it_state = {}) { diff --git a/src/dynarmic/tests/A32/fuzz_thumb.cpp b/src/dynarmic/tests/A32/fuzz_thumb.cpp index ad01e5718b..7f64cb0ccb 100644 --- a/src/dynarmic/tests/A32/fuzz_thumb.cpp +++ b/src/dynarmic/tests/A32/fuzz_thumb.cpp @@ -22,6 +22,7 @@ #include "../rand_int.h" #include "../unicorn_emu/a32_unicorn.h" #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/frontend/A32/FPSCR.h" #include "dynarmic/frontend/A32/PSR.h" #include "dynarmic/frontend/A32/a32_location_descriptor.h" diff --git a/src/dynarmic/tests/A32/test_arm_instructions.cpp b/src/dynarmic/tests/A32/test_arm_instructions.cpp index 0411877823..2e7e7dc5d8 100644 --- a/src/dynarmic/tests/A32/test_arm_instructions.cpp +++ b/src/dynarmic/tests/A32/test_arm_instructions.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2016 MerryMage * SPDX-License-Identifier: 0BSD @@ -6,6 +9,7 @@ #include #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/frontend/A32/a32_location_descriptor.h" #include "dynarmic/interface/A32/a32.h" diff --git a/src/dynarmic/tests/A32/test_coprocessor.cpp b/src/dynarmic/tests/A32/test_coprocessor.cpp index 98da0e5d34..3888d2c68b 100644 --- a/src/dynarmic/tests/A32/test_coprocessor.cpp +++ b/src/dynarmic/tests/A32/test_coprocessor.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2022 MerryMage * SPDX-License-Identifier: 0BSD @@ -8,6 +11,7 @@ #include #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/frontend/A32/a32_location_descriptor.h" #include "dynarmic/interface/A32/a32.h" #include "dynarmic/interface/A32/coprocessor.h" diff --git a/src/dynarmic/tests/A32/test_svc.cpp b/src/dynarmic/tests/A32/test_svc.cpp index 8b55d6537c..0be2432c7b 100644 --- a/src/dynarmic/tests/A32/test_svc.cpp +++ b/src/dynarmic/tests/A32/test_svc.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2022 MerryMage * SPDX-License-Identifier: 0BSD @@ -8,6 +11,7 @@ #include #include "./testenv.h" +#include "../native/testenv.h" using namespace Dynarmic; diff --git a/src/dynarmic/tests/A32/test_thumb_instructions.cpp b/src/dynarmic/tests/A32/test_thumb_instructions.cpp index 3501d5419f..d509acdd8d 100644 --- a/src/dynarmic/tests/A32/test_thumb_instructions.cpp +++ b/src/dynarmic/tests/A32/test_thumb_instructions.cpp @@ -10,6 +10,7 @@ #include "dynarmic/common/common_types.h" #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/interface/A32/a32.h" static Dynarmic::A32::UserConfig GetUserConfig(ThumbTestEnv* testenv) { diff --git a/src/dynarmic/tests/A32/testenv.h b/src/dynarmic/tests/A32/testenv.h index a6df2017ce..72eaafce14 100644 --- a/src/dynarmic/tests/A32/testenv.h +++ b/src/dynarmic/tests/A32/testenv.h @@ -17,7 +17,6 @@ #include "dynarmic/common/assert.h" #include "dynarmic/common/common_types.h" #include "dynarmic/interface/A32/a32.h" -#include "../native/testenv.h" template class A32TestEnv : public Dynarmic::A32::UserCallbacks { diff --git a/src/dynarmic/tests/A64/a64.cpp b/src/dynarmic/tests/A64/a64.cpp index 40eff1f071..bc51eca164 100644 --- a/src/dynarmic/tests/A64/a64.cpp +++ b/src/dynarmic/tests/A64/a64.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2018 MerryMage * SPDX-License-Identifier: 0BSD @@ -7,6 +10,7 @@ #include #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/common/fp/fpsr.h" #include "dynarmic/interface/exclusive_monitor.h" diff --git a/src/dynarmic/tests/A64/fp_min_max.cpp b/src/dynarmic/tests/A64/fp_min_max.cpp index d8b45db807..1669b63071 100644 --- a/src/dynarmic/tests/A64/fp_min_max.cpp +++ b/src/dynarmic/tests/A64/fp_min_max.cpp @@ -12,6 +12,7 @@ #include "dynarmic/common/common_types.h" #include "./testenv.h" +#include "../native/testenv.h" using namespace Dynarmic; diff --git a/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp b/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp index 1c3531ebc5..2fb5a7b35e 100644 --- a/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp +++ b/src/dynarmic/tests/A64/fuzz_with_unicorn.cpp @@ -19,6 +19,7 @@ #include "../rand_int.h" #include "../unicorn_emu/a64_unicorn.h" #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/fp/fpsr.h" #include "dynarmic/common/llvm_disassemble.h" diff --git a/src/dynarmic/tests/A64/misaligned_page_table.cpp b/src/dynarmic/tests/A64/misaligned_page_table.cpp index 8235e14a67..fc0bc77428 100644 --- a/src/dynarmic/tests/A64/misaligned_page_table.cpp +++ b/src/dynarmic/tests/A64/misaligned_page_table.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2018 MerryMage * SPDX-License-Identifier: 0BSD @@ -6,6 +9,7 @@ #include #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/interface/A64/a64.h" TEST_CASE("misaligned load/store do not use page_table when detect_misaligned_access_via_page_table is set", "[a64]") { diff --git a/src/dynarmic/tests/A64/real_world.cpp b/src/dynarmic/tests/A64/real_world.cpp index 07532d95af..a083f16d61 100644 --- a/src/dynarmic/tests/A64/real_world.cpp +++ b/src/dynarmic/tests/A64/real_world.cpp @@ -5,6 +5,7 @@ #include #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/interface/A64/a64.h" using namespace Dynarmic; diff --git a/src/dynarmic/tests/A64/test_invalidation.cpp b/src/dynarmic/tests/A64/test_invalidation.cpp index 168043c1cb..0c92f5f606 100644 --- a/src/dynarmic/tests/A64/test_invalidation.cpp +++ b/src/dynarmic/tests/A64/test_invalidation.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2018 MerryMage * SPDX-License-Identifier: 0BSD @@ -6,6 +9,7 @@ #include #include "./testenv.h" +#include "../native/testenv.h" #include "dynarmic/interface/A64/a64.h" using namespace Dynarmic; diff --git a/src/dynarmic/tests/A64/testenv.h b/src/dynarmic/tests/A64/testenv.h index 31e338b138..fcdadb23e6 100644 --- a/src/dynarmic/tests/A64/testenv.h +++ b/src/dynarmic/tests/A64/testenv.h @@ -12,7 +12,6 @@ #include "dynarmic/common/assert.h" #include "dynarmic/common/common_types.h" #include "dynarmic/interface/A64/a64.h" -#include "../native/testenv.h" using Vector = Dynarmic::A64::Vector; diff --git a/src/dynarmic/tests/CMakeLists.txt b/src/dynarmic/tests/CMakeLists.txt index 4ace6c2afd..df90168a52 100644 --- a/src/dynarmic/tests/CMakeLists.txt +++ b/src/dynarmic/tests/CMakeLists.txt @@ -135,6 +135,8 @@ target_include_directories(dynarmic_tests PRIVATE . ../src) target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS}) target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1) -target_compile_options(dynarmic_tests PRIVATE -mavx2) +if ("x86_64" IN_LIST ARCHITECTURE) + target_compile_options(dynarmic_tests PRIVATE -mavx2) +endif() add_test(dynarmic_tests dynarmic_tests --durations yes) diff --git a/src/dynarmic/tests/decoder_tests.cpp b/src/dynarmic/tests/decoder_tests.cpp index e545309960..cdd2c70cd9 100644 --- a/src/dynarmic/tests/decoder_tests.cpp +++ b/src/dynarmic/tests/decoder_tests.cpp @@ -36,22 +36,12 @@ TEST_CASE("ASIMD Decoder: Ensure table order correctness", "[decode][a32][.]") { const auto is_decode_error = [&get_ir](const A32::ASIMDMatcher& matcher, u32 instruction) { const auto block = get_ir(matcher, instruction); - - for (const auto& ir_inst : block) { - if (ir_inst.GetOpcode() == IR::Opcode::A32ExceptionRaised) { - if (static_cast(ir_inst.GetArg(1).GetU64()) == A32::Exception::DecodeError) { - return true; - } - } - } - return false; + return std::find_if(block.cbegin(), block.cend(), [](auto const& e) { + return e.GetOpcode() == IR::Opcode::A32ExceptionRaised && A32::Exception(e.GetArg(1).GetU64()) == A32::Exception::DecodeError; + }) != block.cend(); }; for (auto iter = table.cbegin(); iter != table.cend(); ++iter) { - if (std::strncmp(iter->GetName(), "UNALLOCATED", 11) == 0) { - continue; - } - const u32 expect = iter->GetExpected(); const u32 mask = iter->GetMask(); u32 x = 0; @@ -59,15 +49,17 @@ TEST_CASE("ASIMD Decoder: Ensure table order correctness", "[decode][a32][.]") { const u32 instruction = expect | x; const bool iserr = is_decode_error(*iter, instruction); - const auto alternative = std::find_if(table.cbegin(), iter, [instruction](const auto& m) { return m.Matches(instruction); }); + const auto alternative = std::find_if(table.cbegin(), iter, [instruction](const auto& m) { + return m.Matches(instruction); + }); const bool altiserr = is_decode_error(*alternative, instruction); INFO("Instruction: " << std::hex << std::setfill('0') << std::setw(8) << instruction); INFO("Expect: " << std::hex << std::setfill('0') << std::setw(8) << expect); INFO("Fill: " << std::hex << std::setfill('0') << std::setw(8) << x); - INFO("Name: " << iter->GetName()); + //INFO("Name: " << *A32::GetNameASIMD(instruction)); INFO("iserr: " << iserr); - INFO("alternative: " << alternative->GetName()); + //INFO("alternative: " << alternative->GetName()); INFO("altiserr: " << altiserr); REQUIRE(((!iserr && alternative == iter) || (iserr && alternative != iter && !altiserr))); @@ -75,4 +67,4 @@ TEST_CASE("ASIMD Decoder: Ensure table order correctness", "[decode][a32][.]") { x = ((x | mask) + 1) & ~mask; } while (x != 0); } -} +} \ No newline at end of file diff --git a/src/dynarmic/tests/native/preserve_xmm.cpp b/src/dynarmic/tests/native/preserve_xmm.cpp index 0f69697b7a..7421252063 100644 --- a/src/dynarmic/tests/native/preserve_xmm.cpp +++ b/src/dynarmic/tests/native/preserve_xmm.cpp @@ -6,6 +6,7 @@ #include #include "../A64/testenv.h" +#include "../native/testenv.h" #include "dynarmic/common/fp/fpsr.h" #include "dynarmic/interface/exclusive_monitor.h" diff --git a/src/dynarmic/tests/print_info.cpp b/src/dynarmic/tests/print_info.cpp index 4b6c951c03..3d1268f467 100644 --- a/src/dynarmic/tests/print_info.cpp +++ b/src/dynarmic/tests/print_info.cpp @@ -32,27 +32,26 @@ #include "dynarmic/frontend/A64/translate/a64_translate.h" #include "dynarmic/frontend/A64/translate/impl/impl.h" #include "dynarmic/interface/A32/a32.h" +#include "dynarmic/interface/A32/config.h" #include "dynarmic/interface/A32/disassembler.h" #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/opt_passes.h" using namespace Dynarmic; -const char* GetNameOfA32Instruction(u32 instruction) { - if (auto vfp_decoder = A32::DecodeVFP(instruction)) { - return vfp_decoder->get().GetName(); - } else if (auto asimd_decoder = A32::DecodeASIMD(instruction)) { - return asimd_decoder->get().GetName(); - } else if (auto decoder = A32::DecodeArm(instruction)) { - return decoder->get().GetName(); - } +std::string_view GetNameOfA32Instruction(u32 instruction) { + //if (auto const vfp_decoder = A32::DecodeVFP(instruction)) + // return *A32::GetNameVFP(instruction); + //else if (auto const asimd_decoder = A32::DecodeASIMD(instruction)) + // return *A32::GetNameASIMD(instruction); + //else if (auto const decoder = A32::DecodeArm(instruction)) + // return *A32::GetNameARM(instruction); return ""; } -const char* GetNameOfA64Instruction(u32 instruction) { - if (auto decoder = A64::Decode(instruction)) { - return decoder->get().GetName(); - } +std::string_view GetNameOfA64Instruction(u32 instruction) { + //if (auto const decoder = A64::Decode(instruction)) + // return *A64::GetName(instruction); return ""; } @@ -66,7 +65,7 @@ void PrintA32Instruction(u32 instruction) { fmt::print("should_continue: {}\n\n", should_continue); fmt::print("IR:\n"); fmt::print("{}\n", IR::DumpBlock(ir_block)); - Optimization::Optimize(ir_block, conf, {}); + Optimization::Optimize(ir_block, A32::UserConfig{}, {}); fmt::print("Optimized IR:\n"); fmt::print("{}\n", IR::DumpBlock(ir_block)); } @@ -81,7 +80,7 @@ void PrintA64Instruction(u32 instruction) { fmt::print("should_continue: {}\n\n", should_continue); fmt::print("IR:\n"); fmt::print("{}\n", IR::DumpBlock(ir_block)); - Optimization::Optimize(ir_block, conf, {}); + Optimization::Optimize(ir_block, A64::UserConfig{}, {}); fmt::print("Optimized IR:\n"); fmt::print("{}\n", IR::DumpBlock(ir_block)); } @@ -99,7 +98,7 @@ void PrintThumbInstruction(u32 instruction) { fmt::print("should_continue: {}\n\n", should_continue); fmt::print("IR:\n"); fmt::print("{}\n", IR::DumpBlock(ir_block)); - Optimization::Optimize(ir_block, conf, {}); + Optimization::Optimize(ir_block, A32::UserConfig{}, {}); fmt::print("Optimized IR:\n"); fmt::print("{}\n", IR::DumpBlock(ir_block)); } diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index 98a55e1fcf..8f5d929b74 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -62,22 +62,20 @@ std::unique_ptr InitializeTranslations(QObject* parent) Settings, use_multi_core, tr("Multicore CPU Emulation"), - tr("This option increases CPU emulation thread use from 1 to the Switch’s maximum of 4.\n" - "This is mainly a debug option and shouldn’t be disabled.")); + tr("This option increases CPU emulation thread use from 1 to the maximum of 4.\n" + "This is mainly a debug option and shouldn't be disabled.")); INSERT( Settings, memory_layout_mode, tr("Memory Layout"), - tr("Increases the amount of emulated RAM from the stock 4GB of the retail Switch to the " - "developer kit's 8/6GB.\nIt’s doesn’t improve stability or performance and is intended " - "to let big texture mods fit in emulated RAM.\nEnabling it will increase memory " - "use. It is not recommended to enable unless a specific game with a texture mod needs " - "it.")); + tr("Increases the amount of emulated RAM from 4GB of the board to the " + "devkit 8/6GB.\nDoesn't affect performance/stability but may allow HD texture " + "mods to load.")); INSERT(Settings, use_speed_limit, QString(), QString()); INSERT(Settings, speed_limit, tr("Limit Speed Percent"), - tr("Controls the game's maximum rendering speed, but it’s up to each game if it runs " + tr("Controls the game's maximum rendering speed, but it's up to each game if it runs " "faster or not.\n200% for a 30 FPS game is 60 FPS, and for a " "60 FPS game it will be 120 FPS.\nDisabling it means unlocking the framerate to the " "maximum your PC can reach.")); @@ -86,15 +84,13 @@ std::unique_ptr InitializeTranslations(QObject* parent) tr("Synchronize Core Speed"), tr("Synchronizes CPU core speed with the game's maximum rendering speed to boost FPS " "without affecting game speed (animations, physics, etc.).\n" - "Compatibility varies by game; many (especially older ones) may not respond well.\n" "Can help reduce stuttering at lower framerates.")); // Cpu INSERT(Settings, cpu_accuracy, tr("Accuracy:"), - tr("This setting controls the accuracy of the emulated CPU.\nDon't change this unless " - "you know what you are doing.")); + tr("Change the accuracy of the emulated CPU (for debugging only).")); INSERT(Settings, cpu_backend, tr("Backend:"), QString()); INSERT(Settings, use_fast_cpu_time, QString(), QString()); @@ -110,7 +106,7 @@ std::unique_ptr InitializeTranslations(QObject* parent) cpu_ticks, tr("Custom CPU Ticks"), tr("Set a custom value of CPU ticks. Higher values can increase performance, but may " - "also cause the game to freeze. A range of 77–21000 is recommended.")); + "cause deadlocks. A range of 77-21000 is recommended.")); INSERT(Settings, cpu_backend, tr("Backend:"), QString()); // Cpu Debug @@ -144,8 +140,7 @@ std::unique_ptr InitializeTranslations(QObject* parent) cpuopt_unsafe_fastmem_check, tr("Disable address space checks"), tr("This option improves speed by eliminating a safety check before every memory " - "read/write in guest.\nDisabling it may allow a game to read/write the emulator's " - "memory.")); + "operation.\nDisabling it may allow arbitrary code execution.")); INSERT( Settings, cpuopt_unsafe_ignore_global_monitor, @@ -159,36 +154,31 @@ std::unique_ptr InitializeTranslations(QObject* parent) Settings, renderer_backend, tr("API:"), - tr("Switches between the available graphics APIs.\nVulkan is recommended in most cases.")); + tr("Changes the output graphics API.\nVulkan is recommended.")); INSERT(Settings, vulkan_device, tr("Device:"), - tr("This setting selects the GPU to use with the Vulkan backend.")); + tr("This setting selects the GPU to use (Vulkan only).")); INSERT(Settings, shader_backend, tr("Shader Backend:"), - tr("The shader backend to use for the OpenGL renderer.\nGLSL is the fastest in " - "performance and the best in rendering accuracy.\n" - "GLASM is a deprecated NVIDIA-only backend that offers much better shader building " - "performance at the cost of FPS and rendering accuracy.\n" - "SPIR-V compiles the fastest, but yields poor results on most GPU drivers.")); + tr("The shader backend to use with OpenGL.\nGLSL is recommended.")); INSERT(Settings, resolution_setup, tr("Resolution:"), - tr("Forces the game to render at a different resolution.\nHigher resolutions require " - "much more VRAM and bandwidth.\n" - "Options lower than 1X can cause rendering issues.")); + tr("Forces to render at a different resolution.\n" + "Higher resolutions require more VRAM and bandwidth.\n" + "Options lower than 1X can cause artifacts.")); INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QString()); INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"), - tr("Determines how sharpened the image will look while using FSR’s dynamic contrast.")); + tr("Determines how sharpened the image will look using FSR's dynamic contrast.")); INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"), - tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA has a " - "lower performance impact and can produce a better and more stable picture under " - "very low resolutions.")); + tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA " + "can produce a more stable picture in lower resolutions.")); INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"), @@ -199,18 +189,17 @@ std::unique_ptr InitializeTranslations(QObject* parent) INSERT(Settings, aspect_ratio, tr("Aspect Ratio:"), - tr("Stretches the game to fit the specified aspect ratio.\nSwitch games only support " - "16:9, so custom game mods are required to get other ratios.\nAlso controls the " + tr("Stretches the renderer to fit the specified aspect ratio.\nMost games only support " + "16:9, so modifications are required to get other ratios.\nAlso controls the " "aspect ratio of captured screenshots.")); INSERT(Settings, use_disk_shader_cache, - tr("Use disk pipeline cache"), + tr("Use persistent pipeline cache"), tr("Allows saving shaders to storage for faster loading on following game " - "boots.\nDisabling " - "it is only intended for debugging.")); + "boots.\nDisabling it is only intended for debugging.")); INSERT(Settings, optimize_spirv_output, - tr("Optimize SPIRV output shader"), + tr("Optimize SPIRV output"), tr("Runs an additional optimization pass over generated SPIRV shaders.\n" "Will increase time required for shader compilation.\nMay slightly improve " "performance.\nThis feature is experimental.")); @@ -229,37 +218,35 @@ std::unique_ptr InitializeTranslations(QObject* parent) accelerate_astc, tr("ASTC Decoding Method:"), tr("This option controls how ASTC textures should be decoded.\n" - "CPU: Use the CPU for decoding, slowest but safest method.\n" - "GPU: Use the GPU's compute shaders to decode ASTC textures, recommended for most " - "games and users.\n" - "CPU Asynchronously: Use the CPU to decode ASTC textures as they arrive. Completely " - "eliminates ASTC decoding\nstuttering at the cost of rendering issues while the " - "texture is being decoded.")); + "CPU: Use the CPU for decoding.\n" + "GPU: Use the GPU's compute shaders to decode ASTC textures (recommended).\n" + "CPU Asynchronously: Use the CPU to decode ASTC textures on demand. Eliminates" + "ASTC decoding\nstuttering but may present artifacts.")); INSERT( Settings, astc_recompression, tr("ASTC Recompression Method:"), - tr("Almost all desktop and laptop dedicated GPUs lack support for ASTC textures, forcing " - "the emulator to decompress to an intermediate format any card supports, RGBA8.\n" - "This option recompresses RGBA8 to either the BC1 or BC3 format, saving VRAM but " - "negatively affecting image quality.")); + tr("Most GPUs lack support for ASTC textures and must decompress to an" + "intermediate format: RGBA8.\n" + "BC1/BC3: The intermediate format will be recompressed to BC1 or BC3 format,\n" + " saving VRAM but degrading image quality.")); INSERT(Settings, vram_usage_mode, tr("VRAM Usage Mode:"), - tr("Selects whether the emulator should prefer to conserve memory or make maximum usage of available video memory for performance.\nAggressive mode may severely impact the performance of other applications such as recording software.")); + tr("Selects whether the emulator should prefer to conserve memory or make maximum usage of available video memory for performance.\nAggressive mode may impact performance of other applications such as recording software.")); INSERT(Settings, skip_cpu_inner_invalidation, tr("Skip CPU Inner Invalidation"), - tr("Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and " - "improving it's performance. This may cause glitches or crashes on some games.")); + tr("Skips certain cache invalidations during memory updates, reducing CPU usage and " + "improving latency. This may cause soft-crashes.")); INSERT( Settings, vsync_mode, tr("VSync Mode:"), tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " - "refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from " - "a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop " - "frames.\nImmediate (no synchronization) just presents whatever is available and can " + "refresh rate.\nFIFO Relaxed allows tearing as it recovers from a slow down.\n" + "Mailbox can have lower latency than FIFO and does not tear but may drop " + "frames.\nImmediate (no synchronization) presents whatever is available and can " "exhibit tearing.")); INSERT(Settings, bg_red, QString(), QString()); INSERT(Settings, bg_green, QString(), QString()); @@ -267,7 +254,7 @@ std::unique_ptr InitializeTranslations(QObject* parent) // Renderer (Advanced Graphics) INSERT(Settings, sync_memory_operations, tr("Sync Memory Operations"), - tr("Ensures data consistency between compute and memory operations.\nThis option should fix issues in some games, but may also reduce performance in some cases.\nUnreal Engine 4 games often see the most significant changes thereof.")); + tr("Ensures data consistency between compute and memory operations.\nThis option fixes issues in games, but may degrade performance.\nUnreal Engine 4 games often see the most significant changes thereof.")); INSERT(Settings, async_presentation, tr("Enable asynchronous presentation (Vulkan only)"), @@ -281,8 +268,7 @@ std::unique_ptr InitializeTranslations(QObject* parent) INSERT(Settings, max_anisotropy, tr("Anisotropic Filtering:"), - tr("Controls the quality of texture rendering at oblique angles.\nIt’s a light setting " - "and safe to set at 16x on most GPUs.")); + tr("Controls the quality of texture rendering at oblique angles.\nSafe to set at 16x on most GPUs.")); INSERT(Settings, gpu_accuracy, tr("GPU Accuracy:"), @@ -292,11 +278,11 @@ std::unique_ptr InitializeTranslations(QObject* parent) INSERT(Settings, dma_accuracy, tr("DMA Accuracy:"), - tr("Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases.\nIf unsure, leave this on Default.")); + tr("Controls the DMA precision accuracy. Safe precision fixes issues in some games but may degrade performance.")); INSERT(Settings, use_asynchronous_shaders, - tr("Use asynchronous shader building (Hack)"), - tr("Enables asynchronous shader compilation, which may reduce shader stutter.")); + tr("Enable asynchronous shader compilation (Hack)"), + tr("May reduce shader stutter.")); INSERT(Settings, use_fast_gpu_time, QString(), QString()); INSERT(Settings, fast_gpu_time, @@ -314,8 +300,8 @@ std::unique_ptr InitializeTranslations(QObject* parent) Settings, enable_compute_pipelines, tr("Enable Compute Pipelines (Intel Vulkan Only)"), - tr("Enable compute pipelines, required by some games.\nThis setting only exists for Intel " - "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled " + tr("Required by some games.\nThis setting only exists for Intel " + "proprietary drivers and may crash if enabled.\nCompute pipelines are always enabled " "on all other drivers.")); INSERT( Settings, @@ -343,12 +329,12 @@ std::unique_ptr InitializeTranslations(QObject* parent) INSERT(Settings, dyna_state, tr("Extended Dynamic State"), - tr("Controls the number of features that can be used in Extended Dynamic State.\nHigher numbers allow for more features and can increase performance, but may cause issues with some drivers and vendors.\nThe default value may vary depending on your system and hardware capabilities.\nThis value can be changed until stability and a better visual quality are achieved.")); + tr("Controls the number of features that can be used in Extended Dynamic State.\nHigher numbers allow for more features and can increase performance, but may cause issues.\nThe default value is per-system.")); INSERT(Settings, provoking_vertex, tr("Provoking Vertex"), - tr("Improves lighting and vertex handling in certain games.\n" + tr("Improves lighting and vertex handling in some games.\n" "Only Vulkan 1.0+ devices support this extension.")); INSERT(Settings, @@ -363,8 +349,8 @@ std::unique_ptr InitializeTranslations(QObject* parent) sample_shading_fraction, tr("Sample Shading"), tr("Allows the fragment shader to execute per sample in a multi-sampled fragment " - "instead once per fragment. Improves graphics quality at the cost of some performance.\n" - "Higher values improve quality more but also reduce performance to a greater extent.")); + "instead of once per fragment. Improves graphics quality at the cost of performance.\n" + "Higher values improve quality but degrade performance.")); // Renderer (Debug) @@ -372,31 +358,30 @@ std::unique_ptr InitializeTranslations(QObject* parent) INSERT(Settings, rng_seed, tr("RNG Seed"), - tr("Controls the seed of the random number generator.\nMainly used for speedrunning " - "purposes.")); + tr("Controls the seed of the random number generator.\nMainly used for speedrunning.")); INSERT(Settings, rng_seed_enabled, QString(), QString()); - INSERT(Settings, device_name, tr("Device Name"), tr("The name of the emulated Switch.")); + INSERT(Settings, device_name, tr("Device Name"), tr("The name of the console.")); INSERT(Settings, custom_rtc, tr("Custom RTC Date:"), - tr("This option allows to change the emulated clock of the Switch.\n" + tr("This option allows to change the clock of the console.\n" "Can be used to manipulate time in games.")); INSERT(Settings, custom_rtc_enabled, QString(), QString()); INSERT(Settings, custom_rtc_offset, QStringLiteral(" "), - QStringLiteral("The number of seconds from the current unix time")); + tr("The number of seconds from the current unix time")); INSERT(Settings, language_index, tr("Language:"), - tr("Note: this can be overridden when region setting is auto-select")); - INSERT(Settings, region_index, tr("Region:"), tr("The region of the emulated Switch.")); - INSERT(Settings, time_zone_index, tr("Time Zone:"), tr("The time zone of the emulated Switch.")); + tr("This option can be overridden when region setting is auto-select")); + INSERT(Settings, region_index, tr("Region:"), tr("The region of the console.")); + INSERT(Settings, time_zone_index, tr("Time Zone:"), tr("The time zone of the console.")); INSERT(Settings, sound_index, tr("Sound Output Mode:"), QString()); INSERT(Settings, use_docked_mode, tr("Console Mode:"), - tr("Selects if the console is emulated in Docked or Handheld mode.\nGames will change " + tr("Selects if the console is in Docked or Handheld mode.\nGames will change " "their resolution, details and supported controllers and depending on this setting.\n" "Setting to Handheld can help improve performance for low end systems.")); INSERT(Settings, current_user, QString(), QString()); @@ -418,27 +403,26 @@ std::unique_ptr InitializeTranslations(QObject* parent) // Ui General INSERT(UISettings, select_user_on_boot, - tr("Prompt for user on game boot"), - tr("Ask to select a user profile on each boot, useful if multiple people use Eden on " - "the same PC.")); + tr("Prompt for user profile on boot"), + tr("Useful if multiple people use the same PC.")); INSERT(UISettings, pause_when_in_background, - tr("Pause emulation when in background"), - tr("This setting pauses Eden when focusing other windows.")); + tr("Pause when not in focus"), + tr("Pauses emulation when focusing on other windows.")); INSERT(UISettings, confirm_before_stopping, tr("Confirm before stopping emulation"), - tr("This setting overrides game prompts asking to confirm stopping the game.\nEnabling " + tr("Overrides prompts asking to confirm stopping the emulation.\nEnabling " "it bypasses such prompts and directly exits the emulation.")); INSERT(UISettings, hide_mouse, tr("Hide mouse on inactivity"), - tr("This setting hides the mouse after 2.5s of inactivity.")); + tr("Hides the mouse after 2.5s of inactivity.")); INSERT(UISettings, controller_applet_disabled, tr("Disable controller applet"), - tr("Forcibly disables the use of the controller applet by guests.\nWhen a guest " - "attempts to open the controller applet, it is immediately closed.")); + tr("Forcibly disables the use of the controller applet in emulated programs.\n" + "When a program attempts to open the controller applet, it is immediately closed.")); INSERT(UISettings, check_for_updates, tr("Check for updates"), diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index b5e1e70b4c..6d325b4aad 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp @@ -991,6 +991,7 @@ IR::AbstractSyntaxList BuildASL(ObjectPool& inst_pool, ObjectPool::BindHostGraphicsUniformBuffers(size_t stage) { } template -void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 binding_index, - bool needs_bind) { +void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 binding_index, bool needs_bind) { + ++channel_state->uniform_cache_shots[0]; const Binding& binding = channel_state->uniform_buffers[stage][index]; const DAddr device_addr = binding.device_addr; const u32 size = (std::min)(binding.size, (*channel_state->uniform_buffer_sizes)[stage][index]); @@ -823,12 +823,9 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 return; } // Classic cached path - const bool sync_cached = SynchronizeBuffer(buffer, device_addr, size); - if (sync_cached) { + if (SynchronizeBuffer(buffer, device_addr, size)) { ++channel_state->uniform_cache_hits[0]; } - ++channel_state->uniform_cache_shots[0]; - // Skip binding if it's not needed and if the bound buffer is not the fast version // This exists to avoid instances where the fast buffer is bound and a GPU write happens needs_bind |= HasFastUniformBufferBound(stage, binding_index); diff --git a/src/video_core/cdma_pusher.cpp b/src/video_core/cdma_pusher.cpp index 1b6b4c6d45..b9140d9335 100644 --- a/src/video_core/cdma_pusher.cpp +++ b/src/video_core/cdma_pusher.cpp @@ -39,8 +39,8 @@ void CDmaPusher::ProcessEntries(std::stop_token stop_token) { while (!stop_token.stop_requested()) { { std::unique_lock l{command_mutex}; - Common::CondvarWait(command_cv, l, stop_token, - [this]() { return command_lists.size() > 0; }); + command_cv.wait(l, stop_token, + [this]() { return command_lists.size() > 0; }); if (stop_token.stop_requested()) { return; } diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 9392534e7d..8739905d99 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -116,7 +116,7 @@ u64 ThreadManager::PushCommand(CommandData&& command_data, bool block) { state.queue.EmplaceWait(std::move(command_data), fence, block); if (block) { - Common::CondvarWait(state.cv, lk, thread.get_stop_token(), [this, fence] { + state.cv.wait(lk, thread.get_stop_token(), [this, fence] { return fence <= state.signaled_fence.load(std::memory_order_relaxed); }); } diff --git a/src/video_core/host1x/codecs/decoder.cpp b/src/video_core/host1x/codecs/decoder.cpp index cb17784b19..887eb28c8c 100755 --- a/src/video_core/host1x/codecs/decoder.cpp +++ b/src/video_core/host1x/codecs/decoder.cpp @@ -38,6 +38,10 @@ void Decoder::Decode() { // Receive output frames from decoder. auto frame = decode_api.ReceiveFrame(); + if (!frame) { + return; + } + if (IsInterlaced()) { auto [luma_top, luma_bottom, chroma_top, chroma_bottom] = GetInterlacedOffsets(); auto frame_copy = frame; diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp index 536a01fcc8..bbbbe615ce 100644 --- a/src/video_core/host1x/ffmpeg/ffmpeg.cpp +++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp @@ -233,7 +233,7 @@ bool DecoderContext::OpenContext(const Decoder& decoder) { } bool DecoderContext::SendPacket(const Packet& packet) { - if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF) { + if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) { LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret)); return false; } @@ -242,31 +242,31 @@ bool DecoderContext::SendPacket(const Packet& packet) { } std::shared_ptr DecoderContext::ReceiveFrame() { - auto ReceiveImpl = [&](AVFrame* frame) -> bool { - if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0 && ret != AVERROR_EOF) { + auto ReceiveImpl = [&](AVFrame* frame) -> int { + const int ret = avcodec_receive_frame(m_codec_context, frame); + if (ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) { LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret)); - return false; } - return true; + return ret; }; std::shared_ptr intermediate_frame = std::make_shared(); - if (!ReceiveImpl(intermediate_frame->GetFrame())) { + if (ReceiveImpl(intermediate_frame->GetFrame()) < 0) { return {}; } - m_temp_frame = std::make_shared(); + m_final_frame = std::make_shared(); if (m_codec_context->hw_device_ctx) { - m_temp_frame->SetFormat(PreferredGpuFormat); - if (int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) { + m_final_frame->SetFormat(PreferredGpuFormat); + if (const int ret = av_hwframe_transfer_data(m_final_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) { LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret)); return {}; } } else { - m_temp_frame = std::move(intermediate_frame); + m_final_frame = std::move(intermediate_frame); } - return std::move(m_temp_frame); + return std::move(m_final_frame); } void DecodeApi::Reset() { diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.h b/src/video_core/host1x/ffmpeg/ffmpeg.h index 0dd7c7cb04..d60a8ac4a7 100644 --- a/src/video_core/host1x/ffmpeg/ffmpeg.h +++ b/src/video_core/host1x/ffmpeg/ffmpeg.h @@ -194,7 +194,7 @@ public: private: const Decoder& m_decoder; AVCodecContext* m_codec_context{}; - std::shared_ptr m_temp_frame{}; + std::shared_ptr m_final_frame{}; bool m_decode_order{}; }; diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp index 9c33370337..3dbbfa5552 100644 --- a/src/video_core/host1x/vic.cpp +++ b/src/video_core/host1x/vic.cpp @@ -146,6 +146,11 @@ void Vic::Execute() { } auto frame = frame_queue.GetFrame(nvdec_id, luma_offset); + + if (!frame) { + continue; + } + if (!frame.get()) { LOG_ERROR(HW_GPU, "Vic {} failed to get frame with offset {:#X}", id, luma_offset); continue; diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index c2ead26bd9..45f729698e 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -54,7 +54,7 @@ using VideoCommon::LoadPipelines; using VideoCommon::SerializePipeline; using Context = ShaderContext::Context; -constexpr u32 CACHE_VERSION = 10; +constexpr u32 CACHE_VERSION = 13; template auto MakeSpan(Container& container) { diff --git a/src/video_core/renderer_vulkan/present/layer.cpp b/src/video_core/renderer_vulkan/present/layer.cpp index fa7c457573..5676dfe62a 100644 --- a/src/video_core/renderer_vulkan/present/layer.cpp +++ b/src/video_core/renderer_vulkan/present/layer.cpp @@ -280,6 +280,7 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i Tegra::Texture::UnswizzleTexture( mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size), bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0); + buffer.Flush(); // Ensure host writes are visible before the GPU copy. } const VkBufferImageCopy copy{ diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp index 600003953d..3af9758a31 100644 --- a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp @@ -31,7 +31,7 @@ struct DescriptorBank { bool DescriptorBankInfo::IsSuperset(const DescriptorBankInfo& subset) const noexcept { return uniform_buffers >= subset.uniform_buffers && storage_buffers >= subset.storage_buffers && texture_buffers >= subset.texture_buffers && image_buffers >= subset.image_buffers && - textures >= subset.textures && images >= subset.image_buffers; + textures >= subset.textures && images >= subset.images; } template diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp index 6761127582..e65755de64 100644 --- a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp +++ b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp @@ -208,7 +208,7 @@ void MasterSemaphore::WaitThread(std::stop_token token) { vk::Fence fence; { std::unique_lock lock{wait_mutex}; - Common::CondvarWait(wait_cv, lock, token, [this] { return !wait_queue.empty(); }); + wait_cv.wait(lock, token, [this] { return !wait_queue.empty(); }); if (token.stop_requested()) { return; } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 2fd0b59b3a..9cdbe5611b 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -55,7 +55,7 @@ using VideoCommon::FileEnvironment; using VideoCommon::GenericEnvironment; using VideoCommon::GraphicsEnvironment; -constexpr u32 CACHE_VERSION = 12; +constexpr u32 CACHE_VERSION = 13; constexpr std::array VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'}; template diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index 23279e49b9..0b29ad1389 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -279,7 +279,7 @@ void PresentManager::PresentThread(std::stop_token token) { std::unique_lock lock{queue_mutex}; // Wait for presentation frames - Common::CondvarWait(frame_cv, lock, token, [this] { return !present_queue.empty(); }); + frame_cv.wait(lock, token, [this] { return !present_queue.empty(); }); if (token.stop_requested()) { return; } diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 530d161dfe..d109d22cab 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -166,7 +166,7 @@ void Scheduler::WorkerThread(std::stop_token stop_token) { std::unique_lock lk{queue_mutex}; // Wait for work. - Common::CondvarWait(event_cv, lk, stop_token, [&] { return TryPopQueue(work); }); + event_cv.wait(lk, stop_token, [&] { return TryPopQueue(work); }); // If we've been asked to stop, we're done. if (stop_token.stop_requested()) { diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp index 04a51f2d1e..54183be12c 100644 --- a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp +++ b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -224,7 +227,7 @@ void TurboMode::Run(std::stop_token stop_token) { #endif // Wait for the next graphics queue submission if necessary. std::unique_lock lk{m_submission_lock}; - Common::CondvarWait(m_submission_cv, lk, stop_token, [this] { + m_submission_cv.wait(lk, stop_token, [this] { return (std::chrono::steady_clock::now() - m_submission_time) <= std::chrono::milliseconds{100}; }); diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index b16c1d99ce..00e03bd935 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -366,10 +366,10 @@ if (APPLE) set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE TRUE) set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) - if (NOT USE_SYSTEM_MOLTENVK) + if (YUZU_USE_BUNDLED_MOLTENVK) set(MOLTENVK_PLATFORM "macOS") set(MOLTENVK_VERSION "v1.3.0") - download_moltenvk_external(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION}) + download_moltenvk(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION}) endif() find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED) message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.") diff --git a/src/yuzu/Info.plist b/src/yuzu/Info.plist index 96096c84d1..773c4ee302 100644 --- a/src/yuzu/Info.plist +++ b/src/yuzu/Info.plist @@ -45,9 +45,31 @@ SPDX-License-Identifier: GPL-2.0-or-later NSHumanReadableCopyright + + LSApplicationCategoryType + public.app-category.games + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + nsp + xci + nro + + CFBundleTypeName + Switch File + CFBundleTypeRole + Viewer + LSHandlerRank + Default + + NSPrincipalClass NSApplication NSHighResolutionCapable True + UIDesignRequiresCompatibility + diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp index b7c0cd58d5..9f7597f471 100644 --- a/src/yuzu/about_dialog.cpp +++ b/src/yuzu/about_dialog.cpp @@ -14,11 +14,12 @@ AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent) , ui{std::make_unique()} { - static const std::string description = std::string{Common::g_build_version}; static const std::string build_id = std::string{Common::g_build_id}; - static const std::string compiler = std::string{Common::g_compiler_id}; - - static const std::string yuzu_build = fmt::format("Eden | {} | {}", description, compiler); + static const std::string yuzu_build = fmt::format("{} | {} | {}", + std::string{Common::g_build_name}, + std::string{Common::g_build_version}, + std::string{Common::g_compiler_id} + ); const auto override_build = fmt::format(fmt::runtime( std::string(Common::g_title_bar_format_idle)), diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 7b5f2a314f..cdc4e4024a 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -108,13 +108,13 @@ void EmuThread::run() { m_system.Run(); m_stopped.Reset(); - Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return !m_should_run; }); + m_should_run_cv.wait(lk, stop_token, [&] { return !m_should_run; }); } else { m_system.Pause(); m_stopped.Set(); EmulationPaused(lk); - Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return m_should_run; }); + m_should_run_cv.wait(lk, stop_token, [&] { return m_should_run; }); EmulationResumed(lk); } } diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp index a7ebae91f8..af81ef552e 100644 --- a/src/yuzu/configuration/configure_audio.cpp +++ b/src/yuzu/configuration/configure_audio.cpp @@ -270,10 +270,8 @@ void ConfigureAudio::UpdateAudioDevices(int sink_index) { void ConfigureAudio::InitializeAudioSinkComboBox() { sink_combo_box->clear(); sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); - - for (const auto& id : AudioCore::Sink::GetSinkIDs()) { - sink_combo_box->addItem(QString::fromStdString(Settings::CanonicalizeEnum(id))); - } + for (const auto& id : AudioCore::Sink::GetSinkIDs()) + sink_combo_box->addItem(QString::fromStdString(std::string{Settings::CanonicalizeEnum(id)})); } void ConfigureAudio::RetranslateUI() { diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index f5de08a676..df74738df4 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp @@ -373,13 +373,13 @@ bool ConfigureProfileManager::LoadAvatarData() { const auto romfs = nca->GetRomFS(); if (!romfs) { QMessageBox::warning(this, tr("Error loading archive"), - tr("Archive does not contain romfs. It is probably corrupt.")); + tr("Could not locate RomFS. Your file or decryption keys may be corrupted.")); return false; } const auto extracted = FileSys::ExtractRomFS(romfs); if (!extracted) { QMessageBox::warning(this, tr("Error extracting archive"), - tr("Archive could not be extracted. It is probably corrupt.")); + tr("Could not extract RomFS. Your file or decryption keys may be corrupted.")); return false; } const auto chara_dir = extracted->GetSubdirectory("chara"); diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h index 9e718098a3..dd5d5b7257 100644 --- a/src/yuzu/configuration/shared_widget.h +++ b/src/yuzu/configuration/shared_widget.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "qt_common/shared_translation.h" diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 94e7b2dc42..cd71fb2139 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -58,11 +58,11 @@ class GameList : public QWidget { public: enum { COLUMN_NAME, - COLUMN_COMPATIBILITY, - COLUMN_ADD_ONS, COLUMN_FILE_TYPE, COLUMN_SIZE, COLUMN_PLAY_TIME, + COLUMN_ADD_ONS, + COLUMN_COMPATIBILITY, COLUMN_COUNT, // Number of columns }; diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index 538c7ab822..2914c275a8 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp @@ -204,36 +204,24 @@ QList MakeGameListEntry(const std::string& path, const PlayTime::PlayTimeManager& play_time_manager, const FileSys::PatchManager& patch) { - const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); + auto const it = FindMatchingCompatibilityEntry(compatibility_list, program_id); + // The game list uses 99 as compatibility number for untested games + QString compatibility = it != compatibility_list.end() ? it->second.first : QStringLiteral("99"); - // The game list uses this as compatibility number for untested games - QString compatibility{QStringLiteral("99")}; - if (it != compatibility_list.end()) { - compatibility = it->second.first; - } + auto const file_type = loader.GetFileType(); + auto const file_type_string = QString::fromStdString(Loader::GetFileTypeString(file_type)); - const auto file_type = loader.GetFileType(); - const auto file_type_string = QString::fromStdString(Loader::GetFileTypeString(file_type)); - - QList list{ - new GameListItemPath(FormatGameName(path), icon, QString::fromStdString(name), - file_type_string, program_id), - new GameListItemCompat(compatibility), + QString patch_versions = GetGameListCachedObject(fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] { + return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable()); + }); + return QList{ + new GameListItemPath(FormatGameName(path), icon, QString::fromStdString(name), file_type_string, program_id), new GameListItem(file_type_string), new GameListItemSize(size), new GameListItemPlayTime(play_time_manager.GetPlayTime(program_id)), + new GameListItem(patch_versions), + new GameListItemCompat(compatibility), }; - - QString patch_versions; - - patch_versions = GetGameListCachedObject( - fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] { - return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable()); - }); - - list.insert(2, new GameListItem(patch_versions)); - - return list; } } // Anonymous namespace diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 19162a4ab7..4d5238643c 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -35,7 +35,6 @@ #include "applets/qt_profile_select.h" #include "applets/qt_software_keyboard.h" #include "applets/qt_web_browser.h" -#include "common/nvidia_flags.h" #include "common/settings_enums.h" #include "configuration/configure_input.h" #include "configuration/configure_per_game.h" @@ -1771,16 +1770,25 @@ void GMainWindow::OnDisplayTitleBars(bool show) { void GMainWindow::SetupPrepareForSleep() { #ifdef __unix__ - auto bus = QDBusConnection::systemBus(); - if (bus.isConnected()) { + if (auto bus = QDBusConnection::systemBus(); bus.isConnected()) { + // See https://github.com/ConsoleKit2/ConsoleKit2/issues/150 +#ifdef __linux__ + const auto dbus_logind_service = QStringLiteral("org.freedesktop.login1"); + const auto dbus_logind_path = QStringLiteral("/org/freedesktop/login1"); + const auto dbus_logind_manager_if = QStringLiteral("org.freedesktop.login1.Manager"); + //const auto dbus_logind_session_if = QStringLiteral("org.freedesktop.login1.Session"); +#else + const auto dbus_logind_service = QStringLiteral("org.freedesktop.ConsoleKit"); + const auto dbus_logind_path = QStringLiteral("/org/freedesktop/ConsoleKit/Manager"); + const auto dbus_logind_manager_if = QStringLiteral("org.freedesktop.ConsoleKit.Manager"); + //const auto dbus_logind_session_if = QStringLiteral("org.freedesktop.ConsoleKit.Session"); +#endif const bool success = bus.connect( - QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1"), - QStringLiteral("org.freedesktop.login1.Manager"), QStringLiteral("PrepareForSleep"), + dbus_logind_service, dbus_logind_path, + dbus_logind_manager_if, QStringLiteral("PrepareForSleep"), QStringLiteral("b"), this, SLOT(OnPrepareForSleep(bool))); - - if (!success) { + if (!success) LOG_WARNING(Frontend, "Couldn't register PrepareForSleep signal"); - } } else { LOG_WARNING(Frontend, "QDBusConnection system bus is not connected"); } @@ -4193,23 +4201,25 @@ void GMainWindow::OnEmulatorUpdateAvailable() { update_prompt.addButton(QMessageBox::Yes); update_prompt.addButton(QMessageBox::Ignore); update_prompt.setText( - tr("Update %1 for Eden is available.\nWould you like to download it?").arg(version_string)); + tr("Download the %1 update?").arg(version_string)); update_prompt.exec(); if (update_prompt.button(QMessageBox::Yes) == update_prompt.clickedButton()) { - QDesktopServices::openUrl( - QUrl(QString::fromStdString("https://github.com/eden-emulator/Releases/releases/tag/") + - version_string)); + auto const full_url = fmt::format("{}/{}/releases/tag/", + std::string{Common::g_build_auto_update_website}, + std::string{Common::g_build_auto_update_repo} + ); + QDesktopServices::openUrl(QUrl(QString::fromStdString(full_url) + version_string)); } } #endif -void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_view title_version, - std::string_view gpu_vendor) { - static const std::string description = std::string{Common::g_build_version}; +void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_view title_version, std::string_view gpu_vendor) { static const std::string build_id = std::string{Common::g_build_id}; - static const std::string compiler = std::string{Common::g_compiler_id}; - - static const std::string yuzu_title = fmt::format("Eden | {} | {}", description, compiler); + static const std::string yuzu_title = fmt::format("{} | {} | {}", + std::string{Common::g_build_name}, + std::string{Common::g_build_version}, + std::string{Common::g_compiler_id} + ); const auto override_title = fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); @@ -4917,7 +4927,6 @@ int main(int argc, char* argv[]) { #endif Common::DetachedTasks detached_tasks; - Common::ConfigureNvidiaEnvironmentFlags(); // Init settings params QCoreApplication::setOrganizationName(QStringLiteral("eden")); diff --git a/src/yuzu/update_checker.cpp b/src/yuzu/update_checker.cpp index 8291987d73..e54eb8d7f8 100644 --- a/src/yuzu/update_checker.cpp +++ b/src/yuzu/update_checker.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -12,6 +15,7 @@ #include #include #include +#include "common/scm_rev.h" std::optional UpdateChecker::GetResponse(std::string url, std::string path) { @@ -54,8 +58,8 @@ std::optional UpdateChecker::GetResponse(std::string url, std::stri std::optional UpdateChecker::GetLatestRelease(bool include_prereleases) { - constexpr auto update_check_url = "http://api.github.com"; - std::string update_check_path = "/repos/eden-emulator/Releases"; + const auto update_check_url = std::string{Common::g_build_auto_update_api}; + std::string update_check_path = fmt::format("/repos/{}", std::string{Common::g_build_auto_update_repo}); try { if (include_prereleases) { // This can return either a prerelease or a stable release, // whichever is more recent. diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 9ec6b1d594..4b56f3794b 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -229,7 +229,7 @@ void EmuWindow_SDL2::WaitEvent() { const u32 current_time = SDL_GetTicks(); if (current_time > last_time + 2000) { const auto results = system.GetAndResetPerfStats(); - const auto title = fmt::format("Eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)", + const auto title = fmt::format("{} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc, diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 4b012fe134..32f365e0d0 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -90,7 +93,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste } SDL_GL_SetSwapInterval(0); - std::string window_title = fmt::format("Eden {} | {}-{}", Common::g_build_fullname, + std::string window_title = fmt::format("{} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), @@ -138,7 +141,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste OnResize(); OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); SDL_PumpEvents(); - LOG_INFO(Frontend, "Eden Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, + LOG_INFO(Frontend, "Build string: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); Settings::LogSettings(); } diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 599582aba9..4a99f34861 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -16,7 +16,6 @@ #include "common/detached_tasks.h" #include "common/logging/backend.h" #include "common/logging/log.h" -#include "common/nvidia_flags.h" #include "common/scm_rev.h" #include "common/scope_exit.h" #include "common/settings.h" @@ -334,8 +333,6 @@ int main(int argc, char** argv) { LocalFree(argv_w); #endif - Common::ConfigureNvidiaEnvironmentFlags(); - if (filepath.empty()) { LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); return -1; diff --git a/tools/optimize-assets.sh b/tools/optimize-assets.sh new file mode 100755 index 0000000000..07facc8fa0 --- /dev/null +++ b/tools/optimize-assets.sh @@ -0,0 +1,6 @@ +#!/bin/sh -e +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later +# Optimizes assets of eden (requires OptiPng) +which optipng || exit +find . -type f -name *.png -exec optipng -o7 {} \; diff --git a/.ci/update-icons.sh b/tools/update-icons.sh similarity index 95% rename from .ci/update-icons.sh rename to tools/update-icons.sh index c95ba0ad82..da54156665 100755 --- a/.ci/update-icons.sh +++ b/tools/update-icons.sh @@ -1,8 +1,7 @@ #!/bin/sh -e - # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later - +# Updates main icons for eden which png2icns || [ which yay && yay libicns ] || exit which magick || exit