mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-05-23 22:45:05 -04:00
Merge branch 'main' of https://github.com/TwilitRealm/dusk into instant-text
This commit is contained in:
+29
-24
@@ -67,6 +67,7 @@ jobs:
|
||||
run: ci/build-appimage.sh
|
||||
|
||||
- name: Upload artifacts
|
||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dusk-${{env.DUSK_VERSION}}-linux-${{matrix.preset}}-${{matrix.artifact_arch}}
|
||||
@@ -76,24 +77,27 @@ jobs:
|
||||
|
||||
build-apple:
|
||||
name: Build Apple (${{matrix.name}})
|
||||
if: 'false' # TODO enable when CI is free
|
||||
runs-on: macos-latest
|
||||
runs-on: [self-hosted, macOS]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: AppleClang macOS universal
|
||||
- name: AppleClang macOS arm64
|
||||
platform: macos
|
||||
preset: x-macos-ci
|
||||
artifact_name: macos-appleclang-universal
|
||||
- name: AppleClang iOS arm64
|
||||
platform: ios
|
||||
preset: x-ios-ci
|
||||
artifact_name: ios-appleclang-arm64
|
||||
- name: AppleClang tvOS arm64
|
||||
platform: tvos
|
||||
preset: x-tvos-ci
|
||||
artifact_name: tvos-appleclang-arm64
|
||||
preset: x-macos-ci-arm64
|
||||
artifact_name: macos-appleclang-arm64
|
||||
# - name: AppleClang macOS x86_64
|
||||
# platform: macos
|
||||
# preset: x-macos-ci-x86_64
|
||||
# artifact_name: macos-appleclang-x86_64
|
||||
# - name: AppleClang iOS arm64
|
||||
# platform: ios
|
||||
# preset: x-ios-ci
|
||||
# artifact_name: ios-appleclang-arm64
|
||||
# - name: AppleClang tvOS arm64
|
||||
# platform: tvos
|
||||
# preset: x-tvos-ci
|
||||
# artifact_name: tvos-appleclang-arm64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
@@ -101,22 +105,15 @@ jobs:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Update Homebrew
|
||||
if: matrix.platform == 'tvos'
|
||||
run: |
|
||||
brew update
|
||||
brew upgrade --formula
|
||||
|
||||
- name: Install dependencies
|
||||
if: 'false'
|
||||
run: brew install cmake ninja
|
||||
|
||||
- name: Install markupsafe
|
||||
if: matrix.platform == 'tvos'
|
||||
run: pip3 install --break-system-packages markupsafe
|
||||
|
||||
- name: Install Rust iOS target
|
||||
if: matrix.platform == 'ios'
|
||||
run: rustup target add aarch64-apple-ios
|
||||
run: |
|
||||
rustup toolchain install stable
|
||||
rustup target add aarch64-apple-ios
|
||||
|
||||
- name: Install Rust tvOS target
|
||||
if: matrix.platform == 'tvos'
|
||||
@@ -124,6 +121,12 @@ jobs:
|
||||
rustup toolchain install nightly
|
||||
rustup target add --toolchain nightly aarch64-apple-tvos
|
||||
|
||||
- name: Install Rust x86_64 macOS target
|
||||
if: endsWith(matrix.preset, 'x86_64')
|
||||
run: |
|
||||
rustup toolchain install stable
|
||||
rustup target add x86_64-apple-darwin
|
||||
|
||||
- name: Setup sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.9
|
||||
|
||||
@@ -134,6 +137,7 @@ jobs:
|
||||
run: cmake --build --preset ${{matrix.preset}}
|
||||
|
||||
- name: Upload artifacts
|
||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dusk-${{env.DUSK_VERSION}}-${{matrix.artifact_name}}
|
||||
@@ -199,6 +203,7 @@ jobs:
|
||||
run: cmake --build --preset x-windows-ci-${{matrix.preset}}
|
||||
|
||||
- name: Upload artifacts
|
||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dusk-${{env.DUSK_VERSION}}-win32-msvc-${{matrix.artifact_arch}}
|
||||
|
||||
+102
-68
@@ -68,6 +68,9 @@ endif()
|
||||
message(STATUS "Dusk version set to ${DUSK_WC_DESCRIBE}")
|
||||
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
||||
project(dusk LANGUAGES C CXX VERSION ${DUSK_VERSION_STRING})
|
||||
if (APPLE)
|
||||
enable_language(OBJC)
|
||||
endif ()
|
||||
if (APPLE AND NOT TVOS AND CMAKE_SYSTEM_NAME STREQUAL tvOS)
|
||||
# ios.toolchain.cmake hack for SDL
|
||||
set(TVOS ON)
|
||||
@@ -125,19 +128,37 @@ if (DUSK_MOVIE_SUPPORT)
|
||||
else ()
|
||||
set(_jpeg_lib ${_jpeg_install_dir}/lib/libturbojpeg.a)
|
||||
endif ()
|
||||
set(_jpeg_cmake_args
|
||||
-DCMAKE_INSTALL_PREFIX=${_jpeg_install_dir}
|
||||
-DENABLE_SHARED=OFF
|
||||
-DWITH_TURBOJPEG=ON
|
||||
-DWITH_JAVA=OFF
|
||||
)
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
get_filename_component(_jpeg_toolchain_file "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
list(APPEND _jpeg_cmake_args -DCMAKE_TOOLCHAIN_FILE=${_jpeg_toolchain_file})
|
||||
endif ()
|
||||
set(_jpeg_passthrough_vars
|
||||
CMAKE_BUILD_TYPE
|
||||
CMAKE_C_COMPILER
|
||||
CMAKE_C_COMPILER_LAUNCHER
|
||||
CMAKE_MAKE_PROGRAM
|
||||
CMAKE_MSVC_RUNTIME_LIBRARY
|
||||
CMAKE_OSX_ARCHITECTURES
|
||||
DEPLOYMENT_TARGET
|
||||
ENABLE_ARC
|
||||
ENABLE_BITCODE
|
||||
PLATFORM
|
||||
)
|
||||
foreach(_var IN LISTS _jpeg_passthrough_vars)
|
||||
if (DEFINED ${_var})
|
||||
list(APPEND _jpeg_cmake_args -D${_var}=${${_var}})
|
||||
endif ()
|
||||
endforeach ()
|
||||
ExternalProject_Add(libjpeg-turbo-ext
|
||||
URL https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/3.1.0.tar.gz
|
||||
URL_HASH SHA256=35fec2e1ddfb05ecf6d93e50bc57c1e54bc81c16d611ddf6eff73fff266d8285
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DCMAKE_INSTALL_PREFIX=${_jpeg_install_dir}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
|
||||
-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}
|
||||
-DENABLE_SHARED=OFF
|
||||
-DWITH_TURBOJPEG=ON
|
||||
-DWITH_JAVA=OFF
|
||||
CMAKE_ARGS ${_jpeg_cmake_args}
|
||||
BUILD_BYPRODUCTS ${_jpeg_lib}
|
||||
)
|
||||
file(MAKE_DIRECTORY ${_jpeg_install_dir}/include)
|
||||
@@ -249,7 +270,7 @@ include(files.cmake)
|
||||
# TODO: version handling for res includes
|
||||
|
||||
set(DUSK_BUNDLE_NAME Dusk)
|
||||
set(DUSK_BUNDLE_IDENTIFIER dev.decomp.dusk)
|
||||
set(DUSK_BUNDLE_IDENTIFIER dev.twilitrealm.dusk)
|
||||
set(DUSK_COMPANY_NAME "Twilit Realm")
|
||||
set(DUSK_FILE_DESCRIPTION "Dusk")
|
||||
set(DUSK_PRODUCT_NAME "Dusk")
|
||||
@@ -277,7 +298,7 @@ set(GAME_INCLUDE_DIRS
|
||||
${CMAKE_BINARY_DIR})
|
||||
|
||||
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd
|
||||
aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient)
|
||||
aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt)
|
||||
|
||||
list(APPEND GAME_LIBS libzstd_static)
|
||||
|
||||
@@ -362,12 +383,14 @@ if (ANDROID)
|
||||
target_link_options(dusk PRIVATE "-Wl,-u,SDL_main")
|
||||
endif ()
|
||||
|
||||
add_custom_command(TARGET dusk POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${CMAKE_SOURCE_DIR}/res"
|
||||
"$<TARGET_FILE_DIR:dusk>/res"
|
||||
COMMENT "Copying resources"
|
||||
)
|
||||
if (NOT APPLE)
|
||||
add_custom_command(TARGET dusk POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${CMAKE_SOURCE_DIR}/res"
|
||||
"$<TARGET_FILE_DIR:dusk>/res"
|
||||
COMMENT "Copying resources"
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
set(DUSK_WINDOWS_RESOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/platforms/windows)
|
||||
@@ -401,44 +424,49 @@ endif ()
|
||||
if (APPLE)
|
||||
if (IOS)
|
||||
set(DUSK_RESOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios)
|
||||
set(DUSK_INFO_PLIST ${DUSK_RESOURCE_DIR}/Info.plist.in)
|
||||
file(GLOB_RECURSE DUSK_RESOURCE_FILES "${DUSK_RESOURCE_DIR}/Base.lproj/*")
|
||||
endif ()
|
||||
if (IOS OR TVOS)
|
||||
target_sources(dusk PRIVATE ${DUSK_RESOURCE_FILES})
|
||||
foreach (FILE ${DUSK_RESOURCE_FILES})
|
||||
file(RELATIVE_PATH NEW_FILE "${DUSK_RESOURCE_DIR}" ${FILE})
|
||||
get_filename_component(NEW_FILE_PATH ${NEW_FILE} DIRECTORY)
|
||||
set_property(SOURCE ${FILE} PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${NEW_FILE_PATH}")
|
||||
endforeach ()
|
||||
set_target_properties(
|
||||
dusk PROPERTIES
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_BUNDLE_NAME ${DUSK_BUNDLE_NAME}
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER ${DUSK_BUNDLE_IDENTIFIER}
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${DUSK_VERSION_STRING}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${DUSK_SHORT_VERSION_STRING}
|
||||
OUTPUT_NAME dusk
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "YES"
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES"
|
||||
)
|
||||
if (CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
set_target_properties(dusk PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${DUSK_INFO_PLIST})
|
||||
elseif (DEFINED DUSK_INFO_PLIST)
|
||||
set(MACOSX_BUNDLE_EXECUTABLE_NAME dusk)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER ${DUSK_BUNDLE_IDENTIFIER})
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME ${DUSK_BUNDLE_NAME})
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${DUSK_VERSION_STRING})
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${DUSK_SHORT_VERSION_STRING})
|
||||
set(DUSK_GENERATED_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/dusk.Info.plist)
|
||||
configure_file(${DUSK_INFO_PLIST} ${DUSK_GENERATED_INFO_PLIST})
|
||||
add_custom_command(
|
||||
TARGET dusk POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DUSK_GENERATED_INFO_PLIST} $<TARGET_FILE_DIR:dusk>/Info.plist
|
||||
VERBATIM
|
||||
)
|
||||
endif ()
|
||||
elseif (TVOS)
|
||||
set(DUSK_RESOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/platforms/tvos)
|
||||
else ()
|
||||
set(DUSK_RESOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/platforms/macos)
|
||||
endif ()
|
||||
set(DUSK_INFO_PLIST ${DUSK_RESOURCE_DIR}/Info.plist.in)
|
||||
file(GLOB_RECURSE DUSK_RESOURCE_FILES
|
||||
"${DUSK_RESOURCE_DIR}/Assets.car"
|
||||
"${DUSK_RESOURCE_DIR}/Base.lproj/*"
|
||||
"${DUSK_RESOURCE_DIR}/Dusk.icns")
|
||||
file(GLOB_RECURSE DUSK_APP_RESOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/res/*")
|
||||
target_sources(dusk PRIVATE ${DUSK_RESOURCE_FILES})
|
||||
target_sources(dusk PRIVATE ${DUSK_APP_RESOURCE_FILES})
|
||||
foreach (FILE ${DUSK_RESOURCE_FILES})
|
||||
file(RELATIVE_PATH NEW_FILE "${DUSK_RESOURCE_DIR}" ${FILE})
|
||||
get_filename_component(NEW_FILE_PATH ${NEW_FILE} DIRECTORY)
|
||||
set_property(SOURCE ${FILE} PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${NEW_FILE_PATH}")
|
||||
endforeach ()
|
||||
foreach (FILE ${DUSK_APP_RESOURCE_FILES})
|
||||
file(RELATIVE_PATH NEW_FILE "${CMAKE_CURRENT_SOURCE_DIR}" ${FILE})
|
||||
get_filename_component(NEW_FILE_PATH ${NEW_FILE} DIRECTORY)
|
||||
set_property(SOURCE ${FILE} PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${NEW_FILE_PATH}")
|
||||
endforeach ()
|
||||
set_target_properties(
|
||||
dusk PROPERTIES
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_BUNDLE_NAME ${DUSK_BUNDLE_NAME}
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER ${DUSK_BUNDLE_IDENTIFIER}
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${DUSK_VERSION_STRING}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${DUSK_SHORT_VERSION_STRING}
|
||||
MACOSX_BUNDLE_INFO_PLIST ${DUSK_INFO_PLIST}
|
||||
OUTPUT_NAME Dusk
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "YES"
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES"
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (IOS)
|
||||
find_library(UIKIT_FRAMEWORK UIKit REQUIRED)
|
||||
find_library(UNIFORM_TYPE_IDENTIFIERS_FRAMEWORK UniformTypeIdentifiers REQUIRED)
|
||||
target_sources(dusk PRIVATE src/dusk/ios/FileSelectDialog.m)
|
||||
set_source_files_properties(src/dusk/ios/FileSelectDialog.m PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
||||
target_link_libraries(dusk PRIVATE ${UIKIT_FRAMEWORK} ${UNIFORM_TYPE_IDENTIFIERS_FRAMEWORK})
|
||||
endif ()
|
||||
|
||||
include(extern/aurora/cmake/AuroraCopyRuntimeDLLs.cmake)
|
||||
@@ -487,7 +515,9 @@ if (TARGET crashpad_handler)
|
||||
endif ()
|
||||
install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
aurora_install_runtime_dlls(dusk ${CMAKE_INSTALL_PREFIX})
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
if (NOT APPLE)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
endif ()
|
||||
if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
|
||||
set(DEBUG_FILES_LIST "")
|
||||
foreach (target IN LISTS BINARY_TARGETS EXTRA_TARGETS)
|
||||
@@ -509,18 +539,22 @@ if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
|
||||
endif ()
|
||||
list(APPEND DEBUG_FILES_LIST "${output_name}")
|
||||
endforeach ()
|
||||
if (WIN32)
|
||||
list(TRANSFORM DEBUG_FILES_LIST APPEND ".pdb")
|
||||
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
|
||||
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND 7z a -t7z \"${CMAKE_INSTALL_PREFIX}/debug.7z\" ${DEBUG_FILES})")
|
||||
elseif (APPLE)
|
||||
list(TRANSFORM DEBUG_FILES_LIST APPEND ".dSYM")
|
||||
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
|
||||
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND tar acfv \"${CMAKE_INSTALL_PREFIX}/debug.tar.xz\" ${DEBUG_FILES})")
|
||||
elseif (UNIX)
|
||||
list(TRANSFORM DEBUG_FILES_LIST APPEND ".dbg")
|
||||
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
|
||||
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND tar -I \"xz -9 -T0\" -cvf \"${CMAKE_INSTALL_PREFIX}/debug.tar.xz\" ${DEBUG_FILES})")
|
||||
# This is a terrible hack to only run this on CI
|
||||
# until I turn this into a script or something
|
||||
if(DEFINED ENV{GITHUB_ENV})
|
||||
if (WIN32)
|
||||
list(TRANSFORM DEBUG_FILES_LIST APPEND ".pdb")
|
||||
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
|
||||
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND 7z a -t7z \"${CMAKE_INSTALL_PREFIX}/debug.7z\" ${DEBUG_FILES})")
|
||||
elseif (APPLE)
|
||||
list(TRANSFORM DEBUG_FILES_LIST APPEND ".dSYM")
|
||||
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
|
||||
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND tar acfv \"${CMAKE_INSTALL_PREFIX}/debug.tar.xz\" ${DEBUG_FILES})")
|
||||
elseif (UNIX)
|
||||
list(TRANSFORM DEBUG_FILES_LIST APPEND ".dbg")
|
||||
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
|
||||
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND tar -I \"xz -9 -T0\" -cvf \"${CMAKE_INSTALL_PREFIX}/debug.tar.xz\" ${DEBUG_FILES})")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
foreach (target IN LISTS BINARY_TARGETS)
|
||||
|
||||
+61
-11
@@ -380,7 +380,40 @@
|
||||
"inherits": [
|
||||
"macos-default-relwithdebinfo",
|
||||
"ci"
|
||||
]
|
||||
],
|
||||
"cacheVariables": {
|
||||
"AURORA_DAWN_PROVIDER": "vendor",
|
||||
"AURORA_NOD_PROVIDER": "vendor",
|
||||
"CMAKE_DISABLE_FIND_PACKAGE_PkgConfig": {
|
||||
"type": "BOOL",
|
||||
"value": true
|
||||
},
|
||||
"CMAKE_OSX_DEPLOYMENT_TARGET": "11.0",
|
||||
"CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew",
|
||||
"DUSK_MOVIE_SUPPORT": {
|
||||
"type": "BOOL",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x-macos-ci-arm64",
|
||||
"inherits": [
|
||||
"x-macos-ci"
|
||||
],
|
||||
"cacheVariables": {
|
||||
"CMAKE_OSX_ARCHITECTURES": "arm64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x-macos-ci-x86_64",
|
||||
"inherits": [
|
||||
"x-macos-ci"
|
||||
],
|
||||
"cacheVariables": {
|
||||
"CMAKE_OSX_ARCHITECTURES": "x86_64",
|
||||
"Rust_CARGO_TARGET": "x86_64-apple-darwin"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x-ios-ci",
|
||||
@@ -389,7 +422,11 @@
|
||||
],
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache",
|
||||
"DUSK_MOVIE_SUPPORT": {
|
||||
"type": "BOOL",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -399,7 +436,11 @@
|
||||
],
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache",
|
||||
"DUSK_MOVIE_SUPPORT": {
|
||||
"type": "BOOL",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -556,10 +597,19 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "x-macos-ci",
|
||||
"configurePreset": "x-macos-ci",
|
||||
"description": "(Internal) macOS CI",
|
||||
"displayName": "(Internal) macOS CI",
|
||||
"name": "x-macos-ci-arm64",
|
||||
"configurePreset": "x-macos-ci-arm64",
|
||||
"description": "(Internal) macOS CI arm64",
|
||||
"displayName": "(Internal) macOS CI arm64",
|
||||
"targets": [
|
||||
"install"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "x-macos-ci-x86_64",
|
||||
"configurePreset": "x-macos-ci-x86_64",
|
||||
"description": "(Internal) macOS CI x86_64",
|
||||
"displayName": "(Internal) macOS CI x86_64",
|
||||
"targets": [
|
||||
"install"
|
||||
]
|
||||
@@ -567,8 +617,8 @@
|
||||
{
|
||||
"name": "x-ios-ci",
|
||||
"configurePreset": "x-ios-ci",
|
||||
"description": "(Internal) iOS CI",
|
||||
"displayName": "(Internal) iOS CI",
|
||||
"description": "(Internal) iOS CI arm64",
|
||||
"displayName": "(Internal) iOS CI arm64",
|
||||
"targets": [
|
||||
"install"
|
||||
]
|
||||
@@ -576,8 +626,8 @@
|
||||
{
|
||||
"name": "x-tvos-ci",
|
||||
"configurePreset": "x-tvos-ci",
|
||||
"description": "(Internal) tvOS CI",
|
||||
"displayName": "(Internal) tvOS CI",
|
||||
"description": "(Internal) tvOS CI arm64",
|
||||
"displayName": "(Internal) tvOS CI arm64",
|
||||
"targets": [
|
||||
"install"
|
||||
]
|
||||
|
||||
@@ -1343,6 +1343,8 @@ set(DUSK_FILES
|
||||
src/dusk/endian.cpp
|
||||
src/dusk/extras.c
|
||||
src/dusk/extras.cpp
|
||||
src/dusk/file_select.cpp
|
||||
src/dusk/file_select.hpp
|
||||
src/dusk/frame_interpolation.cpp
|
||||
src/dusk/globals.cpp
|
||||
src/dusk/gyro.cpp
|
||||
|
||||
@@ -125,8 +125,15 @@ public:
|
||||
#if TARGET_PC
|
||||
static f32 hudAspectScaleDown;
|
||||
static f32 hudAspectScaleUp;
|
||||
static f32 ScaleHUDXLeft(f32 baseX) { return getMinXF() + baseX; }
|
||||
static f32 ScaleHUDXRight(f32 baseX) { return -getMinXF() + baseX; }
|
||||
static void updateSafeAreaBounds();
|
||||
static f32 getSafeMinXF() { return m_safeMinXF; }
|
||||
static f32 getSafeMinYF() { return m_safeMinYF; }
|
||||
static f32 getSafeWidthF() { return m_safeWidthF; }
|
||||
static f32 getSafeHeightF() { return m_safeHeightF; }
|
||||
static f32 getSafeMaxXF() { return m_safeMaxXF; }
|
||||
static f32 getSafeMaxYF() { return m_safeMaxYF; }
|
||||
static f32 ScaleHUDXLeft(f32 baseX) { return getSafeMinXF() + baseX; }
|
||||
static f32 ScaleHUDXRight(f32 baseX) { return getSafeMaxXF() - FB_WIDTH_BASE + baseX; }
|
||||
#endif
|
||||
|
||||
static void setBlureMtx(const Mtx m) {
|
||||
@@ -369,6 +376,15 @@ public:
|
||||
static int m_height;
|
||||
static f32 m_heightF;
|
||||
static f32 m_widthF;
|
||||
|
||||
#if TARGET_PC
|
||||
static f32 m_safeMinXF;
|
||||
static f32 m_safeMinYF;
|
||||
static f32 m_safeMaxXF;
|
||||
static f32 m_safeMaxYF;
|
||||
static f32 m_safeWidthF;
|
||||
static f32 m_safeHeightF;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
android:allowBackup="true"
|
||||
android:hardwareAccelerated="true"
|
||||
android:appCategory="game"
|
||||
android:icon="@android:drawable/sym_def_app_icon"
|
||||
android:icon="@mipmap/icon"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
android:enableOnBackInvokedCallback="false">
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -13,7 +13,9 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>mainicon.icns</string>
|
||||
<string>Dusk</string>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>Dusk</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleName</key>
|
||||
|
||||
@@ -147,7 +147,7 @@ void dBrightCheck_c::modeMove() {
|
||||
void dBrightCheck_c::brightCheckWide() {
|
||||
// Main Canvas
|
||||
mBrightCheck.Scr->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mBrightCheck.Scr->translate(mDoGph_gInf_c::getMinXF(), 0.0f);
|
||||
mBrightCheck.Scr->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
|
||||
// Right Square
|
||||
mBrightCheck.Scr->search(MULTI_CHAR('fuchi_1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
@@ -3776,7 +3776,7 @@ bool dFile_select_c::yesnoWakuAlpahAnm(u8 param_1) {
|
||||
#if TARGET_PC
|
||||
void dFile_select_c::fileSelectWide() {
|
||||
mYnSel.ScrYn->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mYnSel.ScrYn->translate(mDoGph_gInf_c::getMinXF(), 0.0f);
|
||||
mYnSel.ScrYn->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
|
||||
mYnSel.ScrYn->search(MULTI_CHAR('w_no_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mYnSel.ScrYn->search(MULTI_CHAR('f_no_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
@@ -3784,7 +3784,7 @@ void dFile_select_c::fileSelectWide() {
|
||||
mYnSel.ScrYn->search(MULTI_CHAR('f_yes_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
m3mSel.Scr3m->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
m3mSel.Scr3m->translate(mDoGph_gInf_c::getMinXF(), 0.0f);
|
||||
m3mSel.Scr3m->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
|
||||
m3mSel.Scr3m->search(MULTI_CHAR('w_sta'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
m3mSel.Scr3m->search(MULTI_CHAR('f_sta'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
@@ -3794,7 +3794,7 @@ void dFile_select_c::fileSelectWide() {
|
||||
m3mSel.Scr3m->search(MULTI_CHAR('f_cop_t'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
fileSel.Scr->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
fileSel.Scr->translate(mDoGph_gInf_c::getMinXF(), 0.0f);
|
||||
fileSel.Scr->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
|
||||
fileSel.Scr->search(MULTI_CHAR('t_for'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
fileSel.Scr->search(MULTI_CHAR('t_for1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
@@ -5584,7 +5584,13 @@ void dFile_select3D_c::createMirrorModel() {
|
||||
void dFile_select3D_c::toItem3Dpos(f32 param_0, f32 param_1, f32 param_2, cXyz* param_3) {
|
||||
Mtx adStack_98;
|
||||
Mtx auStack_c8;
|
||||
#if TARGET_PC
|
||||
param_0 =
|
||||
(2.0f * ((param_0 - mDoGph_gInf_c::getSafeMinXF()) / mDoGph_gInf_c::getSafeWidthF()) -
|
||||
1.0f);
|
||||
#else
|
||||
param_0 = (2.0f * ((param_0 - mDoGph_gInf_c::getMinXF()) / mDoGph_gInf_c::getWidthF()) - 1.0f);
|
||||
#endif
|
||||
param_1 = (2.0f * ((param_1 - -100.0f) / FB_HEIGHT_BASE) - 1.0f);
|
||||
calcViewMtx(adStack_98);
|
||||
cMtx_inverse(adStack_98, auStack_c8);
|
||||
@@ -5601,4 +5607,3 @@ void dFile_select3D_c::calcViewMtx(Mtx param_0) {
|
||||
cXyz pos2(0.0f, 1.0f, 0.0f);
|
||||
cMtx_lookAt(param_0, &pos1, &cXyz::Zero, &pos2, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ dMenu_Collect2D_c::~dMenu_Collect2D_c() {
|
||||
void dMenu_Collect2D_c::menuCollectWide() {
|
||||
// Main Canvas
|
||||
mpScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mpScreen->translate(mDoGph_gInf_c::getMinXF(), 0.0f);
|
||||
mpScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
|
||||
// Pieces of Heart
|
||||
mpScreen->search(MULTI_CHAR('heart_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
@@ -182,7 +182,7 @@ void dMenu_Collect2D_c::_create() {
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
mpScreenIcon->translate(-mDoGph_gInf_c::getMinXF(), 0.0f);
|
||||
mpScreenIcon->translate(-mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
#endif
|
||||
|
||||
dPaneClass_showNullPane(mpScreenIcon);
|
||||
@@ -2706,8 +2706,14 @@ void dMenu_Collect3D_c::setupItem3D(Mtx param_0) {
|
||||
void dMenu_Collect3D_c::toItem3Dpos(f32 param_0, f32 param_1, f32 param_2, cXyz* param_3) {
|
||||
Mtx adStack_98;
|
||||
Mtx auStack_c8;
|
||||
#if TARGET_PC
|
||||
param_0 =
|
||||
(2.0f * ((param_0 - mDoGph_gInf_c::getSafeMinXF()) / mDoGph_gInf_c::getSafeWidthF()) -
|
||||
1.0f);
|
||||
#else
|
||||
param_0 =
|
||||
(2.0f * ((param_0 - mDoGph_gInf_c::getMinXF()) / mDoGph_gInf_c::getWidthF()) - 1.0f);
|
||||
#endif
|
||||
param_1 = (2.0f * ((param_1 - -100.0f) / FB_HEIGHT_BASE) - 1.0f);
|
||||
calcViewMtx(adStack_98);
|
||||
MTXInverse(adStack_98, auStack_c8);
|
||||
|
||||
@@ -2782,7 +2782,7 @@ void dMenu_save_c::_draw() {
|
||||
#if TARGET_PC
|
||||
void dMenu_save_c::menuSaveWide() {
|
||||
mSaveSel.Scr->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mSaveSel.Scr->translate(mDoGph_gInf_c::getMinXF(), 0.0f);
|
||||
mSaveSel.Scr->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
|
||||
mSaveSel.Scr->search(MULTI_CHAR('t_for'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mSaveSel.Scr->search(MULTI_CHAR('t_for1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "file_select.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <SDL3/SDL_dialog.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST
|
||||
#define USE_IOS_DIALOG 1
|
||||
#include "ios/FileSelectDialog.h"
|
||||
#else
|
||||
#define USE_IOS_DIALOG 0
|
||||
#endif
|
||||
|
||||
namespace dusk {
|
||||
namespace {
|
||||
|
||||
#if USE_IOS_DIALOG
|
||||
struct IOSDialogCallbackState {
|
||||
FileCallback callback;
|
||||
void* userdata;
|
||||
};
|
||||
|
||||
void onIOSDialogFinished(void* userdata, const char* path, const char* error) {
|
||||
std::unique_ptr<IOSDialogCallbackState> state(static_cast<IOSDialogCallbackState*>(userdata));
|
||||
|
||||
if (error != nullptr) {
|
||||
state->callback(state->userdata, nullptr, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (path == nullptr) {
|
||||
state->callback(state->userdata, nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
state->callback(state->userdata, path, nullptr);
|
||||
}
|
||||
#else
|
||||
struct SDLDialogCallbackState {
|
||||
FileCallback callback;
|
||||
void* userdata;
|
||||
};
|
||||
|
||||
void onSDLDialogFinished(void* userdata, const char* const* filelist, [[maybe_unused]] int filter) {
|
||||
std::unique_ptr<SDLDialogCallbackState> state(static_cast<SDLDialogCallbackState*>(userdata));
|
||||
|
||||
if (filelist == nullptr) {
|
||||
state->callback(state->userdata, nullptr, SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if (filelist[0] == nullptr) {
|
||||
state->callback(state->userdata, nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
state->callback(state->userdata, filelist[0], nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
void ShowFileSelect(FileCallback callback, void* userdata, SDL_Window* window,
|
||||
const SDL_DialogFileFilter* filters, int nfilters, const char* default_location,
|
||||
bool allow_many) {
|
||||
if (callback == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if USE_IOS_DIALOG
|
||||
auto state = std::make_unique<IOSDialogCallbackState>();
|
||||
state->callback = callback;
|
||||
state->userdata = userdata;
|
||||
|
||||
Dusk_iOS_ShowFileSelect(&onIOSDialogFinished, state.release(), window, filters, nfilters,
|
||||
default_location, allow_many);
|
||||
#else
|
||||
auto state = std::make_unique<SDLDialogCallbackState>();
|
||||
state->callback = callback;
|
||||
state->userdata = userdata;
|
||||
|
||||
SDL_ShowOpenFileDialog(&onSDLDialogFinished, state.release(), window, filters, nfilters,
|
||||
default_location, allow_many);
|
||||
#endif
|
||||
}
|
||||
} // namespace dusk
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL_dialog.h>
|
||||
|
||||
struct SDL_Window;
|
||||
|
||||
namespace dusk {
|
||||
|
||||
using FileCallback = void (*)(void* userdata, const char* path, const char* error);
|
||||
|
||||
void ShowFileSelect(FileCallback callback, void* userdata, SDL_Window* window,
|
||||
const SDL_DialogFileFilter* filters, int nfilters, const char* default_location,
|
||||
bool allow_many);
|
||||
|
||||
} // namespace dusk
|
||||
+151
-21
@@ -3,23 +3,24 @@
|
||||
#include <numeric>
|
||||
#include <string_view>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "fmt/format.h"
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include "imgui.h"
|
||||
#include <imgui_internal.h>
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "ImGuiConsole.hpp"
|
||||
|
||||
#include "JSystem/JUtility/JUTGamePad.h"
|
||||
#include "SDL3/SDL_events.h"
|
||||
#include "SDL3/SDL_mouse.h"
|
||||
#include "m_Do/m_Do_controller_pad.h"
|
||||
#include "m_Do/m_Do_main.h"
|
||||
#include "aurora/lib/window.hpp"
|
||||
#include "dusk/audio/DuskAudioSystem.h"
|
||||
#include "dusk/config.hpp"
|
||||
#include "dusk/dusk.h"
|
||||
#include "dusk/main.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "dusk/audio/DuskAudioSystem.h"
|
||||
#include "dusk/dusk.h"
|
||||
#include "m_Do/m_Do_controller_pad.h"
|
||||
#include "m_Do/m_Do_main.h"
|
||||
#include "tracy/Tracy.hpp"
|
||||
|
||||
#if _WIN32
|
||||
@@ -30,6 +31,30 @@
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
namespace {
|
||||
ImVec2 TouchEventToScreenPos(const SDL_TouchFingerEvent& touch) {
|
||||
const AuroraWindowSize size = aurora::window::get_window_size();
|
||||
return ImVec2{
|
||||
touch.x * static_cast<float>(size.width),
|
||||
touch.y * static_cast<float>(size.height),
|
||||
};
|
||||
}
|
||||
|
||||
ImGuiWindow* FindDragScrollWindow(ImGuiWindow* window) {
|
||||
while (window != nullptr) {
|
||||
const bool canScrollX = window->ScrollMax.x > 0.0f;
|
||||
const bool canScrollY = window->ScrollMax.y > 0.0f;
|
||||
const bool canScrollWithMouse = (window->Flags & (ImGuiWindowFlags_NoScrollWithMouse |
|
||||
ImGuiWindowFlags_NoMouseInputs)) == 0;
|
||||
if ((canScrollX || canScrollY) && canScrollWithMouse) {
|
||||
return window;
|
||||
}
|
||||
window = window->ParentWindow;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace dusk {
|
||||
float ImGuiScale() { return 1.0f; }
|
||||
|
||||
@@ -208,6 +233,51 @@ namespace dusk {
|
||||
|
||||
ImGuiConsole::ImGuiConsole() {}
|
||||
|
||||
void ImGuiConsole::HandleSDLEvent(const SDL_Event& event) {
|
||||
if (!IsGameLaunched) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
if (!m_touchTapActive) {
|
||||
m_touchTapActive = true;
|
||||
m_touchTapMoved = false;
|
||||
m_touchTapFingerId = event.tfinger.fingerID;
|
||||
m_touchTapStartPos = TouchEventToScreenPos(event.tfinger);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
if (m_touchTapActive && m_touchTapFingerId == event.tfinger.fingerID) {
|
||||
const auto currentPos = TouchEventToScreenPos(event.tfinger);
|
||||
const auto delta = currentPos - m_touchTapStartPos;
|
||||
if (ImLengthSqr(delta) > 144.0f) {
|
||||
m_touchTapMoved = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
if (m_touchTapActive && m_touchTapFingerId == event.tfinger.fingerID) {
|
||||
const bool shouldToggle =
|
||||
!m_touchTapMoved && (m_isHidden || !ImGui::GetIO().WantCaptureMouse);
|
||||
m_touchTapActive = false;
|
||||
m_touchTapMoved = false;
|
||||
if (shouldToggle) {
|
||||
m_isHidden = !m_isHidden;
|
||||
getSettings().backend.duskMenuOpen.setValue(!m_isHidden);
|
||||
Save();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_FINGER_CANCELED:
|
||||
m_touchTapActive = false;
|
||||
m_touchTapMoved = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiConsole::UpdateSettings() {
|
||||
getTransientSettings().skipFrameRateLimit = getSettings().game.enableTurboKeybind && ImGui::IsKeyDown(ImGuiKey_Tab);
|
||||
|
||||
@@ -237,26 +307,31 @@ namespace dusk {
|
||||
if (!dusk::IsGameLaunched) {
|
||||
m_preLaunchWindow.draw();
|
||||
}
|
||||
|
||||
m_isHidden = getSettings().backend.duskMenuOpen;
|
||||
CheckMenuViewToggle(ImGuiKey_F1, m_isHidden);
|
||||
|
||||
m_isHidden = !getSettings().backend.duskMenuOpen;
|
||||
bool showMenu = !dusk::IsGameLaunched || !CheckMenuViewToggle(ImGuiKey_F1, m_isHidden);
|
||||
if (dusk::IsGameLaunched) {
|
||||
if (getSettings().backend.duskMenuOpen != m_isHidden) {
|
||||
m_isHidden = !getSettings().backend.duskMenuOpen;
|
||||
getSettings().backend.duskMenuOpen.setValue(m_isHidden);
|
||||
config::Save();
|
||||
const bool menuOpen = !m_isHidden;
|
||||
if (getSettings().backend.duskMenuOpen != menuOpen) {
|
||||
getSettings().backend.duskMenuOpen.setValue(menuOpen);
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
if ((!dusk::IsGameLaunched || getSettings().backend.duskMenuOpen) && ImGui::BeginMainMenuBar()) {
|
||||
if (showMenu && ImGui::BeginMainMenuBar()) {
|
||||
m_menuGame.draw();
|
||||
m_menuEnhancements.draw();
|
||||
m_menuTools.draw();
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 100.0f * ImGuiScale());
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiStringViewText(fmt::format(FMT_STRING("FPS: {:.2f}\n"), io.Framerate));
|
||||
const auto fpsLabel =
|
||||
fmt::format(FMT_STRING("FPS: {:.2f}\n"), ImGui::GetIO().Framerate);
|
||||
const auto fpsSize =
|
||||
ImGui::CalcTextSize(fpsLabel.data(), fpsLabel.data() + fpsLabel.size());
|
||||
ImGui::SetCursorPosX(
|
||||
ImMax(ImGui::GetCursorPosX(), ImGui::GetWindowWidth() -
|
||||
ImGui::GetStyle().DisplaySafeAreaPadding.x -
|
||||
fpsSize.x - ImGui::GetStyle().ItemSpacing.x));
|
||||
ImGuiStringViewText(fpsLabel);
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
@@ -267,10 +342,15 @@ namespace dusk {
|
||||
}
|
||||
|
||||
if (dusk::IsGameLaunched && !m_isLaunchInitialized) {
|
||||
m_toasts.emplace_back("Press F1 to toggle menu"s, 2.5f);
|
||||
m_toasts.emplace_back(ImGui::GetIO().MouseSource == ImGuiMouseSource_TouchScreen ?
|
||||
"Tap to toggle menu"s :
|
||||
"Press F1 to toggle menu"s,
|
||||
2.5f);
|
||||
m_isLaunchInitialized = true;
|
||||
}
|
||||
|
||||
UpdateDragScroll();
|
||||
|
||||
m_menuGame.windowControllerConfig();
|
||||
m_menuGame.windowInputViewer();
|
||||
if (dusk::IsGameLaunched) {
|
||||
@@ -289,8 +369,7 @@ namespace dusk {
|
||||
DuskDebugPad(); // temporary, remove later
|
||||
|
||||
// Only show cursor when menu or any windows are open
|
||||
if ((!dusk::IsGameLaunched || getSettings().backend.duskMenuOpen) || ImGui::GetIO().MetricsRenderWindows > 0)
|
||||
{
|
||||
if (showMenu || ImGui::GetIO().MetricsRenderWindows > 0) {
|
||||
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange;
|
||||
// Imgui will re-show cursor.
|
||||
} else {
|
||||
@@ -306,6 +385,57 @@ namespace dusk {
|
||||
ShowPipelineProgress();
|
||||
}
|
||||
|
||||
void ImGuiConsole::UpdateDragScroll() {
|
||||
ImGuiContext& g = *ImGui::GetCurrentContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
if (io.MouseSource != ImGuiMouseSource_TouchScreen) {
|
||||
m_dragScrollWindow = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
|
||||
m_dragScrollWindow = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (io.WantTextInput || (g.ActiveId != 0 && g.InputTextState.ID == g.ActiveId)) {
|
||||
m_dragScrollWindow = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ImGui::IsMouseDragging(ImGuiMouseButton_Left, io.MouseDragThreshold)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_dragScrollWindow == nullptr) {
|
||||
ImGuiWindow* hoveredWindow = nullptr;
|
||||
ImGuiWindow* hoveredWindowUnderMovingWindow = nullptr;
|
||||
ImGui::FindHoveredWindowEx(io.MousePos, false, &hoveredWindow,
|
||||
&hoveredWindowUnderMovingWindow);
|
||||
m_dragScrollWindow = FindDragScrollWindow(hoveredWindow);
|
||||
m_dragScrollLastMousePos = io.MousePos;
|
||||
}
|
||||
|
||||
if (m_dragScrollWindow == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto mouseDelta = io.MousePos - m_dragScrollLastMousePos;
|
||||
m_dragScrollLastMousePos = io.MousePos;
|
||||
|
||||
if (mouseDelta.x != 0.0f && m_dragScrollWindow->ScrollMax.x > 0.0f) {
|
||||
ImGui::SetScrollX(m_dragScrollWindow,
|
||||
ImClamp(m_dragScrollWindow->Scroll.x - mouseDelta.x, 0.0f,
|
||||
m_dragScrollWindow->ScrollMax.x));
|
||||
}
|
||||
if (mouseDelta.y != 0.0f && m_dragScrollWindow->ScrollMax.y > 0.0f) {
|
||||
ImGui::SetScrollY(m_dragScrollWindow,
|
||||
ImClamp(m_dragScrollWindow->Scroll.y - mouseDelta.y, 0.0f,
|
||||
m_dragScrollWindow->ScrollMax.y));
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGuiConsole::CheckMenuViewToggle(ImGuiKey key, bool& active) {
|
||||
if (ImGui::IsKeyPressed(key)) {
|
||||
active = !active;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#ifndef DUSK_IMGUI_HPP
|
||||
#define DUSK_IMGUI_HPP
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
#include <SDL3/SDL_touch.h>
|
||||
|
||||
#include "ImGuiFirstRunPreset.hpp"
|
||||
#include "ImGuiMenuEnhancements.hpp"
|
||||
#include "ImGuiMenuGame.hpp"
|
||||
@@ -13,10 +15,14 @@
|
||||
#include "ImGuiPreLaunchWindow.hpp"
|
||||
#include "imgui.h"
|
||||
|
||||
union SDL_Event;
|
||||
struct ImGuiWindow;
|
||||
|
||||
namespace dusk {
|
||||
class ImGuiConsole {
|
||||
public:
|
||||
ImGuiConsole();
|
||||
void HandleSDLEvent(const SDL_Event& event);
|
||||
void UpdateSettings();
|
||||
void PreDraw();
|
||||
void PostDraw();
|
||||
@@ -34,6 +40,12 @@ private:
|
||||
|
||||
bool m_isHidden = true;
|
||||
bool m_isLaunchInitialized = false;
|
||||
bool m_touchTapActive = false;
|
||||
bool m_touchTapMoved = false;
|
||||
SDL_FingerID m_touchTapFingerId = 0;
|
||||
ImVec2 m_touchTapStartPos = {};
|
||||
ImGuiWindow* m_dragScrollWindow = nullptr;
|
||||
ImVec2 m_dragScrollLastMousePos = {};
|
||||
std::deque<Toast> m_toasts;
|
||||
|
||||
ImGuiFirstRunPreset m_firstRunPreset;
|
||||
@@ -46,6 +58,7 @@ private:
|
||||
|
||||
void ShowToasts();
|
||||
void ShowPipelineProgress();
|
||||
void UpdateDragScroll();
|
||||
};
|
||||
|
||||
extern ImGuiConsole g_imguiConsole;
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#include <SDL3/SDL_video.h>
|
||||
#include <aurora/imgui.h>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
|
||||
#include "aurora/lib/window.hpp"
|
||||
#include "dusk/logging.h"
|
||||
|
||||
#ifdef IMGUI_ENABLE_FREETYPE
|
||||
@@ -37,6 +39,20 @@ ImTextureID AddTexture(const char* assetName) {
|
||||
}
|
||||
return aurora_imgui_add_texture(image.width, image.height, image.data.get());
|
||||
}
|
||||
|
||||
ImVec2 GetDisplaySafeAreaPadding() {
|
||||
SDL_Window* window = aurora::window::get_sdl_window();
|
||||
if (window == nullptr) {
|
||||
return ImVec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
SDL_Rect safeRect{};
|
||||
if (!SDL_GetWindowSafeArea(window, &safeRect)) {
|
||||
return ImVec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
return ImVec2(static_cast<float>(safeRect.x), static_cast<float>(safeRect.y));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ImFont* ImGuiEngine::fontNormal;
|
||||
@@ -75,6 +91,7 @@ void ImGuiEngine_Initialize(float scale) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->Clear();
|
||||
io.FontGlobalScale = scale > 0.0f ? 1.0f / scale : 1.0f;
|
||||
io.ConfigWindowsMoveFromTitleBarOnly = IsMobile;
|
||||
|
||||
ImGuiEngine::fontNormal =
|
||||
CreateFont(std::floor(18.f * scale), GetAssetPath("Inter-Regular.ttf"), "Inter Regular");
|
||||
@@ -104,6 +121,7 @@ void ImGuiEngine_Initialize(float scale) {
|
||||
style.PopupRounding = 7.0;
|
||||
style.TabBorderSize = 1.f;
|
||||
style.TabRounding = 3.f;
|
||||
style.DisplaySafeAreaPadding = GetDisplaySafeAreaPadding();
|
||||
|
||||
auto* colors = style.Colors;
|
||||
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
|
||||
|
||||
@@ -25,4 +25,10 @@ struct Image {
|
||||
uint32_t height;
|
||||
};
|
||||
Image GetImage(const std::string& path);
|
||||
|
||||
#if (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST) || defined(__ANDROID__)
|
||||
inline constexpr bool IsMobile = true;
|
||||
#else
|
||||
inline constexpr bool IsMobile = false;
|
||||
#endif
|
||||
} // namespace dusk
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "fmt/format.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include "ImGuiEngine.hpp"
|
||||
#include "ImGuiConsole.hpp"
|
||||
#include "ImGuiMenuGame.hpp"
|
||||
#include "ImGuiConfig.hpp"
|
||||
@@ -32,15 +33,17 @@ namespace dusk {
|
||||
void ImGuiMenuGame::draw() {
|
||||
if (ImGui::BeginMenu("Game")) {
|
||||
if (ImGui::BeginMenu("Graphics")) {
|
||||
if (ImGui::MenuItem("Toggle Fullscreen", hotkeys::TOGGLE_FULLSCREEN)) {
|
||||
ToggleFullscreen();
|
||||
}
|
||||
if (!IsMobile) {
|
||||
if (ImGui::MenuItem("Toggle Fullscreen", hotkeys::TOGGLE_FULLSCREEN)) {
|
||||
ToggleFullscreen();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Default Window Size")) {
|
||||
getSettings().video.enableFullscreen.setValue(false);
|
||||
VISetWindowFullscreen(false);
|
||||
VISetWindowSize(FB_WIDTH * 2, FB_HEIGHT * 2);
|
||||
VICenterWindow();
|
||||
if (ImGui::MenuItem("Default Window Size")) {
|
||||
getSettings().video.enableFullscreen.setValue(false);
|
||||
VISetWindowFullscreen(false);
|
||||
VISetWindowSize(FB_WIDTH * 2, FB_HEIGHT * 2);
|
||||
VICenterWindow();
|
||||
}
|
||||
}
|
||||
|
||||
bool vsync = getSettings().video.enableVsync;
|
||||
@@ -147,7 +150,7 @@ namespace dusk {
|
||||
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Exit")) {
|
||||
if (!IsMobile && ImGui::MenuItem("Exit")) {
|
||||
dusk::IsRunning = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
#include "ImGuiEngine.hpp"
|
||||
#include "ImGuiPreLaunchWindow.hpp"
|
||||
|
||||
#include "../file_select.hpp"
|
||||
#include "../iso_validate.hpp"
|
||||
#include "ImGuiConsole.hpp"
|
||||
#include "dusk/main.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "../iso_validate.hpp"
|
||||
|
||||
#include <SDL3/SDL_dialog.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
|
||||
#include "aurora/lib/internal.hpp"
|
||||
@@ -46,30 +46,22 @@ static std::string ShowIsoInvalidError(const iso::ValidationError code) {
|
||||
}
|
||||
}
|
||||
|
||||
void fileDialogCallback(void* userdata, const char* const* filelist, [[maybe_unused]] int filter) {
|
||||
void fileDialogCallback(void* userdata, const char* path, const char* error) {
|
||||
auto* self = static_cast<ImGuiPreLaunchWindow*>(userdata);
|
||||
self->m_errorString.clear();
|
||||
if (filelist != nullptr) {
|
||||
if (filelist[0] == nullptr) {
|
||||
// Cancelled
|
||||
self->m_selectedIsoPath.clear();
|
||||
} else {
|
||||
const auto path = filelist[0];
|
||||
const auto ret = iso::validate(path);
|
||||
if (ret != iso::ValidationError::Success) {
|
||||
self->m_selectedIsoPath.clear();
|
||||
self->m_errorString = std::move(ShowIsoInvalidError(ret));
|
||||
return;
|
||||
}
|
||||
self->m_selectedIsoPath = path;
|
||||
getSettings().backend.isoPath.setValue(path);
|
||||
config::Save();
|
||||
}
|
||||
} else {
|
||||
// Error occurred
|
||||
if (error != nullptr) {
|
||||
self->m_selectedIsoPath.clear();
|
||||
self->m_errorString = fmt::format("File dialog error: {}", SDL_GetError());
|
||||
self->m_errorString = fmt::format("File dialog error: {}", error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (path == nullptr) {
|
||||
self->m_selectedIsoPath.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
self->m_selectedIsoPath = path;
|
||||
getSettings().backend.isoPath.setValue(self->m_selectedIsoPath);
|
||||
config::Save();
|
||||
}
|
||||
|
||||
ImGuiPreLaunchWindow::ImGuiPreLaunchWindow() = default;
|
||||
@@ -144,9 +136,9 @@ void ImGuiPreLaunchWindow::drawMainMenu() {
|
||||
}
|
||||
|
||||
if (ImGuiButtonCenter("Select disc image...")) {
|
||||
SDL_ShowOpenFileDialog(&fileDialogCallback, this, aurora::window::get_sdl_window(),
|
||||
skGameDiscFileFilters.data(), int(skGameDiscFileFilters.size()),
|
||||
nullptr, false);
|
||||
ShowFileSelect(&fileDialogCallback, this, aurora::window::get_sdl_window(),
|
||||
skGameDiscFileFilters.data(), int(skGameDiscFileFilters.size()), nullptr,
|
||||
false);
|
||||
}
|
||||
} else {
|
||||
if (ImGuiButtonCenter("Start game")) {
|
||||
@@ -187,9 +179,9 @@ void ImGuiPreLaunchWindow::drawOptions() {
|
||||
ImGui::InputText("Game ISO Path", &m_selectedIsoPath, ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Set")) {
|
||||
SDL_ShowOpenFileDialog(&fileDialogCallback, this, aurora::window::get_sdl_window(),
|
||||
skGameDiscFileFilters.data(), int(skGameDiscFileFilters.size()),
|
||||
nullptr, false);
|
||||
ShowFileSelect(&fileDialogCallback, this, aurora::window::get_sdl_window(),
|
||||
skGameDiscFileFilters.data(), int(skGameDiscFileFilters.size()), nullptr,
|
||||
false);
|
||||
}
|
||||
|
||||
AuroraBackend configuredBackend = BACKEND_AUTO;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <SDL3/SDL_dialog.h>
|
||||
|
||||
struct SDL_Window;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*IOSFileCallback)(void* userdata, const char* path, const char* error);
|
||||
|
||||
void Dusk_iOS_ShowFileSelect(IOSFileCallback callback, void* userdata, SDL_Window* window,
|
||||
const SDL_DialogFileFilter* filters, int nfilters,
|
||||
const char* default_location, bool allow_many);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,151 @@
|
||||
#include "FileSelectDialog.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_properties.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_video.h>
|
||||
|
||||
static void *g_picker_delegate_key = &g_picker_delegate_key;
|
||||
|
||||
static void RunOnMainThread(void (^block)(void))
|
||||
{
|
||||
if ([NSThread isMainThread]) {
|
||||
block();
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), block);
|
||||
}
|
||||
}
|
||||
|
||||
static NSError *MakeError(NSString *message)
|
||||
{
|
||||
return [NSError errorWithDomain:@"org.twilitrealm.dusk.file-select"
|
||||
code:1
|
||||
userInfo:@{NSLocalizedDescriptionKey: message}];
|
||||
}
|
||||
|
||||
static UIViewController *FindTopViewController(UIViewController *controller)
|
||||
{
|
||||
UIViewController *current = controller;
|
||||
while (current.presentedViewController != nil) {
|
||||
current = current.presentedViewController;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
static UIViewController *PresenterFromWindow(SDL_Window *window)
|
||||
{
|
||||
if (window == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
const SDL_PropertiesID props = SDL_GetWindowProperties(window);
|
||||
if (props == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
UIWindow *uiwindow = (__bridge UIWindow *)SDL_GetPointerProperty(
|
||||
props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL);
|
||||
if (uiwindow == nil || uiwindow.rootViewController == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return FindTopViewController(uiwindow.rootViewController);
|
||||
}
|
||||
|
||||
static NSURL *InitialDirectoryURL(const char *default_location)
|
||||
{
|
||||
if (default_location == NULL || *default_location == '\0') {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString *path = [NSString stringWithUTF8String:default_location];
|
||||
NSURL *url = [NSURL fileURLWithPath:path];
|
||||
if ([path hasSuffix:@"/"]) {
|
||||
return url;
|
||||
}
|
||||
|
||||
return [url URLByDeletingLastPathComponent];
|
||||
}
|
||||
|
||||
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
|
||||
|
||||
@property(nonatomic, assign) IOSFileCallback callback;
|
||||
@property(nonatomic, assign) void *userdata;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DocumentPickerDelegate
|
||||
|
||||
- (void)finishWithPath:(const char *)path error:(const char *)error {
|
||||
if (self.callback != NULL) {
|
||||
self.callback(self.userdata, path, error);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller
|
||||
didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls
|
||||
{
|
||||
NSURL *url = urls.firstObject;
|
||||
if (url == nil) {
|
||||
[self finishWithPath:NULL error:NULL];
|
||||
return;
|
||||
}
|
||||
|
||||
[self finishWithPath:url.path.UTF8String error:NULL];
|
||||
(void)controller;
|
||||
}
|
||||
|
||||
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller
|
||||
{
|
||||
[self finishWithPath:NULL error:NULL];
|
||||
(void)controller;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void Dusk_iOS_ShowFileSelect(IOSFileCallback callback, void *userdata,
|
||||
SDL_Window *window,
|
||||
const SDL_DialogFileFilter *filters, int nfilters,
|
||||
const char *default_location,
|
||||
bool allow_many)
|
||||
{
|
||||
RunOnMainThread(^{
|
||||
@autoreleasepool {
|
||||
UIViewController *presenter = PresenterFromWindow(window);
|
||||
if (presenter == nil) {
|
||||
callback(userdata, NULL, "Failed to find an iOS view controller for the file picker.");
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"[ShowFileSelect] presenting picker from %@", NSStringFromClass([presenter class]));
|
||||
|
||||
UIDocumentPickerViewController *picker =
|
||||
[[UIDocumentPickerViewController alloc]
|
||||
initForOpeningContentTypes:@[ UTTypeItem ]
|
||||
asCopy:YES];
|
||||
picker.allowsMultipleSelection = allow_many ? YES : NO;
|
||||
picker.shouldShowFileExtensions = YES;
|
||||
|
||||
NSURL *directory_url = InitialDirectoryURL(default_location);
|
||||
if (directory_url != nil) {
|
||||
picker.directoryURL = directory_url;
|
||||
}
|
||||
|
||||
DocumentPickerDelegate *delegate = [DocumentPickerDelegate new];
|
||||
delegate.callback = callback;
|
||||
delegate.userdata = userdata;
|
||||
picker.delegate = delegate;
|
||||
objc_setAssociatedObject(picker, g_picker_delegate_key, delegate,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
|
||||
[presenter presentViewController:picker animated:YES completion:nil];
|
||||
(void)filters;
|
||||
(void)nfilters;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -47,6 +47,8 @@
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
#include <SDL3/SDL_video.h>
|
||||
#include "aurora/lib/window.hpp"
|
||||
#include "d/actor/d_a_horse.h"
|
||||
#include "dusk/dusk.h"
|
||||
#include "dusk/endian.h"
|
||||
@@ -636,8 +638,9 @@ void mDoGph_gInf_c::setTvSize() {
|
||||
m_invScale = 1.0f / m_scale;
|
||||
|
||||
#if TARGET_PC
|
||||
hudAspectScaleDown = 1.3571428f / mDoGph_gInf_c::getAspect();
|
||||
hudAspectScaleUp = 1.0f / hudAspectScaleDown;
|
||||
updateSafeAreaBounds();
|
||||
hudAspectScaleUp = getSafeWidthF() / FB_WIDTH_BASE;
|
||||
hudAspectScaleDown = FB_WIDTH_BASE / getSafeWidthF();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -765,6 +768,88 @@ void mDoGph_gInf_c::setWideZoomLightProjection(Mtx& m) {
|
||||
#if TARGET_PC
|
||||
f32 mDoGph_gInf_c::hudAspectScaleDown = 1.0f;
|
||||
f32 mDoGph_gInf_c::hudAspectScaleUp = 1.0f;
|
||||
f32 mDoGph_gInf_c::m_safeMinXF = 0.0f;
|
||||
f32 mDoGph_gInf_c::m_safeMinYF = 0.0f;
|
||||
f32 mDoGph_gInf_c::m_safeMaxXF = FB_WIDTH_BASE;
|
||||
f32 mDoGph_gInf_c::m_safeMaxYF = FB_HEIGHT_BASE;
|
||||
f32 mDoGph_gInf_c::m_safeWidthF = FB_WIDTH_BASE;
|
||||
f32 mDoGph_gInf_c::m_safeHeightF = FB_HEIGHT_BASE;
|
||||
|
||||
void mDoGph_gInf_c::updateSafeAreaBounds() {
|
||||
m_safeMinXF = m_minXF;
|
||||
m_safeMinYF = m_minYF;
|
||||
m_safeMaxXF = m_maxXF;
|
||||
m_safeMaxYF = m_maxYF;
|
||||
m_safeWidthF = m_widthF;
|
||||
m_safeHeightF = m_heightF;
|
||||
|
||||
SDL_Window* window = aurora::window::get_sdl_window();
|
||||
if (window == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const AuroraWindowSize windowSize = aurora::window::get_window_size();
|
||||
const f32 windowWidth = static_cast<f32>(windowSize.width);
|
||||
const f32 windowHeight = static_cast<f32>(windowSize.height);
|
||||
if (windowWidth <= 0.0f || windowHeight <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Rect safeRect{};
|
||||
if (!SDL_GetWindowSafeArea(window, &safeRect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (windowSize.native_fb_width == 0 || windowSize.native_fb_height == 0 ||
|
||||
windowSize.fb_width == 0 || windowSize.fb_height == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const f32 nativeScaleX = static_cast<f32>(windowSize.native_fb_width) / windowWidth;
|
||||
const f32 nativeScaleY = static_cast<f32>(windowSize.native_fb_height) / windowHeight;
|
||||
|
||||
const f32 safeLeft = static_cast<f32>(safeRect.x) * nativeScaleX;
|
||||
const f32 safeTop = static_cast<f32>(safeRect.y) * nativeScaleY;
|
||||
const f32 safeRight = static_cast<f32>(safeRect.x + safeRect.w) * nativeScaleX;
|
||||
const f32 safeBottom = static_cast<f32>(safeRect.y + safeRect.h) * nativeScaleY;
|
||||
|
||||
const f32 viewportLeft =
|
||||
(static_cast<f32>(windowSize.native_fb_width) - static_cast<f32>(windowSize.fb_width)) *
|
||||
0.5f;
|
||||
const f32 viewportTop =
|
||||
(static_cast<f32>(windowSize.native_fb_height) - static_cast<f32>(windowSize.fb_height)) *
|
||||
0.5f;
|
||||
const f32 viewportRight = viewportLeft + static_cast<f32>(windowSize.fb_width);
|
||||
const f32 viewportBottom = viewportTop + static_cast<f32>(windowSize.fb_height);
|
||||
|
||||
const f32 leftInset = std::max(0.0f, safeLeft - viewportLeft) *
|
||||
(m_widthF / static_cast<f32>(windowSize.fb_width));
|
||||
const f32 topInset = std::max(0.0f, safeTop - viewportTop) *
|
||||
(m_heightF / static_cast<f32>(windowSize.fb_height));
|
||||
const f32 rightInset = std::max(0.0f, viewportRight - safeRight) *
|
||||
(m_widthF / static_cast<f32>(windowSize.fb_width));
|
||||
const f32 bottomInset = std::max(0.0f, viewportBottom - safeBottom) *
|
||||
(m_heightF / static_cast<f32>(windowSize.fb_height));
|
||||
|
||||
const f32 safeMinXF = m_minXF + leftInset;
|
||||
const f32 safeMinYF = m_minYF + topInset;
|
||||
const f32 safeMaxXF = m_maxXF - rightInset;
|
||||
const f32 safeMaxYF = m_maxYF - bottomInset;
|
||||
const f32 safeWidthF = safeMaxXF - safeMinXF;
|
||||
const f32 safeHeightF = safeMaxYF - safeMinYF;
|
||||
|
||||
if (safeWidthF <= 0.0f || safeHeightF <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_safeMinXF = safeMinXF;
|
||||
m_safeMinYF = safeMinYF;
|
||||
m_safeMaxXF = safeMaxXF;
|
||||
m_safeMaxYF = safeMaxYF;
|
||||
m_safeWidthF = safeWidthF;
|
||||
m_safeHeightF = safeHeightF;
|
||||
}
|
||||
|
||||
void mDoGph_gInf_c::setWindowSize(AuroraWindowSize const& size) {
|
||||
JUTVideo::getManager()->setWindowSize(size);
|
||||
|
||||
@@ -154,7 +154,7 @@ void mDoLib_project(Vec* src, Vec* dst, JGeometry::TBox2<f32> viewport) {
|
||||
xSize = FB_WIDTH;
|
||||
} else {
|
||||
#if TARGET_PC
|
||||
xOffset = mDoGph_gInf_c::getMinXF();
|
||||
xOffset = mDoGph_gInf_c::getSafeMinXF();
|
||||
xSize = viewport.f.x * mDoGph_gInf_c::hudAspectScaleUp;
|
||||
#else
|
||||
xOffset = viewport.i.x;
|
||||
|
||||
@@ -133,6 +133,9 @@ bool launchUILoop() {
|
||||
const AuroraEvent* event = aurora_update();
|
||||
while (event != nullptr && event->type != AURORA_NONE) {
|
||||
switch (event->type) {
|
||||
case AURORA_SDL_EVENT:
|
||||
dusk::g_imguiConsole.HandleSDLEvent(event->sdl);
|
||||
break;
|
||||
case AURORA_WINDOW_RESIZED:
|
||||
preLaunchUIWindowSize = event->windowSize;
|
||||
break;
|
||||
@@ -213,6 +216,9 @@ void main01(void) {
|
||||
switch (event->type) {
|
||||
case AURORA_NONE:
|
||||
goto eventsDone;
|
||||
case AURORA_SDL_EVENT:
|
||||
dusk::g_imguiConsole.HandleSDLEvent(event->sdl);
|
||||
break;
|
||||
case AURORA_WINDOW_RESIZED:
|
||||
mDoGph_gInf_c::setWindowSize(event->windowSize);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user