mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-25 14:45:45 -04:00
Compare commits
229 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f0d89473a | |||
| adaa52aa9d | |||
| 3dd9430576 | |||
| 6facff1297 | |||
| ba324dfdf6 | |||
| a775418c66 | |||
| 48b5c2e8c1 | |||
| 705e7f058b | |||
| e30e0fe062 | |||
| c4f4712d0e | |||
| 2d70c24b37 | |||
| 72ccb14d35 | |||
| c53f3f774b | |||
| 5a8622c6b2 | |||
| 29b86f938f | |||
| e02638ac6d | |||
| 622b782614 | |||
| 9a4b1edfe5 | |||
| 1db2a74192 | |||
| 595c621173 | |||
| ba95fdd4ab | |||
| a39c272985 | |||
| f3bbde4b7d | |||
| 46a2ac2c46 | |||
| 2885c7d9d8 | |||
| 19b8f7ede0 | |||
| b138735cbe | |||
| 1a6775eab1 | |||
| dd5da64332 | |||
| d281c34a65 | |||
| a6813841b8 | |||
| 39a84e67b7 | |||
| 788700daa6 | |||
| 3aa54ca170 | |||
| 81dfe701e9 | |||
| 16f2b954fa | |||
| a8a7513710 | |||
| 797d264a71 | |||
| c0293b1f52 | |||
| a9ea8aa935 | |||
| 7240c19566 | |||
| dbc56da290 | |||
| 41d5148793 | |||
| 14f9b6c762 | |||
| 44e02a9d53 | |||
| 63d431d058 | |||
| 87d96c2696 | |||
| 8f5ecdba1c | |||
| 42805210df | |||
| df522f1abb | |||
| c475d72110 | |||
| 3606ec64e3 | |||
| 1b51fa0112 | |||
| 1e8d72c3ed | |||
| 28479314c2 | |||
| 89a8384c7c | |||
| d9cac5befa | |||
| 3cd1f46e7b | |||
| 0b26cee96d | |||
| 42bba9c9a8 | |||
| 3869ac6423 | |||
| 54bed771ee | |||
| 83b10681c3 | |||
| 641855e49e | |||
| 9977e78758 | |||
| 9a62d8c86f | |||
| 2cee0db91f | |||
| 932c3aaba7 | |||
| 5d1dda7e94 | |||
| 75ae2767e9 | |||
| 829b0de69c | |||
| 5f0f3d4ebe | |||
| 283b3704bb | |||
| 6cc22e71a9 | |||
| 54ecdfe4d3 | |||
| 618eb90392 | |||
| 72ea47b973 | |||
| 172d06f38d | |||
| 338995ebe0 | |||
| b5724fb6fd | |||
| 05a1fe4485 | |||
| 6f06a33926 | |||
| 4d5fc47252 | |||
| 97d742a96a | |||
| 80c93957e9 | |||
| dc716329d8 | |||
| 62bf0fbeb1 | |||
| ce4682fd89 | |||
| acc8cc2e6d | |||
| c86d6918d6 | |||
| 5a4e6f3254 | |||
| 5d5c3d5c5f | |||
| 386d2f964b | |||
| 04b915d8c7 | |||
| fd4a5f0cfb | |||
| 33abcbfbe1 | |||
| 3ecd785ac2 | |||
| fd0e33460f | |||
| 6f840b050e | |||
| 88c6e28179 | |||
| f13f0319ec | |||
| 06735d1369 | |||
| 8525b0b40c | |||
| e40506dfeb | |||
| ff3dbfa8d5 | |||
| 5456d98fde | |||
| 2f0cb26ceb | |||
| 21bc055552 | |||
| 3a2dbf9fba | |||
| 2d1487aefd | |||
| f6b7448de3 | |||
| edfb93440c | |||
| f4f564b1b1 | |||
| 4ba25932de | |||
| d4868ea81a | |||
| cd6c82d0ff | |||
| 355ea73510 | |||
| c0d44d4a21 | |||
| f0f7031b3d | |||
| 85c2ddd8ff | |||
| de7f09a6a4 | |||
| 7129605035 | |||
| 0c09d71c0a | |||
| 947fb5b5a5 | |||
| 4c673eb04b | |||
| 9090ee80ab | |||
| 8953532fe7 | |||
| f1dc848ea5 | |||
| 548c843a9b | |||
| 34a753ed85 | |||
| 08e51f83f3 | |||
| b4ba0b5755 | |||
| 7c4338d7b3 | |||
| 85a1a2901c | |||
| a13932e901 | |||
| c880d46fb5 | |||
| 27d27e6d94 | |||
| ac45cac56e | |||
| 9d38af22ee | |||
| 7cac8284d7 | |||
| aa3db8f949 | |||
| 9f7360b359 | |||
| d319bb1049 | |||
| 1f43e16e2d | |||
| 2a67d6800e | |||
| 4cbb8762f6 | |||
| c722cb1be0 | |||
| c2dbdd385d | |||
| 9c52a059bd | |||
| 33a9db2e49 | |||
| e5a4323056 | |||
| 08cda98337 | |||
| b0d4c62903 | |||
| a2cd701203 | |||
| 0f5a248401 | |||
| 045fbd9b46 | |||
| 46da33be37 | |||
| 8143de6bbb | |||
| 162829a8cf | |||
| c65b8a42b8 | |||
| abbcb5a6b9 | |||
| 8229879aab | |||
| 11055282ff | |||
| 839d8fdb63 | |||
| 008a18c142 | |||
| 5b4def820a | |||
| 635901d3bd | |||
| 5abc956448 | |||
| 5830c41547 | |||
| 0c3bbbaba0 | |||
| 1e39c5e1be | |||
| 2f1375297a | |||
| 0fc05028cc | |||
| 71b2eedc82 | |||
| 315897e45a | |||
| 7434a0f834 | |||
| 25a736b9dc | |||
| a8089f1204 | |||
| 1f28fd1ca5 | |||
| e16c05211b | |||
| 8be95d3aa3 | |||
| ce6850acd3 | |||
| 4aa3b647a3 | |||
| a9767ad3e8 | |||
| 2f4d8a06d8 | |||
| 769f83db25 | |||
| 48cf860467 | |||
| 82e2fd4bea | |||
| fcd9dd0f70 | |||
| 8afe479d0f | |||
| c5933be631 | |||
| 928e9b4bc7 | |||
| 3ac0fcb156 | |||
| cb564f7465 | |||
| 2c7ab755a0 | |||
| cd2ed2843c | |||
| cf8ab52f55 | |||
| c853934a24 | |||
| 8c4ad273b8 | |||
| 2a0cd87246 | |||
| 13b3b68fe5 | |||
| 8d677bf517 | |||
| 3160d1c370 | |||
| 0ed984a863 | |||
| 027e23d2e7 | |||
| 105413360e | |||
| 4604304305 | |||
| 794bb130e2 | |||
| d82cb08353 | |||
| 572e9633ab | |||
| 67a511a131 | |||
| 0ff615f991 | |||
| 2191b38c1d | |||
| 2c9f814ec6 | |||
| 76079b6294 | |||
| 519305b7d4 | |||
| 36d31e2bb8 | |||
| 2b489e1a7d | |||
| e93a720d8f | |||
| 66f6942dbb | |||
| 631cb99208 | |||
| a53b363905 | |||
| fae9add351 | |||
| f22bfcd9ba | |||
| 9c2e0e9331 | |||
| ecbec503dc | |||
| 91c6c5c137 | |||
| 449a8408ab | |||
| 61a4ab3117 |
@@ -68,13 +68,18 @@ body:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: game-region
|
||||
id: game-disc
|
||||
attributes:
|
||||
label: Game Region
|
||||
description: The game region you are playing on
|
||||
label: Game Disc
|
||||
description: The game disc you are playing on
|
||||
options:
|
||||
- NTSC-U (North America)
|
||||
- PAL (Europe)
|
||||
- GameCube NTSC-U (North America)
|
||||
- GameCube PAL (Europe)
|
||||
- GameCube NTSC-J (Japan)
|
||||
- Wii NTSC-U (North America) Revision 0
|
||||
- Wii NTSC-U (North America) Revision 2
|
||||
- Wii PAL (Europe)
|
||||
- Wii NTSC-J (Japan)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dusklight-${{env.DUSK_VERSION}}-linux-${{matrix.preset}}-${{matrix.artifact_arch}}
|
||||
name: dusklight-${{env.APP_VERSION}}-linux-${{matrix.preset}}-${{matrix.artifact_arch}}
|
||||
path: |
|
||||
build/install/Dusklight-*.AppImage
|
||||
build/install/debug.tar.*
|
||||
@@ -145,7 +145,7 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dusklight-${{env.DUSK_VERSION}}-${{matrix.artifact_name}}
|
||||
name: dusklight-${{env.APP_VERSION}}-${{matrix.artifact_name}}
|
||||
path: |
|
||||
build/install/Dusklight.app
|
||||
build/install/debug.tar.*
|
||||
@@ -221,7 +221,7 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dusklight-${{env.DUSK_VERSION}}-android-${{matrix.artifact_arch}}
|
||||
name: dusklight-${{env.APP_VERSION}}-android-${{matrix.artifact_arch}}
|
||||
path: upload/
|
||||
|
||||
build-windows:
|
||||
@@ -283,7 +283,7 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dusklight-${{env.DUSK_VERSION}}-win32-msvc-${{matrix.artifact_arch}}
|
||||
name: dusklight-${{env.APP_VERSION}}-win32-msvc-${{matrix.artifact_arch}}
|
||||
path: |
|
||||
build/install/*.exe
|
||||
build/install/*.dll
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
[submodule "extern/aurora"]
|
||||
path = extern/aurora
|
||||
url = https://github.com/encounter/aurora.git
|
||||
[submodule "extern/borealis"]
|
||||
path = extern/borealis
|
||||
url = https://github.com/encounter/borealis.git
|
||||
|
||||
+61
-156
@@ -5,10 +5,11 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||
"Build type options: Debug Release RelWithDebInfo MinSizeRel" FORCE)
|
||||
endif ()
|
||||
|
||||
include(cmake/DetectVersion.cmake)
|
||||
detect_version()
|
||||
include(extern/borealis/cmake/DetectVersion.cmake)
|
||||
borealis_detect_version()
|
||||
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
||||
project(dusklight LANGUAGES C CXX VERSION ${DUSK_VERSION_STRING})
|
||||
project(dusklight LANGUAGES C CXX VERSION ${BOREALIS_APP_VERSION})
|
||||
|
||||
if (APPLE)
|
||||
enable_language(OBJC OBJCXX)
|
||||
endif ()
|
||||
@@ -32,6 +33,7 @@ set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(CMAKE_COLOR_DIAGNOSTICS ON)
|
||||
|
||||
# Folder-based instead of target-based organization
|
||||
# in Visual Studio and Xcode generators
|
||||
@@ -74,6 +76,8 @@ set(AURORA_ENABLE_RMLUI ON CACHE BOOL "Enable RmlUi UI support" FORCE)
|
||||
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
|
||||
target_compile_definitions(aurora_mtx PRIVATE MTX_USE_PS=1)
|
||||
|
||||
add_subdirectory(extern/borealis EXCLUDE_FROM_ALL)
|
||||
|
||||
add_subdirectory(libs/freeverb)
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
@@ -85,12 +89,9 @@ endif ()
|
||||
option(DUSK_BUILD_WARNINGS "Enable compiler warnings (off by default)")
|
||||
option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled with optimizations on Debug, intending to make the game run at 30 FPS. Note for MSVC: you will need to remove '/RTC1' from your debug flags in CMake.")
|
||||
option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON)
|
||||
option(DUSK_ENABLE_UPDATE_CHECKER "Enable update checking support" ON)
|
||||
option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support" OFF)
|
||||
option(DUSK_PACKAGE_INSTALL "Install Dusklight with a Linux-native file structure" OFF)
|
||||
option(DUSK_GFX_DEBUG_GROUPS "Report debug groups to the native graphics API" ${DUSK_GFX_DEBUG_GROUPS_DEFAULT})
|
||||
option(DUSK_ENABLE_CODE_MODS "Enable code mods" OFF)
|
||||
option(DUSK_ENABLE_OPUS "Enable loading Opus audio files for mods" ON)
|
||||
|
||||
set(DUSK_HAS_FUNCHOOK OFF)
|
||||
if (DUSK_ENABLE_CODE_MODS AND (NOT APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
|
||||
@@ -151,6 +152,7 @@ if (DUSK_MOVIE_SUPPORT)
|
||||
-DENABLE_SHARED=OFF
|
||||
-DWITH_TURBOJPEG=ON
|
||||
-DWITH_JAVA=OFF
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
)
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
get_filename_component(_jpeg_toolchain_file "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
@@ -235,18 +237,6 @@ endif ()
|
||||
include(FetchContent)
|
||||
|
||||
# Declare all dependencies first so CMake can download them in parallel
|
||||
message(STATUS "dusklight: Fetching cxxopts")
|
||||
FetchContent_Declare(cxxopts
|
||||
URL https://github.com/jarro2783/cxxopts/archive/refs/tags/v3.3.1.tar.gz
|
||||
URL_HASH SHA256=3bfc70542c521d4b55a46429d808178916a579b28d048bd8c727ee76c39e2072
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP FALSE
|
||||
)
|
||||
message(STATUS "dusklight: Fetching nlohmann/json")
|
||||
FetchContent_Declare(json
|
||||
URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz
|
||||
URL_HASH SHA256=42f6e95cad6ec532fd372391373363b62a14af6d771056dbfc86160e6dfff7aa
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP FALSE
|
||||
)
|
||||
message(STATUS "dusklight: Fetching miniz")
|
||||
FetchContent_Declare(miniz
|
||||
URL https://github.com/richgel999/miniz/releases/download/3.0.2/miniz-3.0.2.zip
|
||||
@@ -254,26 +244,7 @@ FetchContent_Declare(miniz
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
set(_fetch_content_deps cxxopts json miniz)
|
||||
|
||||
if (DUSK_ENABLE_OPUS)
|
||||
message(STATUS "dusklight: Fetching opusfile")
|
||||
|
||||
# Opusfile options
|
||||
SET(OP_DISABLE_HTTP ON CACHE BOOL "" FORCE)
|
||||
SET(OP_DISABLE_DOCS ON CACHE BOOL "" FORCE)
|
||||
SET(OP_DISABLE_EXAMPLES ON CACHE BOOL "" FORCE)
|
||||
|
||||
message(STATUS "dusklight: Fetching opusfile")
|
||||
FetchContent_Declare(
|
||||
opusfile
|
||||
GIT_REPOSITORY https://github.com/xiph/opusfile.git
|
||||
GIT_TAG 6dfd29e7adb87f2e193575fc3fa88cbf1a0b27df
|
||||
)
|
||||
|
||||
list(APPEND _fetch_content_deps opusfile)
|
||||
endif ()
|
||||
|
||||
set(_fetch_content_deps miniz)
|
||||
if (DUSK_HAS_FUNCHOOK)
|
||||
message(STATUS "dusklight: Fetching funchook")
|
||||
# cmake/PatchFunchook.cmake patches funchook's cmake/capstone.cmake.in to inject a
|
||||
@@ -308,40 +279,12 @@ if (DUSK_HAS_FUNCHOOK)
|
||||
endif ()
|
||||
FetchContent_MakeAvailable(${_fetch_content_deps})
|
||||
|
||||
if (DUSK_ENABLE_SENTRY_NATIVE)
|
||||
message(STATUS "dusklight: Fetching sentry-native")
|
||||
set(SENTRY_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
set(SENTRY_BACKEND crashpad CACHE STRING "" FORCE)
|
||||
if (WIN32)
|
||||
set(SENTRY_TRANSPORT winhttp CACHE STRING "" FORCE)
|
||||
endif ()
|
||||
set(SENTRY_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(SENTRY_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
set(SENTRY_BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE)
|
||||
FetchContent_Declare(sentry_native
|
||||
GIT_REPOSITORY https://github.com/getsentry/sentry-native.git
|
||||
GIT_TAG 0.13.6
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SUBMODULES_RECURSE TRUE
|
||||
)
|
||||
if (NOT sentry_native_POPULATED)
|
||||
FetchContent_Populate(sentry_native)
|
||||
set(_skip_install_rules ${CMAKE_SKIP_INSTALL_RULES})
|
||||
set(CMAKE_SKIP_INSTALL_RULES ON)
|
||||
add_subdirectory(${sentry_native_SOURCE_DIR} ${sentry_native_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
set(CMAKE_SKIP_INSTALL_RULES ${_skip_install_rules})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Use signed char on ARM to match the original game (and x86)
|
||||
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _arch)
|
||||
if(_arch MATCHES "^(arm|aarch64)" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
||||
add_compile_options(-fsigned-char)
|
||||
endif()
|
||||
|
||||
configure_version_header()
|
||||
|
||||
include(files.cmake)
|
||||
|
||||
# TODO: version handling for res includes
|
||||
@@ -354,71 +297,23 @@ set(DUSK_PRODUCT_NAME "Dusklight")
|
||||
set(DUSK_COPYRIGHT "Copyright (C) Twilit Realm contributors")
|
||||
|
||||
source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${REL_FILES})
|
||||
source_group("dusklight" FILES ${DUSK_FILES} ${DUSK_HTTP_BACKEND_FILES})
|
||||
source_group("dusklight" FILES ${DUSK_FILES})
|
||||
|
||||
include(cmake/GameABIConfig.cmake)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
set(GAME_COMPILE_DEFS DUSK_BUILDING_GAME=1)
|
||||
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd
|
||||
aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt
|
||||
aurora::card borealis::cli borealis::crash borealis::data borealis::disc borealis::discord borealis::file_select borealis::log borealis::presentation borealis::sentry borealis::update freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt
|
||||
Threads::Threads zstd::libzstd dusklight_game_headers)
|
||||
if (DUSK_HAS_FUNCHOOK)
|
||||
list(APPEND GAME_LIBS funchook-static)
|
||||
endif ()
|
||||
if (DUSK_ENABLE_OPUS)
|
||||
list(APPEND GAME_LIBS OpusFile::opusfile)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_OPUS=1)
|
||||
endif ()
|
||||
|
||||
if (DUSK_ENABLE_SENTRY_NATIVE)
|
||||
list(APPEND GAME_LIBS sentry)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_ENABLE_SENTRY_NATIVE=1 SENTRY_BUILD_STATIC=1)
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
list(APPEND GAME_LIBS Ws2_32)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
list(APPEND GAME_LIBS dbghelp)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_CRASH_DBGHELP=1)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/no_backend.cpp)
|
||||
if (DUSK_ENABLE_UPDATE_CHECKER)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_ENABLE_UPDATE_CHECKER=1)
|
||||
if (WIN32)
|
||||
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/winhttp.cpp)
|
||||
list(APPEND GAME_LIBS winhttp)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_HTTP_BACKEND_WINHTTP=1)
|
||||
message(STATUS "dusklight: Enabled update checker (WinHTTP)")
|
||||
elseif (ANDROID)
|
||||
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/android.cpp)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_HTTP_BACKEND_ANDROID=1)
|
||||
message(STATUS "dusklight: Enabled update checker (Android)")
|
||||
elseif (APPLE)
|
||||
find_library(FOUNDATION_FRAMEWORK Foundation REQUIRED)
|
||||
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/url_session.mm)
|
||||
set_source_files_properties(src/dusk/http/url_session.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
||||
list(APPEND GAME_LIBS ${FOUNDATION_FRAMEWORK})
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_HTTP_BACKEND_URLSESSION=1)
|
||||
message(STATUS "dusklight: Enabled update checker (NSURLSession)")
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
find_package(CURL QUIET OPTIONAL_COMPONENTS HTTPS SSL)
|
||||
if (CURL_FOUND AND CURL_HTTPS_FOUND AND CURL_SSL_FOUND)
|
||||
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/curl.cpp)
|
||||
list(APPEND GAME_LIBS CURL::libcurl)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_HTTP_BACKEND_LIBCURL=1)
|
||||
message(STATUS "dusklight: Enabled update checker (libcurl)")
|
||||
else ()
|
||||
message(STATUS "dusklight: Disabled update checker (libcurl + HTTPS/SSL not found)")
|
||||
endif ()
|
||||
else ()
|
||||
message(STATUS "dusklight: Disabled update checker (unsupported platform)")
|
||||
endif ()
|
||||
endif ()
|
||||
list(APPEND DUSK_FILES ${DUSK_HTTP_BACKEND_SOURCE})
|
||||
|
||||
if (DUSK_MOVIE_SUPPORT)
|
||||
if (TARGET libjpeg-turbo::turbojpeg-static)
|
||||
list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg-static)
|
||||
@@ -428,15 +323,6 @@ if (DUSK_MOVIE_SUPPORT)
|
||||
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
|
||||
endif ()
|
||||
|
||||
set(DUSK_ENABLE_DISCORD_DEFAULT ON)
|
||||
if (DEFINED DUSK_ENABLE_DISCORD_RPC AND NOT DEFINED DUSK_ENABLE_DISCORD)
|
||||
set(DUSK_ENABLE_DISCORD_DEFAULT ${DUSK_ENABLE_DISCORD_RPC})
|
||||
endif ()
|
||||
option(DUSK_ENABLE_DISCORD "Enable Discord Rich Presence support" ${DUSK_ENABLE_DISCORD_DEFAULT})
|
||||
if (DUSK_ENABLE_DISCORD AND NOT ANDROID AND NOT IOS AND NOT TVOS)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_DISCORD=1)
|
||||
endif ()
|
||||
|
||||
if (DUSK_ENABLE_CODE_MODS)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_CODE_MODS=1)
|
||||
endif ()
|
||||
@@ -501,10 +387,10 @@ endif ()
|
||||
set(DUSK_FILES src/dusk/main.cpp ${GAME_BASE_FILES} ${GAME_DEBUG_FILES} ${miniz_SOURCE_DIR}/miniz.c)
|
||||
if(ANDROID)
|
||||
add_library(dusklight SHARED ${DUSK_FILES})
|
||||
set_target_properties(dusklight PROPERTIES OUTPUT_NAME main)
|
||||
else ()
|
||||
add_executable(dusklight ${DUSK_FILES})
|
||||
endif ()
|
||||
borealis_configure_android_application(dusklight)
|
||||
if (ENABLE_ASAN)
|
||||
target_sources(dusklight PRIVATE src/dusk/asan_options.c)
|
||||
endif ()
|
||||
@@ -525,7 +411,47 @@ if (DUSK_ENABLE_CODE_MODS)
|
||||
setup_symbol_manifest(dusklight)
|
||||
endif ()
|
||||
|
||||
# Hook reliability: guaranteed patchable entries on the game ABI surface, and no identical-code folding.
|
||||
# Hook reliability: prevent auto-inlining, guarantee patchable function entries,
|
||||
# and disable identical-code folding for game functions.
|
||||
set(DUSK_GAME_ABI_INLINE_OPTIONS)
|
||||
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND DUSK_GAME_ABI_INLINE_OPTIONS
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-finline-hint-functions>)
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
list(APPEND DUSK_GAME_ABI_INLINE_OPTIONS
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-flive-patching=inline-clone>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-inline-functions>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-inline-small-functions>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-inline-functions-called-once>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-early-inlining>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-ipa-cp>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-ipa-cp-clone>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-ipa-sra>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-partial-inlining>)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (DUSK_GAME_ABI_INLINE_OPTIONS)
|
||||
set(_game_abi_files ${GAME_BASE_FILES} ${GAME_DEBUG_FILES})
|
||||
list(FILTER _game_abi_files EXCLUDE REGEX "^src/dusk/")
|
||||
set_property(SOURCE ${_game_abi_files} APPEND PROPERTY
|
||||
COMPILE_OPTIONS ${DUSK_GAME_ABI_INLINE_OPTIONS})
|
||||
|
||||
foreach(jsystem_lib IN LISTS JSYSTEM_LIBRARIES)
|
||||
target_compile_options(${jsystem_lib} PRIVATE ${DUSK_GAME_ABI_INLINE_OPTIONS})
|
||||
endforeach()
|
||||
foreach(_sdk_lib aurora_card aurora_core aurora_dvd aurora_gd aurora_gx aurora_mtx
|
||||
aurora_os aurora_pad aurora_si aurora_vi)
|
||||
if (TARGET ${_sdk_lib})
|
||||
get_target_property(_sdk_lib_imported ${_sdk_lib} IMPORTED)
|
||||
if (NOT _sdk_lib_imported)
|
||||
target_compile_options(${_sdk_lib} PRIVATE ${DUSK_GAME_ABI_INLINE_OPTIONS})
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(DUSK_PATCHABLE_ENTRY_FLAG $<$<COMPILE_LANGUAGE:C,CXX>:/hotpatch>)
|
||||
@@ -535,11 +461,11 @@ if (MSVC)
|
||||
else ()
|
||||
target_link_options(dusklight PRIVATE /FUNCTIONPADMIN /OPT:NOICF)
|
||||
endif ()
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "^(AppleClang|Clang)$")
|
||||
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU)$")
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)$" OR CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
|
||||
set(DUSK_PATCHABLE_ENTRY_FLAG $<$<COMPILE_LANGUAGE:C,CXX>:-fpatchable-function-entry=2,1>)
|
||||
else ()
|
||||
set(DUSK_PATCHABLE_ENTRY_FLAG $<$<COMPILE_LANGUAGE:C,CXX>:-fpatchable-function-entry=10,5>)
|
||||
set(DUSK_PATCHABLE_ENTRY_FLAG $<$<COMPILE_LANGUAGE:C,CXX>:-fpatchable-function-entry=10,4>)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
@@ -582,17 +508,9 @@ if (TARGET crashpad_handler)
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (ANDROID)
|
||||
# SDLActivity loads SDL_main via dlsym on Android. Since aurora::main is a static
|
||||
# archive, force an undefined reference so the linker keeps the SDL_main object.
|
||||
target_link_options(dusklight PRIVATE "-Wl,-u,SDL_main")
|
||||
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)
|
||||
@@ -641,7 +559,9 @@ if (DUSK_ENABLE_CODE_MODS AND CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR
|
||||
add_subdirectory(mods/ao_mod)
|
||||
add_subdirectory(mods/shadow_mod)
|
||||
add_subdirectory(mods/window_demo)
|
||||
add_subdirectory(mods/audio_mod)
|
||||
add_subdirectory(mods/flow_demo)
|
||||
add_subdirectory(mods/basic_cosmetics_mod)
|
||||
add_subdirectory(mods/randomizer)
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
@@ -675,8 +595,8 @@ if (APPLE)
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_BUNDLE_NAME ${DUSK_BUNDLE_NAME}
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER ${DUSK_BUNDLE_IDENTIFIER}
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${DUSK_VERSION_STRING}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${DUSK_SHORT_VERSION_STRING}
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${BOREALIS_APP_VERSION}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${BOREALIS_APP_SHORT_VERSION}
|
||||
MACOSX_BUNDLE_INFO_PLIST ${DUSK_INFO_PLIST}
|
||||
OUTPUT_NAME Dusklight
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "YES"
|
||||
@@ -709,21 +629,6 @@ if (APPLE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
find_library(APPKIT_FRAMEWORK AppKit REQUIRED)
|
||||
target_sources(dusklight PRIVATE src/dusk/file_select_macos.mm)
|
||||
set_source_files_properties(src/dusk/file_select_macos.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
||||
target_link_libraries(dusklight PRIVATE ${APPKIT_FRAMEWORK})
|
||||
endif ()
|
||||
|
||||
if (IOS)
|
||||
find_library(UIKIT_FRAMEWORK UIKit REQUIRED)
|
||||
find_library(UNIFORM_TYPE_IDENTIFIERS_FRAMEWORK UniformTypeIdentifiers REQUIRED)
|
||||
target_sources(dusklight PRIVATE src/dusk/ios/FileSelectDialog.m)
|
||||
set_source_files_properties(src/dusk/ios/FileSelectDialog.m PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
||||
target_link_libraries(dusklight PRIVATE ${UIKIT_FRAMEWORK} ${UNIFORM_TYPE_IDENTIFIERS_FRAMEWORK})
|
||||
endif ()
|
||||
|
||||
include(extern/aurora/cmake/AuroraCopyRuntimeDLLs.cmake)
|
||||
aurora_copy_runtime_dlls(dusklight)
|
||||
|
||||
|
||||
+4
-4
@@ -28,12 +28,12 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache",
|
||||
"DUSK_ENABLE_SENTRY_NATIVE": {
|
||||
"BOREALIS_ENABLE_SENTRY": {
|
||||
"type": "BOOL",
|
||||
"value": true
|
||||
},
|
||||
"DUSK_SENTRY_DSN": "$env{SENTRY_DSN}",
|
||||
"DUSK_SENTRY_ENVIRONMENT": "production",
|
||||
"BOREALIS_SENTRY_DSN": "$env{SENTRY_DSN}",
|
||||
"BOREALIS_SENTRY_ENVIRONMENT": "production",
|
||||
"Rust_RUSTUP_INSTALL_MISSING_TARGET": {
|
||||
"type": "BOOL",
|
||||
"value": true
|
||||
@@ -448,7 +448,7 @@
|
||||
"ci"
|
||||
],
|
||||
"cacheVariables": {
|
||||
"DUSK_ENABLE_SENTRY_NATIVE": {
|
||||
"BOREALIS_ENABLE_SENTRY": {
|
||||
"type": "BOOL",
|
||||
"value": false
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ It aims to be as accurate as possible to the original while also providing new o
|
||||
|
||||
You must dump your own copy of the game. Please see [this article](https://wiki.dolphin-emu.org/index.php?title=Ripping_Games) for instructions. After dumping, you can use a program like [Dolphin](https://dolphin-emu.org/) or [nodtool](https://github.com/encounter/nod/releases) to convert the `.iso` to `.rvz` to save space.
|
||||
|
||||
Currently, only the GameCube releases are supported. Support for other versions of the game is planned in the future.
|
||||
Dusklight currently supports all commercial discs except for Wii's Korean release.
|
||||
|
||||
> [!NOTE]
|
||||
> Dusklight is based on the [Twilight Princess decompilation](https://github.com/zeldaret/tp), which is currently only matching for GameCube. As a result, even when playing Dusklight with a Wii disc, you will be presented with the GameCube version's HUD and certain other specificities.
|
||||
|
||||
### 2. Install Dusklight
|
||||
|
||||
|
||||
@@ -23,5 +23,5 @@ cp -r platforms/freedesktop/{16x16,32x32,48x48,64x64,128x128,256x256,512x512,102
|
||||
cp platforms/freedesktop/dev.twilitrealm.dusk.desktop build/appdir/usr/share/applications
|
||||
|
||||
cd build/install
|
||||
VERSION="$DUSK_VERSION" NO_STRIP=1 "$linuxdeploy" \
|
||||
VERSION="$APP_VERSION" NO_STRIP=1 "$linuxdeploy" \
|
||||
-l "$lib_dir/libusb-1.0.so" --appdir "$build_dir/appdir" --output appimage
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
# Version detection shared by the main build and the mod SDK (sdk/CMakeLists.txt)
|
||||
include_guard(GLOBAL)
|
||||
|
||||
get_filename_component(_DUSK_VERSION_ROOT "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
|
||||
|
||||
set(DUSK_SENTRY_DSN "" CACHE STRING "Sentry DSN")
|
||||
set(DUSK_SENTRY_ENVIRONMENT "development" CACHE STRING "Sentry environment")
|
||||
|
||||
set(DUSK_VERSION_OVERRIDE "" CACHE STRING "Override version string (skips git detection and format validation)")
|
||||
|
||||
macro(detect_version)
|
||||
if (DUSK_VERSION_OVERRIDE)
|
||||
set(DUSK_WC_DESCRIBE "${DUSK_VERSION_OVERRIDE}")
|
||||
set(DUSK_VERSION_STRING "0.0.0.0")
|
||||
set(DUSK_SHORT_VERSION_STRING "0.0.0")
|
||||
set(DUSK_VERSION_CODE "1")
|
||||
set(DUSK_WC_REVISION "")
|
||||
set(DUSK_WC_BRANCH "")
|
||||
set(DUSK_WC_DATE "")
|
||||
message(STATUS "Dusklight version overridden to ${DUSK_WC_DESCRIBE}")
|
||||
else ()
|
||||
# obtain revision info from git
|
||||
find_package(Git)
|
||||
if (GIT_FOUND)
|
||||
# make sure version information gets re-run when the current Git HEAD changes
|
||||
execute_process(WORKING_DIRECTORY ${_DUSK_VERSION_ROOT} COMMAND ${GIT_EXECUTABLE} rev-parse --git-path HEAD
|
||||
OUTPUT_VARIABLE dusk_git_head_filename
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
get_filename_component(dusk_git_head_filename "${dusk_git_head_filename}" ABSOLUTE BASE_DIR "${_DUSK_VERSION_ROOT}")
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${dusk_git_head_filename}")
|
||||
|
||||
execute_process(WORKING_DIRECTORY ${_DUSK_VERSION_ROOT} COMMAND ${GIT_EXECUTABLE} rev-parse --symbolic-full-name HEAD
|
||||
OUTPUT_VARIABLE dusk_git_head_symbolic
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(WORKING_DIRECTORY ${_DUSK_VERSION_ROOT}
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse --git-path ${dusk_git_head_symbolic}
|
||||
OUTPUT_VARIABLE dusk_git_head_symbolic_filename
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
get_filename_component(dusk_git_head_symbolic_filename "${dusk_git_head_symbolic_filename}" ABSOLUTE BASE_DIR "${_DUSK_VERSION_ROOT}")
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${dusk_git_head_symbolic_filename}")
|
||||
|
||||
# defines DUSK_WC_REVISION
|
||||
execute_process(WORKING_DIRECTORY ${_DUSK_VERSION_ROOT} COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
||||
OUTPUT_VARIABLE DUSK_WC_REVISION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
# defines DUSK_WC_DESCRIBE
|
||||
execute_process(WORKING_DIRECTORY ${_DUSK_VERSION_ROOT} COMMAND ${GIT_EXECUTABLE} describe --tags --long --dirty --match "v*"
|
||||
OUTPUT_VARIABLE DUSK_WC_DESCRIBE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# remove the git hash, then collapse a clean "-0" suffix only
|
||||
string(REGEX REPLACE "-[^-]+(-dirty|)$" "\\1" DUSK_WC_DESCRIBE "${DUSK_WC_DESCRIBE}")
|
||||
string(REGEX REPLACE "-0$" "" DUSK_WC_DESCRIBE "${DUSK_WC_DESCRIBE}")
|
||||
|
||||
# defines DUSK_WC_BRANCH
|
||||
execute_process(WORKING_DIRECTORY ${_DUSK_VERSION_ROOT} COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
|
||||
OUTPUT_VARIABLE DUSK_WC_BRANCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
# defines DUSK_WC_DATE
|
||||
execute_process(WORKING_DIRECTORY ${_DUSK_VERSION_ROOT} COMMAND ${GIT_EXECUTABLE} log -1 --format=%ad
|
||||
OUTPUT_VARIABLE DUSK_WC_DATE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
else ()
|
||||
message(STATUS "Unable to find git, commit information will not be available")
|
||||
endif ()
|
||||
|
||||
if (DUSK_WC_DESCRIBE MATCHES "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)([-+].*)?$")
|
||||
set(DUSK_SHORT_VERSION_STRING "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
|
||||
set(_ver_major ${CMAKE_MATCH_1})
|
||||
set(_ver_minor ${CMAKE_MATCH_2})
|
||||
set(_ver_patch ${CMAKE_MATCH_3})
|
||||
set(DUSK_VERSION_TWEAK "0")
|
||||
if (DUSK_WC_DESCRIBE MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+-([0-9]+)(-dirty)?$")
|
||||
set(DUSK_VERSION_TWEAK "${CMAKE_MATCH_1}")
|
||||
elseif (DUSK_WC_DESCRIBE MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+-[0-9A-Za-z.-]+-([0-9]+)(-dirty)?$")
|
||||
set(DUSK_VERSION_TWEAK "${CMAKE_MATCH_1}")
|
||||
endif ()
|
||||
set(DUSK_VERSION_STRING "${DUSK_SHORT_VERSION_STRING}.${DUSK_VERSION_TWEAK}")
|
||||
if (DUSK_VERSION_TWEAK GREATER 999)
|
||||
set(_tweak 999)
|
||||
else ()
|
||||
set(_tweak ${DUSK_VERSION_TWEAK})
|
||||
endif ()
|
||||
# encoding: major*1e7 + minor*1e5 + patch*1e3 + tweak; collision-free for major<210, minor<100, patch<100, tweak<=999
|
||||
math(EXPR DUSK_VERSION_CODE
|
||||
"${_ver_major} * 10000000 + ${_ver_minor} * 100000 + ${_ver_patch} * 1000 + ${_tweak}")
|
||||
else ()
|
||||
set(DUSK_WC_DESCRIBE "UNKNOWN-VERSION")
|
||||
set(DUSK_VERSION_STRING "0.0.0.0")
|
||||
set(DUSK_SHORT_VERSION_STRING "0.0.0")
|
||||
set(DUSK_VERSION_CODE "1")
|
||||
endif ()
|
||||
|
||||
endif ()
|
||||
|
||||
# Add version information to CI environment variables
|
||||
if (DEFINED ENV{GITHUB_ENV})
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "DUSK_VERSION=${DUSK_WC_DESCRIBE}\n")
|
||||
file(APPEND "$ENV{GITHUB_ENV}" "DUSK_VERSION_CODE=${DUSK_VERSION_CODE}\n")
|
||||
endif ()
|
||||
message(STATUS "Dusklight version set to ${DUSK_WC_DESCRIBE}")
|
||||
endmacro()
|
||||
|
||||
# Sets PLATFORM_NAME and configures version.h into the caller's binary dir.
|
||||
macro(configure_version_header)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
set(PLATFORM_NAME win32)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
if (IOS)
|
||||
set(PLATFORM_NAME ios)
|
||||
elseif (TVOS)
|
||||
set(PLATFORM_NAME tvos)
|
||||
else ()
|
||||
set(PLATFORM_NAME macos)
|
||||
endif ()
|
||||
else ()
|
||||
string(TOLOWER CMAKE_SYSTEM_NAME PLATFORM_NAME)
|
||||
endif ()
|
||||
|
||||
configure_file(${_DUSK_VERSION_ROOT}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||
endmacro()
|
||||
@@ -2,7 +2,7 @@ include_guard(GLOBAL)
|
||||
|
||||
get_filename_component(_SYMBOL_MANIFEST_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
|
||||
|
||||
set(_SYMGEN_VERSION "1.3.2")
|
||||
set(_SYMGEN_VERSION "1.3.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)
|
||||
@@ -15,32 +15,32 @@ function(symgen_host_asset out_name out_hash)
|
||||
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||
if (_host_processor MATCHES "^(arm64|aarch64)$")
|
||||
set(_asset "symgen-macos-arm64")
|
||||
set(_asset_hash "SHA256=0344838d1674df09c17c3eeddcf26eb89c333fdb85dfd78f68adc436070eccbe")
|
||||
set(_asset_hash "SHA256=e8420df1160242c83bd0e5197efeeb25ceb9fecc69dbc82bdc4927476381e948")
|
||||
elseif (_host_processor MATCHES "^(x86_64|amd64)$")
|
||||
set(_asset "symgen-macos-x86_64")
|
||||
set(_asset_hash "SHA256=ae0674f4a1e9d0dedfa02d35939ac28cdd229276b331c1f507df5df809cbec7e")
|
||||
set(_asset_hash "SHA256=e51d13bbf0e982d1519f56850ff3c7b5910ca5a7095dd5a82cd8e59750e2d013")
|
||||
endif ()
|
||||
elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
if (_host_processor MATCHES "^(aarch64|arm64)$")
|
||||
set(_asset "symgen-linux-aarch64")
|
||||
set(_asset_hash "SHA256=af766de2bfaeb0a06f6d7bc17bb2510b4a9c40f44a56e49bc4a4b798a6223042")
|
||||
set(_asset_hash "SHA256=331190dd21ecee12a52e857b7f90a8b3e0a114608173813f7df74a31cf783f70")
|
||||
elseif (_host_processor MATCHES "^(x86_64|amd64)$")
|
||||
set(_asset "symgen-linux-x86_64")
|
||||
set(_asset_hash "SHA256=ebd62fb9623acc942b6295609e2306f85a73043b0a8a117f2072b761dd08e68f")
|
||||
set(_asset_hash "SHA256=d727e0ba43242f92a92865af1b69c47aa9d81a0242c4570ce53b90e1ecd15e84")
|
||||
elseif (_host_processor MATCHES "^(i[3-6]86|x86)$")
|
||||
set(_asset "symgen-linux-i686")
|
||||
set(_asset_hash "SHA256=07780a4513fd29726578efc4ff2d88736b22f407ed821b32a68e35ff1e9af5f4")
|
||||
set(_asset_hash "SHA256=0c9f94d36b7fa46d15a199c9d0f1a633b73eb7d9c02621a6a76a676b83a135c7")
|
||||
endif ()
|
||||
elseif (CMAKE_HOST_WIN32)
|
||||
if (_host_processor MATCHES "^(arm64|aarch64)$")
|
||||
set(_asset "symgen-windows-arm64.exe")
|
||||
set(_asset_hash "SHA256=5bb22b4a4a9b5ad45646af411bfb09b8321a732ff3a077eb4c9de1feaef27d2b")
|
||||
set(_asset_hash "SHA256=c699192957e2086ed68912ed39fa77858e1ae894476ab8b557711804cf2aa7cb")
|
||||
elseif (_host_processor MATCHES "^(x86_64|amd64)$")
|
||||
set(_asset "symgen-windows-x86_64.exe")
|
||||
set(_asset_hash "SHA256=1d1ac087f991a96932d108969e15998becfec643e88f3e7d182ca97ebfc6a46f")
|
||||
set(_asset_hash "SHA256=6d56a45617c75065ab7a3192d09ca52ff735baf5637b0899f446138d46acc310")
|
||||
elseif (_host_processor MATCHES "^(i[3-6]86|x86)$")
|
||||
set(_asset "symgen-windows-x86.exe")
|
||||
set(_asset_hash "SHA256=c113f4cd05f813efe2b1878dbfcf44d6302aee3974271736e0036430b0cced78")
|
||||
set(_asset_hash "SHA256=6cccc3a8d29e7525a4d1ade1dc4d89327b7c3002a604ab1c7decb43eea6fd4ab")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma endian big
|
||||
|
||||
#include "std/sys.pat"
|
||||
#include "type/magic.pat"
|
||||
#include "std/array.pat"
|
||||
|
||||
/**
|
||||
* Wrapper for a file-global pointer that allows it to be stored in an array.
|
||||
*/
|
||||
struct Offset<T> {
|
||||
T* offset : u32 [[inline]];
|
||||
};
|
||||
|
||||
struct JAUSeqCollectionTable {
|
||||
u32 mEntryCount;
|
||||
u32 mBmsOffset[mEntryCount];
|
||||
};
|
||||
|
||||
struct JAUSeqCollectionData {
|
||||
type::Magic<"SC"> mMagic;
|
||||
u16 mNumSoundCategories;
|
||||
u32 mSectionSize;
|
||||
Offset<JAUSeqCollectionTable> mTableOffsets[mNumSoundCategories];
|
||||
};
|
||||
|
||||
JAUSeqCollectionData data @ 0x0;
|
||||
@@ -1,71 +0,0 @@
|
||||
#pragma endian big
|
||||
|
||||
#include "std/sys.pat"
|
||||
#include "type/magic.pat"
|
||||
#include "std/array.pat"
|
||||
|
||||
/**
|
||||
* Wrapper for a file-global pointer that allows it to be stored in an array.
|
||||
*/
|
||||
struct Offset<T> {
|
||||
T* offset : u32 [[inline]];
|
||||
};
|
||||
|
||||
struct ItemSoundEffect {
|
||||
u8 mPriority;
|
||||
u8 mVolume;
|
||||
padding[2];
|
||||
u32 mSwBit;
|
||||
float mPitch;
|
||||
};
|
||||
|
||||
struct ItemSequence {
|
||||
u8 mPriority;
|
||||
u8 mVolume;
|
||||
u16 mResourceId;
|
||||
};
|
||||
|
||||
struct ItemStream {
|
||||
u8 mPriority;
|
||||
u8 mVolume;
|
||||
u16 mStreamPanParameters;
|
||||
char* mStreamFilePath[] : u32;
|
||||
};
|
||||
|
||||
struct SoundTableGroupEntry {
|
||||
u8 mTypeId;
|
||||
if (mTypeId == 0x51) {
|
||||
ItemSoundEffect* mOffset : u24 [[inline]];
|
||||
} else if (mTypeId == 0x60) {
|
||||
ItemSequence* mOffset : u24 [[inline]];
|
||||
} else if (mTypeId == 0x70 || mTypeId == 0x71) {
|
||||
ItemStream* mOffset : u24 [[inline]];
|
||||
} else {
|
||||
u24 mOffset;
|
||||
}
|
||||
};
|
||||
|
||||
struct TGroup {
|
||||
u32 mNumItems;
|
||||
padding[4];
|
||||
SoundTableGroupEntry mEntries[mNumItems];
|
||||
};
|
||||
|
||||
struct TSection {
|
||||
u32 mNumGroups;
|
||||
Offset<TGroup> mGroupOffsets[mNumGroups];
|
||||
};
|
||||
|
||||
struct Root {
|
||||
u32 mSectionNumber;
|
||||
Offset<TSection> mSectionOffsets[mSectionNumber];
|
||||
};
|
||||
|
||||
struct THeader {
|
||||
type::Magic<"BST "> mMagic;
|
||||
|
||||
padding[8];
|
||||
Root* mRoot : u32;
|
||||
};
|
||||
|
||||
THeader header @ 0x0;
|
||||
@@ -1,228 +0,0 @@
|
||||
#pragma endian big
|
||||
|
||||
#include "std/sys.pat"
|
||||
#include "type/magic.pat"
|
||||
#include "std/array.pat"
|
||||
|
||||
/*
|
||||
WSYS file
|
||||
The WSYS file contains roughly two sections: WBCT and WINF.
|
||||
WBCT contains the mapping of Wave ID -> wave archives.
|
||||
WINF are the wave archives themselves and their metadata.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper for a file-global pointer that allows it to be stored in an array.
|
||||
*/
|
||||
struct Offset<T> {
|
||||
T* offset : u32 [[inline]];
|
||||
};
|
||||
|
||||
/**
|
||||
* Format that audio data is in..
|
||||
*/
|
||||
enum WaveFormat : u8 {
|
||||
/**
|
||||
* 16-samples-per-9-bytes custom Nintendo ADPCM.
|
||||
*/
|
||||
ADPCM4 = 0,
|
||||
|
||||
/**
|
||||
* 16-samples-per-5-bytes custom Nintendo ADPCM.
|
||||
*/
|
||||
ADPCM2 = 1,
|
||||
|
||||
/**
|
||||
* 8-bit-per-sample PCM.
|
||||
*/
|
||||
PCM8 = 2,
|
||||
|
||||
/**
|
||||
* 16-bit-per-sample PCM.
|
||||
*/
|
||||
PCM16 = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines playback info for a single audio "wave".
|
||||
* This data is stored per archive, making it duplicated (except for mAWOffsetStart)
|
||||
*/
|
||||
struct TWave {
|
||||
padding[1]; // unknown
|
||||
WaveFormat mWaveFormat;
|
||||
|
||||
/**
|
||||
* Key (as in like, the musical term) this sample is in.
|
||||
*/
|
||||
u8 mBaseKey;
|
||||
padding[1];
|
||||
|
||||
/**
|
||||
* Sample rate of the audio in Hz.
|
||||
*/
|
||||
float mSampleRate;
|
||||
|
||||
/**
|
||||
* Position where the sample data starts.
|
||||
* This is in the .aw file for the archive containing this TWave.
|
||||
*/
|
||||
u32 mAWOffsetStart;
|
||||
|
||||
/**
|
||||
* Byte length of the sample data.
|
||||
*/
|
||||
u32 mAWLength;
|
||||
|
||||
/**
|
||||
* Indicates whether the sample should loop or not. All bits appear set if so.
|
||||
*/
|
||||
u32 mLoopFlags;
|
||||
|
||||
/**
|
||||
* Audio sample at which the loop starts.
|
||||
*/
|
||||
u32 mLoopStartSample;
|
||||
|
||||
/**
|
||||
* Audio sample at which the loop ends (and goes back to mLoopStartSample).
|
||||
*/
|
||||
u32 mLoopEndSample;
|
||||
|
||||
/**
|
||||
* Total sample count in this wave.
|
||||
*/
|
||||
u32 mSampleCount;
|
||||
|
||||
/**
|
||||
* Last sample for continuing ADPCM decode after loop.
|
||||
*/
|
||||
s16 mpLast;
|
||||
|
||||
/**
|
||||
* Penult sample for continuing ADPCM decode after loop.
|
||||
*/
|
||||
s16 mpPenult;
|
||||
};
|
||||
|
||||
/**
|
||||
* A single wave archive on disk.
|
||||
* These are paired 1:1 with TCtrlScene objects.
|
||||
*/
|
||||
struct TWaveArchive {
|
||||
/**
|
||||
* Filename of the raw sample data on disc. Relative to /Audiores/Waves/
|
||||
*/
|
||||
char mFileName[0x70];
|
||||
|
||||
/**
|
||||
* Amount of waves in this archive.
|
||||
* Matches the count in the paired TCtrl object.
|
||||
*/
|
||||
u32 mWaveCount;
|
||||
|
||||
/**
|
||||
* Offsets to the wave metadata (not sample data) in the WSYS.
|
||||
* These are paired 1:1 to the TCtrlWaves, and the TCtrlWave contains the actual
|
||||
* "Wave ID" used by the game for lookups.
|
||||
*/
|
||||
Offset<TWave> waveOffsets[mWaveCount];
|
||||
};
|
||||
|
||||
/**
|
||||
* Header containing data for wave archives and their metadata.
|
||||
*/
|
||||
struct TWaveArchiveBank {
|
||||
type::Magic<"WINF"> mMagic;
|
||||
|
||||
/**
|
||||
* Amount of archives in this wave bank.
|
||||
* Matches the value in TCtrlGroup.
|
||||
*/
|
||||
u32 mArchiveCounts;
|
||||
Offset<TWaveArchive> mArchiveOffsets[mArchiveCounts];
|
||||
};
|
||||
|
||||
/**
|
||||
* Definition for a single wave in a control group.
|
||||
*/
|
||||
struct TCtrlWave {
|
||||
/**
|
||||
* Group ID matches the index of the control group this item is referenced by.
|
||||
*/
|
||||
u16 mGroupId;
|
||||
|
||||
/**
|
||||
* Wave ID used by the game to look this wave up.
|
||||
*/
|
||||
u16 mWaveId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains the actual data for a TCtrlScene.
|
||||
* Why is this separate? Who knows.
|
||||
*/
|
||||
struct TCtrl {
|
||||
// Other versions of this struct with different magic (C-EX and C-ST) also exist in the file.
|
||||
// They aren't pointed to so we don't need to worry about them.
|
||||
type::Magic<"C-DF"> mMagic;
|
||||
|
||||
/**
|
||||
* Amount of waves in this group.
|
||||
* Matches the value in TWaveArchive.
|
||||
*/
|
||||
u32 waveCount;
|
||||
Offset<TCtrlWave> mWaveOffsets[waveCount];
|
||||
};
|
||||
|
||||
/**
|
||||
* A single scene or "group" of waves that are loaded at once.
|
||||
*/
|
||||
struct TCtrlScene {
|
||||
type::Magic<"SCNE"> mMagic;
|
||||
|
||||
padding[8]; // unknown
|
||||
TCtrl* mCtrlOffset : u32 [[inline]];
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains the "control" section of the WSYS.
|
||||
*/
|
||||
struct TCtrlGroup {
|
||||
type::Magic<"WBCT"> mMagic;
|
||||
|
||||
padding[4]; // unknown
|
||||
u32 mGroupCount;
|
||||
|
||||
Offset<TCtrlScene> mCtrlSceneOffsets[mGroupCount];
|
||||
};
|
||||
|
||||
struct THeader {
|
||||
type::Magic<"WSYS"> mMagic;
|
||||
|
||||
/**
|
||||
* Size of WSYS in bytes.
|
||||
*/
|
||||
u32 mSize;
|
||||
|
||||
/**
|
||||
* ID of wave bank.
|
||||
* This matches the value passed to the BAA load command.
|
||||
* The game originally does not use this value itself, but Dusklight does rely on it.
|
||||
*/
|
||||
u32 mId;
|
||||
|
||||
/**
|
||||
* Total amount of waves in this wave bank.
|
||||
* (not groups! Waves!)
|
||||
*/
|
||||
u32 mWaveTableSize;
|
||||
|
||||
TWaveArchiveBank* archiveBankOffset : u32;
|
||||
TCtrlGroup* ctrlGroupOffset : u32;
|
||||
};
|
||||
|
||||
THeader header @ 0x0;
|
||||
|
||||
std::assert(
|
||||
header.archiveBankOffset.mArchiveCounts == header.ctrlGroupOffset.mGroupCount,
|
||||
"Control group and archive count does not match!");
|
||||
@@ -5,7 +5,13 @@
|
||||
- A Windows, Linux, or macOS device
|
||||
- iOS device connected to computer via USB
|
||||
- Dusklight IPA file (download the latest `Dusklight-vX.X.X-ios-arm64.ipa` from the [releases page](https://github.com/TwilitRealm/dusklight/releases))
|
||||
- Legally acquired game disc - `GZ2E01` (Gamecube USA) or `GZ2PE01` (Gamecube PAL)
|
||||
- Legally acquired game disc:
|
||||
- `GZ2E01` (GameCube USA)
|
||||
- `GZ2P01` (GameCube PAL)
|
||||
- `GZ2J01` (GameCube JPN)
|
||||
- `RZDE01` (Wii USA Rev. 0 *or* Rev. 2)
|
||||
- `RZDP01` (Wii PAL)
|
||||
- `RZDJ01` (Wii JPN)
|
||||
|
||||
## 1. Install iloader
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
# JAudio
|
||||
|
||||
**JAudio** is the name for the audio engine used by Twilight Princess (along with many other Nintendo games from the era). TP uses exclusively JAudio v2, while other games use v1 or a mix of v1 and v2 infrastructure. This document will primarily focus on TP's use case, but best efforts will be made to document where behavior is TP-specific.
|
||||
|
||||
## Common concepts
|
||||
|
||||
Audio is almost exclusively
|
||||
|
||||
### `JAISoundID`
|
||||
|
||||
A "sound", be that a _sound effect_ or music, is referenced in-code through the `JAISoundID` type. This is a `u32` that the game uses to look up the relevant sound. The actual value is bitpacked (BE) from the following fields:
|
||||
|
||||
| Type | Field | Description |
|
||||
|-------|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `u8` | Section ID | Section of the Sound Table this sound effect is located in. 0 for sound effects, 1 for sequenced music, 2 for streamed music.[^sectionids] |
|
||||
| `u8` | Group ID | ID of group further used to organize inside the Sound Table's Section. Sound effects are grouped into things like "SYSTEM" and "ENEMY", other sections leave this at 0. |
|
||||
| `u16` | "Wave ID" | Index inside the group to look up the sound at.<br/>**Note** that the term "wave" in code is extremely confusing[^waveterm]; it does **not** refer to audio samples ("waves") in the wave banks directly. |
|
||||
|
||||
[^sectionids]: JAudio itself can seemingly work outside this convention, however it is enforced by some TP-specific game code.
|
||||
|
||||
[^waveterm]: Possibly vestigial from JAudio v1, where I believe there were less layers of indirection.
|
||||
|
||||
## Disc files
|
||||
|
||||
All audio data is stored in `/Audiores` on the disc. Files are as follows:
|
||||
|
||||
### `/Audiores/Seqs/Z2SoundSeqs.arc`
|
||||
|
||||
Contains the BMS instructions for all BMS-based music and sound effects. Not all data is kept in memory at once.
|
||||
|
||||
### `/Audiores/Stream/*.ast`
|
||||
|
||||
Contains individual streamed music. Each file is a separate music track. See [this page](https://www.lumasworkshop.com/wiki/AST_(File_Format)) for file format description.
|
||||
|
||||
### `/Audiores/Waves/*.aw`
|
||||
|
||||
Contains audio sample data for sequenced music and sound effects. These files are pure meat, no bone: they are loaded directly into ARAM and all metadata is stored in the BAA WSYS sections.
|
||||
|
||||
Each file contains audio samples for one "scene", with factors like the current level determining what "scenes" are made resident in memory. There is tons of duplicate data between scenes, presumably to increase simplicity and loading performance.
|
||||
|
||||
### `/Audiores/Z2Sound.baa`
|
||||
|
||||
Contains all remaining metadata for the audio system. This is effectively a container for a bunch of different sub-sections. The file starts with a bunch of "commands" that indicate where other data in the file is. Each command has a 4-character identifier and depending on the command will be followed by some extra arguments before the next command.
|
||||
|
||||
The commands used by TP's BAA file are as follows (note that the decompiled code has support for more load commands, which are unused):
|
||||
|
||||
| Command/Argument | Value | Description |
|
||||
|------------------|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Command | `AA_<` | Start of BAA commands. Must be at the start of the file and only appear once. |
|
||||
| Command | `>_AA` | End of BAA commands. |
|
||||
| Command | `ws `[^spaces] | Wave bank/WSYS data. Defines where audio samples are located on disc. |
|
||||
| Argument | u32 | Wave bank ID, max 255. In TP, 0 is sound effects, 1 is music samples. |
|
||||
| Argument | u32 | File offset for start of `WSYS` data |
|
||||
| Argument | u32 | Bit field selecting which groups (= `.aw` files) to load immediately. TP leaves this at zero.[^32ws] |
|
||||
| Command | `bnk `[^spaces] | Instrument bank/IBNK |
|
||||
| Argument | u32 | Target wave bank ID |
|
||||
| Argument | u32 | File offset for start of `IBNK` data |
|
||||
| Command | `bsc `[^spaces] | Sound effect sequence collection. |
|
||||
| Argument | u32 | File offset for start of `SC` data. |
|
||||
| Argument | u32 | File offset for end of `SC` data. |
|
||||
| Command | `bst `[^spaces] | Sound table. Defines parameters for music and sound effects. |
|
||||
| Argument | u32 | File offset for start of `BST `[^spaces] data. |
|
||||
| Argument | u32 | File offset for end of `BST `[^spaces] data. |
|
||||
| Command | `bstn` | Sound name table. Defines names of all music and sound effects. Present on disc, but loading is disabled on release versions of the game. |
|
||||
| Argument | u32 | File offset for start of `BSTN` data. |
|
||||
| Argument | u32 | File offset for end of `BSTN` data. |
|
||||
| Command | `bfca` | Unknown, something related to initialization of DSP FX data. |
|
||||
| Argument | u32 | File offset for start of `RARC` data. |
|
||||
|
||||
[^spaces]: Padded with spaces.
|
||||
|
||||
[^32ws]: Both of TP's wave banks have far more than 32 groups, and seemingly this mechanism would not be able to deal with that.
|
||||
|
||||
Following is data descriptions for the remaining data in the `.BAA`, as pointed to by the above commands.
|
||||
|
||||
### `WSYS` / Wave banks
|
||||
|
||||
`WSYS` / Wave bank data defines where a set of audio samples can be found on disc. Each wave bank is made of multiple "groups", where each group corresponds to one `.aw` file on disc. Each group has a set of "wave IDs" it contains, along with the metadata (e.g. sample rate) and data offset in the `.aw` file.
|
||||
|
||||
Multiple groups can contain the same wave ID, thus meaning the raw audio samples can be duplicated on disk.
|
||||
|
||||
For the actual binary layout of this data, check [the ImHex pattern](imhex/jaudio/wsys.hexpat)
|
||||
|
||||
*Relevant classes: `JASWSParser`, `JASBasicWaveBank`, `JASSimpleWaveBank`.*
|
||||
|
||||
## Further reading & credits
|
||||
|
||||
* https://www.lumasworkshop.com/wiki/SMR.szs (note that details like the exact layout of the BAA are not the same as TP)
|
||||
* XAYRGA for doing much RE work and making [JAMTools](https://xayr.gay/tools/SoundModdingToolkit/)
|
||||
* The decompiled source code, duh.
|
||||
+314
-19
@@ -209,8 +209,8 @@ if (svc_resource->load(mod_ctx, "config.txt", &buf) == MOD_OK) {
|
||||
}
|
||||
```
|
||||
|
||||
Missing files return `MOD_UNAVAILABLE`. Always `free` what you `load`. Note that the bundle is read-only; for writable
|
||||
storage, use the directory from `svc_host->mod_dir(mod_ctx)`.
|
||||
Missing files return `MOD_UNAVAILABLE`. Always `free` what you `load`. The bundle is read-only; use
|
||||
`HostService::data_dir` for persistent storage.
|
||||
|
||||
### HostService (`mods/svc/host.h`)
|
||||
|
||||
@@ -219,9 +219,17 @@ Mod metadata and runtime interaction with the loader:
|
||||
```cpp
|
||||
IMPORT_SERVICE(HostService, svc_host);
|
||||
|
||||
const char* id = svc_host->mod_id(mod_ctx);
|
||||
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
|
||||
// Temporary mod data directory, wiped on startup
|
||||
const char* cacheDir = svc_host->mod_dir(mod_ctx);
|
||||
|
||||
// Persistent mod data directory
|
||||
const char* dataDir = nullptr;
|
||||
if (svc_host->data_dir(mod_ctx, &dataDir) == MOD_OK) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Report an error and disable the mod
|
||||
svc_host->fail(mod_ctx, MOD_ERROR, "something unrecoverable happened");
|
||||
```
|
||||
|
||||
`get_service`/`publish_service` provide dynamic service lookup; see [Exporting Services](#exporting-services).
|
||||
@@ -254,14 +262,16 @@ Installs hooks on game functions and resolves symbols by name. You'll rarely cal
|
||||
### OverlayService (`mods/svc/overlay.h`)
|
||||
|
||||
Registers DVD file overlays at runtime: the dynamic counterpart to the static `overlay/` directory (see
|
||||
[Asset Overlays](#asset-overlays)). Overlay a disc path with a file from your bundle, or with a caller-owned buffer
|
||||
[Asset Overlays](#asset-overlays)). Overlay a disc path with a file from your bundle, a file within an archive,
|
||||
or with a caller-owned buffer
|
||||
(copied on registration):
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(OverlayService, svc_overlay);
|
||||
|
||||
OverlayHandle handle = 0;
|
||||
svc_overlay->add_file(mod_ctx, "/res/Msgus.arc", "res/replacement.arc", &handle);
|
||||
svc_overlay->add_file(mod_ctx, "/Movie/demo_movie98_00.thp", "res/replacement.thp", &handle); // Replaces the demo movie
|
||||
svc_overlay->add_file(mod_ctx, "/res/Object/Kmdl/archive/bmwr/al.bmd", "res/link_model.bmd", &handle); // Replaces link's model
|
||||
svc_overlay->add_buffer(mod_ctx, "/generated.txt", data, size, nullptr);
|
||||
svc_overlay->remove(mod_ctx, handle);
|
||||
```
|
||||
@@ -270,6 +280,9 @@ svc_overlay->remove(mod_ctx, handle);
|
||||
on the disc are added as new files. Changes are applied at the next frame boundary, and data the game already read
|
||||
stays in memory until the file is re-read: sometimes a scene reload, and in the worst case, a full restart.
|
||||
|
||||
Dusklight reloads core archive files during scene transitions so modifications to Link, Midna or other globally-loaded
|
||||
data get refreshed without a full restart.
|
||||
|
||||
See [Asset Overlays](#asset-overlays) for priority and conflict handling.
|
||||
|
||||
### TextureService (`mods/svc/texture.h`)
|
||||
@@ -340,6 +353,88 @@ Change callbacks fire on the game thread whenever the value changes at runtime (
|
||||
Writes that store the same value are silent. Values applied from `config.json` or `--cvar` at registration do
|
||||
**not** fire callbacks; read the value after `register_var` for the starting state.
|
||||
|
||||
### SaveService (`mods/svc/save.h`)
|
||||
|
||||
Stores named binary blobs for each save slot. Blob names are scoped to the calling mod, and each mod may store up to
|
||||
`SAVE_BLOB_BUDGET_BYTES` per slot. The service copies data passed to `set_blob`.
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(SaveService, svc_save);
|
||||
|
||||
struct MySaveData {
|
||||
uint32_t version;
|
||||
uint32_t counter;
|
||||
};
|
||||
|
||||
MySaveData state{1, 42};
|
||||
svc_save->set_blob(mod_ctx, "state", &state, sizeof(state));
|
||||
|
||||
MySaveData loaded{};
|
||||
size_t loadedSize = sizeof(loaded);
|
||||
if (svc_save->get_blob(mod_ctx, "state", &loaded, &loadedSize) == MOD_OK &&
|
||||
loadedSize == sizeof(loaded)) {
|
||||
apply_state(loaded);
|
||||
}
|
||||
```
|
||||
|
||||
`set_blob`, `get_blob`, and `delete_blob` operate on the current slot, which is available after creating or loading a
|
||||
save and unavailable at file select. Blob changes are written with the next game save. File-select copy and erase
|
||||
operations update the blob data as well. Use `peek_blob` to read the calling mod's data from any slot; it uses the same
|
||||
buffer contract as `get_blob`. Pass a `NULL` buffer to either read function to query the blob size.
|
||||
|
||||
`observe_saves` registers callbacks for new, loaded, and written saves. New-save callbacks run after the slot's blobs
|
||||
are cleared. Observers are removed automatically when the mod is detached, so the output handle is only needed for
|
||||
manual unregistration. Save callbacks run on the game thread.
|
||||
|
||||
### StageService (`mods/svc/stage.h`)
|
||||
|
||||
Allows making changes to a stage's "stage info" (contents of .dzs/.dzr files).
|
||||
(Currently only supports editing actor nodes.)
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(StageService, svc_stage);
|
||||
|
||||
stage_actor_data_class record = {
|
||||
"carry00",
|
||||
0xFF000000,
|
||||
cXyz(0.0f, 0.0f, 0.0f),
|
||||
csXyz(0, 0, 0),
|
||||
0,
|
||||
};
|
||||
|
||||
StageActorHandle handle{};
|
||||
svc_stage->patch_actor(mod_ctx, "F_SP102", 0, -1, record_crc, &record, sizeof(record), &handle);
|
||||
```
|
||||
|
||||
```
|
||||
StageActorHandle handle{};
|
||||
svc_stage->delete_actor(mod_ctx, "F_SP102", 0, -1, record_crc, &handle);
|
||||
```
|
||||
|
||||
Patch or remove actors from the original actor list as the room loads.
|
||||
Given records must be of either `stage_actor_data_class` or `stage_tgsc_data_class` types.
|
||||
`record_crc` is the CRC-32 of the unmodified original record used to identify the record to replace or remove.
|
||||
|
||||
```
|
||||
stage_actor_data_class record = {
|
||||
"carry00",
|
||||
0xFF000000,
|
||||
cXyz(0.0f, 0.0f, 0.0f),
|
||||
csXyz(0, 0, 0),
|
||||
0,
|
||||
};
|
||||
|
||||
StageActorHandle handle{};
|
||||
svc_stage->add_actor(mod_ctx, "F_SP102", 0, -1, &record, sizeof(record), &handle);
|
||||
```
|
||||
|
||||
Add a new actor to the actor list as the room loads.
|
||||
Given records must be of either `stage_actor_data_class` or `stage_tgsc_data_class` types.
|
||||
|
||||
Stage names may contain up to 8 characters. For patches and deletions, room `0xff` and layer `-1` match any room or
|
||||
layer; additions require a specific room. Edits are removed when the mod is detached. If multiple mods edit the same
|
||||
record, the later-loaded mod wins.
|
||||
|
||||
### UiService (`mods/svc/ui.h`)
|
||||
|
||||
Integrate seamlessly with Dusklight's UI system: add controls and buttons to your mod's detail pane in the Mods window,
|
||||
@@ -379,8 +474,8 @@ per-window RCSS. A non-`MOD_OK` result from `build`/`update` fails your mod, as
|
||||
callback.
|
||||
|
||||
**Controls:** `pane_add_control` adds an input row described by a `UiControlDesc`: `UI_CONTROL_BUTTON`,
|
||||
`UI_CONTROL_TOGGLE`, `UI_CONTROL_NUMBER`, `UI_CONTROL_STRING`, or `UI_CONTROL_SELECT`. Values bind with callbacks or
|
||||
directly to a config var.
|
||||
`UI_CONTROL_GROUP`, `UI_CONTROL_TOGGLE`, `UI_CONTROL_NUMBER`, `UI_CONTROL_STRING`, `UI_CONTROL_SELECT`, or
|
||||
`UI_CONTROL_COLOR`. Values bind with callbacks or directly to a config var.
|
||||
|
||||
```cpp
|
||||
UiControlDesc control = UI_CONTROL_DESC_INIT;
|
||||
@@ -393,9 +488,56 @@ svc_ui->pane_add_control(mod_ctx, leftPane, &control, nullptr);
|
||||
```
|
||||
|
||||
`UI_BINDING_CONFIG_VAR` wires persistence, change notifications, and the modified indicator automatically. The var
|
||||
type must match the control: `TOGGLE` = bool, `NUMBER` and `SELECT` = int, `STRING` = string. Float vars are not
|
||||
bindable; use callbacks and convert. `help_rml` and `SELECT` option lists render in a help pane, so `SELECT` controls
|
||||
are only available inside window tabs.
|
||||
type must match the control: `TOGGLE` = bool, `NUMBER` and `SELECT` = int, `STRING` and `COLOR` = string. Float vars
|
||||
are not bindable; use callbacks and convert. `help_rml` and `SELECT` option lists render in a help pane, so `SELECT`
|
||||
controls are only available inside window tabs.
|
||||
|
||||
`pane_add_group` adds a category button to a window tab's left pane. Focusing the button clears the paired right pane
|
||||
and calls the group's build callback with that pane, which is useful for organizing related controls without adding
|
||||
more tabs.
|
||||
|
||||
**Lists:** `pane_add_list` adds a scrollable virtualized list of items that can be efficiently updated and filtered.
|
||||
Keys must be unique and remain stable across replacements.
|
||||
|
||||
```cpp
|
||||
UiListHandle locationList = 0;
|
||||
|
||||
void replace_locations(std::string_view query) {
|
||||
std::vector<UiListItem> items;
|
||||
for (uint64_t i = 0; i < locations.size(); ++i) {
|
||||
if (matches(locations[i], query)) {
|
||||
UiListItem item = UI_LIST_ITEM_INIT;
|
||||
item.key = i;
|
||||
item.label = locations[i].c_str();
|
||||
items.push_back(item);
|
||||
}
|
||||
}
|
||||
svc_ui->list_set_items(mod_ctx, locationList, items.data(), items.size());
|
||||
}
|
||||
|
||||
void set_filter(ModContext*, void*, const UiControlValue* value) {
|
||||
replace_locations(value->string_value);
|
||||
}
|
||||
|
||||
bool location_selected(ModContext*, UiListHandle, uint64_t key, void*) {
|
||||
return selected_locations.contains(key);
|
||||
}
|
||||
|
||||
UiControlDesc filter = UI_CONTROL_DESC_INIT;
|
||||
filter.kind = UI_CONTROL_STRING;
|
||||
filter.label = "Filter";
|
||||
filter.get = get_filter;
|
||||
filter.set = set_filter;
|
||||
filter.string_set_mode = UI_STRING_SET_ON_CHANGE; /* invoke `set` while typing */
|
||||
svc_ui->pane_add_control(mod_ctx, pane, &filter, nullptr);
|
||||
|
||||
UiListDesc list = UI_LIST_DESC_INIT;
|
||||
/* items may be passed as a part of list creation, or set afterwards */
|
||||
list.on_pressed = location_pressed;
|
||||
list.is_selected = location_selected;
|
||||
svc_ui->pane_add_list(mod_ctx, pane, &list, &locationList);
|
||||
replace_locations(""); /* calls `list_set_items` */
|
||||
```
|
||||
|
||||
**Windows:** `window_push` pushes a tabbed two-pane window onto the document stack and shows it. Each tab's `build`
|
||||
receives the window handle plus fresh left and right pane handles on every activation. The optional per-tab `update`
|
||||
@@ -417,10 +559,36 @@ svc_ui->window_push(mod_ctx, &desc, &window);
|
||||
```
|
||||
|
||||
**Dialogs:** `dialog_push` shows a modal dialog. `variant` picks the style, `icon` optionally overrides the variant's
|
||||
default icon, and actions become buttons. After an action's `on_pressed` returns, the dialog closes unless the action
|
||||
sets `keep_open`. A `keep_open` action can close it later (or immediately) with `dialog_close`. Cancel fires
|
||||
`on_dismiss` if present and always closes. `dialog_set_body`, `dialog_set_icon`, and `dialog_add_action` mutate a live
|
||||
dialog.
|
||||
default icon, and actions become buttons. The optional `build` callback allows you to add controls to a pane between
|
||||
the body and actions. It uses the same text, progress, and control builders as panels.
|
||||
|
||||
```cpp
|
||||
ModResult build_dialog(ModContext*, UiElementHandle pane, void*, ModError*) {
|
||||
UiControlDesc input = UI_CONTROL_DESC_INIT;
|
||||
input.kind = UI_CONTROL_STRING;
|
||||
input.label = "Name";
|
||||
input.get = get_name;
|
||||
input.set = set_name;
|
||||
return svc_ui->pane_add_control(mod_ctx, pane, &input, nullptr);
|
||||
}
|
||||
|
||||
UiDialogAction action = UI_DIALOG_ACTION_INIT;
|
||||
action.label = "Save";
|
||||
action.on_pressed = save;
|
||||
action.is_disabled = is_save_disabled;
|
||||
|
||||
UiDialogDesc dialog = UI_DIALOG_DESC_INIT;
|
||||
dialog.title = "New Preset";
|
||||
dialog.body_rml = "Choose a name for the preset.";
|
||||
dialog.actions = &action;
|
||||
dialog.action_count = 1;
|
||||
dialog.build = build_dialog;
|
||||
svc_ui->dialog_push(mod_ctx, &dialog, nullptr);
|
||||
```
|
||||
|
||||
After an action's `on_pressed`, the dialog closes unless the action sets `keep_open`. It can then be closed later
|
||||
(or immediately) with `dialog_close`. Cancel fires `on_dismiss` and always closes. `dialog_set_body` and
|
||||
`dialog_set_icon` mutate a live dialog.
|
||||
|
||||
**Toasts:** `push_toast` enqueues a notification. Titles and bodies accept RML. The optional `type` is applied as an
|
||||
RCSS class; `warning` uses the built-in warning appearance, and mods can define their own types. A duration of 0 uses
|
||||
@@ -543,6 +711,128 @@ if (svc_camera->get_camera(mod_ctx, game_view, &camera) == MOD_OK) {
|
||||
first in-game frame. Projection matrices match the renderer's WebGPU clip convention and renderer depth convention
|
||||
(reversed-Z by default).
|
||||
|
||||
Camera operators allow overriding the main camera. When an operator callback returns true, its values replace the camera
|
||||
state for the current frame. Register and unregister using `register_camera_operator` / `unregister_camera_operator`.
|
||||
|
||||
### GameModeService (`mods/svc/game_mode.h`)
|
||||
|
||||
Allows a mod to register a game mode with callbacks for key gameplay and save lifecycle events. Registered game modes
|
||||
appear in the prelaunch menu. Game modes may use a unique set of saves by configuring `save_name`; leave it empty to use
|
||||
the vanilla `gczelda2` save.
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(LogService, svc_log);
|
||||
IMPORT_SERVICE(HookService, svc_hook);
|
||||
IMPORT_SERVICE(GameModeService, svc_game_mode);
|
||||
|
||||
DEFINE_HOOK(fopAcM_createItem, CreateItem);
|
||||
|
||||
#define MY_GAME_MODE_ID "game-mode-id"
|
||||
|
||||
static HookAction my_function_hook(ModContext* ctx, void* args, void*, void*) {
|
||||
// If we wish to have this hook only run while the gamemode is registered, we need to hook the function from the
|
||||
// gamemode's onActivatedFunction, and uninstall the hook during the onDeactivatedFunction. Example below.
|
||||
// Alternatively, check with `svc_game_mode->is_active(mod_ctx, MY_GAME_MODE_ID, &active) == MOD_OK && active`.
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
ModResult on_game_mode_activated(void*, ModError* outError) {
|
||||
// Setup the gamemode, Add any hooks that are gamemode specific
|
||||
// Overlay any files that are gamemode specific
|
||||
ModResult result = mods::hook_add_pre<CreateItem>(svc_hook, my_function_hook);
|
||||
if (result != MOD_OK) {
|
||||
return mods::set_error(outError, result, "failed to install fopAcM_createItem hook");
|
||||
}
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
ModResult on_game_mode_deactivated(void*, ModError* outError) {
|
||||
// Uninstall any hooks that are gamemode specific
|
||||
// Remove any file overlays that are gamemode specific
|
||||
ModResult result = mods::hook_uninstall<CreateItem>();
|
||||
if (result != MOD_OK) {
|
||||
return mods::set_error(outError, result, "failed to uninstall fopAcM_createItem hook");
|
||||
}
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
ModResult on_save_loaded(void*, ModError*) {
|
||||
// This function will be invoked by the game as a save is loaded
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
const GameModeDesc gameModeDesc = {
|
||||
.struct_size = sizeof(GameModeDesc),
|
||||
.game_mode_id = MY_GAME_MODE_ID,
|
||||
.full_name = "My Game Mode",
|
||||
.save_name = "my-unique-save",
|
||||
.user_data = nullptr,
|
||||
.on_activated = on_game_mode_activated,
|
||||
.on_deactivated = on_game_mode_deactivated,
|
||||
.on_save_loaded = on_save_loaded,
|
||||
};
|
||||
svc_game_mode->register_game_mode(mod_ctx, &gameModeDesc);
|
||||
```
|
||||
|
||||
A game mode can also open UI for per-save settings when creating a new file. The state begins as
|
||||
`GAME_MODE_STATE_PENDING` and remains valid until the mod selects `PROCEED` or `RETURN`.
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(GameModeService, svc_game_mode);
|
||||
IMPORT_SERVICE(UiService, svc_ui);
|
||||
|
||||
ModResult on_new_save_select(void*, GameModeNewSaveState* state, ModError* outError) {
|
||||
static GameModeNewSaveState* newSaveState;
|
||||
static UiWindowHandle windowHandle;
|
||||
|
||||
newSaveState = state;
|
||||
|
||||
UiTabDesc tabs[1]{};
|
||||
|
||||
tabs[0].struct_size = sizeof(UiTabDesc);
|
||||
tabs[0].title = "Play";
|
||||
tabs[0].build = [](ModContext* ctx, UiWindowHandle, UiElementHandle leftPane, UiElementHandle rightPane, void*, ModError*) {
|
||||
UiControlDesc desc = UI_CONTROL_DESC_INIT;
|
||||
desc.kind = UI_CONTROL_BUTTON;
|
||||
desc.label = "Play";
|
||||
desc.help_rml = "Play Button";
|
||||
desc.on_pressed = [](ModContext* ctx, void* userdata) {
|
||||
*newSaveState = GAME_MODE_STATE_PROCEED;
|
||||
svc_ui->window_close(ctx, *static_cast<UiWindowHandle*>(userdata));
|
||||
};
|
||||
desc.user_data = &windowHandle;
|
||||
svc_ui->pane_add_control(mod_ctx, leftPane, &desc, nullptr);
|
||||
return MOD_OK;
|
||||
};
|
||||
|
||||
UiWindowDesc desc = UI_WINDOW_DESC_INIT;
|
||||
desc.tabs = tabs;
|
||||
desc.tab_count = 1;
|
||||
desc.on_closed = [](ModContext *, UiWindowHandle, void *userdata) {
|
||||
// If closing the window through backing out, return to file select
|
||||
if (*newSaveState == GAME_MODE_STATE_PENDING) {
|
||||
*newSaveState = GAME_MODE_STATE_RETURN;
|
||||
}
|
||||
};
|
||||
|
||||
ModResult result = svc_ui->window_push(mod_ctx, &desc, &windowHandle);
|
||||
if (result != MOD_OK) {
|
||||
return mods::set_error(outError, result, "failed to open new-save settings");
|
||||
}
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
const GameModeDesc gameModeDesc = {
|
||||
.struct_size = sizeof(GameModeDesc),
|
||||
.game_mode_id = "my-game-mode-id",
|
||||
.full_name = "My Game Mode",
|
||||
.save_name = "my-unique-save",
|
||||
.on_new_save_select = on_new_save_select,
|
||||
};
|
||||
svc_game_mode->register_game_mode(mod_ctx, &gameModeDesc);
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hooking Game Functions
|
||||
@@ -670,6 +960,11 @@ For reference parameters (e.g. `const cXyz& pos`), `arg_ref<cXyz>` yields a dire
|
||||
|
||||
Files placed under `overlay/` in the `.dusk` archive override game files at the corresponding path, equivalent to
|
||||
replacing files in the .iso. This requires no code: an archive with just `mod.json` and `overlay/` is a complete mod.
|
||||
To replace a file within an `.arc` archive, replace the archive suffix with a directory and place the replacement at
|
||||
its path within the archive.
|
||||
|
||||
- `overlay/Audiores/Stream/menu_select.ast` replaces the main title's audio stream.
|
||||
- `overlay/res/Layout/main2D/main2d/timg/midona64.bti` replaces Midna's UI icon inside `main2D.arc`.
|
||||
|
||||
Files placed under `textures/` register as texture replacements, and act just like the user's general
|
||||
`texture_replacements/` directory: Dolphin-style naming, matched by texture hash
|
||||
@@ -845,6 +1140,6 @@ 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.
|
||||
`mod_shutdown`. Do not write into `native_dir`; use `data_dir` for persistent storage or `mod_dir` for temporary
|
||||
(session) storage. 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.
|
||||
|
||||
Vendored
+1
-1
Submodule extern/aurora updated: 0bddb86249...2c9c95cfed
+1
Submodule extern/borealis added at 6fd955e7e6
+29
-29
@@ -1412,6 +1412,7 @@ set(DOLPHIN_FILES
|
||||
|
||||
set(DUSK_FILES
|
||||
include/helpers/batch.hpp
|
||||
include/helpers/bits.hpp
|
||||
include/helpers/endian_gx.hpp
|
||||
src/d/actor/d_a_alink_dusk.cpp
|
||||
src/dusk/OSContext.cpp
|
||||
@@ -1421,30 +1422,23 @@ set(DUSK_FILES
|
||||
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/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/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/game_mode.cpp
|
||||
src/dusk/gamepad_color.cpp
|
||||
src/dusk/globals.cpp
|
||||
src/dusk/gyro.cpp
|
||||
src/dusk/http/http.hpp
|
||||
src/dusk/hq_minimap.cpp
|
||||
src/dusk/imgui/ImGuiActorSpawner.cpp
|
||||
src/dusk/imgui/ImGuiBloomWindow.cpp
|
||||
src/dusk/imgui/ImGuiBloomWindow.hpp
|
||||
@@ -1465,6 +1459,8 @@ set(DUSK_FILES
|
||||
src/dusk/imgui/ImGuiStubLog.cpp
|
||||
src/dusk/io.cpp
|
||||
src/dusk/iso_validate.cpp
|
||||
src/dusk/language.cpp
|
||||
src/dusk/language.hpp
|
||||
src/dusk/layout.cpp
|
||||
src/dusk/livesplit.cpp
|
||||
src/dusk/logging.cpp
|
||||
@@ -1481,27 +1477,23 @@ set(DUSK_FILES
|
||||
src/dusk/mods/loader/native_module.hpp
|
||||
src/dusk/mods/loader/prepatch.cpp
|
||||
src/dusk/mods/loader/prepatch.hpp
|
||||
src/dusk/mods/item.hpp
|
||||
src/dusk/mods/item_checks.cpp
|
||||
src/dusk/mods/item_gives.cpp
|
||||
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/audio_res/audio_res.hpp
|
||||
src/dusk/mods/svc/audio_res/audio_res.cpp
|
||||
src/dusk/mods/svc/audio_res/bst.cpp
|
||||
src/dusk/mods/svc/audio_res/bst.hpp
|
||||
src/dusk/mods/svc/audio_res/wsys.cpp
|
||||
src/dusk/mods/svc/audio_res/wsys.hpp
|
||||
src/dusk/mods/svc/audio_res/wave.cpp
|
||||
src/dusk/mods/svc/audio_res/opus.cpp
|
||||
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/flow.cpp
|
||||
src/dusk/mods/svc/hook.cpp
|
||||
src/dusk/mods/svc/host.cpp
|
||||
src/dusk/mods/svc/id_allocator.cpp
|
||||
src/dusk/mods/svc/id_allocator.hpp
|
||||
src/dusk/mods/svc/item.cpp
|
||||
src/dusk/mods/svc/item.hpp
|
||||
src/dusk/mods/svc/log.cpp
|
||||
src/dusk/mods/svc/overlay.cpp
|
||||
src/dusk/mods/svc/registry.cpp
|
||||
@@ -1510,9 +1502,16 @@ set(DUSK_FILES
|
||||
src/dusk/mods/svc/texture.cpp
|
||||
src/dusk/mods/svc/ui.cpp
|
||||
src/dusk/mods/svc/ui.hpp
|
||||
src/dusk/mods/svc/game_mode.cpp
|
||||
src/dusk/mods/svc/window.cpp
|
||||
src/dusk/mods/svc/window.hpp
|
||||
src/dusk/mods/svc/save.cpp
|
||||
src/dusk/mods/svc/save.hpp
|
||||
src/dusk/mods/svc/stage.cpp
|
||||
src/dusk/mods/svc/stage.hpp
|
||||
src/dusk/mouse.cpp
|
||||
src/dusk/presentation.cpp
|
||||
src/dusk/presentation.hpp
|
||||
src/dusk/scope_guard.hpp
|
||||
src/dusk/settings.cpp
|
||||
src/dusk/speedrun.cpp
|
||||
@@ -1526,6 +1525,8 @@ set(DUSK_FILES
|
||||
src/dusk/ui/bool_button.hpp
|
||||
src/dusk/ui/button.cpp
|
||||
src/dusk/ui/button.hpp
|
||||
src/dusk/ui/color_input.cpp
|
||||
src/dusk/ui/color_input.hpp
|
||||
src/dusk/ui/component.cpp
|
||||
src/dusk/ui/component.hpp
|
||||
src/dusk/ui/controller_config.cpp
|
||||
@@ -1539,12 +1540,16 @@ set(DUSK_FILES
|
||||
src/dusk/ui/event.hpp
|
||||
src/dusk/ui/graphics_tuner.cpp
|
||||
src/dusk/ui/graphics_tuner.hpp
|
||||
src/dusk/ui/group_button.cpp
|
||||
src/dusk/ui/group_button.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/list.cpp
|
||||
src/dusk/ui/list.hpp
|
||||
src/dusk/ui/menu_bar.cpp
|
||||
src/dusk/ui/menu_bar.hpp
|
||||
src/dusk/ui/mod_texture_provider.cpp
|
||||
@@ -1556,12 +1561,16 @@ set(DUSK_FILES
|
||||
src/dusk/ui/mods_window.cpp
|
||||
src/dusk/ui/mods_window.hpp
|
||||
src/dusk/ui/nav_types.hpp
|
||||
src/dusk/ui/nav_group.cpp
|
||||
src/dusk/ui/nav_group.hpp
|
||||
src/dusk/ui/number_button.cpp
|
||||
src/dusk/ui/number_button.hpp
|
||||
src/dusk/ui/overlay.cpp
|
||||
src/dusk/ui/overlay.hpp
|
||||
src/dusk/ui/pane.cpp
|
||||
src/dusk/ui/pane.hpp
|
||||
src/dusk/ui/popover.cpp
|
||||
src/dusk/ui/popover.hpp
|
||||
src/dusk/ui/prelaunch.cpp
|
||||
src/dusk/ui/prelaunch.hpp
|
||||
src/dusk/ui/preset.cpp
|
||||
@@ -1588,19 +1597,10 @@ set(DUSK_FILES
|
||||
src/dusk/ui/warp.hpp
|
||||
src/dusk/ui/window.cpp
|
||||
src/dusk/ui/window.hpp
|
||||
src/dusk/update_check.cpp
|
||||
src/dusk/update_check.hpp
|
||||
src/dusk/version.cpp
|
||||
src/dusk/utilities.cpp
|
||||
src/helpers/batch.cpp
|
||||
src/helpers/endian.cpp
|
||||
src/helpers/offset_ptr.cpp
|
||||
src/helpers/string.cpp
|
||||
src/helpers/cast.cpp
|
||||
)
|
||||
|
||||
set(DUSK_HTTP_BACKEND_FILES
|
||||
src/dusk/http/no_backend.cpp
|
||||
src/dusk/http/curl.cpp
|
||||
src/dusk/http/winhttp.cpp
|
||||
src/dusk/http/url_session.mm
|
||||
)
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
ninjaFlags = [ "dusklight" ];
|
||||
|
||||
cmakeFlags = [
|
||||
"-DDUSK_VERSION_OVERRIDE=${versionSuffix}"
|
||||
"-DBOREALIS_APP_VERSION_OVERRIDE=${versionSuffix}"
|
||||
"-DFETCHCONTENT_FULLY_DISCONNECTED=ON"
|
||||
"-DAURORA_DAWN_PROVIDER=package"
|
||||
"-DAURORA_DAWN_LINKAGE=static"
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "JSystem/JAudio2/JAUAudibleParam.h"
|
||||
#include "JSystem/TPosition3.h"
|
||||
|
||||
#define Z2_AUDIO_PLAYERS 1
|
||||
|
||||
struct Z2Audible;
|
||||
|
||||
struct Z2AudibleAbsPos {
|
||||
@@ -51,14 +49,10 @@ struct Z2AudioCamera {
|
||||
f32 getCamDist() const { return mCamDist; }
|
||||
|
||||
|
||||
/* 0x00 */ JGeometry::TPosition3f32 mViewMatrix;
|
||||
/* 0x00 */ JGeometry::TPosition3f32 field_0x0;
|
||||
/* 0x30 */ JGeometry::TVec3<f32> mVel;
|
||||
/* 0x3C */ JGeometry::TVec3<f32> mPos;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/* 0x48 */ JGeometry::TVec3<f32> mLastPos;
|
||||
/* 0x48 */ JGeometry::TVec3<f32> field_0x48;
|
||||
/* 0x54 */ f32 mFovySin;
|
||||
/* 0x58 */ f32 mVolCenterZ;
|
||||
/* 0x5C */ f32 mTargetVolume;
|
||||
@@ -89,14 +83,14 @@ struct Z2SpotMic {
|
||||
/* 0x04 */ f32 field_0x4;
|
||||
/* 0x08 */ f32 field_0x8;
|
||||
/* 0x0C */ f32 field_0xc;
|
||||
/* 0x10 */ Z2AudioCamera* field_0x10[Z2_AUDIO_PLAYERS];
|
||||
/* 0x10 */ Z2AudioCamera* field_0x10[1];
|
||||
/* 0x14 */ Vec* mPosPtr;
|
||||
/* 0x18 */ f32 field_0x18[Z2_AUDIO_PLAYERS];
|
||||
/* 0x18 */ f32 field_0x18[1];
|
||||
/* 0x1C */ f32 field_0x1c;
|
||||
/* 0x20 */ f32 field_0x20[Z2_AUDIO_PLAYERS];
|
||||
/* 0x20 */ f32 field_0x20[1];
|
||||
/* 0x24 */ bool mIgnoreIfOut;
|
||||
/* 0x25 */ bool mMicOn;
|
||||
/* 0x26 */ bool field_0x26[Z2_AUDIO_PLAYERS];
|
||||
/* 0x26 */ bool field_0x26[1];
|
||||
}; // Size: 0x28
|
||||
|
||||
struct Z2Audience3DSetting {
|
||||
@@ -108,99 +102,62 @@ struct Z2Audience3DSetting {
|
||||
void updateDolbyDist(f32, f32);
|
||||
|
||||
void calcVolumeFactorAll() {
|
||||
mDistanceMaxes[1] = 1.25f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[2] = 1.5f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[3] = 2.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[4] = 3.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[5] = 4.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[6] = 6.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[7] = 8.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[8] = 0.9f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[9] = 0.8f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[10] = 0.7f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[11] = 0.6f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[12] = 0.5f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[13] = 0.4f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[14] = 0.3f * mDistanceMaxes[0];
|
||||
field_0x0[1] = 1.25f * field_0x0[0];
|
||||
field_0x0[2] = 1.5f * field_0x0[0];
|
||||
field_0x0[3] = 2.0f * field_0x0[0];
|
||||
field_0x0[4] = 3.0f * field_0x0[0];
|
||||
field_0x0[5] = 4.0f * field_0x0[0];
|
||||
field_0x0[6] = 6.0f * field_0x0[0];
|
||||
field_0x0[7] = 8.0f * field_0x0[0];
|
||||
field_0x0[8] = 0.9f * field_0x0[0];
|
||||
field_0x0[9] = 0.8f * field_0x0[0];
|
||||
field_0x0[10] = 0.7f * field_0x0[0];
|
||||
field_0x0[11] = 0.6f * field_0x0[0];
|
||||
field_0x0[12] = 0.5f * field_0x0[0];
|
||||
field_0x0[13] = 0.4f * field_0x0[0];
|
||||
field_0x0[14] = 0.3f * field_0x0[0];
|
||||
for (int i = 0; i < 15; i++) {
|
||||
mVolumeFactor[i] = (mMinDistanceVolume - 1.0f) / (mDistanceMaxes[i] - mMaxVolumeDistance);
|
||||
field_0x70[i] = (field_0x40 - 1.0f) / (field_0x0[i] - field_0x3c);
|
||||
}
|
||||
}
|
||||
|
||||
void calcPriorityFactorAll() {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
mPriorityFactor[i] = mMaxDistancePriority / (mDistanceMaxes[i] - mMaxVolumeDistance);
|
||||
field_0xac[i] = field_0x64 / (field_0x0[i] - field_0x3c);
|
||||
}
|
||||
}
|
||||
|
||||
void calcFxMixFactorAll() {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
mFxMixFactor[i] = (mMaxDistanceFxMix - mMinDistanceFxMix) / (mDistanceMaxes[i] - mMaxVolumeDistance);
|
||||
field_0xe8[i] = (field_0x54 - field_0x50) / (field_0x0[i] - field_0x3c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum distance a sound can reach before being "far away"
|
||||
* Being far away affects stuff like culling, lowering its priority, forcibly stopping it, etc.
|
||||
* Sounds select which entry they use based on their VolBits.
|
||||
*/
|
||||
/* 0x000 */ f32 mDistanceMaxes[15];
|
||||
|
||||
/**
|
||||
* Distance at which the max volume of a sound is reached.
|
||||
* i.e. sounds do *not* get louder if they get closer than this.
|
||||
*/
|
||||
/* 0x03C */ f32 mMaxVolumeDistance;
|
||||
|
||||
/**
|
||||
* FX Mix value at maximum distance (@ref mDistanceMaxes)
|
||||
*/
|
||||
/* 0x040 */ f32 mMinDistanceVolume;
|
||||
/* 0x044 */ f32 mDolbyFrontDistanceMax;
|
||||
/* 0x048 */ f32 mDolbyBehindDistanceMax;
|
||||
/* 0x04C */ f32 mDolbyCenterValue;
|
||||
|
||||
/**
|
||||
* FX Mix value at minimum distance (@ref mMaxVolumeDistance)
|
||||
*/
|
||||
/* 0x050 */ f32 mMinDistanceFxMix;
|
||||
|
||||
/**
|
||||
* FX Mix value at maximum distance (@ref mDistanceMaxes)
|
||||
*/
|
||||
/* 0x054 */ f32 mMaxDistanceFxMix;
|
||||
/* 0x058 */ f32 mPanFactor;
|
||||
/* 0x05C */ f32 mSonicSpeed; // Used for doppler effect calculations.
|
||||
/* 0x000 */ f32 field_0x0[15];
|
||||
/* 0x03C */ f32 field_0x3c;
|
||||
/* 0x040 */ f32 field_0x40;
|
||||
/* 0x044 */ f32 field_0x44;
|
||||
/* 0x048 */ f32 field_0x48;
|
||||
/* 0x04C */ f32 field_0x4c;
|
||||
/* 0x050 */ f32 field_0x50;
|
||||
/* 0x054 */ f32 field_0x54;
|
||||
/* 0x058 */ f32 field_0x58;
|
||||
/* 0x05C */ f32 field_0x5c;
|
||||
/* 0x060 */ f32 field_0x60;
|
||||
|
||||
/**
|
||||
* Priority that sounds receive when "far away".
|
||||
* @see mDistanceMaxes
|
||||
*/
|
||||
/* 0x064 */ u32 mMaxDistancePriority;
|
||||
/* 0x064 */ u32 field_0x64;
|
||||
/* 0x068 */ f32 field_0x68;
|
||||
/* 0x06C */ f32 field_0x6c;
|
||||
/* 0x070 */ f32 mVolumeFactor[15];
|
||||
/* 0x0AC */ f32 mPriorityFactor[15];
|
||||
/* 0x0E8 */ f32 mFxMixFactor[15];
|
||||
/* 0x070 */ f32 field_0x70[15];
|
||||
/* 0x0AC */ f32 field_0xac[15];
|
||||
/* 0x0E8 */ f32 field_0xe8[15];
|
||||
/* 0x124 */ bool mVolumeDistInit;
|
||||
/* 0x125 */ bool mDolbyDistInit;
|
||||
}; // Size: 0x128
|
||||
|
||||
struct Z2AudibleRelPos {
|
||||
/* 0x00 */ JGeometry::TVec3<f32> mCameraRelative;
|
||||
|
||||
/**
|
||||
* Distance from mCameraRelative. This is from the object root and not the
|
||||
* exact distance used for volume/priority calculations.
|
||||
*/
|
||||
/* 0x0C */ f32 mTrueDistance;
|
||||
|
||||
/**
|
||||
* Distance from mCameraRelative but offset by mVolCenterZ.
|
||||
* This presumably means the distance is more centered on the object than mTrueDistance.
|
||||
*/
|
||||
/* 0x10 */ f32 mCenterDistance;
|
||||
/* 0x00 */ JGeometry::TVec3<f32> field_0x00;
|
||||
/* 0x0C */ f32 field_0xC;
|
||||
/* 0x10 */ f32 field_0x10;
|
||||
};
|
||||
|
||||
struct Z2AudibleChannel {
|
||||
@@ -214,7 +171,7 @@ struct Z2AudibleChannel {
|
||||
}
|
||||
|
||||
/* 0x00 */ JASSoundParams mParams;
|
||||
/* 0x14 */ Z2AudibleRelPos mRelPos;
|
||||
/* 0x14 */ Z2AudibleRelPos field_0x14;
|
||||
/* 0x28 */ f32 field_0x28;
|
||||
/* 0x2c */ f32 mPan;
|
||||
/* 0x30 */ f32 mDolby;
|
||||
@@ -243,8 +200,8 @@ struct Z2Audible : public JAIAudible, public JASPoolAllocObject<Z2Audible> {
|
||||
|
||||
/* 0x10 */ JAUAudibleParam mParam;
|
||||
/* 0x14 */ Z2AudibleAbsPos mAbsPos;
|
||||
/* 0x2C */ Z2AudibleChannel mChannel[Z2_AUDIO_PLAYERS];
|
||||
/* 0x64 */ f32 mMicDistances[Z2_AUDIO_PLAYERS];
|
||||
/* 0x2C */ Z2AudibleChannel mChannel[1];
|
||||
/* 0x64 */ f32 field_0x64[1];
|
||||
};
|
||||
|
||||
struct Z2Audience : public JAIAudience, public JASGlobalInstance<Z2Audience> {
|
||||
@@ -266,8 +223,7 @@ struct Z2Audience : public JAIAudience, public JASGlobalInstance<Z2Audience> {
|
||||
|
||||
virtual ~Z2Audience();
|
||||
virtual JAIAudible* newAudible(const JGeometry::TVec3<f32>& pos, JAISoundID soundID,
|
||||
const JGeometry::TVec3<f32>*, u32
|
||||
IF_DUSK_ARG(dusk::mods::svc::audio_res::bst::SoundTableReplacementSlot const*));
|
||||
const JGeometry::TVec3<f32>*, u32);
|
||||
virtual int getMaxChannels();
|
||||
virtual void deleteAudible(JAIAudible* audible);
|
||||
virtual u32 calcPriority(JAIAudible* audible);
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
s32 getBgmLoadStatus(u32 wave) { return getWaveLoadStatus(wave, 1); }
|
||||
u8 getDemoSeWaveNum() { return loadedDemoWave; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x00 */ JAISoundID BGM_ID;
|
||||
/* 0x04 */ int sceneNum;
|
||||
/* 0x08 */ int timer;
|
||||
|
||||
@@ -6,29 +6,23 @@
|
||||
#include "JSystem/JAudio2/JAUSoundInfo.h"
|
||||
#include "JSystem/JAudio2/JAUSoundTable.h"
|
||||
|
||||
#define STRM_CH_SHIFT_ 2
|
||||
|
||||
#define STRM_CH_CENTER 1
|
||||
#define STRM_CH_LEFT 2
|
||||
#define STRM_CH_RIGHT 3
|
||||
|
||||
class Z2SoundInfo : public JAISoundInfo, public JAUSoundInfo, public JAIStreamDataMgr, public JASGlobalInstance<Z2SoundInfo> {
|
||||
public:
|
||||
Z2SoundInfo() : JAISoundInfo(true), JAUSoundInfo(true), JASGlobalInstance<Z2SoundInfo>(true) {}
|
||||
virtual u16 getAudibleSw(JAISoundID soundID IF_DUSK_ARG(SoundTableReplacementSlot const* replacement)) const;
|
||||
virtual u16 getAudibleSw(JAISoundID soundID) const;
|
||||
virtual u16 getBgmSeqResourceID(JAISoundID soundID) const;
|
||||
virtual s32 getStreamFileEntry(JAISoundID soundID IF_DUSK_ARG(StreamReplacementSlot const* replacement));
|
||||
virtual s32 getStreamFileEntry(JAISoundID soundID);
|
||||
virtual int getSoundType(JAISoundID soundID) const;
|
||||
virtual int getCategory(JAISoundID soundID) const;
|
||||
virtual u32 getPriority(JAISoundID soundID IF_DUSK_ARG(SoundTableReplacementSlot const* replacement)) const;
|
||||
virtual void getSeInfo(JAISoundID soundID, JAISe* sePtr IF_DUSK_ARG(SoundEffectReplacementSlot const* replacement)) const;
|
||||
virtual u32 getPriority(JAISoundID soundID) const;
|
||||
virtual void getSeInfo(JAISoundID soundID, JAISe* sePtr) const;
|
||||
virtual void getSeqInfo(JAISoundID soundID, JAISeq* seqPtr) const;
|
||||
virtual void getStreamInfo(JAISoundID soundID, JAIStream* streamPtr IF_DUSK_ARG(StreamReplacementSlot const* replacement)) const;
|
||||
virtual void getStreamInfo(JAISoundID soundID, JAIStream* streamPtr) const;
|
||||
virtual ~Z2SoundInfo() {}
|
||||
|
||||
JAUAudibleParam getAudibleSwFull(JAISoundID soundID IF_DUSK_ARG(SoundTableReplacementSlot const* replacement));
|
||||
const char* getStreamFilePath(JAISoundID soundID IF_DUSK_ARG(StreamReplacementSlot const* replacement));
|
||||
int getSwBit(JAISoundID soundID IF_DUSK_ARG(SoundTableReplacementSlot const* replacement)) const;
|
||||
JAUAudibleParam getAudibleSwFull(JAISoundID soundID);
|
||||
const char* getStreamFilePath(JAISoundID soundID);
|
||||
int getSwBit(JAISoundID soundID) const;
|
||||
void getSoundInfo_(JAISoundID soundID, JAISound* soundPtr) const;
|
||||
|
||||
BOOL isValid() const {
|
||||
|
||||
@@ -42,7 +42,7 @@ private:
|
||||
/* 0x004 */ JAISeMgr seMgr_;
|
||||
/* 0x728 */ JAISeqMgr seqMgr_;
|
||||
/* 0x79C */ JAIStreamMgr streamMgr_;
|
||||
/* 0x80C */ JAISoundID bgmMuter;
|
||||
/* 0x80C */ JAISoundID soundID_;
|
||||
}; // Size: 0x810
|
||||
|
||||
#if VERSION != VERSION_SHIELD_DEBUG
|
||||
|
||||
@@ -8449,8 +8449,10 @@ struct daAlink_cutHorseParamTbl {
|
||||
/* 0xA */ u8 m_cutType;
|
||||
}; // Size: 0xC
|
||||
|
||||
#if !TARGET_PC
|
||||
inline BOOL dComIfGs_isTransformLV(int i_no);
|
||||
inline BOOL dComIfGs_isEventBit(const u16);
|
||||
#endif
|
||||
|
||||
static fopAc_ac_c* daAlink_searchPortal(fopAc_ac_c* i_actor, void* i_data);
|
||||
static fopAc_ac_c* daAlink_searchCanoe(fopAc_ac_c* i_actor, void* i_data);
|
||||
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
bool checkFlag(u16 flag) { return field_0x68e & flag; }
|
||||
void setAction(u8 action) { mAction = action; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x56C */ request_of_phase_process_class mPhase1;
|
||||
/* 0x574 */ request_of_phase_process_class mPhase2;
|
||||
/* 0x57C */ J3DModel* mModel1;
|
||||
|
||||
@@ -96,6 +96,9 @@ public:
|
||||
/* 0xDE0 */ cXyz field_0xde0;
|
||||
/* 0xDEC */ u8 field_0xdec[0xdf9 - 0xdec];
|
||||
/* 0xDF9 */ u8 field_0xdf9;
|
||||
#if TARGET_PC
|
||||
bool mItemCheckHandled;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(daE_HP_c) == 0xdfc);
|
||||
|
||||
@@ -32,6 +32,12 @@ struct daItemBase_data {
|
||||
class daItemBase_c : public fopAc_ac_c {
|
||||
public:
|
||||
u8 getItemNo();
|
||||
#if TARGET_PC
|
||||
u8 getDisplayItemNo() const {
|
||||
return mDisplayItemNo != 0xFF ? mDisplayItemNo : m_itemNo;
|
||||
}
|
||||
void setDisplayItemNo(u8 itemNo) { mDisplayItemNo = itemNo; }
|
||||
#endif
|
||||
void hide();
|
||||
void show();
|
||||
void changeDraw();
|
||||
@@ -79,6 +85,9 @@ public:
|
||||
/* 0x928 */ s16 m_get_timer;
|
||||
/* 0x92A */ u8 m_itemNo;
|
||||
/* 0x92B */ u8 field_0x92b;
|
||||
#if TARGET_PC
|
||||
u8 mDisplayItemNo = 0xFF;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* D_A_D_A_ITEMBASE_H */
|
||||
|
||||
@@ -423,7 +423,7 @@ public:
|
||||
static DUSK_GAME_DATA daMidna_texData_s const m_texDataTable[21];
|
||||
static DUSK_GAME_DATA daMidna_anmData_s const m_anmDataTable[53];
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhase;
|
||||
/* 0x570 */ J3DModel* mpModel;
|
||||
/* 0x574 */ J3DModel* mpShadowModel;
|
||||
|
||||
@@ -296,7 +296,7 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mCutNameList[18];
|
||||
static DUSK_GAME_DATA cutFunc DUSK_CONST mCutList[18];
|
||||
private:
|
||||
// private:
|
||||
/* 0x0E40 */ NPC_FAIRY_HIO_CLASS* mHIO;
|
||||
/* 0x0E44 */ dCcD_Cyl mCyl;
|
||||
/* 0x0F80 */ u8 mType;
|
||||
|
||||
@@ -287,7 +287,7 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mCutNameList[10];
|
||||
static DUSK_GAME_DATA cutFunc DUSK_CONST mCutList[10];
|
||||
private:
|
||||
// private:
|
||||
/* 0x0E40 */ mDoExt_McaMorfSO* mFishModelMorf;
|
||||
/* 0x0E44 */ mDoExt_McaMorfSO* mLeafModelMorf;
|
||||
/* 0x0E48 */ NPC_YKM_HIO_CLASS* mpHIO;
|
||||
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mEvtCutNameList[2];
|
||||
static DUSK_GAME_DATA EventFn DUSK_CONST mEvtCutList[2];
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0xB48 */ Z2Creature mCreatureSound;
|
||||
/* 0xBD8 */ daNpcF_MatAnm_c* mpMatAnm;
|
||||
/* 0xBDC */ daNpcF_Lookat_c mLookat;
|
||||
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
void himoCalc();
|
||||
void adjustShapeAngle() {}
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x0B48 */ Z2Creature mCreatureSound;
|
||||
/* 0x0BD8 */ daNpcF_MatAnm_c* mpMatAnm;
|
||||
/* 0x0BDC */ mDoExt_invisibleModel mInvisibleModel;
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
bool isFirst() { return fopAcM_GetParamBit(this, 0x1b, 1); }
|
||||
void setAction(u8 action) { mAction = action; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x570 */ J3DModel* mpModel;
|
||||
/* 0x574 */ mDoExt_btkAnm* mpBtkAnm[2];
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
current.pos = new_pos;
|
||||
}
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x92C */ fpc_ProcID mItemId;
|
||||
/* 0x930 */ int mCounter;
|
||||
/* 0x934 */ u8 mStatus;
|
||||
@@ -88,6 +88,12 @@ private:
|
||||
/* 0x99C */ dPa_followEcallBack mEffect2;
|
||||
/* 0x9B0 */ Z2SoundObjSimple mSound;
|
||||
/* 0x9D0 */ u8 mIsHookCarry;
|
||||
#if TARGET_PC
|
||||
u8 mOriginalItemNo;
|
||||
bool mItemOverridden;
|
||||
bool mOverrideHover;
|
||||
bool mGoldenWolfItem;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(daObjLife_c) == 0x9d4);
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
static DUSK_GAME_DATA daObjMasterSword_Attr_c const mAttr;
|
||||
static DUSK_GAME_DATA actionFunc ActionTable[];
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x568 */ J3DModel* mpModel;
|
||||
/* 0x56C */ request_of_phase_process_class mPhase;
|
||||
/* 0x574 */ mDoExt_btkAnm mBtk;
|
||||
|
||||
@@ -311,9 +311,11 @@ private:
|
||||
class daMidna_c;
|
||||
class daSpinner_c;
|
||||
class daPy_py_c;
|
||||
#if !TARGET_PC
|
||||
inline daPy_py_c* dComIfGp_getLinkPlayer();
|
||||
inline BOOL dComIfGs_isEventBit(const u16);
|
||||
inline u32 dComIfGs_getLastSceneMode();
|
||||
#endif
|
||||
|
||||
class daPy_py_c : public fopAc_ac_c {
|
||||
public:
|
||||
|
||||
@@ -194,6 +194,9 @@ private:
|
||||
/* 0x9FC */ u8 field_0x9fc;
|
||||
/* 0x9FD */ u8 field_0x9fd;
|
||||
/* 0xA00 */ Mtx mDrawMtx;
|
||||
#if TARGET_PC
|
||||
u8 mOriginalItemNo;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(daTbox_c) == 0xA30);
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
u8 getModelType() { return fopAcM_GetParamBit(this, 8, 4); }
|
||||
u8 getItemNo() { return fopAcM_GetParamBit(this, 0, 8); }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x718 */ u8 mReturnRupee;
|
||||
/* 0x71C */ request_of_phase_process_class mPhase;
|
||||
/* 0x724 */ J3DModel* mpModel;
|
||||
@@ -83,6 +83,10 @@ private:
|
||||
/* 0xAC0 */ u8 field_0xAC0[0xAC4 - 0xAC0];
|
||||
/* 0xAC4 */ int mStaffIdx;
|
||||
/* 0xAC8 */ dBgW* mBoxBgW;
|
||||
#if TARGET_PC
|
||||
bool mParamsInit;
|
||||
u8 mOriginalItemNo;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(daTbox2_c) == 0xACC);
|
||||
|
||||
@@ -145,6 +145,10 @@ public:
|
||||
/* 0x9BC */ u8 field_0x9bc[4];
|
||||
/* 0x9C0 */ u8 field_0x9c0;
|
||||
/* 0x9C1 */ u8 field_0x9c1;
|
||||
#if TARGET_PC
|
||||
u8 mOriginalItemNo;
|
||||
bool mItemOverridden;
|
||||
#endif
|
||||
}; // Size: 0x9C4
|
||||
|
||||
#endif /* D_A_D_A_ITEM_STATIC_H */
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
#ifndef D_A_D_A_ITEMBASE_STATIC_H
|
||||
#define D_A_D_A_ITEMBASE_STATIC_H
|
||||
|
||||
#include "dolphin/types.h"
|
||||
|
||||
class fopAc_ac_c;
|
||||
|
||||
int CheckFieldItemCreateHeap(fopAc_ac_c* actor);
|
||||
int CheckItemCreateHeap(fopAc_ac_c* i_this);
|
||||
|
||||
#if TARGET_PC
|
||||
const char* dItem_fieldModelArc(u8 itemNo);
|
||||
#endif
|
||||
|
||||
#endif /* D_A_D_A_ITEMBASE_STATIC_H */
|
||||
|
||||
@@ -50,6 +50,9 @@ public:
|
||||
csXyz* getRotateP();
|
||||
cXyz* getPosP();
|
||||
const char* getShopArcname();
|
||||
#if TARGET_PC
|
||||
const ResourceData& getResourceData() const;
|
||||
#endif
|
||||
u16 getHeapSize();
|
||||
void CreateInit();
|
||||
void set_mtx();
|
||||
@@ -110,6 +113,10 @@ private:
|
||||
/* 0x960 */ s16 mAngleX;
|
||||
/* 0x962 */ s16 mAngleY;
|
||||
/* 0x964 */ u8 mShopItemID;
|
||||
#if TARGET_PC
|
||||
ResourceData mOverrideData;
|
||||
bool mItemOverridden;
|
||||
#endif
|
||||
};
|
||||
|
||||
int CheckShopItemCreateHeap(fopAc_ac_c* i_this);
|
||||
|
||||
+934
-78
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,7 @@ public:
|
||||
CPaneMgrAlpha* getNoDatBase() { return mNoDatBase; }
|
||||
void draw() { _draw(); }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x04 */ JKRArchive* mArchive;
|
||||
/* 0x08 */ dDlst_FileInfo_c mFileInfo;
|
||||
/* 0x1C */ u8 field_0x1c[4];
|
||||
|
||||
+13
-33
@@ -9,42 +9,13 @@
|
||||
#include "JSystem/J3DGraphLoader/J3DModelLoader.h"
|
||||
#include "JSystem/J3DGraphLoader/J3DAnmLoader.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "mods/svc/game_mode.h"
|
||||
#endif
|
||||
|
||||
class dFile_info_c;
|
||||
class J2DPicture;
|
||||
|
||||
#if TARGET_PC
|
||||
static PaneCache mSelDtPanes[] = {
|
||||
{MULTI_CHAR('tate_n0'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('tate_n1'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('ken_n0'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('ken_n1'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('fuku_n0'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('fuku_n1'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('fuku_n2'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('gray_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('b_base'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('b_base1'), 0.0f, 0.0f, false},
|
||||
};
|
||||
|
||||
static PaneCache fileSelPanes[] = {
|
||||
{MULTI_CHAR('w_uzu00'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu01'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu02'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu03'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu04'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu05'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu06'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu07'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu08'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_uzu09'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_er_msg'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_er_msE'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_er_msR'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('er_for0'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('er_for1'), 0.0f, 0.0f, false},
|
||||
};
|
||||
#endif
|
||||
|
||||
class dDlst_FileSel_c : public dDlst_base_c {
|
||||
public:
|
||||
void draw();
|
||||
@@ -420,6 +391,13 @@ public:
|
||||
bool pointerMenuSelect();
|
||||
bool pointerCopyDataToSelect();
|
||||
bool pointerYesNoSelect(bool errorSelect);
|
||||
void backToDataSelectMove() {
|
||||
headerTxtSet(0x43, 1, 0);
|
||||
fileRecScaleAnmInitSet2(0.0f, 1.0f);
|
||||
nameMoveAnmInitSet(0xd29, 0xd1f);
|
||||
modoruTxtDispAnmInit(0);
|
||||
mDataSelProc = DATASELPROC_NAME_TO_DATA_SELECT_MOVE;
|
||||
}
|
||||
#endif
|
||||
void _draw();
|
||||
void errorMoveAnmInitSet(int, int);
|
||||
@@ -733,6 +711,8 @@ public:
|
||||
#endif
|
||||
#ifdef TARGET_PC
|
||||
dDlst_FileSelFade_c mFadeDlst;
|
||||
bool mGameModeSaveStartBuildUi = true;
|
||||
GameModeNewSaveState mGameModeNewSaveState = GAME_MODE_STATE_PENDING;
|
||||
#endif
|
||||
|
||||
#if PLATFORM_WII || PLATFORM_SHIELD
|
||||
|
||||
+3
-1
@@ -11,7 +11,9 @@ public:
|
||||
static DUSK_GAME_DATA u8* mData;
|
||||
};
|
||||
|
||||
void execItemGet(u8 item_id);
|
||||
class fopAc_ac_c;
|
||||
void execItemGet(
|
||||
u8 item_id IF_DUSK_ARG(u32 item_give_tag = 0) IF_DUSK_ARG(fopAc_ac_c* giver = NULL));
|
||||
|
||||
void item_func_HEART();
|
||||
void item_func_GREEN_RUPEE();
|
||||
|
||||
@@ -142,7 +142,12 @@ enum {
|
||||
/* 0x2F */ dItemNo_WEAR_KOKIRI_e,
|
||||
/* 0x30 */ dItemNo_ARMOR_e,
|
||||
/* 0x31 */ dItemNo_WEAR_ZORA_e,
|
||||
#if TARGET_PC
|
||||
/* 0x32 */ dItemNo_MAGIC_LV1_e,
|
||||
dItemNo_SHADOW_CRYSTAL_e = dItemNo_MAGIC_LV1_e,
|
||||
#else
|
||||
/* 0x32 */ dItemNo_MAGIC_LV1_e,
|
||||
#endif
|
||||
/* 0x33 */ dItemNo_DUNGEON_EXIT_2_e,
|
||||
/* 0x34 */ dItemNo_WALLET_LV1_e,
|
||||
/* 0x35 */ dItemNo_WALLET_LV2_e,
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
|
||||
void drawSelf() { mpKanteraIcon->draw(); }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x04 */ dDlst_KanteraIcon_c* mpKanteraIcon;
|
||||
/* 0x08 */ CPaneMgr* mpParent;
|
||||
/* 0x0C */ CPaneMgr* mpGauge;
|
||||
|
||||
@@ -15,49 +15,6 @@ class dMenu_Fishing_c;
|
||||
class dMenu_Skill_c;
|
||||
class dMenu_Insect_c;
|
||||
class dSelect_cursor_c;
|
||||
|
||||
#if TARGET_PC
|
||||
struct PaneCache {
|
||||
u64 tag;
|
||||
f32 origTransX;
|
||||
f32 origTransY;
|
||||
bool cached;
|
||||
};
|
||||
|
||||
static PaneCache mpScreenPanes[] = {
|
||||
{MULTI_CHAR('sa_tex_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('op_tex_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('heart_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('wolf_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('item_0_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('item_1_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('item_2_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('fish_3_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('lett_4_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('maki_5_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('fuku_n0'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('fuku_n1'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('fuku_n2'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('tate_n0'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('tate_n1'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('ken_n0'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('ken_n1'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('kabu_6n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('t_t00'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('f_t00'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('itemn_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('infotxtn'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('sa_op_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('title_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('menu_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('w_er_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('center_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('info_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('lavel_n'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('modelbgn'), 0.0f, 0.0f, false},
|
||||
};
|
||||
#endif
|
||||
|
||||
class dMenu_Collect2D_c;
|
||||
class dMenu_Collect2DTop_c : public dDlst_base_c {
|
||||
public:
|
||||
@@ -172,7 +129,7 @@ public:
|
||||
J2DPicture* getBlackTex() { return mpBlackTex; }
|
||||
u8 getSubWindowOpenCheck() { return mSubWindowOpenCheck; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ JKRExpHeap* mpHeap;
|
||||
/* 0x008 */ JKRExpHeap* mpSubHeap;
|
||||
/* 0x00C */ void* field_0xc;
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
u8 getStatus() { return mStatus; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ JKRExpHeap* mpHeap;
|
||||
/* 0x008 */ JKRArchive* mpArchive;
|
||||
/* 0x00C */ STControl* mpStick;
|
||||
|
||||
@@ -270,7 +270,7 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA dMenu_Fmap_c* MyClass;
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ JKRExpHeap* mpHeap;
|
||||
/* 0x008 */ JKRExpHeap* mpTalkHeap;
|
||||
/* 0x00C */ STControl* mpStick;
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
u8 getStatus() { return mStatus; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x04 */ JKRExpHeap* mpHeap;
|
||||
/* 0x08 */ JKRArchive* mpArchive;
|
||||
/* 0x0C */ STControl* mpStick;
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
|
||||
u8 getStatus() { return mStatus; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ JKRExpHeap* mpHeap;
|
||||
/* 0x008 */ JKRArchive* mpArchive;
|
||||
/* 0x00C */ STControl* mpStick;
|
||||
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
return ((u8)mUseFlag & (u8)i_flag) != 0 ? true : false;
|
||||
}
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ J2DScreen* mpBackScreen;
|
||||
/* 0x008 */ J2DScreen* mpScreen;
|
||||
/* 0x00C */ J2DScreen* mpClipScreen;
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
void drawFlag0() { mDrawFlag = 0; }
|
||||
void setStatus(u8 i_status) { mStatus = i_status; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ JKRExpHeap* mpHeap;
|
||||
/* 0x008 */ STControl* mpStick;
|
||||
/* 0x00C */ CSTControl* mpCStick;
|
||||
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
u8 getEndStatus() { return mEndStatus; }
|
||||
void setUseType(u8 type) { mUseType = type; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x0004 */ JKRArchive* mpArchive;
|
||||
/* 0x0008 */ mDoDvdThd_mountArchive_c* mpMount;
|
||||
/* 0x000C */ STControl* stick;
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
u8 getStatus() { return mStatus; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ JKRExpHeap* mpHeap;
|
||||
/* 0x008 */ JKRArchive* mpArchive;
|
||||
/* 0x00C */ STControl* mpStick;
|
||||
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ item_params mItemParams[4];
|
||||
/* 0x074 */ JKRExpHeap* heap;
|
||||
/* 0x078 */ J2DScreen* mpScreen;
|
||||
|
||||
@@ -328,6 +328,150 @@ void dMeter2Info_onWide2D();
|
||||
void dMeter2Info_offWide2D();
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
DUSK_NOINLINE void dMeter2Info_Initialize();
|
||||
DUSK_NOINLINE dMeterMap_c* dMeter2Info_getMeterMapClass();
|
||||
DUSK_NOINLINE dMw_c* dMeter2Info_getMenuWindowClass();
|
||||
DUSK_NOINLINE void dMeter2Info_setWindowStatus(u8 i_status);
|
||||
DUSK_NOINLINE CPaneMgr* dMeter2Info_getMeterItemPanePtr(s32 i_idx);
|
||||
DUSK_NOINLINE void dMeter2Info_getString(
|
||||
u32 i_stringID, TEXT_SPAN o_string, JMSMesgEntry_c* i_msgEntry);
|
||||
DUSK_NOINLINE void dMeter2Info_getStringKanji(
|
||||
u32 i_stringID, TEXT_SPAN o_string, JMSMesgEntry_c* i_msgEntry);
|
||||
DUSK_NOINLINE void dMeter2Info_getStringKana(
|
||||
u32 i_stringID, TEXT_SPAN o_string, JMSMesgEntry_c* i_msgEntry);
|
||||
DUSK_NOINLINE f32 dMeter2Info_getStringLength(
|
||||
JUTFont* i_font, f32 param_2, f32 param_3, char* i_string);
|
||||
DUSK_NOINLINE f32 dMeter2Info_getStringLength(J2DTextBox* i_textbox, char* i_string);
|
||||
DUSK_NOINLINE void dMeter2Info_setHotSpringTimer(u8 i_slotNo);
|
||||
DUSK_NOINLINE u16 dMeter2Info_getOilGaugeBackUp();
|
||||
DUSK_NOINLINE void dMeter2Info_setOilGaugeBackUp(u16 param_1);
|
||||
DUSK_NOINLINE void dMeter2Info_setSaveStageName(const char* i_stageName);
|
||||
DUSK_NOINLINE u8 dMeter2Info_getInsectSelectType();
|
||||
DUSK_NOINLINE void dMeter2Info_setInsectSelectType(u8 i_type);
|
||||
DUSK_NOINLINE u8 dMeter2Info_getWarpStatus();
|
||||
DUSK_NOINLINE void dMeter2Info_setWarpStatus(u8 i_status);
|
||||
DUSK_NOINLINE int dMeter2Info_readItemTexture(u8 i_itemNo, void* i_texBuf1, J2DPicture* i_pic1,
|
||||
void* i_texBuf2, J2DPicture* i_pic2, void* i_texBuf3, J2DPicture* i_pic3, void* i_texBuf4,
|
||||
J2DPicture* i_pic4, int param_9);
|
||||
DUSK_NOINLINE void dMeter2Info_setItemColor(
|
||||
u8 i_itemNo, J2DPicture* i_pic1, J2DPicture* i_pic2, J2DPicture* i_pic3, J2DPicture* i_pic4);
|
||||
DUSK_NOINLINE u8 dMeter2Info_getWarpRoomNo();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getWarpPlayerNo();
|
||||
DUSK_NOINLINE cXyz& dMeter2Info_getWarpPos();
|
||||
DUSK_NOINLINE const char* dMeter2Info_getWarpStageName();
|
||||
DUSK_NOINLINE void dMeter2Info_setNowCount(u8 i_count);
|
||||
DUSK_NOINLINE void dMeter2Info_setMaxCount(u8 i_count);
|
||||
DUSK_NOINLINE BOOL dMeter2Info_isDirectUseItem(int param_0);
|
||||
DUSK_NOINLINE bool dMeter2Info_isUseButton(int i_buttonBit);
|
||||
DUSK_NOINLINE void dMeter2Info_setMeterMapClass(dMeterMap_c* i_map);
|
||||
DUSK_NOINLINE void dMeter2Info_decHotSpringTimer();
|
||||
DUSK_NOINLINE void dMeter2Info_allUseButton();
|
||||
DUSK_NOINLINE void dMeter2Info_offUseButton(int i_buttonBit);
|
||||
DUSK_NOINLINE void dMeter2Info_resetGameStatus();
|
||||
DUSK_NOINLINE void dMeter2Info_onGameStatus(int i_status);
|
||||
DUSK_NOINLINE void dMeter2Info_setMapStatus(u8 i_status);
|
||||
DUSK_NOINLINE u8 dMeter2Info_getMapStatus();
|
||||
DUSK_NOINLINE void dMeter2Info_setPauseStatus(u8 i_status);
|
||||
DUSK_NOINLINE void dMeter2Info_resetPauseStatus();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getPauseStatus();
|
||||
DUSK_NOINLINE bool dMeter2Info_isGameStatus(int i_status);
|
||||
DUSK_NOINLINE bool dMeter2Info_isTouchKeyCheck(int i_status);
|
||||
DUSK_NOINLINE void dMeter2Info_setMapKeyDirection(u16 i_direction);
|
||||
DUSK_NOINLINE bool dMeter2Info_isSub2DStatus(int i_flag);
|
||||
DUSK_NOINLINE void dMeter2Info_offMenuInForce(int i_flag);
|
||||
DUSK_NOINLINE bool dMeter2Info_isMenuInForce(int i_flag);
|
||||
DUSK_NOINLINE void dMeter2Info_setMenuWindowClass(dMw_c* i_menu);
|
||||
DUSK_NOINLINE void dMeter2Info_resetWarpStatus();
|
||||
DUSK_NOINLINE u16 dMeter2Info_getMapKeyDirection();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getWindowStatus();
|
||||
DUSK_NOINLINE void dMeter2Info_setMsgResource(void* i_res);
|
||||
DUSK_NOINLINE void dMeter2Info_setStageMsgResource(void* i_res);
|
||||
DUSK_NOINLINE void dMeter2Info_setMsgUnitResource(void* i_res);
|
||||
DUSK_NOINLINE void* dMeter2Info_getMsgResource();
|
||||
DUSK_NOINLINE void* dMeter2Info_getStageMsgResource();
|
||||
DUSK_NOINLINE void* dMeter2Info_getMsgUnitResource();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getLightDropGetFlag(int i_no);
|
||||
DUSK_NOINLINE s32 dMeter2Info_getMeterStringType();
|
||||
DUSK_NOINLINE void dMeter2Info_setMeterClass(dMeter2_c* i_meter);
|
||||
DUSK_NOINLINE void dMeter2Info_onLifeGaugeSE();
|
||||
DUSK_NOINLINE void dMeter2Info_offLifeGaugeSE();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getLifeGaugeSE();
|
||||
DUSK_NOINLINE const char* dMeter2Info_getSaveStageName();
|
||||
DUSK_NOINLINE void dMeter2Info_onShopTalkFlag();
|
||||
DUSK_NOINLINE void dMeter2Info_setLightDropGetFlag(int i_no, u8 i_flag);
|
||||
DUSK_NOINLINE u8 dMeter2Info_getRentalBombBag();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getMiniGameItemSetFlag();
|
||||
DUSK_NOINLINE void dMeter2Info_setMiniGameItem(u8 i_minigameFlag);
|
||||
DUSK_NOINLINE void dMeter2Info_resetMiniGameItem(bool i_saveItem);
|
||||
DUSK_NOINLINE void dMeter2Info_setTableMapRegionNo(u8 i_regionNo);
|
||||
DUSK_NOINLINE void dMeter2Info_setGoldWolfMapType(u8 i_mapType);
|
||||
DUSK_NOINLINE void dMeter2Info_changeWater(u8 i_slotNo);
|
||||
DUSK_NOINLINE void dMeter2Info_warpInProc();
|
||||
DUSK_NOINLINE void dMeter2Info_warpOutProc();
|
||||
DUSK_NOINLINE dMeter2_c* dMeter2Info_getMeterClass();
|
||||
DUSK_NOINLINE s16 dMeter2Info_getMsgKeyWaitTimer();
|
||||
DUSK_NOINLINE void dMeter2Info_onDirectUseItem(int param_0);
|
||||
DUSK_NOINLINE void dMeter2Info_setFloatingFlow(u16 i_flowID, s16 i_msgTimer, bool i_wakuVisible);
|
||||
DUSK_NOINLINE u8 dMeter2Info_getGameOverType();
|
||||
DUSK_NOINLINE void dMeter2Info_setGameOverType(u8 i_gameoverType);
|
||||
DUSK_NOINLINE void dMeter2Info_setMsgKeyWaitTimer(s16 i_waitTimer);
|
||||
DUSK_NOINLINE s32 dMeter2Info_getMsgTimeMs();
|
||||
DUSK_NOINLINE s32 dMeter2Info_getTimeMs();
|
||||
DUSK_NOINLINE void dMeter2Info_setMsgTimeMs(s32 i_msgTime);
|
||||
DUSK_NOINLINE void dMeter2Info_setTimeMs(s32 i_time);
|
||||
DUSK_NOINLINE u8 dMeter2Info_getNowCount();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getMaxCount();
|
||||
DUSK_NOINLINE void dMeter2Info_setScopeZoomPointer(u8 param_0);
|
||||
DUSK_NOINLINE void dMeter2Info_decMsgKeyWaitTimer();
|
||||
DUSK_NOINLINE bool dMeter2Info_isFloatingMessageVisible();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getItemExplainWindowStatus();
|
||||
DUSK_NOINLINE void dMeter2Info_setItemExplainWindowStatus(u8 i_value);
|
||||
DUSK_NOINLINE void dMeter2Info_resetDirectUseItem();
|
||||
DUSK_NOINLINE u16 dMeter2Info_getFloatingFlowID();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getCollectCursorPosX();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getCollectCursorPosY();
|
||||
DUSK_NOINLINE void dMeter2Info_setCollectCursorPosXY(u8 x, u8 y);
|
||||
DUSK_NOINLINE void dMeter2Info_onBlinkButton(int i_flag);
|
||||
DUSK_NOINLINE bool dMeter2Info_isFloatingMessageWakuVisible();
|
||||
DUSK_NOINLINE bool dMeter2Info_isBlinkButton(int i_flag);
|
||||
DUSK_NOINLINE void dMeter2Info_resetBlinkButton();
|
||||
DUSK_NOINLINE void dMeter2Info_resetFloatingMessage();
|
||||
DUSK_NOINLINE s16 dMeter2Info_decFloatingMessageTimer();
|
||||
DUSK_NOINLINE s16 dMeter2Info_getFloatingMessageTimer();
|
||||
DUSK_NOINLINE u16 dMeter2Info_getFloatingMessageID();
|
||||
DUSK_NOINLINE s16 dMeter2Info_getHorseLifeCount();
|
||||
DUSK_NOINLINE void dMeter2Info_setMeterString(s32 i_string);
|
||||
DUSK_NOINLINE void dMeter2Info_resetMeterString();
|
||||
DUSK_NOINLINE void dMeter2Info_setMeterItemPanePtr(int i_no, CPaneMgr* i_pane);
|
||||
DUSK_NOINLINE bool dMeter2Info_isShopTalkFlag();
|
||||
DUSK_NOINLINE void dMeter2Info_setMapDrugFlag(bool i_flag);
|
||||
DUSK_NOINLINE bool dMeter2Info_isTempBit(int i_bit);
|
||||
DUSK_NOINLINE void dMeter2Info_offSub2DStatus(int i_bit);
|
||||
DUSK_NOINLINE void dMeter2Info_onSub2DStatus(int i_bit);
|
||||
DUSK_NOINLINE void dMeter2Info_set2DWidth(f32 i_width);
|
||||
DUSK_NOINLINE void dMeter2Info_set2DHeight(f32 i_height);
|
||||
DUSK_NOINLINE void dMeter2Info_set2DPosH(f32 i_posH);
|
||||
DUSK_NOINLINE void dMeter2Info_set2DPosV(f32 i_posV);
|
||||
DUSK_NOINLINE void dMeter2Info_offShopTalkFlag();
|
||||
DUSK_NOINLINE void dMeter2Info_onUseButton(int i_button);
|
||||
DUSK_NOINLINE f32 dMeter2Info_get2DWidth();
|
||||
DUSK_NOINLINE f32 dMeter2Info_get2DHeight();
|
||||
DUSK_NOINLINE void dMeter2Info_setWarpInfo(const char* i_stageName, const cXyz& i_position,
|
||||
s16 i_angle, u8 i_roomNo, u8 param_4, u8 i_warpPlayerNo);
|
||||
DUSK_NOINLINE u8 dMeter2Info_getTableMapRegionNo();
|
||||
DUSK_NOINLINE u8 dMeter2Info_getGoldWolfMapType();
|
||||
DUSK_NOINLINE bool dMeter2Info_isWindowAccept(int param_0);
|
||||
DUSK_NOINLINE void dMeter2Info_setHorseLifeCount(s16 i_count);
|
||||
DUSK_NOINLINE void dMeter2Info_offTempBit(int i_bit);
|
||||
DUSK_NOINLINE void dMeter2Info_onTempBit(int i_bit);
|
||||
DUSK_NOINLINE void dMeter2Info_setFloatingMessage(u16 i_msgID, s16 i_msgTimer, bool i_wakuVisible);
|
||||
DUSK_NOINLINE void dMeter2Info_setMiniGameCount(s8 i_count);
|
||||
DUSK_NOINLINE void dMeter2Info_onWindowAccept(int param_0);
|
||||
DUSK_NOINLINE void dMeter2Info_offWindowAccept(int param_0);
|
||||
DUSK_NOINLINE void dMeter2Info_onMenuInForce(int param_0);
|
||||
|
||||
#else
|
||||
inline void dMeter2Info_Initialize() {
|
||||
g_meter2_info.init();
|
||||
}
|
||||
@@ -865,4 +1009,6 @@ inline void dMeter2Info_onMenuInForce(int param_0) {
|
||||
g_meter2_info.onMenuInForce(param_0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* D_METER_D_METER2_INFO_H */
|
||||
|
||||
+47
-12
@@ -27,18 +27,20 @@ public:
|
||||
|
||||
// Attributes
|
||||
/* 0x04 */ BE(u16) message_id;
|
||||
/* 0x06 */ BE(u16) event_label_id;
|
||||
/* 0x08 */ u8 se_speaker;
|
||||
/* 0x09 */ u8 fuki_kind;
|
||||
/* 0x0A */ u8 output_type;
|
||||
/* 0x0B */ u8 fuki_pos_type;
|
||||
/* 0x0C */ u8 unk_0xc;
|
||||
/* 0x0D */ u8 unk_0xd;
|
||||
/* 0x0E */ u8 se_mood;
|
||||
/* 0x0F */ u8 camera_id;
|
||||
/* 0x10 */ u8 base_anm_id;
|
||||
/* 0x11 */ u8 face_anm_id;
|
||||
/* 0x12 */ BE(u16) unk_0x12;
|
||||
/* 0x06 */ BE(u16) event_label_id; // saveBitLabels index set when the message displays
|
||||
/* 0x08 */ u8 speaker; // Z2SpeechMgr2 voice bank ID
|
||||
/* 0x09 */ u8 box_kind; // screen class, see dMsgObject_c::talkStartInit
|
||||
/* 0x0A */ u8 draw_type; // text pacing, see jmessage_tSequenceProcessor::do_begin
|
||||
/* 0x0B */ u8 box_position; // see dMsgObject_c::fukiPosCalc
|
||||
/* 0x0C */ u8 item_no; // unused; legacy dItemNo, 0xFF = none
|
||||
/* 0x0D */ u8 line_alignment; // 0 centered (JP only), 1 left; also copied to
|
||||
// jmessage_tReference::mForm
|
||||
/* 0x0E */ u8 speaker_mood; // grunt emotion index for the voice bank
|
||||
/* 0x0F */ u8 camera_attr; // 1-10 talk-actor slot, >=11 talk-camera style
|
||||
/* 0x10 */ u8 talk_anim; // NPC talk motion attribute
|
||||
/* 0x11 */ u8 face_anim; // NPC talk face attribute
|
||||
/* 0x12 */ u8 lines_per_page; // unused; runtime uses getLineMax()
|
||||
/* 0x13 */ u8 _pad;
|
||||
};
|
||||
|
||||
class JMSMesgInfo_c {
|
||||
@@ -119,6 +121,25 @@ struct jmessage_tReference : public JMessage::TReference {
|
||||
void setDemoFrame(u32 i_frame) { mDemoFrame = i_frame; }
|
||||
void setTopColorType(u8 i_colorType) { mTopColorType = i_colorType; }
|
||||
void setNowColorType(u8 i_colorType) { mNowColorType = i_colorType; }
|
||||
#if TARGET_PC
|
||||
void resetColors() {
|
||||
mNowCCColor = 0xFFFFFFFF;
|
||||
mNowGCColor = 0xFFFFFFFF;
|
||||
mTopCCColor = 0xFFFFFFFF;
|
||||
mTopGCColor = 0xFFFFFFFF;
|
||||
mNowFullColor = false;
|
||||
mTopFullColor = false;
|
||||
}
|
||||
void setFullColor(u32 ccColor, u32 gcColor) {
|
||||
mNowCCColor = ccColor;
|
||||
mNowGCColor = gcColor;
|
||||
mNowFullColor = true;
|
||||
}
|
||||
void clearNowFullColor() { mNowFullColor = false; }
|
||||
bool hasTopFullColor() { return mTopFullColor; }
|
||||
u32 getTopCCColor() { return mTopCCColor; }
|
||||
u32 getTopGCColor() { return mTopGCColor; }
|
||||
#endif
|
||||
void setTopTagScale(u16 i_tagScale) { mTopTagScale = i_tagScale; }
|
||||
void setNowTagScale(u16 i_tagScale) { mNowTagScale = i_tagScale; }
|
||||
void setRevoMessageID(u32 i_msgID) { mRevoMessageID = i_msgID; }
|
||||
@@ -363,6 +384,14 @@ struct jmessage_tReference : public JMessage::TReference {
|
||||
/* 0x1274 */ bool mSelectSetCancelFlag;
|
||||
/* 0x1275 */ bool mBombNameUseFlag;
|
||||
/* 0x1276 */ u8 mBatchColorFlag;
|
||||
#if TARGET_PC
|
||||
u32 mNowCCColor;
|
||||
u32 mNowGCColor;
|
||||
u32 mTopCCColor;
|
||||
u32 mTopGCColor;
|
||||
bool mNowFullColor;
|
||||
bool mTopFullColor;
|
||||
#endif
|
||||
}; // Size: 0x1278
|
||||
|
||||
struct jmessage_tMeasureProcessor : public JMessage::TRenderingProcessor {
|
||||
@@ -460,6 +489,9 @@ struct jmessage_tRenderingProcessor : public JMessage::TRenderingProcessor {
|
||||
void do_selwidthcenter(int);
|
||||
void do_heightcenter();
|
||||
void do_color(u8);
|
||||
#if TARGET_PC
|
||||
void do_fullcolor(u32 ccColor, u32 gcColor);
|
||||
#endif
|
||||
void do_scale(f32);
|
||||
void do_linedown(s16);
|
||||
void do_transY(s16, bool);
|
||||
@@ -638,6 +670,9 @@ struct jmessage_string_tRenderingProcessor : public JMessage::TRenderingProcesso
|
||||
void do_rubystrcat(char*);
|
||||
void do_outfont(u8);
|
||||
void do_color(u8);
|
||||
#if TARGET_PC
|
||||
void do_fullcolor(u32 ccColor, u32 gcColor);
|
||||
#endif
|
||||
void do_scale(f32);
|
||||
void do_linedown(s16);
|
||||
void do_numset(s16);
|
||||
|
||||
@@ -22,7 +22,7 @@ struct msg_class;
|
||||
// all mesg_flow_node structs members might be wrong
|
||||
struct mesg_flow_node {
|
||||
/* 0x00 */ u8 type;
|
||||
/* 0x01 */ u8 field_0x1;
|
||||
/* 0x01 */ u8 subtype;
|
||||
/* 0x02 */ BE(u16) msg_index;
|
||||
/* 0x04 */ BE(u16) next_node_idx;
|
||||
/* 0x06 */ BE(u16) unk_0x6;
|
||||
@@ -30,7 +30,7 @@ struct mesg_flow_node {
|
||||
|
||||
struct mesg_flow_node_branch {
|
||||
/* 0x00 */ u8 type;
|
||||
/* 0x01 */ u8 field_0x1;
|
||||
/* 0x01 */ u8 result_count;
|
||||
/* 0x02 */ BE(u16) query_idx;
|
||||
/* 0x04 */ BE(u16) param;
|
||||
/* 0x06 */ BE(u16) next_node_idx;
|
||||
|
||||
@@ -280,13 +280,13 @@ public:
|
||||
/* 0x150 */ f32 field_0x150;
|
||||
/* 0x154 */ u32 mMessageID;
|
||||
/* 0x158 */ u32 field_0x158;
|
||||
/* 0x15C */ u32 field_0x15c;
|
||||
/* 0x15C */ u32 mSelectMessageID; // message ID of the selection options message; 1000 = none
|
||||
/* 0x160 */ int mIdx;
|
||||
/* 0x164 */ u16 mNodeIdx;
|
||||
/* 0x166 */ u16 field_0x166;
|
||||
/* 0x168 */ u16 field_0x168;
|
||||
/* 0x16A */ s16 field_0x16a;
|
||||
/* 0x16C */ s16 field_0x16c;
|
||||
/* 0x16C */ s16 mCurrentGroupID; // group whose BMG is parsed; -1 none, 0 common, 1-8 stage
|
||||
/* 0x16E */ s16 field_0x16e;
|
||||
/* 0x170 */ s16 mNowTalkFlowNo;
|
||||
/* 0x172 */ s16 field_0x172;
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
void setTextBoxPtr(J2DTextBox* p_textBox) { mpTextBoxPtr = p_textBox; }
|
||||
void resetType() { mType = 0x47; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x04 */ J2DTextBox* mpTextBoxPtr;
|
||||
/* 0x08 */ f32 mPosX;
|
||||
/* 0x0C */ f32 mPosY;
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
|
||||
void setRupeeColor(u8 color) { mRupeeColor = color; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x004 */ COutFontSet_c* mpOfs[35];
|
||||
/* 0x090 */ J2DPicture* mpPane[70];
|
||||
/* 0x1A8 */ f32 mAlphaRatio;
|
||||
|
||||
@@ -12,34 +12,6 @@ class J2DTextBox;
|
||||
class JUTFont;
|
||||
class STControl;
|
||||
|
||||
#if TARGET_PC
|
||||
struct PaneCache {
|
||||
u64 tag;
|
||||
f32 origTransX;
|
||||
f32 origTransY;
|
||||
bool cached;
|
||||
};
|
||||
|
||||
static PaneCache l_tagName[] = {
|
||||
{MULTI_CHAR('m_00_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_00_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_00_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_00_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_00_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_01_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_01_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_01_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_01_3'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('m_01_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_02_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_02_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_02_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_02_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_02_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m03_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m03_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m03_2'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('m03_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m03_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_04_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_04_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_04_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_04_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_04_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_05_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_05_1'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('m_05_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_05_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_05_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_06_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_06_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_06_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_06_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_06_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_07_0'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('m_07_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_07_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_07_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_07_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_08_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_08_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_08_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_08_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_08_4'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('m_09_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_09_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_09_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_09_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_09_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_10_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_10_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_10_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_10_3'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('m_10_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_11_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_11_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_11_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_11_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m_11_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('m12_0'), 0.0f, 0.0f, false}, {MULTI_CHAR('m12_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('m12_2'), 0.0f, 0.0f, false},
|
||||
{MULTI_CHAR('m12_3'), 0.0f, 0.0f, false}, {MULTI_CHAR('m12_4'), 0.0f, 0.0f, false}, {MULTI_CHAR('p_end_2'), 0.0f, 0.0f, false}, {MULTI_CHAR('p_end_1'), 0.0f, 0.0f, false}, {MULTI_CHAR('p_end_0'), 0.0f, 0.0f, false},
|
||||
};
|
||||
|
||||
static PaneCache l_nameTagName[] = {
|
||||
{MULTI_CHAR('name_00'), 0.0f, 0.0f, false}, {MULTI_CHAR('name_01'), 0.0f, 0.0f, false}, {MULTI_CHAR('name_02'), 0.0f, 0.0f, false}, {MULTI_CHAR('name_03'), 0.0f, 0.0f, false}, {MULTI_CHAR('name_04'), 0.0f, 0.0f, false}, {MULTI_CHAR('name_05'), 0.0f, 0.0f, false}, {MULTI_CHAR('name_06'), 0.0f, 0.0f, false}, {MULTI_CHAR('name_07'), 0.0f, 0.0f, false},
|
||||
};
|
||||
|
||||
static PaneCache l_nameCurTagName[] = {
|
||||
{MULTI_CHAR('s__n_00'), 0.0f, 0.0f, false}, {MULTI_CHAR('s__n_01'), 0.0f, 0.0f, false}, {MULTI_CHAR('s__n_02'), 0.0f, 0.0f, false}, {MULTI_CHAR('s__n_03'), 0.0f, 0.0f, false}, {MULTI_CHAR('s__n_04'), 0.0f, 0.0f, false}, {MULTI_CHAR('s__n_05'), 0.0f, 0.0f, false}, {MULTI_CHAR('s__n_06'), 0.0f, 0.0f, false}, {MULTI_CHAR('s__n_07'), 0.0f, 0.0f, false},
|
||||
};
|
||||
#endif
|
||||
|
||||
class dNm_HIO_c {
|
||||
public:
|
||||
dNm_HIO_c();
|
||||
|
||||
@@ -1291,6 +1291,7 @@ public:
|
||||
}
|
||||
void set(const char*, s8, s16, s8, s8, u8);
|
||||
void offEnable() { enabled = 0; }
|
||||
void onEnable() { enabled = 1; }
|
||||
BOOL isEnable() const { return enabled; }
|
||||
s8 getWipe() const { return wipe; }
|
||||
u8 getWipeSpeed() const { return wipe_speed; }
|
||||
|
||||
@@ -318,6 +318,11 @@ public:
|
||||
/* 0x566 */ s8 field_0x566;
|
||||
/* 0x567 */ s8 field_0x567;
|
||||
|
||||
#if TARGET_PC
|
||||
u32 mItemGiveTag;
|
||||
u8 mItemGiveOriginalNo;
|
||||
#endif
|
||||
|
||||
#if !__MWERKS__
|
||||
s8 actor_last_base_field;
|
||||
#endif
|
||||
|
||||
@@ -79,6 +79,10 @@ struct fopAcM_prm_class {
|
||||
/* 0x1C */ fpc_ProcID parent_id;
|
||||
/* 0x20 */ s8 argument;
|
||||
/* 0x21 */ s8 room_no;
|
||||
#if TARGET_PC
|
||||
u32 mItemGiveTag;
|
||||
u8 mItemGiveOriginalNo;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct fopAcM_search4ev_prm {
|
||||
@@ -516,8 +520,9 @@ s32 fopAcM_SearchByName(s16 i_procName, fopAc_ac_c** i_outActor);
|
||||
fopAcM_prm_class* fopAcM_CreateAppend();
|
||||
|
||||
fopAcM_prm_class* createAppend(u16 i_setId, u32 i_parameters, const cXyz* i_pos, int i_roomNo,
|
||||
const csXyz* i_angle, const cXyz* i_scale, s8 i_argument,
|
||||
fpc_ProcID i_parentId);
|
||||
const csXyz* i_angle, const cXyz* i_scale, s8 i_argument,
|
||||
fpc_ProcID i_parentId IF_DUSK_ARG(u32 i_itemGiveTag = 0)
|
||||
IF_DUSK_ARG(u8 i_itemOriginalNo = 0xFF));
|
||||
|
||||
void fopAcM_Log(fopAc_ac_c const* i_actor, char const* i_message);
|
||||
|
||||
@@ -526,19 +531,22 @@ s32 fopAcM_delete(fopAc_ac_c* i_actor);
|
||||
s32 fopAcM_delete(fpc_ProcID i_actorID);
|
||||
|
||||
fpc_ProcID fopAcM_create(s16 i_procName, u16 i_setId, u32 i_parameters, const cXyz* i_pos,
|
||||
int i_roomNo, const csXyz* i_angle, const cXyz* i_scale, s8 i_argument,
|
||||
createFunc i_createFunc);
|
||||
int i_roomNo, const csXyz* i_angle, const cXyz* i_scale, s8 i_argument,
|
||||
createFunc i_createFunc IF_DUSK_ARG(u32 i_itemGiveTag = 0)
|
||||
IF_DUSK_ARG(u8 i_itemOriginalNo = 0xFF));
|
||||
|
||||
fpc_ProcID fopAcM_create(s16 i_procName, u32 i_parameters, const cXyz* i_pos, int i_roomNo,
|
||||
const csXyz* i_angle, const cXyz* i_scale, s8 i_argument);
|
||||
const csXyz* i_angle, const cXyz* i_scale, s8 i_argument IF_DUSK_ARG(u32 i_itemGiveTag = 0)
|
||||
IF_DUSK_ARG(u8 i_itemOriginalNo = 0xFF));
|
||||
|
||||
inline fpc_ProcID fopAcM_Create(s16 i_procName, createFunc i_createFunc, void* params) {
|
||||
return fpcM_Create(i_procName, i_createFunc,params);
|
||||
}
|
||||
|
||||
fopAc_ac_c* fopAcM_fastCreate(s16 i_procName, u32 i_parameters, const cXyz* i_pos, int i_roomNo,
|
||||
const csXyz* i_angle, const cXyz* i_scale, s8 i_argument,
|
||||
createFunc i_createFunc, void* i_createFuncData);
|
||||
const csXyz* i_angle, const cXyz* i_scale, s8 i_argument, createFunc i_createFunc,
|
||||
void* i_createFuncData IF_DUSK_ARG(u32 i_itemGiveTag = 0)
|
||||
IF_DUSK_ARG(u8 i_itemOriginalNo = 0xFF));
|
||||
|
||||
fopAc_ac_c* fopAcM_fastCreate(const char* i_actorname, u32 i_parameters, const cXyz* i_pos,
|
||||
int i_roomNo, const csXyz* i_angle, const cXyz* i_scale,
|
||||
@@ -623,11 +631,11 @@ fopAc_ac_c* fopAcM_getItemEventPartner(const fopAc_ac_c*);
|
||||
fopAc_ac_c* fopAcM_getEventPartner(const fopAc_ac_c*);
|
||||
|
||||
fpc_ProcID fopAcM_createItemForPresentDemo(cXyz const* i_pos, int i_itemNo, u8 param_2,
|
||||
int i_itemBitNo, int i_roomNo, csXyz const* i_angle,
|
||||
cXyz const* i_scale);
|
||||
int i_itemBitNo, int i_roomNo, csXyz const* i_angle,
|
||||
cXyz const* i_scale IF_DUSK_ARG(u32 i_itemGiveTag = 0));
|
||||
|
||||
fpc_ProcID fopAcM_createItemForTrBoxDemo(cXyz const* i_pos, int i_itemNo, int i_itemBitNo,
|
||||
int i_roomNo, csXyz const* i_angle, cXyz const* i_scale);
|
||||
int i_roomNo, csXyz const* i_angle, cXyz const* i_scale IF_DUSK_ARG(u32 i_itemGiveTag = 0));
|
||||
|
||||
u8 fopAcM_getItemNoFromTableNo(u8 i_tableNo);
|
||||
|
||||
@@ -641,11 +649,12 @@ fpc_ProcID fopAcM_createItemFromTable(cXyz const* i_pos, int i_tableNo, int i_it
|
||||
bool i_createDirect);
|
||||
|
||||
fpc_ProcID fopAcM_createDemoItem(const cXyz* i_pos, int i_itemNo, int i_itemBitNo,
|
||||
const csXyz* i_angle, int i_roomNo, const cXyz* scale, u8 param_7);
|
||||
const csXyz* i_angle, int i_roomNo, const cXyz* scale,
|
||||
u8 param_7 IF_DUSK_ARG(u32 i_itemGiveTag = 0));
|
||||
|
||||
fpc_ProcID fopAcM_createItemForBoss(const cXyz* i_pos, int i_itemNo, int i_roomNo,
|
||||
const csXyz* i_angle, const cXyz* i_scale, f32 i_speedF,
|
||||
f32 i_speedY, int param_8);
|
||||
const csXyz* i_angle, const cXyz* i_scale, f32 i_speedF, f32 i_speedY,
|
||||
int param_8 IF_DUSK_ARG(const char* i_itemCheckName = NULL));
|
||||
|
||||
fpc_ProcID fopAcM_createItemForMidBoss(const cXyz* i_pos, int i_itemNo, int i_roomNo,
|
||||
const csXyz* i_angle, const cXyz* i_scale, int param_6,
|
||||
|
||||
@@ -30,7 +30,7 @@ struct msg_class {
|
||||
/* 0xDC */ fopAc_ac_c* talk_actor;
|
||||
/* 0xE0 */ cXyz pos;
|
||||
/* 0xEC */ u32 msg_idx;
|
||||
/* 0xF0 */ u32 field_0xf0;
|
||||
/* 0xF0 */ u32 select_msg_idx; // selection options message ID; 1000 = none
|
||||
/* 0xF4 */ u32 field_0xf4;
|
||||
/* 0xF8 */ u16 mode;
|
||||
/* 0xFA */ u8 select_idx;
|
||||
|
||||
@@ -19,7 +19,7 @@ struct fopMsg_prm_class {
|
||||
/* 0x00 */ fopAc_ac_c* talk_actor;
|
||||
/* 0x04 */ cXyz pos;
|
||||
/* 0x10 */ u32 msg_idx;
|
||||
/* 0x14 */ u32 field_0x14;
|
||||
/* 0x14 */ u32 select_msg_idx; // selection options message ID; 1000 = none
|
||||
/* 0x18 */ fpc_ProcID field_0x18;
|
||||
}; // Size: 0x1C
|
||||
|
||||
@@ -46,8 +46,8 @@ void fopMsgM_setMessageID(fpc_ProcID msg_id);
|
||||
void fopMsgM_destroyExpHeap(JKRExpHeap* i_heap);
|
||||
f32 fopMsgM_valueIncrease(int param_0, int param_1, u8 i_type);
|
||||
s32 fopMsgM_setStageLayer(void* i_process);
|
||||
fpc_ProcID fopMsgM_messageSet(u32 i_msgIdx, fopAc_ac_c* i_talkActor, u32 param_2);
|
||||
fpc_ProcID fopMsgM_messageSet(u32 i_msgIdx, u32 param_1);
|
||||
fpc_ProcID fopMsgM_messageSet(u32 i_msgIdx, fopAc_ac_c* i_talkActor, u32 i_selectMsgIdx);
|
||||
fpc_ProcID fopMsgM_messageSet(u32 i_msgIdx, u32 i_selectMsgIdx);
|
||||
fpc_ProcID fopMsgM_messageSetDemo(u32 i_msgidx);
|
||||
msg_class* fopMsgM_SearchByID(fpc_ProcID i_id);
|
||||
TEXT_SPAN fopMsgM_messageGet(TEXT_SPAN i_stringBuf, u32 i_msgId);
|
||||
|
||||
@@ -123,6 +123,14 @@ inline int __builtin_clz(unsigned int v) {
|
||||
#endif
|
||||
#define DUSK_GAME_EXTERN extern DUSK_GAME_DATA
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define DUSK_NOINLINE __declspec(noinline)
|
||||
#elif defined(__GNUC__)
|
||||
#define DUSK_NOINLINE __attribute__((noinline))
|
||||
#else
|
||||
#define DUSK_NOINLINE
|
||||
#endif
|
||||
|
||||
#define FAST_DIV(x, n) (x >> (n / 2))
|
||||
|
||||
#define SQUARE(x) ((x) * (x))
|
||||
@@ -256,4 +264,23 @@ using std::isnan;
|
||||
#define DUSK_CONST IF_DUSK(const)
|
||||
#define DUSK_CONSTEXPR IF_DUSK(constexpr)
|
||||
|
||||
#if TARGET_PC && defined(DUSK_BUILDING_GAME)
|
||||
#include "dusk/mods/item.hpp"
|
||||
#define DUSK_ITEM_CHECK(name, item_no, giver) \
|
||||
(item_no) = ::dusk::mods::item_check_commit(name, (item_no), giver).itemNo
|
||||
#define DUSK_ITEM_CHECK_EXPR(name, item_no, giver) \
|
||||
(::dusk::mods::item_check_commit(name, (item_no), giver).itemNo)
|
||||
#define DUSK_ITEM_CHECK_PREVIEW(name, item_no, giver) \
|
||||
(item_no) = ::dusk::mods::item_check(name, (item_no), giver)
|
||||
#define DUSK_ITEM_CHECK_PREVIEW_EXPR(name, item_no, giver) \
|
||||
(::dusk::mods::item_check(name, (item_no), giver))
|
||||
#define DUSK_GIVE_TAG(name) IF_DUSK_ARG(::dusk::mods::item_give_tag(name))
|
||||
#else
|
||||
#define DUSK_ITEM_CHECK(name, item_no, giver)
|
||||
#define DUSK_ITEM_CHECK_EXPR(name, item_no, giver) (item_no)
|
||||
#define DUSK_ITEM_CHECK_PREVIEW(name, item_no, giver)
|
||||
#define DUSK_ITEM_CHECK_PREVIEW_EXPR(name, item_no, giver) (item_no)
|
||||
#define DUSK_GIVE_TAG(name)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace dusk::helpers::alignment {
|
||||
|
||||
/**
|
||||
* Read data from an address that may not be aligned properly.
|
||||
* @tparam T Type of data to read.
|
||||
* @param ptr Address to read from.
|
||||
* @return The copied value.
|
||||
*/
|
||||
template <typename T> requires std::is_trivially_copyable_v<T>
|
||||
[[nodiscard]] constexpr T read_unaligned(u8 const* ptr) {
|
||||
T copy;
|
||||
memcpy(©, ptr, sizeof(T));
|
||||
return copy;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
#pragma once
|
||||
|
||||
#include <bit>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
namespace dusk {
|
||||
namespace detail {
|
||||
|
||||
template <size_t Size>
|
||||
struct uint_of_size;
|
||||
|
||||
template <>
|
||||
struct uint_of_size<1> {
|
||||
using type = uint8_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct uint_of_size<2> {
|
||||
using type = uint16_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct uint_of_size<4> {
|
||||
using type = uint32_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct uint_of_size<8> {
|
||||
using type = uint64_t;
|
||||
};
|
||||
|
||||
template <size_t Size>
|
||||
using uint_of_size_t = uint_of_size<Size>::type;
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_trivially_copyable_v<T>)
|
||||
T unaligned_load(const void* source) noexcept {
|
||||
T value;
|
||||
std::memcpy(&value, source, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_trivially_copyable_v<T>)
|
||||
void unaligned_store(void* destination, T value) noexcept {
|
||||
std::memcpy(destination, &value, sizeof(value));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_unsigned_v<T>)
|
||||
constexpr T bswap(T value) noexcept {
|
||||
if constexpr (sizeof(T) == 1) {
|
||||
return value;
|
||||
} else if constexpr (sizeof(T) == 2) {
|
||||
return static_cast<T>((value << 8) | (value >> 8));
|
||||
} else if constexpr (sizeof(T) == 4) {
|
||||
return static_cast<T>(((value & 0x000000ffU) << 24) | ((value & 0x0000ff00U) << 8) |
|
||||
((value & 0x00ff0000U) >> 8) | ((value & 0xff000000U) >> 24));
|
||||
} else {
|
||||
static_assert(sizeof(T) == 8);
|
||||
return static_cast<T>(
|
||||
((value & 0x00000000000000ffULL) << 56) | ((value & 0x000000000000ff00ULL) << 40) |
|
||||
((value & 0x0000000000ff0000ULL) << 24) | ((value & 0x00000000ff000000ULL) << 8) |
|
||||
((value & 0x000000ff00000000ULL) >> 8) | ((value & 0x0000ff0000000000ULL) >> 24) |
|
||||
((value & 0x00ff000000000000ULL) >> 40) | ((value & 0xff00000000000000ULL) >> 56));
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads an unaligned integral value in the specified byte order.
|
||||
template <typename T>
|
||||
requires(std::is_integral_v<T> && !std::is_same_v<T, bool>)
|
||||
T read_bits(const void* source, std::endian endian = std::endian::big) noexcept {
|
||||
using Bits = std::make_unsigned_t<T>;
|
||||
Bits value = detail::unaligned_load<Bits>(source);
|
||||
if constexpr (sizeof(Bits) > 1) {
|
||||
if (endian != std::endian::native) {
|
||||
value = bswap(value);
|
||||
}
|
||||
}
|
||||
return std::bit_cast<T>(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_integral_v<T> && !std::is_same_v<T, bool>)
|
||||
constexpr T read_bits(const uint8_t* source, std::endian endian = std::endian::big) noexcept {
|
||||
if (!std::is_constant_evaluated()) {
|
||||
return read_bits<T>(static_cast<const void*>(source), endian);
|
||||
}
|
||||
using Bits = std::make_unsigned_t<T>;
|
||||
Bits value{};
|
||||
if (endian == std::endian::big) {
|
||||
for (size_t i = 0; i < sizeof(Bits); ++i) {
|
||||
value = static_cast<Bits>((value << 8) | source[i]);
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < sizeof(Bits); ++i) {
|
||||
value |= static_cast<Bits>(source[i]) << (i * 8);
|
||||
}
|
||||
}
|
||||
return std::bit_cast<T>(value);
|
||||
}
|
||||
|
||||
/// Reads an unaligned floating-point value in the specified byte order.
|
||||
template <typename T>
|
||||
requires(
|
||||
std::is_floating_point_v<T> && requires { typename detail::uint_of_size_t<sizeof(T)>; })
|
||||
T read_bits(const void* source, std::endian endian = std::endian::big) noexcept {
|
||||
using Bits = detail::uint_of_size_t<sizeof(T)>;
|
||||
return std::bit_cast<T>(read_bits<Bits>(source, endian));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires(
|
||||
std::is_floating_point_v<T> && requires { typename detail::uint_of_size_t<sizeof(T)>; })
|
||||
constexpr T read_bits(const uint8_t* source, std::endian endian = std::endian::big) noexcept {
|
||||
using Bits = detail::uint_of_size_t<sizeof(T)>;
|
||||
return std::bit_cast<T>(read_bits<Bits>(source, endian));
|
||||
}
|
||||
|
||||
/// Writes an unaligned integral value in the specified byte order.
|
||||
template <typename T>
|
||||
requires(std::is_integral_v<T> && !std::is_same_v<T, bool>)
|
||||
void write_bits(void* destination, T value, std::endian endian = std::endian::big) noexcept {
|
||||
using Bits = std::make_unsigned_t<T>;
|
||||
Bits bits = std::bit_cast<Bits>(value);
|
||||
if constexpr (sizeof(Bits) > 1) {
|
||||
if (endian != std::endian::native) {
|
||||
bits = bswap(bits);
|
||||
}
|
||||
}
|
||||
detail::unaligned_store(destination, bits);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_integral_v<T> && !std::is_same_v<T, bool>)
|
||||
constexpr void write_bits(
|
||||
uint8_t* destination, T value, std::endian endian = std::endian::big) noexcept {
|
||||
if (!std::is_constant_evaluated()) {
|
||||
write_bits(static_cast<void*>(destination), value, endian);
|
||||
return;
|
||||
}
|
||||
using Bits = std::make_unsigned_t<T>;
|
||||
const Bits bits = std::bit_cast<Bits>(value);
|
||||
if (endian == std::endian::big) {
|
||||
for (size_t i = 0; i < sizeof(Bits); ++i) {
|
||||
destination[sizeof(Bits) - i - 1] = static_cast<uint8_t>(bits >> (i * 8));
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < sizeof(Bits); ++i) {
|
||||
destination[i] = static_cast<uint8_t>(bits >> (i * 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes an unaligned floating-point value in the specified byte order.
|
||||
template <typename T>
|
||||
requires(
|
||||
std::is_floating_point_v<T> && requires { typename detail::uint_of_size_t<sizeof(T)>; })
|
||||
void write_bits(void* destination, T value, std::endian endian = std::endian::big) noexcept {
|
||||
using Bits = detail::uint_of_size_t<sizeof(T)>;
|
||||
write_bits(destination, std::bit_cast<Bits>(value), endian);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires(
|
||||
std::is_floating_point_v<T> && requires { typename detail::uint_of_size_t<sizeof(T)>; })
|
||||
constexpr void write_bits(
|
||||
uint8_t* destination, T value, std::endian endian = std::endian::big) noexcept {
|
||||
using Bits = detail::uint_of_size_t<sizeof(T)>;
|
||||
write_bits(destination, std::bit_cast<Bits>(value), endian);
|
||||
}
|
||||
|
||||
} // namespace dusk
|
||||
@@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <span>
|
||||
|
||||
/**
|
||||
* Helper functions for performing casts.
|
||||
*/
|
||||
namespace dusk::helpers::cast {
|
||||
/**
|
||||
* Implementation details of dusk::helpers::cast.
|
||||
*/
|
||||
namespace _impl {
|
||||
[[noreturn]] void overrun_high();
|
||||
[[noreturn]] void overrun_low();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
concept IntCastable = std::is_integral_v<T> && std::is_trivially_copyable_v<T>;
|
||||
|
||||
/**
|
||||
* Helper type that allows easily casting between integer types,
|
||||
* that safely aborts if an overflow were to occur.
|
||||
* Usage:
|
||||
* @code
|
||||
* size_t foobar = 20;
|
||||
* int real = bounded_cast(foobar);
|
||||
* @endcode
|
||||
*/
|
||||
template <IntCastable Source>
|
||||
struct bounded_cast {
|
||||
Source src;
|
||||
|
||||
template <IntCastable Target>
|
||||
[[nodiscard]] constexpr operator Target() const {
|
||||
if (std::cmp_greater(src, std::numeric_limits<Target>::max())) [[unlikely]] {
|
||||
_impl::overrun_high();
|
||||
}
|
||||
|
||||
if (std::cmp_less(src, std::numeric_limits<Target>::min())) [[unlikely]] {
|
||||
_impl::overrun_low();
|
||||
}
|
||||
|
||||
return static_cast<Target>(src);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -285,7 +285,6 @@ inline void be_swap(Mtx& val) {
|
||||
}
|
||||
}
|
||||
|
||||
#define LE(T) T
|
||||
#define BE(T) BE<T>
|
||||
#define BE_HOST(T) (T.host())
|
||||
#else
|
||||
|
||||
@@ -112,6 +112,11 @@ public:
|
||||
mSerialNo = serial_no;
|
||||
}
|
||||
|
||||
#ifdef TARGET_PC
|
||||
void setFileName(const std::string& fileName);
|
||||
const char* getFileName();
|
||||
#endif
|
||||
|
||||
/* 0x0000 */ u8 mData[SAVEFILE_SIZE];
|
||||
/* 0x1FBC */ u8 mChannel;
|
||||
/* 0x1FBD */ u8 mCopyToPos;
|
||||
@@ -124,6 +129,11 @@ public:
|
||||
/* 0x1FEC */ s32 mNandState;
|
||||
/* 0x1FF0 */ u64 mSerialNo;
|
||||
/* 0x1FF8 */ u32 mDataVersion;
|
||||
#ifdef TARGET_PC
|
||||
bool mInitialized;
|
||||
std::string mFileName;
|
||||
#endif
|
||||
|
||||
}; // Size: 0x2000
|
||||
|
||||
STATIC_ASSERT(sizeof(mDoMemCd_Ctrl_c) == 8192);
|
||||
@@ -230,4 +240,14 @@ inline s32 mDoMemCd_checkNANDFile() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_PC
|
||||
inline void mDoMemCd_SetFileName(const std::string& fileName) {
|
||||
g_mDoMemCd_control.setFileName(fileName);
|
||||
}
|
||||
|
||||
inline const char* mDoMemCd_GetFileName() {
|
||||
return g_mDoMemCd_control.getFileName();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* M_DO_M_DO_MEMCARD_H */
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
JKRMemArchive* getArchive() const { return mArchive; }
|
||||
JKRHeap* getHeap() const { return mHeap; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x14 */ u8 mMountDirection;
|
||||
/* 0x18 */ s32 mEntryNumber;
|
||||
/* 0x1C */ JKRMemArchive* mArchive;
|
||||
@@ -130,8 +130,8 @@ private:
|
||||
}; // Size = 0x28
|
||||
|
||||
struct mDoDvdThdStack {
|
||||
u8 stack[4096];
|
||||
} ATTRIBUTE_ALIGN(16);
|
||||
ATTRIBUTE_ALIGN(16) u8 stack[4096];
|
||||
};
|
||||
|
||||
struct mDoDvdThd {
|
||||
static s32 main(void*);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
class J3DModelData;
|
||||
class J3DMaterialTable;
|
||||
struct J3DModelHierarchy;
|
||||
class J3DVertexData;
|
||||
|
||||
#if TARGET_PC
|
||||
#define OFFSET_PTR_V0 BE(u32)
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
#include "JSystem/JGeometry.h"
|
||||
|
||||
namespace dusk::mods::svc::audio_res::bst {
|
||||
struct SoundTableReplacementSlot;
|
||||
}
|
||||
|
||||
class JAIAudible;
|
||||
class JAISoundID;
|
||||
struct JASSoundParams;
|
||||
@@ -18,8 +14,7 @@ struct JASSoundParams;
|
||||
struct JAIAudience {
|
||||
virtual ~JAIAudience();
|
||||
virtual JAIAudible* newAudible(JGeometry::TVec3<f32> const&, JAISoundID,
|
||||
JGeometry::TVec3<f32> const*, u32
|
||||
IF_DUSK_ARG(dusk::mods::svc::audio_res::bst::SoundTableReplacementSlot const*)) = 0;
|
||||
JGeometry::TVec3<f32> const*, u32) = 0;
|
||||
virtual int getMaxChannels() = 0;
|
||||
virtual void deleteAudible(JAIAudible*) = 0;
|
||||
virtual u32 calcPriority(JAIAudible*) = 0;
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
void startTrack_(const JASSoundParams& params);
|
||||
void JAISeCategoryMgr_mixOut_(bool, const JASSoundParams& params, JAISoundActivity activity);
|
||||
void JAISeCategoryMgr_calc_();
|
||||
void JAISeMgr_startID_(JAISoundID id, const JGeometry::TVec3<f32>* posPtr, JAIAudience* audience IF_DUSK_ARG(std::shared_ptr<SoundEffectReplacementSlot> replacement));
|
||||
void JAISeMgr_startID_(JAISoundID id, const JGeometry::TVec3<f32>* posPtr, JAIAudience* audience);
|
||||
bool prepare_getSeqData_();
|
||||
void prepare_();
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
JAISe* newSe_(int category, u32 priority);
|
||||
void calc();
|
||||
void mixOut();
|
||||
bool startSound(JAISoundID id, JAISoundHandle* handle, const JGeometry::TVec3<f32>* posPtr IF_DUSK_ARG(std::shared_ptr<dusk::mods::svc::audio_res::bst::SoundEffectReplacementSlot> replacement));
|
||||
bool startSound(JAISoundID id, JAISoundHandle* handle, const JGeometry::TVec3<f32>* posPtr);
|
||||
int getNumActiveSe() const;
|
||||
|
||||
/* 0x004 */ JAISoundActivity mSoundActivity;
|
||||
|
||||
@@ -6,16 +6,7 @@
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include "global.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include <memory>
|
||||
|
||||
namespace dusk::mods::svc::audio_res::bst {
|
||||
struct SoundTableReplacementSlot;
|
||||
struct SoundEffectReplacementSlot;
|
||||
struct StreamReplacementSlot;
|
||||
}
|
||||
#endif
|
||||
#include <cstdint>
|
||||
|
||||
class JAISound;
|
||||
|
||||
@@ -110,7 +101,7 @@ struct JAISoundStatus_ {
|
||||
bool isMute() const { return field_0x0.flags.mute; }
|
||||
bool isPaused() const { return field_0x0.flags.paused; }
|
||||
void pauseWhenOut() {
|
||||
field_0x1.flags.mPauseWhenOut = 1;
|
||||
field_0x1.flags.flag3 = 1;
|
||||
}
|
||||
|
||||
/* 0x0 */ union {
|
||||
@@ -129,9 +120,9 @@ struct JAISoundStatus_ {
|
||||
/* 0x1 */ union {
|
||||
u8 value;
|
||||
struct {
|
||||
u8 mComesBack : 1;
|
||||
u8 flag1 : 1;
|
||||
u8 flag2 : 1;
|
||||
u8 mPauseWhenOut : 1;
|
||||
u8 flag3 : 1;
|
||||
u8 flag4 : 1;
|
||||
u8 flag5 : 1;
|
||||
u8 flag6 : 1;
|
||||
@@ -280,16 +271,10 @@ class JAITempoMgr;
|
||||
*/
|
||||
class JAISound {
|
||||
public:
|
||||
#if TARGET_PC
|
||||
using SoundTableReplacementSlot = dusk::mods::svc::audio_res::bst::SoundTableReplacementSlot;
|
||||
using SoundEffectReplacementSlot = dusk::mods::svc::audio_res::bst::SoundEffectReplacementSlot;
|
||||
using StreamReplacementSlot = dusk::mods::svc::audio_res::bst::StreamReplacementSlot;
|
||||
#endif
|
||||
|
||||
void releaseHandle();
|
||||
void attachHandle(JAISoundHandle* handle);
|
||||
JAISound();
|
||||
void start_JAISound_(JAISoundID id, const JGeometry::TVec3<f32>* posPtr, JAIAudience* audience IF_DUSK_ARG(std::shared_ptr<SoundTableReplacementSlot> replacement));
|
||||
void start_JAISound_(JAISoundID id, const JGeometry::TVec3<f32>* posPtr, JAIAudience* audience);
|
||||
bool acceptsNewAudible() const;
|
||||
void newAudible(const JGeometry::TVec3<f32>&, JGeometry::TVec3<f32> const*, u32,
|
||||
JAIAudience*);
|
||||
@@ -312,11 +297,6 @@ public:
|
||||
virtual bool JAISound_tryDie_() = 0;
|
||||
|
||||
JAISoundID getID() const { return soundID_; }
|
||||
#if TARGET_PC
|
||||
SoundTableReplacementSlot* getReplacement() const {
|
||||
return replacement.get();
|
||||
}
|
||||
#endif
|
||||
u32 getAnimationState() const { return status_.state.flags.animationState; }
|
||||
bool isAnimated() const { return getAnimationState() != 0; }
|
||||
void setAnimationState(u32 state) {
|
||||
@@ -329,7 +309,7 @@ public:
|
||||
bool hasLifeTime() const { return status_.field_0x1.flags.flag2; }
|
||||
|
||||
void removeLifeTime_() {
|
||||
status_.field_0x1.flags.mComesBack = false;
|
||||
status_.field_0x1.flags.flag1 = false;
|
||||
status_.field_0x1.flags.flag2 = 0;
|
||||
}
|
||||
|
||||
@@ -366,7 +346,7 @@ public:
|
||||
|
||||
void setComesBack(bool param_0) {
|
||||
JUT_ASSERT(354, status_.state.flags.calcedOnce == 0);
|
||||
status_.field_0x1.flags.mComesBack = 1;
|
||||
status_.field_0x1.flags.flag1 = 1;
|
||||
if (param_0) {
|
||||
status_.pauseWhenOut();
|
||||
}
|
||||
@@ -400,9 +380,6 @@ public:
|
||||
/* 0x34 */ u32 priority_;
|
||||
/* 0x38 */ s32 count_;
|
||||
/* 0x3C */ JAISoundParams params_;
|
||||
#if TARGET_PC
|
||||
std::shared_ptr<SoundTableReplacementSlot> replacement;
|
||||
#endif
|
||||
}; // Size: 0x98
|
||||
|
||||
STATIC_ASSERT(sizeof(JAISound) == 0x98);
|
||||
|
||||
@@ -9,17 +9,13 @@
|
||||
*
|
||||
*/
|
||||
struct JAISoundInfo : public JASGlobalInstance<JAISoundInfo> {
|
||||
IF_DUSK(using SoundTableReplacementSlot = dusk::mods::svc::audio_res::bst::SoundTableReplacementSlot);
|
||||
IF_DUSK(using SoundEffectReplacementSlot = dusk::mods::svc::audio_res::bst::SoundEffectReplacementSlot);
|
||||
IF_DUSK(using StreamReplacementSlot = dusk::mods::svc::audio_res::bst::StreamReplacementSlot);
|
||||
|
||||
JAISoundInfo(bool);
|
||||
virtual int getSoundType(JAISoundID) const = 0;
|
||||
virtual int getCategory(JAISoundID) const = 0;
|
||||
virtual u32 getPriority(JAISoundID IF_DUSK_ARG(SoundTableReplacementSlot const* replacement)) const = 0;
|
||||
virtual void getSeInfo(JAISoundID, JAISe* IF_DUSK_ARG(SoundEffectReplacementSlot const* replacement)) const = 0;
|
||||
virtual u32 getPriority(JAISoundID) const = 0;
|
||||
virtual void getSeInfo(JAISoundID, JAISe*) const = 0;
|
||||
virtual void getSeqInfo(JAISoundID, JAISeq*) const = 0;
|
||||
virtual void getStreamInfo(JAISoundID, JAIStream* IF_DUSK_ARG(StreamReplacementSlot const* replacement)) const = 0;
|
||||
virtual void getStreamInfo(JAISoundID, JAIStream*) const = 0;
|
||||
virtual ~JAISoundInfo();
|
||||
};
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
*/
|
||||
struct JAISoundParamsProperty {
|
||||
void init() {
|
||||
mVolume = 1.0f;
|
||||
mFxMix = 0.0f;
|
||||
mPitch = 1.0f;
|
||||
field_0x0 = 1.0f;
|
||||
field_0x4 = 0.0f;
|
||||
field_0x8 = 1.0f;
|
||||
}
|
||||
|
||||
/* 0x00 */ f32 mVolume;
|
||||
/* 0x04 */ f32 mFxMix;
|
||||
/* 0x08 */ f32 mPitch;
|
||||
/* 0x00 */ f32 field_0x0;
|
||||
/* 0x04 */ f32 field_0x4;
|
||||
/* 0x08 */ f32 field_0x8;
|
||||
}; // Size: 0xC
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
JAIStream(JAIStreamMgr* streamMgr, JAISoundStrategyMgr<JAIStream>* soundStrategyMgr);
|
||||
void JAIStreamMgr_startID_(JAISoundID id, s32 streamFileEntry,
|
||||
const JGeometry::TVec3<f32>* posPtr, JAIAudience* audience,
|
||||
int category IF_DUSK_ARG(std::shared_ptr<StreamReplacementSlot> replacement));
|
||||
int category);
|
||||
bool prepare_prepareStream_();
|
||||
void prepare_();
|
||||
void prepare_startStream_();
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
*
|
||||
*/
|
||||
struct JAIStreamDataMgr {
|
||||
IF_DUSK(using StreamReplacementSlot2 = dusk::mods::svc::audio_res::bst::StreamReplacementSlot);
|
||||
|
||||
virtual s32 getStreamFileEntry(JAISoundID IF_DUSK_ARG(StreamReplacementSlot2 const*)) = 0;
|
||||
virtual s32 getStreamFileEntry(JAISoundID) = 0;
|
||||
virtual ~JAIStreamDataMgr();
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ struct JAIStreamDataMgr;
|
||||
class JAIStreamMgr : public JASGlobalInstance<JAIStreamMgr> {
|
||||
public:
|
||||
JAIStreamMgr(bool setInstance);
|
||||
bool startSound(JAISoundID id, JAISoundHandle* handle, const JGeometry::TVec3<f32>* posPtr IF_DUSK_ARG(std::shared_ptr<dusk::mods::svc::audio_res::bst::StreamReplacementSlot> replacement));
|
||||
bool startSound(JAISoundID id, JAISoundHandle* handle, const JGeometry::TVec3<f32>* posPtr);
|
||||
void freeDeadStream_();
|
||||
void calc();
|
||||
void stop();
|
||||
|
||||
@@ -14,20 +14,20 @@ const int OSC_MAX = 2;
|
||||
*/
|
||||
struct JASInstParam : public JASSoundParams {
|
||||
JASInstParam() {
|
||||
mOscillators = NULL;
|
||||
mDirectRelease = 0;
|
||||
mWaveId = 0;
|
||||
mChannelType = 0;
|
||||
mOscillatorCount = 0;
|
||||
mDontSetKey = 0;
|
||||
field_0x14 = NULL;
|
||||
field_0x18 = 0;
|
||||
field_0x1a = 0;
|
||||
field_0x1c = 0;
|
||||
field_0x1d = 0;
|
||||
field_0x1e = 0;
|
||||
}
|
||||
|
||||
JASOscillator::Data** mOscillators;
|
||||
u16 mDirectRelease;
|
||||
u16 mWaveId;
|
||||
u8 mChannelType; // Always CHANNEL_WAVE in practice
|
||||
u8 mOscillatorCount;
|
||||
u8 mDontSetKey;
|
||||
JASOscillator::Data** field_0x14;
|
||||
u16 field_0x18;
|
||||
u16 field_0x1a;
|
||||
u8 field_0x1c;
|
||||
u8 field_0x1d;
|
||||
u8 field_0x1e;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -52,10 +52,10 @@ struct JASBasicInst : public JASInst {
|
||||
void setHighKey(int key) { mHighKey = key; }
|
||||
|
||||
/* 0x0 */ s32 mHighKey;
|
||||
/* 0x4 */ u16 mWaveId;
|
||||
/* 0x4 */ u16 field_0x4;
|
||||
/* 0x6 */ u16 field_0x6;
|
||||
/* 0x8 */ f32 mVolumeMult;
|
||||
/* 0xC */ f32 mPitchMult;
|
||||
/* 0x8 */ f32 field_0x8;
|
||||
/* 0xC */ f32 field_0xc;
|
||||
};
|
||||
|
||||
JASBasicInst();
|
||||
@@ -74,7 +74,7 @@ struct JASBasicInst : public JASInst {
|
||||
|
||||
/* 0x04 */ f32 mVolume;
|
||||
/* 0x08 */ f32 mPitch;
|
||||
/* 0x0C */ JASOscillator::Data const* mOscillators[OSC_MAX];
|
||||
/* 0x0C */ JASOscillator::Data const* field_0xc[OSC_MAX];
|
||||
/* 0x10 */ u32 mKeymapCount;
|
||||
/* 0x14 */ TKeymap* mKeymap;
|
||||
};
|
||||
|
||||
@@ -12,27 +12,21 @@ struct JASBasicWaveBank : public JASWaveBank {
|
||||
struct TWaveHandle : public JASWaveHandle {
|
||||
TWaveHandle() { mHeap = NULL; }
|
||||
virtual intptr_t getWavePtr() const;
|
||||
virtual const JASWaveInfo* getWaveInfo() const { return &mWaveInfo; }
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] void const* getAramBaseAddress() const override { return nullptr; }
|
||||
#endif
|
||||
virtual const JASWaveInfo* getWaveInfo() const { return &field_0x4; }
|
||||
bool compareHeap(JASHeap* heap) const { return mHeap == heap;}
|
||||
|
||||
/* 0x04 */ JASWaveInfo mWaveInfo;
|
||||
/* 0x04 */ JASWaveInfo field_0x4;
|
||||
/* 0x28 */ JASHeap* mHeap;
|
||||
};
|
||||
|
||||
struct TGroupWaveInfo {
|
||||
TGroupWaveInfo() {
|
||||
waveId = 0xffff;
|
||||
mOffsetStart = -1;
|
||||
field_0x0 = 0xffff;
|
||||
field_0x4 = -1;
|
||||
}
|
||||
|
||||
/* 0x00 */ u16 waveId;
|
||||
/* 0x04 */ int mOffsetStart;
|
||||
/* 0x00 */ u16 field_0x0;
|
||||
/* 0x04 */ int field_0x4;
|
||||
};
|
||||
|
||||
struct TWaveGroup : JASWaveArc {
|
||||
@@ -50,7 +44,7 @@ struct JASBasicWaveBank : public JASWaveBank {
|
||||
u32 getWaveCount() const { return mWaveCount; }
|
||||
};
|
||||
|
||||
JASBasicWaveBank(IF_DUSK(u32 bankId));
|
||||
JASBasicWaveBank();
|
||||
~JASBasicWaveBank();
|
||||
TWaveGroup* getWaveGroup(u32);
|
||||
void setGroupCount(u32, JKRHeap*);
|
||||
@@ -62,7 +56,7 @@ struct JASBasicWaveBank : public JASWaveBank {
|
||||
JASWaveArc* getWaveArc(u32 param_0) { return getWaveGroup(param_0); }
|
||||
u32 getArcCount() const { return mGroupCount; }
|
||||
|
||||
/* 0x04 */ OSMutex mWaveTableMutex;
|
||||
/* 0x04 */ OSMutex field_0x4;
|
||||
/* 0x1C */ TWaveHandle* mWaveTable;
|
||||
/* 0x20 */ TWaveGroup* mWaveGroupArray;
|
||||
/* 0x24 */ u16 mHandleCount;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define JASCALC_H
|
||||
|
||||
#include <types.h>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
/**
|
||||
@@ -10,16 +11,31 @@
|
||||
*/
|
||||
struct JASCalc {
|
||||
static void imixcopy(const s16*, const s16*, s16*, u32);
|
||||
static void bcopyfast(const void* src, void* dest, u32 size);
|
||||
#if TARGET_PC
|
||||
static void bcopyfast(const void* src, void* dest, u32 size) {
|
||||
std::memcpy(dest, src, size);
|
||||
}
|
||||
#if TARGET_ANDROID
|
||||
static void _bcopy(const void* src, void* dest, u32 size);
|
||||
static void _bcopy(const void* src, void* dest, u32 size) {
|
||||
#else
|
||||
static void bcopy(const void* src, void* dest, u32 size);
|
||||
static void bcopy(const void* src, void* dest, u32 size) {
|
||||
#endif
|
||||
static void bzerofast(void* dest, u32 size);
|
||||
std::memcpy(dest, src, size);
|
||||
}
|
||||
static void bzerofast(void* dest, u32 size) {
|
||||
std::memset(dest, 0, size);
|
||||
}
|
||||
#if TARGET_ANDROID
|
||||
static void _bzero(void* dest, u32 size);
|
||||
static void _bzero(void* dest, u32 size) {
|
||||
#else
|
||||
static void bzero(void* dest, u32 size) {
|
||||
#endif
|
||||
std::memset(dest, 0, size);
|
||||
}
|
||||
#else
|
||||
static void bcopyfast(const void* src, void* dest, u32 size);
|
||||
static void bcopy(const void* src, void* dest, u32 size);
|
||||
static void bzerofast(void* dest, u32 size);
|
||||
static void bzero(void* dest, u32 size);
|
||||
#endif
|
||||
static f32 pow2(f32);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "JSystem/JAudio2/JASWaveInfo.h"
|
||||
#include "JSystem/JAudio2/JASDSPInterface.h"
|
||||
#include <os.h>
|
||||
#include <memory>
|
||||
|
||||
struct JASDSPChannel;
|
||||
|
||||
@@ -16,10 +15,6 @@ namespace JASDsp {
|
||||
struct TChannel;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
#include "JSystem/JAudio2/JASSampleDataReference.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jaudio
|
||||
*
|
||||
@@ -164,30 +159,13 @@ public:
|
||||
struct {
|
||||
u32 mChannelType; // CHANNEL_WAVE or CHANNEL_OSCILLATOR
|
||||
JASWaveInfo mWaveInfo;
|
||||
} mAnon;
|
||||
} field_0xdc;
|
||||
union {
|
||||
u32 mWaveAramAddress;
|
||||
u32 mOscillatorSomething;
|
||||
u32 field_0x104;
|
||||
};
|
||||
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* Memory address at which this sound effect should consider ARAM to start.
|
||||
*
|
||||
* By changing this, sound effects can effectively be played back from anywhere in memory,
|
||||
* rather than just the emulated ARAM space.
|
||||
*
|
||||
* If nullptr, the regular emulated ARAM is used.
|
||||
*/
|
||||
void const* mAramBaseAddress;
|
||||
|
||||
/**
|
||||
* @see JASSampleDataReference
|
||||
*/
|
||||
std::unique_ptr<JASSampleDataReference> mSampleReference;
|
||||
#endif
|
||||
|
||||
static DUSK_GAME_DATA OSMessageQueue sBankDisposeMsgQ;
|
||||
static DUSK_GAME_DATA OSMessage sBankDisposeMsg[16];
|
||||
static DUSK_GAME_DATA OSMessage sBankDisposeList[16];
|
||||
|
||||
@@ -109,9 +109,7 @@ namespace JASDsp {
|
||||
* Pitch shift via changing playback speed.
|
||||
*/
|
||||
/* 0x004 */ u16 mPitch;
|
||||
#if !TARGET_PC
|
||||
/* 0x006 */ short _unused1;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set to 1 when playback starts, cleared by DSP later,
|
||||
@@ -120,27 +118,19 @@ namespace JASDsp {
|
||||
* (Corroborated by fields JASAramStream checks never being cleared explicitly by CPU.)
|
||||
*/
|
||||
/* 0x008 */ u16 mResetFlag;
|
||||
#if !TARGET_PC
|
||||
/* 0x00A */ u8 _unused2[0x00C - 0x00A];
|
||||
#endif
|
||||
/* 0x00C */ s16 mPauseFlag;
|
||||
#if !TARGET_PC
|
||||
/* 0x00E */ short _unused3;
|
||||
#endif
|
||||
/* 0x010 */ OutputChannelConfig mOutputChannels[DSP_OUTPUT_CHANNELS];
|
||||
#if !TARGET_PC
|
||||
/* 0x040 */ u8 _unused4[0x050 - 0x040];
|
||||
#endif
|
||||
/* 0x050 */ u16 mAutoMixerPanDolby; // pan is upper 8 bits, dolby lower 8.
|
||||
/* 0x052 */ u16 mAutoMixerFxMix;
|
||||
/* 0x054 */ u16 mAutoMixerInitVolume;
|
||||
/* 0x056 */ u16 mAutoMixerVolume;
|
||||
/* 0x058 */ u16 mAutoMixerBeenSet;
|
||||
#if !TARGET_PC
|
||||
/* 0x05A */ u8 _unused5[0x060 - 0x05A];
|
||||
/* 0x060 */ short field_0x060; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x062 */ u8 _unused6[0x064 - 0x062];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Samples per ADPCM frame for ADPCM audio. Seems just set to 1 for PCM formats.
|
||||
@@ -149,9 +139,7 @@ namespace JASDsp {
|
||||
/* 0x064 */ u16 mSamplesPerBlock;
|
||||
/* 0x066 */ short field_0x066; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x068 */ u32 mSamplePosition; // Only ever initialized by code, name is guess.
|
||||
#if !TARGET_PC
|
||||
/* 0x06C */ u8 _unused7[0x070 - 0x06C];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Current audio read position in ARAM. Updated by DSP.
|
||||
@@ -163,13 +151,11 @@ namespace JASDsp {
|
||||
* Gets written by DSP, but also CPU.
|
||||
*/
|
||||
/* 0x074 */ u32 mSamplesLeft; // Never directly cleared to zero. Seems sus. Cleared by DSP?
|
||||
#if !TARGET_PC
|
||||
/* 0x078 */ short field_0x078[4]; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x080 */ short field_0x080[20]; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x0A8 */ short field_0x0a8[4]; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x0B0 */ u16 field_0x0b0[16]; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x0D0 */ u8 _unused8[0x100 - 0x0D0];
|
||||
#endif
|
||||
/* 0x100 */ u16 mBytesPerBlock;
|
||||
/* 0x102 */ u16 mLoopFlag;
|
||||
|
||||
@@ -190,26 +176,9 @@ namespace JASDsp {
|
||||
/* 0x118 */ u32 mWaveAramAddress;
|
||||
/* 0x11C */ int mSampleCount;
|
||||
/* 0x120 */ s16 fir_filter_params[8];
|
||||
#if !TARGET_PC
|
||||
/* 0x130 */ u8 _unused9[0x148 - 0x130];
|
||||
#endif
|
||||
/* 0x148 */ s16 iir_filter_params[8];
|
||||
#if !TARGET_PC
|
||||
/* 0x158 */ u8 _unused10[0x180 - 0x158];
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* Memory address at which this sound effect should consider ARAM to start.
|
||||
* This means fields like mWaveAramAddress will be relative to this pointer instead.
|
||||
*
|
||||
* By changing this, sound effects can effectively be played back from anywhere in memory,
|
||||
* rather than just the emulated ARAM space.
|
||||
*
|
||||
* If nullptr, the regular emulated ARAM is used.
|
||||
*/
|
||||
void const* mAramBaseAddress;
|
||||
#endif
|
||||
};
|
||||
|
||||
void boot(void (*)(void*));
|
||||
|
||||
@@ -21,10 +21,10 @@ struct JASDrumSet : public JASInst {
|
||||
/* 0x00 */ f32 mVolume;
|
||||
/* 0x04 */ f32 mPitch;
|
||||
/* 0x08 */ f32 mPan;
|
||||
/* 0x0C */ u16 mDirectRelease;
|
||||
/* 0x0E */ u16 mWaveId;
|
||||
/* 0x10 */ f32 mVolumeMult;
|
||||
/* 0x14 */ f32 mPitchMult;
|
||||
/* 0x0C */ u16 field_0xc;
|
||||
/* 0x0E */ u16 field_0xe;
|
||||
/* 0x10 */ f32 field_0x10;
|
||||
/* 0x14 */ f32 field_0x14;
|
||||
};
|
||||
|
||||
JASDrumSet();
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef DUSKLIGHT_JASSAMPLEDATAREFERENCE_H
|
||||
#define DUSKLIGHT_JASSAMPLEDATAREFERENCE_H
|
||||
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* An object to manage the lifetime of the sample data pointed to by JASChannel.
|
||||
*
|
||||
* JASChannel can (optionally) accept an unique_ptr to an object to this type,
|
||||
* in which case it will be destroyed when the JASChannel is done.
|
||||
*
|
||||
* @see JASChannel::mSampleReference
|
||||
*/
|
||||
struct JASSampleDataReference {
|
||||
virtual ~JASSampleDataReference() = default;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // DUSKLIGHT_JASSAMPLEDATAREFERENCE_H
|
||||
@@ -10,18 +10,12 @@ struct JASSimpleWaveBank : JASWaveBank, JASWaveArc {
|
||||
intptr_t getWavePtr() const;
|
||||
TWaveHandle();
|
||||
const JASWaveInfo* getWaveInfo() const;
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] void const* getAramBaseAddress() const override { return nullptr; }
|
||||
#endif
|
||||
|
||||
/* 0x04 */ JASWaveInfo mWaveInfo;
|
||||
/* 0x28 */ JASHeap* mHeap;
|
||||
};
|
||||
|
||||
JASSimpleWaveBank(IF_DUSK(u32 bankId));
|
||||
JASSimpleWaveBank();
|
||||
~JASSimpleWaveBank();
|
||||
void setWaveTableSize(u32, JKRHeap*);
|
||||
JASWaveHandle* getWaveHandle(u32) const;
|
||||
|
||||
@@ -26,9 +26,7 @@ public:
|
||||
};
|
||||
|
||||
struct TCtrlWave {
|
||||
// Wave ID in lower half.
|
||||
// Upper bits appear to be group ID, which is unused by the game code.
|
||||
/* 0x0 */ BE(u32) mWaveAndGroupId;
|
||||
/* 0x0 */ BE(u32) _00;
|
||||
};
|
||||
|
||||
struct TWave {
|
||||
@@ -59,14 +57,13 @@ public:
|
||||
};
|
||||
|
||||
struct TCtrl {
|
||||
/* 0x0 */ BE(u32) mMagic; // 'C-DF'.
|
||||
/* 0x0 */ u8 _00[4];
|
||||
/* 0x4 */ BE(u32) mWaveCount;
|
||||
/* 0x8 */ TOffset<TCtrlWave> mCtrlWaveOffsets[0];
|
||||
};
|
||||
|
||||
struct TCtrlScene {
|
||||
/* 0x0 */ BE(u32) mMagic; // 'SCNE'
|
||||
/* 0x4 */ u8 _00[0x8];
|
||||
/* 0x0 */ u8 _00[0xC];
|
||||
/* 0xC */ TOffset<TCtrl> mCtrlOffset;
|
||||
};
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ struct JASWaveArc : JASDisposer {
|
||||
};
|
||||
|
||||
/* 0x04 */ mutable JASHeap mHeap;
|
||||
/* 0x48 */ u32 mCurrentlyLoaded;
|
||||
/* 0x48 */ u32 _48;
|
||||
/* 0x4C */ volatile s32 mStatus;
|
||||
/* 0x50 */ int mEntryNum;
|
||||
/* 0x54 */ u32 mFileLength;
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
#define JASWAVEINFO_H
|
||||
|
||||
#include <types.h>
|
||||
#include <memory>
|
||||
|
||||
#if TARGET_PC
|
||||
#include "JSystem/JAudio2/JASSampleDataReference.h"
|
||||
#endif
|
||||
|
||||
struct JASWaveArc;
|
||||
|
||||
@@ -22,7 +17,7 @@ struct JASWaveArc;
|
||||
struct JASWaveInfo {
|
||||
JASWaveInfo() {
|
||||
mBaseKey = 0x3c;
|
||||
mpLoaded = &one;
|
||||
field_0x20 = &one;
|
||||
}
|
||||
|
||||
/* 0x00 */ u8 mWaveFormat;
|
||||
@@ -36,7 +31,7 @@ struct JASWaveInfo {
|
||||
/* 0x18 */ int mSampleCount;
|
||||
/* 0x1C */ s16 mpLast;
|
||||
/* 0x1E */ s16 mpPenult;
|
||||
/* 0x20 */ const u32* mpLoaded;
|
||||
/* 0x20 */ const u32* field_0x20;
|
||||
|
||||
static DUSK_GAME_DATA u32 one;
|
||||
};
|
||||
@@ -50,17 +45,6 @@ public:
|
||||
virtual ~JASWaveHandle() {}
|
||||
virtual const JASWaveInfo* getWaveInfo() const = 0;
|
||||
virtual intptr_t getWavePtr() const = 0;
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] virtual void const* getAramBaseAddress() const = 0;
|
||||
|
||||
/**
|
||||
* Create a @ref JASSampleDataReference to keep the sample data for this wave alive.
|
||||
*/
|
||||
[[nodiscard]] virtual std::unique_ptr<JASSampleDataReference> getSampleReference() const { return nullptr; }
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,12 +53,6 @@ public:
|
||||
*/
|
||||
class JASWaveBank {
|
||||
public:
|
||||
#if TARGET_PC
|
||||
const u32 bankId;
|
||||
|
||||
JASWaveBank(u32 bankId) : bankId(bankId) { }
|
||||
#endif
|
||||
|
||||
virtual ~JASWaveBank() {}
|
||||
virtual JASWaveHandle* getWaveHandle(u32) const = 0;
|
||||
virtual JASWaveArc* getWaveArc(u32) = 0;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
struct JAUAudibleParam {
|
||||
f32 getDopplerPower() const {
|
||||
return field_0x0.bytes.mDopplerPower * (1.0f / 15.0f);
|
||||
return field_0x0.bytes.b0_0 * (1.0f / 15.0f);
|
||||
}
|
||||
|
||||
union {
|
||||
@@ -19,18 +19,14 @@ struct JAUAudibleParam {
|
||||
BE(u16) f1;
|
||||
} half;
|
||||
struct {
|
||||
u8 mDopplerPower : 4;
|
||||
u8 mCalculatePriority : 1;
|
||||
u8 mCalcDistanceVolume : 1;
|
||||
u8 mCalcFxMix : 1;
|
||||
u8 mCullAtMaxDistance : 1;
|
||||
u8 mCalcPan : 1;
|
||||
u8 mCalcDolby : 1;
|
||||
/**
|
||||
* Most bits in this field are unused, 8 indicates clamping of volume
|
||||
* to ensure it doesn't go below 0.2 in mixChannelOut()
|
||||
*/
|
||||
u8 mClampMinVolume : 6;
|
||||
u8 b0_0 : 4;
|
||||
u8 b0_4 : 1;
|
||||
u8 b0_5 : 1;
|
||||
u8 b0_6 : 1;
|
||||
u8 b0_7 : 1;
|
||||
u8 b1_0 : 1;
|
||||
u8 b1_1 : 1;
|
||||
u8 b1_2_7 : 6;
|
||||
u8 b2;
|
||||
u8 b3;
|
||||
} bytes;
|
||||
|
||||
@@ -10,10 +10,8 @@
|
||||
*/
|
||||
class JAUSoundInfo : public JASGlobalInstance<JAUSoundInfo> {
|
||||
public:
|
||||
IF_DUSK(using SoundTableReplacementSlot2 = dusk::mods::svc::audio_res::bst::SoundTableReplacementSlot);
|
||||
|
||||
JAUSoundInfo(bool param_0) : JASGlobalInstance<JAUSoundInfo>(param_0) {}
|
||||
virtual u16 getAudibleSw(JAISoundID IF_DUSK_ARG(SoundTableReplacementSlot2 const*)) const = 0;
|
||||
virtual u16 getAudibleSw(JAISoundID) const = 0;
|
||||
virtual u16 getBgmSeqResourceID(JAISoundID) const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,179 +5,16 @@
|
||||
#include "JSystem/JAudio2/JASGadget.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
// Constants for TypeIDs of JAUSoundTable entries.
|
||||
|
||||
/**
|
||||
* Used as a test to see if the type ID is valid. All other type IDs contain this bit.
|
||||
*/
|
||||
#define SOUND_TYPEID_VALID 0x40
|
||||
|
||||
/**
|
||||
* Sound is a sound effect.
|
||||
*/
|
||||
#define SOUND_TYPEID_SOUND_EFFECT 0x51
|
||||
|
||||
/**
|
||||
* Sound is a music sequence.
|
||||
*/
|
||||
#define SOUND_TYPEID_SEQUENCE 0x60
|
||||
|
||||
/**
|
||||
* Sound is a streamed music file.
|
||||
*/
|
||||
#define SOUND_TYPEID_STREAM 0x70
|
||||
|
||||
/**
|
||||
* Sound is a streamed music file. Unsure of difference from SOUND_TYPEID_STREAM
|
||||
*/
|
||||
#define SOUND_TYPEID_STREAM_ALT 0x71
|
||||
|
||||
//
|
||||
// Values for mSwBit on sound effect items.
|
||||
//
|
||||
|
||||
/**
|
||||
* Sound is always calculated as max priority (0).
|
||||
*/
|
||||
#define SOUND_SW_ALWAYS_MAX_PRIORITY 0x0000'0001
|
||||
|
||||
/**
|
||||
* Don't calculate volume by distance.
|
||||
*/
|
||||
#define SOUND_SW_IGNORE_DISTANCE_VOL 0x0000'0002
|
||||
|
||||
/**
|
||||
* Don't calculate FX mix (reverb) by distance.
|
||||
*/
|
||||
#define SOUND_SW_IGNORE_FX_MIX 0x0000'0004
|
||||
|
||||
/**
|
||||
* Mute all BGM sequences while this sound is playing.
|
||||
*/
|
||||
#define SOUND_SW_MUTE_BGM 0x0000'0008
|
||||
|
||||
/**
|
||||
* Offset to shift to access @see SOUND_SW_RANDOM_PITCH_MASK
|
||||
*/
|
||||
#define SOUND_SW_RANDOM_PITCH_OFFSET 4
|
||||
|
||||
/**
|
||||
* 4-bit value (0-15) to control the power of pitch randomization on sound playback.
|
||||
* Code acts different for values above 8, not sure what the exact implication is.
|
||||
*/
|
||||
#define SOUND_SW_RANDOM_PITCH_MASK 0x0000'00F0
|
||||
|
||||
/**
|
||||
* Offset to shift to access @see SOUND_SW_DOPPLER_POWER_MASK
|
||||
*/
|
||||
#define SOUND_SW_DOPPLER_POWER_OFFSET 8
|
||||
|
||||
/**
|
||||
* 4-bit value (0-15) to scale the power of the Doppler effect for this sound.
|
||||
*/
|
||||
#define SOUND_SW_DOPPLER_POWER_MASK 0x0000'0F00
|
||||
|
||||
/**
|
||||
* Don't calculate panning (left/right) values for this sound.
|
||||
*/
|
||||
#define SOUND_SW_IGNORE_PAN 0x0000'1000
|
||||
|
||||
/**
|
||||
* Don't calculate Dolby (behind/front) values for this sound.
|
||||
*/
|
||||
#define SOUND_SW_IGNORE_DOLBY 0x0000'2000
|
||||
|
||||
/**
|
||||
* Unsure. Relates to Z2 pooling of sound handles.
|
||||
*/
|
||||
#define SOUND_SW_POOL_FLAG_1 0x0000'4000
|
||||
|
||||
/**
|
||||
* Unsure. Relates to Z2 pooling of sound handles.
|
||||
*/
|
||||
#define SOUND_SW_POOL_FLAG_2 0x0000'8000
|
||||
|
||||
/**
|
||||
* 3-bit mask used to select a volume distance/falloff class for this sound.
|
||||
*/
|
||||
#define SOUND_SW_VOL_DIST_BIT_MASK 0x0007'0000
|
||||
#define SOUND_SW_VOL_DIST_BIT_OFFSET 16
|
||||
|
||||
/**
|
||||
* Limit minimum volume of this sound (after distance falloff) to 0.2.
|
||||
*/
|
||||
#define SOUND_SW_CLAMP_MIN_VOLUME 0x0008'0000
|
||||
|
||||
/**
|
||||
* 3-bit mask used to select a *different* volume distance/falloff class for this sound.
|
||||
* @see SOUND_SW_VOL_DIST_BIT_MASK must be zero for this to work.
|
||||
*/
|
||||
#define SOUND_SW_VOL_DIST_BIT_2_MASK 0x0070'0000
|
||||
#define SOUND_SW_VOL_DIST_BIT_2_OFFSET 20
|
||||
|
||||
/**
|
||||
* Mark sound as "far away" or "culled" when at max distance (selected by distance class).
|
||||
* This affects a bunch of stuff like culling, automatic stopping, priorities, etc.
|
||||
*/
|
||||
#define SOUND_SW_CULL_AT_MAX_DISTANCE 0x0080'0000
|
||||
|
||||
/**
|
||||
* Not sure what this does.
|
||||
* Something causing volume/pan/dolby adjustment in Z2Audible::setOuterParams?
|
||||
*/
|
||||
#define SOUND_SW_VOL_SOMETHING_MASK 0x0F00'0000
|
||||
|
||||
/**
|
||||
* Offset to shift to access @see SOUND_SW_RANDOM_VOLUME_MASK
|
||||
*/
|
||||
#define SOUND_SW_RANDOM_VOLUME_OFFSET 28
|
||||
|
||||
/**
|
||||
* 4-bit value (0-15) to control the power of volume randomization on sound playback.
|
||||
*/
|
||||
#define SOUND_SW_RANDOM_VOLUME_MASK 0xF000'0000
|
||||
|
||||
#define SOUND_VOL_DIST_BIT_MASK_SHIFTED (SOUND_SW_VOL_DIST_BIT_MASK >> 16)
|
||||
#define SOUND_VOL_DIST_BIT_2_MASK_SHIFTED (SOUND_SW_VOL_DIST_BIT_2_MASK >> 16)
|
||||
#define SOUND_VOL_SOMETHING_MASK_SHIFTED (SOUND_SW_VOL_SOMETHING_MASK >> 16)
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jaudio
|
||||
* A single entry in the sound table.
|
||||
* Fields are interpreted differently depending on the type ID of the entry,
|
||||
* which is not stored in this struct.
|
||||
*
|
||||
*/
|
||||
struct JAUSoundTableItem {
|
||||
u8 mPriority;
|
||||
u8 mVolume;
|
||||
union {
|
||||
/**
|
||||
* For music sequences: the resource ID of the sequence.
|
||||
*/
|
||||
BE(u16) mResourceId;
|
||||
|
||||
/**
|
||||
* For streamed music: bitpacked channel configuration.
|
||||
*/
|
||||
BE(u16) mStreamPanParameters;
|
||||
};
|
||||
union {
|
||||
/**
|
||||
* For sound effects: bitpacked field controlling a *bunch* of audio parameters.
|
||||
*/
|
||||
BE(u32) mSwBit;
|
||||
|
||||
/**
|
||||
* For streamed music: offset (relative to start of BST)
|
||||
* to null-terminated string containing music file path.
|
||||
*/
|
||||
BE(u32) mStreamFilePath;
|
||||
};
|
||||
|
||||
/**
|
||||
* For sound effects: pitch multiplier.
|
||||
*/
|
||||
BE(f32) mPitch;
|
||||
u8 field_0x1;
|
||||
BE(u16) mResourceId;
|
||||
BE(u32) field_0x4;
|
||||
BE(f32) field_0x8;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -187,25 +24,23 @@ struct JAUSoundTableItem {
|
||||
template<typename Root, typename Section, typename Group, typename Typename_0>
|
||||
struct JAUSoundTable_ {
|
||||
JAUSoundTable_() {
|
||||
mData = NULL;
|
||||
mRoot = 0;
|
||||
field_0x0 = NULL;
|
||||
field_0x4 = 0;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mData = NULL;
|
||||
mRoot = NULL;
|
||||
field_0x0 = NULL;
|
||||
field_0x4 = NULL;
|
||||
}
|
||||
|
||||
void init(const void* dataStart) {
|
||||
mData = dataStart;
|
||||
void init(const void* param_0) {
|
||||
field_0x0 = param_0;
|
||||
// magic number is not in debug rom. I'm not sure what this comparison is (maybe some sort of '' number?)
|
||||
// I also do not know how it is different between JAUSoundTable and JAUSoundNameTable
|
||||
// Future person here: This is checking for either "BST " or "BSTN", with the second two letters in Root::magicNumber().
|
||||
// Idk why the operations here are all weird but I can't use objdiff right now.
|
||||
if (*(BE(u32)*)mData + 0xbdad0000 != Root::magicNumber()) {
|
||||
mData = NULL;
|
||||
if (*(BE(u32)*)field_0x0 + 0xbdad0000 != Root::magicNumber()) {
|
||||
field_0x0 = NULL;
|
||||
} else {
|
||||
mRoot = (Root*)((u8*)mData + *((BE(u32)*)mData + 3));
|
||||
field_0x4 = (Root*)((u8*)field_0x0 + *((BE(u32)*)field_0x0 + 3));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,34 +48,34 @@ struct JAUSoundTable_ {
|
||||
if (index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if ((u32)index >= mRoot->mSectionNumber) {
|
||||
if ((u32)index >= field_0x4->mSectionNumber) {
|
||||
return NULL;
|
||||
}
|
||||
u32 offset = mRoot->mSectionOffsets[index];
|
||||
u32 offset = field_0x4->mSectionOffsets[index];
|
||||
if (offset == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return (Section*)((u8*)mData + offset);
|
||||
return (Section*)((u8*)field_0x0 + offset);
|
||||
}
|
||||
|
||||
Group* getGroup(Section* section, int index) const {
|
||||
Group* getGroup(Section* param_1, int index) const {
|
||||
int iVar1;
|
||||
|
||||
if (index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if ((u32)index >= section->mNumGroups) {
|
||||
if ((u32)index >= param_1->mNumGroups) {
|
||||
return NULL;
|
||||
}
|
||||
u32 offset = section->getGroupOffset(index);
|
||||
u32 offset = param_1->getGroupOffset(index);
|
||||
if (offset == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return (Group*)((u8*)mData + offset);
|
||||
return (Group*)((u8*)field_0x0 + offset);
|
||||
}
|
||||
|
||||
const void* mData;
|
||||
Root* mRoot;
|
||||
const void* field_0x0;
|
||||
Root* field_0x4;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -248,7 +83,7 @@ struct JAUSoundTable_ {
|
||||
*
|
||||
*/
|
||||
struct JAUSoundTableRoot {
|
||||
static inline u32 magicNumber() { return 'T '; } // Second half of "BST "
|
||||
static inline u32 magicNumber() { return 0x5420; }
|
||||
BE(u32) mSectionNumber;
|
||||
BE(u32) mSectionOffsets[0];
|
||||
};
|
||||
@@ -299,7 +134,7 @@ struct JAUSoundTableGroup {
|
||||
|
||||
BE(u32) mNumItems;
|
||||
BE(u32) field_0x4;
|
||||
u8 mTypeIds[0]; // TODO: Should probably be BE(u32), but I can't objdiff rn.
|
||||
u8 mTypeIds[0];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -307,17 +142,13 @@ struct JAUSoundTableGroup {
|
||||
*
|
||||
*/
|
||||
struct JAUSoundTable : public JASGlobalInstance<JAUSoundTable> {
|
||||
#if TARGET_PC
|
||||
using SoundTableReplacementSlot = dusk::mods::svc::audio_res::bst::SoundTableReplacementSlot;
|
||||
#endif
|
||||
|
||||
JAUSoundTable(bool setInstance) : JASGlobalInstance<JAUSoundTable>(setInstance) {
|
||||
JAUSoundTable(bool param_0) : JASGlobalInstance<JAUSoundTable>(param_0) {
|
||||
}
|
||||
~JAUSoundTable() {}
|
||||
|
||||
void init(void const*);
|
||||
u8 getTypeID(JAISoundID IF_DUSK_ARG(SoundTableReplacementSlot const*)) const;
|
||||
JAUSoundTableItem DUSK_CONST* getData(JAISoundID IF_DUSK_ARG(SoundTableReplacementSlot const*)) const;
|
||||
u8 getTypeID(JAISoundID) const;
|
||||
JAUSoundTableItem* getData(JAISoundID) const;
|
||||
int getNumGroups_inSection(u8) const;
|
||||
int getNumItems_inGroup(u8, u8) const;
|
||||
|
||||
@@ -326,11 +157,11 @@ struct JAUSoundTable : public JASGlobalInstance<JAUSoundTable> {
|
||||
if (offset == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return (JAUSoundTableItem*)((u8*)field_0x0.mData + offset);
|
||||
return (JAUSoundTableItem*)((u8*)field_0x0.field_0x0 + offset);
|
||||
}
|
||||
|
||||
const void* getResource() const { return field_0x0.mData; }
|
||||
bool isValid() const { return field_0x0.mData != NULL; }
|
||||
const void* getResource() const { return field_0x0.field_0x0; }
|
||||
bool isValid() const { return field_0x0.field_0x0 != NULL; }
|
||||
|
||||
JAUSoundTable_<JAUSoundTableRoot,JAUSoundTableSection,JAUSoundTableGroup,void> field_0x0;
|
||||
};
|
||||
@@ -340,7 +171,7 @@ struct JAUSoundTable : public JASGlobalInstance<JAUSoundTable> {
|
||||
*
|
||||
*/
|
||||
struct JAUSoundNameTableRoot {
|
||||
static inline u32 magicNumber() { return 'TN'; } // Second half of "BSTN"
|
||||
static inline u32 magicNumber() { return 0x544e; }
|
||||
BE(u32) mSectionNumber;
|
||||
BE(u32) mSectionOffsets[0];
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ struct JAUStreamFileTable {
|
||||
*
|
||||
*/
|
||||
struct JAUStreamDataMgr_StreamFileTable : public JAIStreamDataMgr, JAUStreamFileTable {
|
||||
virtual s32 getStreamFileEntry(JAISoundID IF_DUSK_ARG(StreamReplacementSlot2 const*));
|
||||
virtual s32 getStreamFileEntry(JAISoundID);
|
||||
virtual ~JAUStreamDataMgr_StreamFileTable() {}
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user