forked from eden-emu/eden
Compare commits
10 commits
Author | SHA1 | Date | |
---|---|---|---|
61adc85c4b | |||
4be6d30cd9 | |||
020f1cdb1f | |||
dfe10bc851 | |||
9a098441de | |||
91fb1df624 | |||
43a7470a7d | |||
dfca07f4e3 | |||
2e0a4163cf | |||
815d85677a |
33 changed files with 269 additions and 520 deletions
136
CMakeLists.txt
136
CMakeLists.txt
|
@ -139,65 +139,50 @@ 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)
|
||||
|
||||
set(EXT_DEFAULT OFF)
|
||||
|
||||
if (MSVC OR ANDROID)
|
||||
set(EXT_DEFAULT ON)
|
||||
endif()
|
||||
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)
|
||||
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})
|
||||
|
||||
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})
|
||||
|
||||
# TODO(crueter): CI this?
|
||||
option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON)
|
||||
|
||||
|
||||
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_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_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)
|
||||
|
@ -205,17 +190,42 @@ if(YUZU_ENABLE_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)
|
||||
|
||||
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_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_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 "LINUX" 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)
|
||||
|
@ -228,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)
|
||||
|
@ -263,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)
|
||||
|
@ -327,6 +319,18 @@ 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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -101,7 +101,7 @@ sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glsl
|
|||
<summary>Ubuntu, Debian, Mint Linux</summary>
|
||||
|
||||
```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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -162,6 +165,12 @@ Result InfoUpdater::UpdateEffectsVersion1(EffectContext& effect_context, const b
|
|||
reinterpret_cast<EffectInfoBase::OutStatusVersion1*>(output), effect_count};
|
||||
|
||||
for (u32 i = 0; i < effect_count; i++) {
|
||||
#ifdef _WIN32
|
||||
// There's a bug in Windows where using this effect causes extreme noise. So let's skip it.
|
||||
if (in_params[i].type == EffectInfoBase::Type::Reverb) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
auto effect_info{&effect_context.GetInfo(i)};
|
||||
if (effect_info->GetType() != in_params[i].type) {
|
||||
effect_info->ForceUnmapBuffers(pool_mapper);
|
||||
|
@ -209,6 +218,12 @@ Result InfoUpdater::UpdateEffectsVersion2(EffectContext& effect_context, const b
|
|||
reinterpret_cast<EffectInfoBase::OutStatusVersion2*>(output), effect_count};
|
||||
|
||||
for (u32 i = 0; i < effect_count; i++) {
|
||||
#ifdef _WIN32
|
||||
// There's a bug in Windows where using this effect causes extreme noise. So let's skip it.
|
||||
if (in_params[i].type == EffectInfoBase::Type::Reverb) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
auto effect_info{&effect_context.GetInfo(i)};
|
||||
if (effect_info->GetType() != in_params[i].type) {
|
||||
effect_info->ForceUnmapBuffers(pool_mapper);
|
||||
|
|
|
@ -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; });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/fs/file.h"
|
||||
#include "common/fs/fs.h"
|
||||
#ifdef ANDROID
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/fs/fs.h"
|
||||
#ifdef ANDROID
|
||||
#include "common/fs/fs_android.h"
|
||||
|
|
|
@ -56,6 +56,16 @@
|
|||
#include "common/host_memory.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
#if defined(__ANDROID__) && __ANDROID_API__ < 30
|
||||
#include <sys/syscall.h>
|
||||
#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;
|
||||
|
|
|
@ -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 <version>
|
||||
|
||||
#ifdef __cpp_lib_jthread
|
||||
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <stop_token>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
namespace Common {
|
||||
|
||||
template <typename Condvar, typename Lock, typename Pred>
|
||||
void CondvarWait(Condvar& cv, std::unique_lock<Lock>& lk, std::stop_token token, Pred&& pred) {
|
||||
cv.wait(lk, token, std::forward<Pred>(pred));
|
||||
}
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
|
||||
std::condition_variable_any cv;
|
||||
|
@ -35,341 +28,3 @@ bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep,
|
|||
}
|
||||
|
||||
} // namespace Common
|
||||
|
||||
#else
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
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<void()> 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<void()> 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<stop_state_callback, function<void()>> 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 Callback>
|
||||
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 <typename Callback>
|
||||
friend class stop_callback;
|
||||
stop_token(shared_ptr<polyfill::stop_state> stop_state) : m_stop_state(std::move(stop_state)) {}
|
||||
|
||||
private:
|
||||
shared_ptr<polyfill::stop_state> m_stop_state;
|
||||
};
|
||||
|
||||
class stop_source {
|
||||
public:
|
||||
stop_source() : m_stop_state(make_shared<polyfill::stop_state>()) {}
|
||||
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<polyfill::stop_state> stop_state)
|
||||
: m_stop_state(std::move(stop_state)) {}
|
||||
|
||||
private:
|
||||
shared_ptr<polyfill::stop_state> m_stop_state;
|
||||
};
|
||||
|
||||
template <typename Callback>
|
||||
class stop_callback {
|
||||
static_assert(is_nothrow_destructible_v<Callback>);
|
||||
static_assert(is_invocable_v<Callback>);
|
||||
|
||||
public:
|
||||
using callback_type = Callback;
|
||||
|
||||
template <typename C>
|
||||
requires constructible_from<Callback, C>
|
||||
explicit stop_callback(const stop_token& st,
|
||||
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
|
||||
: m_stop_state(st.m_stop_state) {
|
||||
if (m_stop_state) {
|
||||
m_callback = m_stop_state->insert_callback(std::move(cb));
|
||||
}
|
||||
}
|
||||
template <typename C>
|
||||
requires constructible_from<Callback, C>
|
||||
explicit stop_callback(stop_token&& st,
|
||||
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
|
||||
: 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<polyfill::stop_state> m_stop_state;
|
||||
polyfill::stop_state_callback m_callback;
|
||||
};
|
||||
|
||||
template <typename Callback>
|
||||
stop_callback(stop_token, Callback) -> stop_callback<Callback>;
|
||||
|
||||
class jthread {
|
||||
public:
|
||||
using id = thread::id;
|
||||
using native_handle_type = thread::native_handle_type;
|
||||
|
||||
jthread() noexcept = default;
|
||||
|
||||
template <typename F, typename... Args,
|
||||
typename = enable_if_t<!is_same_v<remove_cvref_t<F>, jthread>>>
|
||||
explicit jthread(F&& f, Args&&... args)
|
||||
: m_stop_state(make_shared<polyfill::stop_state>()),
|
||||
m_thread(make_thread(std::forward<F>(f), std::forward<Args>(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 <typename F, typename... Args>
|
||||
thread make_thread(F&& f, Args&&... args) {
|
||||
if constexpr (is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>) {
|
||||
return thread(std::forward<F>(f), get_stop_token(), std::forward<Args>(args)...);
|
||||
} else {
|
||||
return thread(std::forward<F>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<polyfill::stop_state> m_stop_state;
|
||||
thread m_thread;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
namespace Common {
|
||||
|
||||
template <typename Condvar, typename Lock, typename Pred>
|
||||
void CondvarWait(Condvar& cv, std::unique_lock<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 <typename Rep, typename Period>
|
||||
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -991,6 +991,7 @@ IR::AbstractSyntaxList BuildASL(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::
|
|||
Statement& root{goto_pass.RootStatement()};
|
||||
IR::AbstractSyntaxList syntax_list;
|
||||
TranslatePass{inst_pool, block_pool, stmt_pool, env, root, syntax_list, host_info};
|
||||
stmt_pool.ReleaseContents();
|
||||
return syntax_list;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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};
|
||||
});
|
||||
|
|
|
@ -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}.")
|
||||
|
|
|
@ -14,11 +14,12 @@ AboutDialog::AboutDialog(QWidget* parent)
|
|||
: QDialog(parent)
|
||||
, ui{std::make_unique<Ui::AboutDialog>()}
|
||||
{
|
||||
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)),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4192,23 +4192,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);
|
||||
|
|
|
@ -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 <nlohmann/json.hpp>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include "common/scm_rev.h"
|
||||
|
||||
std::optional<std::string> UpdateChecker::GetResponse(std::string url, std::string path)
|
||||
{
|
||||
|
@ -54,8 +58,8 @@ std::optional<std::string> UpdateChecker::GetResponse(std::string url, std::stri
|
|||
|
||||
std::optional<std::string> 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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue