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: |         with: | ||||||
|           name: UnleashedRecomp-Flatpak |           name: UnleashedRecomp-Flatpak | ||||||
|           path: ./${{ env.FLATPAK_ID }}.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"] | [submodule "UnleashedRecomp/api"] | ||||||
| 	path = UnleashedRecomp/api | 	path = UnleashedRecomp/api | ||||||
| 	url = https://github.com/hedge-dev/SWA.git | 	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!") |     message(FATAL_ERROR "VCPKG_ROOT is not defined!") | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake) |  | ||||||
| set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty) | set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty) | ||||||
| set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools) | set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools) | ||||||
| set(CMAKE_CXX_STANDARD 20) | set(CMAKE_CXX_STANDARD 20) | ||||||
|  | @ -18,16 +17,28 @@ endif() | ||||||
| 
 | 
 | ||||||
| set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") | set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") | ||||||
| 
 | 
 | ||||||
| # Target Sandy Bridge for all projects | project("UnleashedRecomp-ALL") | ||||||
| add_compile_options( | 
 | ||||||
|     -march=sandybridge | 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_THIRDPARTY_ROOT}) | ||||||
| add_subdirectory(${UNLEASHED_RECOMP_TOOLS_ROOT}) | add_subdirectory(${UNLEASHED_RECOMP_TOOLS_ROOT}) | ||||||
| 
 | 
 | ||||||
| project("UnleashedRecomp-ALL") |  | ||||||
| 
 |  | ||||||
| # Include sub-projects. | # Include sub-projects. | ||||||
| add_subdirectory("UnleashedRecompLib") | add_subdirectory("UnleashedRecompLib") | ||||||
| add_subdirectory("UnleashedRecomp") | add_subdirectory("UnleashedRecomp") | ||||||
|  |  | ||||||
|  | @ -113,6 +113,58 @@ | ||||||
|                 "CMAKE_BUILD_TYPE": "Release", |                 "CMAKE_BUILD_TYPE": "Release", | ||||||
|                 "CMAKE_INTERPROCEDURAL_OPTIMIZATION": true |                 "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/user_linux.cpp" | ||||||
|         "os/linux/version_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() | endif() | ||||||
| 
 | 
 | ||||||
| set(UNLEASHED_RECOMP_CPU_CXX_SOURCES | set(UNLEASHED_RECOMP_CPU_CXX_SOURCES | ||||||
|  | @ -119,7 +127,7 @@ endif() | ||||||
| 
 | 
 | ||||||
| set(UNLEASHED_RECOMP_APU_CXX_SOURCES | set(UNLEASHED_RECOMP_APU_CXX_SOURCES | ||||||
|     "apu/audio.cpp" |     "apu/audio.cpp" | ||||||
|     "apu/embedded_player.cpp" |     "apu/embedded_player.cpp" | ||||||
|     "apu/driver/sdl2_driver.cpp" |     "apu/driver/sdl2_driver.cpp" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -149,16 +157,16 @@ set(UNLEASHED_RECOMP_PATCHES_CXX_SOURCES | ||||||
| 
 | 
 | ||||||
| set(UNLEASHED_RECOMP_UI_CXX_SOURCES | set(UNLEASHED_RECOMP_UI_CXX_SOURCES | ||||||
|     "ui/achievement_menu.cpp" |     "ui/achievement_menu.cpp" | ||||||
|     "ui/achievement_overlay.cpp" |     "ui/achievement_overlay.cpp" | ||||||
|     "ui/black_bar.cpp" |     "ui/black_bar.cpp" | ||||||
|     "ui/button_guide.cpp" |     "ui/button_guide.cpp" | ||||||
|     "ui/fader.cpp" |     "ui/fader.cpp" | ||||||
|     "ui/game_window.cpp" |     "ui/game_window.cpp" | ||||||
|     "ui/imgui_utils.cpp" |     "ui/imgui_utils.cpp" | ||||||
|     "ui/installer_wizard.cpp" |     "ui/installer_wizard.cpp" | ||||||
|     "ui/message_window.cpp" |     "ui/message_window.cpp" | ||||||
|     "ui/options_menu.cpp" |     "ui/options_menu.cpp" | ||||||
|     "ui/options_menu_thumbnails.cpp" |     "ui/options_menu_thumbnails.cpp" | ||||||
|     "ui/tv_static.cpp" |     "ui/tv_static.cpp" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -180,7 +188,7 @@ set(UNLEASHED_RECOMP_INSTALL_CXX_SOURCES | ||||||
| set(UNLEASHED_RECOMP_USER_CXX_SOURCES | set(UNLEASHED_RECOMP_USER_CXX_SOURCES | ||||||
|     "user/achievement_data.cpp" |     "user/achievement_data.cpp" | ||||||
|     "user/achievement_manager.cpp" |     "user/achievement_manager.cpp" | ||||||
|     "user/config.cpp" |     "user/config.cpp" | ||||||
|     "user/registry.cpp" |     "user/registry.cpp" | ||||||
|     "user/paths.cpp" |     "user/paths.cpp" | ||||||
|     "user/persistent_data.cpp" |     "user/persistent_data.cpp" | ||||||
|  | @ -231,7 +239,7 @@ set(UNLEASHED_RECOMP_CXX_SOURCES | ||||||
|     "app.cpp" |     "app.cpp" | ||||||
|     "exports.cpp" |     "exports.cpp" | ||||||
|     "main.cpp" |     "main.cpp" | ||||||
|     "misc_impl.cpp" |     "misc_impl.cpp" | ||||||
|     "preload_executable.cpp" |     "preload_executable.cpp" | ||||||
|     "sdl_listener.cpp" |     "sdl_listener.cpp" | ||||||
|     "stdafx.cpp" |     "stdafx.cpp" | ||||||
|  | @ -250,11 +258,11 @@ set(UNLEASHED_RECOMP_CXX_SOURCES | ||||||
|     ${UNLEASHED_RECOMP_USER_CXX_SOURCES} |     ${UNLEASHED_RECOMP_USER_CXX_SOURCES} | ||||||
|     ${UNLEASHED_RECOMP_MOD_CXX_SOURCES} |     ${UNLEASHED_RECOMP_MOD_CXX_SOURCES} | ||||||
|     ${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} |     ${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| include("version.cmake") | include("version.cmake") | ||||||
| 
 | 
 | ||||||
| set(VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt") | set(VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt") | ||||||
| 
 | 
 | ||||||
| # Only show Git info and build type if not Release. | # Only show Git info and build type if not Release. | ||||||
| set(SHOW_GIT_INFO_AND_BUILD_TYPE 0) | set(SHOW_GIT_INFO_AND_BUILD_TYPE 0) | ||||||
|  | @ -270,53 +278,102 @@ GenerateVersionSources( | ||||||
|     BUILD_TYPE ${CMAKE_BUILD_TYPE} |     BUILD_TYPE ${CMAKE_BUILD_TYPE} | ||||||
|     SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} |     SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||||
|     SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} |     SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| if (WIN32) | if (WIN32) | ||||||
|     # Create binary version number for Win32 integer attributes. |     # Create binary version number for Win32 integer attributes. | ||||||
|     CreateVersionString( |     CreateVersionString( | ||||||
|         VERSION_TXT ${VERSION_TXT} |         VERSION_TXT ${VERSION_TXT} | ||||||
|         OUTPUT_CSV 1 |         OUTPUT_CSV 1 | ||||||
|         OUTPUT_VAR WIN32_VERSION_BINARY |         OUTPUT_VAR WIN32_VERSION_BINARY | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     # Create string version number for Win32 detailed attributes. |     # Create string version number for Win32 detailed attributes. | ||||||
|     CreateVersionString( |     CreateVersionString( | ||||||
|         VERSION_TXT ${VERSION_TXT} |         VERSION_TXT ${VERSION_TXT} | ||||||
|         BUILD_TYPE ${CMAKE_BUILD_TYPE} |         BUILD_TYPE ${CMAKE_BUILD_TYPE} | ||||||
|         SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} |         SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||||
|         SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} |         SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||||
|         OUTPUT_VAR WIN32_VERSION_STRING |         OUTPUT_VAR WIN32_VERSION_STRING | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     # Set Win32 icon path. |     # 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) |     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") |     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") | ||||||
| 
 | 
 | ||||||
|     # Hide console for release configurations. |     # Hide console for release configurations. | ||||||
|     if (${CMAKE_BUILD_TYPE} MATCHES "Release") |     if (${CMAKE_BUILD_TYPE} MATCHES "Release") | ||||||
|         target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup") |         target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup") | ||||||
|     endif() |     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() | else() | ||||||
|     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES}) |     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES}) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| if (UNLEASHED_RECOMP_FLATPAK) | if (UNLEASHED_RECOMP_FLATPAK) | ||||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  |     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||||
|         "UNLEASHED_RECOMP_FLATPAK" |         "UNLEASHED_RECOMP_FLATPAK" | ||||||
|         "GAME_INSTALL_DIRECTORY=\"/var/data\"" |         "GAME_INSTALL_DIRECTORY=\"/var/data\"" | ||||||
|     ) |     ) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| if (UNLEASHED_RECOMP_D3D12) | if (UNLEASHED_RECOMP_D3D12) | ||||||
|     find_package(directx-headers CONFIG REQUIRED) |     find_package(directx-headers CONFIG REQUIRED) | ||||||
|     find_package(directx12-agility CONFIG REQUIRED) |     find_package(directx12-agility CONFIG REQUIRED) | ||||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  |     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||||
|         UNLEASHED_RECOMP_D3D12 |         UNLEASHED_RECOMP_D3D12 | ||||||
|         D3D12MA_USING_DIRECTX_HEADERS |         D3D12MA_USING_DIRECTX_HEADERS | ||||||
|         D3D12MA_OPTIONS16_SUPPORTED |         D3D12MA_OPTIONS16_SUPPORTED | ||||||
|     ) |     ) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
|  | @ -324,19 +381,17 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux") | ||||||
|     target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED) |     target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| find_package(directx-dxc REQUIRED) |  | ||||||
| find_package(CURL REQUIRED) | find_package(CURL REQUIRED) | ||||||
| 
 | 
 | ||||||
| if (UNLEASHED_RECOMP_D3D12) | if (UNLEASHED_RECOMP_D3D12) | ||||||
|     file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) |     file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) | ||||||
|     add_custom_command(TARGET UnleashedRecomp POST_BUILD |     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-Core,IMPORTED_LOCATION_RELEASE> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12 | ||||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> ${CMAKE_CURRENT_BINARY_DIR}/D3D12 |         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12 | ||||||
|        COMMAND_EXPAND_LISTS |         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 |     target_link_libraries(UnleashedRecomp PRIVATE | ||||||
|         Microsoft::DirectX-Headers  |         Microsoft::DirectX-Headers  | ||||||
|  | @ -348,18 +403,17 @@ if (UNLEASHED_RECOMP_D3D12) | ||||||
|     ) |     ) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| file(CHMOD ${DIRECTX_DXC_TOOL} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) |  | ||||||
| 
 |  | ||||||
| if (WIN32) | if (WIN32) | ||||||
|     target_link_libraries(UnleashedRecomp PRIVATE |     target_link_libraries(UnleashedRecomp PRIVATE | ||||||
|         comctl32 |         comctl32 | ||||||
|         dwmapi |         dwmapi | ||||||
|         ntdll |         ntdll | ||||||
|         Shcore |         Shcore | ||||||
|         Synchronization |         Synchronization | ||||||
|         winmm |         winmm | ||||||
|  |         windowsapp | ||||||
|     ) |     ) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| target_link_libraries(UnleashedRecomp PRIVATE | target_link_libraries(UnleashedRecomp PRIVATE | ||||||
|     fmt::fmt |     fmt::fmt | ||||||
|  | @ -410,16 +464,16 @@ function(compile_shader FILE_PATH TARGET_NAME) | ||||||
| endfunction() | endfunction() | ||||||
| 
 | 
 | ||||||
| function(compile_vertex_shader FILE_PATH) | 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() | endfunction() | ||||||
| 
 | 
 | ||||||
| function(compile_pixel_shader FILE_PATH) | function(compile_pixel_shader FILE_PATH) | ||||||
|     compile_shader(${FILE_PATH} ps_6_0) |     compile_shader(${FILE_PATH} ps_6_0 -DUNLEASHED_RECOMP) | ||||||
| endfunction() | endfunction() | ||||||
| 
 | 
 | ||||||
| compile_pixel_shader(blend_color_alpha_ps) | compile_pixel_shader(blend_color_alpha_ps) | ||||||
| compile_vertex_shader(copy_vs) | compile_vertex_shader(copy_vs) | ||||||
| compile_pixel_shader(copy_color_ps) | compile_pixel_shader(copy_color_ps) | ||||||
| compile_pixel_shader(copy_depth_ps) | compile_pixel_shader(copy_depth_ps) | ||||||
| compile_pixel_shader(csd_filter_ps) | compile_pixel_shader(csd_filter_ps) | ||||||
| compile_vertex_shader(csd_no_tex_vs) | compile_vertex_shader(csd_no_tex_vs) | ||||||
|  | @ -433,7 +487,7 @@ compile_pixel_shader(gamma_correction_ps) | ||||||
| compile_pixel_shader(imgui_ps) | compile_pixel_shader(imgui_ps) | ||||||
| compile_vertex_shader(imgui_vs) | compile_vertex_shader(imgui_vs) | ||||||
| compile_pixel_shader(movie_ps) | 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_2x) | ||||||
| compile_pixel_shader(resolve_msaa_color_4x) | compile_pixel_shader(resolve_msaa_color_4x) | ||||||
| compile_pixel_shader(resolve_msaa_color_8x) | 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_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") | ||||||
| set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") | set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") | ||||||
| 
 | 
 | ||||||
| ## Miscellaneous ## | ## 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}/bc_diff/button_bc_diff.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/bc_diff/button_bc_diff.bin" ARRAY_NAME "g_button_bc_diff" COMPRESSION_TYPE "zstd") | ||||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.bin" ARRAY_NAME "g_im_font_atlas" COMPRESSION_TYPE "zstd") | BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.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/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/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") | 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 ## | ## 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/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_NAME "g_arrow_circle" COMPRESSION_TYPE "zstd") | ||||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd") | BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_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_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/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/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 ## | ## 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/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_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/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_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_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_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/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/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/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/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_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/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_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/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/default.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/default.dds" ARRAY_NAME "g_default" COMPRESSION_TYPE "zstd") | ||||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/effects_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/effects_volume.dds" ARRAY_NAME "g_effects_volume" COMPRESSION_TYPE "zstd") | BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/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_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_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/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/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_attenuation.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_attenuation.dds" ARRAY_NAME "g_music_attenuation" COMPRESSION_TYPE "zstd") | ||||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_volume.dds" ARRAY_NAME "g_music_volume" COMPRESSION_TYPE "zstd") | BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/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_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_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/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/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_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/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/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/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/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_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/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_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/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/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/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/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.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") | 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 ## | ## 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.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 ## | ## 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_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_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_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_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_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_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); |     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) | static void GuestThreadFunc(GuestThreadHandle* hThread) | ||||||
| { | { | ||||||
|  | #endif | ||||||
|     hThread->suspended.wait(true); |     hThread->suspended.wait(true); | ||||||
|     GuestThread::Start(hThread->params); |     GuestThread::Start(hThread->params); | ||||||
|  | #ifdef USE_PTHREAD | ||||||
|  |     return nullptr; | ||||||
|  | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GuestThreadHandle::GuestThreadHandle(const GuestThreadParams& params) | 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() | GuestThreadHandle::~GuestThreadHandle() | ||||||
| { | { | ||||||
|  | #ifdef USE_PTHREAD | ||||||
|  |     pthread_join(thread, nullptr); | ||||||
|  | #else | ||||||
|     if (thread.joinable()) |     if (thread.joinable()) | ||||||
|         thread.join(); |         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) | uint32_t GuestThreadHandle::Wait(uint32_t timeout) | ||||||
| { | { | ||||||
|     assert(timeout == INFINITE); |     assert(timeout == INFINITE); | ||||||
| 
 | 
 | ||||||
|  | #ifdef USE_PTHREAD | ||||||
|  |     pthread_join(thread, nullptr); | ||||||
|  | #else | ||||||
|     if (thread.joinable()) |     if (thread.joinable()) | ||||||
|         thread.join(); |         thread.join(); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|     return STATUS_WAIT_0; |     return STATUS_WAIT_0; | ||||||
| } | } | ||||||
|  | @ -80,27 +152,25 @@ uint32_t GuestThread::Start(const GuestThreadParams& params) | ||||||
|     return ctx.ppcContext.r3.u32; |     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) | GuestThreadHandle* GuestThread::Start(const GuestThreadParams& params, uint32_t* threadId) | ||||||
| { | { | ||||||
|     auto hThread = CreateKernelObject<GuestThreadHandle>(params); |     auto hThread = CreateKernelObject<GuestThreadHandle>(params); | ||||||
| 
 | 
 | ||||||
|     if (threadId != nullptr) |     if (threadId != nullptr) | ||||||
|         *threadId = GetThreadId(hThread->thread.get_id()); |     { | ||||||
|  |         *threadId = hThread->GetThreadId(); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     return hThread; |     return hThread; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t GuestThread::GetCurrentThreadId() | 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) | void GuestThread::SetLastError(uint32_t error) | ||||||
|  |  | ||||||
|  | @ -2,6 +2,15 @@ | ||||||
| 
 | 
 | ||||||
| #include <kernel/xdm.h> | #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) | #define CURRENT_THREAD_HANDLE uint32_t(-2) | ||||||
| 
 | 
 | ||||||
| struct GuestThreadContext | struct GuestThreadContext | ||||||
|  | @ -24,11 +33,17 @@ struct GuestThreadHandle : KernelObject | ||||||
| { | { | ||||||
|     GuestThreadParams params; |     GuestThreadParams params; | ||||||
|     std::atomic<bool> suspended; |     std::atomic<bool> suspended; | ||||||
|  | #ifdef USE_PTHREAD | ||||||
|  |     pthread_t thread; | ||||||
|  | #else | ||||||
|     std::thread thread; |     std::thread thread; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|     GuestThreadHandle(const GuestThreadParams& params); |     GuestThreadHandle(const GuestThreadParams& params); | ||||||
|     ~GuestThreadHandle() override; |     ~GuestThreadHandle() override; | ||||||
| 
 | 
 | ||||||
|  |     uint32_t GetThreadId() const; | ||||||
|  | 
 | ||||||
|     uint32_t Wait(uint32_t timeout) override; |     uint32_t Wait(uint32_t timeout) override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3437,6 +3437,7 @@ namespace plume { | ||||||
|                 adapter = adapterOption; |                 adapter = adapterOption; | ||||||
|                 d3d = deviceOption; |                 d3d = deviceOption; | ||||||
|                 shaderModel = dataShaderModel.HighestShaderModel; |                 shaderModel = dataShaderModel.HighestShaderModel; | ||||||
|  |                 capabilities.geometryShader = true; | ||||||
|                 capabilities.raytracing = rtSupportOption; |                 capabilities.raytracing = rtSupportOption; | ||||||
|                 capabilities.raytracingStateUpdate = rtStateUpdateSupportOption; |                 capabilities.raytracingStateUpdate = rtStateUpdateSupportOption; | ||||||
|                 capabilities.sampleLocations = samplePositionsOption; |                 capabilities.sampleLocations = samplePositionsOption; | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ | ||||||
| #undef ControlMask | #undef ControlMask | ||||||
| #undef Success | #undef Success | ||||||
| #elif defined(__APPLE__) | #elif defined(__APPLE__) | ||||||
| typedef struct _NSWindow NSWindow; | #include <SDL.h> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef SDL_VULKAN_ENABLED | #ifdef SDL_VULKAN_ENABLED | ||||||
|  | @ -52,7 +52,9 @@ namespace plume { | ||||||
|     }; |     }; | ||||||
| #elif defined(__APPLE__) | #elif defined(__APPLE__) | ||||||
|     struct RenderWindow { |     struct RenderWindow { | ||||||
|         NSWindow* window; |         SDL_Window* window; | ||||||
|  |         void* view; | ||||||
|  | 
 | ||||||
|         bool operator==(const struct RenderWindow& rhs) const { |         bool operator==(const struct RenderWindow& rhs) const { | ||||||
|             return window == rhs.window; |             return window == rhs.window; | ||||||
|         } |         } | ||||||
|  | @ -1784,6 +1786,9 @@ namespace plume { | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     struct RenderDeviceCapabilities { |     struct RenderDeviceCapabilities { | ||||||
|  |         // Geometry shaders.
 | ||||||
|  |         bool geometryShader = false; | ||||||
|  | 
 | ||||||
|         // Raytracing.
 |         // Raytracing.
 | ||||||
|         bool raytracing = false; |         bool raytracing = false; | ||||||
|         bool raytracingStateUpdate = false; |         bool raytracingStateUpdate = false; | ||||||
|  |  | ||||||
|  | @ -51,13 +51,18 @@ namespace plume { | ||||||
|         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, |         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, | ||||||
| #   elif defined(__linux__) | #   elif defined(__linux__) | ||||||
|         VK_KHR_XLIB_SURFACE_EXTENSION_NAME, |         VK_KHR_XLIB_SURFACE_EXTENSION_NAME, | ||||||
|  | #   elif defined(__APPLE__) | ||||||
|  |         VK_EXT_METAL_SURFACE_EXTENSION_NAME, | ||||||
| #   endif | #   endif | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     static const std::unordered_set<std::string> OptionalInstanceExtensions = { |     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 = { |     static const std::unordered_set<std::string> RequiredDeviceExtensions = { | ||||||
|         VK_KHR_SWAPCHAIN_EXTENSION_NAME, |         VK_KHR_SWAPCHAIN_EXTENSION_NAME, | ||||||
|         VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, |         VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, | ||||||
|  | @ -79,6 +84,8 @@ namespace plume { | ||||||
|         VK_KHR_PRESENT_ID_EXTENSION_NAME, |         VK_KHR_PRESENT_ID_EXTENSION_NAME, | ||||||
|         VK_KHR_PRESENT_WAIT_EXTENSION_NAME, |         VK_KHR_PRESENT_WAIT_EXTENSION_NAME, | ||||||
|         VK_GOOGLE_DISPLAY_TIMING_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.
 |     // 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; |         VkPipelineStageFlags flags = 0; | ||||||
| 
 | 
 | ||||||
|         if (stages & RenderBarrierStage::GRAPHICS) { |         if (stages & RenderBarrierStage::GRAPHICS) { | ||||||
|             flags |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; |             flags |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; | ||||||
|             flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; |             flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; | ||||||
|             flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_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_FRAGMENT_SHADER_BIT; | ||||||
|             flags |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; |             flags |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; | ||||||
|             flags |= VK_PIPELINE_STAGE_LATE_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); |             fprintf(stderr, "vkCreateXlibSurfaceKHR failed with error code 0x%X.\n", res); | ||||||
|             return; |             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 | #   endif | ||||||
| 
 | 
 | ||||||
|         VkBool32 presentSupported = false; |         VkBool32 presentSupported = false; | ||||||
|  | @ -2191,7 +2213,14 @@ namespace plume { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Handle the error silently.
 |         // 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)) { |         if ((res != VK_SUCCESS) && (res != VK_SUBOPTIMAL_KHR)) { | ||||||
|  | #endif | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -2360,6 +2389,8 @@ namespace plume { | ||||||
|         // The attributes width and height members do not include the border.
 |         // The attributes width and height members do not include the border.
 | ||||||
|         dstWidth = attributes.width; |         dstWidth = attributes.width; | ||||||
|         dstHeight = attributes.height; |         dstHeight = attributes.height; | ||||||
|  | #   elif defined(__APPLE__) | ||||||
|  |         SDL_GetWindowSizeInPixels(renderWindow.window, (int *)(&dstWidth), (int *)(&dstHeight)); | ||||||
| #   endif | #   endif | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -2683,9 +2714,10 @@ namespace plume { | ||||||
| 
 | 
 | ||||||
|         endActiveRenderPass(); |         endActiveRenderPass(); | ||||||
| 
 | 
 | ||||||
|  |         const bool geometryEnabled = device->capabilities.geometryShader; | ||||||
|         const bool rtEnabled = device->capabilities.raytracing; |         const bool rtEnabled = device->capabilities.raytracing; | ||||||
|         VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; |         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<VkBufferMemoryBarrier> bufferMemoryBarriers; | ||||||
|         thread_local std::vector<VkImageMemoryBarrier> imageMemoryBarriers; |         thread_local std::vector<VkImageMemoryBarrier> imageMemoryBarriers; | ||||||
|         bufferMemoryBarriers.clear(); |         bufferMemoryBarriers.clear(); | ||||||
|  | @ -2704,7 +2736,7 @@ namespace plume { | ||||||
|             bufferMemoryBarrier.offset = 0; |             bufferMemoryBarrier.offset = 0; | ||||||
|             bufferMemoryBarrier.size = interfaceBuffer->desc.size; |             bufferMemoryBarrier.size = interfaceBuffer->desc.size; | ||||||
|             bufferMemoryBarriers.emplace_back(bufferMemoryBarrier); |             bufferMemoryBarriers.emplace_back(bufferMemoryBarrier); | ||||||
|             srcStageMask |= toStageFlags(interfaceBuffer->barrierStages, rtEnabled); |             srcStageMask |= toStageFlags(interfaceBuffer->barrierStages, geometryEnabled, rtEnabled); | ||||||
|             interfaceBuffer->barrierStages = stages; |             interfaceBuffer->barrierStages = stages; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -2724,7 +2756,7 @@ namespace plume { | ||||||
|             imageMemoryBarrier.subresourceRange.layerCount = interfaceTexture->desc.arraySize; |             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; |             imageMemoryBarrier.subresourceRange.aspectMask = (interfaceTexture->desc.flags & RenderTextureFlag::DEPTH_TARGET) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; | ||||||
|             imageMemoryBarriers.emplace_back(imageMemoryBarrier); |             imageMemoryBarriers.emplace_back(imageMemoryBarrier); | ||||||
|             srcStageMask |= toStageFlags(interfaceTexture->barrierStages, rtEnabled); |             srcStageMask |= toStageFlags(interfaceTexture->barrierStages, geometryEnabled, rtEnabled); | ||||||
|             interfaceTexture->textureLayout = textureBarrier.layout; |             interfaceTexture->textureLayout = textureBarrier.layout; | ||||||
|             interfaceTexture->barrierStages = stages; |             interfaceTexture->barrierStages = stages; | ||||||
|         } |         } | ||||||
|  | @ -2890,6 +2922,9 @@ namespace plume { | ||||||
|             offsetVector.clear(); |             offsetVector.clear(); | ||||||
|             for (uint32_t i = 0; i < viewCount; i++) { |             for (uint32_t i = 0; i < viewCount; i++) { | ||||||
|                 const VulkanBuffer *interfaceBuffer = static_cast<const VulkanBuffer *>(views[i].buffer.ref); |                 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); |                 bufferVector.emplace_back((interfaceBuffer != nullptr) ? interfaceBuffer->vk : VK_NULL_HANDLE); | ||||||
|                 offsetVector.emplace_back(views[i].buffer.offset); |                 offsetVector.emplace_back(views[i].buffer.offset); | ||||||
|             } |             } | ||||||
|  | @ -3696,6 +3731,11 @@ namespace plume { | ||||||
|         bufferDeviceAddressFeatures.pNext = featuresChain; |         bufferDeviceAddressFeatures.pNext = featuresChain; | ||||||
|         featuresChain = &bufferDeviceAddressFeatures; |         featuresChain = &bufferDeviceAddressFeatures; | ||||||
| 
 | 
 | ||||||
|  |         VkPhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures = {}; | ||||||
|  |         portabilityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR; | ||||||
|  |         portabilityFeatures.pNext = featuresChain; | ||||||
|  |         featuresChain = &portabilityFeatures; | ||||||
|  | 
 | ||||||
|         VkPhysicalDeviceFeatures2 deviceFeatures = {}; |         VkPhysicalDeviceFeatures2 deviceFeatures = {}; | ||||||
|         deviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; |         deviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; | ||||||
|         deviceFeatures.pNext = featuresChain; |         deviceFeatures.pNext = featuresChain; | ||||||
|  | @ -3766,6 +3806,12 @@ namespace plume { | ||||||
|             createDeviceChain = &bufferDeviceAddressFeatures; |             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.
 |         // Retrieve the information for the queue families.
 | ||||||
|         uint32_t queueFamilyCount = 0; |         uint32_t queueFamilyCount = 0; | ||||||
|         vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr); |         vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr); | ||||||
|  | @ -3778,6 +3824,7 @@ namespace plume { | ||||||
|             uint32_t familyIndex = 0; |             uint32_t familyIndex = 0; | ||||||
|             uint32_t familySetBits = sizeof(uint32_t) * 8; |             uint32_t familySetBits = sizeof(uint32_t) * 8; | ||||||
|             uint32_t familyQueueCount = 0; |             uint32_t familyQueueCount = 0; | ||||||
|  |             bool familyUsed = false; | ||||||
|             for (uint32_t i = 0; i < queueFamilyCount; i++) { |             for (uint32_t i = 0; i < queueFamilyCount; i++) { | ||||||
|                 const VkQueueFamilyProperties &props = queueFamilyProperties[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.
 |                 // 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); |                 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; |                     familyIndex = i; | ||||||
|                     familySetBits = setBits; |                     familySetBits = setBits; | ||||||
|                     familyQueueCount = props.queueCount; |                     familyQueueCount = props.queueCount; | ||||||
|  |                     familyUsed = used; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -3912,6 +3962,7 @@ namespace plume { | ||||||
|         description.dedicatedVideoMemory = memoryHeapSize; |         description.dedicatedVideoMemory = memoryHeapSize; | ||||||
| 
 | 
 | ||||||
|         // Fill capabilities.
 |         // Fill capabilities.
 | ||||||
|  |         capabilities.geometryShader = deviceFeatures.features.geometryShader; | ||||||
|         capabilities.raytracing = rtSupported; |         capabilities.raytracing = rtSupported; | ||||||
|         capabilities.raytracingStateUpdate = false; |         capabilities.raytracingStateUpdate = false; | ||||||
|         capabilities.sampleLocations = sampleLocationsSupported; |         capabilities.sampleLocations = sampleLocationsSupported; | ||||||
|  | @ -3920,13 +3971,25 @@ namespace plume { | ||||||
|         capabilities.presentWait = presentWait; |         capabilities.presentWait = presentWait; | ||||||
|         capabilities.displayTiming = supportedOptionalExtensions.find(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME) != supportedOptionalExtensions.end(); |         capabilities.displayTiming = supportedOptionalExtensions.find(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME) != supportedOptionalExtensions.end(); | ||||||
|         capabilities.preferHDR = memoryHeapSize > (512 * 1024 * 1024); |         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; |         capabilities.triangleFan = true; | ||||||
|  | #endif | ||||||
|         capabilities.dynamicDepthBias = true; |         capabilities.dynamicDepthBias = true; | ||||||
|         capabilities.uma = (description.type == RenderDeviceType::INTEGRATED) && hasHostVisibleDeviceLocalMemory; |         capabilities.uma = (description.type == RenderDeviceType::INTEGRATED) && hasHostVisibleDeviceLocalMemory; | ||||||
|         capabilities.gpuUploadHeap = capabilities.uma; |         capabilities.gpuUploadHeap = capabilities.uma; | ||||||
| 
 | 
 | ||||||
|         // Fill Vulkan-only capabilities.
 |         // Fill Vulkan-only capabilities.
 | ||||||
|         loadStoreOpNoneSupported = supportedOptionalExtensions.find(VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME) != supportedOptionalExtensions.end(); |         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() { |     VulkanDevice::~VulkanDevice() { | ||||||
|  | @ -4253,6 +4316,10 @@ namespace plume { | ||||||
|         createInfo.ppEnabledLayerNames = nullptr; |         createInfo.ppEnabledLayerNames = nullptr; | ||||||
|         createInfo.enabledLayerCount = 0; |         createInfo.enabledLayerCount = 0; | ||||||
| 
 | 
 | ||||||
|  | #   ifdef __APPLE__ | ||||||
|  |         createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; | ||||||
|  | #   endif | ||||||
|  | 
 | ||||||
|         // Check for extensions.
 |         // Check for extensions.
 | ||||||
|         uint32_t extensionCount; |         uint32_t extensionCount; | ||||||
|         vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); |         vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); | ||||||
|  |  | ||||||
|  | @ -20,8 +20,13 @@ | ||||||
| #define VK_USE_PLATFORM_ANDROID_KHR | #define VK_USE_PLATFORM_ANDROID_KHR | ||||||
| #elif defined(__linux__) | #elif defined(__linux__) | ||||||
| #define VK_USE_PLATFORM_XLIB_KHR | #define VK_USE_PLATFORM_XLIB_KHR | ||||||
|  | #elif defined(__APPLE__) | ||||||
|  | #define VK_USE_PLATFORM_METAL_EXT | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | // For VK_KHR_portability_subset
 | ||||||
|  | #define VK_ENABLE_BETA_EXTENSIONS | ||||||
|  | 
 | ||||||
| #include <volk.h> | #include <volk.h> | ||||||
| 
 | 
 | ||||||
| #ifdef __clang__ | #ifdef __clang__ | ||||||
|  | @ -403,7 +408,9 @@ namespace plume { | ||||||
|         RenderDeviceDescription description; |         RenderDeviceDescription description; | ||||||
|         VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtPipelineProperties = {}; |         VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtPipelineProperties = {}; | ||||||
|         VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationProperties = {}; |         VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationProperties = {}; | ||||||
|  |         std::unique_ptr<RenderBuffer> nullBuffer = nullptr; | ||||||
|         bool loadStoreOpNoneSupported = false; |         bool loadStoreOpNoneSupported = false; | ||||||
|  |         bool nullDescriptorSupported = false; | ||||||
| 
 | 
 | ||||||
|         VulkanDevice(VulkanInterface *renderInterface, const std::string &preferredDeviceName); |         VulkanDevice(VulkanInterface *renderInterface, const std::string &preferredDeviceName); | ||||||
|         ~VulkanDevice() override; |         ~VulkanDevice() override; | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ | ||||||
| #include <magic_enum/magic_enum.hpp> | #include <magic_enum/magic_enum.hpp> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #define UNLEASHED_RECOMP | ||||||
| #include "../../tools/XenosRecomp/XenosRecomp/shader_common.h" | #include "../../tools/XenosRecomp/XenosRecomp/shader_common.h" | ||||||
| 
 | 
 | ||||||
| #ifdef UNLEASHED_RECOMP_D3D12 | #ifdef UNLEASHED_RECOMP_D3D12 | ||||||
|  |  | ||||||
|  | @ -166,6 +166,9 @@ void UpdateChecker::visitWebsite() | ||||||
| #elif defined(__linux__) | #elif defined(__linux__) | ||||||
|     std::string command = "xdg-open " + std::string(VISIT_URL) + " &"; |     std::string command = "xdg-open " + std::string(VISIT_URL) + " &"; | ||||||
|     std::system(command.c_str()); |     std::system(command.c_str()); | ||||||
|  | #elif defined(__APPLE__) | ||||||
|  |     std::string command = "open " + std::string(VISIT_URL) + " &"; | ||||||
|  |     std::system(command.c_str()); | ||||||
| #else | #else | ||||||
|     static_assert(false, "Visit website not implemented for this platform."); |     static_assert(false, "Visit website not implemented for this platform."); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -660,7 +660,7 @@ void KeQueryBasePriorityThread() | ||||||
| 
 | 
 | ||||||
| uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount) | 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 = true; | ||||||
|     hThread->suspended.wait(true); |     hThread->suspended.wait(true); | ||||||
|  |  | ||||||
|  | @ -306,26 +306,26 @@ uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const | ||||||
| 
 | 
 | ||||||
|         if (!exists) |         if (!exists) | ||||||
|         { |         { | ||||||
|             std::string root = ""; |             std::filesystem::path rootPath; | ||||||
| 
 | 
 | ||||||
|             if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA) |             if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA) | ||||||
|             { |             { | ||||||
|                 std::u8string savePathU8 = GetSavePath(true).u8string(); |                 rootPath = GetSavePath(true); | ||||||
|                 root = (const char *)(savePathU8.c_str()); |  | ||||||
|             } |             } | ||||||
|             else if (pContentData->dwContentType == XCONTENTTYPE_DLC) |             else if (pContentData->dwContentType == XCONTENTTYPE_DLC) | ||||||
|             { |             { | ||||||
|                 root = GAME_INSTALL_DIRECTORY "/dlc"; |                 rootPath = GetGamePath() / "dlc"; | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 root = GAME_INSTALL_DIRECTORY; |                 rootPath = GetGamePath(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             const std::string root = (const char*)rootPath.u8string().c_str(); | ||||||
|             XamRegisterContent(*pContentData, root); |             XamRegisterContent(*pContentData, root); | ||||||
| 
 | 
 | ||||||
|             std::error_code ec; |             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); |             XamRootCreate(szRootName, root); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| #include <stdafx.h> | #include <stdafx.h> | ||||||
|  | #ifdef __x86_64__ | ||||||
| #include <cpuid.h> | #include <cpuid.h> | ||||||
|  | #endif | ||||||
| #include <cpu/guest_thread.h> | #include <cpu/guest_thread.h> | ||||||
| #include <gpu/video.h> | #include <gpu/video.h> | ||||||
| #include <kernel/function.h> | #include <kernel/function.h> | ||||||
|  | @ -69,8 +71,10 @@ void KiSystemStartup() | ||||||
| 
 | 
 | ||||||
|     const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game"); |     const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game"); | ||||||
|     const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update"); |     const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update"); | ||||||
|     XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game"); |     const std::string gamePath = (const char*)(GetGamePath() / "game").u8string().c_str(); | ||||||
|     XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update"); |     const std::string updatePath = (const char*)(GetGamePath() / "update").u8string().c_str(); | ||||||
|  |     XamRegisterContent(gameContent, gamePath); | ||||||
|  |     XamRegisterContent(updateContent, updatePath); | ||||||
| 
 | 
 | ||||||
|     const auto saveFilePath = GetSaveFilePath(true); |     const auto saveFilePath = GetSaveFilePath(true); | ||||||
|     bool saveFileExists = std::filesystem::exists(saveFilePath); |     bool saveFileExists = std::filesystem::exists(saveFilePath); | ||||||
|  | @ -102,7 +106,7 @@ void KiSystemStartup() | ||||||
|     XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr); |     XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr); | ||||||
| 
 | 
 | ||||||
|     std::error_code ec; |     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()) |         if (file.is_directory()) | ||||||
|         { |         { | ||||||
|  | @ -165,10 +169,10 @@ uint32_t LdrLoadModule(const std::filesystem::path &path) | ||||||
|     return entry; |     return entry; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #ifdef __x86_64__ | ||||||
| __attribute__((constructor(101), target("no-avx,no-avx2"), noinline)) | __attribute__((constructor(101), target("no-avx,no-avx2"), noinline)) | ||||||
| void init() | void init() | ||||||
| { | { | ||||||
| #ifdef __x86_64__ |  | ||||||
|     uint32_t eax, ebx, ecx, edx; |     uint32_t eax, ebx, ecx, edx; | ||||||
| 
 | 
 | ||||||
|     // Execute CPUID for processor info and feature bits.
 |     // Execute CPUID for processor info and feature bits.
 | ||||||
|  | @ -185,8 +189,8 @@ void init() | ||||||
| 
 | 
 | ||||||
|         std::_Exit(1); |         std::_Exit(1); | ||||||
|     } |     } | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| int main(int argc, char *argv[]) | 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.
 |         // Set the current working directory to the executable's path.
 | ||||||
|         std::error_code ec; |         std::error_code ec; | ||||||
|         std::filesystem::current_path(os::process::GetExecutablePath().parent_path(), ec); |         std::filesystem::current_path(os::process::GetExecutableRoot(), ec); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     Config::Load(); |     Config::Load(); | ||||||
|  | @ -321,7 +325,7 @@ int main(int argc, char *argv[]) | ||||||
|     HostStartup(); |     HostStartup(); | ||||||
| 
 | 
 | ||||||
|     std::filesystem::path modulePath; |     std::filesystem::path modulePath; | ||||||
|     bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY, modulePath); |     bool isGameInstalled = Installer::checkGameInstall(GetGamePath(), modulePath); | ||||||
|     bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled; |     bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled; | ||||||
|     if (runInstallerWizard) |     if (runInstallerWizard) | ||||||
|     { |     { | ||||||
|  | @ -331,7 +335,7 @@ int main(int argc, char *argv[]) | ||||||
|             std::_Exit(1); |             std::_Exit(1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller)) |         if (!InstallerWizard::Run(GetGamePath(), isGameInstalled && forceDLCInstaller)) | ||||||
|         { |         { | ||||||
|             std::_Exit(0); |             std::_Exit(0); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -100,7 +100,7 @@ void ModLoader::Init() | ||||||
|     { |     { | ||||||
|         configIni = {}; |         configIni = {}; | ||||||
| 
 | 
 | ||||||
|         if (!configIni.read(GAME_INSTALL_DIRECTORY "/cpkredir.ini")) |         if (!configIni.read(GetGamePath() / "cpkredir.ini")) | ||||||
|             return; |             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() | std::filesystem::path os::process::GetWorkingDirectory() | ||||||
| { | { | ||||||
|     char cwd[PATH_MAX] = {}; |     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; |     inline bool g_consoleVisible; | ||||||
| 
 | 
 | ||||||
|     std::filesystem::path GetExecutablePath(); |     std::filesystem::path GetExecutablePath(); | ||||||
|  |     std::filesystem::path GetExecutableRoot(); | ||||||
|     std::filesystem::path GetWorkingDirectory(); |     std::filesystem::path GetWorkingDirectory(); | ||||||
|     bool SetWorkingDirectory(const std::filesystem::path& path); |     bool SetWorkingDirectory(const std::filesystem::path& path); | ||||||
|     bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {}); |     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> | #include <os/win32/registry_win32.inl> | ||||||
| #elif defined(__linux__) | #elif defined(__linux__) | ||||||
| #include <os/linux/registry_linux.inl> | #include <os/linux/registry_linux.inl> | ||||||
|  | #elif defined(__APPLE__) | ||||||
|  | #include <os/macos/registry_macos.inl> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -10,6 +10,11 @@ std::filesystem::path os::process::GetExecutablePath() | ||||||
|     return std::filesystem::path(exePath); |     return std::filesystem::path(exePath); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::filesystem::path os::process::GetExecutableRoot() | ||||||
|  | { | ||||||
|  |     return GetExecutablePath().remove_filename(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::filesystem::path os::process::GetWorkingDirectory() | std::filesystem::path os::process::GetWorkingDirectory() | ||||||
| { | { | ||||||
|     WCHAR workPath[MAX_PATH]; |     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; | float g_sideMargins = DEFAULT_SIDE_MARGINS; | ||||||
| 
 | 
 | ||||||
| std::vector<Button> g_buttons; | static std::vector<Button> g_buttons; | ||||||
| 
 | 
 | ||||||
| std::unordered_map<EButtonIcon, float> g_iconWidths = | std::unordered_map<EButtonIcon, float> g_iconWidths = | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -217,6 +217,9 @@ void GameWindow::Init(const char* sdlVideoDriver) | ||||||
|     s_renderWindow = s_pWindow; |     s_renderWindow = s_pWindow; | ||||||
| #elif defined(__linux__) | #elif defined(__linux__) | ||||||
|     s_renderWindow = { info.info.x11.display, info.info.x11.window }; |     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 | #else | ||||||
|     static_assert(false, "Unknown platform."); |     static_assert(false, "Unknown platform."); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -1146,7 +1146,11 @@ static void PickerStart(bool folderMode) { | ||||||
|     g_currentPickerVisible = true; |     g_currentPickerVisible = true; | ||||||
| 
 | 
 | ||||||
|     // Optional single thread mode for testing on systems that do not interact well with the separate thread being used for NFD.
 |     // 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; |     constexpr bool singleThreadMode = false; | ||||||
|  | #endif | ||||||
|     if (singleThreadMode) |     if (singleThreadMode) | ||||||
|         PickerThreadProcess(); |         PickerThreadProcess(); | ||||||
|     else |     else | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ static ImFont* g_fntSeurat; | ||||||
| 
 | 
 | ||||||
| std::string g_text; | std::string g_text; | ||||||
| int g_result; | int g_result; | ||||||
| std::vector<std::string> g_buttons; | static std::vector<std::string> g_buttons; | ||||||
| int g_defaultButtonIndex; | int g_defaultButtonIndex; | ||||||
| int g_cancelButtonIndex; | int g_cancelButtonIndex; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| #include "paths.h" | #include "paths.h" | ||||||
| #include <os/process.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(); | std::filesystem::path g_userPath = BuildUserPath(); | ||||||
| 
 | 
 | ||||||
| bool CheckPortable() | bool CheckPortable() | ||||||
|  | @ -22,18 +22,24 @@ std::filesystem::path BuildUserPath() | ||||||
|         userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY; |         userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY; | ||||||
| 
 | 
 | ||||||
|     CoTaskMemFree(knownPath); |     CoTaskMemFree(knownPath); | ||||||
| #elif defined(__linux__) | #elif defined(__linux__) || defined(__APPLE__) | ||||||
|     const char* homeDir = getenv("HOME"); |     const char* homeDir = getenv("HOME"); | ||||||
|  | #if defined(__linux__) | ||||||
|     if (homeDir == nullptr) |     if (homeDir == nullptr) | ||||||
|     { |     { | ||||||
|         homeDir = getpwuid(getuid())->pw_dir; |         homeDir = getpwuid(getuid())->pw_dir; | ||||||
|     } |     } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|     if (homeDir != nullptr) |     if (homeDir != nullptr) | ||||||
|     { |     { | ||||||
|         // Prefer to store in the .config directory if it exists. Use the home directory otherwise.
 |         // Prefer to store in the .config directory if it exists. Use the home directory otherwise.
 | ||||||
|         std::filesystem::path homePath = homeDir; |         std::filesystem::path homePath = homeDir; | ||||||
|  | #if defined(__linux__) | ||||||
|         std::filesystem::path configPath = homePath / ".config"; |         std::filesystem::path configPath = homePath / ".config"; | ||||||
|  | #else | ||||||
|  |         std::filesystem::path configPath = homePath / "Library" / "Application Support"; | ||||||
|  | #endif | ||||||
|         if (std::filesystem::exists(configPath)) |         if (std::filesystem::exists(configPath)) | ||||||
|             userPath = configPath / USER_DIRECTORY; |             userPath = configPath / USER_DIRECTORY; | ||||||
|         else |         else | ||||||
|  |  | ||||||
|  | @ -10,15 +10,22 @@ | ||||||
| 
 | 
 | ||||||
| extern std::filesystem::path g_executableRoot; | extern std::filesystem::path g_executableRoot; | ||||||
| 
 | 
 | ||||||
| inline std::filesystem::path GetGamePath() |  | ||||||
| { |  | ||||||
|     return GAME_INSTALL_DIRECTORY; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool CheckPortable(); | bool CheckPortable(); | ||||||
| std::filesystem::path BuildUserPath(); | std::filesystem::path BuildUserPath(); | ||||||
| const std::filesystem::path& GetUserPath(); | 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) | inline std::filesystem::path GetSavePath(bool checkForMods) | ||||||
| { | { | ||||||
|     if (checkForMods && !ModLoader::s_saveFilePath.empty()) |     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.xex" | ||||||
|         "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xexp" |         "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xexp" | ||||||
|         "${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml" |         "${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml" | ||||||
|  |     USES_TERMINAL | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| add_custom_command( | add_custom_command( | ||||||
|  | @ -53,6 +54,7 @@ target_compile_definitions(XenosRecomp PRIVATE | ||||||
|     XENOS_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\"  |     XENOS_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\"  | ||||||
|     XENOS_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\" |     XENOS_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\" | ||||||
|     XENOS_RECOMP_INCLUDE_INPUT=\"${XENOS_RECOMP_INCLUDE}\" |     XENOS_RECOMP_INCLUDE_INPUT=\"${XENOS_RECOMP_INCLUDE}\" | ||||||
|  |     UNLEASHED_RECOMP | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| file(GLOB XENOS_RECOMP_SOURCES  | file(GLOB XENOS_RECOMP_SOURCES  | ||||||
|  | @ -70,6 +72,7 @@ add_custom_command( | ||||||
|         "${CMAKE_CURRENT_SOURCE_DIR}/private/shader_decompressed.ar"  |         "${CMAKE_CURRENT_SOURCE_DIR}/private/shader_decompressed.ar"  | ||||||
|         ${XENOS_RECOMP_SOURCES}  |         ${XENOS_RECOMP_SOURCES}  | ||||||
|         ${XENOS_RECOMP_INCLUDE} |         ${XENOS_RECOMP_INCLUDE} | ||||||
|  |     USES_TERMINAL | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| add_library(UnleashedRecompLib  | add_library(UnleashedRecompLib  | ||||||
|  | @ -79,4 +82,5 @@ add_library(UnleashedRecompLib | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| target_include_directories(UnleashedRecompLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) | 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") | 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] | > [!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. | > 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 | ## 4. Build the Project | ||||||
| 
 | 
 | ||||||
| ### Windows | ### Windows | ||||||
|  | @ -81,3 +96,22 @@ cmake --build ./out/build/linux-release --target UnleashedRecomp | ||||||
| ```bash | ```bash | ||||||
| ./UnleashedRecomp | ./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}/o1heap") | ||||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL") | add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL") | ||||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL_mixer") | 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", |             "name": "directx12-agility", | ||||||
|             "platform": "windows" |             "platform": "windows" | ||||||
|         }, |         }, | ||||||
|         "directx-dxc", |  | ||||||
|         "freetype", |         "freetype", | ||||||
|         "curl" |         "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