mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-24 13:49:01 -04:00
Merge branch 'main' of https://github.com/TwilitRealm/dusk into randomizer
This commit is contained in:
@@ -80,6 +80,7 @@ jobs:
|
||||
path: |
|
||||
build/install/Dusklight-*.AppImage
|
||||
build/install/debug.tar.*
|
||||
build/install/sdk/
|
||||
|
||||
build-apple:
|
||||
name: Build Apple (${{matrix.name}})
|
||||
@@ -148,6 +149,7 @@ jobs:
|
||||
path: |
|
||||
build/install/Dusklight.app
|
||||
build/install/debug.tar.*
|
||||
build/install/sdk/
|
||||
|
||||
build-android:
|
||||
name: Build Android (${{matrix.name}})
|
||||
@@ -203,6 +205,9 @@ jobs:
|
||||
- name: Build native library
|
||||
run: cmake --build --preset ${{matrix.preset}} --target dusklight
|
||||
|
||||
- name: Build bundled mods
|
||||
run: cmake --build --preset ${{matrix.preset}} --target dusklight_mods
|
||||
|
||||
- name: Stage stripped JNI library
|
||||
run: ANDROID_STAGE_ABIS="${{matrix.abi}}" platforms/android/scripts/stage-jni-libs.sh
|
||||
|
||||
@@ -210,11 +215,17 @@ jobs:
|
||||
working-directory: platforms/android
|
||||
run: ./gradlew :app:assembleRelease --rerun-tasks
|
||||
|
||||
- name: Stage artifacts
|
||||
run: |
|
||||
mkdir -p upload/sdk
|
||||
cp build/*/stub-android-*.so upload/sdk/
|
||||
cp platforms/android/app/build/outputs/apk/release/app-${{matrix.abi}}-release-unsigned.apk upload/
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dusklight-${{env.DUSK_VERSION}}-android-${{matrix.artifact_arch}}
|
||||
path: platforms/android/app/build/outputs/apk/release/app-${{matrix.abi}}-release-unsigned.apk
|
||||
path: upload/
|
||||
|
||||
build-windows:
|
||||
name: Build Windows (${{matrix.name}})
|
||||
@@ -280,4 +291,6 @@ jobs:
|
||||
build/install/*.exe
|
||||
build/install/*.dll
|
||||
build/install/res/
|
||||
build/install/mods/
|
||||
build/install/debug.7z
|
||||
build/install/sdk/
|
||||
|
||||
+8
-3
@@ -511,9 +511,12 @@ if (WIN32)
|
||||
target_link_libraries(dusklight PRIVATE Psapi)
|
||||
endif ()
|
||||
if (APPLE)
|
||||
# Mods resolve game symbols from the executable at dlopen time.
|
||||
target_link_options(dusklight PRIVATE -Wl,-export_dynamic)
|
||||
elseif (UNIX AND NOT ANDROID)
|
||||
include(cmake/AppleExports.cmake)
|
||||
setup_apple_exports(dusklight)
|
||||
elseif (ANDROID)
|
||||
include(cmake/AndroidExports.cmake)
|
||||
setup_android_exports(dusklight)
|
||||
elseif (UNIX)
|
||||
target_link_options(dusklight PRIVATE -rdynamic)
|
||||
endif ()
|
||||
|
||||
@@ -536,6 +539,8 @@ endif ()
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
target_link_options(dusklight PRIVATE "-Wl,--build-id=sha1")
|
||||
target_link_libraries(dusklight PRIVATE dl)
|
||||
elseif (ANDROID)
|
||||
target_link_options(dusklight PRIVATE "-Wl,--build-id=sha1")
|
||||
endif ()
|
||||
|
||||
if (NOT APPLE)
|
||||
|
||||
+4
-21
@@ -22,18 +22,6 @@
|
||||
"CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreadedDLL"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "release",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreadedDLL",
|
||||
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": {
|
||||
"type": "BOOL",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci",
|
||||
"hidden": true,
|
||||
@@ -208,17 +196,13 @@
|
||||
{
|
||||
"name": "windows-arm64-msvc",
|
||||
"displayName": "Windows ARM64 (MSVC)",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"inherits": [
|
||||
"windows-msvc"
|
||||
],
|
||||
"architecture": {
|
||||
"value": "arm64",
|
||||
"strategy": "external"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "cl",
|
||||
"CMAKE_CXX_COMPILER": "cl",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install"
|
||||
},
|
||||
"vendor": {
|
||||
"microsoft.com/VisualStudioSettings/CMake/1.0": {
|
||||
"hostOS": [
|
||||
@@ -445,8 +429,7 @@
|
||||
"hidden": true,
|
||||
"inherits": [
|
||||
"android-base",
|
||||
"ci",
|
||||
"release"
|
||||
"ci"
|
||||
],
|
||||
"cacheVariables": {
|
||||
"DUSK_ENABLE_SENTRY_NATIVE": {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
|
||||
|
||||
# Android mod linking: symgen scans and filters the game's exports, generating a version script used for the executable
|
||||
# link step, and generates a shared object stub that mods can link against without having to build the whole game.
|
||||
function(setup_android_exports target)
|
||||
include("${_dir}/SymbolManifest.cmake")
|
||||
ensure_symgen(TRUE)
|
||||
add_dependencies(${target} symgen)
|
||||
|
||||
set(_rsp_lines "$<TARGET_OBJECTS:${target}>")
|
||||
foreach (_lib IN LISTS JSYSTEM_LIBRARIES)
|
||||
list(APPEND _rsp_lines "$<TARGET_FILE:${_lib}>")
|
||||
endforeach ()
|
||||
list(JOIN _rsp_lines "\n" _rsp_content)
|
||||
set(_rsp "${CMAKE_BINARY_DIR}/dusklight_exports_input.rsp")
|
||||
file(GENERATE OUTPUT "${_rsp}" CONTENT "${_rsp_content}")
|
||||
|
||||
set(_sdk_args)
|
||||
foreach (_lib aurora_card aurora_core aurora_dvd aurora_gd aurora_gx aurora_mtx
|
||||
aurora_os aurora_pad aurora_si aurora_vi)
|
||||
if (TARGET ${_lib})
|
||||
list(APPEND _sdk_args --sdk-lib "$<TARGET_FILE:${_lib}>")
|
||||
endif ()
|
||||
endforeach ()
|
||||
if (TARGET dawn::webgpu_dawn)
|
||||
get_target_property(_dawn_type dawn::webgpu_dawn TYPE)
|
||||
if (_dawn_type STREQUAL "STATIC_LIBRARY")
|
||||
list(APPEND _sdk_args --sdk-lib "$<TARGET_FILE:dawn::webgpu_dawn>")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(_vscript "${CMAKE_BINARY_DIR}/dusklight_exports.ver")
|
||||
add_custom_command(TARGET ${target} PRE_LINK
|
||||
COMMAND "${SYMGEN_EXE}" exports
|
||||
"@${_rsp}"
|
||||
--out "${_vscript}"
|
||||
--format version-script
|
||||
--exclude cmake_pch
|
||||
--exclude miniz
|
||||
--exclude asan_options
|
||||
--exclude src/dusk
|
||||
# Resolved from the Java side; the SDL ones live in the statically-linked
|
||||
# SDL archive, outside the provenance scan.
|
||||
--extra-sym JNI_OnLoad
|
||||
--extra-sym SDL_main
|
||||
--extra-sym "Java_*"
|
||||
${_sdk_args}
|
||||
COMMENT "Generating dusklight exports"
|
||||
VERBATIM)
|
||||
target_link_options(${target} PRIVATE "-Wl,--version-script=${_vscript}")
|
||||
|
||||
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _arch)
|
||||
set(_stub "${CMAKE_BINARY_DIR}/stub-android-${_arch}.so")
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND "${SYMGEN_EXE}" stub -f elf "$<TARGET_FILE:${target}>" -o "${_stub}"
|
||||
--soname "$<TARGET_FILE_NAME:${target}>" --arch "${_arch}"
|
||||
BYPRODUCTS "${_stub}"
|
||||
COMMENT "Generating dusklight link stub"
|
||||
VERBATIM)
|
||||
install(FILES "${_stub}" DESTINATION sdk)
|
||||
endfunction()
|
||||
@@ -0,0 +1,90 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
|
||||
|
||||
# Apple mod linking: symgen scans and filters the game's exports, generating an exports list used for the executable
|
||||
# link step, and generates a MH_EXECUTE Mach-O stub that mods can link against without having to build the whole game.
|
||||
function(setup_apple_exports target)
|
||||
include("${_dir}/SymbolManifest.cmake")
|
||||
ensure_symgen(TRUE)
|
||||
set(_symgen "${SYMGEN_EXE}")
|
||||
add_dependencies(${target} symgen)
|
||||
|
||||
set(_config_subdir "")
|
||||
if (CMAKE_CONFIGURATION_TYPES)
|
||||
set(_config_subdir "$<CONFIG>/")
|
||||
endif ()
|
||||
|
||||
set(_rsp_lines "$<TARGET_OBJECTS:${target}>")
|
||||
foreach (_lib IN LISTS JSYSTEM_LIBRARIES)
|
||||
list(APPEND _rsp_lines "$<TARGET_FILE:${_lib}>")
|
||||
endforeach ()
|
||||
list(JOIN _rsp_lines "\n" _rsp_content)
|
||||
set(_rsp "${CMAKE_BINARY_DIR}/${_config_subdir}dusklight_exports_input.rsp")
|
||||
file(GENERATE OUTPUT "${_rsp}" CONTENT "${_rsp_content}")
|
||||
|
||||
set(_sdk_args)
|
||||
foreach (_lib aurora_card aurora_core aurora_dvd aurora_gd aurora_gx aurora_mtx
|
||||
aurora_os aurora_pad aurora_si aurora_vi)
|
||||
if (TARGET ${_lib})
|
||||
list(APPEND _sdk_args --sdk-lib "$<TARGET_FILE:${_lib}>")
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# Dawn is linked statically on Apple; mods reach wgpu* through the executable.
|
||||
if (TARGET dawn::webgpu_dawn)
|
||||
get_target_property(_dawn_type dawn::webgpu_dawn TYPE)
|
||||
if (_dawn_type STREQUAL "STATIC_LIBRARY")
|
||||
list(APPEND _sdk_args --sdk-lib "$<TARGET_FILE:dawn::webgpu_dawn>")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(_exp "${CMAKE_BINARY_DIR}/${_config_subdir}dusklight_exports.exp")
|
||||
add_custom_command(TARGET ${target} PRE_LINK
|
||||
COMMAND "${_symgen}" exports
|
||||
"@${_rsp}"
|
||||
--out "${_exp}"
|
||||
--exclude cmake_pch
|
||||
--exclude miniz
|
||||
--exclude asan_options
|
||||
--exclude src/dusk
|
||||
${_sdk_args}
|
||||
COMMENT "Generating dusklight exports"
|
||||
VERBATIM)
|
||||
target_link_options(${target} PRIVATE -Xlinker -exported_symbols_list -Xlinker "${_exp}")
|
||||
|
||||
# Generate the stub executable mods link against via -bundle_loader.
|
||||
set(_stub_args)
|
||||
if (IOS)
|
||||
set(_stub_platform "ios")
|
||||
list(APPEND _stub_args --platform ios)
|
||||
elseif (TVOS)
|
||||
set(_stub_platform "tvos")
|
||||
list(APPEND _stub_args --platform tvos)
|
||||
else ()
|
||||
set(_stub_platform "macos")
|
||||
endif ()
|
||||
if (CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
list(APPEND _stub_args --min-os "${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
endif ()
|
||||
if (CMAKE_OSX_ARCHITECTURES)
|
||||
set(_archs "${CMAKE_OSX_ARCHITECTURES}")
|
||||
else ()
|
||||
set(_archs "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif ()
|
||||
set(_arch_names "")
|
||||
foreach (_arch IN LISTS _archs)
|
||||
string(TOLOWER "${_arch}" _arch)
|
||||
list(APPEND _stub_args --arch "${_arch}")
|
||||
list(APPEND _arch_names "${_arch}")
|
||||
endforeach ()
|
||||
list(JOIN _arch_names "_" _arch_name)
|
||||
|
||||
set(_stub "${CMAKE_BINARY_DIR}/${_config_subdir}dusklight-stub")
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND "${_symgen}" stub -f macho "${_exp}" -o "${_stub}" ${_stub_args}
|
||||
BYPRODUCTS "${_stub}"
|
||||
COMMENT "Generating dusklight link stub"
|
||||
VERBATIM)
|
||||
install(FILES "${_stub}" DESTINATION sdk RENAME "stub-${_stub_platform}-${_arch_name}")
|
||||
endfunction()
|
||||
+33
-10
@@ -9,24 +9,47 @@ if (ANDROID)
|
||||
list(APPEND _game_compile_defs TARGET_ANDROID=1)
|
||||
endif ()
|
||||
|
||||
set(_game_include_dirs
|
||||
# Public game headers
|
||||
set(_game_abi_include_dirs
|
||||
${_game_root}/include
|
||||
${_game_root}/src
|
||||
${_game_root}/assets/GZ2E01 # TODO: make this dynamic if needed?
|
||||
${_game_root}/assets/GZ2E01
|
||||
${_game_root}/libs/JSystem/include
|
||||
${_game_root}/libs
|
||||
${_game_root}/extern/aurora/include/dolphin
|
||||
${_game_root}/extern/aurora/include
|
||||
${_game_root}/sdk/include
|
||||
)
|
||||
|
||||
# Internal game headers
|
||||
set(_game_include_dirs
|
||||
${_game_abi_include_dirs}
|
||||
${_game_root}/src
|
||||
${_game_root}/extern
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
# Interface target for mods and sub-projects to inherit game headers/defines.
|
||||
# Mod API, including services
|
||||
add_library(dusklight_mod_api INTERFACE)
|
||||
target_include_directories(dusklight_mod_api INTERFACE ${_game_root}/sdk/include)
|
||||
|
||||
# Full internal headers used to build the game
|
||||
add_library(dusklight_game_headers INTERFACE)
|
||||
target_include_directories(dusklight_game_headers INTERFACE ${_game_include_dirs})
|
||||
target_compile_definitions(dusklight_game_headers INTERFACE ${_game_compile_defs})
|
||||
if (TARGET dawn::dawncpp_headers)
|
||||
target_link_libraries(dusklight_game_headers INTERFACE dawn::dawncpp_headers)
|
||||
elseif (TARGET dawn::webgpu_dawn)
|
||||
target_link_libraries(dusklight_game_headers INTERFACE dawn::webgpu_dawn)
|
||||
endif ()
|
||||
|
||||
# Public game ABI for mods
|
||||
add_library(dusklight_game_abi_headers INTERFACE)
|
||||
target_include_directories(dusklight_game_abi_headers INTERFACE ${_game_abi_include_dirs})
|
||||
target_compile_definitions(dusklight_game_abi_headers INTERFACE ${_game_compile_defs})
|
||||
|
||||
# Mod feature targets
|
||||
add_library(dusklight_mod_feature_game INTERFACE)
|
||||
target_link_libraries(dusklight_mod_feature_game INTERFACE
|
||||
dusklight_mod_api
|
||||
dusklight_game_abi_headers)
|
||||
target_compile_definitions(dusklight_mod_feature_game INTERFACE DUSK_MOD_FEATURE_GAME=1)
|
||||
target_sources(dusklight_mod_feature_game INTERFACE
|
||||
${_game_root}/sdk/src/game_feature.cpp)
|
||||
|
||||
add_library(dusklight_mod_feature_webgpu INTERFACE)
|
||||
target_link_libraries(dusklight_mod_feature_webgpu INTERFACE dusklight_mod_api)
|
||||
target_compile_definitions(dusklight_mod_feature_webgpu INTERFACE DUSK_MOD_FEATURE_WEBGPU=1)
|
||||
|
||||
+170
-55
@@ -1,8 +1,9 @@
|
||||
# add_mod(<target> SOURCES <file>... MOD_JSON <mod.json> [RES_DIR <res>] [OVERLAY_DIR <overlay>]
|
||||
# add_mod(<target> [FEATURES <feature>...] SOURCES <file>... MOD_JSON <mod.json>
|
||||
# [RUNTIME_LIBRARIES <file>...] [RES_DIR <res>] [OVERLAY_DIR <overlay>]
|
||||
# [TEXTURES_DIR <textures>] [OUTPUT_DIR <dir>] [BUNDLE])
|
||||
set(DUSK_MODS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/mods" CACHE PATH "Directory to write mod packages into")
|
||||
|
||||
function(_mod_lib_name out_var)
|
||||
function(_mod_lib_info out_platform_var out_name_var)
|
||||
set(_arch "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
if (APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
list(LENGTH CMAKE_OSX_ARCHITECTURES _count)
|
||||
@@ -12,18 +13,20 @@ function(_mod_lib_name out_var)
|
||||
set(_arch "${CMAKE_OSX_ARCHITECTURES}")
|
||||
endif ()
|
||||
string(TOLOWER "${CMAKE_SYSTEM_NAME}" _platform)
|
||||
if (_platform STREQUAL "darwin")
|
||||
set(_platform "macos")
|
||||
endif ()
|
||||
string(TOLOWER "${_arch}" _arch)
|
||||
if (_arch MATCHES "^(i[3-6]86|x86)$")
|
||||
set(_arch "x86")
|
||||
endif ()
|
||||
if (WIN32)
|
||||
set(_ext ".dll")
|
||||
elseif (APPLE)
|
||||
set(_ext ".dylib")
|
||||
else ()
|
||||
set(_ext ".so")
|
||||
endif ()
|
||||
set(${out_var} "${_platform}-${_arch}${_ext}" PARENT_SCOPE)
|
||||
set(${out_platform_var} "${_platform}-${_arch}" PARENT_SCOPE)
|
||||
set(${out_name_var} "mod${_ext}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_mod_resolve_source_path out_var path)
|
||||
@@ -44,8 +47,28 @@ function(_mod_collect_assets out_var dir)
|
||||
set(${out_var} ${_files} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_mod_add_webgpu_headers target_name)
|
||||
if (NOT TARGET dawn::dawncpp_headers AND NOT TARGET dawn::webgpu_dawn)
|
||||
include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../extern/aurora/cmake/AuroraDependencyVersions.cmake")
|
||||
set(AURORA_DAWN_PROVIDER "package" CACHE STRING "How to provide Dawn for the mod SDK")
|
||||
include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../extern/aurora/cmake/AuroraDawnProvider.cmake")
|
||||
endif ()
|
||||
|
||||
if (TARGET dawn::dawncpp_headers)
|
||||
target_link_libraries(${target_name} PRIVATE dawn::dawncpp_headers)
|
||||
elseif (TARGET dawn::webgpu_dawn)
|
||||
target_link_libraries(${target_name} PRIVATE dawn::webgpu_dawn)
|
||||
else ()
|
||||
message(FATAL_ERROR "add_mod: FEATURES webgpu could not provide WebGPU headers")
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
function(add_mod target_name)
|
||||
cmake_parse_arguments(ARG "BUNDLE" "MOD_JSON;RES_DIR;OVERLAY_DIR;TEXTURES_DIR;OUTPUT_DIR" "SOURCES" ${ARGN})
|
||||
cmake_parse_arguments(ARG "BUNDLE" "MOD_JSON;RES_DIR;OVERLAY_DIR;TEXTURES_DIR;OUTPUT_DIR"
|
||||
"SOURCES;RUNTIME_LIBRARIES;FEATURES" ${ARGN})
|
||||
if (ARG_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "add_mod: unknown arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
||||
endif ()
|
||||
if (NOT ARG_MOD_JSON)
|
||||
message(FATAL_ERROR "add_mod: MOD_JSON is required")
|
||||
endif ()
|
||||
@@ -54,12 +77,33 @@ function(add_mod target_name)
|
||||
message(FATAL_ERROR "add_mod: MOD_JSON does not exist: ${_mod_json}")
|
||||
endif ()
|
||||
|
||||
set(_supported_features game webgpu)
|
||||
set(_features "")
|
||||
foreach (_feature IN LISTS ARG_FEATURES)
|
||||
list(FIND _supported_features "${_feature}" _feature_index)
|
||||
if (_feature_index EQUAL -1)
|
||||
list(JOIN _supported_features ", " _supported_features_text)
|
||||
message(FATAL_ERROR
|
||||
"add_mod: unknown feature '${_feature}' (supported: ${_supported_features_text})")
|
||||
endif ()
|
||||
list(FIND _features "${_feature}" _duplicate_index)
|
||||
if (NOT _duplicate_index EQUAL -1)
|
||||
message(FATAL_ERROR "add_mod: duplicate feature '${_feature}'")
|
||||
endif ()
|
||||
list(APPEND _features "${_feature}")
|
||||
endforeach ()
|
||||
if (_features AND NOT ARG_SOURCES)
|
||||
message(FATAL_ERROR "add_mod: FEATURES requires SOURCES")
|
||||
endif ()
|
||||
|
||||
set(_has_lib FALSE)
|
||||
set(_needs_host_link FALSE)
|
||||
set(_lib_platform "")
|
||||
set(_lib_name "")
|
||||
if (ARG_SOURCES)
|
||||
set(_has_lib TRUE)
|
||||
add_library(${target_name} SHARED ${ARG_SOURCES})
|
||||
_mod_lib_name(_lib_name)
|
||||
add_library(${target_name} MODULE ${ARG_SOURCES})
|
||||
_mod_lib_info(_lib_platform _lib_name)
|
||||
set_target_properties(${target_name} PROPERTIES
|
||||
PREFIX ""
|
||||
C_VISIBILITY_PRESET hidden
|
||||
@@ -67,7 +111,16 @@ function(add_mod target_name)
|
||||
VISIBILITY_INLINES_HIDDEN ON
|
||||
WINDOWS_EXPORT_ALL_SYMBOLS OFF)
|
||||
target_compile_features(${target_name} PRIVATE cxx_std_20)
|
||||
target_link_libraries(${target_name} PRIVATE dusklight_game_headers)
|
||||
target_link_libraries(${target_name} PRIVATE dusklight_mod_api)
|
||||
foreach (_feature IN LISTS _features)
|
||||
target_link_libraries(${target_name} PRIVATE dusklight_mod_feature_${_feature})
|
||||
if (_feature STREQUAL "webgpu")
|
||||
_mod_add_webgpu_headers(${target_name})
|
||||
endif ()
|
||||
if (_feature STREQUAL "game" OR _feature STREQUAL "webgpu")
|
||||
set(_needs_host_link TRUE)
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
if (NOT TARGET dusklight)
|
||||
# Apply global compile options for out-of-tree mod builds
|
||||
@@ -90,50 +143,77 @@ function(add_mod target_name)
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
# Game symbols resolve against the host executable at dlopen time.
|
||||
target_link_options(${target_name} PRIVATE -undefined dynamic_lookup)
|
||||
if (_needs_host_link)
|
||||
if (TARGET dusklight)
|
||||
set(_game_exe "$<TARGET_FILE:dusklight>")
|
||||
add_dependencies(${target_name} dusklight)
|
||||
elseif (DUSK_GAME_EXE)
|
||||
_mod_resolve_source_path(_game_exe "${DUSK_GAME_EXE}")
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"add_mod: FEATURES ${_features} requires DUSK_GAME_EXE (game executable)")
|
||||
endif ()
|
||||
target_link_options(${target_name} PRIVATE
|
||||
-Xlinker -bundle_loader -Xlinker "${_game_exe}")
|
||||
set_property(TARGET ${target_name} APPEND PROPERTY LINK_DEPENDS "${_game_exe}")
|
||||
endif ()
|
||||
set_target_properties(${target_name} PROPERTIES
|
||||
BUILD_RPATH "@loader_path"
|
||||
INSTALL_RPATH "@loader_path")
|
||||
elseif (ANDROID)
|
||||
if (TARGET dusklight)
|
||||
target_link_libraries(${target_name} PRIVATE dusklight)
|
||||
elseif (DUSK_GAME_SOLIB)
|
||||
target_link_libraries(${target_name} PRIVATE "${DUSK_GAME_SOLIB}")
|
||||
else ()
|
||||
message(FATAL_ERROR "add_mod: DUSK_GAME_SOLIB is not set (libmain.so)")
|
||||
if (_needs_host_link)
|
||||
if (TARGET dusklight)
|
||||
target_link_libraries(${target_name} PRIVATE dusklight)
|
||||
elseif (DUSK_GAME_EXE)
|
||||
_mod_resolve_source_path(_game_lib "${DUSK_GAME_EXE}")
|
||||
target_link_libraries(${target_name} PRIVATE "${_game_lib}")
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"add_mod: FEATURES ${_features} requires DUSK_GAME_EXE (libmain.so or stub)")
|
||||
endif ()
|
||||
endif ()
|
||||
set_target_properties(${target_name} PROPERTIES
|
||||
BUILD_RPATH "$ORIGIN"
|
||||
INSTALL_RPATH "$ORIGIN")
|
||||
elseif (UNIX)
|
||||
target_link_options(${target_name} PRIVATE -Wl,--allow-shlib-undefined)
|
||||
elseif (WIN32)
|
||||
# Link against the generated import library (game ABI surface). Function calls
|
||||
# resolve through import thunks. Data is toolchain dependent:
|
||||
# - clang-cl: lld's mingw mode auto-imports data references, fixed up at load by
|
||||
# the mod SDK's pseudo-relocation runtime (pseudo_reloc.cpp).
|
||||
# - cl (MSVC): only DUSK_GAME_DATA-annotated data is reachable. Un-annotated
|
||||
# references fail to link.
|
||||
if (NOT DUSK_GAME_IMPLIB)
|
||||
message(FATAL_ERROR "add_mod: DUSK_GAME_IMPLIB is not set.")
|
||||
if (_needs_host_link)
|
||||
target_link_options(${target_name} PRIVATE -Wl,--allow-shlib-undefined)
|
||||
endif ()
|
||||
set_target_properties(${target_name} PROPERTIES
|
||||
BUILD_RPATH "$ORIGIN"
|
||||
INSTALL_RPATH "$ORIGIN")
|
||||
elseif (WIN32)
|
||||
# Mods link against the game's import library (sdk/windows-<arch>.lib, generated by
|
||||
# setup_windows_exports); cl and clang-cl both consume it in MSVC mode. Function
|
||||
# calls resolve through import thunks; game data is reachable only through
|
||||
# __declspec(dllimport), i.e. DUSK_GAME_DATA-annotated declarations.
|
||||
if (_needs_host_link)
|
||||
if (TARGET dusklight)
|
||||
if (NOT DUSK_GAME_IMPLIB)
|
||||
message(FATAL_ERROR
|
||||
"add_mod: DUSK_GAME_IMPLIB is not set (see setup_windows_exports)")
|
||||
endif ()
|
||||
set(_game_lib "${DUSK_GAME_IMPLIB}")
|
||||
elseif (DUSK_GAME_EXE)
|
||||
_mod_resolve_source_path(_game_lib "${DUSK_GAME_EXE}")
|
||||
if (NOT _game_lib MATCHES "\\.lib$")
|
||||
message(FATAL_ERROR
|
||||
"add_mod: DUSK_GAME_EXE must be an import library on Windows "
|
||||
"(sdk/windows-<arch>.lib)")
|
||||
endif ()
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"add_mod: FEATURES ${_features} requires DUSK_GAME_EXE (import library)")
|
||||
endif ()
|
||||
target_link_libraries(${target_name} PRIVATE "${_game_lib}")
|
||||
endif ()
|
||||
target_link_libraries(${target_name} PRIVATE "${DUSK_GAME_IMPLIB}")
|
||||
set_target_properties(${target_name} PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
|
||||
target_compile_definitions(${target_name} PRIVATE _ITERATOR_DEBUG_LEVEL=0)
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
target_compile_options(${target_name} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:/clang:-mcmodel=large>")
|
||||
target_sources(${target_name} PRIVATE "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../sdk/pseudo_reloc.cpp")
|
||||
# lld mingw mode rewrites /DEFAULTLIB directives to -l style and skips %LIB%, so
|
||||
# the CRT libraries and search paths are spelled out explicitly.
|
||||
target_link_options(${target_name} PRIVATE -lldmingw /nodefaultlib /INCREMENTAL:NO)
|
||||
target_link_libraries(${target_name} PRIVATE
|
||||
msvcrt.lib msvcprt.lib vcruntime.lib ucrt.lib
|
||||
oldnames.lib uuid.lib kernel32.lib user32.lib)
|
||||
set(_lib_dirs "$ENV{LIB}")
|
||||
if ("${_lib_dirs}" STREQUAL "")
|
||||
message(FATAL_ERROR "add_mod: %LIB% is empty; configure from a VS dev shell")
|
||||
endif ()
|
||||
foreach (_libdir IN LISTS _lib_dirs)
|
||||
target_link_options(${target_name} PRIVATE "/libpath:${_libdir}")
|
||||
endforeach ()
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
if (ARG_RUNTIME_LIBRARIES AND NOT _has_lib)
|
||||
message(FATAL_ERROR "add_mod: RUNTIME_LIBRARIES requires SOURCES")
|
||||
endif ()
|
||||
|
||||
set(_output_dir "${DUSK_MODS_OUTPUT_DIR}")
|
||||
if (ARG_OUTPUT_DIR)
|
||||
@@ -142,18 +222,39 @@ function(add_mod target_name)
|
||||
set(_stage "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_stage")
|
||||
set(_out "${_output_dir}/${target_name}.dusk")
|
||||
|
||||
set(_zip_args "${_lib_name}" mod.json)
|
||||
set(_zip_args mod.json)
|
||||
set(_package_deps "${_mod_json}")
|
||||
set(_package_inputs "${_mod_json}")
|
||||
set(_extra_cmds "")
|
||||
set(_lib_copy_cmd "")
|
||||
set(_target_depend "")
|
||||
if (_has_lib)
|
||||
list(APPEND _zip_args "${_lib_name}")
|
||||
set(_lib_copy_cmd COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"$<TARGET_FILE:${target_name}>" "${_stage}/${_lib_name}")
|
||||
list(APPEND _zip_args lib)
|
||||
set(_lib_copy_cmd
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${_stage}/lib/${_lib_platform}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"$<TARGET_FILE:${target_name}>" "${_stage}/lib/${_lib_platform}/${_lib_name}")
|
||||
set(_target_depend ${target_name})
|
||||
endif ()
|
||||
string(TOLOWER "${_lib_name}" _lib_name_key)
|
||||
set(_runtime_lib_name_keys "${_lib_name_key}")
|
||||
foreach (_runtime_lib IN LISTS ARG_RUNTIME_LIBRARIES)
|
||||
_mod_resolve_source_path(_runtime_lib_path "${_runtime_lib}")
|
||||
if (NOT EXISTS "${_runtime_lib_path}" OR IS_DIRECTORY "${_runtime_lib_path}")
|
||||
message(FATAL_ERROR "add_mod: runtime library does not exist or is not a file: ${_runtime_lib_path}")
|
||||
endif ()
|
||||
get_filename_component(_runtime_lib_name "${_runtime_lib_path}" NAME)
|
||||
string(TOLOWER "${_runtime_lib_name}" _runtime_lib_name_key)
|
||||
list(FIND _runtime_lib_name_keys "${_runtime_lib_name_key}" _runtime_lib_name_index)
|
||||
if (NOT _runtime_lib_name_index EQUAL -1)
|
||||
message(FATAL_ERROR "add_mod: duplicate runtime library filename: ${_runtime_lib_name}")
|
||||
endif ()
|
||||
list(APPEND _runtime_lib_name_keys "${_runtime_lib_name_key}")
|
||||
list(APPEND _package_deps "${_runtime_lib_path}")
|
||||
list(APPEND _package_inputs "${_runtime_lib_path}")
|
||||
list(APPEND _lib_copy_cmd COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${_runtime_lib_path}" "${_stage}/lib/${_lib_platform}/${_runtime_lib_name}")
|
||||
endforeach ()
|
||||
if (ARG_RES_DIR)
|
||||
_mod_resolve_source_path(_res_dir "${ARG_RES_DIR}")
|
||||
_mod_collect_assets(_res_deps "${_res_dir}")
|
||||
@@ -190,6 +291,7 @@ function(add_mod target_name)
|
||||
set_property(GLOBAL APPEND PROPERTY DUSK_BUNDLED_MOD_IDS "${_mod_id}")
|
||||
set_property(GLOBAL APPEND PROPERTY DUSK_BUNDLED_MOD_STAGES "${_stage}")
|
||||
set_property(GLOBAL APPEND PROPERTY DUSK_BUNDLED_MOD_PACKAGES "${_out}")
|
||||
set_property(GLOBAL APPEND PROPERTY DUSK_BUNDLED_MOD_LIB_PLATFORMS "${_lib_platform}")
|
||||
set_property(GLOBAL APPEND PROPERTY DUSK_BUNDLED_MOD_LIB_NAMES "${_lib_name}")
|
||||
set(_bundle_cmds
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundled_mods"
|
||||
@@ -228,9 +330,10 @@ endfunction()
|
||||
# user cache).
|
||||
# - Linux: pre-extracted stage dirs into <install>/mods so native libs dlopen in place from
|
||||
# read-only installs.
|
||||
# - macOS: pre-extracted stage dirs into the installed app's Contents/Resources/mods, dylibs
|
||||
# ad-hoc signed in place, then the whole bundle re-signed.
|
||||
# - iOS/tvOS: assets into <app>/mods/<id> and the dylib into Frameworks/<id>.dylib.
|
||||
# - macOS: pre-extracted stage dirs into the installed app's Contents/Resources/mods, native
|
||||
# libs ad-hoc signed in place, then the whole bundle re-signed.
|
||||
# - iOS/tvOS: assets into <app>/mods/<id>, the mod library into Frameworks/<id>.so,
|
||||
# and runtime libraries alongside it.
|
||||
# - Android: nothing here; gradle packs ${CMAKE_BINARY_DIR}/bundled_mods into APK assets.
|
||||
function(install_bundled_mods)
|
||||
get_property(_targets GLOBAL PROPERTY DUSK_BUNDLED_MOD_TARGETS)
|
||||
@@ -239,6 +342,7 @@ function(install_bundled_mods)
|
||||
endif ()
|
||||
get_property(_ids GLOBAL PROPERTY DUSK_BUNDLED_MOD_IDS)
|
||||
get_property(_stages GLOBAL PROPERTY DUSK_BUNDLED_MOD_STAGES)
|
||||
get_property(_lib_platforms GLOBAL PROPERTY DUSK_BUNDLED_MOD_LIB_PLATFORMS)
|
||||
get_property(_lib_names GLOBAL PROPERTY DUSK_BUNDLED_MOD_LIB_NAMES)
|
||||
list(LENGTH _targets _count)
|
||||
math(EXPR _last "${_count} - 1")
|
||||
@@ -254,19 +358,30 @@ function(install_bundled_mods)
|
||||
list(GET _targets ${_i} _target)
|
||||
list(GET _ids ${_i} _id)
|
||||
list(GET _stages ${_i} _stage)
|
||||
list(GET _lib_platforms ${_i} _lib_platform)
|
||||
list(GET _lib_names ${_i} _lib_name)
|
||||
install(DIRECTORY "${_stage}/" DESTINATION "${_bundle_dir}/mods/${_id}"
|
||||
PATTERN "${_lib_name}" EXCLUDE)
|
||||
PATTERN "lib" EXCLUDE)
|
||||
install(PROGRAMS "$<TARGET_FILE:${_target}>"
|
||||
DESTINATION "${_bundle_dir}/Frameworks" RENAME "${_id}.dylib")
|
||||
DESTINATION "${_bundle_dir}/Frameworks" RENAME "${_id}.so")
|
||||
install(DIRECTORY "${_stage}/lib/${_lib_platform}/"
|
||||
DESTINATION "${_bundle_dir}/Frameworks"
|
||||
PATTERN "${_lib_name}" EXCLUDE)
|
||||
endforeach ()
|
||||
else ()
|
||||
foreach (_i RANGE ${_last})
|
||||
list(GET _ids ${_i} _id)
|
||||
list(GET _stages ${_i} _stage)
|
||||
list(GET _lib_platforms ${_i} _lib_platform)
|
||||
list(GET _lib_names ${_i} _lib_name)
|
||||
install(DIRECTORY "${_stage}/" DESTINATION "${_bundle_dir}/Contents/Resources/mods/${_id}")
|
||||
install(CODE "execute_process(COMMAND /usr/bin/codesign --force --sign - \"${_bundle_dir}/Contents/Resources/mods/${_id}/${_lib_name}\" COMMAND_ERROR_IS_FATAL ANY)")
|
||||
install(CODE "
|
||||
file(GLOB _mod_libs \"${_bundle_dir}/Contents/Resources/mods/${_id}/lib/${_lib_platform}/*\")
|
||||
foreach (_mod_lib IN LISTS _mod_libs)
|
||||
if (NOT IS_DIRECTORY \"\${_mod_lib}\")
|
||||
execute_process(COMMAND /usr/bin/codesign --force --sign - \"\${_mod_lib}\" COMMAND_ERROR_IS_FATAL ANY)
|
||||
endif ()
|
||||
endforeach ()")
|
||||
endforeach ()
|
||||
if (TARGET crashpad_handler)
|
||||
install(CODE "execute_process(COMMAND /usr/bin/codesign --force --sign - \"${_bundle_dir}/Contents/MacOS/$<TARGET_FILE_NAME:crashpad_handler>\" COMMAND_ERROR_IS_FATAL ANY)")
|
||||
|
||||
@@ -2,7 +2,7 @@ include_guard(GLOBAL)
|
||||
|
||||
get_filename_component(_SYMBOL_MANIFEST_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
|
||||
|
||||
set(_SYMGEN_VERSION "1.1.1")
|
||||
set(_SYMGEN_VERSION "1.2.3")
|
||||
set(_SYMGEN_RELEASE_BASE_URL "https://github.com/encounter/symgen/releases/download/v${_SYMGEN_VERSION}")
|
||||
set(SYMGEN_PATH "" CACHE FILEPATH "Path to a symgen executable; empty downloads the pinned release")
|
||||
mark_as_advanced(SYMGEN_PATH)
|
||||
@@ -108,18 +108,21 @@ function(setup_symbol_manifest target)
|
||||
|
||||
if (WIN32)
|
||||
set(_input --pdb "$<TARGET_PDB_FILE:${target}>")
|
||||
set(_out "$<TARGET_FILE_DIR:${target}>/dusklight.symdb")
|
||||
else ()
|
||||
set(_input --binary "$<TARGET_FILE:${target}>")
|
||||
if (APPLE)
|
||||
set(_out "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/Resources/dusklight.symdb")
|
||||
else ()
|
||||
set(_out "$<TARGET_FILE_DIR:${target}>/dusklight.symdb")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
# Room for the load command `symgen manifest --embed` inserts post-link.
|
||||
target_link_options(${target} PRIVATE "LINKER:-headerpad,0x200")
|
||||
endif ()
|
||||
|
||||
# The manifest is embedded into the image as a new section, located at runtime through
|
||||
# the descriptor manifest.cpp reserves. On Apple platforms this command must stay
|
||||
# attached before the ad-hoc codesign POST_BUILD command: the patch invalidates any
|
||||
# existing signature.
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND "${SYMGEN_EXE}" manifest ${_input} --out "${_out}"
|
||||
COMMENT "Generating symbol manifest"
|
||||
COMMAND "${SYMGEN_EXE}" manifest ${_input} --embed "$<TARGET_FILE:${target}>"
|
||||
COMMENT "Embedding symbol manifest"
|
||||
VERBATIM)
|
||||
endfunction()
|
||||
|
||||
+17
-14
@@ -6,9 +6,16 @@ get_filename_component(_DUSK_WINDOWS_EXPORTS_CMAKE_DIR "${CMAKE_CURRENT_LIST_FIL
|
||||
# import library mods link against. symgen scans the built objects, filters by source, and
|
||||
# writes a .def used by the main link and import library generation.
|
||||
function(setup_windows_exports target)
|
||||
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
message(WARNING "dusklight: Windows code-mod exports are x64-only for now; skipping")
|
||||
return()
|
||||
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _implib_arch)
|
||||
if (_implib_arch STREQUAL "arm64")
|
||||
set(_dlltool_machine "arm64")
|
||||
set(_lib_machine "arm64")
|
||||
elseif (_implib_arch MATCHES "^(amd64|x86_64)$")
|
||||
set(_dlltool_machine "i386:x86-64")
|
||||
set(_lib_machine "x64")
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"dusklight: no Windows mod linking support for ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif ()
|
||||
|
||||
include("${_DUSK_WINDOWS_EXPORTS_CMAKE_DIR}/SymbolManifest.cmake")
|
||||
@@ -50,14 +57,13 @@ function(setup_windows_exports target)
|
||||
# Generate curated exports list from the main binary
|
||||
set(_def "${CMAKE_BINARY_DIR}/${_config_subdir}dusklight_exports.def")
|
||||
add_custom_command(TARGET ${target} PRE_LINK
|
||||
# TODO: src/dusk/ is NOT excluded: inline code in game headers
|
||||
# currently call into it (e.g. dusk::frame_interp::lookup_replacement).
|
||||
COMMAND "${_symgen}" def
|
||||
--rsp "${_rsp}"
|
||||
"@${_rsp}"
|
||||
--out "${_def}"
|
||||
--exclude cmake_pch
|
||||
--exclude miniz
|
||||
--exclude asan_options
|
||||
--exclude src/dusk
|
||||
--max-exports 58000
|
||||
${_sdk_args}
|
||||
${_forward_args}
|
||||
@@ -70,11 +76,11 @@ function(setup_windows_exports target)
|
||||
get_filename_component(_compiler_dir "${CMAKE_CXX_COMPILER}" DIRECTORY)
|
||||
find_program(DUSK_LLVM_DLLTOOL llvm-dlltool HINTS "${_compiler_dir}")
|
||||
if (DUSK_LLVM_DLLTOOL)
|
||||
set(_implib_cmd "${DUSK_LLVM_DLLTOOL}" -d "${_def}" -D dusklight.exe -m i386:x86-64
|
||||
-l "${_implib}")
|
||||
set(_implib_cmd "${DUSK_LLVM_DLLTOOL}" -d "${_def}" -D dusklight.exe
|
||||
-m "${_dlltool_machine}" -l "${_implib}")
|
||||
else ()
|
||||
set(_implib_cmd "${CMAKE_AR}" /nologo "/def:${_def}" /machine:x64 /name:dusklight.exe
|
||||
"/out:${_implib}")
|
||||
set(_implib_cmd "${CMAKE_AR}" /nologo "/def:${_def}" "/machine:${_lib_machine}"
|
||||
/name:dusklight.exe "/out:${_implib}")
|
||||
endif ()
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${_implib_cmd}
|
||||
@@ -82,9 +88,6 @@ function(setup_windows_exports target)
|
||||
COMMENT "Generating dusklight import library"
|
||||
VERBATIM)
|
||||
set(DUSK_GAME_IMPLIB "${_implib}" CACHE INTERNAL "Import library for Windows mod linking")
|
||||
set(DUSK_GAME_DEF "${_def}" CACHE INTERNAL "Curated export .def for the game executable")
|
||||
|
||||
# Ship the import library as sdk/dusklight.lib in the install tree: mods may use it to
|
||||
# compile against Dusklight without having to build the whole game. (See DUSK_GAME_IMPLIB)
|
||||
install(FILES "${_implib}" DESTINATION sdk RENAME dusklight.lib)
|
||||
install(FILES "${_implib}" DESTINATION sdk RENAME "windows-${_implib_arch}.lib")
|
||||
endfunction()
|
||||
|
||||
+86
-72
@@ -22,7 +22,7 @@ function, read and write data fields, and hook the vast majority of game functio
|
||||
7. [Asset Overlays](#asset-overlays)
|
||||
8. [Runtime Lifecycle](#runtime-lifecycle)
|
||||
9. [Error Handling](#error-handling)
|
||||
10. [Advanced: Exporting Services](#advanced-exporting-services)
|
||||
10. [Advanced](#advanced)
|
||||
|
||||
---
|
||||
|
||||
@@ -50,6 +50,7 @@ set(DUSKLIGHT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dusklight" CACHE PATH "Path to du
|
||||
add_subdirectory("${DUSKLIGHT_DIR}/sdk" dusklight-sdk EXCLUDE_FROM_ALL)
|
||||
|
||||
add_mod(my_mod
|
||||
FEATURES game # optional
|
||||
SOURCES src/mod.cpp
|
||||
MOD_JSON mod.json
|
||||
RES_DIR res # optional
|
||||
@@ -58,6 +59,12 @@ add_mod(my_mod
|
||||
)
|
||||
```
|
||||
|
||||
Available features:
|
||||
- `game`: Allows calling into and hooking game code. Mods that **only** use services may omit it, providing a wider
|
||||
range of compatibility with Dusklight versions and a slightly faster build process.
|
||||
- `webgpu`: Allows importing the WebGPU API (`webgpu/webgpu.h`). Must be enabled when using
|
||||
[GfxService](#gfxservice-modssvcgfxh).
|
||||
|
||||
Building produces `my_mod.dusk` in `build/<preset>/mods/` (configurable via the `DUSK_MODS_OUTPUT_DIR` cache variable).
|
||||
Dusklight searches a `mods/` directory next to the app in addition to the user directory, so a dev build launched from
|
||||
`build/<preset>/` picks these up automatically: rebuild, relaunch (or click Reload), done.
|
||||
@@ -131,26 +138,30 @@ A service is a struct of C function pointers with a version header. You declare
|
||||
loader resolves it before your mod initializes:
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(LogService, svc_log); // required, any minor version
|
||||
IMPORT_SERVICE_VERSION(LogService, svc_log, 2); // required, minor version >= 2
|
||||
IMPORT_SERVICE(LogService, svc_log); // required, latest minor version
|
||||
IMPORT_SERVICE_VERSION(LogService, svc_log, 0); // required, minimum minor version 0 (for backwards compatibility)
|
||||
IMPORT_OPTIONAL_SERVICE(SomeService, svc_maybe); // may be null
|
||||
```
|
||||
|
||||
Each service is individually versioned, and there may be multiple major versions of a service provided at once,
|
||||
allowing backwards compatibility with older mods while still changing services fundamentally if necessary. A **major**
|
||||
bump is a breaking change, treated as a different service entirely. For **additive** changes, a service appends new
|
||||
functions to the end of the struct without breaking existing callers and simply bumps the minor version. Mods that
|
||||
want the newer functions may use `IMPORT_SERVICE_VERSION` to require that minor at **load time**, or `SERVICE_HAS` to
|
||||
check at **runtime** whether a specific function is available.
|
||||
functions to the end of the struct without breaking existing callers and simply bumps the minor version.
|
||||
|
||||
The contract (see `include/mods/api.h` for the full version):
|
||||
`IMPORT_SERVICE` and `IMPORT_OPTIONAL_SERVICE` require the latest minor version compiled against, making every field in
|
||||
the service safe to call. A mod can use `IMPORT_SERVICE_VERSION` (or its optional counterpart) with an older minor
|
||||
version to remain compatible with older Dusklight versions, then use `SERVICE_HAS` to check at runtime for fields added
|
||||
after that explicitly requested version.
|
||||
|
||||
The contract (see `sdk/include/mods/api.h` for the full version):
|
||||
|
||||
- **A required import is guaranteed valid.** If the service is missing or too old, the mod fails to load with a clear
|
||||
error. No need to null check at call sites.
|
||||
- **Anything at or below the minor version you imported can be called unconditionally.**
|
||||
- **Anything at or below the minor version you imported can be called unconditionally.** The default macros import
|
||||
the service type's current minor version; the versioned macros explicitly override that minimum.
|
||||
- Optional imports may be null; check once in `mod_initialize`.
|
||||
- Fields newer than your imported minor must be gated behind `SERVICE_HAS(service, ServiceType, field)` plus a null
|
||||
check.
|
||||
- Fields newer than your imported minor version must be gated behind `SERVICE_HAS(service, ServiceType, field)` plus a
|
||||
null check.
|
||||
|
||||
---
|
||||
|
||||
@@ -200,13 +211,13 @@ const char* dir = svc_host->mod_dir(mod_ctx); // writable per-mod directory
|
||||
svc_host->fail(mod_ctx, MOD_ERROR, "something unrecoverable happened"); // disables the mod
|
||||
```
|
||||
|
||||
`get_service`/`publish_service` provide dynamic service lookup; see [Advanced](#advanced-exporting-services).
|
||||
`get_service`/`publish_service` provide dynamic service lookup; see [Exporting Services](#exporting-services).
|
||||
|
||||
**Lifecycle watches.** If your mod provides a service that hands out per-caller state (registrations, callbacks,
|
||||
handles), watch other mods' lifecycle and drop what you hold for a mod when it detaches.
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE_VERSION(HostService, svc_host, 1);
|
||||
IMPORT_SERVICE(HostService, svc_host);
|
||||
|
||||
void on_mod_lifecycle(ModContext* ctx, ModContext* subject, const char* subject_id,
|
||||
ModLifecycleEvent event, void* user_data) {
|
||||
@@ -411,6 +422,8 @@ unless changing host UI is intentional.
|
||||
|
||||
### GfxService (`mods/svc/gfx.h`)
|
||||
|
||||
**Requires `add_mod(... FEATURES webgpu)`**
|
||||
|
||||
Direct WebGPU access at various stages of the rendering pipeline. Mods use the `wgpu*` C API (via `webgpu/webgpu.h`) for
|
||||
custom draws and compute dispatches. Mods must manage their own WebGPU state, including pipelines and bind groups.
|
||||
|
||||
@@ -461,6 +474,8 @@ first in-game frame. Projection matrices match the renderer's WebGPU clip conven
|
||||
|
||||
## Hooking Game Functions
|
||||
|
||||
**Requires `add_mod(... FEATURES game)`**
|
||||
|
||||
Mods may hook the vast majority of game functions, including file-local static, private and virtual functions.
|
||||
`mods/hook.hpp` provides typed helpers over the hook service:
|
||||
|
||||
@@ -469,8 +484,14 @@ Mods may hook the vast majority of game functions, including file-local static,
|
||||
#include "mods/svc/hook.h"
|
||||
|
||||
IMPORT_SERVICE(HookService, svc_hook);
|
||||
|
||||
DEFINE_HOOK(&daAlink_c::posMove, LinkPosMove);
|
||||
DEFINE_HOOK(&daAlink_c::execute, LinkExecute);
|
||||
```
|
||||
|
||||
Every hook target must be **declared** at namespace scope with `DEFINE_HOOK` (a target you can name in C++) or
|
||||
`DEFINE_HOOK_SYMBOL` (a symbol name).
|
||||
|
||||
### Pre-hooks
|
||||
|
||||
Run before the original. Return `HOOK_SKIP_ORIGINAL` to cancel it (post-hooks still run).
|
||||
@@ -484,7 +505,7 @@ HookAction on_pos_move_pre(ModContext*, void* args, void* retval, void* userdata
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
dusk::mods::hook_add_pre<&daAlink_c::posMove>(svc_hook, on_pos_move_pre);
|
||||
dusk::mods::hook_add_pre<LinkPosMove>(svc_hook, on_pos_move_pre);
|
||||
```
|
||||
|
||||
### Post-hooks
|
||||
@@ -495,24 +516,22 @@ if any.
|
||||
```cpp
|
||||
void on_pos_move_post(ModContext*, void* args, void* retval, void* userdata) { ... }
|
||||
|
||||
dusk::mods::hook_add_post<&daAlink_c::posMove>(svc_hook, on_pos_move_post);
|
||||
dusk::mods::hook_add_post<LinkPosMove>(svc_hook, on_pos_move_post);
|
||||
```
|
||||
|
||||
### Replace-hooks
|
||||
|
||||
Substitute the original entirely. Call through to it via `Hook<...>::g_orig` if needed:
|
||||
Substitute the original entirely. Call through to it via the declaration's `g_orig` if needed:
|
||||
|
||||
```cpp
|
||||
using ExecuteEntry = dusk::mods::Hook<&daAlink_c::execute>;
|
||||
|
||||
void on_execute_replace(ModContext*, void* args, void* retval, void*) {
|
||||
int result = ExecuteEntry::g_orig(dusk::mods::arg<daAlink_c*>(args, 0));
|
||||
int result = LinkExecute::g_orig(dusk::mods::arg<daAlink_c*>(args, 0));
|
||||
if (retval != nullptr) {
|
||||
*static_cast<int*>(retval) = result;
|
||||
}
|
||||
}
|
||||
|
||||
dusk::mods::hook_replace<&daAlink_c::execute>(svc_hook, on_execute_replace);
|
||||
dusk::mods::hook_replace<LinkExecute>(svc_hook, on_execute_replace);
|
||||
```
|
||||
|
||||
By default a second replace-hook on the same function is a conflict; `HookOptions` (`replace_policy`, `priority`,
|
||||
@@ -525,10 +544,8 @@ Functions you can't name in C++ (file-local statics, private class members, anyt
|
||||
symbol name instead. You must supply the signature along with the name.
|
||||
|
||||
```cpp
|
||||
// static callback used by Link's hookshot collider in d_a_alink_hook.inc
|
||||
using HookshotHit = dusk::mods::NamedHook<
|
||||
"daAlink_hookshotAtHitCallBack",
|
||||
void(fopAc_ac_c*, dCcD_GObjInf*, fopAc_ac_c*, dCcD_GObjInf*)>;
|
||||
DEFINE_HOOK_SYMBOL("daAlink_hookshotAtHitCallBack",
|
||||
void(fopAc_ac_c*, dCcD_GObjInf*, fopAc_ac_c*, dCcD_GObjInf*), HookshotHit);
|
||||
|
||||
dusk::mods::hook_add_pre<HookshotHit>(svc_hook, on_hookshot_hit_pre);
|
||||
...
|
||||
@@ -537,9 +554,16 @@ HookshotHit::g_orig(link, atObjInf, target, tgObjInf); // call through to the o
|
||||
|
||||
Class member functions must include `Class*` as the first argument.
|
||||
|
||||
The install fails with the resolve error when the name is missing (`MOD_UNAVAILABLE`), ambiguous (`MOD_CONFLICT`),
|
||||
or the manifest is absent (`MOD_UNSUPPORTED`). Unlike `Hook<&Class::method>`, the signature is **not**
|
||||
compiler-checked: a mismatched signature will corrupt the call.
|
||||
Two spellings work on every platform:
|
||||
|
||||
- **Display names** (`daAlink_c::posMove`, `fapGm_Before`): the qualified name with no parameter list. They carry no
|
||||
signature, so overload sets (and file-local statics sharing a name) return `MOD_CONFLICT`.
|
||||
- **Decorated names** (`_ZN9daAlink_c7posMoveEv` / `?posMove@daAlink_c@@...`): the platform's mangled spelling in
|
||||
dlsym convention (no Mach-O leading underscore). The escape hatch for overloads.
|
||||
|
||||
Installing fails with `MOD_UNAVAILABLE` when it didn't resolve (missing, ambiguous, or no symbol manifest). Unlike
|
||||
`DEFINE_HOOK`, the signature is **not** compiler-checked: a mismatched signature will corrupt the
|
||||
call.
|
||||
|
||||
### Reading and writing arguments
|
||||
|
||||
@@ -552,6 +576,8 @@ T& ref = dusk::mods::arg_ref<T>(args, n); // read/write reference
|
||||
```
|
||||
|
||||
```cpp
|
||||
DEFINE_HOOK(fopAcM_createItem, CreateItem);
|
||||
|
||||
// fpc_ProcID fopAcM_createItem(..., int itemNo, ...): turn heart drops into green rupees
|
||||
HookAction on_create_item_pre(ModContext*, void* args, void*, void*) {
|
||||
int& itemNo = dusk::mods::arg_ref<int>(args, 1);
|
||||
@@ -561,54 +587,11 @@ HookAction on_create_item_pre(ModContext*, void* args, void*, void*) {
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
dusk::mods::hook_add_pre<&fopAcM_createItem>(svc_hook, on_create_item_pre);
|
||||
dusk::mods::hook_add_pre<CreateItem>(svc_hook, on_create_item_pre);
|
||||
```
|
||||
|
||||
For reference parameters (e.g. `const cXyz& pos`), `arg_ref<cXyz>` yields a direct reference.
|
||||
|
||||
### Resolving symbols by name
|
||||
|
||||
`resolve` looks a symbol up in the **symbol manifest**: a name→address map generated alongside every game build and
|
||||
keyed to that exact binary. It covers the whole image, including functions that aren't exported (file-local statics),
|
||||
which makes them hookable:
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(HookService, svc_hook);
|
||||
|
||||
void* addr = nullptr;
|
||||
uint32_t flags = 0;
|
||||
if (svc_hook->resolve(mod_ctx, "GXSetProjection", &addr, &flags) == MOD_OK) {
|
||||
// addr is the function's real address in the running game; hook or call it.
|
||||
}
|
||||
```
|
||||
|
||||
Two spellings work on every platform:
|
||||
|
||||
- **Display names** (`daAlink_c::posMove`, `fapGm_Before`): the qualified name with no parameter list. They carry no
|
||||
signature, so overload sets (and file-local statics sharing a name) return `MOD_CONFLICT`.
|
||||
- **Decorated names** (`_ZN9daAlink_c7posMoveEv` / `?posMove@daAlink_c@@...`): the platform's mangled spelling in
|
||||
dlsym convention (no Mach-O leading underscore). The escape hatch for overloads.
|
||||
|
||||
`MOD_UNSUPPORTED` means the manifest is missing or was built for a different game binary.
|
||||
|
||||
### Game code ABI contract
|
||||
|
||||
A primary consideration when letting mods link against the game is maintaining ABI stability across Dusklight
|
||||
versions. If your mod calls or hooks game code directly (anything beyond the service APIs), import `GameService`
|
||||
(`mods/svc/game.h`):
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(GameService, svc_game);
|
||||
```
|
||||
|
||||
Its major version is the game code ABI epoch: it's bumped when game struct or vtable layouts change incompatibly, and
|
||||
the ordinary service version check then rejects your mod with a clear error instead of letting it corrupt memory in a
|
||||
version it wasn't built for. Service-only and asset-only mods should *not* import it and will continue to work across
|
||||
game ABI changes.
|
||||
|
||||
The more you can do through services, the better: a mod that avoids touching game code directly sidesteps future ABI
|
||||
breaks entirely and plays nicer with other enabled mods.
|
||||
|
||||
---
|
||||
|
||||
## Asset Overlays
|
||||
@@ -680,7 +663,9 @@ explicit results.
|
||||
|
||||
---
|
||||
|
||||
## Advanced: Exporting Services
|
||||
## Advanced
|
||||
|
||||
### Exporting Services
|
||||
|
||||
Mods may export services of their own, permitting framework mods and cross-mod integration. Define the interface in a
|
||||
header both mods share:
|
||||
@@ -704,6 +689,7 @@ template <>
|
||||
struct dusk::mods::ServiceTraits<MyModService> {
|
||||
static constexpr const char* id = MY_MOD_SERVICE_ID;
|
||||
static constexpr uint16_t major_version = MY_MOD_SERVICE_MAJOR;
|
||||
static constexpr uint16_t minor_version = MY_MOD_SERVICE_MINOR;
|
||||
};
|
||||
#endif
|
||||
```
|
||||
@@ -732,7 +718,7 @@ svc_my_mod->do_thing(mod_ctx, 42);
|
||||
The loader registers all exports before resolving any imports, so declaration order between mods doesn't matter. Note
|
||||
that the `ctx` a provider receives identifies the *calling* mod.
|
||||
|
||||
### Dependencies between mods
|
||||
#### Dependencies between mods
|
||||
|
||||
Service imports are also dependency declarations: the loader initializes mods in dependency order, so by the time your
|
||||
`mod_initialize` runs, every mod you import services from (required *or* optional) has already finished its own
|
||||
@@ -762,3 +748,31 @@ For services whose construction can't happen at static-init time, declare the ex
|
||||
and publish the pointer later via `svc_host->publish_service(...)`. Consumers can fetch services dynamically with
|
||||
`svc_host->get_service(...)`; prefer manifest imports whenever possible, since they give the loader dependency
|
||||
information and fail fast with good errors.
|
||||
|
||||
### Native Runtime Libraries
|
||||
|
||||
`RUNTIME_LIBRARIES` passed to `add_mod` are packaged beside the mod's native module in `lib/<platform>/`. Dusklight
|
||||
extracts the whole directory before loading the mod, so libraries linked by the mod resolve normally. The SDK links the
|
||||
mod itself with `$ORIGIN` on Linux and `@loader_path` on Apple platforms; runtime libraries with their own non-system
|
||||
dependencies must also be built with origin-relative lookup paths. On Windows, Dusklight uses an isolated DLL search
|
||||
rooted at this directory.
|
||||
|
||||
```cmake
|
||||
add_mod(my_mod
|
||||
SOURCES src/mod.cpp
|
||||
MOD_JSON mod.json
|
||||
RUNTIME_LIBRARIES "${VENDOR_RUNTIME_LIBRARY}")
|
||||
```
|
||||
|
||||
SDKs that load plugins by directory can pass them the absolute runtime path from the current HostService:
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(HostService, svc_host);
|
||||
|
||||
const char* nativeDir = svc_host->native_dir(mod_ctx); // read-only
|
||||
```
|
||||
|
||||
Libraries loaded explicitly by the mod remain its responsibility: stop their threads and unload them during
|
||||
`mod_shutdown`. Do not write into `native_dir`; use `mod_dir` for writable state. Native library namespaces are
|
||||
process-wide on some platforms, so two mods cannot safely assume that incompatible libraries with the same filename
|
||||
will remain isolated.
|
||||
|
||||
+88
-49
@@ -1411,70 +1411,103 @@ set(DOLPHIN_FILES
|
||||
)
|
||||
|
||||
set(DUSK_FILES
|
||||
include/dusk/action_bindings.h
|
||||
include/dusk/endian_gx.hpp
|
||||
include/dusk/config.hpp
|
||||
include/dusk/dvd_asset.hpp
|
||||
include/dusk/scope_guard.hpp
|
||||
src/dusk/dvd_asset.cpp
|
||||
include/helpers/batch.hpp
|
||||
include/helpers/endian_gx.hpp
|
||||
src/d/actor/d_a_alink_dusk.cpp
|
||||
src/dusk/android_frame_rate.hpp
|
||||
src/dusk/OSContext.cpp
|
||||
src/dusk/OSMutex.cpp
|
||||
src/dusk/OSReport.cpp
|
||||
src/dusk/OSThread.cpp
|
||||
src/dusk/achievements.cpp
|
||||
src/dusk/action_bindings.cpp
|
||||
src/dusk/action_bindings.h
|
||||
src/dusk/android_frame_rate.cpp
|
||||
src/dusk/android_frame_rate.hpp
|
||||
src/dusk/asserts.cpp
|
||||
src/dusk/batch.cpp
|
||||
src/dusk/batch.hpp
|
||||
src/dusk/autosave.cpp
|
||||
src/dusk/config.cpp
|
||||
src/dusk/config.hpp
|
||||
src/dusk/crash_handler.cpp
|
||||
src/dusk/crash_reporting.cpp
|
||||
src/dusk/data.cpp
|
||||
src/dusk/data.hpp
|
||||
src/dusk/endian.cpp
|
||||
src/dusk/discord.cpp
|
||||
src/dusk/discord.hpp
|
||||
src/dusk/discord_presence.cpp
|
||||
src/dusk/dvd_asset.cpp
|
||||
src/dusk/dvd_asset.hpp
|
||||
src/dusk/extras.c
|
||||
src/dusk/file_select.cpp
|
||||
src/dusk/file_select.hpp
|
||||
src/dusk/frame_interpolation.cpp
|
||||
src/dusk/game_clock.cpp
|
||||
src/dusk/gamepad_color.cpp
|
||||
src/dusk/globals.cpp
|
||||
src/dusk/gyro.cpp
|
||||
include/dusk/menu_pointer.h
|
||||
src/dusk/menu_pointer.cpp
|
||||
src/dusk/mouse.cpp
|
||||
src/dusk/gamepad_color.cpp
|
||||
src/dusk/autosave.cpp
|
||||
src/dusk/http/http.hpp
|
||||
src/dusk/io.cpp
|
||||
src/dusk/layout.cpp
|
||||
src/dusk/logging.cpp
|
||||
src/dusk/settings.cpp
|
||||
src/dusk/speedrun.cpp
|
||||
src/dusk/string.cpp
|
||||
src/dusk/stubs.cpp
|
||||
include/dusk/texture_replacements.hpp
|
||||
src/dusk/texture_replacements.cpp
|
||||
src/dusk/touch_camera.cpp
|
||||
src/dusk/update_check.cpp
|
||||
src/dusk/update_check.hpp
|
||||
#src/dusk/m_Do_ext_dusk.cpp
|
||||
src/dusk/imgui/ImGuiConfig.hpp
|
||||
src/dusk/imgui/ImGuiConsole.hpp
|
||||
src/dusk/imgui/ImGuiConsole.cpp
|
||||
src/dusk/imgui/ImGuiEngine.cpp
|
||||
src/dusk/imgui/ImGuiEngine.hpp
|
||||
src/dusk/imgui/ImGuiActorSpawner.cpp
|
||||
src/dusk/imgui/ImGuiBloomWindow.cpp
|
||||
src/dusk/imgui/ImGuiBloomWindow.hpp
|
||||
src/dusk/imgui/ImGuiCameraOverlay.cpp
|
||||
src/dusk/imgui/ImGuiConfig.hpp
|
||||
src/dusk/imgui/ImGuiConsole.cpp
|
||||
src/dusk/imgui/ImGuiConsole.hpp
|
||||
src/dusk/imgui/ImGuiControllerOverlay.cpp
|
||||
src/dusk/imgui/ImGuiEngine.cpp
|
||||
src/dusk/imgui/ImGuiEngine.hpp
|
||||
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
||||
src/dusk/imgui/ImGuiMenuTools.cpp
|
||||
src/dusk/imgui/ImGuiMenuTools.hpp
|
||||
src/dusk/imgui/ImGuiMenuRandomizer.cpp
|
||||
src/dusk/imgui/ImGuiMenuRandomizer.hpp
|
||||
src/dusk/imgui/ImGuiActorSpawner.cpp
|
||||
src/dusk/imgui/ImGuiProcessOverlay.cpp
|
||||
src/dusk/imgui/ImGuiCameraOverlay.cpp
|
||||
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
||||
src/dusk/imgui/ImGuiControllerOverlay.cpp
|
||||
src/dusk/imgui/ImGuiStubLog.cpp
|
||||
src/dusk/imgui/ImGuiSaveEditor.cpp
|
||||
src/dusk/imgui/ImGuiStateShare.hpp
|
||||
src/dusk/imgui/ImGuiStateShare.cpp
|
||||
src/dusk/imgui/ImGuiStateShare.hpp
|
||||
src/dusk/imgui/ImGuiStubLog.cpp
|
||||
src/dusk/io.cpp
|
||||
src/dusk/iso_validate.cpp
|
||||
src/dusk/layout.cpp
|
||||
src/dusk/livesplit.cpp
|
||||
src/dusk/logging.cpp
|
||||
src/dusk/menu_pointer.cpp
|
||||
src/dusk/menu_pointer.h
|
||||
src/dusk/mods/loader/bundle_disk.cpp
|
||||
src/dusk/mods/loader/bundle_zip.cpp
|
||||
src/dusk/mods/loader/context.cpp
|
||||
src/dusk/mods/loader/depgraph.cpp
|
||||
src/dusk/mods/loader/depgraph.hpp
|
||||
src/dusk/mods/loader/loader.cpp
|
||||
src/dusk/mods/loader/loader.hpp
|
||||
src/dusk/mods/loader/native_module.cpp
|
||||
src/dusk/mods/loader/native_module.hpp
|
||||
src/dusk/mods/log_buffer.cpp
|
||||
src/dusk/mods/log_buffer.hpp
|
||||
src/dusk/mods/manifest.cpp
|
||||
src/dusk/mods/manifest.hpp
|
||||
src/dusk/mods/svc/camera.cpp
|
||||
src/dusk/mods/svc/config.cpp
|
||||
src/dusk/mods/svc/config.hpp
|
||||
src/dusk/mods/svc/game.cpp
|
||||
src/dusk/mods/svc/gfx.cpp
|
||||
src/dusk/mods/svc/hook.cpp
|
||||
src/dusk/mods/svc/host.cpp
|
||||
src/dusk/mods/svc/log.cpp
|
||||
src/dusk/mods/svc/overlay.cpp
|
||||
src/dusk/mods/svc/registry.cpp
|
||||
src/dusk/mods/svc/registry.hpp
|
||||
src/dusk/mods/svc/resource.cpp
|
||||
src/dusk/mods/svc/texture.cpp
|
||||
src/dusk/mods/svc/ui.cpp
|
||||
src/dusk/mods/svc/ui.hpp
|
||||
src/dusk/mouse.cpp
|
||||
src/dusk/scope_guard.hpp
|
||||
src/dusk/settings.cpp
|
||||
src/dusk/speedrun.cpp
|
||||
src/dusk/stubs.cpp
|
||||
src/dusk/texture_replacements.cpp
|
||||
src/dusk/texture_replacements.hpp
|
||||
src/dusk/touch_camera.cpp
|
||||
src/dusk/ui/achievements.cpp
|
||||
src/dusk/ui/achievements.hpp
|
||||
src/dusk/ui/bool_button.cpp
|
||||
@@ -1483,11 +1516,11 @@ set(DUSK_FILES
|
||||
src/dusk/ui/button.hpp
|
||||
src/dusk/ui/component.cpp
|
||||
src/dusk/ui/component.hpp
|
||||
src/dusk/ui/controls.hpp
|
||||
src/dusk/ui/controller_config.cpp
|
||||
src/dusk/ui/controller_config.hpp
|
||||
src/dusk/ui/cosmetics.hpp
|
||||
src/dusk/ui/cosmetics.cpp
|
||||
src/dusk/ui/controls.hpp
|
||||
src/dusk/ui/document.cpp
|
||||
src/dusk/ui/document.hpp
|
||||
src/dusk/ui/editor.cpp
|
||||
@@ -1496,18 +1529,22 @@ set(DUSK_FILES
|
||||
src/dusk/ui/event.hpp
|
||||
src/dusk/ui/graphics_tuner.cpp
|
||||
src/dusk/ui/graphics_tuner.hpp
|
||||
src/dusk/ui/input.cpp
|
||||
src/dusk/ui/input.hpp
|
||||
src/dusk/ui/icon_provider.cpp
|
||||
src/dusk/ui/icon_provider.hpp
|
||||
src/dusk/ui/input.cpp
|
||||
src/dusk/ui/input.hpp
|
||||
src/dusk/ui/logs_window.cpp
|
||||
src/dusk/ui/logs_window.hpp
|
||||
src/dusk/ui/menu_bar.cpp
|
||||
src/dusk/ui/menu_bar.hpp
|
||||
src/dusk/ui/mod_texture_provider.cpp
|
||||
src/dusk/ui/mod_texture_provider.hpp
|
||||
src/dusk/ui/mod_window.cpp
|
||||
src/dusk/ui/mod_window.hpp
|
||||
src/dusk/ui/modal.cpp
|
||||
src/dusk/ui/modal.hpp
|
||||
src/dusk/ui/mods_window.cpp
|
||||
src/dusk/ui/mods_window.hpp
|
||||
src/dusk/ui/nav_types.hpp
|
||||
src/dusk/ui/number_button.cpp
|
||||
src/dusk/ui/number_button.hpp
|
||||
@@ -1515,10 +1552,6 @@ set(DUSK_FILES
|
||||
src/dusk/ui/overlay.hpp
|
||||
src/dusk/ui/pane.cpp
|
||||
src/dusk/ui/pane.hpp
|
||||
src/dusk/ui/menu_bar.cpp
|
||||
src/dusk/ui/menu_bar.hpp
|
||||
src/dusk/ui/mods_window.cpp
|
||||
src/dusk/ui/mods_window.hpp
|
||||
src/dusk/ui/prelaunch.cpp
|
||||
src/dusk/ui/prelaunch.hpp
|
||||
src/dusk/ui/preset.cpp
|
||||
@@ -1533,10 +1566,10 @@ set(DUSK_FILES
|
||||
src/dusk/ui/string_button.hpp
|
||||
src/dusk/ui/tab_bar.cpp
|
||||
src/dusk/ui/tab_bar.hpp
|
||||
src/dusk/ui/touch_controls_common.cpp
|
||||
src/dusk/ui/touch_controls_common.hpp
|
||||
src/dusk/ui/touch_controls.cpp
|
||||
src/dusk/ui/touch_controls.hpp
|
||||
src/dusk/ui/touch_controls_common.cpp
|
||||
src/dusk/ui/touch_controls_common.hpp
|
||||
src/dusk/ui/touch_controls_editor.cpp
|
||||
src/dusk/ui/touch_controls_editor.hpp
|
||||
src/dusk/ui/ui.cpp
|
||||
@@ -1552,7 +1585,6 @@ set(DUSK_FILES
|
||||
src/dusk/achievements.cpp
|
||||
src/dusk/iso_validate.cpp
|
||||
src/dusk/livesplit.cpp
|
||||
src/dusk/offset_ptr.cpp
|
||||
src/dusk/OSContext.cpp
|
||||
src/dusk/OSReport.cpp
|
||||
src/dusk/OSThread.cpp
|
||||
@@ -1590,6 +1622,9 @@ set(DUSK_FILES
|
||||
src/dusk/discord_presence.cpp
|
||||
src/dusk/version.cpp
|
||||
src/dusk/action_bindings.cpp
|
||||
src/dusk/update_check.cpp
|
||||
src/dusk/update_check.hpp
|
||||
src/dusk/version.cpp
|
||||
src/dusk/cosmetics/color_utils.hpp
|
||||
src/dusk/cosmetics/color_utils.cpp
|
||||
src/dusk/cosmetics/midna_hair_color.hpp
|
||||
@@ -1684,6 +1719,10 @@ set(DUSK_FILES
|
||||
src/dusk/randomizer/generator/utility/time.cpp
|
||||
src/dusk/randomizer/generator/utility/time.hpp
|
||||
src/dusk/randomizer/generator/utility/yaml.hpp
|
||||
src/helpers/batch.cpp
|
||||
src/helpers/endian.cpp
|
||||
src/helpers/offset_ptr.cpp
|
||||
src/helpers/string.cpp
|
||||
)
|
||||
|
||||
set(DUSK_HTTP_BACKEND_FILES
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "f_pc/f_pc_base.h"
|
||||
#include "SSystem/SComponent/c_bg_s_grp_pass_chk.h"
|
||||
#include "SSystem/SComponent/c_bg_s_poly_pass_chk.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
struct cBgD_Vtx_t : public Vec {};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define C_M3D_G_TRI_H_
|
||||
|
||||
#include "SSystem/SComponent/c_m3d_g_pla.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class cM3dGCyl;
|
||||
|
||||
|
||||
@@ -95,12 +95,6 @@ static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr);
|
||||
#define THP_TEXTURE_SET_COUNT 3
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
namespace dusk {
|
||||
void MoviePlayerShutdown();
|
||||
}
|
||||
#endif
|
||||
|
||||
struct daMP_THPPlayer {
|
||||
/* 0x000 */ DVDFileInfo fileInfo;
|
||||
/* 0x03C */ THPHeader header;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "SSystem/SComponent/c_xyz.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/batch.hpp"
|
||||
#include "helpers/batch.hpp"
|
||||
#endif
|
||||
|
||||
class cCcD_Obj;
|
||||
@@ -112,11 +112,11 @@ public:
|
||||
TGXTexObj mTexObj_l_J_Ohana00_64TEX;
|
||||
TGXTexObj mTexObj_l_J_Ohana01_64128_0419TEX;
|
||||
|
||||
dusk::batch::LeafTemplate mTplHana00; // l_J_hana00DL
|
||||
dusk::batch::LeafTemplate mTplHana00Cut; // l_J_hana00_cDL
|
||||
dusk::batch::LeafTemplate mTplHana01; // l_J_hana01DL
|
||||
dusk::batch::LeafTemplate mTplHana01Cut00; // l_J_hana01_c_00DL
|
||||
dusk::batch::LeafTemplate mTplHana01Cut; // l_J_hana01_c_01DL
|
||||
batch::LeafTemplate mTplHana00; // l_J_hana00DL
|
||||
batch::LeafTemplate mTplHana00Cut; // l_J_hana00_cDL
|
||||
batch::LeafTemplate mTplHana01; // l_J_hana01DL
|
||||
batch::LeafTemplate mTplHana01Cut00; // l_J_hana01_c_00DL
|
||||
batch::LeafTemplate mTplHana01Cut; // l_J_hana01_c_01DL
|
||||
#endif
|
||||
}; // Size: 0x12A54
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "SSystem/SComponent/c_xyz.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "../../../src/dusk/batch.hpp"
|
||||
#include <helpers/batch.hpp>
|
||||
#endif
|
||||
|
||||
class cCcD_Obj;
|
||||
@@ -115,9 +115,9 @@ public:
|
||||
TGXTexObj mTexObj_l_M_Hijiki00TEX;
|
||||
TGXTexObj mTexObj_l_M_kusa05_RGBATEX;
|
||||
|
||||
dusk::batch::LeafTemplate mTplKusa9q; // l_M_Kusa_9qDL
|
||||
dusk::batch::LeafTemplate mTplKusa9qCut; // l_M_Kusa_9q_cDL
|
||||
dusk::batch::LeafTemplate mTplTengusa; // l_M_TenGusaDL
|
||||
batch::LeafTemplate mTplKusa9q; // l_M_Kusa_9qDL
|
||||
batch::LeafTemplate mTplKusa9qCut; // l_M_Kusa_9q_cDL
|
||||
batch::LeafTemplate mTplTengusa; // l_M_TenGusaDL
|
||||
#endif
|
||||
}; // Size: 0x1D718
|
||||
|
||||
|
||||
+3
-3
@@ -6,9 +6,9 @@
|
||||
#include "d/d_bg_w_base.h"
|
||||
#include <mtx.h>
|
||||
#include <types.h>
|
||||
#include "dusk/offset_ptr.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "dusk/endian_ssystem.h"
|
||||
#include "helpers/offset_ptr.h"
|
||||
#include "helpers/endian.h"
|
||||
#include "helpers/endian_ssystem.h"
|
||||
|
||||
class cBgS_GrpPassChk;
|
||||
class cBgS_PolyPassChk;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "d/d_bg_plc.h"
|
||||
#include "d/d_bg_s_sph_chk.h"
|
||||
#include "d/d_bg_w_base.h"
|
||||
#include "dusk/offset_ptr.h"
|
||||
#include "helpers/offset_ptr.h"
|
||||
|
||||
class cBgS_GrpPassChk;
|
||||
class cBgS_PolyPassChk;
|
||||
|
||||
+18
-16
@@ -17,8 +17,14 @@
|
||||
#include "m_Do/m_Do_graphic.h"
|
||||
#include <cstring>
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/profiling.hpp"
|
||||
#if defined(DUSK_BUILDING_GAME)
|
||||
#include <tracy/Tracy.hpp>
|
||||
#include "dusk/settings.h"
|
||||
#else
|
||||
#ifndef ZoneScoped
|
||||
#define ZoneScoped
|
||||
#define ZoneScopedN(name)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum dComIfG_ButtonStatus {
|
||||
@@ -4907,27 +4913,23 @@ inline void dComIfGd_drawXluListDark() {
|
||||
g_dComIfG_gameInfo.drawlist.drawXluListDark();
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void dComIfGd_drawXluListInvisible();
|
||||
#else
|
||||
inline void dComIfGd_drawXluListInvisible() {
|
||||
ZoneScoped;
|
||||
#ifdef TARGET_PC
|
||||
if (!dusk::getSettings().game.disableWaterRefraction) {
|
||||
#endif
|
||||
g_dComIfG_gameInfo.drawlist.drawXluListInvisible();
|
||||
#ifdef TARGET_PC
|
||||
}
|
||||
#endif
|
||||
g_dComIfG_gameInfo.drawlist.drawXluListInvisible();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
void dComIfGd_drawOpaListInvisible();
|
||||
#else
|
||||
inline void dComIfGd_drawOpaListInvisible() {
|
||||
ZoneScoped;
|
||||
#ifdef TARGET_PC
|
||||
if (!dusk::getSettings().game.disableWaterRefraction) {
|
||||
#endif
|
||||
g_dComIfG_gameInfo.drawlist.drawOpaListInvisible();
|
||||
#ifdef TARGET_PC
|
||||
}
|
||||
#endif
|
||||
g_dComIfG_gameInfo.drawlist.drawOpaListInvisible();
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void dComIfGd_drawXluListZxlu() {
|
||||
ZoneScoped;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "JSystem/J2DGraph/J2DScreen.h"
|
||||
#include "JSystem/J3DGraphBase/J3DSys.h"
|
||||
#include "SSystem/SComponent/c_m3d_g_pla.h"
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "helpers/gx_helper.h"
|
||||
#include "f_op/f_op_view.h"
|
||||
#include "global.h"
|
||||
#include "m_Do/m_Do_ext.h"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "global.h"
|
||||
#include "f_pc/f_pc_base.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
struct msg_class;
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#include "JSystem/JMessage/control.h"
|
||||
#include "JSystem/JMessage/JMessage.h"
|
||||
#include "SSystem/SComponent/c_xyz.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/endian.h"
|
||||
#include "helpers/string.hpp"
|
||||
|
||||
#if REGION_JPN
|
||||
#define D_MSG_CLASS_PAGE_CNT_MAX 30
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define D_MSG_D_MSG_FLOW_H
|
||||
|
||||
#include <types.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
enum {
|
||||
NODETYPE_MESSAGE_e = 1,
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
#include "d/d_item_data.h"
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include "JSystem/JHostIO/JORReflexible.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include <unordered_map>
|
||||
@@ -522,7 +522,7 @@ public:
|
||||
#endif
|
||||
void setPlayerName(const char* i_name) {
|
||||
#if AVOID_UB
|
||||
dusk::SafeStringCopyTruncate(mPlayerName, i_name);
|
||||
SafeStringCopyTruncate(mPlayerName, i_name);
|
||||
#else
|
||||
strcpy(mPlayerName, i_name);
|
||||
#endif
|
||||
@@ -534,7 +534,7 @@ public:
|
||||
#endif
|
||||
void setHorseName(const char* i_name) {
|
||||
#if AVOID_UB
|
||||
dusk::SafeStringCopyTruncate(mHorseName, i_name);
|
||||
SafeStringCopyTruncate(mHorseName, i_name);
|
||||
#else
|
||||
strcpy(mHorseName, i_name);
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
#include "SSystem/SComponent/c_lib.h"
|
||||
#include "d/d_kankyo.h"
|
||||
#include "d/d_kankyo_data.h"
|
||||
#include "dusk/offset_ptr.h"
|
||||
#include "helpers/offset_ptr.h"
|
||||
#include "f_op/f_op_actor_mng.h"
|
||||
#include "global.h"
|
||||
#include "os_report.h"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define D_D_TRESURE_H
|
||||
|
||||
#include <mtx.h>
|
||||
#include "dusk/offset_ptr.h"
|
||||
#include "helpers/offset_ptr.h"
|
||||
|
||||
class dTres_c {
|
||||
public:
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef __MWERKS__
|
||||
#include "dusk/math.h"
|
||||
#include "helpers/math.h"
|
||||
#endif
|
||||
|
||||
#endif // dolzel.h
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef _SRC_IMGUI_H_
|
||||
#define _SRC_IMGUI_H_
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void imgui_main(const AuroraInfo* info);
|
||||
void frame_limiter();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<tracy/Tracy.hpp>)
|
||||
#include <tracy/Tracy.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ZoneScoped
|
||||
#define ZoneScoped
|
||||
#define ZoneScopedN(name)
|
||||
#endif
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "f_pc/f_pc_manager.h"
|
||||
#include "m_Do/m_Do_hostIO.h"
|
||||
#include "SSystem/SComponent/c_phase.h"
|
||||
#include "dusk/endian_ssystem.h"
|
||||
#include "helpers/endian_ssystem.h"
|
||||
|
||||
#if !__MWERKS__
|
||||
// mwerks compiler makes value initialization act like default initialization so we need
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# Public game helpers
|
||||
|
||||
Headers in this directory provide port-specific types and utilities used by ordinary game
|
||||
headers. Their corresponding implementations live in `src/helpers/`.
|
||||
|
||||
These helpers **must not** depend on internal `src/dusk/` declarations in their public interface.
|
||||
Unlike the internal `dusk::` namespace, they are exposed to mods that use the `game` feature
|
||||
and therefore must remain ABI stable within `GameService` major versions.
|
||||
|
||||
APIs _specifically_ for mod use do not belong here; instead they belong in mod services,
|
||||
which are individually versioned, can provide backwards compatibility, and are designed to
|
||||
keep track of per-mod runtime state.
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <dolphin/types.h>
|
||||
|
||||
namespace dusk::batch {
|
||||
namespace batch {
|
||||
|
||||
struct LeafTemplate {
|
||||
static constexpr u32 kMaxVtx = 192;
|
||||
@@ -22,4 +22,4 @@ struct LeafTemplate {
|
||||
|
||||
void decode_leaf_template(const u8* dl, u32 size, LeafTemplate& out);
|
||||
|
||||
} // namespace dusk
|
||||
} // namespace batch
|
||||
@@ -1,5 +1,4 @@
|
||||
#ifndef DOLPHIN_ENDIAN_H
|
||||
#define DOLPHIN_ENDIAN_H
|
||||
#pragma once
|
||||
|
||||
#include <bit>
|
||||
|
||||
@@ -292,6 +291,3 @@ inline void be_swap(Mtx& val) {
|
||||
#define BE(T) T
|
||||
#define BE_HOST(T) (T)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // DOLPHIN_ENDIAN_H
|
||||
@@ -1,5 +1,4 @@
|
||||
#ifndef _DUSK_ENDIAN_SSYSTEM_H_
|
||||
#define _DUSK_ENDIAN_SSYSTEM_H_
|
||||
#pragma once
|
||||
|
||||
#include "SSystem/SComponent/c_sxyz.h"
|
||||
#include "endian.h"
|
||||
@@ -61,5 +60,3 @@ struct BE<cXyz> {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,12 +1,17 @@
|
||||
#ifndef DUSK_GX_HELPER_H
|
||||
#define DUSK_GX_HELPER_H
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <dolphin/gx/GXAurora.h>
|
||||
#include <dolphin/gx/GXExtra.h>
|
||||
|
||||
#include "profiling.hpp"
|
||||
#if defined(DUSK_BUILDING_GAME)
|
||||
#include <tracy/Tracy.hpp>
|
||||
#else
|
||||
#ifndef ZoneScopedN
|
||||
#define ZoneScopedN(name)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if DUSK_GFX_DEBUG_GROUPS
|
||||
#define GX_DEBUG_GROUP(name, ...) \
|
||||
@@ -79,5 +84,3 @@ struct GXScopedDebugGroup {
|
||||
};
|
||||
|
||||
#define GX_AND_TRACY_SCOPED(name) GXScopedDebugGroup scope(name); ZoneScopedN(name);
|
||||
|
||||
#endif // DUSK_GX_HELPER_H
|
||||
@@ -1,5 +1,4 @@
|
||||
#ifndef _SRC_DUSK_MATH_H_
|
||||
#define _SRC_DUSK_MATH_H_
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@@ -17,5 +16,3 @@ inline float i_tanf(float x) { return tan(x); }
|
||||
inline float i_acosf(float x) { return acos(x); }
|
||||
|
||||
#include <dolphin/ppc_math.h>
|
||||
|
||||
#endif // _SRC_DUSK_MATH_H_
|
||||
@@ -1,5 +1,4 @@
|
||||
#ifndef DUSK_OFFSET_PTR_H
|
||||
#define DUSK_OFFSET_PTR_H
|
||||
#pragma once
|
||||
|
||||
#if TARGET_PC
|
||||
|
||||
@@ -47,21 +46,17 @@ struct OffsetPtrT {
|
||||
}
|
||||
|
||||
operator T*() const {
|
||||
return (T*) value;
|
||||
}
|
||||
return (T*)value; }
|
||||
|
||||
template<typename TOther>
|
||||
template <typename TOther>
|
||||
explicit operator TOther*() const {
|
||||
return (TOther*) value;
|
||||
return (TOther*)value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define OFFSET_PTR(T) OffsetPtrT<T>
|
||||
#define OFFSET_PTR_RAW OffsetPtr
|
||||
#else
|
||||
#define OFFSET_PTR(T) T*
|
||||
#define OFFSET_PTR_RAW u32
|
||||
#endif
|
||||
|
||||
#endif // DUSK_OFFSET_PTR_H
|
||||
@@ -1,8 +1,7 @@
|
||||
#ifndef DUSK_STRING_HPP
|
||||
#define DUSK_STRING_HPP
|
||||
#include <cstdarg>
|
||||
#pragma once
|
||||
|
||||
namespace dusk {
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
|
||||
struct TextSpan {
|
||||
char* buffer;
|
||||
@@ -44,7 +43,7 @@ private:
|
||||
};
|
||||
|
||||
#if TARGET_PC
|
||||
#define TEXT_SPAN dusk::TextSpan
|
||||
#define TEXT_SPAN TextSpan
|
||||
#else
|
||||
#define TEXT_SPAN char*
|
||||
#endif
|
||||
@@ -111,11 +110,11 @@ int SafeStringPrintf(char (&buffer)[BufSize], const char* format, ...) {
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
#define SAFE_STRCPY dusk::SafeStringCopy
|
||||
#define SAFE_STRCAT dusk::SafeStringCat
|
||||
#define SAFE_SPRINTF dusk::SafeStringPrintf
|
||||
#define SAFE_STRCPY_BOUNDED dusk::SafeStringCopy
|
||||
#define SAFE_STRCAT_BOUNDED dusk::SafeStringCat
|
||||
#define SAFE_STRCPY SafeStringCopy
|
||||
#define SAFE_STRCAT SafeStringCat
|
||||
#define SAFE_SPRINTF SafeStringPrintf
|
||||
#define SAFE_STRCPY_BOUNDED SafeStringCopy
|
||||
#define SAFE_STRCAT_BOUNDED SafeStringCat
|
||||
#else
|
||||
#define SAFE_STRCPY strcpy
|
||||
#define SAFE_STRCAT strcat
|
||||
@@ -123,6 +122,3 @@ int SafeStringPrintf(char (&buffer)[BufSize], const char* format, ...) {
|
||||
#define SAFE_STRCPY_BOUNDED strcpy
|
||||
#define SAFE_STRCPY_BOUNDED strcat
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // DUSK_STRING_HPP
|
||||
@@ -4,8 +4,12 @@
|
||||
#include "Z2AudioLib/Z2AudioMgr.h"
|
||||
#include "Z2AudioLib/Z2EnvSeMgr.h"
|
||||
#include "Z2AudioLib/Z2LinkMgr.h"
|
||||
#if defined(DUSK_BUILDING_GAME)
|
||||
#include "dusk/audio.h"
|
||||
#include "dusk/settings.h"
|
||||
#else
|
||||
#define DUSK_AUDIO_SKIP(...)
|
||||
#endif
|
||||
|
||||
class mDoAud_zelAudio_c : public Z2AudioMgr {
|
||||
public:
|
||||
@@ -134,15 +138,7 @@ inline void mDoAud_seStart(u32 i_sfxID, const Vec* i_sePos, u32 param_2, s8 i_re
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
inline void mDoAud_seStartMenu(u32 i_sfxID) {
|
||||
if (!mDoAud_zelAudio_c::isInitFlag()) {
|
||||
return;
|
||||
}
|
||||
if (!dusk::getSettings().audio.menuSounds.getValue()) {
|
||||
return;
|
||||
}
|
||||
mDoAud_seStart(i_sfxID, nullptr, 0, 0);
|
||||
}
|
||||
void mDoAud_seStartMenu(u32 i_sfxID);
|
||||
#endif
|
||||
|
||||
inline void mDoAud_seStartLevel(u32 i_sfxID, const Vec* i_sePos, u32 param_2, s8 i_reverb) {
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
|
||||
#include "JSystem/JUtility/JUTGamePad.h"
|
||||
#include "SSystem/SComponent/c_API_controller_pad.h"
|
||||
|
||||
#if defined(DUSK_BUILDING_GAME)
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
// Controller Ports 1 - 4
|
||||
enum { PAD_1, PAD_2, PAD_3, PAD_4 };
|
||||
@@ -54,29 +57,21 @@ public:
|
||||
static f32 getStickValue(u32 pad) { return getCpadInfo(pad).mMainStickValue; }
|
||||
static s16 getStickAngle(u32 pad) { return getCpadInfo(pad).mMainStickAngle; }
|
||||
|
||||
#if TARGET_PC
|
||||
static s16 getStickAngle3D(u32 pad);
|
||||
#else
|
||||
static s16 getStickAngle3D(u32 pad) {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
return -getCpadInfo(pad).mMainStickAngle;
|
||||
} else {
|
||||
return getCpadInfo(pad).mMainStickAngle;
|
||||
}
|
||||
#else
|
||||
return getCpadInfo(pad).mMainStickAngle;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
static f32 getSubStickX3D(u32 pad);
|
||||
#else
|
||||
static f32 getSubStickX3D(u32 pad) {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
return -getCpadInfo(pad).mCStickPosX;
|
||||
} else {
|
||||
return getCpadInfo(pad).mCStickPosX;
|
||||
}
|
||||
#else
|
||||
return getCpadInfo(pad).mCStickPosX;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static f32 getSubStickX(u32 pad) { return getCpadInfo(pad).mCStickPosX; }
|
||||
static f32 getSubStickY(u32 pad) { return getCpadInfo(pad).mCStickPosY; }
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "JSystem/JGeometry.h"
|
||||
#endif
|
||||
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "helpers/gx_helper.h"
|
||||
|
||||
typedef struct Vec Vec;
|
||||
struct ResTIMG;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <mtx.h>
|
||||
|
||||
#include "JSystem/JMath/JMath.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
extern u8 g_printCurrentHeapDebug;
|
||||
DUSK_GAME_EXTERN u8 g_printOtherHeapDebug;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define M_DO_M_DO_PRINTF_H
|
||||
|
||||
#include <os.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
void my_PutString(const char*);
|
||||
void mDoPrintf_vprintf_Interrupt(char const*, va_list);
|
||||
|
||||
@@ -1,464 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "mods/svc/hook.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
namespace dusk::mods {
|
||||
|
||||
template <class T>
|
||||
T arg(void* argsRaw, int n) noexcept {
|
||||
void** args = static_cast<void**>(argsRaw);
|
||||
return *static_cast<std::add_pointer_t<std::remove_reference_t<T> > >(args[n]);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::remove_reference_t<T>& arg_ref(void* argsRaw, int n) noexcept {
|
||||
void** args = static_cast<void**>(argsRaw);
|
||||
return *static_cast<std::add_pointer_t<std::remove_reference_t<T> > >(args[n]);
|
||||
}
|
||||
|
||||
template <class F>
|
||||
void* mfp_addr(F fn) noexcept {
|
||||
void* p = nullptr;
|
||||
static_assert(sizeof(fn) >= sizeof(void*), "unexpected function pointer size");
|
||||
std::memcpy(&p, &fn, sizeof(void*));
|
||||
return p;
|
||||
}
|
||||
|
||||
/* A string usable as a template argument: carries the hook target's symbol name and
|
||||
* makes each NamedHook instantiation's static state unique. */
|
||||
template <size_t N>
|
||||
struct FixedString {
|
||||
char chars[N]{};
|
||||
constexpr FixedString(const char (&s)[N]) noexcept {
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
chars[i] = s[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
constexpr std::string_view class_name() {
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
// "... class_name() [T = daAlink_c]" / "... [with T = daAlink_c; ...]"
|
||||
constexpr std::string_view fn = __PRETTY_FUNCTION__;
|
||||
constexpr size_t start = fn.find("T = ") + 4;
|
||||
return fn.substr(start, fn.find_first_of(";]", start) - start);
|
||||
#elif defined(_MSC_VER)
|
||||
// "... class_name<class daAlink_c>(void)"
|
||||
constexpr std::string_view fn = __FUNCSIG__;
|
||||
constexpr size_t start = fn.find("class_name<") + 11;
|
||||
constexpr std::string_view name = fn.substr(start, fn.rfind(">(") - start);
|
||||
if constexpr (name.starts_with("class ")) {
|
||||
return name.substr(6);
|
||||
} else if constexpr (name.starts_with("struct ")) {
|
||||
return name.substr(7);
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
#else
|
||||
#error "unsupported compiler"
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The manifest name of C's vtable. Only unscoped, non-template class names are
|
||||
* supported (an empty result fails resolution and the install reports it). */
|
||||
template <class C>
|
||||
constexpr auto vtable_symbol() {
|
||||
constexpr std::string_view name = class_name<C>();
|
||||
constexpr bool simple = name.find_first_of(":<> ") == std::string_view::npos;
|
||||
// "_ZTV" + decimal length + name / "??_7" + name + "@@6B@", NUL-terminated
|
||||
std::array<char, name.size() + 12> out{};
|
||||
if constexpr (!simple) {
|
||||
return out;
|
||||
}
|
||||
size_t n = 0;
|
||||
#if defined(_WIN32)
|
||||
for (char c : {'?', '?', '_', '7'}) {
|
||||
out[n++] = c;
|
||||
}
|
||||
for (char c : name) {
|
||||
out[n++] = c;
|
||||
}
|
||||
for (char c : {'@', '@', '6', 'B', '@'}) {
|
||||
out[n++] = c;
|
||||
}
|
||||
#else
|
||||
for (char c : {'_', 'Z', 'T', 'V'}) {
|
||||
out[n++] = c;
|
||||
}
|
||||
size_t len = name.size();
|
||||
char digits[8]{};
|
||||
size_t d = 0;
|
||||
while (len != 0) {
|
||||
digits[d++] = static_cast<char>('0' + len % 10);
|
||||
len /= 10;
|
||||
}
|
||||
while (d != 0) {
|
||||
out[n++] = digits[--d];
|
||||
}
|
||||
for (char c : name) {
|
||||
out[n++] = c;
|
||||
}
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* Follow jump stubs, then match the MSVC vcall thunk a virtual mfp points at.
|
||||
* Returns the vtable slot's byte offset, or npos when fn is not a vcall thunk. */
|
||||
inline size_t vcall_slot_offset(const void*& fn) noexcept {
|
||||
constexpr size_t npos = static_cast<size_t>(-1);
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
const auto* p = static_cast<const uint8_t*>(fn);
|
||||
for (int i = 0; i < 8 && p[0] == 0xE9; ++i) { // incremental-link stubs
|
||||
int32_t rel;
|
||||
std::memcpy(&rel, p + 1, 4);
|
||||
p += 5 + rel;
|
||||
}
|
||||
fn = p;
|
||||
// The vptr load. Unoptimized clang-cl thunks spill/reload rcx first
|
||||
// (push rax; mov [rsp], rcx; mov rcx, [rsp]), so scan a short window.
|
||||
const uint8_t* q = nullptr;
|
||||
for (int i = 0; i <= 12; ++i) {
|
||||
if (p[i] == 0x48 && p[i + 1] == 0x8B && p[i + 2] == 0x01) { // mov rax, [rcx]
|
||||
q = p + i + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (q == nullptr) {
|
||||
return npos;
|
||||
}
|
||||
if (q[0] == 0xFF && q[1] == 0x20) { // jmp [rax] (MSVC)
|
||||
return 0;
|
||||
}
|
||||
if (q[0] == 0xFF && q[1] == 0x60) { // jmp [rax + imm8]
|
||||
return static_cast<int8_t>(q[2]);
|
||||
}
|
||||
if (q[0] == 0xFF && q[1] == 0xA0) { // jmp [rax + imm32]
|
||||
int32_t off;
|
||||
std::memcpy(&off, q + 2, 4);
|
||||
return off;
|
||||
}
|
||||
// clang-cl: mov rax, [rax + off]; (pop r10;) jmp rax. Requiring the jmp rax
|
||||
// distinguishes the thunk from an ordinary getter that begins the same way.
|
||||
if (q[0] == 0x48 && q[1] == 0x8B && (q[2] == 0x00 || q[2] == 0x40 || q[2] == 0x80)) {
|
||||
size_t off = 0;
|
||||
const uint8_t* r = q + 3;
|
||||
if (q[2] == 0x40) {
|
||||
off = static_cast<int8_t>(q[3]);
|
||||
r = q + 4;
|
||||
} else if (q[2] == 0x80) {
|
||||
int32_t off32;
|
||||
std::memcpy(&off32, q + 3, 4);
|
||||
off = off32;
|
||||
r = q + 7;
|
||||
}
|
||||
for (int i = 0; i <= 8; ++i) {
|
||||
if (r[i] == 0xFF && r[i + 1] == 0xE0) { // jmp rax (48 REX optional)
|
||||
return off;
|
||||
}
|
||||
}
|
||||
}
|
||||
return npos;
|
||||
#elif defined(_M_ARM64) || defined(__aarch64__)
|
||||
const auto* p = static_cast<const uint8_t*>(fn);
|
||||
uint32_t insn[3];
|
||||
for (int i = 0; i < 8; ++i) { // incremental-link `b` stubs
|
||||
std::memcpy(insn, p, 4);
|
||||
if ((insn[0] & 0xFC000000u) != 0x14000000u) {
|
||||
break;
|
||||
}
|
||||
const auto imm26 = static_cast<int32_t>(insn[0] << 6) >> 6;
|
||||
p += static_cast<intptr_t>(imm26) * 4;
|
||||
}
|
||||
fn = p;
|
||||
std::memcpy(insn, p, 12);
|
||||
// ldr Xt, [x0]; ldr Xs, [Xt, #imm12*8]; br Xs
|
||||
if ((insn[0] & 0xFFFFFFE0u) != 0xF9400000u) {
|
||||
return npos;
|
||||
}
|
||||
const uint32_t t = insn[0] & 0x1Fu;
|
||||
if ((insn[1] & 0xFFC003E0u) != (0xF9400000u | (t << 5))) {
|
||||
return npos;
|
||||
}
|
||||
const uint32_t s = insn[1] & 0x1Fu;
|
||||
if (insn[2] != (0xD61F0000u | (s << 5))) {
|
||||
return npos;
|
||||
}
|
||||
return ((insn[1] >> 10) & 0xFFFu) * 8;
|
||||
#else
|
||||
(void)fn;
|
||||
return npos;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Code address of the member function a mfp designates. Virtual mfps don't carry
|
||||
* one; recover it from the class's vtable (resolved from the symbol manifest), so
|
||||
* Hook works uniformly on virtual and non-virtual members. */
|
||||
template <class C, class F>
|
||||
ModResult member_target(const HookService* hooks, F mfp, void** out) {
|
||||
*out = nullptr;
|
||||
uintptr_t words[sizeof(F) > sizeof(uintptr_t) ? 2 : 1] = {};
|
||||
std::memcpy(words, &mfp, sizeof(words) < sizeof(F) ? sizeof(words) : sizeof(F));
|
||||
|
||||
#if defined(_WIN32)
|
||||
const void* fn = reinterpret_cast<const void*>(words[0]);
|
||||
const size_t slot = vcall_slot_offset(fn);
|
||||
if (slot == static_cast<size_t>(-1)) { // not a vcall thunk: direct address
|
||||
*out = const_cast<void*>(fn);
|
||||
return MOD_OK;
|
||||
}
|
||||
void* vtable = nullptr;
|
||||
const ModResult resolved = hooks->resolve(mod_ctx, vtable_symbol<C>().data(), &vtable, nullptr);
|
||||
if (resolved != MOD_OK) {
|
||||
return resolved;
|
||||
}
|
||||
// ??_7 points at the first slot.
|
||||
*out = *reinterpret_cast<void**>(static_cast<char*>(vtable) + slot);
|
||||
#else
|
||||
#if defined(__aarch64__) || defined(__arm__)
|
||||
// AAPCS C++ ABI: the virtual flag is bit 0 of the adjustment word (function
|
||||
// addresses can't spare their low bit), and ptr holds the slot offset directly.
|
||||
const bool isVirtual = (words[1] & 1) != 0;
|
||||
const uintptr_t thisAdjust = words[1] >> 1;
|
||||
const uintptr_t slotOffset = words[0];
|
||||
#else
|
||||
// Itanium C++ ABI: virtual mfps set bit 0 of ptr; the slot offset is ptr - 1.
|
||||
const bool isVirtual = (words[0] & 1) != 0;
|
||||
const uintptr_t thisAdjust = words[1];
|
||||
const uintptr_t slotOffset = words[0] - 1;
|
||||
#endif
|
||||
if (!isVirtual) { // non-virtual: the address itself
|
||||
*out = reinterpret_cast<void*>(words[0]);
|
||||
return MOD_OK;
|
||||
}
|
||||
if (thisAdjust != 0) {
|
||||
// this-adjusting mfp (member of a secondary base): the slot offset is
|
||||
// relative to a vtable we can't locate. Hook the overrider by name instead.
|
||||
return MOD_UNSUPPORTED;
|
||||
}
|
||||
void* vtable = nullptr;
|
||||
const ModResult resolved = hooks->resolve(mod_ctx, vtable_symbol<C>().data(), &vtable, nullptr);
|
||||
if (resolved != MOD_OK) {
|
||||
return resolved;
|
||||
}
|
||||
// _ZTV points at the offset-to-top slot; the address point mfps index from is
|
||||
// two pointers in (past offset-to-top and the typeinfo pointer).
|
||||
*out = *reinterpret_cast<void**>(static_cast<char*>(vtable) + 2 * sizeof(void*) + slotOffset);
|
||||
#endif
|
||||
return *out != nullptr ? MOD_OK : MOD_UNAVAILABLE;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/* Trampoline generator + per-target state shared by Hook and NamedHook. Tag makes
|
||||
* each hooked target's statics distinct; the target address is filled in at install. */
|
||||
template <class Tag, class R, class... A>
|
||||
struct HookImpl {
|
||||
static inline R (*g_orig)(A...) = nullptr;
|
||||
static inline const HookService* hooks = nullptr;
|
||||
static inline void* target = nullptr;
|
||||
|
||||
static bool dispatch_pre(void* args, void* retval) {
|
||||
if (hooks == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int skipOriginal = 0;
|
||||
const ModResult result = hooks->dispatch_pre(mod_ctx, target, args, retval, &skipOriginal);
|
||||
return result == MOD_OK && skipOriginal != 0;
|
||||
}
|
||||
|
||||
static void dispatch_post(void* args, void* retval) {
|
||||
if (hooks != nullptr) {
|
||||
hooks->dispatch_post(mod_ctx, target, args, retval);
|
||||
}
|
||||
}
|
||||
|
||||
static R trampoline(A... args) {
|
||||
if constexpr (sizeof...(A) == 0) {
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
const bool skipOriginal = dispatch_pre(nullptr, nullptr);
|
||||
if (!skipOriginal) {
|
||||
g_orig(args...);
|
||||
}
|
||||
dispatch_post(nullptr, nullptr);
|
||||
} else {
|
||||
R result{};
|
||||
const bool skipOriginal =
|
||||
dispatch_pre(nullptr, static_cast<void*>(std::addressof(result)));
|
||||
if (!skipOriginal) {
|
||||
result = g_orig(args...);
|
||||
}
|
||||
dispatch_post(nullptr, static_cast<void*>(std::addressof(result)));
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
void* ptrs[] = {static_cast<void*>(std::addressof(args))...};
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
const bool skipOriginal = dispatch_pre(static_cast<void*>(ptrs), nullptr);
|
||||
if (!skipOriginal) {
|
||||
g_orig(args...);
|
||||
}
|
||||
dispatch_post(static_cast<void*>(ptrs), nullptr);
|
||||
} else {
|
||||
R result{};
|
||||
const bool skipOriginal = dispatch_pre(
|
||||
static_cast<void*>(ptrs), static_cast<void*>(std::addressof(result)));
|
||||
if (!skipOriginal) {
|
||||
result = g_orig(args...);
|
||||
}
|
||||
dispatch_post(static_cast<void*>(ptrs), static_cast<void*>(std::addressof(result)));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <auto Target>
|
||||
using TargetTag = std::integral_constant<decltype(Target), Target>;
|
||||
template <FixedString Name>
|
||||
struct NameTag {};
|
||||
} // namespace detail
|
||||
|
||||
/*
|
||||
* Typed hook on a function named at compile time (&daAlink_c::execute, &free_fn).
|
||||
* Member functions may be virtual: the install decodes the member function pointer and hooks the
|
||||
* class's own overrider.
|
||||
*/
|
||||
template <auto Target>
|
||||
struct Hook;
|
||||
|
||||
template <class C, class R, class... A, R (C::*Target)(A...)>
|
||||
struct Hook<Target> : HookImpl<detail::TargetTag<Target>, R, C*, A...> {
|
||||
static ModResult resolve_target(const HookService* hooks, void** out) {
|
||||
return detail::member_target<C>(hooks, Target, out);
|
||||
}
|
||||
};
|
||||
|
||||
template <class C, class R, class... A, R (C::*Target)(A...) const>
|
||||
struct Hook<Target> : HookImpl<detail::TargetTag<Target>, R, const C*, A...> {
|
||||
static ModResult resolve_target(const HookService* hooks, void** out) {
|
||||
return detail::member_target<C>(hooks, Target, out);
|
||||
}
|
||||
};
|
||||
|
||||
template <class R, class... A, R (*Target)(A...)>
|
||||
struct Hook<Target> : HookImpl<detail::TargetTag<Target>, R, A...> {
|
||||
static ModResult resolve_target(const HookService*, void** out) {
|
||||
*out = mfp_addr(Target);
|
||||
return MOD_OK;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Typed hook on a function by its symbol name, for targets you can't name in C++: file-local
|
||||
* statics, private members, or symbols without a header. The signature is written free-style with
|
||||
* the receiver first and is *not* compiler-checked.
|
||||
*
|
||||
* using HookshotHit = dusk::mods::NamedHook<
|
||||
* "daAlink_hookshotAtHitCallBack",
|
||||
* void(fopAc_ac_c*, dCcD_GObjInf*, fopAc_ac_c*, dCcD_GObjInf*)>;
|
||||
* dusk::mods::hook_add_pre<HookshotHit>(svc_hook, on_hookshot_hit);
|
||||
*/
|
||||
template <FixedString Name, class Sig>
|
||||
struct NamedHook;
|
||||
|
||||
template <FixedString Name, class R, class... A>
|
||||
struct NamedHook<Name, R(A...)> : HookImpl<detail::NameTag<Name>, R, A...> {
|
||||
static ModResult resolve_target(const HookService* hooks, void** out) {
|
||||
HookSymbolFlags flags{};
|
||||
const ModResult resolved = hooks->resolve(mod_ctx, Name.chars, out, &flags);
|
||||
if (resolved == MOD_OK && (flags & HOOK_SYMBOL_CODE) == 0) {
|
||||
*out = nullptr;
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Entry>
|
||||
ModResult hook_install(const HookService* hooks) {
|
||||
if (hooks == nullptr) {
|
||||
return MOD_UNAVAILABLE;
|
||||
}
|
||||
|
||||
Entry::hooks = hooks;
|
||||
if (Entry::target == nullptr) {
|
||||
const ModResult resolved = Entry::resolve_target(hooks, &Entry::target);
|
||||
if (resolved != MOD_OK) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
return hooks->install(mod_ctx, Entry::target, reinterpret_cast<void*>(Entry::trampoline),
|
||||
reinterpret_cast<void**>(&Entry::g_orig));
|
||||
}
|
||||
|
||||
template <auto Target>
|
||||
ModResult hook_install(const HookService* hooks) {
|
||||
return hook_install<Hook<Target> >(hooks);
|
||||
}
|
||||
|
||||
template <class Entry>
|
||||
ModResult hook_add_pre(
|
||||
const HookService* hooks, HookPreFn callback, const HookOptions* options = nullptr) {
|
||||
const ModResult installed = hook_install<Entry>(hooks);
|
||||
if (installed != MOD_OK) {
|
||||
return installed;
|
||||
}
|
||||
|
||||
return hooks->add_pre(mod_ctx, Entry::target, callback, options);
|
||||
}
|
||||
|
||||
template <auto Target>
|
||||
ModResult hook_add_pre(
|
||||
const HookService* hooks, HookPreFn callback, const HookOptions* options = nullptr) {
|
||||
return hook_add_pre<Hook<Target> >(hooks, callback, options);
|
||||
}
|
||||
|
||||
template <class Entry>
|
||||
ModResult hook_add_post(
|
||||
const HookService* hooks, HookPostFn callback, const HookOptions* options = nullptr) {
|
||||
const ModResult installed = hook_install<Entry>(hooks);
|
||||
if (installed != MOD_OK) {
|
||||
return installed;
|
||||
}
|
||||
|
||||
return hooks->add_post(mod_ctx, Entry::target, callback, options);
|
||||
}
|
||||
|
||||
template <auto Target>
|
||||
ModResult hook_add_post(
|
||||
const HookService* hooks, HookPostFn callback, const HookOptions* options = nullptr) {
|
||||
return hook_add_post<Hook<Target> >(hooks, callback, options);
|
||||
}
|
||||
|
||||
template <class Entry>
|
||||
ModResult hook_replace(
|
||||
const HookService* hooks, HookReplaceFn callback, const HookOptions* options = nullptr) {
|
||||
const ModResult installed = hook_install<Entry>(hooks);
|
||||
if (installed != MOD_OK) {
|
||||
return installed;
|
||||
}
|
||||
|
||||
return hooks->replace(mod_ctx, Entry::target, callback, options);
|
||||
}
|
||||
|
||||
template <auto Target>
|
||||
ModResult hook_replace(
|
||||
const HookService* hooks, HookReplaceFn callback, const HookOptions* options = nullptr) {
|
||||
return hook_replace<Hook<Target> >(hooks, callback, options);
|
||||
}
|
||||
|
||||
} // namespace dusk::mods
|
||||
@@ -31,10 +31,4 @@ extern u8 __OSReport_Warning_disable;
|
||||
extern u8 __OSReport_System_disable;
|
||||
extern u8 __OSReport_enable;
|
||||
|
||||
#if TARGET_PC
|
||||
namespace dusk {
|
||||
DUSK_GAME_EXTERN bool OSReportReallyForceEnable;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OS_REPORT_H
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/J2DGraph/J2DManage.h"
|
||||
#include "JSystem/J2DGraph/J2DMatBlock.h"
|
||||
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j2d
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include <gx.h>
|
||||
#include <mtx.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class J2DAnmBase;
|
||||
class J2DAnmColor;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/J2DGraph/J2DPane.h"
|
||||
#include "JSystem/JUtility/JUTTexture.h"
|
||||
#include "JSystem/JUtility/TColor.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class J2DMaterial;
|
||||
class JUTPalette;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/J2DGraph/J2DManage.h"
|
||||
#include "JSystem/J2DGraph/J2DPane.h"
|
||||
#include "JSystem/JUtility/TColor.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class J2DMaterial;
|
||||
class JUTNameTab;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <gx.h>
|
||||
#include <mtx.h>
|
||||
#include "global.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j2d
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include "JSystem/J2DGraph/J2DMaterial.h"
|
||||
#include "JSystem/J2DGraph/J2DPane.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/endian.h"
|
||||
#include "helpers/string.hpp"
|
||||
|
||||
class J2DMaterial;
|
||||
class JUTFont;
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
J2DTextBoxVBinding);
|
||||
void private_readStream(J2DPane*, JSURandomInputStream*, JKRArchive*);
|
||||
TEXT_SPAN getStringPtr() const;
|
||||
dusk::TextSpan getSpan() const;
|
||||
TextSpan getSpan() const;
|
||||
s32 setString(s16, char const*, ...);
|
||||
s32 setString(char const*, ...);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <mtx.h>
|
||||
#include "global.h"
|
||||
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#define OFFSET_PTR_V0 BE(u32)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "JSystem/J3DAssert.h"
|
||||
#include "JSystem/J3DGraphLoader/J3DClusterLoader.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class J3DDeformer;
|
||||
class J3DClusterKey;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "JSystem/J3DAssert.h"
|
||||
#include "JSystem/J3DGraphBase/J3DTransform.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class J3DJoint;
|
||||
class J3DMtxBuffer;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "JSystem/J3DGraphAnimator/J3DSkinDeform.h"
|
||||
#include "JSystem/J3DGraphBase/J3DPacket.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include <types.h>
|
||||
|
||||
enum J3DMdlFlag {
|
||||
@@ -106,12 +105,13 @@ public:
|
||||
void setUserArea(uintptr_t area) { mUserArea = area; }
|
||||
uintptr_t getUserArea() const { return mUserArea; }
|
||||
Vec* getBaseScale() { return &mBaseScale; }
|
||||
#if TARGET_PC
|
||||
void setAnmMtx(int jointNo, Mtx m);
|
||||
#else
|
||||
void setAnmMtx(int jointNo, Mtx m) {
|
||||
mMtxBuffer->setAnmMtx(jointNo, m);
|
||||
#ifdef TARGET_PC
|
||||
dusk::frame_interp::record_final_mtx(mMtxBuffer->getAnmMtx(jointNo));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
MtxP getAnmMtx(int jointNo) { return mMtxBuffer->getAnmMtx(jointNo); }
|
||||
MtxP getWeightAnmMtx(int i) { return mMtxBuffer->getWeightAnmMtx(i); }
|
||||
J3DSkinDeform* getSkinDeform() { return mSkinDeform; }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "JSystem/JMath/JMath.h"
|
||||
#include "global.h"
|
||||
#include <mtx.h>
|
||||
#include "dusk/endian_gx.hpp"
|
||||
#include "helpers/endian_gx.hpp"
|
||||
|
||||
class J3DShapeMtx;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/J3DGraphBase/J3DShape.h"
|
||||
#include "JSystem/J3DAssert.h"
|
||||
#include <mtx.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class J3DTexMtx;
|
||||
class J3DTexGenBlock;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "global.h"
|
||||
#include "JSystem/JMath/JMath.h"
|
||||
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
#include "JSystem/J3DAssert.h"
|
||||
#include "JSystem/JMath/JMath.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
#include "global.h"
|
||||
|
||||
enum J3DSysDrawBuf {
|
||||
@@ -190,15 +189,13 @@ struct J3DSys {
|
||||
Mtx& getModelDrawMtx(u16 no) { return mModelDrawMtx[no]; }
|
||||
J3DShapePacket* getShapePacket() { return mShapePacket; }
|
||||
|
||||
#if TARGET_PC
|
||||
void setViewMtx(const Mtx m);
|
||||
#else
|
||||
void setViewMtx(const Mtx m) {
|
||||
#ifdef TARGET_PC
|
||||
Mtx patched;
|
||||
if (dusk::frame_interp::lookup_replacement(m, patched)) {
|
||||
m = patched;
|
||||
}
|
||||
#endif
|
||||
MTXCopy(m, mViewMtx);
|
||||
}
|
||||
#endif
|
||||
|
||||
J3DModel* getModel() { return mModel; }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "global.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "helpers/gx_helper.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <gx.h>
|
||||
#include <mtx.h>
|
||||
#include "dusk/endian_gx.hpp"
|
||||
#include "helpers/endian_gx.hpp"
|
||||
|
||||
class J3DModel;
|
||||
class J3DAnmVtxColor;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/J3DGraphAnimator/J3DAnimation.h"
|
||||
|
||||
#include "JSystem/J3DGraphAnimator/J3DAnimation.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#define OFFSET_PTR_V0 BE(u32)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/J3DGraphBase/J3DSys.h"
|
||||
#include <mtx.h>
|
||||
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class J3DModelData;
|
||||
class J3DMaterialTable;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "JSystem/JAudio2/JAIAudible.h"
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include "global.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
#include <cstdint>
|
||||
|
||||
class JAISound;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/JAudio2/JASTaskThread.h"
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include <dvd.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class JASChannel;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JASOSCILLATOR_H
|
||||
|
||||
#include <types.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jaudio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JAUAUDIBLEPARAM_H
|
||||
|
||||
#include <types.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jaudio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JAUAUDIOARCINTERPRETER_H
|
||||
|
||||
#include <types.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jaudio
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JAUSOUNDANIMATOR_H
|
||||
|
||||
#include "JSystem/JAudio2/JAISound.h"
|
||||
#include "dusk/offset_ptr.h"
|
||||
#include "helpers/offset_ptr.h"
|
||||
|
||||
class JAUSoundAnimation;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "JSystem/JAudio2/JAISound.h"
|
||||
#include "JSystem/JAudio2/JASGadget.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jaudio
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include "JSystem/JGadget/search.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
namespace JGadget {
|
||||
namespace binary {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JHICOMMONMEM_H
|
||||
|
||||
#include <types.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
inline u32 JHIhtonl(u32 v) {
|
||||
return BSWAP32(v);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/JKernel/JKRCompression.h"
|
||||
#include "JSystem/JKernel/JKRFileLoader.h"
|
||||
#include "global.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class JKRHeap;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <mtx.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "dusk/math.h"
|
||||
#include "helpers/math.h"
|
||||
|
||||
typedef f32 Mtx33[3][3];
|
||||
typedef f32 Mtx23[2][3];
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#else
|
||||
#include <dolphin.h>
|
||||
#endif
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
// Struct definitions might be wrong
|
||||
typedef struct bmg_header_t {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "JSystem/JGeometry.h"
|
||||
|
||||
#include <types.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
struct JPAEmitterWorkData;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JPARESOURCE_H
|
||||
|
||||
#include <types.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class JKRHeap;
|
||||
struct JPAEmitterWorkData;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#define m_PI_D 3.141592653589793
|
||||
#ifndef __MWERKS__
|
||||
#include "dusk/math.h"
|
||||
#include "helpers/math.h"
|
||||
#endif
|
||||
|
||||
namespace JStudio {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JSUINPUTSTREAM_H
|
||||
|
||||
#include "JSystem/JSupport/JSUIosBase.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jsupport
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "JSystem/JUtility/TColor.h"
|
||||
#include <cstring>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
#if TARGET_PC
|
||||
struct FontDrawContext {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JUTNAMETAB_H
|
||||
|
||||
#include <types.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jutility
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <gx.h>
|
||||
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
enum JUTTransparency { UNK0, UNK1 };
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define JUTRESFONT_H
|
||||
|
||||
#include "JSystem/JUtility/JUTFont.h"
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "helpers/gx_helper.h"
|
||||
|
||||
class JKRHeap;
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include <gx.h>
|
||||
#include <stdint.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "helpers/endian.h"
|
||||
#include "helpers/gx_helper.h"
|
||||
|
||||
class JUTPalette;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define TCOLOR_H
|
||||
|
||||
#include <gx.h>
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
namespace JUtility {
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <cstring>
|
||||
#include <types.h>
|
||||
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
|
||||
J2DMaterialFactory::J2DMaterialFactory(J2DMaterialBlock const& param_0) {
|
||||
mMaterialNum = param_0.field_0x8;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "JSystem/JSupport/JSURandomInputStream.h"
|
||||
#include "JSystem/JUtility/JUTResource.h"
|
||||
#ifndef __MWERKS__
|
||||
#include "dusk/math.h"
|
||||
#include "helpers/math.h"
|
||||
#endif
|
||||
|
||||
J2DPane::J2DPane() : mBounds(), mGlobalBounds(), mClipRect(), mPaneTree(this) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifdef __MWERKS__
|
||||
#include <cmath>
|
||||
#else
|
||||
#include <dusk/math.h>
|
||||
#include <helpers/math.h>
|
||||
#endif
|
||||
#include <gx.h>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "JSystem/J2DGraph/J2DWindowEx.h"
|
||||
#include "JSystem/JUtility/JUTTexture.h"
|
||||
#include "JSystem/JSupport/JSURandomInputStream.h"
|
||||
#include "dusk/endian.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
struct J2DWindowExDef {
|
||||
BE(u32) field_0x0[4];
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
#include "JSystem/J3DGraphBase/J3DShapeMtx.h"
|
||||
#include "JSystem/J3DGraphBase/J3DSys.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#endif
|
||||
|
||||
#define J3D_ASSERTMSG(LINE, COND, MSG) JUT_ASSERT_MSG(LINE, (COND) != 0, MSG)
|
||||
#define J3D_WARN1(LINE, MSG, ARG1) JUT_WARN(LINE, MSG, ARG1)
|
||||
@@ -105,6 +108,11 @@ void J3DModel::interp_callback(bool isSimFrame, void* pUserWork) {
|
||||
i_this->diff();
|
||||
}
|
||||
}
|
||||
|
||||
void J3DModel::setAnmMtx(int jointNo, Mtx m) {
|
||||
mMtxBuffer->setAnmMtx(jointNo, m);
|
||||
dusk::frame_interp::record_final_mtx(mMtxBuffer->getAnmMtx(jointNo));
|
||||
}
|
||||
#endif
|
||||
|
||||
s32 J3DModel::createShapePacket(J3DModelData* pModelData) {
|
||||
|
||||
@@ -4,10 +4,14 @@
|
||||
#include "JSystem/J3DGraphBase/J3DSys.h"
|
||||
#include "JSystem/J3DGraphBase/J3DTevs.h"
|
||||
#include "JSystem/J3DGraphBase/J3DTexture.h"
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "helpers/gx_helper.h"
|
||||
#include "global.h"
|
||||
#include "tracy/Tracy.hpp"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#endif
|
||||
|
||||
DUSK_GAME_DATA J3DSys j3dSys;
|
||||
|
||||
DUSK_GAME_DATA Mtx J3DSys::mCurrentMtx;
|
||||
@@ -370,3 +374,13 @@ void J3DSys::reinitPixelProc() {
|
||||
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
||||
GXSetZCompLoc(GX_TRUE);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void J3DSys::setViewMtx(const Mtx m) {
|
||||
Mtx patched;
|
||||
if (dusk::frame_interp::lookup_replacement(m, patched)) {
|
||||
m = patched;
|
||||
}
|
||||
MTXCopy(m, mViewMtx);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <JSystem/JUtility/JUTAssert.h>
|
||||
#include <cstring>
|
||||
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
|
||||
DUSK_GAME_DATA u32 JAHVirtualNode::smVirNodeNum;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "JSystem/JAHostIO/JAHioNode.h"
|
||||
|
||||
#include "JSystem/JHostIO/JORServer.h"
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
|
||||
DUSK_GAME_DATA JAHioNode* JAHioNode::smCurrentNode;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <os.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
|
||||
DUSK_GAME_DATA JASHeap* JASWaveArcLoader::sAramHeap;
|
||||
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
|
||||
#ifdef TARGET_PC
|
||||
#include "dusk/dusk.h"
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/logging.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "dusk/time.h"
|
||||
#include "f_op/f_op_overlap_mng.h"
|
||||
#include "helpers/gx_helper.h"
|
||||
|
||||
#include "SDL3/SDL_timer.h"
|
||||
#include "tracy/Tracy.hpp"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
#include "global.h"
|
||||
|
||||
JKRFileCache* JKRFileCache::mount(const char* path, JKRHeap* heap, const char* param_3) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
#include "global.h"
|
||||
|
||||
DUSK_GAME_DATA JKRFileLoader* JKRFileLoader::sCurrentVolume;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include "JSystem/JUtility/JUTException.h"
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
#ifdef __MWERKS__
|
||||
#include <stdint.h>
|
||||
#else
|
||||
@@ -702,7 +702,7 @@ JKRHeap* JKRHeap::getCurrentHeap() {
|
||||
}
|
||||
|
||||
void JKRHeap::setName(const char* name) {
|
||||
dusk::SafeStringCopyTruncate(mName, name);
|
||||
SafeStringCopyTruncate(mName, name);
|
||||
}
|
||||
|
||||
void JKRHeap::setNamef(const char* fmt, ...) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "global.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include "dusk/string.hpp"
|
||||
#include "helpers/string.hpp"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/os.h"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user