mirror of
				https://github.com/hedge-dev/UnleashedRecomp.git
				synced 2025-10-30 07:11:05 +00:00 
			
		
		
		
	Compare commits
	
		
			2 commits
		
	
	
		
			5d3ab002ff
			...
			d739f3b35d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d739f3b35d | ||
|   | ada0db62dc | 
					 47 changed files with 891 additions and 140 deletions
				
			
		
							
								
								
									
										77
									
								
								.github/workflows/validate.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								.github/workflows/validate.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -210,3 +210,80 @@ jobs: | |||
|         with: | ||||
|           name: UnleashedRecomp-Flatpak | ||||
|           path: ./${{ env.FLATPAK_ID }}.flatpak | ||||
|   build-macos: | ||||
|     name: Build macOS | ||||
|     runs-on: macos-15 | ||||
|     strategy: | ||||
|       matrix: | ||||
|         arch: [ "arm64" ] | ||||
|         preset: ["macos-debug", "macos-release", "macos-relwithdebinfo"] | ||||
|     env: | ||||
|       CMAKE_PRESET: ${{ matrix.preset }} | ||||
| 
 | ||||
|     steps: | ||||
|       - name: Checkout Repository | ||||
|         uses: actions/checkout@v4 | ||||
|         with: | ||||
|           submodules: recursive | ||||
| 
 | ||||
|       - name: Checkout Private Repository | ||||
|         uses: actions/checkout@v4 | ||||
|         with: | ||||
|           repository: ${{ secrets.ASSET_REPO }} | ||||
|           token: ${{ secrets.ASSET_REPO_TOKEN }} | ||||
|           path: ./private | ||||
| 
 | ||||
|       - name: Setup latest Xcode | ||||
|         uses: maxim-lobanov/setup-xcode@v1 | ||||
|         with: | ||||
|           xcode-version: latest-stable | ||||
| 
 | ||||
|       - name: Setup ccache | ||||
|         uses: hendrikmuhs/ccache-action@v1.2 | ||||
|         with: | ||||
|           key: ccache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.preset }} | ||||
| 
 | ||||
|       - name: Cache vcpkg | ||||
|         uses: actions/cache@v4 | ||||
|         with: | ||||
|           path: | | ||||
|             ./thirdparty/vcpkg/downloads | ||||
|             ./thirdparty/vcpkg/packages | ||||
|           key: vcpkg-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('vcpkg.json') }} | ||||
|           restore-keys: | | ||||
|             vcpkg-${{ runner.os }}-${{ matrix.arch }}- | ||||
| 
 | ||||
|       - name: Install Dependencies (macOS) | ||||
|         run: | | ||||
|           brew install ninja | ||||
| 
 | ||||
|       - name: Cache ccache Directory | ||||
|         uses: actions/cache@v4 | ||||
|         with: | ||||
|           path: /tmp/ccache | ||||
|           key: ccache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.preset }} | ||||
| 
 | ||||
|       - name: Prepare Project | ||||
|         run: | | ||||
|           cp ./private/* ./UnleashedRecompLib/private | ||||
| 
 | ||||
|       - name: Configure Project | ||||
|         env: | ||||
|           CCACHE_DIR: /tmp/ccache | ||||
|         run: cmake . --preset ${{ env.CMAKE_PRESET }} -DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch }} -DSDL2MIXER_VORBIS=VORBISFILE -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache | ||||
| 
 | ||||
|       - name: Build Project | ||||
|         env: | ||||
|           CCACHE_DIR: /tmp/ccache | ||||
|         run: cmake --build ./out/build/${{ env.CMAKE_PRESET }} --target UnleashedRecomp | ||||
| 
 | ||||
|       - name: Pack Release | ||||
|         run: | | ||||
|           codesign --deep -fs - "./out/build/${{ env.CMAKE_PRESET }}/UnleashedRecomp/Unleashed Recompiled.app" | ||||
|           tar -czf UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}.tar.gz -C ./out/build/${{ env.CMAKE_PRESET }}/UnleashedRecomp "Unleashed Recompiled.app" | ||||
| 
 | ||||
|       - name: Upload Artifact | ||||
|         uses: actions/upload-artifact@v4 | ||||
|         with: | ||||
|           name: UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }} | ||||
|           path: UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}.tar.gz | ||||
|  |  | |||
							
								
								
									
										6
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							|  | @ -61,3 +61,9 @@ | |||
| [submodule "UnleashedRecomp/api"] | ||||
| 	path = UnleashedRecomp/api | ||||
| 	url = https://github.com/hedge-dev/SWA.git | ||||
| [submodule "thirdparty/MoltenVK/MoltenVK"] | ||||
| 	path = thirdparty/MoltenVK/MoltenVK | ||||
| 	url = https://github.com/KhronosGroup/MoltenVK.git | ||||
| [submodule "thirdparty/MoltenVK/SPIRV-Cross"] | ||||
| 	path = thirdparty/MoltenVK/SPIRV-Cross | ||||
| 	url = https://github.com/KhronosGroup/SPIRV-Cross.git | ||||
|  |  | |||
|  | @ -4,7 +4,6 @@ if(NOT DEFINED ENV{VCPKG_ROOT}) | |||
|     message(FATAL_ERROR "VCPKG_ROOT is not defined!") | ||||
| endif() | ||||
| 
 | ||||
| include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake) | ||||
| set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty) | ||||
| set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools) | ||||
| set(CMAKE_CXX_STANDARD 20) | ||||
|  | @ -18,16 +17,28 @@ endif() | |||
| 
 | ||||
| set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") | ||||
| 
 | ||||
| # Target Sandy Bridge for all projects | ||||
| add_compile_options( | ||||
|     -march=sandybridge | ||||
| ) | ||||
| project("UnleashedRecomp-ALL") | ||||
| 
 | ||||
| if (CMAKE_OSX_ARCHITECTURES) | ||||
|     set(UNLEASHED_RECOMP_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES}) | ||||
| elseif(CMAKE_SYSTEM_PROCESSOR) | ||||
|     set(UNLEASHED_RECOMP_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR}) | ||||
| else() | ||||
|     set(UNLEASHED_RECOMP_ARCHITECTURE ${CMAKE_HOST_SYSTEM_PROCESSOR}) | ||||
| endif() | ||||
| string(TOLOWER "${UNLEASHED_RECOMP_ARCHITECTURE}" UNLEASHED_RECOMP_ARCHITECTURE) | ||||
| message(STATUS "Detected architecture: ${UNLEASHED_RECOMP_ARCHITECTURE}") | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_ARCHITECTURE STREQUAL "x86_64" OR UNLEASHED_RECOMP_ARCHITECTURE STREQUAL "amd64") | ||||
|     # Target Sandy Bridge for all projects | ||||
|     add_compile_options( | ||||
|         -march=sandybridge | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| add_subdirectory(${UNLEASHED_RECOMP_THIRDPARTY_ROOT}) | ||||
| add_subdirectory(${UNLEASHED_RECOMP_TOOLS_ROOT}) | ||||
| 
 | ||||
| project("UnleashedRecomp-ALL") | ||||
| 
 | ||||
| # Include sub-projects. | ||||
| add_subdirectory("UnleashedRecompLib") | ||||
| add_subdirectory("UnleashedRecomp") | ||||
|  |  | |||
|  | @ -113,6 +113,58 @@ | |||
|                 "CMAKE_BUILD_TYPE": "Release", | ||||
|                 "CMAKE_INTERPROCEDURAL_OPTIMIZATION": true | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "macos-base", | ||||
|             "hidden": true, | ||||
|             "generator": "Ninja", | ||||
|             "binaryDir": "${sourceDir}/out/build/${presetName}", | ||||
|             "installDir": "${sourceDir}/out/install/${presetName}", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_TOOLCHAIN_FILE": { | ||||
|                     "value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", | ||||
|                     "type": "FILEPATH" | ||||
|                 }, | ||||
|                 "CMAKE_OSX_DEPLOYMENT_TARGET": "13.0" | ||||
|             }, | ||||
|             "environment": { | ||||
|                 "VCPKG_ROOT": "${sourceDir}/thirdparty/vcpkg" | ||||
|             }, | ||||
|             "condition": { | ||||
|                 "type": "equals", | ||||
|                 "lhs": "${hostSystemName}", | ||||
|                 "rhs": "Darwin" | ||||
|             }, | ||||
|             "vendor": { | ||||
|                 "microsoft.com/VisualStudioRemoteSettings/CMake/2.0": { | ||||
|                     "remoteSourceRootDir": "$env{HOME}/.vs/$ms{projectDirName}" | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "macos-debug", | ||||
|             "displayName": "macOS-Debug", | ||||
|             "inherits": "macos-base", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "Debug" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "macos-relwithdebinfo", | ||||
|             "displayName": "macOS-RelWithDebInfo", | ||||
|             "inherits": "macos-base", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "RelWithDebInfo" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "macos-release", | ||||
|             "displayName": "macOS-Release", | ||||
|             "inherits": "macos-base", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "Release", | ||||
|                 "CMAKE_INTERPROCEDURAL_OPTIMIZATION": true | ||||
|             } | ||||
|         } | ||||
|     ] | ||||
| } | ||||
|  |  | |||
|  | @ -97,6 +97,14 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") | |||
|         "os/linux/user_linux.cpp" | ||||
|         "os/linux/version_linux.cpp" | ||||
|     ) | ||||
| elseif (APPLE) | ||||
|     set(UNLEASHED_RECOMP_OS_CXX_SOURCES | ||||
|         "os/macos/logger_macos.cpp" | ||||
|         "os/macos/media_macos.cpp" | ||||
|         "os/macos/process_macos.cpp" | ||||
|         "os/macos/user_macos.cpp" | ||||
|         "os/macos/version_macos.cpp" | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| set(UNLEASHED_RECOMP_CPU_CXX_SOURCES | ||||
|  | @ -119,7 +127,7 @@ endif() | |||
| 
 | ||||
| set(UNLEASHED_RECOMP_APU_CXX_SOURCES | ||||
|     "apu/audio.cpp" | ||||
|     "apu/embedded_player.cpp" | ||||
|     "apu/embedded_player.cpp" | ||||
|     "apu/driver/sdl2_driver.cpp" | ||||
| ) | ||||
| 
 | ||||
|  | @ -149,16 +157,16 @@ set(UNLEASHED_RECOMP_PATCHES_CXX_SOURCES | |||
| 
 | ||||
| set(UNLEASHED_RECOMP_UI_CXX_SOURCES | ||||
|     "ui/achievement_menu.cpp" | ||||
|     "ui/achievement_overlay.cpp" | ||||
|     "ui/achievement_overlay.cpp" | ||||
|     "ui/black_bar.cpp" | ||||
|     "ui/button_guide.cpp" | ||||
|     "ui/fader.cpp" | ||||
|     "ui/game_window.cpp" | ||||
|     "ui/game_window.cpp" | ||||
|     "ui/imgui_utils.cpp" | ||||
|     "ui/installer_wizard.cpp" | ||||
|     "ui/message_window.cpp" | ||||
|     "ui/options_menu.cpp" | ||||
|     "ui/options_menu_thumbnails.cpp" | ||||
|     "ui/options_menu_thumbnails.cpp" | ||||
|     "ui/tv_static.cpp" | ||||
| ) | ||||
| 
 | ||||
|  | @ -180,7 +188,7 @@ set(UNLEASHED_RECOMP_INSTALL_CXX_SOURCES | |||
| set(UNLEASHED_RECOMP_USER_CXX_SOURCES | ||||
|     "user/achievement_data.cpp" | ||||
|     "user/achievement_manager.cpp" | ||||
|     "user/config.cpp" | ||||
|     "user/config.cpp" | ||||
|     "user/registry.cpp" | ||||
|     "user/paths.cpp" | ||||
|     "user/persistent_data.cpp" | ||||
|  | @ -231,7 +239,7 @@ set(UNLEASHED_RECOMP_CXX_SOURCES | |||
|     "app.cpp" | ||||
|     "exports.cpp" | ||||
|     "main.cpp" | ||||
|     "misc_impl.cpp" | ||||
|     "misc_impl.cpp" | ||||
|     "preload_executable.cpp" | ||||
|     "sdl_listener.cpp" | ||||
|     "stdafx.cpp" | ||||
|  | @ -250,11 +258,11 @@ set(UNLEASHED_RECOMP_CXX_SOURCES | |||
|     ${UNLEASHED_RECOMP_USER_CXX_SOURCES} | ||||
|     ${UNLEASHED_RECOMP_MOD_CXX_SOURCES} | ||||
|     ${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} | ||||
| ) | ||||
| ) | ||||
| 
 | ||||
| include("version.cmake") | ||||
| 
 | ||||
| set(VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt") | ||||
| include("version.cmake") | ||||
| 
 | ||||
| set(VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt") | ||||
| 
 | ||||
| # Only show Git info and build type if not Release. | ||||
| set(SHOW_GIT_INFO_AND_BUILD_TYPE 0) | ||||
|  | @ -270,53 +278,102 @@ GenerateVersionSources( | |||
|     BUILD_TYPE ${CMAKE_BUILD_TYPE} | ||||
|     SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|     SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
| ) | ||||
| ) | ||||
| 
 | ||||
| if (WIN32) | ||||
|     # Create binary version number for Win32 integer attributes. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         OUTPUT_CSV 1 | ||||
|         OUTPUT_VAR WIN32_VERSION_BINARY | ||||
|     ) | ||||
| 
 | ||||
|     # Create string version number for Win32 detailed attributes. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         BUILD_TYPE ${CMAKE_BUILD_TYPE} | ||||
|         SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|         SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|         OUTPUT_VAR WIN32_VERSION_STRING | ||||
|     ) | ||||
| 
 | ||||
|     # Create binary version number for Win32 integer attributes. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         OUTPUT_CSV 1 | ||||
|         OUTPUT_VAR WIN32_VERSION_BINARY | ||||
|     ) | ||||
| 
 | ||||
|     # Create string version number for Win32 detailed attributes. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         BUILD_TYPE ${CMAKE_BUILD_TYPE} | ||||
|         SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|         SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|         OUTPUT_VAR WIN32_VERSION_STRING | ||||
|     ) | ||||
| 
 | ||||
|     # Set Win32 icon path. | ||||
|     set(WIN32_ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico") | ||||
|     set(WIN32_ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico") | ||||
| 
 | ||||
|     configure_file("res/win32/res.rc.template" "${CMAKE_BINARY_DIR}/res.rc" @ONLY) | ||||
|     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") | ||||
| 
 | ||||
|     # Hide console for release configurations. | ||||
|     if (${CMAKE_BUILD_TYPE} MATCHES "Release") | ||||
|         target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup") | ||||
|     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") | ||||
| 
 | ||||
|     # Hide console for release configurations. | ||||
|     if (${CMAKE_BUILD_TYPE} MATCHES "Release") | ||||
|         target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup") | ||||
|     endif() | ||||
| elseif (APPLE) | ||||
|     # Create version number for app bundle. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         OUTPUT_VAR MACOS_BUNDLE_VERSION | ||||
|     ) | ||||
| 
 | ||||
|     add_executable(UnleashedRecomp MACOSX_BUNDLE | ||||
|         ${UNLEASHED_RECOMP_CXX_SOURCES} | ||||
|         res/macos/game_icon.icns | ||||
|     ) | ||||
|     set_source_files_properties(res/macos/game_icon.icns PROPERTIES | ||||
|         MACOSX_PACKAGE_LOCATION Resources) | ||||
|     set_target_properties(UnleashedRecomp PROPERTIES | ||||
|         OUTPUT_NAME "Unleashed Recompiled" | ||||
|         MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/res/macos/MacOSXBundleInfo.plist.in | ||||
|         MACOSX_BUNDLE_GUI_IDENTIFIER hedge-dev.UnleashedRecomp | ||||
|         MACOSX_BUNDLE_BUNDLE_NAME "Unleashed Recompiled" | ||||
|         MACOSX_BUNDLE_BUNDLE_VERSION ${MACOS_BUNDLE_VERSION} | ||||
|         MACOSX_BUNDLE_SHORT_VERSION_STRING ${MACOS_BUNDLE_VERSION} | ||||
|         MACOSX_BUNDLE_ICON_FILE "game_icon.icns" | ||||
|     ) | ||||
| 
 | ||||
|     # Linking with MoltenVK directly would prevent using the system Vulkan loader to load with debug layers. | ||||
|     # Instead, copy the MoltenVK dylib to the app bundle along with an ICD file for the loader to find it. | ||||
|     # In the event the loader is not installed, the MoltenVK dylib can still be picked up directly in the app bundle. | ||||
|     set(MVK_BUNDLED_PATH "Resources/vulkan/icd.d") | ||||
|     set(MVK_DST "${CMAKE_CURRENT_BINARY_DIR}/Unleashed Recompiled.app/Contents/${MVK_BUNDLED_PATH}") | ||||
|     set_property(TARGET UnleashedRecomp APPEND PROPERTY BUILD_RPATH "@executable_path/../${MVK_BUNDLED_PATH}") | ||||
| 
 | ||||
|     set(MVK_ICD_SRC "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/MoltenVK/MoltenVK/MoltenVK/icd/MoltenVK_icd.json") | ||||
|     set(MVK_ICD_DST "${MVK_DST}/MoltenVK_icd.json") | ||||
|     set(MVK_DYLIB_SRC "${CMAKE_BINARY_DIR}/thirdparty/MoltenVK/libMoltenVK.dylib") | ||||
|     set(MVK_DYLIB_DST "${MVK_DST}/libMoltenVK.dylib") | ||||
| 
 | ||||
|     add_custom_command( | ||||
|         OUTPUT ${MVK_DST} | ||||
|         COMMAND ${CMAKE_COMMAND} -E make_directory ${MVK_DST}) | ||||
|     add_custom_command( | ||||
|         OUTPUT ${MVK_ICD_DST} | ||||
|         DEPENDS ${MVK_ICD_SRC} ${MVK_DST} | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy ${MVK_ICD_SRC} ${MVK_ICD_DST}) | ||||
|     add_custom_command( | ||||
|         OUTPUT ${MVK_DYLIB_DST} | ||||
|         DEPENDS ${MVK_DYLIB_SRC} ${MVK_DST} | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST}) | ||||
|     add_custom_target(CopyMoltenVK DEPENDS ${MVK_ICD_DST} ${MVK_DYLIB_DST}) | ||||
|     add_dependencies(CopyMoltenVK MoltenVK) | ||||
|     add_dependencies(UnleashedRecomp CopyMoltenVK) | ||||
| else() | ||||
|     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES}) | ||||
| endif() | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_FLATPAK) | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||
|         "UNLEASHED_RECOMP_FLATPAK" | ||||
|         "GAME_INSTALL_DIRECTORY=\"/var/data\"" | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||
|         "UNLEASHED_RECOMP_FLATPAK" | ||||
|         "GAME_INSTALL_DIRECTORY=\"/var/data\"" | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_D3D12) | ||||
|     find_package(directx-headers CONFIG REQUIRED) | ||||
|     find_package(directx12-agility CONFIG REQUIRED) | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||
|         UNLEASHED_RECOMP_D3D12 | ||||
|         D3D12MA_USING_DIRECTX_HEADERS | ||||
|         D3D12MA_OPTIONS16_SUPPORTED | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||
|         UNLEASHED_RECOMP_D3D12 | ||||
|         D3D12MA_USING_DIRECTX_HEADERS | ||||
|         D3D12MA_OPTIONS16_SUPPORTED | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
|  | @ -324,19 +381,17 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux") | |||
|     target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED) | ||||
| endif() | ||||
| 
 | ||||
| find_package(directx-dxc REQUIRED) | ||||
| find_package(CURL REQUIRED) | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_D3D12) | ||||
|     file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) | ||||
|     add_custom_command(TARGET UnleashedRecomp POST_BUILD | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> ${CMAKE_CURRENT_BINARY_DIR}/D3D12 | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> ${CMAKE_CURRENT_BINARY_DIR}/D3D12 | ||||
|        COMMAND_EXPAND_LISTS | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12 | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12 | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectXShaderCompiler,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp> | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DXIL,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp> | ||||
|         COMMAND_EXPAND_LISTS | ||||
|     ) | ||||
|      | ||||
|     find_file(DIRECTX_DXIL_LIBRARY "dxil.dll") | ||||
|     file(COPY ${DIRECTX_DXIL_LIBRARY} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) | ||||
| 
 | ||||
|     target_link_libraries(UnleashedRecomp PRIVATE | ||||
|         Microsoft::DirectX-Headers  | ||||
|  | @ -348,18 +403,17 @@ if (UNLEASHED_RECOMP_D3D12) | |||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| file(CHMOD ${DIRECTX_DXC_TOOL} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) | ||||
| 
 | ||||
| if (WIN32) | ||||
|     target_link_libraries(UnleashedRecomp PRIVATE | ||||
|         comctl32 | ||||
|         comctl32 | ||||
|         dwmapi | ||||
|         ntdll | ||||
|         ntdll | ||||
|         Shcore | ||||
|         Synchronization | ||||
|         winmm | ||||
|         winmm | ||||
|         windowsapp | ||||
|     ) | ||||
| endif() | ||||
| endif() | ||||
| 
 | ||||
| target_link_libraries(UnleashedRecomp PRIVATE | ||||
|     fmt::fmt | ||||
|  | @ -410,16 +464,16 @@ function(compile_shader FILE_PATH TARGET_NAME) | |||
| endfunction() | ||||
| 
 | ||||
| function(compile_vertex_shader FILE_PATH) | ||||
|     compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y) | ||||
|     compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y -DUNLEASHED_RECOMP) | ||||
| endfunction() | ||||
| 
 | ||||
| function(compile_pixel_shader FILE_PATH) | ||||
|     compile_shader(${FILE_PATH} ps_6_0) | ||||
|     compile_shader(${FILE_PATH} ps_6_0 -DUNLEASHED_RECOMP) | ||||
| endfunction() | ||||
| 
 | ||||
| compile_pixel_shader(blend_color_alpha_ps) | ||||
| compile_vertex_shader(copy_vs) | ||||
| compile_pixel_shader(copy_color_ps) | ||||
| compile_pixel_shader(blend_color_alpha_ps) | ||||
| compile_vertex_shader(copy_vs) | ||||
| compile_pixel_shader(copy_color_ps) | ||||
| compile_pixel_shader(copy_depth_ps) | ||||
| compile_pixel_shader(csd_filter_ps) | ||||
| compile_vertex_shader(csd_no_tex_vs) | ||||
|  | @ -433,7 +487,7 @@ 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_vertex_shader(movie_vs) | ||||
| compile_pixel_shader(resolve_msaa_color_2x) | ||||
| compile_pixel_shader(resolve_msaa_color_4x) | ||||
| compile_pixel_shader(resolve_msaa_color_8x) | ||||
|  | @ -443,7 +497,7 @@ compile_pixel_shader(resolve_msaa_depth_8x) | |||
| 
 | ||||
| set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") | ||||
| set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") | ||||
| 
 | ||||
| 
 | ||||
| ## Miscellaneous ## | ||||
| 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") | ||||
|  | @ -455,7 +509,7 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/co | |||
| 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.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select.dds" ARRAY_NAME "g_select" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/light.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/light.dds" ARRAY_NAME "g_light" COMPRESSION_TYPE "zstd") | ||||
| 
 | ||||
| 
 | ||||
| ## Installer ## | ||||
| 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") | ||||
|  | @ -467,23 +521,23 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/in | |||
| 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/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd") | ||||
| 
 | ||||
| ## Options Menu ## | ||||
| 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_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input_ps.dds" ARRAY_NAME "g_allow_background_input_ps" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input_xb.dds" ARRAY_NAME "g_allow_background_input_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" ARRAY_NAME "g_antialiasing_none" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" ARRAY_NAME "g_antialiasing_2x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" ARRAY_NAME "g_antialiasing_4x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" ARRAY_NAME "g_antialiasing_none" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" ARRAY_NAME "g_antialiasing_2x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" ARRAY_NAME "g_antialiasing_4x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_8x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_8x.dds" ARRAY_NAME "g_antialiasing_8x" 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/channel_stereo.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_stereo.dds" ARRAY_NAME "g_channel_stereo" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_surround.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_surround.dds" ARRAY_NAME "g_channel_surround" 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/channel_stereo.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_stereo.dds" ARRAY_NAME "g_channel_stereo" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_surround.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_surround.dds" ARRAY_NAME "g_channel_surround" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_ps.dds" ARRAY_NAME "g_control_tutorial_ps" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" ARRAY_NAME "g_control_tutorial_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" ARRAY_NAME "g_control_tutorial_xb" 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") | ||||
|  | @ -499,7 +553,7 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/op | |||
| 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_fit.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" ARRAY_NAME "g_movie_scale_fit" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" ARRAY_NAME "g_movie_scale_fit" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fill.dds" ARRAY_NAME "g_movie_scale_fill" 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") | ||||
|  | @ -508,34 +562,34 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/op | |||
| 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/time_transition_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_ps.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/time_transition_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_ps.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/time_transition_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_xb.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/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_alignment_centre.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" ARRAY_NAME "g_ui_alignment_centre" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" ARRAY_NAME "g_ui_alignment_centre" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_alignment_edge.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_edge.dds" ARRAY_NAME "g_ui_alignment_edge" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vertical_camera.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vertical_camera.dds" ARRAY_NAME "g_vertical_camera" 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/vibration_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_ps.dds" ARRAY_NAME "g_vibration_ps" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_xb.dds" ARRAY_NAME "g_vibration_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_on.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_on.dds" ARRAY_NAME "g_vsync_on" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_xb.dds" ARRAY_NAME "g_vibration_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_on.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_on.dds" ARRAY_NAME "g_vsync_on" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_off.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_off.dds" ARRAY_NAME "g_vsync_off" 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.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" ARRAY_NAME "g_xbox_color_correction" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static.dds" ARRAY_NAME "g_options_static" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static.dds" ARRAY_NAME "g_options_static" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static_flash.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static_flash.dds" ARRAY_NAME "g_options_static_flash" COMPRESSION_TYPE "zstd") | ||||
| 
 | ||||
| 
 | ||||
| ## Game Icon ## | ||||
| 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}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night") | ||||
| 
 | ||||
| ## Audio ## | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/music/installer.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/music/installer.ogg" ARRAY_NAME "g_installer_music") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/music/installer.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/music/installer.ogg" ARRAY_NAME "g_installer_music") | ||||
| 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") | ||||
| 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") | ||||
|  |  | |||
|  | @ -40,29 +40,101 @@ GuestThreadContext::~GuestThreadContext() | |||
|     g_userHeap.Free(thread); | ||||
| } | ||||
| 
 | ||||
| #ifdef USE_PTHREAD | ||||
| static size_t GetStackSize() | ||||
| { | ||||
|     // Cache as this should not change.
 | ||||
|     static size_t stackSize = 0; | ||||
|     if (stackSize == 0) | ||||
|     { | ||||
|         // 8 MiB is a typical default.
 | ||||
|         constexpr auto defaultSize = 8 * 1024 * 1024; | ||||
|         struct rlimit lim; | ||||
|         const auto ret = getrlimit(RLIMIT_STACK, &lim); | ||||
|         if (ret == 0 && lim.rlim_cur < defaultSize) | ||||
|         { | ||||
|             // Use what the system allows.
 | ||||
|             stackSize = lim.rlim_cur; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             stackSize = defaultSize; | ||||
|         } | ||||
|     } | ||||
|     return stackSize; | ||||
| } | ||||
| 
 | ||||
| static void* GuestThreadFunc(void* arg) | ||||
| { | ||||
|     GuestThreadHandle* hThread = (GuestThreadHandle*)arg; | ||||
| #else | ||||
| static void GuestThreadFunc(GuestThreadHandle* hThread) | ||||
| { | ||||
| #endif | ||||
|     hThread->suspended.wait(true); | ||||
|     GuestThread::Start(hThread->params); | ||||
| #ifdef USE_PTHREAD | ||||
|     return nullptr; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| GuestThreadHandle::GuestThreadHandle(const GuestThreadParams& params) | ||||
|     : params(params), suspended((params.flags & 0x1) != 0), thread(GuestThreadFunc, this) | ||||
|     : params(params), suspended((params.flags & 0x1) != 0) | ||||
| #ifdef USE_PTHREAD | ||||
| { | ||||
|     pthread_attr_t attr; | ||||
|     pthread_attr_init(&attr); | ||||
|     pthread_attr_setstacksize(&attr, GetStackSize()); | ||||
|     const auto ret = pthread_create(&thread, &attr, GuestThreadFunc, this); | ||||
|     if (ret != 0) { | ||||
|         fprintf(stderr, "pthread_create failed with error code 0x%X.\n", ret); | ||||
|         return; | ||||
|     } | ||||
| } | ||||
| #else | ||||
|       , thread(GuestThreadFunc, this) | ||||
| { | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| GuestThreadHandle::~GuestThreadHandle() | ||||
| { | ||||
| #ifdef USE_PTHREAD | ||||
|     pthread_join(thread, nullptr); | ||||
| #else | ||||
|     if (thread.joinable()) | ||||
|         thread.join(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| template <typename ThreadType> | ||||
| static uint32_t CalcThreadId(const ThreadType& id) | ||||
| { | ||||
|     if constexpr (sizeof(id) == 4) | ||||
|         return *reinterpret_cast<const uint32_t*>(&id); | ||||
|     else | ||||
|         return XXH32(&id, sizeof(id), 0); | ||||
| } | ||||
| 
 | ||||
| uint32_t GuestThreadHandle::GetThreadId() const | ||||
| { | ||||
| #ifdef USE_PTHREAD | ||||
|     return CalcThreadId(thread); | ||||
| #else | ||||
|     return CalcThreadId(thread.get_id()); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| uint32_t GuestThreadHandle::Wait(uint32_t timeout) | ||||
| { | ||||
|     assert(timeout == INFINITE); | ||||
| 
 | ||||
| #ifdef USE_PTHREAD | ||||
|     pthread_join(thread, nullptr); | ||||
| #else | ||||
|     if (thread.joinable()) | ||||
|         thread.join(); | ||||
| #endif | ||||
| 
 | ||||
|     return STATUS_WAIT_0; | ||||
| } | ||||
|  | @ -80,27 +152,25 @@ uint32_t GuestThread::Start(const GuestThreadParams& params) | |||
|     return ctx.ppcContext.r3.u32; | ||||
| } | ||||
| 
 | ||||
| static uint32_t GetThreadId(const std::thread::id& id) | ||||
| { | ||||
|     if constexpr (sizeof(id) == 4) | ||||
|         return *reinterpret_cast<const uint32_t*>(&id); | ||||
|     else | ||||
|         return XXH32(&id, sizeof(id), 0); | ||||
| } | ||||
| 
 | ||||
| GuestThreadHandle* GuestThread::Start(const GuestThreadParams& params, uint32_t* threadId) | ||||
| { | ||||
|     auto hThread = CreateKernelObject<GuestThreadHandle>(params); | ||||
| 
 | ||||
|     if (threadId != nullptr) | ||||
|         *threadId = GetThreadId(hThread->thread.get_id()); | ||||
|     { | ||||
|         *threadId = hThread->GetThreadId(); | ||||
|     } | ||||
| 
 | ||||
|     return hThread; | ||||
| } | ||||
| 
 | ||||
| uint32_t GuestThread::GetCurrentThreadId() | ||||
| { | ||||
|     return GetThreadId(std::this_thread::get_id()); | ||||
| #ifdef USE_PTHREAD | ||||
|     return CalcThreadId(pthread_self()); | ||||
| #else | ||||
|     return CalcThreadId(std::this_thread::get_id()); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void GuestThread::SetLastError(uint32_t error) | ||||
|  |  | |||
|  | @ -2,6 +2,15 @@ | |||
| 
 | ||||
| #include <kernel/xdm.h> | ||||
| 
 | ||||
| // Use pthreads directly on macOS to be able to increase default stack size.
 | ||||
| #ifdef __APPLE__ | ||||
| #define USE_PTHREAD 1 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef USE_PTHREAD | ||||
| #include <pthread.h> | ||||
| #endif | ||||
| 
 | ||||
| #define CURRENT_THREAD_HANDLE uint32_t(-2) | ||||
| 
 | ||||
| struct GuestThreadContext | ||||
|  | @ -24,11 +33,17 @@ struct GuestThreadHandle : KernelObject | |||
| { | ||||
|     GuestThreadParams params; | ||||
|     std::atomic<bool> suspended; | ||||
| #ifdef USE_PTHREAD | ||||
|     pthread_t thread; | ||||
| #else | ||||
|     std::thread thread; | ||||
| #endif | ||||
| 
 | ||||
|     GuestThreadHandle(const GuestThreadParams& params); | ||||
|     ~GuestThreadHandle() override; | ||||
| 
 | ||||
|     uint32_t GetThreadId() const; | ||||
| 
 | ||||
|     uint32_t Wait(uint32_t timeout) override; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -3437,6 +3437,7 @@ namespace plume { | |||
|                 adapter = adapterOption; | ||||
|                 d3d = deviceOption; | ||||
|                 shaderModel = dataShaderModel.HighestShaderModel; | ||||
|                 capabilities.geometryShader = true; | ||||
|                 capabilities.raytracing = rtSupportOption; | ||||
|                 capabilities.raytracingStateUpdate = rtStateUpdateSupportOption; | ||||
|                 capabilities.sampleLocations = samplePositionsOption; | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ | |||
| #undef ControlMask | ||||
| #undef Success | ||||
| #elif defined(__APPLE__) | ||||
| typedef struct _NSWindow NSWindow; | ||||
| #include <SDL.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifdef SDL_VULKAN_ENABLED | ||||
|  | @ -52,7 +52,9 @@ namespace plume { | |||
|     }; | ||||
| #elif defined(__APPLE__) | ||||
|     struct RenderWindow { | ||||
|         NSWindow* window; | ||||
|         SDL_Window* window; | ||||
|         void* view; | ||||
| 
 | ||||
|         bool operator==(const struct RenderWindow& rhs) const { | ||||
|             return window == rhs.window; | ||||
|         } | ||||
|  | @ -1784,6 +1786,9 @@ namespace plume { | |||
|     }; | ||||
| 
 | ||||
|     struct RenderDeviceCapabilities { | ||||
|         // Geometry shaders.
 | ||||
|         bool geometryShader = false; | ||||
| 
 | ||||
|         // Raytracing.
 | ||||
|         bool raytracing = false; | ||||
|         bool raytracingStateUpdate = false; | ||||
|  |  | |||
|  | @ -51,13 +51,18 @@ namespace plume { | |||
|         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, | ||||
| #   elif defined(__linux__) | ||||
|         VK_KHR_XLIB_SURFACE_EXTENSION_NAME, | ||||
| #   elif defined(__APPLE__) | ||||
|         VK_EXT_METAL_SURFACE_EXTENSION_NAME, | ||||
| #   endif | ||||
|     }; | ||||
| 
 | ||||
|     static const std::unordered_set<std::string> OptionalInstanceExtensions = { | ||||
|         // No optional instance extensions yet.
 | ||||
| #   if defined(__APPLE__) | ||||
|         // Tells the system Vulkan loader to enumerate portability drivers, if supported.
 | ||||
|         VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, | ||||
| #   endif | ||||
|     }; | ||||
|      | ||||
| 
 | ||||
|     static const std::unordered_set<std::string> RequiredDeviceExtensions = { | ||||
|         VK_KHR_SWAPCHAIN_EXTENSION_NAME, | ||||
|         VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, | ||||
|  | @ -79,6 +84,8 @@ namespace plume { | |||
|         VK_KHR_PRESENT_ID_EXTENSION_NAME, | ||||
|         VK_KHR_PRESENT_WAIT_EXTENSION_NAME, | ||||
|         VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME, | ||||
|         // Vulkan spec requires this to be enabled if supported by the driver.
 | ||||
|         VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME, | ||||
|     }; | ||||
| 
 | ||||
|     // Common functions.
 | ||||
|  | @ -567,14 +574,16 @@ namespace plume { | |||
|         } | ||||
|     } | ||||
|      | ||||
|     static VkPipelineStageFlags toStageFlags(RenderBarrierStages stages, bool rtSupported) { | ||||
|     static VkPipelineStageFlags toStageFlags(RenderBarrierStages stages, bool geometrySupported, bool rtSupported) { | ||||
|         VkPipelineStageFlags flags = 0; | ||||
| 
 | ||||
|         if (stages & RenderBarrierStage::GRAPHICS) { | ||||
|             flags |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; | ||||
|             flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; | ||||
|             flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT; | ||||
|             flags |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; | ||||
|             if (geometrySupported) { | ||||
|                 flags |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; | ||||
|             } | ||||
|             flags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; | ||||
|             flags |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; | ||||
|             flags |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; | ||||
|  | @ -2051,6 +2060,19 @@ namespace plume { | |||
|             fprintf(stderr, "vkCreateXlibSurfaceKHR failed with error code 0x%X.\n", res); | ||||
|             return; | ||||
|         } | ||||
| #   elif defined(__APPLE__) | ||||
|         assert(renderWindow.window != 0); | ||||
|         assert(renderWindow.view != 0); | ||||
|         VkMetalSurfaceCreateInfoEXT surfaceCreateInfo = {}; | ||||
|         surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; | ||||
|         surfaceCreateInfo.pLayer = renderWindow.view; | ||||
| 
 | ||||
|         VulkanInterface *renderInterface = commandQueue->device->renderInterface; | ||||
|         res = vkCreateMetalSurfaceEXT(renderInterface->instance, &surfaceCreateInfo, nullptr, &surface); | ||||
|         if (res != VK_SUCCESS) { | ||||
|             fprintf(stderr, "vkCreateMetalSurfaceEXT failed with error code 0x%X.\n", res); | ||||
|             return; | ||||
|         } | ||||
| #   endif | ||||
| 
 | ||||
|         VkBool32 presentSupported = false; | ||||
|  | @ -2191,7 +2213,14 @@ namespace plume { | |||
|         } | ||||
| 
 | ||||
|         // Handle the error silently.
 | ||||
| #if defined(__APPLE__) | ||||
|         // Under MoltenVK, VK_SUBOPTIMAL_KHR does not result in a valid state for rendering. We intentionally
 | ||||
|         // only check for this error during present to avoid having to synchronize manually against the semaphore
 | ||||
|         // signalled by vkAcquireNextImageKHR.
 | ||||
|         if (res != VK_SUCCESS) { | ||||
| #else | ||||
|         if ((res != VK_SUCCESS) && (res != VK_SUBOPTIMAL_KHR)) { | ||||
| #endif | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|  | @ -2360,6 +2389,8 @@ namespace plume { | |||
|         // The attributes width and height members do not include the border.
 | ||||
|         dstWidth = attributes.width; | ||||
|         dstHeight = attributes.height; | ||||
| #   elif defined(__APPLE__) | ||||
|         SDL_GetWindowSizeInPixels(renderWindow.window, (int *)(&dstWidth), (int *)(&dstHeight)); | ||||
| #   endif | ||||
|     } | ||||
| 
 | ||||
|  | @ -2683,9 +2714,10 @@ namespace plume { | |||
| 
 | ||||
|         endActiveRenderPass(); | ||||
| 
 | ||||
|         const bool geometryEnabled = device->capabilities.geometryShader; | ||||
|         const bool rtEnabled = device->capabilities.raytracing; | ||||
|         VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; | ||||
|         VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | toStageFlags(stages, rtEnabled); | ||||
|         VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | toStageFlags(stages, geometryEnabled, rtEnabled); | ||||
|         thread_local std::vector<VkBufferMemoryBarrier> bufferMemoryBarriers; | ||||
|         thread_local std::vector<VkImageMemoryBarrier> imageMemoryBarriers; | ||||
|         bufferMemoryBarriers.clear(); | ||||
|  | @ -2704,7 +2736,7 @@ namespace plume { | |||
|             bufferMemoryBarrier.offset = 0; | ||||
|             bufferMemoryBarrier.size = interfaceBuffer->desc.size; | ||||
|             bufferMemoryBarriers.emplace_back(bufferMemoryBarrier); | ||||
|             srcStageMask |= toStageFlags(interfaceBuffer->barrierStages, rtEnabled); | ||||
|             srcStageMask |= toStageFlags(interfaceBuffer->barrierStages, geometryEnabled, rtEnabled); | ||||
|             interfaceBuffer->barrierStages = stages; | ||||
|         } | ||||
| 
 | ||||
|  | @ -2724,7 +2756,7 @@ namespace plume { | |||
|             imageMemoryBarrier.subresourceRange.layerCount = interfaceTexture->desc.arraySize; | ||||
|             imageMemoryBarrier.subresourceRange.aspectMask = (interfaceTexture->desc.flags & RenderTextureFlag::DEPTH_TARGET) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; | ||||
|             imageMemoryBarriers.emplace_back(imageMemoryBarrier); | ||||
|             srcStageMask |= toStageFlags(interfaceTexture->barrierStages, rtEnabled); | ||||
|             srcStageMask |= toStageFlags(interfaceTexture->barrierStages, geometryEnabled, rtEnabled); | ||||
|             interfaceTexture->textureLayout = textureBarrier.layout; | ||||
|             interfaceTexture->barrierStages = stages; | ||||
|         } | ||||
|  | @ -2890,6 +2922,9 @@ namespace plume { | |||
|             offsetVector.clear(); | ||||
|             for (uint32_t i = 0; i < viewCount; i++) { | ||||
|                 const VulkanBuffer *interfaceBuffer = static_cast<const VulkanBuffer *>(views[i].buffer.ref); | ||||
|                 if (interfaceBuffer == nullptr && !device->nullDescriptorSupported) { | ||||
|                     interfaceBuffer = static_cast<const VulkanBuffer *>(device->nullBuffer.get()); | ||||
|                 } | ||||
|                 bufferVector.emplace_back((interfaceBuffer != nullptr) ? interfaceBuffer->vk : VK_NULL_HANDLE); | ||||
|                 offsetVector.emplace_back(views[i].buffer.offset); | ||||
|             } | ||||
|  | @ -3696,6 +3731,11 @@ namespace plume { | |||
|         bufferDeviceAddressFeatures.pNext = featuresChain; | ||||
|         featuresChain = &bufferDeviceAddressFeatures; | ||||
| 
 | ||||
|         VkPhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures = {}; | ||||
|         portabilityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR; | ||||
|         portabilityFeatures.pNext = featuresChain; | ||||
|         featuresChain = &portabilityFeatures; | ||||
| 
 | ||||
|         VkPhysicalDeviceFeatures2 deviceFeatures = {}; | ||||
|         deviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; | ||||
|         deviceFeatures.pNext = featuresChain; | ||||
|  | @ -3766,6 +3806,12 @@ namespace plume { | |||
|             createDeviceChain = &bufferDeviceAddressFeatures; | ||||
|         } | ||||
| 
 | ||||
|         const bool portabilitySubset = supportedOptionalExtensions.find(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) != supportedOptionalExtensions.end(); | ||||
|         if (portabilitySubset) { | ||||
|             portabilityFeatures.pNext = createDeviceChain; | ||||
|             createDeviceChain = &portabilityFeatures; | ||||
|         } | ||||
| 
 | ||||
|         // Retrieve the information for the queue families.
 | ||||
|         uint32_t queueFamilyCount = 0; | ||||
|         vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr); | ||||
|  | @ -3778,6 +3824,7 @@ namespace plume { | |||
|             uint32_t familyIndex = 0; | ||||
|             uint32_t familySetBits = sizeof(uint32_t) * 8; | ||||
|             uint32_t familyQueueCount = 0; | ||||
|             bool familyUsed = false; | ||||
|             for (uint32_t i = 0; i < queueFamilyCount; i++) { | ||||
|                 const VkQueueFamilyProperties &props = queueFamilyProperties[i]; | ||||
| 
 | ||||
|  | @ -3787,11 +3834,14 @@ namespace plume { | |||
|                 } | ||||
| 
 | ||||
|                 // Prefer picking the queues with the least amount of bits set that match the mask we're looking for.
 | ||||
|                 // If the queue families have matching capabilities but one is already used, prefer the unused one.
 | ||||
|                 uint32_t setBits = numberOfSetBits(props.queueFlags); | ||||
|                 if ((setBits < familySetBits) || ((setBits == familySetBits) && (props.queueCount > familyQueueCount))) { | ||||
|                 bool used = queueFamilyUsed[i]; | ||||
|                 if ((setBits < familySetBits) || ((setBits == familySetBits) && ((props.queueCount > familyQueueCount) || (familyUsed && !used)))) { | ||||
|                     familyIndex = i; | ||||
|                     familySetBits = setBits; | ||||
|                     familyQueueCount = props.queueCount; | ||||
|                     familyUsed = used; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -3912,6 +3962,7 @@ namespace plume { | |||
|         description.dedicatedVideoMemory = memoryHeapSize; | ||||
| 
 | ||||
|         // Fill capabilities.
 | ||||
|         capabilities.geometryShader = deviceFeatures.features.geometryShader; | ||||
|         capabilities.raytracing = rtSupported; | ||||
|         capabilities.raytracingStateUpdate = false; | ||||
|         capabilities.sampleLocations = sampleLocationsSupported; | ||||
|  | @ -3920,13 +3971,25 @@ namespace plume { | |||
|         capabilities.presentWait = presentWait; | ||||
|         capabilities.displayTiming = supportedOptionalExtensions.find(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME) != supportedOptionalExtensions.end(); | ||||
|         capabilities.preferHDR = memoryHeapSize > (512 * 1024 * 1024); | ||||
| #if defined(__APPLE__) | ||||
|         // MoltenVK supports triangle fans but does so via compute shaders to translate to lists, since it has to
 | ||||
|         // support all cases including indirect draw. This results in renderpass restarts that can harm performance,
 | ||||
|         // so force disable native triangle fan support and rely on the game to emulate fans if needed.
 | ||||
|         capabilities.triangleFan = false; | ||||
| #else | ||||
|         capabilities.triangleFan = true; | ||||
| #endif | ||||
|         capabilities.dynamicDepthBias = true; | ||||
|         capabilities.uma = (description.type == RenderDeviceType::INTEGRATED) && hasHostVisibleDeviceLocalMemory; | ||||
|         capabilities.gpuUploadHeap = capabilities.uma; | ||||
| 
 | ||||
|         // Fill Vulkan-only capabilities.
 | ||||
|         loadStoreOpNoneSupported = supportedOptionalExtensions.find(VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME) != supportedOptionalExtensions.end(); | ||||
|         nullDescriptorSupported = nullDescriptor; | ||||
| 
 | ||||
|         if (!nullDescriptorSupported) { | ||||
|             nullBuffer = createBuffer(RenderBufferDesc::DefaultBuffer(16, RenderBufferFlag::VERTEX)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     VulkanDevice::~VulkanDevice() { | ||||
|  | @ -4253,6 +4316,10 @@ namespace plume { | |||
|         createInfo.ppEnabledLayerNames = nullptr; | ||||
|         createInfo.enabledLayerCount = 0; | ||||
| 
 | ||||
| #   ifdef __APPLE__ | ||||
|         createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; | ||||
| #   endif | ||||
| 
 | ||||
|         // Check for extensions.
 | ||||
|         uint32_t extensionCount; | ||||
|         vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); | ||||
|  |  | |||
|  | @ -20,8 +20,13 @@ | |||
| #define VK_USE_PLATFORM_ANDROID_KHR | ||||
| #elif defined(__linux__) | ||||
| #define VK_USE_PLATFORM_XLIB_KHR | ||||
| #elif defined(__APPLE__) | ||||
| #define VK_USE_PLATFORM_METAL_EXT | ||||
| #endif | ||||
| 
 | ||||
| // For VK_KHR_portability_subset
 | ||||
| #define VK_ENABLE_BETA_EXTENSIONS | ||||
| 
 | ||||
| #include <volk.h> | ||||
| 
 | ||||
| #ifdef __clang__ | ||||
|  | @ -403,7 +408,9 @@ namespace plume { | |||
|         RenderDeviceDescription description; | ||||
|         VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtPipelineProperties = {}; | ||||
|         VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationProperties = {}; | ||||
|         std::unique_ptr<RenderBuffer> nullBuffer = nullptr; | ||||
|         bool loadStoreOpNoneSupported = false; | ||||
|         bool nullDescriptorSupported = false; | ||||
| 
 | ||||
|         VulkanDevice(VulkanInterface *renderInterface, const std::string &preferredDeviceName); | ||||
|         ~VulkanDevice() override; | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ | |||
| #include <magic_enum/magic_enum.hpp> | ||||
| #endif | ||||
| 
 | ||||
| #define UNLEASHED_RECOMP | ||||
| #include "../../tools/XenosRecomp/XenosRecomp/shader_common.h" | ||||
| 
 | ||||
| #ifdef UNLEASHED_RECOMP_D3D12 | ||||
|  |  | |||
|  | @ -166,6 +166,9 @@ void UpdateChecker::visitWebsite() | |||
| #elif defined(__linux__) | ||||
|     std::string command = "xdg-open " + std::string(VISIT_URL) + " &"; | ||||
|     std::system(command.c_str()); | ||||
| #elif defined(__APPLE__) | ||||
|     std::string command = "open " + std::string(VISIT_URL) + " &"; | ||||
|     std::system(command.c_str()); | ||||
| #else | ||||
|     static_assert(false, "Visit website not implemented for this platform."); | ||||
| #endif | ||||
|  |  | |||
|  | @ -660,7 +660,7 @@ void KeQueryBasePriorityThread() | |||
| 
 | ||||
| uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount) | ||||
| { | ||||
|     assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->thread.get_id() == std::this_thread::get_id()); | ||||
|     assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->GetThreadId() == GuestThread::GetCurrentThreadId()); | ||||
| 
 | ||||
|     hThread->suspended = true; | ||||
|     hThread->suspended.wait(true); | ||||
|  |  | |||
|  | @ -306,26 +306,26 @@ uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const | |||
| 
 | ||||
|         if (!exists) | ||||
|         { | ||||
|             std::string root = ""; | ||||
|             std::filesystem::path rootPath; | ||||
| 
 | ||||
|             if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA) | ||||
|             { | ||||
|                 std::u8string savePathU8 = GetSavePath(true).u8string(); | ||||
|                 root = (const char *)(savePathU8.c_str()); | ||||
|                 rootPath = GetSavePath(true); | ||||
|             } | ||||
|             else if (pContentData->dwContentType == XCONTENTTYPE_DLC) | ||||
|             { | ||||
|                 root = GAME_INSTALL_DIRECTORY "/dlc"; | ||||
|                 rootPath = GetGamePath() / "dlc"; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 root = GAME_INSTALL_DIRECTORY; | ||||
|                 rootPath = GetGamePath(); | ||||
|             } | ||||
| 
 | ||||
|             const std::string root = (const char*)rootPath.u8string().c_str(); | ||||
|             XamRegisterContent(*pContentData, root); | ||||
| 
 | ||||
|             std::error_code ec; | ||||
|             std::filesystem::create_directory(std::u8string_view((const char8_t*)(root.c_str())), ec); | ||||
|             std::filesystem::create_directory(rootPath, ec); | ||||
| 
 | ||||
|             XamRootCreate(szRootName, root); | ||||
|         } | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| #include <stdafx.h> | ||||
| #ifdef __x86_64__ | ||||
| #include <cpuid.h> | ||||
| #endif | ||||
| #include <cpu/guest_thread.h> | ||||
| #include <gpu/video.h> | ||||
| #include <kernel/function.h> | ||||
|  | @ -69,8 +71,10 @@ void KiSystemStartup() | |||
| 
 | ||||
|     const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game"); | ||||
|     const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update"); | ||||
|     XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game"); | ||||
|     XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update"); | ||||
|     const std::string gamePath = (const char*)(GetGamePath() / "game").u8string().c_str(); | ||||
|     const std::string updatePath = (const char*)(GetGamePath() / "update").u8string().c_str(); | ||||
|     XamRegisterContent(gameContent, gamePath); | ||||
|     XamRegisterContent(updateContent, updatePath); | ||||
| 
 | ||||
|     const auto saveFilePath = GetSaveFilePath(true); | ||||
|     bool saveFileExists = std::filesystem::exists(saveFilePath); | ||||
|  | @ -102,7 +106,7 @@ void KiSystemStartup() | |||
|     XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr); | ||||
| 
 | ||||
|     std::error_code ec; | ||||
|     for (auto& file : std::filesystem::directory_iterator(GAME_INSTALL_DIRECTORY "/dlc", ec)) | ||||
|     for (auto& file : std::filesystem::directory_iterator(GetGamePath() / "dlc", ec)) | ||||
|     { | ||||
|         if (file.is_directory()) | ||||
|         { | ||||
|  | @ -165,10 +169,10 @@ uint32_t LdrLoadModule(const std::filesystem::path &path) | |||
|     return entry; | ||||
| } | ||||
| 
 | ||||
| #ifdef __x86_64__ | ||||
| __attribute__((constructor(101), target("no-avx,no-avx2"), noinline)) | ||||
| void init() | ||||
| { | ||||
| #ifdef __x86_64__ | ||||
|     uint32_t eax, ebx, ecx, edx; | ||||
| 
 | ||||
|     // Execute CPUID for processor info and feature bits.
 | ||||
|  | @ -185,8 +189,8 @@ void init() | |||
| 
 | ||||
|         std::_Exit(1); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
|  | @ -232,7 +236,7 @@ int main(int argc, char *argv[]) | |||
|     { | ||||
|         // Set the current working directory to the executable's path.
 | ||||
|         std::error_code ec; | ||||
|         std::filesystem::current_path(os::process::GetExecutablePath().parent_path(), ec); | ||||
|         std::filesystem::current_path(os::process::GetExecutableRoot(), ec); | ||||
|     } | ||||
| 
 | ||||
|     Config::Load(); | ||||
|  | @ -321,7 +325,7 @@ int main(int argc, char *argv[]) | |||
|     HostStartup(); | ||||
| 
 | ||||
|     std::filesystem::path modulePath; | ||||
|     bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY, modulePath); | ||||
|     bool isGameInstalled = Installer::checkGameInstall(GetGamePath(), modulePath); | ||||
|     bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled; | ||||
|     if (runInstallerWizard) | ||||
|     { | ||||
|  | @ -331,7 +335,7 @@ int main(int argc, char *argv[]) | |||
|             std::_Exit(1); | ||||
|         } | ||||
| 
 | ||||
|         if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller)) | ||||
|         if (!InstallerWizard::Run(GetGamePath(), isGameInstalled && forceDLCInstaller)) | ||||
|         { | ||||
|             std::_Exit(0); | ||||
|         } | ||||
|  |  | |||
|  | @ -100,7 +100,7 @@ void ModLoader::Init() | |||
|     { | ||||
|         configIni = {}; | ||||
| 
 | ||||
|         if (!configIni.read(GAME_INSTALL_DIRECTORY "/cpkredir.ini")) | ||||
|         if (!configIni.read(GetGamePath() / "cpkredir.ini")) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,6 +15,11 @@ std::filesystem::path os::process::GetExecutablePath() | |||
|     } | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetExecutableRoot() | ||||
| { | ||||
|     return GetExecutablePath().remove_filename(); | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetWorkingDirectory() | ||||
| { | ||||
|     char cwd[PATH_MAX] = {}; | ||||
|  |  | |||
							
								
								
									
										17
									
								
								UnleashedRecomp/os/macos/logger_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								UnleashedRecomp/os/macos/logger_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| #include <os/logger.h> | ||||
| 
 | ||||
| void os::logger::Init() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void os::logger::Log(const std::string_view str, ELogType type, const char* func) | ||||
| { | ||||
|     if (func) | ||||
|     { | ||||
|         fmt::println("[{}] {}", func, str); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         fmt::println("{}", str); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										7
									
								
								UnleashedRecomp/os/macos/media_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								UnleashedRecomp/os/macos/media_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #include <os/media.h> | ||||
| 
 | ||||
| bool os::media::IsExternalMediaPlaying() | ||||
| { | ||||
|     // This functionality is not supported in macOS.
 | ||||
|     return false; | ||||
| } | ||||
							
								
								
									
										97
									
								
								UnleashedRecomp/os/macos/process_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								UnleashedRecomp/os/macos/process_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,97 @@ | |||
| #include <os/process.h> | ||||
| 
 | ||||
| #include <CoreFoundation/CFBundle.h> | ||||
| #include <dlfcn.h> | ||||
| #include <mach-o/dyld.h> | ||||
| #include <signal.h> | ||||
| #include <sys/param.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| std::filesystem::path os::process::GetExecutablePath() | ||||
| { | ||||
|     uint32_t exePathSize = PATH_MAX; | ||||
|     char exePath[PATH_MAX] = {}; | ||||
|     if (_NSGetExecutablePath(exePath, &exePathSize) == 0) | ||||
|     { | ||||
|         return std::filesystem::path(std::u8string_view((const char8_t*)(exePath))); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return std::filesystem::path(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetExecutableRoot() | ||||
| { | ||||
|     std::filesystem::path resultPath = GetExecutablePath().remove_filename(); | ||||
|     if (CFBundleRef bundleRef = CFBundleGetMainBundle()) | ||||
|     { | ||||
|         if (CFURLRef bundleUrlRef = CFBundleCopyBundleURL(bundleRef)) | ||||
|         { | ||||
|             char appBundlePath[MAXPATHLEN]; | ||||
|             if (CFURLGetFileSystemRepresentation(bundleUrlRef, true, (uint8_t*)(appBundlePath), sizeof(appBundlePath))) | ||||
|             { | ||||
|                 resultPath = std::filesystem::path(appBundlePath).parent_path(); | ||||
|             } | ||||
|             CFRelease(bundleUrlRef); | ||||
|         } | ||||
|     } | ||||
|     return resultPath; | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::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::SetWorkingDirectory(const std::filesystem::path& path) | ||||
| { | ||||
|     return chdir(path.c_str()) == 0; | ||||
| } | ||||
| 
 | ||||
| bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& 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<char*> 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; | ||||
| } | ||||
| 
 | ||||
| void os::process::CheckConsole() | ||||
| { | ||||
|     // Always visible on macOS.
 | ||||
|     g_consoleVisible = true; | ||||
| } | ||||
| 
 | ||||
| void os::process::ShowConsole() | ||||
| { | ||||
|     // Unnecessary on macOS.
 | ||||
| } | ||||
							
								
								
									
										21
									
								
								UnleashedRecomp/os/macos/registry_macos.inl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								UnleashedRecomp/os/macos/registry_macos.inl
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| #include <os/registry.h> | ||||
| 
 | ||||
| // TODO: Implement | ||||
| inline bool os::registry::Init() | ||||
| { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // TODO: read from file? | ||||
| template<typename T> | ||||
| bool os::registry::ReadValue(const std::string_view& name, T& data) | ||||
| { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // TODO: write to file? | ||||
| template<typename T> | ||||
| bool os::registry::WriteValue(const std::string_view& name, const T& data) | ||||
| { | ||||
|     return false; | ||||
| } | ||||
							
								
								
									
										6
									
								
								UnleashedRecomp/os/macos/user_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								UnleashedRecomp/os/macos/user_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| #include <os/user.h> | ||||
| 
 | ||||
| bool os::user::IsDarkTheme() | ||||
| { | ||||
|     return false; | ||||
| } | ||||
							
								
								
									
										7
									
								
								UnleashedRecomp/os/macos/version_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								UnleashedRecomp/os/macos/version_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #include <os/version.h> | ||||
| 
 | ||||
| os::version::OSVersion os::version::GetOSVersion() | ||||
| { | ||||
|     assert(false && "Unimplemented."); | ||||
|     return os::version::OSVersion(); | ||||
| } | ||||
|  | @ -5,6 +5,7 @@ namespace os::process | |||
|     inline bool g_consoleVisible; | ||||
| 
 | ||||
|     std::filesystem::path GetExecutablePath(); | ||||
|     std::filesystem::path GetExecutableRoot(); | ||||
|     std::filesystem::path GetWorkingDirectory(); | ||||
|     bool SetWorkingDirectory(const std::filesystem::path& path); | ||||
|     bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {}); | ||||
|  |  | |||
|  | @ -15,4 +15,6 @@ namespace os::registry | |||
| #include <os/win32/registry_win32.inl> | ||||
| #elif defined(__linux__) | ||||
| #include <os/linux/registry_linux.inl> | ||||
| #elif defined(__APPLE__) | ||||
| #include <os/macos/registry_macos.inl> | ||||
| #endif | ||||
|  |  | |||
|  | @ -10,6 +10,11 @@ std::filesystem::path os::process::GetExecutablePath() | |||
|     return std::filesystem::path(exePath); | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetExecutableRoot() | ||||
| { | ||||
|     return GetExecutablePath().remove_filename(); | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetWorkingDirectory() | ||||
| { | ||||
|     WCHAR workPath[MAX_PATH]; | ||||
|  |  | |||
							
								
								
									
										42
									
								
								UnleashedRecomp/res/macos/MacOSXBundleInfo.plist.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								UnleashedRecomp/res/macos/MacOSXBundleInfo.plist.in
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>CFBundleDevelopmentRegion</key> | ||||
| 	<string>English</string> | ||||
| 	<key>CFBundleExecutable</key> | ||||
| 	<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> | ||||
| 	<key>CFBundleGetInfoString</key> | ||||
| 	<string>${MACOSX_BUNDLE_INFO_STRING}</string> | ||||
| 	<key>CFBundleIconFile</key> | ||||
| 	<string>${MACOSX_BUNDLE_ICON_FILE}</string> | ||||
| 	<key>CFBundleIdentifier</key> | ||||
| 	<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> | ||||
| 	<key>CFBundleInfoDictionaryVersion</key> | ||||
| 	<string>6.0</string> | ||||
| 	<key>CFBundleLongVersionString</key> | ||||
| 	<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> | ||||
| 	<key>CFBundleName</key> | ||||
| 	<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> | ||||
| 	<key>CFBundlePackageType</key> | ||||
| 	<string>APPL</string> | ||||
| 	<key>CFBundleShortVersionString</key> | ||||
| 	<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> | ||||
| 	<key>CFBundleSignature</key> | ||||
| 	<string>????</string> | ||||
| 	<key>CFBundleVersion</key> | ||||
| 	<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> | ||||
| 	<key>CSResourcesFileMapped</key> | ||||
| 	<true/> | ||||
| 	<key>NSHumanReadableCopyright</key> | ||||
| 	<string>${MACOSX_BUNDLE_COPYRIGHT}</string> | ||||
| 	<key>LSMinimumSystemVersion</key> | ||||
| 	<string>13.0</string> | ||||
| 	<key>LSApplicationCategoryType</key> | ||||
| 	<string>public.app-category.games</string> | ||||
| 	<key>GCSupportsGameMode</key> | ||||
| 	<true/> | ||||
| 	<key>NSHighResolutionCapable</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
							
								
								
									
										
											BIN
										
									
								
								UnleashedRecomp/res/macos/game_icon.icns
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								UnleashedRecomp/res/macos/game_icon.icns
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -20,7 +20,7 @@ std::unique_ptr<GuestTexture> g_upKBMIcons; | |||
| 
 | ||||
| float g_sideMargins = DEFAULT_SIDE_MARGINS; | ||||
| 
 | ||||
| std::vector<Button> g_buttons; | ||||
| static std::vector<Button> g_buttons; | ||||
| 
 | ||||
| std::unordered_map<EButtonIcon, float> g_iconWidths = | ||||
| { | ||||
|  |  | |||
|  | @ -217,6 +217,9 @@ void GameWindow::Init(const char* sdlVideoDriver) | |||
|     s_renderWindow = s_pWindow; | ||||
| #elif defined(__linux__) | ||||
|     s_renderWindow = { info.info.x11.display, info.info.x11.window }; | ||||
| #elif defined(__APPLE__) | ||||
|     s_renderWindow.window = s_pWindow; | ||||
|     s_renderWindow.view = SDL_Metal_GetLayer(SDL_Metal_CreateView(s_pWindow)); | ||||
| #else | ||||
|     static_assert(false, "Unknown platform."); | ||||
| #endif | ||||
|  |  | |||
|  | @ -1146,7 +1146,11 @@ static void PickerStart(bool folderMode) { | |||
|     g_currentPickerVisible = true; | ||||
| 
 | ||||
|     // Optional single thread mode for testing on systems that do not interact well with the separate thread being used for NFD.
 | ||||
| #ifdef __APPLE__ | ||||
|     constexpr bool singleThreadMode = true; | ||||
| #else | ||||
|     constexpr bool singleThreadMode = false; | ||||
| #endif | ||||
|     if (singleThreadMode) | ||||
|         PickerThreadProcess(); | ||||
|     else | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ static ImFont* g_fntSeurat; | |||
| 
 | ||||
| std::string g_text; | ||||
| int g_result; | ||||
| std::vector<std::string> g_buttons; | ||||
| static std::vector<std::string> g_buttons; | ||||
| int g_defaultButtonIndex; | ||||
| int g_cancelButtonIndex; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| #include "paths.h" | ||||
| #include <os/process.h> | ||||
| 
 | ||||
| std::filesystem::path g_executableRoot = os::process::GetExecutablePath().remove_filename(); | ||||
| std::filesystem::path g_executableRoot = os::process::GetExecutableRoot(); | ||||
| std::filesystem::path g_userPath = BuildUserPath(); | ||||
| 
 | ||||
| bool CheckPortable() | ||||
|  | @ -22,18 +22,24 @@ std::filesystem::path BuildUserPath() | |||
|         userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY; | ||||
| 
 | ||||
|     CoTaskMemFree(knownPath); | ||||
| #elif defined(__linux__) | ||||
| #elif defined(__linux__) || defined(__APPLE__) | ||||
|     const char* homeDir = getenv("HOME"); | ||||
| #if defined(__linux__) | ||||
|     if (homeDir == nullptr) | ||||
|     { | ||||
|         homeDir = getpwuid(getuid())->pw_dir; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     if (homeDir != nullptr) | ||||
|     { | ||||
|         // Prefer to store in the .config directory if it exists. Use the home directory otherwise.
 | ||||
|         std::filesystem::path homePath = homeDir; | ||||
| #if defined(__linux__) | ||||
|         std::filesystem::path configPath = homePath / ".config"; | ||||
| #else | ||||
|         std::filesystem::path configPath = homePath / "Library" / "Application Support"; | ||||
| #endif | ||||
|         if (std::filesystem::exists(configPath)) | ||||
|             userPath = configPath / USER_DIRECTORY; | ||||
|         else | ||||
|  |  | |||
|  | @ -10,15 +10,22 @@ | |||
| 
 | ||||
| extern std::filesystem::path g_executableRoot; | ||||
| 
 | ||||
| inline std::filesystem::path GetGamePath() | ||||
| { | ||||
|     return GAME_INSTALL_DIRECTORY; | ||||
| } | ||||
| 
 | ||||
| bool CheckPortable(); | ||||
| std::filesystem::path BuildUserPath(); | ||||
| const std::filesystem::path& GetUserPath(); | ||||
| 
 | ||||
| inline std::filesystem::path GetGamePath() | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
|     // On macOS, there is the expectation that the app may be installed to
 | ||||
|     // /Applications/, and the bundle should not be modified. Thus we need
 | ||||
|     // to install game files to the user directory instead of next to the app.
 | ||||
|     return GetUserPath(); | ||||
| #else | ||||
|     return GAME_INSTALL_DIRECTORY; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| inline std::filesystem::path GetSavePath(bool checkForMods) | ||||
| { | ||||
|     if (checkForMods && !ModLoader::s_saveFilePath.empty()) | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ add_custom_command( | |||
|         "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xex" | ||||
|         "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xexp" | ||||
|         "${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml" | ||||
|     USES_TERMINAL | ||||
| ) | ||||
| 
 | ||||
| add_custom_command( | ||||
|  | @ -53,6 +54,7 @@ target_compile_definitions(XenosRecomp PRIVATE | |||
|     XENOS_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\"  | ||||
|     XENOS_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\" | ||||
|     XENOS_RECOMP_INCLUDE_INPUT=\"${XENOS_RECOMP_INCLUDE}\" | ||||
|     UNLEASHED_RECOMP | ||||
| ) | ||||
| 
 | ||||
| file(GLOB XENOS_RECOMP_SOURCES  | ||||
|  | @ -70,6 +72,7 @@ add_custom_command( | |||
|         "${CMAKE_CURRENT_SOURCE_DIR}/private/shader_decompressed.ar"  | ||||
|         ${XENOS_RECOMP_SOURCES}  | ||||
|         ${XENOS_RECOMP_INCLUDE} | ||||
|     USES_TERMINAL | ||||
| ) | ||||
| 
 | ||||
| add_library(UnleashedRecompLib  | ||||
|  | @ -79,4 +82,5 @@ add_library(UnleashedRecompLib | |||
| ) | ||||
| 
 | ||||
| target_include_directories(UnleashedRecompLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) | ||||
| target_include_directories(UnleashedRecompLib PRIVATE "${UNLEASHED_RECOMP_TOOLS_ROOT}/XenonRecomp/thirdparty/simde") | ||||
| target_precompile_headers(UnleashedRecompLib PUBLIC "ppc/ppc_recomp_shared.h") | ||||
|  |  | |||
|  | @ -50,6 +50,21 @@ You can also find the equivalent packages for your preferred distro. | |||
| > [!NOTE] | ||||
| > This list may not be comprehensive for your particular distro and you may be required to install additional packages, should an error occur during configuration. | ||||
| 
 | ||||
| ### macOS | ||||
| You will need to install Xcode 16.3+ or the equivalent Xcode Command Line Tools from Apple. | ||||
| 
 | ||||
| The following commands will install additional required dependencies, depending on which package manager you use. | ||||
| 
 | ||||
| If you use Homebrew: | ||||
| ```bash | ||||
| brew install cmake ninja pkg-config | ||||
| ``` | ||||
| 
 | ||||
| If you use MacPorts: | ||||
| ```bash | ||||
| sudo port install cmake ninja pkg-config | ||||
| ``` | ||||
| 
 | ||||
| ## 4. Build the Project | ||||
| 
 | ||||
| ### Windows | ||||
|  | @ -81,3 +96,22 @@ cmake --build ./out/build/linux-release --target UnleashedRecomp | |||
| ```bash | ||||
| ./UnleashedRecomp | ||||
| ``` | ||||
| 
 | ||||
| ### macOS | ||||
| 1. Configure the project using CMake by navigating to the repository and running the following command. | ||||
| ```bash | ||||
| cmake . --preset macos-release | ||||
| ``` | ||||
| 
 | ||||
| > [!NOTE] | ||||
| > The available presets are `macos-debug`, `macos-relwithdebinfo` and `macos-release`. | ||||
| 
 | ||||
| 2. Build the project using the selected configuration. | ||||
| ```bash | ||||
| cmake --build ./out/build/macos-release --target UnleashedRecomp | ||||
| ``` | ||||
| 
 | ||||
| 3. Navigate to the directory that was specified as the output in the previous step and run the game. | ||||
| ```bash | ||||
| open -a UnleashedRecomp.app | ||||
| ``` | ||||
|  |  | |||
							
								
								
									
										4
									
								
								thirdparty/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								thirdparty/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -20,3 +20,7 @@ add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nativefiledialog-extended" | |||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/o1heap") | ||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL") | ||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL_mixer") | ||||
| 
 | ||||
| if (APPLE) | ||||
|     add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/MoltenVK") | ||||
| endif() | ||||
|  |  | |||
							
								
								
									
										86
									
								
								thirdparty/MoltenVK/CMakeLists.txt
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								thirdparty/MoltenVK/CMakeLists.txt
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | |||
| # Simple CMake script to compile MoltenVK with SPIRV-Cross as a shared library target | ||||
| 
 | ||||
| # Prepare MoltenVK Git revision | ||||
| find_package(Git) | ||||
| if(GIT_FOUND) | ||||
|     execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD | ||||
|             OUTPUT_VARIABLE MVK_GIT_REV | ||||
|             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK | ||||
|             ERROR_QUIET | ||||
|             OUTPUT_STRIP_TRAILING_WHITESPACE) | ||||
| endif() | ||||
| set(MVK_GENERATED_INCLUDES ${CMAKE_CURRENT_BINARY_DIR}/Generated) | ||||
| file(WRITE ${MVK_GENERATED_INCLUDES}/mvkGitRevDerived.h "static const char* mvkRevString = \"${MVK_GIT_REV}\";") | ||||
| message(STATUS "MoltenVK revision: ${MVK_GIT_REV}") | ||||
| 
 | ||||
| # Prepare MoltenVK version | ||||
| file(READ ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK/MoltenVK/API/mvk_private_api.h MVK_PRIVATE_API) | ||||
| string(REGEX MATCH "#define MVK_VERSION_MAJOR   [0-9]+" MVK_VERSION_MAJOR_LINE "${MVK_PRIVATE_API}") | ||||
| string(REGEX MATCH "[0-9]+" MVK_VERSION_MAJOR "${MVK_VERSION_MAJOR_LINE}") | ||||
| string(REGEX MATCH "#define MVK_VERSION_MINOR   [0-9]+" MVK_VERSION_MINOR_LINE "${MVK_PRIVATE_API}") | ||||
| string(REGEX MATCH "[0-9]+" MVK_VERSION_MINOR "${MVK_VERSION_MINOR_LINE}") | ||||
| string(REGEX MATCH "#define MVK_VERSION_PATCH   [0-9]+" MVK_VERSION_PATCH_LINE "${MVK_PRIVATE_API}") | ||||
| string(REGEX MATCH "[0-9]+" MVK_VERSION_PATCH "${MVK_VERSION_PATCH_LINE}") | ||||
| set(MVK_VERSION "${MVK_VERSION_MAJOR}.${MVK_VERSION_MINOR}.${MVK_VERSION_PATCH}") | ||||
| message(STATUS "MoltenVK version: ${MVK_VERSION}") | ||||
| 
 | ||||
| # Find required system libraries | ||||
| find_library(APPKIT_LIBRARY AppKit REQUIRED) | ||||
| find_library(FOUNDATION_LIBRARY Foundation REQUIRED) | ||||
| find_library(IOKIT_LIBRARY IOKit REQUIRED) | ||||
| find_library(IOSURFACE_LIBRARY IOSurface REQUIRED) | ||||
| find_library(METAL_LIBRARY Metal REQUIRED) | ||||
| find_library(QUARTZCORE_LIBRARY QuartzCore REQUIRED) | ||||
| 
 | ||||
| # SPIRV-Cross | ||||
| option(SPIRV_CROSS_CLI "" OFF) | ||||
| option(SPIRV_CROSS_ENABLE_TESTS "" OFF) | ||||
| option(SPIRV_CROSS_ENABLE_HLSL "" OFF) | ||||
| option(SPIRV_CROSS_ENABLE_CPP "" OFF) | ||||
| option(SPIRV_CROSS_SKIP_INSTALL "" ON) | ||||
| add_subdirectory(SPIRV-Cross) | ||||
| 
 | ||||
| # Common | ||||
| set(MVK_COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/Common) | ||||
| file(GLOB_RECURSE MVK_COMMON_SOURCES CONFIGURE_DEPENDS | ||||
|     ${MVK_COMMON_DIR}/*.cpp | ||||
|     ${MVK_COMMON_DIR}/*.m | ||||
|     ${MVK_COMMON_DIR}/*.mm) | ||||
| set(MVK_COMMON_INCLUDES ${MVK_COMMON_DIR}) | ||||
| 
 | ||||
| add_library(MoltenVKCommon STATIC ${MVK_COMMON_SOURCES}) | ||||
| target_include_directories(MoltenVKCommon PUBLIC ${MVK_COMMON_INCLUDES}) | ||||
| target_compile_options(MoltenVKCommon PRIVATE -w) | ||||
| 
 | ||||
| # MoltenVKShaderConverter | ||||
| set(MVK_SHADER_CONVERTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVKShaderConverter) | ||||
| file(GLOB_RECURSE MVK_SHADER_CONVERTER_SOURCES CONFIGURE_DEPENDS | ||||
|     ${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.cpp | ||||
|     ${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.m | ||||
|     ${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.mm) | ||||
| set(MVK_SHADER_CONVERTER_INCLUDES ${MVK_SHADER_CONVERTER_DIR} ${MVK_SHADER_CONVERTER_DIR}/include) | ||||
| 
 | ||||
| add_library(MoltenVKShaderConverter STATIC ${MVK_SHADER_CONVERTER_SOURCES}) | ||||
| target_include_directories(MoltenVKShaderConverter PUBLIC ${MVK_SHADER_CONVERTER_INCLUDES}) | ||||
| target_compile_options(MoltenVKShaderConverter PRIVATE -w) | ||||
| target_link_libraries(MoltenVKShaderConverter PRIVATE spirv-cross-msl spirv-cross-reflect MoltenVKCommon) | ||||
| target_compile_definitions(MoltenVKShaderConverter PRIVATE MVK_EXCLUDE_SPIRV_TOOLS=1) | ||||
| 
 | ||||
| # MoltenVK | ||||
| set(MVK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK) | ||||
| file(GLOB_RECURSE MVK_SOURCES CONFIGURE_DEPENDS | ||||
|     ${MVK_DIR}/MoltenVK/*.cpp | ||||
|     ${MVK_DIR}/MoltenVK/*.m | ||||
|     ${MVK_DIR}/MoltenVK/*.mm) | ||||
| file(GLOB MVK_SRC_INCLUDES LIST_DIRECTORIES ON ${MVK_DIR}/MoltenVK/*) | ||||
| set(MVK_INCLUDES | ||||
|     ${MVK_SRC_INCLUDES} ${MVK_GENERATED_INCLUDES} ${MVK_DIR}/include | ||||
|     ${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/Vulkan-Headers/include) | ||||
| 
 | ||||
| add_library(MoltenVK SHARED ${MVK_SOURCES}) | ||||
| target_include_directories(MoltenVK PRIVATE ${MVK_INCLUDES}) | ||||
| target_compile_options(MoltenVK PRIVATE -w) | ||||
| target_link_libraries(MoltenVK PRIVATE | ||||
|     ${APPKIT_LIBRARY} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${IOSURFACE_LIBRARY} ${METAL_LIBRARY} ${QUARTZCORE_LIBRARY} | ||||
|     spirv-cross-msl MoltenVKCommon MoltenVKShaderConverter) | ||||
| target_compile_definitions(MoltenVK PRIVATE MVK_FRAMEWORK_VERSION=${MVK_VERSION} MVK_USE_CEREAL=0) | ||||
							
								
								
									
										1
									
								
								thirdparty/MoltenVK/MoltenVK
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/MoltenVK/MoltenVK
									
										
									
									
										vendored
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit 3a0b07a24a4a681ffe70b461b1f4333b2729e2ef | ||||
							
								
								
									
										1
									
								
								thirdparty/MoltenVK/SPIRV-Cross
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/MoltenVK/SPIRV-Cross
									
										
									
									
										vendored
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit 22b22f5685d868828be01c9ac00c31902e60afd9 | ||||
							
								
								
									
										2
									
								
								thirdparty/Vulkan-Headers
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								thirdparty/Vulkan-Headers
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +1 @@ | |||
| Subproject commit 14345dab231912ee9601136e96ca67a6e1f632e7 | ||||
| Subproject commit 75ad707a587e1469fb53a901b9b68fe9f6fbc11f | ||||
|  | @ -1 +1 @@ | |||
| Subproject commit c017eb630ab917bffd3bc6a0a46995b49e7d8049 | ||||
| Subproject commit c5bfd90d87f2ed0db8cff5c19ea3aff0e161e527 | ||||
|  | @ -1 +1 @@ | |||
| Subproject commit 56738e5893ed7c4dc108996590475c52726623e3 | ||||
| Subproject commit 990d03b28a27b50277ee5d8d942e1c5f873869d1 | ||||
|  | @ -9,8 +9,12 @@ | |||
|             "name": "directx12-agility", | ||||
|             "platform": "windows" | ||||
|         }, | ||||
|         "directx-dxc", | ||||
|         "freetype", | ||||
|         "curl" | ||||
|     ] | ||||
|     ], | ||||
|     "vcpkg-configuration": { | ||||
|         "overlay-triplets": [ | ||||
|             "vcpkg/triplets" | ||||
|         ] | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										7
									
								
								vcpkg/triplets/arm64-osx.cmake
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vcpkg/triplets/arm64-osx.cmake
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| set(VCPKG_TARGET_ARCHITECTURE arm64) | ||||
| set(VCPKG_CRT_LINKAGE dynamic) | ||||
| set(VCPKG_LIBRARY_LINKAGE static) | ||||
| 
 | ||||
| set(VCPKG_CMAKE_SYSTEM_NAME Darwin) | ||||
| set(VCPKG_OSX_ARCHITECTURES arm64) | ||||
| set(VCPKG_OSX_DEPLOYMENT_TARGET "13.0") | ||||
							
								
								
									
										7
									
								
								vcpkg/triplets/x64-osx.cmake
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vcpkg/triplets/x64-osx.cmake
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| set(VCPKG_TARGET_ARCHITECTURE x64) | ||||
| set(VCPKG_CRT_LINKAGE dynamic) | ||||
| set(VCPKG_LIBRARY_LINKAGE static) | ||||
| 
 | ||||
| set(VCPKG_CMAKE_SYSTEM_NAME Darwin) | ||||
| set(VCPKG_OSX_ARCHITECTURES x86_64) | ||||
| set(VCPKG_OSX_DEPLOYMENT_TARGET "13.0") | ||||
		Loading…
	
	Add table
		
		Reference in a new issue