mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2025-03-04 18:55:21 +01:00
Add macOS Support
This commit is contained in:
parent
0c78154c2d
commit
f4cfe6e4b6
33
.github/macos/Info.plist.in
vendored
Normal file
33
.github/macos/Info.plist.in
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>Zelda64Recompiled</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||||
|
<key>LSApplicationCategoryType</key>
|
||||||
|
<string>public.app-category.games</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>11</string>
|
||||||
|
<key>LSEnvironment</key>
|
||||||
|
<dict>
|
||||||
|
<key>MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>MVK_CONFIG_USE_METAL_PRIVATE_API</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>MVK_CONFIG_RESUME_LOST_DEVICE</key>
|
||||||
|
<string>1</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
8
.github/macos/MoltenVK_icd.json
vendored
Normal file
8
.github/macos/MoltenVK_icd.json
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"file_format_version": "1.0.0",
|
||||||
|
"ICD": {
|
||||||
|
"library_path": "../../../Frameworks/libMoltenVK.dylib",
|
||||||
|
"api_version": "1.2.0",
|
||||||
|
"is_portability_driver": true
|
||||||
|
}
|
||||||
|
}
|
12
.github/macos/entitlements.plist
vendored
Normal file
12
.github/macos/entitlements.plist
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.cs.allow-jit</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.disable-library-validation</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
44
.github/macos/fixup_bundle.cmake
vendored
Normal file
44
.github/macos/fixup_bundle.cmake
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
include(BundleUtilities)
|
||||||
|
|
||||||
|
# Check for pkgx installation
|
||||||
|
find_program(PKGX_EXECUTABLE pkgx)
|
||||||
|
|
||||||
|
# Xcode generator puts the build type in the build directory
|
||||||
|
set(BUILD_PREFIX "")
|
||||||
|
if (CMAKE_GENERATOR STREQUAL "Xcode")
|
||||||
|
set(BUILD_PREFIX "${CMAKE_BUILD_TYPE}/")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Use generator expressions to get the absolute path to the bundle
|
||||||
|
set(APPS "${BUILD_PREFIX}Zelda64Recompiled.app/Contents/MacOS/Zelda64Recompiled")
|
||||||
|
|
||||||
|
# Set up framework search paths
|
||||||
|
set(DIRS "${BUILD_PREFIX}Zelda64Recompiled.app/Contents/Frameworks")
|
||||||
|
|
||||||
|
# Detect if we're using pkgx
|
||||||
|
if(PKGX_EXECUTABLE)
|
||||||
|
message(STATUS "pkgx detected, adding pkgx directories to framework search path")
|
||||||
|
list(APPEND DIRS "$ENV{HOME}/.pkgx/")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Convert all paths to absolute paths
|
||||||
|
file(REAL_PATH ${APPS} APPS)
|
||||||
|
|
||||||
|
set(RESOLVED_DIRS "")
|
||||||
|
foreach(DIR IN LISTS DIRS)
|
||||||
|
# Handle home directory expansion
|
||||||
|
string(REPLACE "~" "$ENV{HOME}" DIR "${DIR}")
|
||||||
|
# Convert to absolute path, but don't fail if directory doesn't exist
|
||||||
|
if(EXISTS "${DIR}")
|
||||||
|
file(REAL_PATH "${DIR}" RESOLVED_DIR)
|
||||||
|
list(APPEND RESOLVED_DIRS "${RESOLVED_DIR}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Debug output
|
||||||
|
message(STATUS "Bundle fixup paths:")
|
||||||
|
message(STATUS " App: ${APPS}")
|
||||||
|
message(STATUS " Search dirs: ${RESOLVED_DIRS}")
|
||||||
|
|
||||||
|
# Fix up the bundle
|
||||||
|
fixup_bundle("${APPS}" "" "${RESOLVED_DIRS}")
|
14
.github/macos/macports.yaml
vendored
Normal file
14
.github/macos/macports.yaml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
version: '2.9.3'
|
||||||
|
prefix: '/opt/local'
|
||||||
|
variants:
|
||||||
|
select:
|
||||||
|
- aqua
|
||||||
|
- metal
|
||||||
|
deselect: x11
|
||||||
|
ports:
|
||||||
|
- name: clang-18
|
||||||
|
- name: llvm-18
|
||||||
|
- name: libsdl2
|
||||||
|
select: universal
|
||||||
|
- name: freetype
|
||||||
|
select: universal
|
71
.github/workflows/validate.yml
vendored
71
.github/workflows/validate.yml
vendored
@ -283,3 +283,74 @@ jobs:
|
|||||||
name: Zelda64Recompiled-PDB-${{ matrix.type }}
|
name: Zelda64Recompiled-PDB-${{ matrix.type }}
|
||||||
path: |
|
path: |
|
||||||
Zelda64Recompiled.pdb
|
Zelda64Recompiled.pdb
|
||||||
|
build-macos:
|
||||||
|
runs-on: blaze/macos-14
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
type: [ Debug, Release ]
|
||||||
|
name: macos (x64, arm64, ${{ matrix.type }})
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha || github.ref }}
|
||||||
|
submodules: recursive
|
||||||
|
- name: ccache
|
||||||
|
uses: hendrikmuhs/ccache-action@v1.2
|
||||||
|
with:
|
||||||
|
key: ${{ runner.os }}-z64re-ccache-${{ matrix.type }}
|
||||||
|
- name: Homebrew Setup
|
||||||
|
run: |
|
||||||
|
brew install ninja
|
||||||
|
brew uninstall --ignore-dependencies libpng freetype
|
||||||
|
- name: MacPorts Setup
|
||||||
|
uses: melusina-org/setup-macports@v1
|
||||||
|
id: 'macports'
|
||||||
|
with:
|
||||||
|
parameters: '.github/macos/macports.yaml'
|
||||||
|
- name: Prepare Build
|
||||||
|
run: |-
|
||||||
|
git clone ${{ secrets.ZRE_REPO_WITH_PAT }}
|
||||||
|
./zre/process.sh
|
||||||
|
cp ./zre/mm_shader_cache.bin ./shadercache/
|
||||||
|
- name: Build N64Recomp & RSPRecomp
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/Mr-Wiseguy/N64Recomp.git --recurse-submodules N64RecompSource
|
||||||
|
cd N64RecompSource
|
||||||
|
git checkout ${{ inputs.N64RECOMP_COMMIT }}
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
# enable ccache
|
||||||
|
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||||
|
|
||||||
|
# Build N64Recomp & RSPRecomp
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_MAKE_PROGRAM=ninja -G Ninja -S . -B cmake-build
|
||||||
|
cmake --build cmake-build --config Release --target N64Recomp -j $(sysctl -n hw.ncpu)
|
||||||
|
cmake --build cmake-build --config Release --target RSPRecomp -j $(sysctl -n hw.ncpu)
|
||||||
|
|
||||||
|
# Copy N64Recomp & RSPRecomp to root directory
|
||||||
|
cp cmake-build/N64Recomp ..
|
||||||
|
cp cmake-build/RSPRecomp ..
|
||||||
|
- name: Run N64Recomp & RSPRecomp
|
||||||
|
run: |
|
||||||
|
./N64Recomp us.rev1.toml
|
||||||
|
./RSPRecomp aspMain.us.rev1.toml
|
||||||
|
./RSPRecomp njpgdspMain.us.rev1.toml
|
||||||
|
- name: Build ZeldaRecomp
|
||||||
|
run: |-
|
||||||
|
# enable ccache
|
||||||
|
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||||
|
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_MAKE_PROGRAM=ninja -G Ninja -S . -B cmake-build \
|
||||||
|
-DPATCHES_LD=/opt/local/bin/ld.lld-mp-18 -DPATCHES_OBJCOPY=/opt/local/bin/llvm-objcopy-mp-18 -DCMAKE_AR=/opt/local/bin/llvm-ar-mp-18 -DPATCHES_C_COMPILER=/opt/local/bin/clang-mp-18 \
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||||
|
cmake --build cmake-build --config ${{ matrix.type }} --target Zelda64Recompiled -j $(sysctl -n hw.ncpu)
|
||||||
|
- name: Prepare Archive
|
||||||
|
run: |
|
||||||
|
mv cmake-build/Zelda64Recompiled.app Zelda64Recompiled.app
|
||||||
|
zip -r -y Zelda64Recompiled.zip Zelda64Recompiled.app
|
||||||
|
- name: Archive Zelda64Recomp
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Zelda64Recompiled-${{ runner.os }}-${{ matrix.type }}
|
||||||
|
path: Zelda64Recompiled.zip
|
||||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
.vscode/c_cpp_properties.json
|
.vscode/c_cpp_properties.json
|
||||||
.vscode/launch.json
|
.vscode/launch.json
|
||||||
|
.vscode/tasks.json
|
||||||
|
|
||||||
# Input elf and rom files
|
# Input elf and rom files
|
||||||
*.elf
|
*.elf
|
||||||
@ -62,3 +63,9 @@ RSPRecomp
|
|||||||
|
|
||||||
# Controller mappings file
|
# Controller mappings file
|
||||||
gamecontrollerdb.txt
|
gamecontrollerdb.txt
|
||||||
|
|
||||||
|
# Cmake build directory
|
||||||
|
.cache
|
||||||
|
.idea
|
||||||
|
build-*
|
||||||
|
cmake-build-*
|
134
CMakeLists.txt
134
CMakeLists.txt
@ -1,5 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
project(Zelda64Recompiled)
|
|
||||||
|
if (APPLE) # has to be set before the first project() or enable_language()
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum OS X deployment version")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
project(Zelda64Recompiled LANGUAGES C CXX)
|
||||||
set(CMAKE_C_STANDARD 17)
|
set(CMAKE_C_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
@ -16,6 +21,10 @@ if (WIN32)
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
enable_language(OBJC OBJCXX)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:
|
# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:
|
||||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
|
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
|
||||||
cmake_policy(SET CMP0135 NEW)
|
cmake_policy(SET CMP0135 NEW)
|
||||||
@ -31,7 +40,6 @@ endif()
|
|||||||
set(RT64_STATIC TRUE)
|
set(RT64_STATIC TRUE)
|
||||||
set(RT64_SDL_WINDOW_VULKAN TRUE)
|
set(RT64_SDL_WINDOW_VULKAN TRUE)
|
||||||
add_compile_definitions(HLSL_CPU)
|
add_compile_definitions(HLSL_CPU)
|
||||||
|
|
||||||
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/rt64 ${CMAKE_BINARY_DIR}/rt64)
|
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/rt64 ${CMAKE_BINARY_DIR}/rt64)
|
||||||
|
|
||||||
# set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
|
# set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
|
||||||
@ -137,11 +145,12 @@ add_custom_target(DownloadGameControllerDB
|
|||||||
DEPENDS ${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt)
|
DEPENDS ${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt)
|
||||||
|
|
||||||
# Main executable
|
# Main executable
|
||||||
add_executable(Zelda64Recompiled)
|
add_executable(Zelda64Recompiled MACOSX_BUNDLE)
|
||||||
add_dependencies(Zelda64Recompiled DownloadGameControllerDB)
|
add_dependencies(Zelda64Recompiled DownloadGameControllerDB)
|
||||||
|
|
||||||
set (SOURCES
|
set (SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/src/main/main.cpp
|
${CMAKE_SOURCE_DIR}/src/main/main.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/src/main/support.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/main/register_overlays.cpp
|
${CMAKE_SOURCE_DIR}/src/main/register_overlays.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/main/register_patches.cpp
|
${CMAKE_SOURCE_DIR}/src/main/register_patches.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/main/rt64_render_context.cpp
|
${CMAKE_SOURCE_DIR}/src/main/rt64_render_context.cpp
|
||||||
@ -189,6 +198,10 @@ set (SOURCES
|
|||||||
${CMAKE_SOURCE_DIR}/lib/RmlUi/Backends/RmlUi_Platform_SDL.cpp
|
${CMAKE_SOURCE_DIR}/lib/RmlUi/Backends/RmlUi_Platform_SDL.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
list(APPEND SOURCES ${CMAKE_SOURCE_DIR}/src/main/support_apple.mm)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_include_directories(Zelda64Recompiled PRIVATE
|
target_include_directories(Zelda64Recompiled PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime/N64Recomp/include
|
${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime/N64Recomp/include
|
||||||
@ -267,6 +280,113 @@ if (WIN32)
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_sources(Zelda64Recompiled PRIVATE ${CMAKE_SOURCE_DIR}/icons/app.rc)
|
target_sources(Zelda64Recompiled PRIVATE ${CMAKE_SOURCE_DIR}/icons/app.rc)
|
||||||
|
target_link_libraries(Zelda64Recompiled PRIVATE SDL2)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
|
target_include_directories(Zelda64Recompiled PRIVATE ${SDL2_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
add_compile_definitions("RT64_SDL_WINDOW_METAL")
|
||||||
|
|
||||||
|
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
target_link_libraries(Zelda64Recompiled PRIVATE ${CMAKE_DL_LIBS} Threads::Threads SDL2::SDL2)
|
||||||
|
|
||||||
|
# Set bundle properties
|
||||||
|
set_target_properties(Zelda64Recompiled PROPERTIES
|
||||||
|
MACOSX_BUNDLE TRUE
|
||||||
|
MACOSX_BUNDLE_BUNDLE_NAME "Zelda64Recompiled"
|
||||||
|
MACOSX_BUNDLE_GUI_IDENTIFIER "com.github.zelda64recompiled"
|
||||||
|
MACOSX_BUNDLE_BUNDLE_VERSION "1.0"
|
||||||
|
MACOSX_BUNDLE_SHORT_VERSION_STRING "1.0"
|
||||||
|
MACOSX_BUNDLE_ICON_FILE "AppIcon.icns"
|
||||||
|
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_BINARY_DIR}/Info.plist
|
||||||
|
)
|
||||||
|
|
||||||
|
set(ICON_SOURCE ${CMAKE_SOURCE_DIR}/icons/512.png)
|
||||||
|
set(ICONSET_DIR ${CMAKE_BINARY_DIR}/AppIcon.iconset)
|
||||||
|
set(ICNS_FILE ${CMAKE_BINARY_DIR}/resources/AppIcon.icns)
|
||||||
|
|
||||||
|
# Create iconset directory and add PNG file
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${ICONSET_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${ICONSET_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${ICON_SOURCE} ${ICONSET_DIR}/icon_512x512.png
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${ICON_SOURCE} ${ICONSET_DIR}/icon_512x512@2x.png
|
||||||
|
COMMAND touch ${ICONSET_DIR}
|
||||||
|
COMMENT "Creating iconset directory and copying PNG file"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert iconset to icns
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${ICNS_FILE}
|
||||||
|
DEPENDS ${ICONSET_DIR}
|
||||||
|
COMMAND iconutil -c icns ${ICONSET_DIR} -o ${ICNS_FILE}
|
||||||
|
COMMENT "Converting iconset to icns"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Custom target to ensure icns creation
|
||||||
|
add_custom_target(create_icns ALL DEPENDS ${ICNS_FILE})
|
||||||
|
|
||||||
|
# Set source file properties for the resulting icns file
|
||||||
|
set_source_files_properties(${ICNS_FILE} PROPERTIES
|
||||||
|
MACOSX_PACKAGE_LOCATION "Resources"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add the icns file to the executable target
|
||||||
|
target_sources(Zelda64Recompiled PRIVATE ${ICNS_FILE})
|
||||||
|
|
||||||
|
# Ensure Zelda64Recompiled depends on create_icns
|
||||||
|
add_dependencies(Zelda64Recompiled create_icns)
|
||||||
|
|
||||||
|
# Configure Info.plist
|
||||||
|
configure_file(${CMAKE_SOURCE_DIR}/.github/macos/Info.plist.in ${CMAKE_BINARY_DIR}/Info.plist @ONLY)
|
||||||
|
|
||||||
|
# Install the app bundle
|
||||||
|
install(TARGETS Zelda64Recompiled BUNDLE DESTINATION .)
|
||||||
|
|
||||||
|
# Define the path to the entitlements file
|
||||||
|
set(ENTITLEMENTS_FILE ${CMAKE_SOURCE_DIR}/.github/macos/entitlements.plist)
|
||||||
|
|
||||||
|
# Ensure the entitlements file exists
|
||||||
|
if(NOT EXISTS ${ENTITLEMENTS_FILE})
|
||||||
|
message(FATAL_ERROR "Entitlements file not found at ${ENTITLEMENTS_FILE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Post-build steps for macOS bundle
|
||||||
|
add_custom_command(TARGET Zelda64Recompiled POST_BUILD
|
||||||
|
# Copy and fix frameworks first
|
||||||
|
COMMAND ${CMAKE_COMMAND} -D CMAKE_BUILD_TYPE=$<CONFIG> -D CMAKE_GENERATOR=${CMAKE_GENERATOR} -P ${CMAKE_SOURCE_DIR}/.github/macos/fixup_bundle.cmake
|
||||||
|
|
||||||
|
# Copy all resources
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets ${CMAKE_BINARY_DIR}/temp_assets
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/temp_assets/scss
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/temp_assets $<TARGET_BUNDLE_DIR:Zelda64Recompiled>/Contents/Resources/assets
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/temp_assets
|
||||||
|
|
||||||
|
# Copy Vulkan ICD files
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_BUNDLE_DIR:Zelda64Recompiled>/Contents/Resources/vulkan/icd.d
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/.github/macOS/MoltenVK_icd.json $<TARGET_BUNDLE_DIR:Zelda64Recompiled>/Contents/Resources/vulkan/icd.d/
|
||||||
|
|
||||||
|
# Copy controller database
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt $<TARGET_BUNDLE_DIR:Zelda64Recompiled>/Contents/Resources/
|
||||||
|
|
||||||
|
# Set RPATH
|
||||||
|
COMMAND install_name_tool -add_rpath "@executable_path/../Frameworks/" $<TARGET_BUNDLE_DIR:Zelda64Recompiled>/Contents/MacOS/Zelda64Recompiled
|
||||||
|
|
||||||
|
# Apply JIT workaround
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Applying JIT compilation workaround"
|
||||||
|
COMMAND /bin/bash -c "printf '\\x07' | dd of=$<TARGET_FILE:Zelda64Recompiled> bs=1 seek=160 count=1 conv=notrunc"
|
||||||
|
|
||||||
|
# Finally sign the whole bundle with runtime option and entitlements
|
||||||
|
COMMAND codesign --deep --force --options runtime --sign - --entitlements ${ENTITLEMENTS_FILE} $<TARGET_BUNDLE_DIR:Zelda64Recompiled>
|
||||||
|
|
||||||
|
COMMENT "Performing post-build steps for macOS bundle"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
@ -302,7 +422,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|||||||
message(STATUS "FREETYPE_LIBRARIES = ${FREETYPE_LIBRARIES}")
|
message(STATUS "FREETYPE_LIBRARIES = ${FREETYPE_LIBRARIES}")
|
||||||
|
|
||||||
include_directories(${FREETYPE_LIBRARIES})
|
include_directories(${FREETYPE_LIBRARIES})
|
||||||
target_link_libraries(Zelda64Recompiled PRIVATE ${FREETYPE_LIBRARIES})
|
target_link_libraries(Zelda64Recompiled PRIVATE ${FREETYPE_LIBRARIES} SDL2::SDL2)
|
||||||
|
|
||||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||||
@ -314,7 +434,6 @@ endif()
|
|||||||
target_link_libraries(Zelda64Recompiled PRIVATE
|
target_link_libraries(Zelda64Recompiled PRIVATE
|
||||||
PatchesLib
|
PatchesLib
|
||||||
RecompiledFuncs
|
RecompiledFuncs
|
||||||
SDL2
|
|
||||||
librecomp
|
librecomp
|
||||||
ultramodern
|
ultramodern
|
||||||
rt64
|
rt64
|
||||||
@ -342,6 +461,11 @@ else()
|
|||||||
if (APPLE)
|
if (APPLE)
|
||||||
# Apple's binary is universal, so it'll work on both x86_64 and arm64
|
# Apple's binary is universal, so it'll work on both x86_64 and arm64
|
||||||
set (DXC "DYLD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/lib/arm64" "${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/bin/arm64/dxc-macos")
|
set (DXC "DYLD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/lib/arm64" "${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/bin/arm64/dxc-macos")
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
|
||||||
|
set(SPIRVCROSS "DYLD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/spirv-cross/lib/x64" "${PROJECT_SOURCE_DIR}/lib/rt64//src/contrib/spirv-cross/bin/x64/spirv-cross")
|
||||||
|
else()
|
||||||
|
set(SPIRVCROSS "DYLD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/spirv-cross/lib/arm64" "${PROJECT_SOURCE_DIR}/lib/rt64//src/contrib/spirv-cross/bin/x64/spirv-cross")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
|
||||||
set (DXC "LD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/lib/x64" "${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/bin/x64/dxc")
|
set (DXC "LD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/lib/x64" "${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/bin/x64/dxc")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef __ZELDA_RENDER_H__
|
#ifndef __ZELDA_RENDER_H__
|
||||||
#define __ZELDA_RENDER_H__
|
#define __ZELDA_RENDER_H__
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <set>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include "common/rt64_user_configuration.h"
|
#include "common/rt64_user_configuration.h"
|
||||||
@ -32,7 +32,7 @@ namespace zelda64 {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<RT64::Application> app;
|
std::unique_ptr<RT64::Application> app;
|
||||||
std::unordered_set<std::filesystem::path> enabled_texture_packs;
|
std::set<std::filesystem::path> enabled_texture_packs;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<ultramodern::renderer::RendererContext> create_render_context(uint8_t *rdram, ultramodern::renderer::WindowHandle window_handle, bool developer_mode);
|
std::unique_ptr<ultramodern::renderer::RendererContext> create_render_context(uint8_t *rdram, ultramodern::renderer::WindowHandle window_handle, bool developer_mode);
|
||||||
|
14
include/zelda_support.h
Normal file
14
include/zelda_support.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __ZELDA_SUPPORT_H__
|
||||||
|
#define __ZELDA_SUPPORT_H__
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace zelda64 {
|
||||||
|
void dispatch_on_main_thread(std::function<void()> func);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const char* get_bundle_resource_directory();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1 +1 @@
|
|||||||
Subproject commit 4c7acc6eb11a662e6024105ace37242584b977f2
|
Subproject commit 0fa969865f1b8cbdbcf2116a000e7ab1e2e50b57
|
2
lib/rt64
2
lib/rt64
@ -1 +1 @@
|
|||||||
Subproject commit 1db8c347caa9dd356050777ac79a81f1ccfa462b
|
Subproject commit 3cb338b321a99fd203fde86ebda9bf635bbd8f9f
|
@ -13,6 +13,8 @@
|
|||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include "common/rt64_apple.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr std::u8string_view general_filename = u8"general.json";
|
constexpr std::u8string_view general_filename = u8"general.json";
|
||||||
@ -145,8 +147,8 @@ std::filesystem::path zelda64::get_app_folder_path() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CoTaskMemFree(known_path);
|
CoTaskMemFree(known_path);
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__) || defined(__APPLE__)
|
||||||
// check for APP_FOLDER_PATH env var used by AppImage
|
// check for APP_FOLDER_PATH env var
|
||||||
if (getenv("APP_FOLDER_PATH") != nullptr) {
|
if (getenv("APP_FOLDER_PATH") != nullptr) {
|
||||||
return std::filesystem::path{getenv("APP_FOLDER_PATH")};
|
return std::filesystem::path{getenv("APP_FOLDER_PATH")};
|
||||||
}
|
}
|
||||||
@ -154,7 +156,11 @@ std::filesystem::path zelda64::get_app_folder_path() {
|
|||||||
const char *homedir;
|
const char *homedir;
|
||||||
|
|
||||||
if ((homedir = getenv("HOME")) == nullptr) {
|
if ((homedir = getenv("HOME")) == nullptr) {
|
||||||
|
#if defined(__linux__)
|
||||||
homedir = getpwuid(getuid())->pw_dir;
|
homedir = getpwuid(getuid())->pw_dir;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
homedir = GetHomeDirectory();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (homedir != nullptr) {
|
if (homedir != nullptr) {
|
||||||
|
@ -52,7 +52,12 @@ void exit_error(const char* str, Ts ...args) {
|
|||||||
// TODO pop up an error
|
// TODO pop up an error
|
||||||
((void)fprintf(stderr, str, args), ...);
|
((void)fprintf(stderr, str, args), ...);
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
std::_Exit(EXIT_FAILURE);
|
||||||
|
#else
|
||||||
std::quick_exit(EXIT_FAILURE);
|
std::quick_exit(EXIT_FAILURE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ultramodern::gfx_callbacks_t::gfx_data_t create_gfx() {
|
ultramodern::gfx_callbacks_t::gfx_data_t create_gfx() {
|
||||||
@ -126,7 +131,9 @@ SDL_Window* window;
|
|||||||
ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::gfx_data_t) {
|
ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::gfx_data_t) {
|
||||||
uint32_t flags = SDL_WINDOW_RESIZABLE;
|
uint32_t flags = SDL_WINDOW_RESIZABLE;
|
||||||
|
|
||||||
#if defined(RT64_SDL_WINDOW_VULKAN)
|
#if defined(__APPLE__)
|
||||||
|
flags |= SDL_WINDOW_METAL;
|
||||||
|
#elif defined(RT64_SDL_WINDOW_VULKAN)
|
||||||
flags |= SDL_WINDOW_VULKAN;
|
flags |= SDL_WINDOW_VULKAN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -152,6 +159,9 @@ ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::
|
|||||||
return ultramodern::renderer::WindowHandle{ wmInfo.info.win.window, GetCurrentThreadId() };
|
return ultramodern::renderer::WindowHandle{ wmInfo.info.win.window, GetCurrentThreadId() };
|
||||||
#elif defined(__linux__) || defined(__ANDROID__)
|
#elif defined(__linux__) || defined(__ANDROID__)
|
||||||
return ultramodern::renderer::WindowHandle{ window };
|
return ultramodern::renderer::WindowHandle{ window };
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
SDL_MetalView view = SDL_Metal_CreateView(window);
|
||||||
|
return ultramodern::renderer::WindowHandle{ wmInfo.info.cocoa.window, SDL_Metal_GetLayer(view) };
|
||||||
#else
|
#else
|
||||||
static_assert(false && "Unimplemented");
|
static_assert(false && "Unimplemented");
|
||||||
#endif
|
#endif
|
||||||
|
@ -263,6 +263,9 @@ zelda64::renderer::RT64Context::RT64Context(uint8_t* rdram, ultramodern::rendere
|
|||||||
case ultramodern::renderer::GraphicsApi::Vulkan:
|
case ultramodern::renderer::GraphicsApi::Vulkan:
|
||||||
app->userConfig.graphicsAPI = RT64::UserConfiguration::GraphicsAPI::Vulkan;
|
app->userConfig.graphicsAPI = RT64::UserConfiguration::GraphicsAPI::Vulkan;
|
||||||
break;
|
break;
|
||||||
|
case ultramodern::renderer::GraphicsApi::Metal:
|
||||||
|
app->userConfig.graphicsAPI = RT64::UserConfiguration::GraphicsAPI::Metal;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
case ultramodern::renderer::GraphicsApi::Auto:
|
case ultramodern::renderer::GraphicsApi::Auto:
|
||||||
// Don't override if auto is selected.
|
// Don't override if auto is selected.
|
||||||
|
10
src/main/support.cpp
Normal file
10
src/main/support.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __APPLE__
|
||||||
|
|
||||||
|
#include "zelda_support.h"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
void zelda64::dispatch_on_main_thread(std::function<void()> func) {
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
13
src/main/support_apple.mm
Normal file
13
src/main/support_apple.mm
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "zelda_support.h"
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
void zelda64::dispatch_on_main_thread(std::function<void()> func) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
func();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* zelda64::get_bundle_resource_directory() {
|
||||||
|
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
|
||||||
|
return strdup([bundlePath UTF8String]);
|
||||||
|
}
|
@ -48,17 +48,29 @@ namespace recompui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Slider::update_label_text() {
|
void Slider::update_label_text() {
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
char text_buffer[32];
|
||||||
|
if (type == SliderType::Double) {
|
||||||
|
std::snprintf(text_buffer, sizeof(text_buffer), "%.1f", value);
|
||||||
|
} else if (type == SliderType::Percent) {
|
||||||
|
std::snprintf(text_buffer, sizeof(text_buffer), "%d%%", static_cast<int>(value));
|
||||||
|
} else {
|
||||||
|
std::snprintf(text_buffer, sizeof(text_buffer), "%d", static_cast<int>(value));
|
||||||
|
}
|
||||||
|
value_label->set_text(text_buffer);
|
||||||
|
#else
|
||||||
char text_buffer[32];
|
char text_buffer[32];
|
||||||
int precision = type == SliderType::Double ? 1 : 0;
|
int precision = type == SliderType::Double ? 1 : 0;
|
||||||
auto result = std::to_chars(text_buffer, text_buffer + sizeof(text_buffer) - 1, value, std::chars_format::fixed, precision);
|
auto result = std::to_chars(text_buffer, text_buffer + sizeof(text_buffer) - 1,
|
||||||
|
value, std::chars_format::fixed, precision);
|
||||||
if (result.ec == std::errc()) {
|
if (result.ec == std::errc()) {
|
||||||
if (type == SliderType::Percent) {
|
if (type == SliderType::Percent) {
|
||||||
*result.ptr = '%';
|
*result.ptr = '%';
|
||||||
result.ptr++;
|
result.ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_label->set_text(std::string(text_buffer, result.ptr));
|
value_label->set_text(std::string(text_buffer, result.ptr));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Slider::Slider(Element *parent, SliderType type) : Element(parent) {
|
Slider::Slider(Element *parent, SliderType type) : Element(parent) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "zelda_config.h"
|
#include "zelda_config.h"
|
||||||
#include "zelda_debug.h"
|
#include "zelda_debug.h"
|
||||||
#include "zelda_render.h"
|
#include "zelda_render.h"
|
||||||
|
#include "zelda_support.h"
|
||||||
#include "promptfont.h"
|
#include "promptfont.h"
|
||||||
#include "ultramodern/config.hpp"
|
#include "ultramodern/config.hpp"
|
||||||
#include "ultramodern/ultramodern.hpp"
|
#include "ultramodern/ultramodern.hpp"
|
||||||
@ -443,7 +444,12 @@ public:
|
|||||||
}
|
}
|
||||||
Rml::ElementDocument* load_document(Rml::Context* context) override {
|
Rml::ElementDocument* load_document(Rml::Context* context) override {
|
||||||
(void)context;
|
(void)context;
|
||||||
config_context = recompui::create_context("assets/config_menu.rml");
|
#if defined(__APPLE__)
|
||||||
|
const Rml::String asset = "/assets/config_menu.rml";
|
||||||
|
config_context = recompui::create_context(zelda64::get_bundle_resource_directory() + asset);
|
||||||
|
#else
|
||||||
|
config_context = recompui::create_context("assets/config_menu.rml");
|
||||||
|
#endif
|
||||||
Rml::ElementDocument* ret = config_context.get_document();
|
Rml::ElementDocument* ret = config_context.get_document();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -651,7 +657,7 @@ public:
|
|||||||
throw std::runtime_error("Failed to make RmlUi data model for the controls config menu");
|
throw std::runtime_error("Failed to make RmlUi data model for the controls config menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor.BindFunc("input_count", [](Rml::Variant& out) { out = recomp::get_num_inputs(); } );
|
constructor.BindFunc("input_count", [](Rml::Variant& out) { out = static_cast<uint64_t>(recomp::get_num_inputs()); } );
|
||||||
constructor.BindFunc("input_device_is_keyboard", [](Rml::Variant& out) { out = cur_device == recomp::InputDevice::Keyboard; } );
|
constructor.BindFunc("input_device_is_keyboard", [](Rml::Variant& out) { out = cur_device == recomp::InputDevice::Keyboard; } );
|
||||||
|
|
||||||
constructor.RegisterTransformFunc("get_input_name", [](const Rml::VariantList& inputs) {
|
constructor.RegisterTransformFunc("get_input_name", [](const Rml::VariantList& inputs) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "recomp_ui.h"
|
#include "recomp_ui.h"
|
||||||
#include "zelda_config.h"
|
#include "zelda_config.h"
|
||||||
|
#include "zelda_support.h"
|
||||||
#include "librecomp/game.hpp"
|
#include "librecomp/game.hpp"
|
||||||
#include "ultramodern/ultramodern.hpp"
|
#include "ultramodern/ultramodern.hpp"
|
||||||
#include "RmlUi/Core.h"
|
#include "RmlUi/Core.h"
|
||||||
@ -15,41 +16,44 @@ extern std::vector<recomp::GameEntry> supported_games;
|
|||||||
|
|
||||||
void select_rom() {
|
void select_rom() {
|
||||||
nfdnchar_t* native_path = nullptr;
|
nfdnchar_t* native_path = nullptr;
|
||||||
nfdresult_t result = NFD_OpenDialogN(&native_path, nullptr, 0, nullptr);
|
zelda64::dispatch_on_main_thread([&native_path]
|
||||||
|
{
|
||||||
|
nfdresult_t result = NFD_OpenDialogN(&native_path, nullptr, 0, nullptr);
|
||||||
|
|
||||||
if (result == NFD_OKAY) {
|
if (result == NFD_OKAY) {
|
||||||
std::filesystem::path path{native_path};
|
std::filesystem::path path{native_path};
|
||||||
|
|
||||||
NFD_FreePathN(native_path);
|
NFD_FreePathN(native_path);
|
||||||
native_path = nullptr;
|
native_path = nullptr;
|
||||||
|
|
||||||
recomp::RomValidationError rom_error = recomp::select_rom(path, supported_games[0].game_id);
|
recomp::RomValidationError rom_error = recomp::select_rom(path, supported_games[0].game_id);
|
||||||
switch (rom_error) {
|
switch (rom_error) {
|
||||||
case recomp::RomValidationError::Good:
|
case recomp::RomValidationError::Good:
|
||||||
mm_rom_valid = true;
|
mm_rom_valid = true;
|
||||||
model_handle.DirtyVariable("mm_rom_valid");
|
model_handle.DirtyVariable("mm_rom_valid");
|
||||||
break;
|
break;
|
||||||
case recomp::RomValidationError::FailedToOpen:
|
case recomp::RomValidationError::FailedToOpen:
|
||||||
recompui::message_box("Failed to open ROM file.");
|
recompui::message_box("Failed to open ROM file.");
|
||||||
break;
|
break;
|
||||||
case recomp::RomValidationError::NotARom:
|
case recomp::RomValidationError::NotARom:
|
||||||
recompui::message_box("This is not a valid ROM file.");
|
recompui::message_box("This is not a valid ROM file.");
|
||||||
break;
|
break;
|
||||||
case recomp::RomValidationError::IncorrectRom:
|
case recomp::RomValidationError::IncorrectRom:
|
||||||
recompui::message_box("This ROM is not the correct game.");
|
recompui::message_box("This ROM is not the correct game.");
|
||||||
break;
|
break;
|
||||||
case recomp::RomValidationError::NotYet:
|
case recomp::RomValidationError::NotYet:
|
||||||
recompui::message_box("This game isn't supported yet.");
|
recompui::message_box("This game isn't supported yet.");
|
||||||
break;
|
break;
|
||||||
case recomp::RomValidationError::IncorrectVersion:
|
case recomp::RomValidationError::IncorrectVersion:
|
||||||
recompui::message_box(
|
recompui::message_box(
|
||||||
"This ROM is the correct game, but the wrong version.\nThis project requires the NTSC-U N64 version of the game.");
|
"This ROM is the correct game, but the wrong version.\nThis project requires the NTSC-U N64 version of the game.");
|
||||||
break;
|
break;
|
||||||
case recomp::RomValidationError::OtherError:
|
case recomp::RomValidationError::OtherError:
|
||||||
recompui::message_box("An unknown error has occurred.");
|
recompui::message_box("An unknown error has occurred.");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
recompui::ContextId launcher_context;
|
recompui::ContextId launcher_context;
|
||||||
@ -68,7 +72,12 @@ public:
|
|||||||
}
|
}
|
||||||
Rml::ElementDocument* load_document(Rml::Context* context) override {
|
Rml::ElementDocument* load_document(Rml::Context* context) override {
|
||||||
(void)context;
|
(void)context;
|
||||||
launcher_context = recompui::create_context("assets/launcher.rml");
|
#if defined(__APPLE__)
|
||||||
|
const Rml::String asset = "/assets/launcher.rml";
|
||||||
|
launcher_context = recompui::create_context(zelda64::get_bundle_resource_directory() + asset);
|
||||||
|
#else
|
||||||
|
launcher_context = recompui::create_context("assets/launcher.rml");
|
||||||
|
#endif
|
||||||
Rml::ElementDocument* ret = launcher_context.get_document();
|
Rml::ElementDocument* ret = launcher_context.get_document();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "librecomp/mods.hpp"
|
#include "librecomp/mods.hpp"
|
||||||
|
|
||||||
|
#include "zelda_support.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -223,6 +225,9 @@ void ModMenu::open_mods_folder() {
|
|||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
std::string command = "xdg-open " + mods_directory.string() + " &";
|
std::string command = "xdg-open " + mods_directory.string() + " &";
|
||||||
std::system(command.c_str());
|
std::system(command.c_str());
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
std::string command = "open " + mods_directory.string();
|
||||||
|
std::system(command.c_str());
|
||||||
#else
|
#else
|
||||||
static_assert(false, "Not implemented for this platform.");
|
static_assert(false, "Not implemented for this platform.");
|
||||||
#endif
|
#endif
|
||||||
@ -540,7 +545,12 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
|||||||
|
|
||||||
context.close();
|
context.close();
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
const Rml::String asset = "/assets/config_sub_menu.rml";
|
||||||
|
sub_menu_context = recompui::create_context(zelda64::get_bundle_resource_directory() + asset);
|
||||||
|
#else
|
||||||
sub_menu_context = recompui::create_context("assets/config_sub_menu.rml");
|
sub_menu_context = recompui::create_context("assets/config_sub_menu.rml");
|
||||||
|
#endif
|
||||||
sub_menu_context.open();
|
sub_menu_context.open();
|
||||||
Rml::ElementDocument* sub_menu_doc = sub_menu_context.get_document();
|
Rml::ElementDocument* sub_menu_doc = sub_menu_context.get_document();
|
||||||
Rml::Element* config_sub_menu_generic = sub_menu_doc->GetElementById("config_sub_menu");
|
Rml::Element* config_sub_menu_generic = sub_menu_doc->GetElementById("config_sub_menu");
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include "InterfaceVS.hlsl.dxil.h"
|
# include "InterfaceVS.hlsl.dxil.h"
|
||||||
# include "InterfacePS.hlsl.dxil.h"
|
# include "InterfacePS.hlsl.dxil.h"
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
# include "InterfaceVS.hlsl.metal.h"
|
||||||
|
# include "InterfacePS.hlsl.metal.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -31,6 +34,13 @@
|
|||||||
# define GET_SHADER_SIZE(name, format) \
|
# define GET_SHADER_SIZE(name, format) \
|
||||||
((format) == RT64::RenderShaderFormat::SPIRV ? std::size(name##BlobSPIRV) : \
|
((format) == RT64::RenderShaderFormat::SPIRV ? std::size(name##BlobSPIRV) : \
|
||||||
(format) == RT64::RenderShaderFormat::DXIL ? std::size(name##BlobDXIL) : 0)
|
(format) == RT64::RenderShaderFormat::DXIL ? std::size(name##BlobDXIL) : 0)
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
# define GET_SHADER_BLOB(name, format) \
|
||||||
|
((format) == RT64::RenderShaderFormat::SPIRV ? name##BlobSPIRV : \
|
||||||
|
(format) == RT64::RenderShaderFormat::METAL ? name##BlobMSL : nullptr)
|
||||||
|
# define GET_SHADER_SIZE(name, format) \
|
||||||
|
((format) == RT64::RenderShaderFormat::SPIRV ? std::size(name##BlobSPIRV) : \
|
||||||
|
(format) == RT64::RenderShaderFormat::METAL ? std::size(name##BlobMSL) : 0)
|
||||||
#else
|
#else
|
||||||
# define GET_SHADER_BLOB(name, format) \
|
# define GET_SHADER_BLOB(name, format) \
|
||||||
((format) == RT64::RenderShaderFormat::SPIRV ? name##BlobSPIRV : nullptr)
|
((format) == RT64::RenderShaderFormat::SPIRV ? name##BlobSPIRV : nullptr)
|
||||||
@ -236,7 +246,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
copy_command_queue_ = device->createCommandQueue(RT64::RenderCommandListType::COPY);
|
copy_command_queue_ = device->createCommandQueue(RT64::RenderCommandListType::COPY);
|
||||||
copy_command_list_ = device->createCommandList(RT64::RenderCommandListType::COPY);
|
copy_command_list_ = copy_command_queue_->createCommandList(RT64::RenderCommandListType::COPY);
|
||||||
copy_command_fence_ = device->createCommandFence();
|
copy_command_fence_ = device->createCommandFence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <SDL2/SDL_video.h>
|
#include <SDL2/SDL_video.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "rt64_render_hooks.h"
|
#include "rt64_render_hooks.h"
|
||||||
|
|
||||||
#include "concurrentqueue.h"
|
#include "concurrentqueue.h"
|
||||||
@ -19,6 +21,7 @@
|
|||||||
#include "recomp_input.h"
|
#include "recomp_input.h"
|
||||||
#include "librecomp/game.hpp"
|
#include "librecomp/game.hpp"
|
||||||
#include "zelda_config.h"
|
#include "zelda_config.h"
|
||||||
|
#include "zelda_support.h"
|
||||||
#include "ui_rml_hacks.hpp"
|
#include "ui_rml_hacks.hpp"
|
||||||
#include "ui_elements.h"
|
#include "ui_elements.h"
|
||||||
#include "ui_mod_menu.h"
|
#include "ui_mod_menu.h"
|
||||||
@ -209,8 +212,6 @@ public:
|
|||||||
|
|
||||||
Rml::Debugger::Initialise(context);
|
Rml::Debugger::Initialise(context);
|
||||||
{
|
{
|
||||||
const Rml::String directory = "assets/";
|
|
||||||
|
|
||||||
struct FontFace {
|
struct FontFace {
|
||||||
const char* filename;
|
const char* filename;
|
||||||
bool fallback_face;
|
bool fallback_face;
|
||||||
@ -227,7 +228,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const FontFace& face : font_faces) {
|
for (const FontFace& face : font_faces) {
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
const Rml::String directory = "/assets/";
|
||||||
|
Rml::LoadFontFace(zelda64::get_bundle_resource_directory() + directory + face.filename, face.fallback_face);
|
||||||
|
#else
|
||||||
|
const Rml::String directory = "assets/";
|
||||||
Rml::LoadFontFace(directory + face.filename, face.fallback_face);
|
Rml::LoadFontFace(directory + face.filename, face.fallback_face);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -718,7 +725,10 @@ void recompui::set_render_hooks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void recompui::message_box(const char* msg) {
|
void recompui::message_box(const char* msg) {
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, zelda64::program_name.data(), msg, nullptr);
|
std::string message(msg);
|
||||||
|
zelda64::dispatch_on_main_thread([message] {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, zelda64::program_name.data(), message.c_str(), nullptr);
|
||||||
|
});
|
||||||
printf("[ERROR] %s\n", msg);
|
printf("[ERROR] %s\n", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user