diff --git a/.gitmodules b/.gitmodules index 05092ac0..59978ec3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,45 @@ [submodule "thirdparty/vcpkg"] path = thirdparty/vcpkg url = https://github.com/microsoft/vcpkg +[submodule "thirdparty/volk"] + path = thirdparty/volk + url = https://github.com/zeux/volk +[submodule "thirdparty/SDL"] + path = thirdparty/SDL + url = https://github.com/libsdl-org/SDL.git +[submodule "thirdparty/Vulkan-Headers"] + path = thirdparty/Vulkan-Headers + url = https://github.com/KhronosGroup/Vulkan-Headers.git +[submodule "thirdparty/VulkanMemoryAllocator"] + path = thirdparty/VulkanMemoryAllocator + url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git +[submodule "thirdparty/D3D12MemoryAllocator"] + path = thirdparty/D3D12MemoryAllocator + url = https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator.git +[submodule "thirdparty/stb"] + path = thirdparty/stb + url = https://github.com/nothings/stb.git +[submodule "thirdparty/concurrentqueue"] + path = thirdparty/concurrentqueue + url = https://github.com/cameron314/concurrentqueue.git +[submodule "thirdparty/tiny-AES-c"] + path = thirdparty/tiny-AES-c + url = https://github.com/kokke/tiny-AES-c.git +[submodule "thirdparty/magic_enum"] + path = thirdparty/magic_enum + url = https://github.com/Neargye/magic_enum.git +[submodule "thirdparty/nativefiledialog-extended"] + path = thirdparty/nativefiledialog-extended + url = https://github.com/btzy/nativefiledialog-extended.git +[submodule "thirdparty/imgui"] + path = thirdparty/imgui + url = https://github.com/ocornut/imgui.git +[submodule "thirdparty/unordered_dense"] + path = thirdparty/unordered_dense + url = https://github.com/martinus/unordered_dense.git +[submodule "thirdparty/vorbis"] + path = thirdparty/vorbis + url = https://gitlab.xiph.org/xiph/vorbis.git +[submodule "thirdparty/ogg"] + path = thirdparty/ogg + url = https://gitlab.xiph.org/xiph/ogg.git diff --git a/CMakePresets.json b/CMakePresets.json index a6c20c23..3c2d0987 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -16,6 +16,9 @@ "type": "FILEPATH" } }, + "environment": { + "VCPKG_ROOT": "${sourceDir}/thirdparty/vcpkg" + }, "condition": { "type": "equals", "lhs": "${hostSystemName}", @@ -57,14 +60,12 @@ } }, { - "name": "linux-debug", - "displayName": "Linux Debug", - "description": "Target the Windows Subsystem for Linux (WSL) or a remote Linux system.", + "name": "linux-base", + "hidden": true, "generator": "Ninja", "binaryDir": "${sourceDir}/out/build/${presetName}", "installDir": "${sourceDir}/out/install/${presetName}", "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", "CMAKE_TOOLCHAIN_FILE": { "value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", "type": "FILEPATH" @@ -88,6 +89,31 @@ "remoteSourceRootDir": "$env{HOME}/.vs/$ms{projectDirName}" } } + }, + { + "name": "linux-debug", + "displayName": "Linux-Debug", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "linux-relwithdebinfo", + "displayName": "Linux-RelWithDebInfo", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "linux-release", + "displayName": "Linux-Release", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INTERPROCEDURAL_OPTIMIZATION": true + } } ] } diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index 2fcefd3b..d28a29fb 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -1,465 +1,476 @@ -project("UnleashedRecomp") -set(TARGET_NAME "SWA") - -if (WIN32) - option(SWA_D3D12 "Add D3D12 support for rendering" ON) -endif() - -option(SWA_XAUDIO2 "Use XAudio2 for audio playback" OFF) - -function(BIN2C) - cmake_parse_arguments(BIN2C_ARGS "" "TARGET_OBJ;SOURCE_FILE;DEST_FILE;ARRAY_NAME;COMPRESSION_TYPE" "" ${ARGN}) - - if(NOT BIN2C_ARGS_TARGET_OBJ) - message(FATAL_ERROR "TARGET_OBJ not specified.") - endif() - - if(NOT BIN2C_ARGS_SOURCE_FILE) - message(FATAL_ERROR "SOURCE_FILE not specified.") - endif() - - if(NOT BIN2C_ARGS_DEST_FILE) - set(BIN2C_ARGS_DEST_FILE "${BIN2C_ARGS_SOURCE_FILE}") - endif() - - if(NOT BIN2C_ARGS_COMPRESSION_TYPE) - set(BIN2C_ARGS_COMPRESSION_TYPE "none") - endif() - - add_custom_command(OUTPUT "${BIN2C_ARGS_DEST_FILE}.c" - COMMAND file_to_c "${BIN2C_ARGS_SOURCE_FILE}" "${BIN2C_ARGS_ARRAY_NAME}" "${BIN2C_ARGS_COMPRESSION_TYPE}" "${BIN2C_ARGS_DEST_FILE}.c" "${BIN2C_ARGS_DEST_FILE}.h" - DEPENDS "${BIN2C_ARGS_SOURCE_FILE}" file_to_c - BYPRODUCTS "${BIN2C_ARGS_DEST_FILE}.h" - COMMENT "Generating binary header for ${BIN2C_ARGS_SOURCE_FILE}..." - ) - - set_source_files_properties(${BIN2C_ARGS_DEST_FILE}.c PROPERTIES SKIP_PRECOMPILE_HEADERS ON) - target_sources(${BIN2C_ARGS_TARGET_OBJ} PRIVATE ${BIN2C_ARGS_DEST_FILE}.c) -endfunction() - -add_compile_options( - /fp:strict - -march=sandybridge - -fno-strict-aliasing - - -Wno-switch - -Wno-unused-function - -Wno-unused-variable - -Wno-unused-but-set-variable - -Wno-void-pointer-to-int-cast - -Wno-int-to-void-pointer-cast - -Wno-invalid-offsetof -) - -add_compile_definitions( - SWA_IMPL - SDL_MAIN_HANDLED - _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR # Microsoft wtf? - _CRT_SECURE_NO_WARNINGS) - -set(SWA_PRECOMPILED_HEADERS - "stdafx.h" -) - -set(SWA_KERNEL_CXX_SOURCES - "kernel/imports.cpp" - "kernel/xdm.cpp" - "kernel/heap.cpp" - "kernel/memory.cpp" - "kernel/xam.cpp" - "kernel/io/file_system.cpp" -) - -set(SWA_LOCALE_CXX_SOURCES - "locale/config_locale.cpp" - "locale/locale.cpp" -) - -set(SWA_OS_CXX_SOURCES - "os/logger.cpp" - "os/media.cpp" - "os/process.cpp" - "os/version.cpp" +project("UnleashedRecomp") +set(TARGET_NAME "SWA") + +if (WIN32) + option(SWA_D3D12 "Add D3D12 support for rendering" ON) +endif() + +option(SWA_XAUDIO2 "Use XAudio2 for audio playback" OFF) + +function(BIN2C) + cmake_parse_arguments(BIN2C_ARGS "" "TARGET_OBJ;SOURCE_FILE;DEST_FILE;ARRAY_NAME;COMPRESSION_TYPE" "" ${ARGN}) + + if(NOT BIN2C_ARGS_TARGET_OBJ) + message(FATAL_ERROR "TARGET_OBJ not specified.") + endif() + + if(NOT BIN2C_ARGS_SOURCE_FILE) + message(FATAL_ERROR "SOURCE_FILE not specified.") + endif() + + if(NOT BIN2C_ARGS_DEST_FILE) + set(BIN2C_ARGS_DEST_FILE "${BIN2C_ARGS_SOURCE_FILE}") + endif() + + if(NOT BIN2C_ARGS_COMPRESSION_TYPE) + set(BIN2C_ARGS_COMPRESSION_TYPE "none") + endif() + + add_custom_command(OUTPUT "${BIN2C_ARGS_DEST_FILE}.c" + COMMAND $ "${BIN2C_ARGS_SOURCE_FILE}" "${BIN2C_ARGS_ARRAY_NAME}" "${BIN2C_ARGS_COMPRESSION_TYPE}" "${BIN2C_ARGS_DEST_FILE}.c" "${BIN2C_ARGS_DEST_FILE}.h" + DEPENDS "${BIN2C_ARGS_SOURCE_FILE}" + BYPRODUCTS "${BIN2C_ARGS_DEST_FILE}.h" + COMMENT "Generating binary header for ${BIN2C_ARGS_SOURCE_FILE}..." + ) + + set_source_files_properties(${BIN2C_ARGS_DEST_FILE}.c PROPERTIES SKIP_PRECOMPILE_HEADERS ON) + target_sources(${BIN2C_ARGS_TARGET_OBJ} PRIVATE ${BIN2C_ARGS_DEST_FILE}.c) +endfunction() + +add_compile_options( + -march=sandybridge + -fno-strict-aliasing + + -Wno-switch + -Wno-unused-function + -Wno-unused-variable + -Wno-unused-but-set-variable + -Wno-void-pointer-to-int-cast + -Wno-int-to-void-pointer-cast + -Wno-invalid-offsetof + -Wno-null-arithmetic + -Wno-null-conversion + -Wno-tautological-undefined-compare ) if (WIN32) - list(APPEND SWA_OS_CXX_SOURCES - "os/win32/logger_win32.cpp" - "os/win32/media_win32.cpp" - "os/win32/process_win32.cpp" - "os/win32/version_win32.cpp" - ) -endif() - -set(SWA_CPU_CXX_SOURCES - "cpu/guest_thread.cpp" - "cpu/code_cache.cpp" + add_compile_options(/fp:strict) +else() + add_compile_options(-ffp-model=strict) +endif() + +add_compile_definitions( + SWA_IMPL + SDL_MAIN_HANDLED + _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR # Microsoft wtf? + _CRT_SECURE_NO_WARNINGS) + +set(SWA_PRECOMPILED_HEADERS + "stdafx.h" +) + +set(SWA_KERNEL_CXX_SOURCES + "kernel/imports.cpp" + "kernel/xdm.cpp" + "kernel/heap.cpp" + "kernel/memory.cpp" + "kernel/xam.cpp" + "kernel/io/file_system.cpp" +) + +set(SWA_LOCALE_CXX_SOURCES + "locale/config_locale.cpp" + "locale/locale.cpp" +) + +set(SWA_OS_CXX_SOURCES + "os/logger.cpp" + "os/media.cpp" + "os/process.cpp" + "os/version.cpp" +) + +if (WIN32) + list(APPEND SWA_OS_CXX_SOURCES + "os/win32/logger_win32.cpp" + "os/win32/media_win32.cpp" + "os/win32/process_win32.cpp" + "os/win32/version_win32.cpp" + ) +elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") + list(APPEND SWA_OS_CXX_SOURCES + "os/linux/logger_linux.cpp" + "os/linux/media_linux.cpp" + "os/linux/process_linux.cpp" + "os/linux/version_linux.cpp" + ) +endif() + +set(SWA_CPU_CXX_SOURCES + "cpu/guest_thread.cpp" + "cpu/code_cache.cpp" +) + +set(SWA_GPU_CXX_SOURCES + "gpu/video.cpp" + "gpu/imgui/imgui_common.cpp" + "gpu/imgui/imgui_font_builder.cpp" + "gpu/imgui/imgui_snapshot.cpp" + "gpu/rhi/plume_vulkan.cpp" +) + +if (SWA_D3D12) + list(APPEND SWA_GPU_CXX_SOURCES + "gpu/rhi/plume_d3d12.cpp" + ) +endif() + +set(SWA_APU_CXX_SOURCES + "apu/audio.cpp" + "apu/embedded_player.cpp" +) + +if (SWA_XAUDIO2) + list(APPEND SWA_APU_CXX_SOURCES "apu/driver/xaudio_driver.cpp") +else() + list(APPEND SWA_APU_CXX_SOURCES "apu/driver/miniaudio_driver.cpp") +endif() + +set(SWA_HID_CXX_SOURCES + "hid/hid.cpp" + "hid/driver/sdl_hid.cpp" +) + +set(SWA_PATCHES_CXX_SOURCES + "patches/ui/CHudPause_patches.cpp" + "patches/ui/CTitleStateIntro_patches.cpp" + "patches/ui/CTitleStateMenu_patches.cpp" + "patches/ui/frontend_listener.cpp" + "patches/audio_patches.cpp" + "patches/camera_patches.cpp" + "patches/fps_patches.cpp" + "patches/misc_patches.cpp" + "patches/object_patches.cpp" + "patches/player_patches.cpp" + "patches/resident_patches.cpp" + "patches/video_patches.cpp" +) + +set(SWA_UI_CXX_SOURCES + "ui/achievement_menu.cpp" + "ui/achievement_overlay.cpp" + "ui/installer_wizard.cpp" + "ui/button_guide.cpp" + "ui/fader.cpp" + "ui/message_window.cpp" + "ui/options_menu_thumbnails.cpp" + "ui/options_menu.cpp" + "ui/sdl_listener.cpp" + "ui/game_window.cpp" +) + +set(SWA_INSTALL_CXX_SOURCES + "install/installer.cpp" + "install/iso_file_system.cpp" + "install/memory_mapped_file.cpp" + "install/xcontent_file_system.cpp" + "install/xex_patcher.cpp" + "install/hashes/apotos_shamar.cpp" + "install/hashes/chunnan.cpp" + "install/hashes/empire_city_adabat.cpp" + "install/hashes/game.cpp" + "install/hashes/holoska.cpp" + "install/hashes/mazuri.cpp" + "install/hashes/spagonia.cpp" + "install/hashes/update.cpp" ) -set(SWA_GPU_CXX_SOURCES - "gpu/video.cpp" - "gpu/imgui/imgui_common.cpp" - "gpu/imgui/imgui_font_builder.cpp" - "gpu/imgui/imgui_snapshot.cpp" - "gpu/rhi/plume_vulkan.cpp" +set(SWA_USER_CXX_SOURCES + "user/achievement_data.cpp" + "user/config.cpp" +) + +set(SWA_THIRDPARTY_SOURCES + "${SWA_THIRDPARTY_ROOT}/imgui/backends/imgui_impl_sdl2.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui_demo.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui_draw.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui_tables.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui_widgets.cpp" + "${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack/lzxd.c" + "${SWA_THIRDPARTY_ROOT}/tiny-AES-c/aes.c" + "${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source/smolv.cpp" +) + +set(SWA_THIRDPARTY_INCLUDES + "${SWA_THIRDPARTY_ROOT}/concurrentqueue" + "${SWA_THIRDPARTY_ROOT}/ddspp" + "${SWA_THIRDPARTY_ROOT}/imgui" + "${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack" + "${SWA_THIRDPARTY_ROOT}/magic_enum/include" + "${SWA_THIRDPARTY_ROOT}/miniaudio" + "${SWA_THIRDPARTY_ROOT}/stb" + "${SWA_THIRDPARTY_ROOT}/tiny-AES-c" + "${SWA_THIRDPARTY_ROOT}/TinySHA1" + "${SWA_THIRDPARTY_ROOT}/unordered_dense/include" + "${SWA_THIRDPARTY_ROOT}/volk" + "${SWA_THIRDPARTY_ROOT}/Vulkan-Headers/include" + "${SWA_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include" + "${SWA_TOOLS_ROOT}/bc_diff" + "${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source" ) if (SWA_D3D12) - list(APPEND SWA_GPU_CXX_SOURCES - "gpu/rhi/plume_d3d12.cpp" - ) -endif() - -set(SWA_APU_CXX_SOURCES - "apu/audio.cpp" - "apu/embedded_player.cpp" -) - -if (SWA_XAUDIO2) - list(APPEND SWA_APU_CXX_SOURCES "apu/driver/xaudio_driver.cpp") -else() - list(APPEND SWA_APU_CXX_SOURCES "apu/driver/miniaudio_driver.cpp") -endif() - -set(SWA_HID_CXX_SOURCES - "hid/hid.cpp" - "hid/driver/sdl_hid.cpp" -) - -set(SWA_PATCHES_CXX_SOURCES - "patches/ui/CHudPause_patches.cpp" - "patches/ui/CTitleStateIntro_patches.cpp" - "patches/ui/CTitleStateMenu_patches.cpp" - "patches/ui/frontend_listener.cpp" - "patches/audio_patches.cpp" - "patches/camera_patches.cpp" - "patches/fps_patches.cpp" - "patches/misc_patches.cpp" - "patches/object_patches.cpp" - "patches/player_patches.cpp" - "patches/resident_patches.cpp" - "patches/video_patches.cpp" -) - -set(SWA_UI_CXX_SOURCES - "ui/achievement_menu.cpp" - "ui/achievement_overlay.cpp" - "ui/installer_wizard.cpp" - "ui/button_guide.cpp" - "ui/fader.cpp" - "ui/message_window.cpp" - "ui/options_menu_thumbnails.cpp" - "ui/options_menu.cpp" - "ui/sdl_listener.cpp" - "ui/window.cpp" -) - -set(SWA_INSTALL_CXX_SOURCES - "install/installer.cpp" - "install/iso_file_system.cpp" - "install/memory_mapped_file.cpp" - "install/xcontent_file_system.cpp" - "install/xex_patcher.cpp" - "install/hashes/apotos_shamar.cpp" - "install/hashes/chunnan.cpp" - "install/hashes/empire_city_adabat.cpp" - "install/hashes/game.cpp" - "install/hashes/holoska.cpp" - "install/hashes/mazuri.cpp" - "install/hashes/spagonia.cpp" - "install/hashes/update.cpp" -) - -set(LIBMSPACK_PATH ${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack) - -set(LIBMSPACK_C_SOURCES - ${LIBMSPACK_PATH}/lzxd.c -) - -set_source_files_properties(${LIBMSPACK_C_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON) - -set(SMOLV_SOURCE_DIR "${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source") -set(BC_DIFF_SOURCE_DIR "${SWA_TOOLS_ROOT}/bc_diff") - -set(MINIAUDIO_INCLUDE_DIRS "${SWA_THIRDPARTY_ROOT}/miniaudio") - -set(SWA_USER_CXX_SOURCES - "user/achievement_data.cpp" - "user/config.cpp" - "user/config_detail.cpp" -) - -set(SWA_CXX_SOURCES - "app.cpp" - "exports.cpp" - "main.cpp" - "misc_impl.cpp" - "stdafx.cpp" - - ${SWA_KERNEL_CXX_SOURCES} - ${SWA_LOCALE_CXX_SOURCES} - ${SWA_OS_CXX_SOURCES} - ${SWA_CPU_CXX_SOURCES} - ${SWA_GPU_CXX_SOURCES} - ${SWA_APU_CXX_SOURCES} - ${SWA_HID_CXX_SOURCES} - ${SWA_PATCHES_CXX_SOURCES} - ${SWA_UI_CXX_SOURCES} - ${SWA_INSTALL_CXX_SOURCES} - ${LIBMSPACK_C_SOURCES} - "${SMOLV_SOURCE_DIR}/smolv.cpp" + list(APPEND SWA_THIRDPARTY_INCLUDES "${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include") + list(APPEND SWA_THIRDPARTY_SOURCES "${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp") +endif() + +set_source_files_properties(${SWA_THIRDPARTY_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON) + +set(SWA_CXX_SOURCES + "app.cpp" + "exports.cpp" + "main.cpp" + "misc_impl.cpp" + "stdafx.cpp" + + ${SWA_KERNEL_CXX_SOURCES} + ${SWA_LOCALE_CXX_SOURCES} + ${SWA_OS_CXX_SOURCES} + ${SWA_CPU_CXX_SOURCES} + ${SWA_GPU_CXX_SOURCES} + ${SWA_APU_CXX_SOURCES} + ${SWA_HID_CXX_SOURCES} + ${SWA_PATCHES_CXX_SOURCES} + ${SWA_UI_CXX_SOURCES} + ${SWA_INSTALL_CXX_SOURCES} ${SWA_USER_CXX_SOURCES} -) - -if (WIN32) - # Set up Win32 resources for application icon. - set(ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico") - configure_file("res/win32/res.rc" "${CMAKE_BINARY_DIR}/res.rc" @ONLY) - add_executable(UnleashedRecomp ${SWA_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") -else() - add_executable(UnleashedRecomp ${SWA_CXX_SOURCES}) -endif() - -set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) - -if (SWA_D3D12) - find_package(directx-headers CONFIG REQUIRED) - find_package(directx12-agility CONFIG REQUIRED) - find_package(d3d12-memory-allocator CONFIG REQUIRED) - target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12) -endif() - -find_package(SDL2 CONFIG REQUIRED) -find_package(unordered_dense CONFIG REQUIRED) -find_package(VulkanHeaders CONFIG) -find_package(volk CONFIG REQUIRED) -find_package(VulkanMemoryAllocator CONFIG REQUIRED) -find_package(xxHash CONFIG REQUIRED) -find_package(PkgConfig REQUIRED) -pkg_check_modules(tomlplusplus REQUIRED IMPORTED_TARGET tomlplusplus) + ${SWA_THIRDPARTY_SOURCES} +) + +if (WIN32) + # Set up Win32 resources for application icon. + set(ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico") + configure_file("res/win32/res.rc" "${CMAKE_BINARY_DIR}/res.rc" @ONLY) + add_executable(UnleashedRecomp ${SWA_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") +else() + add_executable(UnleashedRecomp ${SWA_CXX_SOURCES}) +endif() + +set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) + +if (SWA_D3D12) + find_package(directx-headers CONFIG REQUIRED) + find_package(directx12-agility CONFIG REQUIRED) + target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12) +endif() + find_package(directx-dxc REQUIRED) -find_package(zstd CONFIG REQUIRED) -find_package(Stb REQUIRED) -find_package(unofficial-concurrentqueue REQUIRED) -find_package(imgui CONFIG REQUIRED) -find_package(magic_enum CONFIG REQUIRED) -find_package(unofficial-tiny-aes-c CONFIG REQUIRED) -find_package(nfd CONFIG REQUIRED) -find_package(Vorbis CONFIG REQUIRED) -find_package(fmt CONFIG REQUIRED) - -if (SWA_D3D12) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) - add_custom_command(TARGET UnleashedRecomp POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/D3D12 - COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/D3D12 - COMMAND_EXPAND_LISTS - ) - - file(COPY ${PACKAGE_PREFIX_DIR}/bin/dxil.dll DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - - target_link_libraries(UnleashedRecomp PRIVATE - Microsoft::DirectX-Headers - Microsoft::DirectX-Guids - Microsoft::DirectX12-Agility + +if (SWA_D3D12) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) + add_custom_command(TARGET UnleashedRecomp POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/D3D12 + COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/D3D12 + COMMAND_EXPAND_LISTS + ) + + file(COPY ${PACKAGE_PREFIX_DIR}/bin/dxil.dll DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + + target_link_libraries(UnleashedRecomp PRIVATE + Microsoft::DirectX-Headers + Microsoft::DirectX-Guids + Microsoft::DirectX12-Agility Microsoft::DirectXShaderCompiler - unofficial::D3D12MemoryAllocator - dxgi - ) -endif() - -if (WIN32) - target_link_libraries(UnleashedRecomp PRIVATE - comctl32 - ntdll - winmm - Synchronization - ) -endif() - -target_link_libraries(UnleashedRecomp PRIVATE - Vulkan::Headers - volk::volk - volk::volk_headers - GPUOpen::VulkanMemoryAllocator - o1heap - PowerUtils - SDL2::SDL2-static - UnleashedRecompLib - unordered_dense::unordered_dense - xxHash::xxhash - PkgConfig::tomlplusplus - zstd::libzstd_static - unofficial::concurrentqueue::concurrentqueue - imgui::imgui - magic_enum::magic_enum - unofficial::tiny-aes-c::tiny-aes-c - nfd::nfd - msdf-atlas-gen::msdf-atlas-gen - Vorbis::vorbisfile + Microsoft::DXIL + dxgi + ) +endif() + +file(CHMOD ${DIRECTX_DXC_TOOL} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) + +if (WIN32) + target_link_libraries(UnleashedRecomp PRIVATE + comctl32 + ntdll + winmm + Synchronization + ) +endif() + +target_link_libraries(UnleashedRecomp PRIVATE fmt::fmt -) - -target_include_directories(UnleashedRecomp PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/api - ${SWA_THIRDPARTY_ROOT}/ddspp - ${SWA_THIRDPARTY_ROOT}/TinySHA1 - ${LIBMSPACK_PATH} - ${Stb_INCLUDE_DIR} - ${SMOLV_SOURCE_DIR} - ${MINIAUDIO_INCLUDE_DIRS} - ${BC_DIFF_SOURCE_DIR} -) - -target_precompile_headers(UnleashedRecomp PUBLIC ${SWA_PRECOMPILED_HEADERS}) - -function(compile_shader FILE_PATH TARGET_NAME) - set(FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/gpu/shader/${FILE_PATH}.hlsl) - cmake_path(GET FILE_PATH STEM VARIABLE_NAME) - if (SWA_D3D12) - add_custom_command( - OUTPUT ${FILE_PATH}.dxil.h - COMMAND ${DIRECTX_DXC_TOOL} -T ${TARGET_NAME} -HV 2021 -all-resources-bound -Wno-ignored-attributes -Fh ${FILE_PATH}.dxil.h ${FILE_PATH} -Vn g_${VARIABLE_NAME}_dxil - DEPENDS ${FILE_PATH} - ) - target_sources(UnleashedRecomp PRIVATE ${FILE_PATH}.dxil.h) - endif() - add_custom_command( - OUTPUT ${FILE_PATH}.spirv.h - COMMAND ${DIRECTX_DXC_TOOL} -T ${TARGET_NAME} -HV 2021 -all-resources-bound -spirv -fvk-use-dx-layout ${ARGN} -Fh ${FILE_PATH}.spirv.h ${FILE_PATH} -Vn g_${VARIABLE_NAME}_spirv - DEPENDS ${FILE_PATH} - ) - target_sources(UnleashedRecomp PRIVATE ${FILE_PATH}.spirv.h) -endfunction() - -function(compile_vertex_shader FILE_PATH) - compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y) -endfunction() - -function(compile_pixel_shader FILE_PATH) - compile_shader(${FILE_PATH} ps_6_0) -endfunction() - -compile_vertex_shader(copy_vs) -compile_pixel_shader(csd_filter_ps) -compile_pixel_shader(enhanced_motion_blur_ps) -compile_pixel_shader(gaussian_blur_3x3) -compile_pixel_shader(gaussian_blur_5x5) -compile_pixel_shader(gaussian_blur_7x7) -compile_pixel_shader(gaussian_blur_9x9) -compile_pixel_shader(gamma_correction_ps) -compile_pixel_shader(imgui_ps) -compile_vertex_shader(imgui_vs) -compile_pixel_shader(movie_ps) -compile_vertex_shader(movie_vs) -compile_pixel_shader(resolve_msaa_depth_2x) -compile_pixel_shader(resolve_msaa_depth_4x) -compile_pixel_shader(resolve_msaa_depth_8x) - -function(generate_aggregate_header INPUT_DIRECTORY OUTPUT_FILE) - get_filename_component(ABS_OUTPUT_FILE "${OUTPUT_FILE}" ABSOLUTE) - file(GLOB_RECURSE HEADER_FILES "${INPUT_DIRECTORY}/*.h") - set(HEADER_CONTENT "#pragma once\n\n") - - foreach(HEADER_FILE IN LISTS HEADER_FILES) - get_filename_component(ABS_HEADER_FILE "${HEADER_FILE}" ABSOLUTE) - if (ABS_HEADER_FILE STREQUAL ABS_OUTPUT_FILE) - continue() - endif() - file(RELATIVE_PATH RELATIVE_HEADER_FILE "${INPUT_DIRECTORY}" "${HEADER_FILE}") - string(APPEND HEADER_CONTENT "#include \"${RELATIVE_HEADER_FILE}\"\n") - endforeach() - - if (EXISTS "${OUTPUT_FILE}") - file(READ "${OUTPUT_FILE}" EXISTING_CONTENT) - if (EXISTING_CONTENT STREQUAL HEADER_CONTENT) - return() - endif() - endif() - - file(WRITE "${OUTPUT_FILE}" "${HEADER_CONTENT}") -endfunction() - -generate_aggregate_header( + libzstd_static + msdf-atlas-gen::msdf-atlas-gen + nfd::nfd + o1heap + PowerUtils + SDL2::SDL2-static + tomlplusplus::tomlplusplus + UnleashedRecompLib + Vorbis::vorbisfile + xxHash::xxhash ) + +target_include_directories(UnleashedRecomp PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/api" - "${CMAKE_CURRENT_SOURCE_DIR}/api/SWA.h" -) - -set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") -set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") - -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/bc_diff/button_bc_diff.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/bc_diff/button_bc_diff.bin" ARRAY_NAME "g_button_bc_diff" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.bin" ARRAY_NAME "g_im_font_atlas" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.dds" ARRAY_NAME "g_im_font_atlas_texture" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/achievements_menu/trophy.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/achievements_menu/trophy.dds" ARRAY_NAME "g_trophy" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/controller.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/controller.dds" ARRAY_NAME "g_controller" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/general_window.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/general_window.dds" ARRAY_NAME "g_general_window" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/kbm.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/kbm.dds" ARRAY_NAME "g_kbm" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_NAME "g_select_fade" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_NAME "g_select_fill" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_NAME "g_arrow_circle" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_002.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_002.dds" ARRAY_NAME "g_install_002" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_003.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_003.dds" ARRAY_NAME "g_install_003" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_004.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_004.dds" ARRAY_NAME "g_install_004" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_005.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_005.dds" ARRAY_NAME "g_install_005" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_006.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_006.dds" ARRAY_NAME "g_install_006" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_007.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_007.dds" ARRAY_NAME "g_install_007" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_008.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_008.dds" ARRAY_NAME "g_install_008" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/miles_electric_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/miles_electric_icon.dds" ARRAY_NAME "g_miles_electric_icon" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" ARRAY_NAME "g_achievement_notifications" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input.dds" ARRAY_NAME "g_allow_background_input" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_dpad_movement.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_dpad_movement.dds" ARRAY_NAME "g_allow_dpad_movement" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing.dds" ARRAY_NAME "g_antialiasing" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" ARRAY_NAME "g_aspect_ratio" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/battle_theme.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/battle_theme.dds" ARRAY_NAME "g_battle_theme" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/brightness.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/brightness.dds" ARRAY_NAME "g_brightness" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial.dds" ARRAY_NAME "g_control_tutorial" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/controller_icons.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/controller_icons.dds" ARRAY_NAME "g_controller_icons" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/default.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/default.dds" ARRAY_NAME "g_default" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/effects_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/effects_volume.dds" ARRAY_NAME "g_effects_volume" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/fps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/fps.dds" ARRAY_NAME "g_fps" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/fullscreen.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/fullscreen.dds" ARRAY_NAME "g_fullscreen" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/gi_texture_filtering_bilinear.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/gi_texture_filtering_bilinear.dds" ARRAY_NAME "g_gi_texture_filtering_bilinear" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/gi_texture_filtering_bicubic.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/gi_texture_filtering_bicubic.dds" ARRAY_NAME "g_gi_texture_filtering_bicubic" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/hints.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/hints.dds" ARRAY_NAME "g_hints" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/invert_camera_x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/invert_camera_x.dds" ARRAY_NAME "g_invert_camera_x" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/invert_camera_y.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/invert_camera_y.dds" ARRAY_NAME "g_invert_camera_y" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/language.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/language.dds" ARRAY_NAME "g_language" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/monitor.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/monitor.dds" ARRAY_NAME "g_monitor" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_off.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_off.dds" ARRAY_NAME "g_motion_blur_off" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_original.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_original.dds" ARRAY_NAME "g_motion_blur_original" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_enhanced.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_enhanced.dds" ARRAY_NAME "g_motion_blur_enhanced" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_mode.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_mode.dds" ARRAY_NAME "g_movie_scale_mode" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_attenuation.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_attenuation.dds" ARRAY_NAME "g_music_attenuation" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_volume.dds" ARRAY_NAME "g_music_volume" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/resolution_scale.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/resolution_scale.dds" ARRAY_NAME "g_resolution_scale" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_original.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_original.dds" ARRAY_NAME "g_shadow_resolution_original" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x512.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x512.dds" ARRAY_NAME "g_shadow_resolution_x512" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x1024.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x1024.dds" ARRAY_NAME "g_shadow_resolution_x1024" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x2048.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x2048.dds" ARRAY_NAME "g_shadow_resolution_x2048" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x4096.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x4096.dds" ARRAY_NAME "g_shadow_resolution_x4096" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x8192.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x8192.dds" ARRAY_NAME "g_shadow_resolution_x8192" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/subtitles.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/subtitles.dds" ARRAY_NAME "g_subtitles" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_of_day_transition_xbox.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_of_day_transition_xbox.dds" ARRAY_NAME "g_time_of_day_transition_xbox" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_of_day_transition_playstation.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_of_day_transition_playstation.dds" ARRAY_NAME "g_time_of_day_transition_playstation" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/transparency_antialiasing_false.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/transparency_antialiasing_false.dds" ARRAY_NAME "g_transparency_antialiasing_false" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/transparency_antialiasing_true.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/transparency_antialiasing_true.dds" ARRAY_NAME "g_transparency_antialiasing_true" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_scale_mode.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_scale_mode.dds" ARRAY_NAME "g_ui_scale_mode" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/voice_language.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/voice_language.dds" ARRAY_NAME "g_voice_language" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync.dds" ARRAY_NAME "g_vsync" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/window_size.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/window_size.dds" ARRAY_NAME "g_window_size" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction_false.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction_false.dds" ARRAY_NAME "g_xbox_color_correction_false" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction_true.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction_true.dds" ARRAY_NAME "g_xbox_color_correction_true" COMPRESSION_TYPE "zstd") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_NAME "g_game_icon") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_worldmap_cursor.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_worldmap_cursor.ogg" ARRAY_NAME "g_sys_worldmap_cursor") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_worldmap_finaldecide.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_worldmap_finaldecide.ogg" ARRAY_NAME "g_sys_worldmap_finaldecide") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausecansel.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausecansel.ogg" ARRAY_NAME "g_sys_actstg_pausecansel") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausecursor.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausecursor.ogg" ARRAY_NAME "g_sys_actstg_pausecursor") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausedecide.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausedecide.ogg" ARRAY_NAME "g_sys_actstg_pausedecide") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinclose.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinclose.ogg" ARRAY_NAME "g_sys_actstg_pausewinclose") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinopen.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinopen.ogg" ARRAY_NAME "g_sys_actstg_pausewinopen") - + ${SWA_THIRDPARTY_INCLUDES} +) + +if (CMAKE_SYSTEM_NAME MATCHES "Linux") + find_package(X11 REQUIRED) + target_include_directories(UnleashedRecomp PRIVATE ${X11_INCLUDE_DIR}) + target_link_libraries(UnleashedRecomp PRIVATE ${X11_LIBRARIES}) +endif() + +target_precompile_headers(UnleashedRecomp PUBLIC ${SWA_PRECOMPILED_HEADERS}) + +function(compile_shader FILE_PATH TARGET_NAME) + set(FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/gpu/shader/${FILE_PATH}.hlsl) + cmake_path(GET FILE_PATH STEM VARIABLE_NAME) + if (SWA_D3D12) + add_custom_command( + OUTPUT ${FILE_PATH}.dxil.h + COMMAND ${DIRECTX_DXC_TOOL} -T ${TARGET_NAME} -HV 2021 -all-resources-bound -Wno-ignored-attributes -Fh ${FILE_PATH}.dxil.h ${FILE_PATH} -Vn g_${VARIABLE_NAME}_dxil + DEPENDS ${FILE_PATH} + ) + target_sources(UnleashedRecomp PRIVATE ${FILE_PATH}.dxil.h) + endif() + add_custom_command( + OUTPUT ${FILE_PATH}.spirv.h + COMMAND ${DIRECTX_DXC_TOOL} -T ${TARGET_NAME} -HV 2021 -all-resources-bound -spirv -fvk-use-dx-layout ${ARGN} -Fh ${FILE_PATH}.spirv.h ${FILE_PATH} -Vn g_${VARIABLE_NAME}_spirv + DEPENDS ${FILE_PATH} + ) + target_sources(UnleashedRecomp PRIVATE ${FILE_PATH}.spirv.h) +endfunction() + +function(compile_vertex_shader FILE_PATH) + compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y) +endfunction() + +function(compile_pixel_shader FILE_PATH) + compile_shader(${FILE_PATH} ps_6_0) +endfunction() + +compile_vertex_shader(copy_vs) +compile_pixel_shader(csd_filter_ps) +compile_pixel_shader(enhanced_motion_blur_ps) +compile_pixel_shader(gaussian_blur_3x3) +compile_pixel_shader(gaussian_blur_5x5) +compile_pixel_shader(gaussian_blur_7x7) +compile_pixel_shader(gaussian_blur_9x9) +compile_pixel_shader(gamma_correction_ps) +compile_pixel_shader(imgui_ps) +compile_vertex_shader(imgui_vs) +compile_pixel_shader(movie_ps) +compile_vertex_shader(movie_vs) +compile_pixel_shader(resolve_msaa_depth_2x) +compile_pixel_shader(resolve_msaa_depth_4x) +compile_pixel_shader(resolve_msaa_depth_8x) + +function(generate_aggregate_header INPUT_DIRECTORY OUTPUT_FILE) + get_filename_component(ABS_OUTPUT_FILE "${OUTPUT_FILE}" ABSOLUTE) + file(GLOB_RECURSE HEADER_FILES "${INPUT_DIRECTORY}/*.h") + set(HEADER_CONTENT "#pragma once\n\n") + + foreach(HEADER_FILE IN LISTS HEADER_FILES) + get_filename_component(ABS_HEADER_FILE "${HEADER_FILE}" ABSOLUTE) + if (ABS_HEADER_FILE STREQUAL ABS_OUTPUT_FILE) + continue() + endif() + file(RELATIVE_PATH RELATIVE_HEADER_FILE "${INPUT_DIRECTORY}" "${HEADER_FILE}") + string(APPEND HEADER_CONTENT "#include \"${RELATIVE_HEADER_FILE}\"\n") + endforeach() + + if (EXISTS "${OUTPUT_FILE}") + file(READ "${OUTPUT_FILE}" EXISTING_CONTENT) + if (EXISTING_CONTENT STREQUAL HEADER_CONTENT) + return() + endif() + endif() + + file(WRITE "${OUTPUT_FILE}" "${HEADER_CONTENT}") +endfunction() + +generate_aggregate_header( + "${CMAKE_CURRENT_SOURCE_DIR}/api" + "${CMAKE_CURRENT_SOURCE_DIR}/api/SWA.h" +) + +set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") +set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") + +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/bc_diff/button_bc_diff.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/bc_diff/button_bc_diff.bin" ARRAY_NAME "g_button_bc_diff" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.bin" ARRAY_NAME "g_im_font_atlas" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.dds" ARRAY_NAME "g_im_font_atlas_texture" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/achievements_menu/trophy.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/achievements_menu/trophy.dds" ARRAY_NAME "g_trophy" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/controller.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/controller.dds" ARRAY_NAME "g_controller" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/general_window.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/general_window.dds" ARRAY_NAME "g_general_window" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/kbm.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/kbm.dds" ARRAY_NAME "g_kbm" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_NAME "g_select_fade" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_NAME "g_select_fill" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_NAME "g_arrow_circle" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_002.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_002.dds" ARRAY_NAME "g_install_002" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_003.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_003.dds" ARRAY_NAME "g_install_003" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_004.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_004.dds" ARRAY_NAME "g_install_004" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_005.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_005.dds" ARRAY_NAME "g_install_005" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_006.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_006.dds" ARRAY_NAME "g_install_006" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_007.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_007.dds" ARRAY_NAME "g_install_007" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_008.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_008.dds" ARRAY_NAME "g_install_008" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/miles_electric_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/miles_electric_icon.dds" ARRAY_NAME "g_miles_electric_icon" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" ARRAY_NAME "g_achievement_notifications" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input.dds" ARRAY_NAME "g_allow_background_input" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_dpad_movement.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_dpad_movement.dds" ARRAY_NAME "g_allow_dpad_movement" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing.dds" ARRAY_NAME "g_antialiasing" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" ARRAY_NAME "g_aspect_ratio" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/battle_theme.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/battle_theme.dds" ARRAY_NAME "g_battle_theme" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/brightness.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/brightness.dds" ARRAY_NAME "g_brightness" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial.dds" ARRAY_NAME "g_control_tutorial" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/controller_icons.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/controller_icons.dds" ARRAY_NAME "g_controller_icons" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/default.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/default.dds" ARRAY_NAME "g_default" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/effects_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/effects_volume.dds" ARRAY_NAME "g_effects_volume" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/fps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/fps.dds" ARRAY_NAME "g_fps" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/fullscreen.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/fullscreen.dds" ARRAY_NAME "g_fullscreen" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/gi_texture_filtering_bilinear.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/gi_texture_filtering_bilinear.dds" ARRAY_NAME "g_gi_texture_filtering_bilinear" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/gi_texture_filtering_bicubic.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/gi_texture_filtering_bicubic.dds" ARRAY_NAME "g_gi_texture_filtering_bicubic" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/hints.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/hints.dds" ARRAY_NAME "g_hints" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/invert_camera_x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/invert_camera_x.dds" ARRAY_NAME "g_invert_camera_x" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/invert_camera_y.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/invert_camera_y.dds" ARRAY_NAME "g_invert_camera_y" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/language.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/language.dds" ARRAY_NAME "g_language" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/monitor.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/monitor.dds" ARRAY_NAME "g_monitor" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_off.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_off.dds" ARRAY_NAME "g_motion_blur_off" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_original.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_original.dds" ARRAY_NAME "g_motion_blur_original" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_enhanced.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_enhanced.dds" ARRAY_NAME "g_motion_blur_enhanced" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_mode.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_mode.dds" ARRAY_NAME "g_movie_scale_mode" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_attenuation.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_attenuation.dds" ARRAY_NAME "g_music_attenuation" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_volume.dds" ARRAY_NAME "g_music_volume" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/resolution_scale.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/resolution_scale.dds" ARRAY_NAME "g_resolution_scale" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_original.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_original.dds" ARRAY_NAME "g_shadow_resolution_original" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x512.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x512.dds" ARRAY_NAME "g_shadow_resolution_x512" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x1024.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x1024.dds" ARRAY_NAME "g_shadow_resolution_x1024" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x2048.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x2048.dds" ARRAY_NAME "g_shadow_resolution_x2048" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x4096.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x4096.dds" ARRAY_NAME "g_shadow_resolution_x4096" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x8192.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x8192.dds" ARRAY_NAME "g_shadow_resolution_x8192" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/subtitles.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/subtitles.dds" ARRAY_NAME "g_subtitles" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_of_day_transition_xbox.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_of_day_transition_xbox.dds" ARRAY_NAME "g_time_of_day_transition_xbox" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_of_day_transition_playstation.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_of_day_transition_playstation.dds" ARRAY_NAME "g_time_of_day_transition_playstation" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/transparency_antialiasing_false.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/transparency_antialiasing_false.dds" ARRAY_NAME "g_transparency_antialiasing_false" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/transparency_antialiasing_true.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/transparency_antialiasing_true.dds" ARRAY_NAME "g_transparency_antialiasing_true" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_scale_mode.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_scale_mode.dds" ARRAY_NAME "g_ui_scale_mode" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/voice_language.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/voice_language.dds" ARRAY_NAME "g_voice_language" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync.dds" ARRAY_NAME "g_vsync" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/window_size.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/window_size.dds" ARRAY_NAME "g_window_size" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction_false.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction_false.dds" ARRAY_NAME "g_xbox_color_correction_false" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction_true.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction_true.dds" ARRAY_NAME "g_xbox_color_correction_true" COMPRESSION_TYPE "zstd") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_NAME "g_game_icon") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_worldmap_cursor.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_worldmap_cursor.ogg" ARRAY_NAME "g_sys_worldmap_cursor") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_worldmap_finaldecide.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_worldmap_finaldecide.ogg" ARRAY_NAME "g_sys_worldmap_finaldecide") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausecansel.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausecansel.ogg" ARRAY_NAME "g_sys_actstg_pausecansel") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausecursor.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausecursor.ogg" ARRAY_NAME "g_sys_actstg_pausecursor") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausedecide.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausedecide.ogg" ARRAY_NAME "g_sys_actstg_pausedecide") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinclose.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinclose.ogg" ARRAY_NAME "g_sys_actstg_pausewinclose") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinopen.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinopen.ogg" ARRAY_NAME "g_sys_actstg_pausewinopen") + diff --git a/UnleashedRecomp/app.cpp b/UnleashedRecomp/app.cpp index 94cc4191..ac936fc7 100644 --- a/UnleashedRecomp/app.cpp +++ b/UnleashedRecomp/app.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -15,10 +15,7 @@ void App::Restart(std::vector restartArgs) void App::Exit() { Config::Save(); - -#if _WIN32 - ExitProcess(0); -#endif + std::_Exit(0); } // CApplication::Ctor @@ -41,7 +38,7 @@ PPC_FUNC(sub_822C1130) SDL_PumpEvents(); SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); - Window::Update(); + GameWindow::Update(); AudioPatches::Update(App::s_deltaTime); __imp__sub_822C1130(ctx, base); diff --git a/UnleashedRecomp/app.h b/UnleashedRecomp/app.h index e5ea4343..b6541358 100644 --- a/UnleashedRecomp/app.h +++ b/UnleashedRecomp/app.h @@ -1,6 +1,6 @@ #pragma once -#include +#include class App { diff --git a/UnleashedRecomp/apu/audio.cpp b/UnleashedRecomp/apu/audio.cpp index 582231a9..9f0f2de8 100644 --- a/UnleashedRecomp/apu/audio.cpp +++ b/UnleashedRecomp/apu/audio.cpp @@ -14,7 +14,7 @@ std::ofstream g_audioDumpStream; #endif -uint32_t XAudioRegisterRenderDriverClient(XLPDWORD callback, XLPDWORD driver) +uint32_t XAudioRegisterRenderDriverClient(be* callback, be* driver) { #ifdef AUDIO_DUMP_SAMPLES_PATH g_audioDumpStream.open(AUDIO_DUMP_SAMPLES_PATH, std::ios::binary); @@ -25,7 +25,7 @@ uint32_t XAudioRegisterRenderDriverClient(XLPDWORD callback, XLPDWORD driver) return 0; } -uint32_t XAudioUnregisterRenderDriverClient(DWORD driver) +uint32_t XAudioUnregisterRenderDriverClient(uint32_t driver) { return 0; } diff --git a/UnleashedRecomp/apu/audio.h b/UnleashedRecomp/apu/audio.h index c09a1f8a..229264f5 100644 --- a/UnleashedRecomp/apu/audio.h +++ b/UnleashedRecomp/apu/audio.h @@ -13,6 +13,6 @@ void XAudioRegisterClient(PPCFunc* callback, uint32_t param); void XAudioSubmitFrame(void* samples); #endif -uint32_t XAudioRegisterRenderDriverClient(XLPDWORD callback, XLPDWORD driver); -uint32_t XAudioUnregisterRenderDriverClient(DWORD driver); +uint32_t XAudioRegisterRenderDriverClient(be* callback, be* driver); +uint32_t XAudioUnregisterRenderDriverClient(uint32_t driver); uint32_t XAudioSubmitRenderDriverFrame(uint32_t driver, void* samples); diff --git a/UnleashedRecomp/apu/driver/miniaudio_driver.cpp b/UnleashedRecomp/apu/driver/miniaudio_driver.cpp index 8ac823d3..b2dbc0ee 100644 --- a/UnleashedRecomp/apu/driver/miniaudio_driver.cpp +++ b/UnleashedRecomp/apu/driver/miniaudio_driver.cpp @@ -5,7 +5,7 @@ #include static PPCFunc* g_clientCallback{}; -static DWORD g_clientCallbackParam{}; // pointer in guest memory +static uint32_t g_clientCallbackParam{}; // pointer in guest memory static ma_device g_audioDevice{}; static std::unique_ptr g_audioCtx; static uint32_t* g_audioOutput; diff --git a/UnleashedRecomp/cpu/code_cache.cpp b/UnleashedRecomp/cpu/code_cache.cpp index 1c8775e0..bbbebc4a 100644 --- a/UnleashedRecomp/cpu/code_cache.cpp +++ b/UnleashedRecomp/cpu/code_cache.cpp @@ -9,7 +9,7 @@ CodeCache::CodeCache() assert(bucket != nullptr); #else bucket = (char*)mmap(NULL, 0x200000000, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); - assert(bucket != (char *)MAP_FAILED) + assert(bucket != (char*)MAP_FAILED); #endif } @@ -36,12 +36,12 @@ void CodeCache::Init() } } -void CodeCache::Insert(uint32_t guest, const void* host) +void CodeCache::Insert(uint32_t guest, PPCFunc* host) { #ifdef _WIN32 VirtualAlloc(bucket + static_cast(guest) * 2, sizeof(void*), MEM_COMMIT, PAGE_READWRITE); #endif - *reinterpret_cast(bucket + static_cast(guest) * 2) = host; + *reinterpret_cast(bucket + static_cast(guest) * 2) = host; } void* CodeCache::Find(uint32_t guest) const @@ -56,5 +56,5 @@ SWA_API PPCFunc* KeFindHostFunction(uint32_t guest) SWA_API void KeInsertHostFunction(uint32_t guest, PPCFunc* function) { - g_codeCache.Insert(guest, (const void*)function); + g_codeCache.Insert(guest, function); } diff --git a/UnleashedRecomp/cpu/code_cache.h b/UnleashedRecomp/cpu/code_cache.h index 35d610bf..e2a1d5ac 100644 --- a/UnleashedRecomp/cpu/code_cache.h +++ b/UnleashedRecomp/cpu/code_cache.h @@ -8,7 +8,7 @@ struct CodeCache ~CodeCache(); void Init(); - void Insert(uint32_t guest, const void* host); + void Insert(uint32_t guest, PPCFunc* host); void* Find(uint32_t guest) const; }; diff --git a/UnleashedRecomp/exports.cpp b/UnleashedRecomp/exports.cpp index ee4eb0dd..9a5d166e 100644 --- a/UnleashedRecomp/exports.cpp +++ b/UnleashedRecomp/exports.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include SWA_API void Game_PlaySound(const char* pName) @@ -31,5 +31,5 @@ SWA_API void Game_PlaySound(const char* pName) SWA_API void Window_SetFullscreen(bool isEnabled) { - Window::SetFullscreen(isEnabled); + GameWindow::SetFullscreen(isEnabled); } diff --git a/UnleashedRecomp/framework.h b/UnleashedRecomp/framework.h index a8234114..68ad36f7 100644 --- a/UnleashedRecomp/framework.h +++ b/UnleashedRecomp/framework.h @@ -4,8 +4,9 @@ #define SWA_DLLEXPORT __declspec(dllexport) #define SWA_DLLIMPORT __declspec(dllimport) #else - #define SWA_DLLEXPORT __attribute__((dllexport)) - #define SWA_DLLIMPORT __attribute__((dllimport)) + // TODO + #define SWA_DLLEXPORT + #define SWA_DLLIMPORT #endif #ifdef SWA_IMPL @@ -33,19 +34,6 @@ inline T RoundDown(const T& in_rValue, uint32_t in_round) return in_rValue & ~(in_round - 1); } -inline bool FileExists(const char* path) -{ - const auto attributes = GetFileAttributesA(path); - return attributes != INVALID_FILE_ATTRIBUTES && !(attributes & FILE_ATTRIBUTE_DIRECTORY); - -} - -inline bool DirectoryExists(const char* path) -{ - const auto attributes = GetFileAttributesA(path); - return attributes != INVALID_FILE_ATTRIBUTES && !!(attributes & FILE_ATTRIBUTE_DIRECTORY); -} - inline size_t StringHash(const std::string_view& str) { return XXH3_64bits(str.data(), str.size()); diff --git a/UnleashedRecomp/gpu/imgui/imgui_snapshot.cpp b/UnleashedRecomp/gpu/imgui/imgui_snapshot.cpp index cdb1c714..5d5deff7 100644 --- a/UnleashedRecomp/gpu/imgui/imgui_snapshot.cpp +++ b/UnleashedRecomp/gpu/imgui/imgui_snapshot.cpp @@ -196,7 +196,7 @@ void ImFontAtlasSnapshot::GenerateGlyphRanges() { std::vector localeStrings; - for (auto& config : Config::Definitions) + for (auto& config : g_configDefinitions) config->GetLocaleStrings(localeStrings); std::set glyphs; diff --git a/UnleashedRecomp/gpu/rhi/plume_vulkan.h b/UnleashedRecomp/gpu/rhi/plume_vulkan.h index 0e93536e..b38251e4 100644 --- a/UnleashedRecomp/gpu/rhi/plume_vulkan.h +++ b/UnleashedRecomp/gpu/rhi/plume_vulkan.h @@ -22,9 +22,18 @@ #define VK_USE_PLATFORM_XLIB_KHR #endif -#include "volk.h" +#include -#include "vk_mem_alloc.h" +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" +#endif + +#include + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif namespace plume { struct VulkanCommandQueue; diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 4ea8eee8..2e9ebba2 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -26,12 +26,12 @@ #include #include #include -#include +#include #include #include #if defined(ASYNC_PSO_DEBUG) || defined(PSO_CACHING) -#include +#include #endif #include "../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" @@ -70,11 +70,13 @@ #include "shader/resolve_msaa_depth_4x.hlsl.spirv.h" #include "shader/resolve_msaa_depth_8x.hlsl.spirv.h" +#ifdef _WIN32 extern "C" { __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } +#endif namespace plume { @@ -171,7 +173,7 @@ struct DirtyStates static DirtyStates g_dirtyStates(true); template -static FORCEINLINE void SetDirtyValue(bool& dirtyState, T& dest, const T& src) +static void SetDirtyValue(bool& dirtyState, T& dest, const T& src) { if (dest != src) { @@ -556,7 +558,7 @@ static void DestructTempResources() g_tempBuffers[g_frame].clear(); } -static uint32_t g_mainThreadId; +static std::thread::id g_mainThreadId; static ankerl::unordered_dense::map g_barrierMap; @@ -1039,7 +1041,7 @@ static void ProcSetRenderState(const RenderCommand& cmd) } } -static const std::pair g_setRenderStateFunctions[] = +static const std::pair g_setRenderStateFunctions[] = { { D3DRS_ZENABLE, HostToGuestFunction> }, { D3DRS_ZWRITEENABLE, HostToGuestFunction> }, @@ -1094,11 +1096,13 @@ static std::unique_ptr g_enhancedMotionBlurShader; #endif +#ifdef _WIN32 static bool DetectWine() { HMODULE dllHandle = GetModuleHandle("ntdll.dll"); return dllHandle != nullptr && GetProcAddress(dllHandle, "wine_get_version") != nullptr; } +#endif static constexpr size_t TEXTURE_DESCRIPTOR_SIZE = 65536; static constexpr size_t SAMPLER_DESCRIPTOR_SIZE = 1024; @@ -1161,7 +1165,7 @@ static void CreateImGuiBackend() OptionsMenu::Init(); InstallerWizard::Init(); - ImGui_ImplSDL2_InitForOther(Window::s_pWindow); + ImGui_ImplSDL2_InitForOther(GameWindow::s_pWindow); #ifdef ENABLE_IM_FONT_ATLAS_SNAPSHOT g_imFontTexture = LoadTexture( @@ -1311,7 +1315,7 @@ void Video::CreateHostDevice() IMGUI_CHECKVERSION(); ImGui::CreateContext(); - Window::Init(); + GameWindow::Init(); #ifdef SWA_D3D12 g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan; @@ -1356,7 +1360,7 @@ void Video::CreateHostDevice() break; } - g_swapChain = g_queue->createSwapChain(Window::s_handle, bufferCount, BACKBUFFER_FORMAT); + g_swapChain = g_queue->createSwapChain(GameWindow::s_renderWindow, bufferCount, BACKBUFFER_FORMAT); g_swapChain->setVsyncEnabled(Config::VSync); g_swapChainValid = !g_swapChain->needsResize(); @@ -1366,7 +1370,7 @@ void Video::CreateHostDevice() for (auto& renderSemaphore : g_renderSemaphores) renderSemaphore = g_device->createCommandSemaphore(); - g_mainThreadId = GetCurrentThreadId(); + g_mainThreadId = std::this_thread::get_id(); RenderPipelineLayoutBuilder pipelineLayoutBuilder; pipelineLayoutBuilder.begin(false, true); @@ -1658,9 +1662,9 @@ static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, memset(device, 0, sizeof(*device)); uint32_t functionOffset = 0x443344; // D3D - g_codeCache.Insert(functionOffset, reinterpret_cast(HostToGuestFunction)); + g_codeCache.Insert(functionOffset, HostToGuestFunction); - for (size_t i = 0; i < _countof(device->setRenderStateFunctions); i++) + for (size_t i = 0; i < std::size(device->setRenderStateFunctions); i++) device->setRenderStateFunctions[i] = functionOffset; for (auto& [state, function] : g_setRenderStateFunctions) @@ -1670,7 +1674,7 @@ static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, device->setRenderStateFunctions[state / 4] = functionOffset; } - for (size_t i = 0; i < _countof(device->setSamplerStateFunctions); i++) + for (size_t i = 0; i < std::size(device->setSamplerStateFunctions); i++) device->setSamplerStateFunctions[i] = *reinterpret_cast(g_memory.Translate(0x8330F3DC + i * 0xC)); device->viewport.width = 1280.0f; @@ -1795,7 +1799,7 @@ static void UnlockBuffer(GuestBuffer* buffer) { if (!buffer->lockedReadOnly) { - if (GetCurrentThreadId() == g_mainThreadId) + if (std::this_thread::get_id() == g_mainThreadId) { RenderCommand cmd; cmd.type = (sizeof(T) == 2) ? RenderCommandType::UnlockBuffer16 : RenderCommandType::UnlockBuffer32; diff --git a/UnleashedRecomp/hid/driver/sdl_hid.cpp b/UnleashedRecomp/hid/driver/sdl_hid.cpp index f7c142de..ac140824 100644 --- a/UnleashedRecomp/hid/driver/sdl_hid.cpp +++ b/UnleashedRecomp/hid/driver/sdl_hid.cpp @@ -2,7 +2,8 @@ #include #include #include -#include +#include +#include #define TRANSLATE_INPUT(S, X) SDL_GameControllerGetButton(controller, S) << FirstBitLow(X) #define VIBRATION_TIMEOUT_MS 5000 @@ -65,7 +66,7 @@ public: bool CanPoll() { - return controller && (Window::s_isFocused || Config::AllowBackgroundInput); + return controller && (GameWindow::s_isFocused || Config::AllowBackgroundInput); } void PollAxis() @@ -128,7 +129,7 @@ public: std::array g_controllers; Controller* g_activeController; -inline Controller* EnsureController(DWORD dwUserIndex) +inline Controller* EnsureController(uint32_t dwUserIndex) { if (!g_controllers[dwUserIndex].controller) return nullptr; @@ -260,7 +261,7 @@ void hid::detail::Init() uint32_t hid::detail::GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState) { - static DWORD packet; + static uint32_t packet; if (!pState) return ERROR_BAD_ARGUMENTS; diff --git a/UnleashedRecomp/install/memory_mapped_file.cpp b/UnleashedRecomp/install/memory_mapped_file.cpp index b96ea543..ba3c5d8a 100644 --- a/UnleashedRecomp/install/memory_mapped_file.cpp +++ b/UnleashedRecomp/install/memory_mapped_file.cpp @@ -97,7 +97,7 @@ bool MemoryMappedFile::open(const std::filesystem::path &path) if (fileSize == (off_t)(-1)) { fprintf(stderr, "lseek failed with error %s.\n", strerror(errno)); - close(fileHandle); + ::close(fileHandle); fileHandle = -1; return false; } @@ -106,7 +106,7 @@ bool MemoryMappedFile::open(const std::filesystem::path &path) if (fileView == MAP_FAILED) { fprintf(stderr, "mmap failed with error %s.\n", strerror(errno)); - close(fileHandle); + ::close(fileHandle); fileHandle = -1; return false; } @@ -140,7 +140,7 @@ void MemoryMappedFile::close() if (fileHandle != -1) { - close(fileHandle); + ::close(fileHandle); } #endif } diff --git a/UnleashedRecomp/install/xex_patcher.cpp b/UnleashedRecomp/install/xex_patcher.cpp index 8d2ea1b6..4e35c1cb 100644 --- a/UnleashedRecomp/install/xex_patcher.cpp +++ b/UnleashedRecomp/install/xex_patcher.cpp @@ -308,14 +308,14 @@ inline bool bitScanForward(uint64_t v, uint32_t *outFirstSetIndex) inline bool bitScanForward(uint32_t v, uint32_t *outFirstSetIndex) { int i = ffs(v); - *out_first_set_index = i - 1; + *outFirstSetIndex = i - 1; return i != 0; } inline bool bitScanForward(uint64_t v, uint32_t *outFirstSetIndex) { int i = __builtin_ffsll(v); - *out_first_set_index = i - 1; + *outFirstSetIndex = i - 1; return i != 0; } #endif diff --git a/UnleashedRecomp/kernel/function.h b/UnleashedRecomp/kernel/function.h index 14e88ea7..ecd246bc 100644 --- a/UnleashedRecomp/kernel/function.h +++ b/UnleashedRecomp/kernel/function.h @@ -39,7 +39,7 @@ std::enable_if_t<(I < sizeof...(TArgs)), void> _tuple_for(std::tuple& struct ArgTranslator { - FORCEINLINE constexpr static uint64_t GetIntegerArgumentValue(const PPCContext& ctx, uint8_t* base, size_t arg) noexcept + constexpr static uint64_t GetIntegerArgumentValue(const PPCContext& ctx, uint8_t* base, size_t arg) noexcept { if (arg <= 7) { @@ -57,10 +57,10 @@ struct ArgTranslator } } - return *reinterpret_cast(base + ctx.r1.u32 + 0x54 + ((arg - 8) * 8)); + return *reinterpret_cast*>(base + ctx.r1.u32 + 0x54 + ((arg - 8) * 8)); } - FORCEINLINE static double GetPrecisionArgumentValue(const PPCContext& ctx, uint8_t* base, size_t arg) noexcept + static double GetPrecisionArgumentValue(const PPCContext& ctx, uint8_t* base, size_t arg) noexcept { switch (arg) { @@ -84,7 +84,7 @@ struct ArgTranslator return 0; } - FORCEINLINE constexpr static void SetIntegerArgumentValue(PPCContext& ctx, uint8_t* base, size_t arg, uint64_t value) noexcept + constexpr static void SetIntegerArgumentValue(PPCContext& ctx, uint8_t* base, size_t arg, uint64_t value) noexcept { if (arg <= 7) { @@ -105,7 +105,7 @@ struct ArgTranslator assert(arg < 7 && "Pushing to stack memory is not yet supported."); } - FORCEINLINE static void SetPrecisionArgumentValue(PPCContext& ctx, uint8_t* base, size_t arg, double value) noexcept + static void SetPrecisionArgumentValue(PPCContext& ctx, uint8_t* base, size_t arg, double value) noexcept { switch (arg) { @@ -129,7 +129,7 @@ struct ArgTranslator } template - FORCEINLINE constexpr static std::enable_if_t, T> GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept + constexpr static std::enable_if_t, T> GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept { if constexpr (is_precise_v) { @@ -142,7 +142,7 @@ struct ArgTranslator } template - FORCEINLINE constexpr static std::enable_if_t, T> GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept + constexpr static std::enable_if_t, T> GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept { const auto v = GetIntegerArgumentValue(ctx, base, idx); if (!v) @@ -154,7 +154,7 @@ struct ArgTranslator } template - FORCEINLINE constexpr static std::enable_if_t, void> SetValue(PPCContext& ctx, uint8_t* base, size_t idx, T value) noexcept + constexpr static std::enable_if_t, void> SetValue(PPCContext& ctx, uint8_t* base, size_t idx, T value) noexcept { if constexpr (is_precise_v) { @@ -175,7 +175,7 @@ struct ArgTranslator } template - FORCEINLINE constexpr static std::enable_if_t, void> SetValue(PPCContext& ctx, uint8_t* base, size_t idx, T value) noexcept + constexpr static std::enable_if_t, void> SetValue(PPCContext& ctx, uint8_t* base, size_t idx, T value) noexcept { const auto v = g_memory.MapVirtual((void*)value); if (!v) @@ -240,13 +240,13 @@ struct arg_ordinal_t }; template -FORCEINLINE void _translate_args_to_host(PPCContext& ctx, uint8_t* base, std::tuple&) noexcept +void _translate_args_to_host(PPCContext& ctx, uint8_t* base, std::tuple&) noexcept requires (I >= sizeof...(TArgs)) { } template -FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_host(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept +std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_host(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept { using T = std::tuple_element_t>; std::get(tpl) = ArgTranslator::GetValue(ctx, base, arg_ordinal_t::value); @@ -255,13 +255,13 @@ FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_ho } template -FORCEINLINE void _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple&) noexcept +void _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple&) noexcept requires (I >= sizeof...(TArgs)) { } template -FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept +std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept { using T = std::tuple_element_t>; ArgTranslator::SetValue(ctx, base, GatherFunctionArguments(std::tuple{})[I].ordinal, std::get(tpl)); @@ -270,7 +270,7 @@ FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_gu } template -FORCEINLINE PPC_FUNC(HostToGuestFunction) +PPC_FUNC(HostToGuestFunction) { using ret_t = decltype(std::apply(Func, function_args(Func))); @@ -293,7 +293,7 @@ FORCEINLINE PPC_FUNC(HostToGuestFunction) } else { - ctx.r3.u64 = NULL; + ctx.r3.u64 = 0; } } else if constexpr (is_precise_v) @@ -308,7 +308,7 @@ FORCEINLINE PPC_FUNC(HostToGuestFunction) } template -FORCEINLINE T GuestToHostFunction(const TFunction& func, TArgs&&... argv) +T GuestToHostFunction(const TFunction& func, TArgs&&... argv) { auto args = std::make_tuple(std::forward(argv)...); auto& currentCtx = *GetPPCContext(); @@ -331,11 +331,7 @@ FORCEINLINE T GuestToHostFunction(const TFunction& func, TArgs&&... argv) currentCtx.fpscr = newCtx.fpscr; SetPPCContext(currentCtx); - if constexpr (std::is_void_v) - { - return; - } - else if constexpr (std::is_pointer_v) + if constexpr (std::is_pointer_v) { return reinterpret_cast((uint64_t)g_memory.Translate(newCtx.r3.u32)); } @@ -349,7 +345,7 @@ FORCEINLINE T GuestToHostFunction(const TFunction& func, TArgs&&... argv) } else { - static_assert(false, "Unsupported return type."); + static_assert(std::is_void_v, "Unsupported return type."); } } diff --git a/UnleashedRecomp/kernel/heap.cpp b/UnleashedRecomp/kernel/heap.cpp index efa59a61..56718f25 100644 --- a/UnleashedRecomp/kernel/heap.cpp +++ b/UnleashedRecomp/kernel/heap.cpp @@ -103,7 +103,7 @@ uint32_t RtlSizeHeap(uint32_t heapHandle, uint32_t flags, uint32_t memoryPointer return 0; } -SWA_API uint32_t XAlloc(uint32_t size, uint32_t flags) +SWA_API uint32_t XAllocMem(uint32_t size, uint32_t flags) { void* ptr = (flags & 0x80000000) != 0 ? g_userHeap.AllocPhysical(size, (1ull << ((flags >> 24) & 0xF))) : @@ -116,7 +116,7 @@ SWA_API uint32_t XAlloc(uint32_t size, uint32_t flags) return g_memory.MapVirtual(ptr); } -SWA_API void XFree(uint32_t baseAddress, uint32_t flags) +SWA_API void XFreeMem(uint32_t baseAddress, uint32_t flags) { if (baseAddress != NULL) g_userHeap.Free(g_memory.Translate(baseAddress)); @@ -130,6 +130,5 @@ GUEST_FUNCTION_HOOK(sub_82BD8600, RtlFreeHeap); GUEST_FUNCTION_HOOK(sub_82BD88F0, RtlReAllocateHeap); GUEST_FUNCTION_HOOK(sub_82BD6FD0, RtlSizeHeap); -// Seems like these handle allocation of virtual and physical pages -GUEST_FUNCTION_HOOK(sub_831CC9C8, XAlloc); -GUEST_FUNCTION_HOOK(sub_831CCA60, XFree); +GUEST_FUNCTION_HOOK(sub_831CC9C8, XAllocMem); +GUEST_FUNCTION_HOOK(sub_831CCA60, XFreeMem); diff --git a/UnleashedRecomp/kernel/imports.cpp b/UnleashedRecomp/kernel/imports.cpp index 6067f800..552bdc3d 100644 --- a/UnleashedRecomp/kernel/imports.cpp +++ b/UnleashedRecomp/kernel/imports.cpp @@ -10,11 +10,12 @@ #include #include "xam.h" #include "xdm.h" -#include #include #include +#ifdef _WIN32 #include +#endif struct Event final : KernelObject, HostObject { @@ -149,7 +150,7 @@ inline void CloseKernelObject(XDISPATCHER_HEADER& header) DestroyKernelObject(header.WaitListHead.Blink); } -DWORD GuestTimeoutToMilliseconds(XLPQWORD timeout) +uint32_t GuestTimeoutToMilliseconds(be* timeout) { return timeout ? (*timeout * -1) / 10000 : INFINITE; } @@ -207,7 +208,7 @@ uint32_t XGetGameRegion() return 0x03FF; } -uint32_t XMsgStartIORequest(DWORD App, DWORD Message, XXOVERLAPPED* lpOverlapped, void* Buffer, DWORD szBuffer) +uint32_t XMsgStartIORequest(uint32_t App, uint32_t Message, XXOVERLAPPED* lpOverlapped, void* Buffer, uint32_t szBuffer) { return STATUS_SUCCESS; } @@ -227,8 +228,7 @@ void XamContentDelete() LOG_UTILITY("!!! STUB !!!"); } - -uint32_t XamContentGetCreator(DWORD userIndex, const XCONTENT_DATA* contentData, PBOOL isCreator, XLPQWORD xuid, XXOVERLAPPED* overlapped) +uint32_t XamContentGetCreator(uint32_t userIndex, const XCONTENT_DATA* contentData, be* isCreator, be* xuid, XXOVERLAPPED* overlapped) { if (isCreator) *isCreator = true; @@ -269,7 +269,7 @@ uint32_t XamShowDeviceSelectorUI uint32_t contentType, uint32_t contentFlags, uint64_t totalRequested, - XDWORD* deviceId, + be* deviceId, XXOVERLAPPED* overlapped ) { @@ -337,10 +337,10 @@ void RtlInitAnsiString(XANSI_STRING* destination, char* source) destination->Buffer = source; } -DWORD NtCreateFile +uint32_t NtCreateFile ( - XLPDWORD FileHandle, - DWORD DesiredAccess, + be* FileHandle, + uint32_t DesiredAccess, XOBJECT_ATTRIBUTES* Attributes, XIO_STATUS_BLOCK* IoStatusBlock, uint64_t* AllocationSize, @@ -363,8 +363,11 @@ uint32_t NtClose(uint32_t handle) DestroyKernelObject(handle); return 0; } - - return CloseHandle((HANDLE)handle) ? 0 : 0xFFFFFFFF; + else + { + assert(false && "Unrecognized kernel object."); + return 0xFFFFFFFF; + } } void NtSetInformationFile() @@ -377,7 +380,7 @@ uint32_t FscSetCacheElementCount() return 0; } -DWORD NtWaitForSingleObjectEx(DWORD Handle, DWORD WaitMode, DWORD Alertable, XLPQWORD Timeout) +uint32_t NtWaitForSingleObjectEx(uint32_t Handle, uint32_t WaitMode, uint32_t Alertable, be* Timeout) { uint32_t timeout = GuestTimeoutToMilliseconds(Timeout); assert(timeout == 0 || timeout == INFINITE); @@ -404,7 +407,7 @@ void vsprintf_x() LOG_UTILITY("!!! STUB !!!"); } -uint32_t ExGetXConfigSetting(uint16_t Category, uint16_t Setting, void* Buffer, uint16_t SizeOfBuffer, XLPDWORD RequiredSize) +uint32_t ExGetXConfigSetting(uint16_t Category, uint16_t Setting, void* Buffer, uint16_t SizeOfBuffer, be* RequiredSize) { uint32_t data[4]{}; @@ -517,9 +520,9 @@ void XexGetModuleSection() LOG_UTILITY("!!! STUB !!!"); } -NTSTATUS RtlUnicodeToMultiByteN(PCHAR MultiByteString, DWORD MaxBytesInMultiByteString, XLPDWORD BytesInMultiByteString, PCWCH UnicodeString, ULONG BytesInUnicodeString) +uint32_t RtlUnicodeToMultiByteN(char* MultiByteString, uint32_t MaxBytesInMultiByteString, be* BytesInMultiByteString, const be* UnicodeString, uint32_t BytesInUnicodeString) { - const auto reqSize = BytesInUnicodeString / sizeof(wchar_t); + const auto reqSize = BytesInUnicodeString / sizeof(uint16_t); if (BytesInMultiByteString) *BytesInMultiByteString = reqSize; @@ -529,7 +532,7 @@ NTSTATUS RtlUnicodeToMultiByteN(PCHAR MultiByteString, DWORD MaxBytesInMultiByte for (size_t i = 0; i < reqSize; i++) { - const auto c = ByteSwap(UnicodeString[i]); + const auto c = UnicodeString[i].get(); MultiByteString[i] = c < 256 ? c : '?'; } @@ -537,7 +540,7 @@ NTSTATUS RtlUnicodeToMultiByteN(PCHAR MultiByteString, DWORD MaxBytesInMultiByte return STATUS_SUCCESS; } -DWORD KeDelayExecutionThread(DWORD WaitMode, bool Alertable, XLPQWORD Timeout) +uint32_t KeDelayExecutionThread(uint32_t WaitMode, bool Alertable, be* Timeout) { // We don't do async file reads. if (Alertable) @@ -614,7 +617,7 @@ void KeSetBasePriorityThread(GuestThreadHandle* hThread, int priority) #endif } -uint32_t ObReferenceObjectByHandle(uint32_t handle, uint32_t objectType, XLPDWORD object) +uint32_t ObReferenceObjectByHandle(uint32_t handle, uint32_t objectType, be* object) { *object = handle; return 0; @@ -635,7 +638,7 @@ uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount) return S_OK; } -uint32_t KeSetAffinityThread(DWORD Thread, DWORD Affinity, XLPDWORD lpPreviousAffinity) +uint32_t KeSetAffinityThread(uint32_t Thread, uint32_t Affinity, be* lpPreviousAffinity) { if (lpPreviousAffinity) *lpPreviousAffinity = 2; @@ -693,7 +696,7 @@ void RtlFillMemoryUlong() void KeBugCheckEx() { - __debugbreak(); + __builtin_debugtrap(); } uint32_t KeGetCurrentProcessType() @@ -949,7 +952,7 @@ void VdEnableDisableClockGating() void KeBugCheck() { - __debugbreak(); + __builtin_debugtrap(); } void KeLockL2() @@ -962,7 +965,7 @@ void KeUnlockL2() LOG_UTILITY("!!! STUB !!!"); } -bool KeSetEvent(XKEVENT* pEvent, DWORD Increment, bool Wait) +bool KeSetEvent(XKEVENT* pEvent, uint32_t Increment, bool Wait) { bool result = QueryKernelObject(*pEvent)->Set(); @@ -977,7 +980,7 @@ bool KeResetEvent(XKEVENT* pEvent) return QueryKernelObject(*pEvent)->Reset(); } -DWORD KeWaitForSingleObject(XDISPATCHER_HEADER* Object, DWORD WaitReason, DWORD WaitMode, bool Alertable, XLPQWORD Timeout) +uint32_t KeWaitForSingleObject(XDISPATCHER_HEADER* Object, uint32_t WaitReason, uint32_t WaitMode, bool Alertable, be* Timeout) { const uint32_t timeout = GuestTimeoutToMilliseconds(Timeout); assert(timeout == INFINITE); @@ -1019,18 +1022,18 @@ static uint32_t& KeTlsGetValueRef(size_t index) return s_tlsValues[index]; } -uint32_t KeTlsGetValue(DWORD dwTlsIndex) +uint32_t KeTlsGetValue(uint32_t dwTlsIndex) { return KeTlsGetValueRef(dwTlsIndex); } -BOOL KeTlsSetValue(DWORD dwTlsIndex, DWORD lpTlsValue) +uint32_t KeTlsSetValue(uint32_t dwTlsIndex, uint32_t lpTlsValue) { KeTlsGetValueRef(dwTlsIndex) = lpTlsValue; return TRUE; } -DWORD KeTlsAlloc() +uint32_t KeTlsAlloc() { std::lock_guard lock(g_tlsAllocationMutex); if (!g_tlsFreeIndices.empty()) @@ -1043,14 +1046,14 @@ DWORD KeTlsAlloc() return g_tlsNextIndex++; } -BOOL KeTlsFree(DWORD dwTlsIndex) +uint32_t KeTlsFree(uint32_t dwTlsIndex) { std::lock_guard lock(g_tlsAllocationMutex); g_tlsFreeIndices.push_back(dwTlsIndex); return TRUE; } -DWORD XMsgInProcessCall(uint32_t app, uint32_t message, XDWORD* param1, XDWORD* param2) +uint32_t XMsgInProcessCall(uint32_t app, uint32_t message, be* param1, be* param2) { if (message == 0x7001B) { @@ -1070,7 +1073,7 @@ void XamUserReadProfileSettings uint64_t* xuids, uint32_t settingCount, uint32_t* settingIds, - XDWORD* bufferSize, + be* bufferSize, void* buffer, void* overlapped ) @@ -1251,19 +1254,15 @@ void NtQueryFullAttributesFile() LOG_UTILITY("!!! STUB !!!"); } -NTSTATUS RtlMultiByteToUnicodeN(PWCH UnicodeString, ULONG MaxBytesInUnicodeString, XLPDWORD BytesInUnicodeString, const CHAR* MultiByteString, ULONG BytesInMultiByteString) +uint32_t RtlMultiByteToUnicodeN(be* UnicodeString, uint32_t MaxBytesInUnicodeString, be* BytesInUnicodeString, const char* MultiByteString, uint32_t BytesInMultiByteString) { - // i am lazy - const auto n = MultiByteToWideChar(CP_UTF8, 0, MultiByteString, BytesInMultiByteString, UnicodeString, MaxBytesInUnicodeString); + uint32_t length = std::min(MaxBytesInUnicodeString / 2, BytesInMultiByteString); - if (BytesInUnicodeString) - *BytesInUnicodeString = n * sizeof(wchar_t); + for (size_t i = 0; i < length; i++) + UnicodeString[i] = MultiByteString[i]; - if (n) - { - for (size_t i = 0; i < n; i++) - UnicodeString[i] = ByteSwap(UnicodeString[i]); - } + if (BytesInUnicodeString != nullptr) + *BytesInUnicodeString = length * 2; return STATUS_SUCCESS; } @@ -1300,13 +1299,13 @@ uint32_t NtSetEvent(Event* handle, uint32_t* previousState) return 0; } -NTSTATUS NtCreateSemaphore(XLPDWORD Handle, XOBJECT_ATTRIBUTES* ObjectAttributes, DWORD InitialCount, DWORD MaximumCount) +uint32_t NtCreateSemaphore(be* Handle, XOBJECT_ATTRIBUTES* ObjectAttributes, uint32_t InitialCount, uint32_t MaximumCount) { *Handle = GetKernelHandle(CreateKernelObject(InitialCount, MaximumCount)); return STATUS_SUCCESS; } -NTSTATUS NtReleaseSemaphore(Semaphore* Handle, DWORD ReleaseCount, LONG* PreviousCount) +uint32_t NtReleaseSemaphore(Semaphore* Handle, uint32_t ReleaseCount, int32_t* PreviousCount) { uint32_t previousCount; Handle->Release(ReleaseCount, &previousCount); @@ -1347,11 +1346,17 @@ void NtFlushBuffersFile() LOG_UTILITY("!!! STUB !!!"); } -void KeQuerySystemTime(uint64_t* time) +void KeQuerySystemTime(be* time) { - FILETIME t; - GetSystemTimeAsFileTime(&t); - *time = ByteSwap((uint64_t(t.dwHighDateTime) << 32) | t.dwLowDateTime); + constexpr int64_t FILETIME_EPOCH_DIFFERENCE = 116444736000000000LL; + + auto now = std::chrono::system_clock::now(); + auto timeSinceEpoch = now.time_since_epoch(); + + int64_t currentTime100ns = std::chrono::duration_cast>>(timeSinceEpoch).count(); + currentTime100ns += FILETIME_EPOCH_DIFFERENCE; + + *time = ((currentTime100ns & 0xFFFFFFFF) << 32) | (currentTime100ns & 0xFFFFFFFF); } void RtlTimeToTimeFields() @@ -1379,7 +1384,7 @@ void ExTerminateThread() LOG_UTILITY("!!! STUB !!!"); } -uint32_t ExCreateThread(XLPDWORD handle, uint32_t stackSize, XLPDWORD threadId, uint32_t xApiThreadStartup, uint32_t startAddress, uint32_t startContext, uint32_t creationFlags) +uint32_t ExCreateThread(be* handle, uint32_t stackSize, be* threadId, uint32_t xApiThreadStartup, uint32_t startAddress, uint32_t startContext, uint32_t creationFlags) { LOGF_UTILITY("0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}", (intptr_t)handle, stackSize, (intptr_t)threadId, xApiThreadStartup, startAddress, startContext, creationFlags); @@ -1464,7 +1469,7 @@ void NetDll_XNetGetTitleXnAddr() LOG_UTILITY("!!! STUB !!!"); } -DWORD KeWaitForMultipleObjects(DWORD Count, xpointer* Objects, DWORD WaitType, DWORD WaitReason, DWORD WaitMode, DWORD Alertable, XLPQWORD Timeout) +uint32_t KeWaitForMultipleObjects(uint32_t Count, xpointer* Objects, uint32_t WaitType, uint32_t WaitReason, uint32_t WaitMode, uint32_t Alertable, be* Timeout) { // FIXME: This function is only accounting for events. @@ -1492,7 +1497,7 @@ DWORD KeWaitForMultipleObjects(DWORD Count, xpointer* Object { if (s_events[i]->Wait(0) == STATUS_SUCCESS) { - return WAIT_OBJECT_0 + i; + return STATUS_WAIT_0 + i; } } @@ -1522,7 +1527,7 @@ void XAudioGetVoiceCategoryVolume() LOG_UTILITY("!!! STUB !!!"); } -DWORD XAudioGetVoiceCategoryVolumeChangeMask(DWORD Driver, XLPDWORD Mask) +uint32_t XAudioGetVoiceCategoryVolumeChangeMask(uint32_t Driver, be* Mask) { *Mask = 0; return 0; @@ -1556,7 +1561,7 @@ void XMACreateContext() LOG_UTILITY("!!! STUB !!!"); } -// uint32_t XAudioRegisterRenderDriverClient(XLPDWORD callback, XLPDWORD driver) +// uint32_t XAudioRegisterRenderDriverClient(be* callback, be* driver) // { // //printf("XAudioRegisterRenderDriverClient(): %x %x\n"); // diff --git a/UnleashedRecomp/kernel/io/file_system.cpp b/UnleashedRecomp/kernel/io/file_system.cpp index 4bd3b1d7..71d7f2dd 100644 --- a/UnleashedRecomp/kernel/io/file_system.cpp +++ b/UnleashedRecomp/kernel/io/file_system.cpp @@ -14,10 +14,11 @@ struct FileHandle : KernelObject struct FindHandle : KernelObject { + std::error_code ec; std::filesystem::path searchPath; std::filesystem::directory_iterator iterator; - void fillFindData(LPWIN32_FIND_DATAA lpFindFileData) + void fillFindData(WIN32_FIND_DATAA* lpFindFileData) { if (iterator->is_directory()) lpFindFileData->dwFileAttributes = ByteSwap(FILE_ATTRIBUTE_DIRECTORY); @@ -25,7 +26,7 @@ struct FindHandle : KernelObject lpFindFileData->dwFileAttributes = ByteSwap(FILE_ATTRIBUTE_NORMAL); std::u8string pathU8Str = iterator->path().lexically_relative(searchPath).u8string(); - uint64_t fileSize = iterator->file_size(); + uint64_t fileSize = iterator->file_size(ec); strncpy(lpFindFileData->cFileName, (const char *)(pathU8Str.c_str()), sizeof(lpFindFileData->cFileName)); lpFindFileData->nFileSizeLow = ByteSwap(uint32_t(fileSize >> 32U)); lpFindFileData->nFileSizeHigh = ByteSwap(uint32_t(fileSize)); @@ -37,12 +38,12 @@ struct FindHandle : KernelObject SWA_API FileHandle* XCreateFileA ( - LPCSTR lpFileName, - DWORD dwDesiredAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes + const char* lpFileName, + uint32_t dwDesiredAccess, + uint32_t dwShareMode, + void* lpSecurityAttributes, + uint32_t dwCreationDisposition, + uint32_t dwFlagsAndAttributes ) { assert(((dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE | FILE_READ_DATA)) == 0) && "Unknown desired access bits."); @@ -77,7 +78,7 @@ SWA_API FileHandle* XCreateFileA return fileHandle; } -static DWORD XGetFileSizeA(FileHandle* hFile, LPDWORD lpFileSizeHigh) +static uint32_t XGetFileSizeA(FileHandle* hFile, be* lpFileSizeHigh) { std::error_code ec; auto fileSize = std::filesystem::file_size(hFile->path, ec); @@ -85,16 +86,16 @@ static DWORD XGetFileSizeA(FileHandle* hFile, LPDWORD lpFileSizeHigh) { if (lpFileSizeHigh != nullptr) { - *lpFileSizeHigh = ByteSwap(DWORD(fileSize >> 32U)); + *lpFileSizeHigh = uint32_t(fileSize >> 32U); } - return (DWORD)(fileSize); + return (uint32_t)(fileSize); } return INVALID_FILE_SIZE; } -BOOL XGetFileSizeExA(FileHandle* hFile, PLARGE_INTEGER lpFileSize) +uint32_t XGetFileSizeExA(FileHandle* hFile, LARGE_INTEGER* lpFileSize) { std::error_code ec; auto fileSize = std::filesystem::file_size(hFile->path, ec); @@ -111,16 +112,16 @@ BOOL XGetFileSizeExA(FileHandle* hFile, PLARGE_INTEGER lpFileSize) return FALSE; } -BOOL XReadFile +uint32_t XReadFile ( FileHandle* hFile, - LPVOID lpBuffer, - DWORD nNumberOfBytesToRead, - XLPDWORD lpNumberOfBytesRead, + void* lpBuffer, + uint32_t nNumberOfBytesToRead, + be* lpNumberOfBytesRead, XOVERLAPPED* lpOverlapped ) { - BOOL result = FALSE; + uint32_t result = FALSE; if (lpOverlapped != nullptr) { std::streamoff streamOffset = lpOverlapped->Offset + (std::streamoff(lpOverlapped->OffsetHigh.get()) << 32U); @@ -132,11 +133,11 @@ BOOL XReadFile } } - DWORD numberOfBytesRead; + uint32_t numberOfBytesRead; hFile->stream.read((char *)(lpBuffer), nNumberOfBytesToRead); if (!hFile->stream.bad()) { - numberOfBytesRead = DWORD(hFile->stream.gcount()); + numberOfBytesRead = uint32_t(hFile->stream.gcount()); result = TRUE; } @@ -146,9 +147,6 @@ BOOL XReadFile { lpOverlapped->Internal = 0; lpOverlapped->InternalHigh = numberOfBytesRead; - - if (lpOverlapped->hEvent != NULL) - SetEvent((HANDLE)lpOverlapped->hEvent.get()); } else if (lpNumberOfBytesRead != nullptr) { @@ -159,9 +157,9 @@ BOOL XReadFile return result; } -DWORD XSetFilePointer(FileHandle* hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) +uint32_t XSetFilePointer(FileHandle* hFile, int32_t lDistanceToMove, be* lpDistanceToMoveHigh, uint32_t dwMoveMethod) { - LONG distanceToMoveHigh = lpDistanceToMoveHigh ? ByteSwap(*lpDistanceToMoveHigh) : 0; + int32_t distanceToMoveHigh = lpDistanceToMoveHigh ? lpDistanceToMoveHigh->get() : 0; std::streamoff streamOffset = lDistanceToMove + (std::streamoff(distanceToMoveHigh) << 32U); std::fstream::seekdir streamSeekDir = {}; switch (dwMoveMethod) @@ -189,12 +187,12 @@ DWORD XSetFilePointer(FileHandle* hFile, LONG lDistanceToMove, PLONG lpDistanceT std::streampos streamPos = hFile->stream.tellg(); if (lpDistanceToMoveHigh != nullptr) - *lpDistanceToMoveHigh = ByteSwap(LONG(streamPos >> 32U)); + *lpDistanceToMoveHigh = int32_t(streamPos >> 32U); - return DWORD(streamPos); + return uint32_t(streamPos); } -BOOL XSetFilePointerEx(FileHandle* hFile, LONG lDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod) +uint32_t XSetFilePointerEx(FileHandle* hFile, int32_t lDistanceToMove, LARGE_INTEGER* lpNewFilePointer, uint32_t dwMoveMethod) { std::fstream::seekdir streamSeekDir = {}; switch (dwMoveMethod) @@ -222,13 +220,13 @@ BOOL XSetFilePointerEx(FileHandle* hFile, LONG lDistanceToMove, PLARGE_INTEGER l if (lpNewFilePointer != nullptr) { - lpNewFilePointer->QuadPart = ByteSwap(LONGLONG(hFile->stream.tellg())); + lpNewFilePointer->QuadPart = ByteSwap(int64_t(hFile->stream.tellg())); } return TRUE; } -FindHandle* XFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) +FindHandle* XFindFirstFileA(const char* lpFileName, WIN32_FIND_DATAA* lpFindFileData) { const char *transformedPath = FileSystem::TransformPath(lpFileName); size_t transformedPathLength = strlen(transformedPath); @@ -236,11 +234,11 @@ FindHandle* XFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData return (FindHandle*)GUEST_INVALID_HANDLE_VALUE; std::filesystem::path dirPath; - if (strstr(transformedPath, "\\*") == (&transformedPath[transformedPathLength - 2])) + if (strstr(transformedPath, "\\*") == (&transformedPath[transformedPathLength - 2]) || strstr(transformedPath, "/*") == (&transformedPath[transformedPathLength - 2])) { dirPath = std::u8string_view((const char8_t*)(transformedPath), transformedPathLength - 2); } - else if (strstr(transformedPath, "\\*.*") == (&transformedPath[transformedPathLength - 4])) + else if (strstr(transformedPath, "\\*.*") == (&transformedPath[transformedPathLength - 4]) || strstr(transformedPath, "/*.*") == (&transformedPath[transformedPathLength - 4])) { dirPath = std::u8string_view((const char8_t *)(transformedPath), transformedPathLength - 4); } @@ -264,7 +262,7 @@ FindHandle* XFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData return findHandle; } -BOOL XFindNextFileA(FindHandle* Handle, LPWIN32_FIND_DATAA lpFindFileData) +uint32_t XFindNextFileA(FindHandle* Handle, WIN32_FIND_DATAA* lpFindFileData) { Handle->iterator++; @@ -279,10 +277,10 @@ BOOL XFindNextFileA(FindHandle* Handle, LPWIN32_FIND_DATAA lpFindFileData) } } -BOOL XReadFileEx(FileHandle* hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, XOVERLAPPED* lpOverlapped, uint32_t lpCompletionRoutine) +uint32_t XReadFileEx(FileHandle* hFile, void* lpBuffer, uint32_t nNumberOfBytesToRead, XOVERLAPPED* lpOverlapped, uint32_t lpCompletionRoutine) { - BOOL result = FALSE; - DWORD numberOfBytesRead; + uint32_t result = FALSE; + uint32_t numberOfBytesRead; std::streamoff streamOffset = lpOverlapped->Offset + (std::streamoff(lpOverlapped->OffsetHigh.get()) << 32U); hFile->stream.clear(); hFile->stream.seekg(streamOffset, std::ios::beg); @@ -292,7 +290,7 @@ BOOL XReadFileEx(FileHandle* hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, hFile->stream.read((char *)(lpBuffer), nNumberOfBytesToRead); if (!hFile->stream.bad()) { - numberOfBytesRead = DWORD(hFile->stream.gcount()); + numberOfBytesRead = uint32_t(hFile->stream.gcount()); result = TRUE; } @@ -300,15 +298,12 @@ BOOL XReadFileEx(FileHandle* hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, { lpOverlapped->Internal = 0; lpOverlapped->InternalHigh = numberOfBytesRead; - - if (lpOverlapped->hEvent != NULL) - SetEvent((HANDLE)lpOverlapped->hEvent.get()); } return result; } -DWORD XGetFileAttributesA(LPCSTR lpFileName) +uint32_t XGetFileAttributesA(const char* lpFileName) { std::filesystem::path filePath(std::u8string_view((const char8_t*)(FileSystem::TransformPath(lpFileName)))); if (std::filesystem::is_directory(filePath)) @@ -319,7 +314,7 @@ DWORD XGetFileAttributesA(LPCSTR lpFileName) return INVALID_FILE_ATTRIBUTES; } -BOOL XWriteFile(FileHandle* hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) +uint32_t XWriteFile(FileHandle* hFile, const void* lpBuffer, uint32_t nNumberOfBytesToWrite, be* lpNumberOfBytesWritten, void* lpOverlapped) { assert(lpOverlapped == nullptr && "Overlapped not implemented."); @@ -328,16 +323,28 @@ BOOL XWriteFile(FileHandle* hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite return FALSE; if (lpNumberOfBytesWritten != nullptr) - *lpNumberOfBytesWritten = DWORD(hFile->stream.gcount()); + *lpNumberOfBytesWritten = uint32_t(hFile->stream.gcount()); return TRUE; } +static void fixSlashes(char *path) +{ + while (*path != 0) + { + if (*path == '\\') + { + *path = '/'; + } + + path++; + } +} + const char* FileSystem::TransformPath(const char* path) { thread_local char builtPath[2048]{}; const char* relativePath = strstr(path, ":\\"); - if (relativePath != nullptr) { // rooted folder, handle direction @@ -349,12 +356,19 @@ const char* FileSystem::TransformPath(const char* path) strncpy(builtPath, newRoot.data(), newRoot.size()); builtPath[newRoot.size()] = '\\'; strcpy(builtPath + newRoot.size() + 1, relativePath + 2); - - return builtPath; + } + else + { + strncpy(builtPath, relativePath + 2, sizeof(builtPath)); } } + else + { + strncpy(builtPath, path, sizeof(builtPath)); + } - return relativePath != nullptr ? relativePath + 2 : path; + fixSlashes(builtPath); + return builtPath; } SWA_API const char* XExpandFilePathA(const char* path) diff --git a/UnleashedRecomp/kernel/memory.cpp b/UnleashedRecomp/kernel/memory.cpp index 85b11710..76f99256 100644 --- a/UnleashedRecomp/kernel/memory.cpp +++ b/UnleashedRecomp/kernel/memory.cpp @@ -13,6 +13,8 @@ Memory::Memory(void* address, size_t size) : size(size) if (base == (char*)MAP_FAILED) base = (char*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + + mprotect(base, 4096, PROT_NONE); #endif } diff --git a/UnleashedRecomp/kernel/memory.h b/UnleashedRecomp/kernel/memory.h index 0a1eba22..98349a44 100644 --- a/UnleashedRecomp/kernel/memory.h +++ b/UnleashedRecomp/kernel/memory.h @@ -1,5 +1,10 @@ #pragma once +#ifndef _WIN32 +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#endif + class Memory { public: diff --git a/UnleashedRecomp/kernel/xam.cpp b/UnleashedRecomp/kernel/xam.cpp index 5cc0ce4b..23b53e50 100644 --- a/UnleashedRecomp/kernel/xam.cpp +++ b/UnleashedRecomp/kernel/xam.cpp @@ -2,23 +2,25 @@ #include "xam.h" #include "xdm.h" #include -#include +#include #include #include #include -#include #include "xxHashMap.h" #include #include +#ifdef _WIN32 +#include // Needed for commctrl #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif struct XamListener : KernelObject { uint32_t id{}; uint64_t areas{}; - std::vector> notifications; + std::vector> notifications; XamListener(const XamListener&) = delete; XamListener& operator=(const XamListener&) = delete; @@ -116,7 +118,7 @@ XamListener::~XamListener() gListeners.erase(this); } -XCONTENT_DATA XamMakeContent(DWORD type, const std::string_view& name) +XCONTENT_DATA XamMakeContent(uint32_t type, const std::string_view& name) { XCONTENT_DATA data{ 1, type }; @@ -132,7 +134,7 @@ void XamRegisterContent(const XCONTENT_DATA& data, const std::string_view& root) gContentRegistry[idx].emplace(StringHash(data.szFileName), XHOSTCONTENT_DATA{ data }).first->second.szRoot = root; } -void XamRegisterContent(DWORD type, const std::string_view name, const std::string_view& root) +void XamRegisterContent(uint32_t type, const std::string_view name, const std::string_view& root) { XCONTENT_DATA data{ 1, type, {}, "" }; @@ -141,7 +143,7 @@ void XamRegisterContent(DWORD type, const std::string_view name, const std::stri XamRegisterContent(data, root); } -SWA_API DWORD XamNotifyCreateListener(uint64_t qwAreas) +SWA_API uint32_t XamNotifyCreateListener(uint64_t qwAreas) { auto* listener = CreateKernelObject(); @@ -150,7 +152,7 @@ SWA_API DWORD XamNotifyCreateListener(uint64_t qwAreas) return GetKernelHandle(listener); } -SWA_API void XamNotifyEnqueueEvent(DWORD dwId, DWORD dwParam) +SWA_API void XamNotifyEnqueueEvent(uint32_t dwId, uint32_t dwParam) { for (const auto& listener : gListeners) { @@ -161,7 +163,7 @@ SWA_API void XamNotifyEnqueueEvent(DWORD dwId, DWORD dwParam) } } -SWA_API bool XNotifyGetNext(DWORD hNotification, DWORD dwMsgFilter, XDWORD* pdwId, XDWORD* pParam) +SWA_API bool XNotifyGetNext(uint32_t hNotification, uint32_t dwMsgFilter, be* pdwId, be* pParam) { auto& listener = *GetKernelObject(hNotification); @@ -202,9 +204,12 @@ SWA_API bool XNotifyGetNext(DWORD hNotification, DWORD dwMsgFilter, XDWORD* pdwI return false; } -SWA_API uint32_t XamShowMessageBoxUI(DWORD dwUserIndex, XWORD* wszTitle, XWORD* wszText, DWORD cButtons, - xpointer* pwszButtons, DWORD dwFocusButton, DWORD dwFlags, XLPDWORD pResult, XXOVERLAPPED* pOverlapped) +SWA_API uint32_t XamShowMessageBoxUI(uint32_t dwUserIndex, be* wszTitle, be* wszText, uint32_t cButtons, + xpointer>* pwszButtons, uint32_t dwFocusButton, uint32_t dwFlags, be* pResult, XXOVERLAPPED* pOverlapped) { + int button{}; + +#ifdef _WIN32 std::vector texts{}; std::vector buttons{}; @@ -227,20 +232,19 @@ SWA_API uint32_t XamShowMessageBoxUI(DWORD dwUserIndex, XWORD* wszTitle, XWORD* TASKDIALOGCONFIG config{}; config.cbSize = sizeof(config); - // config.hwndParent = Window::s_hWnd; config.pszWindowTitle = texts[0].c_str(); config.pszContent = texts[1].c_str(); config.cButtons = cButtons; config.pButtons = buttons.data(); - int button{}; TaskDialogIndirect(&config, &button, nullptr, nullptr); +#endif *pResult = button; if (pOverlapped) { - pOverlapped->dwCompletionContext = GetCurrentThreadId(); + pOverlapped->dwCompletionContext = GuestThread::GetCurrentThreadId(); pOverlapped->Error = 0; pOverlapped->Length = -1; } @@ -250,8 +254,8 @@ SWA_API uint32_t XamShowMessageBoxUI(DWORD dwUserIndex, XWORD* wszTitle, XWORD* return 0; } -SWA_API uint32_t XamContentCreateEnumerator(DWORD dwUserIndex, DWORD DeviceID, DWORD dwContentType, - DWORD dwContentFlags, DWORD cItem, XLPDWORD pcbBuffer, XLPDWORD phEnum) +SWA_API uint32_t XamContentCreateEnumerator(uint32_t dwUserIndex, uint32_t DeviceID, uint32_t dwContentType, + uint32_t dwContentFlags, uint32_t cItem, be* pcbBuffer, be* phEnum) { if (dwUserIndex != 0) { @@ -271,7 +275,7 @@ SWA_API uint32_t XamContentCreateEnumerator(DWORD dwUserIndex, DWORD DeviceID, D return 0; } -SWA_API uint32_t XamEnumerate(uint32_t hEnum, DWORD dwFlags, PVOID pvBuffer, DWORD cbBuffer, XLPDWORD pcItemsReturned, XXOVERLAPPED* pOverlapped) +SWA_API uint32_t XamEnumerate(uint32_t hEnum, uint32_t dwFlags, void* pvBuffer, uint32_t cbBuffer, be* pcItemsReturned, XXOVERLAPPED* pOverlapped) { auto* enumerator = GetKernelObject(hEnum); const auto count = enumerator->Next(pvBuffer); @@ -285,9 +289,9 @@ SWA_API uint32_t XamEnumerate(uint32_t hEnum, DWORD dwFlags, PVOID pvBuffer, DWO return ERROR_SUCCESS; } -SWA_API uint32_t XamContentCreateEx(DWORD dwUserIndex, LPCSTR szRootName, const XCONTENT_DATA* pContentData, - DWORD dwContentFlags, XLPDWORD pdwDisposition, XLPDWORD pdwLicenseMask, - DWORD dwFileCacheSize, uint64_t uliContentSize, PXXOVERLAPPED pOverlapped) +SWA_API uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const XCONTENT_DATA* pContentData, + uint32_t dwContentFlags, be* pdwDisposition, be* pdwLicenseMask, + uint32_t dwFileCacheSize, uint64_t uliContentSize, PXXOVERLAPPED pOverlapped) { const auto& registry = gContentRegistry[pContentData->dwContentType - 1]; const auto exists = registry.contains(StringHash(pContentData->szFileName)); @@ -309,7 +313,7 @@ SWA_API uint32_t XamContentCreateEx(DWORD dwUserIndex, LPCSTR szRootName, const } else if (pContentData->dwContentType == XCONTENTTYPE_DLC) { - root = ".\\dlc"; + root = "./dlc"; } else { @@ -354,13 +358,13 @@ SWA_API uint32_t XamContentCreateEx(DWORD dwUserIndex, LPCSTR szRootName, const return ERROR_PATH_NOT_FOUND; } -SWA_API uint32_t XamContentClose(LPCSTR szRootName, XXOVERLAPPED* pOverlapped) +SWA_API uint32_t XamContentClose(const char* szRootName, XXOVERLAPPED* pOverlapped) { gRootMap.erase(StringHash(szRootName)); return 0; } -SWA_API uint32_t XamContentGetDeviceData(DWORD DeviceID, XDEVICE_DATA* pDeviceData) +SWA_API uint32_t XamContentGetDeviceData(uint32_t DeviceID, XDEVICE_DATA* pDeviceData) { pDeviceData->DeviceID = DeviceID; pDeviceData->DeviceType = XCONTENTDEVICETYPE_HDD; @@ -401,7 +405,7 @@ SWA_API uint32_t XamInputGetState(uint32_t userIndex, uint32_t flags, XAMINPUT_S uint32_t result = hid::GetState(userIndex, state); - if (Window::s_isFocused) + if (GameWindow::s_isFocused) { auto keyboardState = SDL_GetKeyboardState(NULL); diff --git a/UnleashedRecomp/kernel/xam.h b/UnleashedRecomp/kernel/xam.h index 9fe26b81..6d1f2572 100644 --- a/UnleashedRecomp/kernel/xam.h +++ b/UnleashedRecomp/kernel/xam.h @@ -1,32 +1,32 @@ #pragma once #include -#define MSGID(Area, Number) (DWORD)((WORD)(Area) << 16 | (WORD)(Number)) +#define MSGID(Area, Number) (uint32_t)((uint16_t)(Area) << 16 | (uint16_t)(Number)) #define MSG_AREA(msgid) (((msgid) >> 16) & 0xFFFF) #define MSG_NUMBER(msgid) ((msgid) & 0xFFFF) -XCONTENT_DATA XamMakeContent(DWORD type, const std::string_view& name); +XCONTENT_DATA XamMakeContent(uint32_t type, const std::string_view& name); void XamRegisterContent(const XCONTENT_DATA& data, const std::string_view& root); std::string_view XamGetRootPath(const std::string_view& root); void XamRootCreate(const std::string_view& root, const std::string_view& path); -SWA_API DWORD XamNotifyCreateListener(uint64_t qwAreas); -SWA_API void XamNotifyEnqueueEvent(DWORD dwId, DWORD dwParam); // i made it the fuck up -SWA_API bool XNotifyGetNext(DWORD hNotification, DWORD dwMsgFilter, XDWORD* pdwId, XDWORD* pParam); +SWA_API uint32_t XamNotifyCreateListener(uint64_t qwAreas); +SWA_API void XamNotifyEnqueueEvent(uint32_t dwId, uint32_t dwParam); // i made it the fuck up +SWA_API bool XNotifyGetNext(uint32_t hNotification, uint32_t dwMsgFilter, be* pdwId, be* pParam); -SWA_API uint32_t XamShowMessageBoxUI(DWORD dwUserIndex, XWORD* wszTitle, XWORD* wszText, DWORD cButtons, - xpointer* pwszButtons, DWORD dwFocusButton, DWORD dwFlags, XLPDWORD pResult, XXOVERLAPPED* pOverlapped); +SWA_API uint32_t XamShowMessageBoxUI(uint32_t dwUserIndex, be* wszTitle, be* wszText, uint32_t cButtons, + xpointer>* pwszButtons, uint32_t dwFocusButton, uint32_t dwFlags, be* pResult, XXOVERLAPPED* pOverlapped); -SWA_API uint32_t XamContentCreateEnumerator(DWORD dwUserIndex, DWORD DeviceID, DWORD dwContentType, - DWORD dwContentFlags, DWORD cItem, XLPDWORD pcbBuffer, XLPDWORD phEnum); -SWA_API uint32_t XamEnumerate(uint32_t hEnum, DWORD dwFlags, PVOID pvBuffer, DWORD cbBuffer, XLPDWORD pcItemsReturned, XXOVERLAPPED* pOverlapped); +SWA_API uint32_t XamContentCreateEnumerator(uint32_t dwUserIndex, uint32_t DeviceID, uint32_t dwContentType, + uint32_t dwContentFlags, uint32_t cItem, be* pcbBuffer, be* phEnum); +SWA_API uint32_t XamEnumerate(uint32_t hEnum, uint32_t dwFlags, void* pvBuffer, uint32_t cbBuffer, be* pcItemsReturned, XXOVERLAPPED* pOverlapped); -SWA_API uint32_t XamContentCreateEx(DWORD dwUserIndex, LPCSTR szRootName, const XCONTENT_DATA* pContentData, - DWORD dwContentFlags, XLPDWORD pdwDisposition, XLPDWORD pdwLicenseMask, - DWORD dwFileCacheSize, uint64_t uliContentSize, PXXOVERLAPPED pOverlapped); -SWA_API uint32_t XamContentGetDeviceData(DWORD DeviceID, XDEVICE_DATA* pDeviceData); -SWA_API uint32_t XamContentClose(LPCSTR szRootName, XXOVERLAPPED* pOverlapped); +SWA_API uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const XCONTENT_DATA* pContentData, + uint32_t dwContentFlags, be* pdwDisposition, be* pdwLicenseMask, + uint32_t dwFileCacheSize, uint64_t uliContentSize, PXXOVERLAPPED pOverlapped); +SWA_API uint32_t XamContentGetDeviceData(uint32_t DeviceID, XDEVICE_DATA* pDeviceData); +SWA_API uint32_t XamContentClose(const char* szRootName, XXOVERLAPPED* pOverlapped); SWA_API uint32_t XamInputGetCapabilities(uint32_t unk, uint32_t userIndex, uint32_t flags, XAMINPUT_CAPABILITIES* caps); SWA_API uint32_t XamInputGetState(uint32_t userIndex, uint32_t flags, XAMINPUT_STATE* state); diff --git a/UnleashedRecomp/kernel/xdm.h b/UnleashedRecomp/kernel/xdm.h index 4c933228..5569952e 100644 --- a/UnleashedRecomp/kernel/xdm.h +++ b/UnleashedRecomp/kernel/xdm.h @@ -3,9 +3,84 @@ #include "heap.h" #include "memory.h" -#define OBJECT_SIGNATURE (DWORD)'XBOX' +#define OBJECT_SIGNATURE (uint32_t)'XBOX' #define GUEST_INVALID_HANDLE_VALUE 0xFFFFFFFF +#ifndef _WIN32 + +#define S_OK 0x00000000 +#define FALSE 0x00000000 +#define TRUE 0x00000001 +#define STATUS_SUCCESS 0x00000000 +#define STATUS_WAIT_0 0x00000000 +#define STATUS_USER_APC 0x000000C0 +#define STATUS_TIMEOUT 0x00000102 +#define STATUS_FAIL_CHECK 0xC0000229 +#define INFINITE 0xFFFFFFFF +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define GENERIC_READ 0x80000000 +#define GENERIC_WRITE 0x40000000 +#define FILE_READ_DATA 0x0001 +#define FILE_SHARE_READ 0x00000001 +#define FILE_SHARE_WRITE 0x00000002 +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define INVALID_FILE_SIZE 0xFFFFFFFF +#define INVALID_SET_FILE_POINTER 0xFFFFFFFF +#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF +#define FILE_BEGIN 0 +#define FILE_CURRENT 1 +#define FILE_END 2 +#define ERROR_NO_MORE_FILES 0x12 +#define ERROR_NO_SUCH_USER 0x525 +#define ERROR_SUCCESS 0x0 +#define ERROR_PATH_NOT_FOUND 0x3 +#define ERROR_BAD_ARGUMENTS 0xA0 +#define ERROR_DEVICE_NOT_CONNECTED 0x48F +#define PAGE_READWRITE 0x04 + +typedef union _LARGE_INTEGER { + struct { + uint32_t LowPart; + int32_t HighPart; + }; + struct { + uint32_t LowPart; + int32_t HighPart; + } u; + int64_t QuadPart; +} LARGE_INTEGER; + +static_assert(sizeof(LARGE_INTEGER) == 8); + +typedef struct _FILETIME +{ + uint32_t dwLowDateTime; + uint32_t dwHighDateTime; +} FILETIME; + +static_assert(sizeof(FILETIME) == 8); + +typedef struct _WIN32_FIND_DATAA +{ + uint32_t dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + uint32_t nFileSizeHigh; + uint32_t nFileSizeLow; + uint32_t dwReserved0; + uint32_t dwReserved1; + char cFileName[260]; + char cAlternateFileName[14]; +} WIN32_FIND_DATAA; + +static_assert(sizeof(WIN32_FIND_DATAA) == 320); + +#endif + struct KernelObject { virtual ~KernelObject() diff --git a/UnleashedRecomp/locale/config_locale.cpp b/UnleashedRecomp/locale/config_locale.cpp index 9a904c00..e591186a 100644 --- a/UnleashedRecomp/locale/config_locale.cpp +++ b/UnleashedRecomp/locale/config_locale.cpp @@ -1,5 +1,4 @@ #include -#include #define CONFIG_DEFINE_LOCALE(name) \ CONFIG_LOCALE Config::g_##name##_locale = diff --git a/UnleashedRecomp/locale/locale.cpp b/UnleashedRecomp/locale/locale.cpp index 31048047..b54b4b1d 100644 --- a/UnleashedRecomp/locale/locale.cpp +++ b/UnleashedRecomp/locale/locale.cpp @@ -1,3 +1,4 @@ +#include #include std::unordered_map> g_locale = diff --git a/UnleashedRecomp/locale/locale.h b/UnleashedRecomp/locale/locale.h index 0c0986a1..b7f716c8 100644 --- a/UnleashedRecomp/locale/locale.h +++ b/UnleashedRecomp/locale/locale.h @@ -1,6 +1,14 @@ #pragma once -#include +enum class ELanguage : uint32_t +{ + English = 1, + Japanese, + German, + French, + Spanish, + Italian +}; inline std::string g_localeMissing = ""; diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index b5b20f7e..214b1c64 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -50,8 +50,8 @@ void KiSystemStartup() { const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game"); const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update"); - XamRegisterContent(gameContent, DirectoryExists(".\\game") ? ".\\game" : "."); - XamRegisterContent(updateContent, ".\\update"); + XamRegisterContent(gameContent, std::filesystem::exists("./game") ? "./game" : "."); + XamRegisterContent(updateContent, "./update"); const auto savePath = GetSavePath(); const auto saveName = "SYS-DATA"; @@ -69,27 +69,6 @@ void KiSystemStartup() // OS mounts game data to D: XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr); - WIN32_FIND_DATAA fdata; - const auto findHandle = FindFirstFileA(".\\dlc\\*.*", &fdata); - if (findHandle != INVALID_HANDLE_VALUE) - { - char strBuf[256]; - do - { - if (strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) - { - continue; - } - - if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - snprintf(strBuf, sizeof(strBuf), ".\\dlc\\%s", fdata.cFileName); - XamRegisterContent(XamMakeContent(XCONTENTTYPE_DLC, fdata.cFileName), strBuf); - } - } while (FindNextFileA(findHandle, &fdata)); - FindClose(findHandle); - } - XAudioInitializeSystem(); } diff --git a/UnleashedRecomp/misc_impl.cpp b/UnleashedRecomp/misc_impl.cpp index bfaaddba..a58b58fd 100644 --- a/UnleashedRecomp/misc_impl.cpp +++ b/UnleashedRecomp/misc_impl.cpp @@ -1,22 +1,23 @@ #include "stdafx.h" #include +#include -BOOL QueryPerformanceCounterImpl(LARGE_INTEGER* lpPerformanceCount) +uint32_t QueryPerformanceCounterImpl(LARGE_INTEGER* lpPerformanceCount) { lpPerformanceCount->QuadPart = ByteSwap(std::chrono::steady_clock::now().time_since_epoch().count()); return TRUE; } -BOOL QueryPerformanceFrequencyImpl(LARGE_INTEGER* lpFrequency) +uint32_t QueryPerformanceFrequencyImpl(LARGE_INTEGER* lpFrequency) { constexpr auto Frequency = std::chrono::steady_clock::period::den / std::chrono::steady_clock::period::num; lpFrequency->QuadPart = ByteSwap(Frequency); return TRUE; } -DWORD GetTickCountImpl() +uint32_t GetTickCountImpl() { - return DWORD(std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count()); + return uint32_t(std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count()); } void GlobalMemoryStatusImpl(XLPMEMORYSTATUS lpMemoryStatus) @@ -42,7 +43,11 @@ GUEST_FUNCTION_HOOK(sub_831B5E00, memmove); GUEST_FUNCTION_HOOK(sub_831B0BA0, memset); GUEST_FUNCTION_HOOK(sub_831CCAA0, memset); +#ifdef _WIN32 GUEST_FUNCTION_HOOK(sub_82BD4CA8, OutputDebugStringA); +#else +GUEST_FUNCTION_STUB(sub_82BD4CA8); +#endif GUEST_FUNCTION_HOOK(sub_82BD4AC8, QueryPerformanceCounterImpl); GUEST_FUNCTION_HOOK(sub_831CD040, QueryPerformanceFrequencyImpl); diff --git a/UnleashedRecomp/mutex.h b/UnleashedRecomp/mutex.h index 9cc12b36..9656d521 100644 --- a/UnleashedRecomp/mutex.h +++ b/UnleashedRecomp/mutex.h @@ -1,5 +1,7 @@ #pragma once +#ifdef _WIN32 + struct Mutex : CRITICAL_SECTION { Mutex() @@ -20,4 +22,10 @@ struct Mutex : CRITICAL_SECTION { LeaveCriticalSection(this); } -}; \ No newline at end of file +}; + +#else + +using Mutex = std::mutex; + +#endif diff --git a/UnleashedRecomp/os/linux/logger_linux.cpp b/UnleashedRecomp/os/linux/logger_linux.cpp new file mode 100644 index 00000000..910307ba --- /dev/null +++ b/UnleashedRecomp/os/linux/logger_linux.cpp @@ -0,0 +1,17 @@ +#include + +void os::logger::detail::Init() +{ +} + +void os::logger::detail::Log(const std::string_view str, detail::ELogType type, const char* func) +{ + if (func) + { + fmt::println("[{}] {}", func, str); + } + else + { + fmt::println("{}", str); + } +} diff --git a/UnleashedRecomp/os/linux/media_linux.cpp b/UnleashedRecomp/os/linux/media_linux.cpp new file mode 100644 index 00000000..74ec9961 --- /dev/null +++ b/UnleashedRecomp/os/linux/media_linux.cpp @@ -0,0 +1,7 @@ +#include + +bool os::media::detail::IsExternalMediaPlaying() +{ + // This functionality is not supported in Linux. + return false; +} diff --git a/UnleashedRecomp/os/linux/process_linux.cpp b/UnleashedRecomp/os/linux/process_linux.cpp new file mode 100644 index 00000000..ed02c9e9 --- /dev/null +++ b/UnleashedRecomp/os/linux/process_linux.cpp @@ -0,0 +1,57 @@ +#include + +#include + +std::filesystem::path os::process::detail::GetExecutablePath() +{ + char exePath[PATH_MAX] = {}; + if (readlink("/proc/self/exe", exePath, PATH_MAX) > 0) + { + return std::filesystem::path(std::u8string_view((const char8_t*)(exePath))); + } + else + { + return std::filesystem::path(); + } +} + +std::filesystem::path os::process::detail::GetWorkingDirectory() +{ + char cwd[PATH_MAX] = {}; + char *res = getcwd(cwd, sizeof(cwd)); + if (res != nullptr) + { + return std::filesystem::path(std::u8string_view((const char8_t*)(cwd))); + } + else + { + return std::filesystem::path(); + } +} + +bool os::process::detail::StartProcess(const std::filesystem::path path, const std::vector args, std::filesystem::path work) +{ + pid_t pid = fork(); + if (pid < 0) + return false; + + if (pid == 0) + { + setsid(); + + std::u8string workU8 = work.u8string(); + chdir((const char*)(workU8.c_str())); + + std::u8string pathU8 = path.u8string(); + std::vector argStrs; + argStrs.push_back((char*)(pathU8.c_str())); + for (const std::string& arg : args) + argStrs.push_back((char *)(arg.c_str())); + + argStrs.push_back(nullptr); + execvp((const char*)(pathU8.c_str()), argStrs.data()); + raise(SIGKILL); + } + + return true; +} diff --git a/UnleashedRecomp/os/linux/version_linux.cpp b/UnleashedRecomp/os/linux/version_linux.cpp new file mode 100644 index 00000000..17b5b120 --- /dev/null +++ b/UnleashedRecomp/os/linux/version_linux.cpp @@ -0,0 +1,7 @@ +#include + +os::version::detail::OSVersion os::version::detail::GetOSVersion() +{ + assert(false && "Unimplemented."); + return os::version::detail::OSVersion(); +} diff --git a/UnleashedRecomp/patches/camera_patches.cpp b/UnleashedRecomp/patches/camera_patches.cpp index 9b70e525..83ec4dfa 100644 --- a/UnleashedRecomp/patches/camera_patches.cpp +++ b/UnleashedRecomp/patches/camera_patches.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include constexpr float m_baseAspectRatio = 16.0f / 9.0f; @@ -8,7 +8,7 @@ constexpr float m_baseAspectRatio = 16.0f / 9.0f; bool CameraAspectRatioMidAsmHook(PPCRegister& r31) { auto pCamera = (SWA::CCamera*)g_memory.Translate(r31.u32); - auto newAspectRatio = (float)Window::s_width / (float)Window::s_height; + auto newAspectRatio = (float)GameWindow::s_width / (float)GameWindow::s_height; // Dynamically adjust horizontal aspect ratio to window dimensions. pCamera->m_HorzAspectRatio = newAspectRatio; @@ -27,7 +27,7 @@ bool CameraBoostAspectRatioMidAsmHook(PPCRegister& r31, PPCRegister& f0, PPCRegi { auto pCamera = (SWA::CCamera*)g_memory.Translate(r31.u32); - if (Window::s_width < Window::s_height) + if (GameWindow::s_width < GameWindow::s_height) { pCamera->m_VertFieldOfView = pCamera->m_HorzFieldOfView + f10.f64; } diff --git a/UnleashedRecomp/patches/fps_patches.cpp b/UnleashedRecomp/patches/fps_patches.cpp index 33055db6..684421cb 100644 --- a/UnleashedRecomp/patches/fps_patches.cpp +++ b/UnleashedRecomp/patches/fps_patches.cpp @@ -1,11 +1,11 @@ #include #include -#include +#include #include #include float m_lastLoadingFrameDelta = 0.0f; -std::chrono::steady_clock::time_point m_lastLoadingFrameTime; +std::chrono::high_resolution_clock::time_point m_lastLoadingFrameTime; void DownForceDeltaTimeFixMidAsmHook(PPCRegister& f0) { diff --git a/UnleashedRecomp/patches/misc_patches.cpp b/UnleashedRecomp/patches/misc_patches.cpp index 3c69e3bc..7a368849 100644 --- a/UnleashedRecomp/patches/misc_patches.cpp +++ b/UnleashedRecomp/patches/misc_patches.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/UnleashedRecomp/patches/player_patches.cpp b/UnleashedRecomp/patches/player_patches.cpp index dfa1142d..d33887a6 100644 --- a/UnleashedRecomp/patches/player_patches.cpp +++ b/UnleashedRecomp/patches/player_patches.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -126,7 +126,7 @@ PPC_FUNC(sub_823B49D8) { __imp__sub_823B49D8(ctx, base); - SDL_User_EvilSonic(Window::s_pWindow, true); + SDL_User_EvilSonic(GameWindow::s_pWindow, true); } // SWA::Player::CEvilSonicContext::Dtor @@ -135,5 +135,5 @@ PPC_FUNC(sub_823B4590) { __imp__sub_823B4590(ctx, base); - SDL_User_EvilSonic(Window::s_pWindow, false); + SDL_User_EvilSonic(GameWindow::s_pWindow, false); } diff --git a/UnleashedRecomp/patches/video_patches.cpp b/UnleashedRecomp/patches/video_patches.cpp index 5e407feb..e0ff0e05 100644 --- a/UnleashedRecomp/patches/video_patches.cpp +++ b/UnleashedRecomp/patches/video_patches.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include // TODO: to be removed. constexpr float m_baseAspectRatio = 16.0f / 9.0f; @@ -12,7 +12,7 @@ void CSDAspectRatioMidAsmHook(PPCRegister& f1, PPCRegister& f2) if (Config::UIScaleMode == EUIScaleMode::Stretch) return; - auto newAspectRatio = (float)Window::s_width / (float)Window::s_height; + auto newAspectRatio = (float)GameWindow::s_width / (float)GameWindow::s_height; if (newAspectRatio > m_baseAspectRatio) { diff --git a/UnleashedRecomp/stdafx.h b/UnleashedRecomp/stdafx.h index 3a79732b..a0b541ca 100644 --- a/UnleashedRecomp/stdafx.h +++ b/UnleashedRecomp/stdafx.h @@ -34,11 +34,11 @@ using Microsoft::WRL::ComPtr; #include #include #include -#include +#include #include #include #include -#include +#include #include #include #include @@ -46,6 +46,7 @@ using Microsoft::WRL::ComPtr; #include #include #include +#include #include "framework.h" #include "mutex.h" diff --git a/UnleashedRecomp/ui/achievement_menu.cpp b/UnleashedRecomp/ui/achievement_menu.cpp index a14b9af7..d5c7b9d9 100644 --- a/UnleashedRecomp/ui/achievement_menu.cpp +++ b/UnleashedRecomp/ui/achievement_menu.cpp @@ -281,9 +281,14 @@ static void DrawAchievement(int rowIndex, float yOffset, Achievement& achievemen return; char buffer[32]; - struct tm time; - localtime_s(&time, ×tamp); - strftime(buffer, sizeof(buffer), "%Y/%m/%d %H:%M", &time); +#ifdef _WIN32 + tm timeStruct; + tm *timePtr = &timeStruct; + localtime_s(timePtr, ×tamp); +#else + tm *timePtr = localtime(×tamp); +#endif + strftime(buffer, sizeof(buffer), "%Y/%m/%d %H:%M", timePtr); fontSize = Scale(12); textSize = g_fntNewRodinDB->CalcTextSizeA(fontSize, FLT_MAX, 0, buffer); diff --git a/UnleashedRecomp/ui/window.cpp b/UnleashedRecomp/ui/game_window.cpp similarity index 69% rename from UnleashedRecomp/ui/window.cpp rename to UnleashedRecomp/ui/game_window.cpp index 767062b9..73e5fed2 100644 --- a/UnleashedRecomp/ui/window.cpp +++ b/UnleashedRecomp/ui/game_window.cpp @@ -1,4 +1,4 @@ -#include "window.h" +#include "game_window.h" #include "sdl_listener.h" #include #include @@ -31,10 +31,10 @@ int Window_OnSDLEvent(void*, SDL_Event* event) if (!(event->key.keysym.mod & KMOD_ALT) || !m_isFullscreenKeyReleased) break; - Config::Fullscreen = Window::SetFullscreen(!Window::IsFullscreen()); + Config::Fullscreen = GameWindow::SetFullscreen(!GameWindow::IsFullscreen()); if (!Config::Fullscreen) - Config::WindowState = Window::SetMaximised(Config::WindowState == EWindowState::Maximised); + Config::WindowState = GameWindow::SetMaximised(Config::WindowState == EWindowState::Maximised); // Block holding ALT+ENTER spamming window changes. m_isFullscreenKeyReleased = false; @@ -44,17 +44,17 @@ int Window_OnSDLEvent(void*, SDL_Event* event) // Restore original window dimensions on F2. case SDLK_F2: - Config::Fullscreen = Window::SetFullscreen(false); - Window::SetDimensions(DEFAULT_WIDTH, DEFAULT_HEIGHT); + Config::Fullscreen = GameWindow::SetFullscreen(false); + GameWindow::SetDimensions(DEFAULT_WIDTH, DEFAULT_HEIGHT); break; // Recentre window on F3. case SDLK_F3: { - if (Window::IsFullscreen()) + if (GameWindow::IsFullscreen()) break; - Window::SetDimensions(Window::s_width, Window::s_height); + GameWindow::SetDimensions(GameWindow::s_width, GameWindow::s_height); break; } @@ -79,16 +79,16 @@ int Window_OnSDLEvent(void*, SDL_Event* event) switch (event->window.event) { case SDL_WINDOWEVENT_FOCUS_LOST: - Window::s_isFocused = false; + GameWindow::s_isFocused = false; SDL_ShowCursor(SDL_ENABLE); break; case SDL_WINDOWEVENT_FOCUS_GAINED: { - Window::s_isFocused = true; + GameWindow::s_isFocused = true; - if (Window::IsFullscreen()) - SDL_ShowCursor(Window::s_isFullscreenCursorVisible ? SDL_ENABLE : SDL_DISABLE); + if (GameWindow::IsFullscreen()) + SDL_ShowCursor(GameWindow::s_isFullscreenCursorVisible ? SDL_ENABLE : SDL_DISABLE); break; } @@ -103,14 +103,14 @@ int Window_OnSDLEvent(void*, SDL_Event* event) case SDL_WINDOWEVENT_RESIZED: m_isResizing = true; - Window::s_width = event->window.data1; - Window::s_height = event->window.data2; - Window::SetTitle(fmt::format("{} - [{}x{}]", Window::GetTitle(), Window::s_width, Window::s_height).c_str()); + GameWindow::s_width = event->window.data1; + GameWindow::s_height = event->window.data2; + GameWindow::SetTitle(fmt::format("{} - [{}x{}]", GameWindow::GetTitle(), GameWindow::s_width, GameWindow::s_height).c_str()); break; case SDL_WINDOWEVENT_MOVED: - Window::s_x = event->window.data1; - Window::s_y = event->window.data2; + GameWindow::s_x = event->window.data1; + GameWindow::s_y = event->window.data2; break; } @@ -119,13 +119,13 @@ int Window_OnSDLEvent(void*, SDL_Event* event) case SDL_USER_EVILSONIC: { - Window::s_isIconNight = event->user.code; - Window::SetIcon(Window::s_isIconNight); + GameWindow::s_isIconNight = event->user.code; + GameWindow::SetIcon(GameWindow::s_isIconNight); break; } } - if (!Window::IsFullscreen()) + if (!GameWindow::IsFullscreen()) { if (event->type == SDL_CONTROLLERBUTTONDOWN || event->type == SDL_CONTROLLERBUTTONUP || event->type == SDL_CONTROLLERAXISMOTION) { @@ -142,12 +142,14 @@ int Window_OnSDLEvent(void*, SDL_Event* event) return 0; } -void Window::Init() +void GameWindow::Init() { SDL_InitSubSystem(SDL_INIT_VIDEO); SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); SDL_AddEventWatch(Window_OnSDLEvent, s_pWindow); +#ifdef _WIN32 SetProcessDPIAware(); +#endif s_x = Config::WindowX; s_y = Config::WindowY; @@ -183,21 +185,26 @@ void Window::Init() SDL_VERSION(&info.version); SDL_GetWindowWMInfo(s_pWindow, &info); - s_handle = info.info.win.window; - +#if defined(_WIN32) + s_renderWindow = info.info.win.window; SetDarkTitleBar(true); +#elif defined(__linux__) + s_renderWindow = { info.info.x11.display, info.info.x11.window }; +#else + static_assert(false, "Unknown platform."); +#endif SDL_ShowWindow(s_pWindow); } -void Window::Update() +void GameWindow::Update() { - if (!Window::IsFullscreen() && !Window::IsMaximised()) + if (!GameWindow::IsFullscreen() && !GameWindow::IsMaximised()) { - Config::WindowX = Window::s_x; - Config::WindowY = Window::s_y; - Config::WindowWidth = Window::s_width; - Config::WindowHeight = Window::s_height; + Config::WindowX = GameWindow::s_x; + Config::WindowY = GameWindow::s_y; + Config::WindowWidth = GameWindow::s_width; + Config::WindowHeight = GameWindow::s_height; } if (m_isResizing) diff --git a/UnleashedRecomp/ui/window.h b/UnleashedRecomp/ui/game_window.h similarity index 95% rename from UnleashedRecomp/ui/window.h rename to UnleashedRecomp/ui/game_window.h index 8b036a8f..7fe381e2 100644 --- a/UnleashedRecomp/ui/window.h +++ b/UnleashedRecomp/ui/game_window.h @@ -6,6 +6,7 @@ #include #include #include +#include #if _WIN32 #include @@ -15,11 +16,11 @@ #define DEFAULT_WIDTH 1280 #define DEFAULT_HEIGHT 720 -class Window +class GameWindow { public: static inline SDL_Window* s_pWindow; - static inline HWND s_handle; + static inline plume::RenderWindow s_renderWindow; static inline int s_x; static inline int s_y; @@ -87,7 +88,7 @@ public: : 19; // DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 const DWORD useImmersiveDarkMode = isEnabled; - DwmSetWindowAttribute(s_handle, flag, &useImmersiveDarkMode, sizeof(useImmersiveDarkMode)); + DwmSetWindowAttribute(s_renderWindow, flag, &useImmersiveDarkMode, sizeof(useImmersiveDarkMode)); #endif } @@ -107,7 +108,7 @@ public: { SDL_SetWindowFullscreen(s_pWindow, 0); SDL_ShowCursor(SDL_ENABLE); - SetIcon(Window::s_isIconNight); + SetIcon(GameWindow::s_isIconNight); } return isEnabled; diff --git a/UnleashedRecomp/ui/installer_wizard.cpp b/UnleashedRecomp/ui/installer_wizard.cpp index c68cc51a..67c96017 100644 --- a/UnleashedRecomp/ui/installer_wizard.cpp +++ b/UnleashedRecomp/ui/installer_wizard.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include @@ -133,8 +133,12 @@ static WizardPage g_firstPage = WizardPage::SelectLanguage; static WizardPage g_currentPage = g_firstPage; static std::string g_currentMessagePrompt = ""; static bool g_currentMessagePromptConfirmation = false; +static std::list g_currentPickerResults; +static std::atomic g_currentPickerResultsReady = false; +static std::unique_ptr g_currentPickerThread; +static bool g_currentPickerVisible = false; +static bool g_currentPickerFolderMode = false; static int g_currentMessageResult = -1; -static bool g_filesPickerSkipUpdate = false; static ImVec2 g_joypadAxis = {}; static int g_currentCursorIndex = -1; static int g_currentCursorDefault = 0; @@ -148,7 +152,7 @@ public: { constexpr float AxisValueRange = 32767.0f; constexpr float AxisTapRange = 0.5f; - if (!InstallerWizard::s_isVisible || !g_currentMessagePrompt.empty()) + if (!InstallerWizard::s_isVisible || !g_currentMessagePrompt.empty() || g_currentPickerVisible) { return; } @@ -217,7 +221,7 @@ public: case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEMOTION: { - for (size_t i = 0; i < g_currentCursorRects.size() && !g_filesPickerSkipUpdate; i++) + for (size_t i = 0; i < g_currentCursorRects.size(); i++) { auto ¤tRect = g_currentCursorRects[i]; if (ImGui::IsMouseHoveringRect(currentRect.first, currentRect.second, false)) @@ -734,7 +738,7 @@ static void DrawButton(ImVec2 min, ImVec2 max, const char *buttonText, bool sour int baser = 0; int baseg = 0; - if (g_currentMessagePrompt.empty() && !sourceButton && buttonEnabled && (alpha >= 1.0f)) + if (g_currentMessagePrompt.empty() && !g_currentPickerVisible && !sourceButton && buttonEnabled && (alpha >= 1.0f)) { bool cursorOnButton = PushCursorRect(min, max, buttonPressed, makeDefault); if (cursorOnButton) @@ -882,44 +886,44 @@ static bool ConvertPathSet(const nfdpathset_t *pathSet, std::list &filePaths) +static void PickerThreadProcess() { - filePaths.clear(); - const nfdpathset_t *pathSet; - nfdresult_t result = NFD_OpenDialogMultipleU8(&pathSet, nullptr, 0, nullptr); - g_filesPickerSkipUpdate = true; - - if (result == NFD_OKAY) + nfdresult_t result = NFD_ERROR; + if (g_currentPickerFolderMode) { - bool pathsConverted = ConvertPathSet(pathSet, filePaths); - NFD_PathSet_Free(pathSet); - return pathsConverted; + nfdpickfolderu8args_t openArgs = {}; + result = NFD_PickFolderMultipleU8_With(&pathSet, &openArgs); } else { - return false; + nfdopendialogu8args_t openArgs = {}; + result = NFD_OpenDialogMultipleU8_With(&pathSet, &openArgs); } + + if (result == NFD_OKAY) + { + bool pathsConverted = ConvertPathSet(pathSet, g_currentPickerResults); + NFD_PathSet_Free(pathSet); + } + + g_currentPickerResultsReady = true; + g_currentPickerVisible = false; } -static bool ShowFoldersPicker(std::list &folderPaths) +static void ShowPicker(bool folderMode) { - folderPaths.clear(); - - const nfdpathset_t *pathSet; - nfdresult_t result = NFD_PickFolderMultipleU8(&pathSet, nullptr); - g_filesPickerSkipUpdate = true; - - if (result == NFD_OKAY) + if (g_currentPickerThread != nullptr) { - bool pathsConverted = ConvertPathSet(pathSet, folderPaths); - NFD_PathSet_Free(pathSet); - return pathsConverted; - } - else - { - return false; + g_currentPickerThread->join(); + g_currentPickerThread.reset(); } + + g_currentPickerResults.clear(); + g_currentPickerFolderMode = folderMode; + g_currentPickerResultsReady = false; + g_currentPickerVisible = true; + g_currentPickerThread = std::make_unique(PickerThreadProcess); } static void ParseSourcePaths(std::list &paths) @@ -1013,8 +1017,6 @@ static void DrawLanguagePicker() static void DrawSourcePickers() { - g_filesPickerSkipUpdate = false; - bool buttonPressed = false; std::list paths; if (g_currentPage == WizardPage::SelectGameAndUpdate || g_currentPage == WizardPage::SelectDLC) @@ -1028,9 +1030,9 @@ static void DrawSourcePickers() ImVec2 min = { Scale(AlignToNextGrid(CONTAINER_X) + BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP) }; ImVec2 max = { Scale(AlignToNextGrid(CONTAINER_X) + BOTTOM_X_GAP + textSize.x * squashRatio), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP + BUTTON_HEIGHT) }; DrawButton(min, max, addFilesText.c_str(), false, true, buttonPressed, ADD_BUTTON_MAX_TEXT_WIDTH); - if (buttonPressed && ShowFilesPicker(paths)) + if (buttonPressed) { - ParseSourcePaths(paths); + ShowPicker(false); } min.x += Scale(BOTTOM_X_GAP + textSize.x * squashRatio); @@ -1041,9 +1043,9 @@ static void DrawSourcePickers() max.x = min.x + Scale(textSize.x * squashRatio); DrawButton(min, max, addFolderText.c_str(), false, true, buttonPressed, ADD_BUTTON_MAX_TEXT_WIDTH); - if (buttonPressed && ShowFoldersPicker(paths)) + if (buttonPressed) { - ParseSourcePaths(paths); + ShowPicker(true); } } } @@ -1305,14 +1307,6 @@ static void DrawBorders() static void DrawMessagePrompt() { - if (g_filesPickerSkipUpdate) - { - // If a blocking function like the files picker is called, we must wait one update before actually showing - // the message box, as a lot of time has passed since the last real update. Otherwise, animations will play - // too quickly and input glitches might happen. - return; - } - if (g_currentMessagePrompt.empty()) { return; @@ -1342,6 +1336,18 @@ static void DrawMessagePrompt() } } +static void CheckPickerResults() +{ + if (!g_currentPickerResultsReady) + { + return; + } + + ParseSourcePaths(g_currentPickerResults); + g_currentPickerResultsReady = false; + g_currentPickerVisible = false; +} + void InstallerWizard::Init() { auto &io = ImGui::GetIO(); @@ -1380,6 +1386,7 @@ void InstallerWizard::Draw() DrawNextButton(); DrawBorders(); DrawMessagePrompt(); + CheckPickerResults(); if (g_isDisappearing) { @@ -1439,18 +1446,18 @@ bool InstallerWizard::Run(bool skipGame) g_currentPage = g_firstPage; } - Window::SetFullscreenCursorVisibility(true); + GameWindow::SetFullscreenCursorVisibility(true); s_isVisible = true; while (s_isVisible) { SDL_PumpEvents(); SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); - Window::Update(); + GameWindow::Update(); Video::HostPresent(); } - Window::SetFullscreenCursorVisibility(false); + GameWindow::SetFullscreenCursorVisibility(false); NFD_Quit(); InstallerWizard::Shutdown(); diff --git a/UnleashedRecomp/ui/options_menu.cpp b/UnleashedRecomp/ui/options_menu.cpp index d9153783..f5ba0f1f 100644 --- a/UnleashedRecomp/ui/options_menu.cpp +++ b/UnleashedRecomp/ui/options_menu.cpp @@ -1,7 +1,7 @@ #include "options_menu.h" #include "options_menu_thumbnails.h" #include "imgui_utils.h" -#include "window.h" +#include "game_window.h" #include "exports.h" #include @@ -444,7 +444,7 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef* conf ImVec2 min = { clipRectMin.x, clipRectMin.y + (optionHeight + optionPadding) * rowIndex + yOffset }; ImVec2 max = { min.x + optionWidth, min.y + optionHeight }; - auto configName = config->GetNameLocalised(); + auto configName = config->GetNameLocalised(Config::Language); auto size = Scale(26.0f); auto textSize = g_seuratFont->CalcTextSizeA(size, FLT_MAX, 0.0f, configName.c_str()); @@ -747,7 +747,7 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef* conf } else { - valueText = config->GetValueLocalised(); + valueText = config->GetValueLocalised(Config::Language); } size = Scale(20.0f); @@ -952,7 +952,7 @@ static void DrawInfoPanel() if (g_selectedItem) { - auto desc = g_selectedItem->GetDescription(); + auto desc = g_selectedItem->GetDescription(Config::Language); auto thumbnail = GetThumbnail(g_selectedItem); if (thumbnail) @@ -971,13 +971,13 @@ static void DrawInfoPanel() auto resScale = round(*(float*)g_selectedItem->GetValue() * 1000) / 1000; std::snprintf(buf, sizeof(buf), desc.c_str(), - (int)((float)Window::s_width * resScale), - (int)((float)Window::s_height * resScale)); + (int)((float)GameWindow::s_width * resScale), + (int)((float)GameWindow::s_height * resScale)); desc = buf; } - desc += "\n\n" + g_selectedItem->GetValueDescription(); + desc += "\n\n" + g_selectedItem->GetValueDescription(Config::Language); } auto size = Scale(26.0f); diff --git a/UnleashedRecomp/ui/window_events.h b/UnleashedRecomp/ui/window_events.h index 6e94e3a6..1f1acaa7 100644 --- a/UnleashedRecomp/ui/window_events.h +++ b/UnleashedRecomp/ui/window_events.h @@ -1,7 +1,7 @@ #pragma once #include -#include "ui/window.h" +#include "ui/game_window.h" #define SDL_USER_EVILSONIC (SDL_USEREVENT + 1) diff --git a/UnleashedRecomp/user/config.cpp b/UnleashedRecomp/user/config.cpp index 71df5315..7cad1414 100644 --- a/UnleashedRecomp/user/config.cpp +++ b/UnleashedRecomp/user/config.cpp @@ -20,7 +20,7 @@ void Config::Load() toml = toml::parse(tomlStream); } - for (auto def : Config::Definitions) + for (auto def : g_configDefinitions) { def->ReadValue(toml); #if _DEBUG @@ -44,7 +44,7 @@ void Config::Save() std::string result; std::string section; - for (auto def : Config::Definitions) + for (auto def : g_configDefinitions) { auto isFirstSection = section.empty(); auto isDefWithSection = section != def->GetSection(); diff --git a/UnleashedRecomp/user/config.h b/UnleashedRecomp/user/config.h index 137925ab..fdba970f 100644 --- a/UnleashedRecomp/user/config.h +++ b/UnleashedRecomp/user/config.h @@ -1,14 +1,592 @@ #pragma once -#include +#include #include #include +class IConfigDef +{ +public: + virtual ~IConfigDef() = default; + virtual void ReadValue(toml::v3::ex::parse_result& toml) = 0; + virtual void MakeDefault() = 0; + virtual std::string_view GetSection() const = 0; + virtual std::string_view GetName() const = 0; + virtual std::string GetNameLocalised(ELanguage language) const = 0; + virtual std::string GetDescription(ELanguage language) const = 0; + virtual bool IsDefaultValue() const = 0; + virtual const void* GetValue() const = 0; + virtual std::string GetValueLocalised(ELanguage language) const = 0; + virtual std::string GetValueDescription(ELanguage language) const = 0; + virtual std::string GetDefinition(bool withSection = false) const = 0; + virtual std::string ToString(bool strWithQuotes = true) const = 0; + virtual void GetLocaleStrings(std::vector& localeStrings) const = 0; +}; + +#define CONFIG_LOCALE std::unordered_map> +#define CONFIG_ENUM_LOCALE(type) std::unordered_map>> + +#define CONFIG_DEFINE(section, type, name, defaultValue) \ + static inline ConfigDef name{section, #name, defaultValue}; + +#define CONFIG_DEFINE_LOCALISED(section, type, name, defaultValue) \ + static CONFIG_LOCALE g_##name##_locale; \ + static inline ConfigDef name{section, #name, &g_##name##_locale, defaultValue}; + +#define CONFIG_DEFINE_ENUM(section, type, name, defaultValue) \ + static inline ConfigDef name{section, #name, defaultValue, &g_##type##_template}; + +#define CONFIG_DEFINE_ENUM_LOCALISED(section, type, name, defaultValue) \ + static CONFIG_LOCALE g_##name##_locale; \ + static CONFIG_ENUM_LOCALE(type) g_##type##_locale; \ + static inline ConfigDef name{section, #name, &g_##name##_locale, defaultValue, &g_##type##_template, &g_##type##_locale}; + +#define CONFIG_DEFINE_CALLBACK(section, type, name, defaultValue, readCallback) \ + static CONFIG_LOCALE g_##name##_locale; \ + static inline ConfigDef name{section, #name, defaultValue, [](ConfigDef* def) readCallback}; + +#define CONFIG_DEFINE_ENUM_TEMPLATE(type) \ + inline std::unordered_map g_##type##_template = + +#define WINDOWPOS_CENTRED 0x2FFF0000 + +static inline std::vector g_configDefinitions{}; + +CONFIG_DEFINE_ENUM_TEMPLATE(ELanguage) +{ + { "English", ELanguage::English }, + { "Japanese", ELanguage::Japanese }, + { "German", ELanguage::German }, + { "French", ELanguage::French }, + { "Spanish", ELanguage::Spanish }, + { "Italian", ELanguage::Italian } +}; + +enum class EUnleashGaugeBehaviour : uint32_t +{ + Original, + Revised +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EUnleashGaugeBehaviour) +{ + { "Original", EUnleashGaugeBehaviour::Original }, + { "Revised", EUnleashGaugeBehaviour::Revised } +}; + +enum class ETimeOfDayTransition : uint32_t +{ + Xbox, + PlayStation +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(ETimeOfDayTransition) +{ + { "Xbox", ETimeOfDayTransition::Xbox }, + { "PlayStation", ETimeOfDayTransition::PlayStation } +}; + +enum class EControllerIcons : uint32_t +{ + Auto, + Xbox, + PlayStation +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EControllerIcons) +{ + { "Auto", EControllerIcons::Auto }, + { "Xbox", EControllerIcons::Xbox }, + { "PlayStation", EControllerIcons::PlayStation } +}; + +enum class EVoiceLanguage : uint32_t +{ + English, + Japanese +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EVoiceLanguage) +{ + { "English", EVoiceLanguage::English }, + { "Japanese", EVoiceLanguage::Japanese } +}; + +enum class EGraphicsAPI : uint32_t +{ +#ifdef SWA_D3D12 + D3D12, +#endif + Vulkan +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EGraphicsAPI) +{ +#ifdef SWA_D3D12 + { "D3D12", EGraphicsAPI::D3D12 }, +#endif + { "Vulkan", EGraphicsAPI::Vulkan } +}; + +enum class EWindowState : uint32_t +{ + Normal, + Maximised +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EWindowState) +{ + { "Normal", EWindowState::Normal }, + { "Maximised", EWindowState::Maximised }, + { "Maximized", EWindowState::Maximised } +}; + +enum class EAspectRatio : uint32_t +{ + Auto, + Square, + Widescreen +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EAspectRatio) +{ + { "Auto", EAspectRatio::Auto }, + { "4:3", EAspectRatio::Square }, + { "16:9", EAspectRatio::Widescreen } +}; + +enum class ETripleBuffering : uint32_t +{ + Auto, + On, + Off +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(ETripleBuffering) +{ + { "Auto", ETripleBuffering::Auto }, + { "On", ETripleBuffering::On }, + { "Off", ETripleBuffering::Off } +}; + +enum class EAntiAliasing : uint32_t +{ + None = 0, + MSAA2x = 2, + MSAA4x = 4, + MSAA8x = 8 +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EAntiAliasing) +{ + { "None", EAntiAliasing::None }, + { "2x MSAA", EAntiAliasing::MSAA2x }, + { "4x MSAA", EAntiAliasing::MSAA4x }, + { "8x MSAA", EAntiAliasing::MSAA8x } +}; + +enum class EShadowResolution : int32_t +{ + Original = -1, + x512 = 512, + x1024 = 1024, + x2048 = 2048, + x4096 = 4096, + x8192 = 8192 +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EShadowResolution) +{ + { "Original", EShadowResolution::Original }, + { "512", EShadowResolution::x512 }, + { "1024", EShadowResolution::x1024 }, + { "2048", EShadowResolution::x2048 }, + { "4096", EShadowResolution::x4096 }, + { "8192", EShadowResolution::x8192 }, +}; + +enum class EGITextureFiltering : uint32_t +{ + Bilinear, + Bicubic +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EGITextureFiltering) +{ + { "Bilinear", EGITextureFiltering::Bilinear }, + { "Bicubic", EGITextureFiltering::Bicubic } +}; + +enum class EDepthOfFieldQuality : uint32_t +{ + Auto, + Low, + Medium, + High, + Ultra +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EDepthOfFieldQuality) +{ + { "Auto", EDepthOfFieldQuality::Auto }, + { "Low", EDepthOfFieldQuality::Low }, + { "Medium", EDepthOfFieldQuality::Medium }, + { "High", EDepthOfFieldQuality::High }, + { "Ultra", EDepthOfFieldQuality::Ultra } +}; + +enum class EMotionBlur : uint32_t +{ + Off, + Original, + Enhanced +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EMotionBlur) +{ + { "Off", EMotionBlur::Off }, + { "Original", EMotionBlur::Original }, + { "Enhanced", EMotionBlur::Enhanced } +}; + +enum class EMovieScaleMode : uint32_t +{ + Stretch, + Fit, + Fill +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EMovieScaleMode) +{ + { "Stretch", EMovieScaleMode::Stretch }, + { "Fit", EMovieScaleMode::Fit }, + { "Fill", EMovieScaleMode::Fill } +}; + +enum class EUIScaleMode : uint32_t +{ + Stretch, + Edge, + Centre +}; + +CONFIG_DEFINE_ENUM_TEMPLATE(EUIScaleMode) +{ + { "Stretch", EUIScaleMode::Stretch }, + { "Edge", EUIScaleMode::Edge }, + { "Centre", EUIScaleMode::Centre }, + { "Center", EUIScaleMode::Centre } +}; + +template +class ConfigDef final : public IConfigDef +{ +public: + std::string Section{}; + std::string Name{}; + CONFIG_LOCALE* Locale{}; + T DefaultValue{}; + T Value{ DefaultValue }; + std::unordered_map* EnumTemplate; + std::map EnumTemplateReverse{}; + CONFIG_ENUM_LOCALE(T)* EnumLocale{}; + std::function*)> Callback; + + // CONFIG_DEFINE + ConfigDef(std::string section, std::string name, T defaultValue) : Section(section), Name(name), DefaultValue(defaultValue) + { + g_configDefinitions.emplace_back(this); + } + + // CONFIG_DEFINE_LOCALISED + ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue) : Section(section), Name(name), Locale(nameLocale), DefaultValue(defaultValue) + { + g_configDefinitions.emplace_back(this); + } + + // CONFIG_DEFINE_ENUM + ConfigDef(std::string section, std::string name, T defaultValue, std::unordered_map* enumTemplate) : Section(section), Name(name), DefaultValue(defaultValue), EnumTemplate(enumTemplate) + { + for (const auto& pair : *EnumTemplate) + EnumTemplateReverse[pair.second] = pair.first; + + g_configDefinitions.emplace_back(this); + } + + // CONFIG_DEFINE_ENUM_LOCALISED + ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue, std::unordered_map* enumTemplate, CONFIG_ENUM_LOCALE(T)* enumLocale) : Section(section), Name(name), Locale(nameLocale), DefaultValue(defaultValue), EnumTemplate(enumTemplate), EnumLocale(enumLocale) + { + for (const auto& pair : *EnumTemplate) + EnumTemplateReverse[pair.second] = pair.first; + + g_configDefinitions.emplace_back(this); + } + + // CONFIG_DEFINE_CALLBACK + ConfigDef(std::string section, std::string name, T defaultValue, std::function*)> callback) : Section(section), Name(name), DefaultValue(defaultValue), Callback(callback) + { + g_configDefinitions.emplace_back(this); + } + + void ReadValue(toml::v3::ex::parse_result& toml) override + { + if (auto pSection = toml[Section].as_table()) + { + const auto& section = *pSection; + + if constexpr (std::is_same::value) + { + Value = section[Name].value_or(DefaultValue); + } + else if constexpr (std::is_enum_v) + { + std::string value = section[Name].value_or(std::string()); + auto it = EnumTemplate->find(value); + if (it != EnumTemplate->end()) + { + Value = it->second; + } + else + { + Value = DefaultValue; + } + } + else + { + Value = section[Name].value_or(DefaultValue); + } + + if (Callback) + Callback(this); + } + } + + void MakeDefault() override + { + Value = DefaultValue; + } + + std::string_view GetSection() const override + { + return Section; + } + + std::string_view GetName() const override + { + return Name; + } + + std::string GetNameLocalised(ELanguage language) const override + { + if (!Locale) + return Name; + + if (!Locale->count(language)) + { + if (Locale->count(ELanguage::English)) + { + return std::get<0>(Locale->at(ELanguage::English)); + } + else + { + return Name; + } + } + + return std::get<0>(Locale->at(language)); + } + + std::string GetDescription(ELanguage language) const override + { + if (!Locale) + return ""; + + if (!Locale->count(language)) + { + if (Locale->count(ELanguage::English)) + { + return std::get<1>(Locale->at(ELanguage::English)); + } + else + { + return ""; + } + } + + return std::get<1>(Locale->at(language)); + } + + bool IsDefaultValue() const override + { + return Value == DefaultValue; + } + + const void* GetValue() const override + { + return &Value; + } + + std::string GetValueLocalised(ELanguage language) const override + { + CONFIG_ENUM_LOCALE(T)* locale = nullptr; + + if constexpr (std::is_enum_v) + { + locale = EnumLocale; + } + else if constexpr (std::is_same_v) + { + return Value + ? Localise("Common_On") + : Localise("Common_Off"); + } + + if (!locale) + return ToString(false); + + if (!locale->count(language)) + { + if (locale->count(ELanguage::English)) + { + language = ELanguage::English; + } + else + { + return ToString(false); + } + } + + auto strings = locale->at(language); + + if (!strings.count(Value)) + return ToString(false); + + return std::get<0>(strings.at(Value)); + } + + std::string GetValueDescription(ELanguage language) const override + { + CONFIG_ENUM_LOCALE(T)* locale = nullptr; + + if constexpr (std::is_enum_v) + { + locale = EnumLocale; + } + else if constexpr (std::is_same_v) + { + return ""; + } + + if (!locale) + return ""; + + if (!locale->count(language)) + { + if (locale->count(ELanguage::English)) + { + language = ELanguage::English; + } + else + { + return ""; + } + } + + auto strings = locale->at(language); + + if (!strings.count(Value)) + return ""; + + return std::get<1>(strings.at(Value)); + } + + std::string GetDefinition(bool withSection = false) const override + { + std::string result; + + if (withSection) + result += "[" + Section + "]\n"; + + result += Name + " = " + ToString(); + + return result; + } + + std::string ToString(bool strWithQuotes = true) const override + { + std::string result = "N/A"; + + if constexpr (std::is_same_v) + { + result = fmt::format("{}", Value); + + if (strWithQuotes) + result = fmt::format("\"{}\"", result); + } + else if constexpr (std::is_enum_v) + { + auto it = EnumTemplateReverse.find(Value); + + if (it != EnumTemplateReverse.end()) + result = fmt::format("{}", it->second); + + if (strWithQuotes) + result = fmt::format("\"{}\"", result); + } + else + { + result = fmt::format("{}", Value); + } + + return result; + } + + void GetLocaleStrings(std::vector& localeStrings) const override + { + if (Locale != nullptr) + { + for (auto& [language, nameAndDesc] : *Locale) + { + localeStrings.push_back(std::get<0>(nameAndDesc)); + localeStrings.push_back(std::get<1>(nameAndDesc)); + } + } + + if (EnumLocale != nullptr) + { + for (auto& [language, locale] : *EnumLocale) + { + for (auto& [value, nameAndDesc] : locale) + { + localeStrings.push_back(std::get<0>(nameAndDesc)); + localeStrings.push_back(std::get<1>(nameAndDesc)); + } + } + } + } + + ConfigDef& operator=(const ConfigDef& other) + { + if (this != &other) + Value = other.Value; + + return *this; + } + + operator T() const + { + return Value; + } + + void operator=(const T& other) + { + Value = other; + } +}; + class Config { public: - static inline std::vector Definitions{}; - CONFIG_DEFINE_ENUM_LOCALISED("System", ELanguage, Language, ELanguage::English); CONFIG_DEFINE_LOCALISED("System", bool, Hints, true); CONFIG_DEFINE_LOCALISED("System", bool, ControlTutorial, true); diff --git a/UnleashedRecomp/user/config_detail.cpp b/UnleashedRecomp/user/config_detail.cpp deleted file mode 100644 index dc4cfb4c..00000000 --- a/UnleashedRecomp/user/config_detail.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include "config.h" -#include "config_detail.h" -#include - -// CONFIG_DEFINE -template -ConfigDef::ConfigDef(std::string section, std::string name, T defaultValue) : Section(section), Name(name), DefaultValue(defaultValue) -{ - Config::Definitions.emplace_back(this); -} - -// CONFIG_DEFINE_LOCALISED -template -ConfigDef::ConfigDef(std::string section, std::string name, CONFIG_LOCALE* locale, T defaultValue) - : Section(section), Name(name), Locale(locale), DefaultValue(defaultValue) -{ - Config::Definitions.emplace_back(this); -} - -// CONFIG_DEFINE_ENUM -template -ConfigDef::ConfigDef(std::string section, std::string name, T defaultValue, std::unordered_map* enumTemplate) - : Section(section), Name(name), DefaultValue(defaultValue), EnumTemplate(enumTemplate) -{ - for (const auto& pair : *EnumTemplate) - EnumTemplateReverse[pair.second] = pair.first; - - Config::Definitions.emplace_back(this); -} - -// CONFIG_DEFINE_ENUM_LOCALISED -template -ConfigDef::ConfigDef(std::string section, std::string name, CONFIG_LOCALE* locale, T defaultValue, std::unordered_map* enumTemplate, CONFIG_ENUM_LOCALE(T)* enumLocale) - : Section(section), Name(name), Locale(locale), DefaultValue(defaultValue), EnumTemplate(enumTemplate), EnumLocale(enumLocale) -{ - for (const auto& pair : *EnumTemplate) - EnumTemplateReverse[pair.second] = pair.first; - - Config::Definitions.emplace_back(this); -} - -// CONFIG_DEFINE_CALLBACK -template -ConfigDef::ConfigDef(std::string section, std::string name, T defaultValue, std::function*)> callback) - : Section(section), Name(name), DefaultValue(defaultValue), Callback(callback) -{ - Config::Definitions.emplace_back(this); -} - -template -std::string ConfigDef::GetNameLocalised() const -{ - if (!Locale) - return Name; - - if (!Locale->count(Config::Language)) - { - if (Locale->count(ELanguage::English)) - { - return std::get<0>(Locale->at(ELanguage::English)); - } - else - { - return Name; - } - } - - return std::get<0>(Locale->at(Config::Language)); -} - -template -std::string ConfigDef::GetDescription() const -{ - if (!Locale) - return ""; - - if (!Locale->count(Config::Language)) - { - if (Locale->count(ELanguage::English)) - { - return std::get<1>(Locale->at(ELanguage::English)); - } - else - { - return ""; - } - } - - return std::get<1>(Locale->at(Config::Language)); -} - -template -std::string ConfigDef::GetValueLocalised() const -{ - auto language = Config::Language; - CONFIG_ENUM_LOCALE(T)* locale = nullptr; - - if constexpr (std::is_enum_v) - { - locale = EnumLocale; - } - else if constexpr (std::is_same_v) - { - return Value - ? Localise("Common_On") - : Localise("Common_Off"); - } - - if (!locale) - return ToString(false); - - if (!locale->count(language)) - { - if (locale->count(ELanguage::English)) - { - language = ELanguage::English; - } - else - { - return ToString(false); - } - } - - auto strings = locale->at(language); - - if (!strings.count(Value)) - return ToString(false); - - return std::get<0>(strings.at(Value)); -} - -template -std::string ConfigDef::GetValueDescription() const -{ - auto language = Config::Language; - CONFIG_ENUM_LOCALE(T)* locale = nullptr; - - if constexpr (std::is_enum_v) - { - locale = EnumLocale; - } - else if constexpr (std::is_same_v) - { - return ""; - } - - if (!locale) - return ""; - - if (!locale->count(language)) - { - if (locale->count(ELanguage::English)) - { - language = ELanguage::English; - } - else - { - return ""; - } - } - - auto strings = locale->at(language); - - if (!strings.count(Value)) - return ""; - - return std::get<1>(strings.at(Value)); -} - -template -inline void ConfigDef::GetLocaleStrings(std::vector& localeStrings) const -{ - if (Locale != nullptr) - { - for (auto& [language, nameAndDesc] : *Locale) - { - localeStrings.push_back(std::get<0>(nameAndDesc)); - localeStrings.push_back(std::get<1>(nameAndDesc)); - } - } - - if (EnumLocale != nullptr) - { - for (auto& [language, locale] : *EnumLocale) - { - for (auto& [value, nameAndDesc] : locale) - { - localeStrings.push_back(std::get<0>(nameAndDesc)); - localeStrings.push_back(std::get<1>(nameAndDesc)); - } - } - } -} diff --git a/UnleashedRecomp/user/config_detail.h b/UnleashedRecomp/user/config_detail.h deleted file mode 100644 index cfa91e3d..00000000 --- a/UnleashedRecomp/user/config_detail.h +++ /dev/null @@ -1,440 +0,0 @@ -#pragma once - -#define CONFIG_LOCALE std::unordered_map> -#define CONFIG_ENUM_LOCALE(type) std::unordered_map>> - -#define CONFIG_DEFINE(section, type, name, defaultValue) \ - static inline ConfigDef name{section, #name, defaultValue}; - -#define CONFIG_DEFINE_LOCALISED(section, type, name, defaultValue) \ - static CONFIG_LOCALE g_##name##_locale; \ - static inline ConfigDef name{section, #name, &g_##name##_locale, defaultValue}; - -#define CONFIG_DEFINE_ENUM(section, type, name, defaultValue) \ - static inline ConfigDef name{section, #name, defaultValue, &g_##type##_template}; - -#define CONFIG_DEFINE_ENUM_LOCALISED(section, type, name, defaultValue) \ - static CONFIG_LOCALE g_##name##_locale; \ - static CONFIG_ENUM_LOCALE(type) g_##type##_locale; \ - static inline ConfigDef name{section, #name, &g_##name##_locale, defaultValue, &g_##type##_template, &g_##type##_locale}; - -#define CONFIG_DEFINE_CALLBACK(section, type, name, defaultValue, readCallback) \ - static CONFIG_LOCALE g_##name##_locale; \ - static inline ConfigDef name{section, #name, defaultValue, [](ConfigDef* def) readCallback}; - -#define CONFIG_DEFINE_ENUM_TEMPLATE(type) \ - inline std::unordered_map g_##type##_template = - -#define WINDOWPOS_CENTRED 0x2FFF0000 - -enum class ELanguage : uint32_t -{ - English = 1, - Japanese, - German, - French, - Spanish, - Italian -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(ELanguage) -{ - { "English", ELanguage::English }, - { "Japanese", ELanguage::Japanese }, - { "German", ELanguage::German }, - { "French", ELanguage::French }, - { "Spanish", ELanguage::Spanish }, - { "Italian", ELanguage::Italian } -}; - -enum class EUnleashGaugeBehaviour : uint32_t -{ - Original, - Revised -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EUnleashGaugeBehaviour) -{ - { "Original", EUnleashGaugeBehaviour::Original }, - { "Revised", EUnleashGaugeBehaviour::Revised } -}; - -enum class ETimeOfDayTransition : uint32_t -{ - Xbox, - PlayStation -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(ETimeOfDayTransition) -{ - { "Xbox", ETimeOfDayTransition::Xbox }, - { "PlayStation", ETimeOfDayTransition::PlayStation } -}; - -enum class EControllerIcons : uint32_t -{ - Auto, - Xbox, - PlayStation -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EControllerIcons) -{ - { "Auto", EControllerIcons::Auto }, - { "Xbox", EControllerIcons::Xbox }, - { "PlayStation", EControllerIcons::PlayStation } -}; - -enum class EVoiceLanguage : uint32_t -{ - English, - Japanese -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EVoiceLanguage) -{ - { "English", EVoiceLanguage::English }, - { "Japanese", EVoiceLanguage::Japanese } -}; - -enum class EGraphicsAPI : uint32_t -{ -#ifdef SWA_D3D12 - D3D12, -#endif - Vulkan -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EGraphicsAPI) -{ -#ifdef SWA_D3D12 - { "D3D12", EGraphicsAPI::D3D12 }, -#endif - { "Vulkan", EGraphicsAPI::Vulkan } -}; - -enum class EWindowState : uint32_t -{ - Normal, - Maximised -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EWindowState) -{ - { "Normal", EWindowState::Normal }, - { "Maximised", EWindowState::Maximised }, - { "Maximized", EWindowState::Maximised } -}; - -enum class EAspectRatio : uint32_t -{ - Auto, - Square, - Widescreen -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EAspectRatio) -{ - { "Auto", EAspectRatio::Auto }, - { "4:3", EAspectRatio::Square }, - { "16:9", EAspectRatio::Widescreen } -}; - -enum class ETripleBuffering : uint32_t -{ - Auto, - On, - Off -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(ETripleBuffering) -{ - { "Auto", ETripleBuffering::Auto }, - { "On", ETripleBuffering::On }, - { "Off", ETripleBuffering::Off } -}; - -enum class EAntiAliasing : uint32_t -{ - None = 0, - MSAA2x = 2, - MSAA4x = 4, - MSAA8x = 8 -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EAntiAliasing) -{ - { "None", EAntiAliasing::None }, - { "2x MSAA", EAntiAliasing::MSAA2x }, - { "4x MSAA", EAntiAliasing::MSAA4x }, - { "8x MSAA", EAntiAliasing::MSAA8x } -}; - -enum class EShadowResolution : int32_t -{ - Original = -1, - x512 = 512, - x1024 = 1024, - x2048 = 2048, - x4096 = 4096, - x8192 = 8192 -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EShadowResolution) -{ - { "Original", EShadowResolution::Original }, - { "512", EShadowResolution::x512 }, - { "1024", EShadowResolution::x1024 }, - { "2048", EShadowResolution::x2048 }, - { "4096", EShadowResolution::x4096 }, - { "8192", EShadowResolution::x8192 }, -}; - -enum class EGITextureFiltering : uint32_t -{ - Bilinear, - Bicubic -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EGITextureFiltering) -{ - { "Bilinear", EGITextureFiltering::Bilinear }, - { "Bicubic", EGITextureFiltering::Bicubic } -}; - -enum class EDepthOfFieldQuality : uint32_t -{ - Auto, - Low, - Medium, - High, - Ultra -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EDepthOfFieldQuality) -{ - { "Auto", EDepthOfFieldQuality::Auto }, - { "Low", EDepthOfFieldQuality::Low }, - { "Medium", EDepthOfFieldQuality::Medium }, - { "High", EDepthOfFieldQuality::High }, - { "Ultra", EDepthOfFieldQuality::Ultra } -}; - -enum class EMotionBlur : uint32_t -{ - Off, - Original, - Enhanced -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EMotionBlur) -{ - { "Off", EMotionBlur::Off }, - { "Original", EMotionBlur::Original }, - { "Enhanced", EMotionBlur::Enhanced } -}; - -enum class EMovieScaleMode : uint32_t -{ - Stretch, - Fit, - Fill -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EMovieScaleMode) -{ - { "Stretch", EMovieScaleMode::Stretch }, - { "Fit", EMovieScaleMode::Fit }, - { "Fill", EMovieScaleMode::Fill } -}; - -enum class EUIScaleMode : uint32_t -{ - Stretch, - Edge, - Centre -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EUIScaleMode) -{ - { "Stretch", EUIScaleMode::Stretch }, - { "Edge", EUIScaleMode::Edge }, - { "Centre", EUIScaleMode::Centre }, - { "Center", EUIScaleMode::Centre } -}; - -class IConfigDef -{ -public: - virtual ~IConfigDef() = default; - virtual void ReadValue(toml::v3::ex::parse_result& toml) = 0; - virtual void MakeDefault() = 0; - virtual std::string_view GetSection() const = 0; - virtual std::string_view GetName() const = 0; - virtual std::string GetNameLocalised() const = 0; - virtual std::string GetDescription() const = 0; - virtual bool IsDefaultValue() const = 0; - virtual const void* GetValue() const = 0; - virtual std::string GetValueLocalised() const = 0; - virtual std::string GetValueDescription() const = 0; - virtual std::string GetDefinition(bool withSection = false) const = 0; - virtual std::string ToString(bool strWithQuotes = true) const = 0; - virtual void GetLocaleStrings(std::vector& localeStrings) const = 0; -}; - -template -class ConfigDef final : public IConfigDef -{ -public: - std::string Section{}; - std::string Name{}; - CONFIG_LOCALE* Locale{}; - T DefaultValue{}; - T Value{ DefaultValue }; - std::unordered_map* EnumTemplate; - std::map EnumTemplateReverse{}; - CONFIG_ENUM_LOCALE(T)* EnumLocale{}; - std::function*)> Callback; - - // CONFIG_DEFINE - ConfigDef(std::string section, std::string name, T defaultValue); - - // CONFIG_DEFINE_LOCALISED - ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue); - - // CONFIG_DEFINE_ENUM - ConfigDef(std::string section, std::string name, T defaultValue, std::unordered_map* enumTemplate); - - // CONFIG_DEFINE_ENUM_LOCALISED - ConfigDef(std::string section, std::string name, CONFIG_LOCALE* nameLocale, T defaultValue, std::unordered_map* enumTemplate, CONFIG_ENUM_LOCALE(T)* enumLocale); - - // CONFIG_DEFINE_CALLBACK - ConfigDef(std::string section, std::string name, T defaultValue, std::function*)> callback); - - void ReadValue(toml::v3::ex::parse_result& toml) override - { - if (auto pSection = toml[Section].as_table()) - { - const auto& section = *pSection; - - if constexpr (std::is_same::value) - { - Value = section[Name].value_or(DefaultValue); - } - else if constexpr (std::is_enum_v) - { - std::string value = section[Name].value_or(std::string()); - auto it = EnumTemplate->find(value); - if (it != EnumTemplate->end()) - { - Value = it->second; - } - else - { - Value = DefaultValue; - } - } - else - { - Value = section[Name].value_or(DefaultValue); - } - - if (Callback) - Callback(this); - } - } - - void MakeDefault() override - { - Value = DefaultValue; - } - - std::string_view GetSection() const override - { - return Section; - } - - std::string_view GetName() const override - { - return Name; - } - - std::string GetNameLocalised() const override; - - std::string GetDescription() const override; - - bool IsDefaultValue() const override - { - return Value == DefaultValue; - } - - const void* GetValue() const override - { - return &Value; - } - - std::string GetValueLocalised() const override; - - std::string GetValueDescription() const override; - - std::string GetDefinition(bool withSection = false) const override - { - std::string result; - - if (withSection) - result += "[" + Section + "]\n"; - - result += Name + " = " + ToString(); - - return result; - } - - std::string ToString(bool strWithQuotes = true) const override - { - std::string result = "N/A"; - - if constexpr (std::is_same_v) - { - result = fmt::format("{}", Value); - - if (strWithQuotes) - result = fmt::format("\"{}\"", result); - } - else if constexpr (std::is_enum_v) - { - auto it = EnumTemplateReverse.find(Value); - - if (it != EnumTemplateReverse.end()) - result = fmt::format("{}", it->second); - - if (strWithQuotes) - result = fmt::format("\"{}\"", result); - } - else - { - result = fmt::format("{}", Value); - } - - return result; - } - - void GetLocaleStrings(std::vector& localeStrings) const override; - - ConfigDef& operator=(const ConfigDef& other) - { - if (this != &other) - Value = other.Value; - - return *this; - } - - operator T() const - { - return Value; - } - - void operator=(const T& other) - { - Value = other; - } -}; diff --git a/UnleashedRecomp/user/paths.h b/UnleashedRecomp/user/paths.h index 88d6c53a..7eb7dd42 100644 --- a/UnleashedRecomp/user/paths.h +++ b/UnleashedRecomp/user/paths.h @@ -30,13 +30,12 @@ inline std::filesystem::path GetUserPath() if (homeDir != nullptr) { // Prefer to store in the .config directory if it exists. Use the home directory otherwise. - const std::string dirName = "." USER_DIRECTORY; std::filesystem::path homePath = homeDir; std::filesystem::path configPath = homePath / ".config"; if (std::filesystem::exists(configPath)) - userPath = configPath / dirName; + userPath = configPath / USER_DIRECTORY; else - userPath = homePath / dirName; + userPath = homePath / ("." USER_DIRECTORY); } #else static_assert(false, "GetUserPath() not implemented for this platform."); diff --git a/UnleashedRecompLib/CMakeLists.txt b/UnleashedRecompLib/CMakeLists.txt index f0cff971..98d41dd1 100644 --- a/UnleashedRecompLib/CMakeLists.txt +++ b/UnleashedRecompLib/CMakeLists.txt @@ -1,11 +1,17 @@ project("UnleashedRecompLib") add_compile_options( - "/fp:strict" - "-march=sandybridge" - "-fno-strict-aliasing" + -march=sandybridge + -mlzcnt + -fno-strict-aliasing ) +if (WIN32) + add_compile_options(/fp:strict) +else() + add_compile_options(-ffp-model=strict) +endif() + target_compile_definitions(PowerRecomp PRIVATE CONFIG_FILE_PATH=\"${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml\") set(SWA_PPC_RECOMPILED_SOURCES @@ -21,7 +27,7 @@ endforeach() add_custom_command( OUTPUT ${SWA_PPC_RECOMPILED_SOURCES} - COMMAND PowerRecomp + COMMAND $ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xex" "${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml" ) @@ -41,7 +47,7 @@ file(GLOB SHADER_RECOMP_SOURCES add_custom_command( OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp" - COMMAND ShaderRecomp + COMMAND $ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/private/shader.ar" ${SHADER_RECOMP_SOURCES} ${SHADER_RECOMP_INCLUDE} ) diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 914095fe..28f000da 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -3,5 +3,9 @@ set(MSDF_ATLAS_USE_SKIA OFF) set(MSDF_ATLAS_NO_ARTERY_FONT ON) set(MSDFGEN_DISABLE_PNG ON) -add_subdirectory(${SWA_THIRDPARTY_ROOT}/o1heap) -add_subdirectory(${SWA_THIRDPARTY_ROOT}/msdf-atlas-gen) +add_subdirectory("${SWA_THIRDPARTY_ROOT}/msdf-atlas-gen") +add_subdirectory("${SWA_THIRDPARTY_ROOT}/nativefiledialog-extended") +add_subdirectory("${SWA_THIRDPARTY_ROOT}/ogg") +add_subdirectory("${SWA_THIRDPARTY_ROOT}/o1heap") +add_subdirectory("${SWA_THIRDPARTY_ROOT}/SDL") +add_subdirectory("${SWA_THIRDPARTY_ROOT}/vorbis") diff --git a/thirdparty/D3D12MemoryAllocator b/thirdparty/D3D12MemoryAllocator new file mode 160000 index 00000000..e00c4a7c --- /dev/null +++ b/thirdparty/D3D12MemoryAllocator @@ -0,0 +1 @@ +Subproject commit e00c4a7c85cf9c28c6f4a6cc75032736f416410f diff --git a/thirdparty/SDL b/thirdparty/SDL new file mode 160000 index 00000000..1edaad17 --- /dev/null +++ b/thirdparty/SDL @@ -0,0 +1 @@ +Subproject commit 1edaad17218d67b567c149badce9ef0fc67f65fa diff --git a/thirdparty/Vulkan-Headers b/thirdparty/Vulkan-Headers new file mode 160000 index 00000000..14345dab --- /dev/null +++ b/thirdparty/Vulkan-Headers @@ -0,0 +1 @@ +Subproject commit 14345dab231912ee9601136e96ca67a6e1f632e7 diff --git a/thirdparty/VulkanMemoryAllocator b/thirdparty/VulkanMemoryAllocator new file mode 160000 index 00000000..1c35ba99 --- /dev/null +++ b/thirdparty/VulkanMemoryAllocator @@ -0,0 +1 @@ +Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39 diff --git a/thirdparty/concurrentqueue b/thirdparty/concurrentqueue new file mode 160000 index 00000000..6dd38b8a --- /dev/null +++ b/thirdparty/concurrentqueue @@ -0,0 +1 @@ +Subproject commit 6dd38b8a1dbaa7863aa907045f32308a56a6ff5d diff --git a/thirdparty/imgui b/thirdparty/imgui new file mode 160000 index 00000000..8199457a --- /dev/null +++ b/thirdparty/imgui @@ -0,0 +1 @@ +Subproject commit 8199457a7d9e453f8d3d9cadc14683fb54a858b5 diff --git a/thirdparty/magic_enum b/thirdparty/magic_enum new file mode 160000 index 00000000..1a1824df --- /dev/null +++ b/thirdparty/magic_enum @@ -0,0 +1 @@ +Subproject commit 1a1824df7ac798177a521eed952720681b0bf482 diff --git a/thirdparty/nativefiledialog-extended b/thirdparty/nativefiledialog-extended new file mode 160000 index 00000000..388549a5 --- /dev/null +++ b/thirdparty/nativefiledialog-extended @@ -0,0 +1 @@ +Subproject commit 388549a5badaa7cbd138f5f189f50c67d5bf060c diff --git a/thirdparty/ogg b/thirdparty/ogg new file mode 160000 index 00000000..7cf42ea1 --- /dev/null +++ b/thirdparty/ogg @@ -0,0 +1 @@ +Subproject commit 7cf42ea17aef7bc1b7b21af70724840a96c2e7d0 diff --git a/thirdparty/stb b/thirdparty/stb new file mode 160000 index 00000000..5c205738 --- /dev/null +++ b/thirdparty/stb @@ -0,0 +1 @@ +Subproject commit 5c205738c191bcb0abc65c4febfa9bd25ff35234 diff --git a/thirdparty/tiny-AES-c b/thirdparty/tiny-AES-c new file mode 160000 index 00000000..23856752 --- /dev/null +++ b/thirdparty/tiny-AES-c @@ -0,0 +1 @@ +Subproject commit 23856752fbd139da0b8ca6e471a13d5bcc99a08d diff --git a/thirdparty/unordered_dense b/thirdparty/unordered_dense new file mode 160000 index 00000000..d911053e --- /dev/null +++ b/thirdparty/unordered_dense @@ -0,0 +1 @@ +Subproject commit d911053e390816ecc5dedd5a9d6b4bb5ed92b4c9 diff --git a/thirdparty/vcpkg b/thirdparty/vcpkg index 19847ac3..b322364f 160000 --- a/thirdparty/vcpkg +++ b/thirdparty/vcpkg @@ -1 +1 @@ -Subproject commit 19847ac3d8cad7599e96bd531f9bc1f0ebae6131 +Subproject commit b322364f06308bdd24823f9d8f03fe0cc86fd46f diff --git a/thirdparty/volk b/thirdparty/volk new file mode 160000 index 00000000..447e21b5 --- /dev/null +++ b/thirdparty/volk @@ -0,0 +1 @@ +Subproject commit 447e21b5d92ed8d5271b0d39b071f938fcfa875f diff --git a/thirdparty/vorbis b/thirdparty/vorbis new file mode 160000 index 00000000..84c02369 --- /dev/null +++ b/thirdparty/vorbis @@ -0,0 +1 @@ +Subproject commit 84c023699cdf023a32fa4ded32019f194afcdad0 diff --git a/tools/PowerRecomp b/tools/PowerRecomp index 45c00cfe..14b7fd34 160000 --- a/tools/PowerRecomp +++ b/tools/PowerRecomp @@ -1 +1 @@ -Subproject commit 45c00cfec6c2ad141ebf8fce1f5dbcdde2816e94 +Subproject commit 14b7fd3445857a44ad91b832592cffb069451e4f diff --git a/tools/ShaderRecomp b/tools/ShaderRecomp index 4b69741e..cf44a5e6 160000 --- a/tools/ShaderRecomp +++ b/tools/ShaderRecomp @@ -1 +1 @@ -Subproject commit 4b69741e196e0a8aed9d51bbe0cf24019afab08e +Subproject commit cf44a5e6fb7c9931888ee4e6506109787141f87e diff --git a/tools/bc_diff/CMakeLists.txt b/tools/bc_diff/CMakeLists.txt index 5bba3025..cfe70d44 100644 --- a/tools/bc_diff/CMakeLists.txt +++ b/tools/bc_diff/CMakeLists.txt @@ -6,5 +6,4 @@ set(CMAKE_CXX_STANDARD 17) add_executable(bc_diff "bc_diff.cpp") add_compile_definitions(bc_diff PRIVATE _CRT_SECURE_NO_WARNINGS) -find_package(xxHash CONFIG REQUIRED) target_link_libraries(bc_diff PRIVATE xxHash::xxhash) diff --git a/tools/file_to_c/CMakeLists.txt b/tools/file_to_c/CMakeLists.txt index 96bfb044..6fbafba6 100644 --- a/tools/file_to_c/CMakeLists.txt +++ b/tools/file_to_c/CMakeLists.txt @@ -7,5 +7,4 @@ set(CMAKE_CXX_STANDARD 17) add_executable(file_to_c "file_to_c.cpp") -find_package(zstd CONFIG REQUIRED) -target_link_libraries(file_to_c PRIVATE $,zstd::libzstd_static,zstd::libzstd>) +target_link_libraries(file_to_c PRIVATE $,libzstd_static,libzstd_shared>) diff --git a/tools/file_to_c/file_to_c.cpp b/tools/file_to_c/file_to_c.cpp index 8a999784..cbd6f272 100644 --- a/tools/file_to_c/file_to_c.cpp +++ b/tools/file_to_c/file_to_c.cpp @@ -110,8 +110,8 @@ int main(int argc, const char** argv) { // Write decompressed size. if (!compressed_contents.empty()) { - output_c_file << "extern size_t " << array_name << "_uncompressed_size;\n"; - output_c_file << "size_t " << array_name << "_uncompressed_size = " << contents.size() << ";\n"; + output_c_file << "extern unsigned long long " << array_name << "_uncompressed_size;\n"; + output_c_file << "unsigned long long " << array_name << "_uncompressed_size = " << contents.size() << ";\n"; } } @@ -126,7 +126,7 @@ int main(int argc, const char** argv) { // Write decompressed size. if (!compressed_contents.empty()) { - output_h_file << "extern size_t " << array_name << "_uncompressed_size;\n"; + output_h_file << "extern unsigned long long " << array_name << "_uncompressed_size;\n"; } output_h_file << diff --git a/tools/fshasher/CMakeLists.txt b/tools/fshasher/CMakeLists.txt index ca85067e..f30e4852 100644 --- a/tools/fshasher/CMakeLists.txt +++ b/tools/fshasher/CMakeLists.txt @@ -2,6 +2,4 @@ project("fshasher") add_executable(fshasher "fshasher.cpp") -find_package(xxHash CONFIG REQUIRED) - target_link_libraries(fshasher PRIVATE xxHash::xxhash) diff --git a/vcpkg.json b/vcpkg.json index 7c6b69dd..d930d54c 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,5 +1,5 @@ { - "builtin-baseline": "e63bd09dc0b7204467705c1c7c71d0e2a3f8860b", + "builtin-baseline": "b322364f06308bdd24823f9d8f03fe0cc86fd46f", "dependencies": [ { "name": "directx-headers", @@ -9,34 +9,7 @@ "name": "directx12-agility", "platform": "windows" }, - { - "name": "d3d12-memory-allocator", - "platform": "windows" - }, - { - "name": "pkgconf", - "platform": "windows" - }, - { - "name": "imgui", - "features": [ "sdl2-binding" ] - }, "directx-dxc", - "sdl2", - "unordered-dense", - "volk", - "vulkan-headers", - "vulkan-memory-allocator", - "xxhash", - "tomlplusplus", - "zstd", - "stb", - "concurrentqueue", - "tiny-aes-c", - "magic-enum", - "nativefiledialog-extended", - "freetype", - "libvorbis", - "fmt" + "freetype" ] }