Merge branch 'main' into 26-03-27-better-mapping

This commit is contained in:
PJB3005
2026-04-10 03:50:32 +02:00
404 changed files with 14458 additions and 3069 deletions
+206
View File
@@ -0,0 +1,206 @@
name: Build
on:
push:
paths-ignore:
- '*.md'
- '*LICENSE'
pull_request:
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
jobs:
build-linux:
name: Build Linux (${{matrix.name}})
runs-on: ${{matrix.runner}}
strategy:
fail-fast: false
matrix:
include:
- name: GCC x86_64
runner: ubuntu-latest
preset: gcc
artifact_arch: x86_64
- name: GCC aarch64
runner: ubuntu-24.04-arm
preset: gcc
artifact_arch: aarch64
# - name: Clang x86_64
# runner: ubuntu-latest
# preset: clang
# artifact_arch: x86_64
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: recursive
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install ninja-build clang lld openssl libcurl4-openssl-dev \
zlib1g-dev libglu1-mesa-dev libdbus-1-dev libvulkan-dev libxi-dev libxrandr-dev libasound2-dev \
libpulse-dev libudev-dev libpng-dev libncurses5-dev libx11-xcb-dev libfreetype-dev \
libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev libssl-dev \
libxss-dev libfuse2
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.9
- name: Configure CMake
run: cmake --preset x-linux-ci-${{matrix.preset}}
- name: Build
run: cmake --build --preset x-linux-ci-${{matrix.preset}}
- name: Generate AppImage
run: ci/build-appimage.sh
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: dusk-${{env.DUSK_VERSION}}-linux-${{matrix.preset}}-${{matrix.artifact_arch}}
path: |
build/install/Dusk-*.AppImage
build/install/debug.tar.*
build-apple:
name: Build Apple (${{matrix.name}})
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
include:
- name: AppleClang macOS universal
platform: macos
preset: x-macos-ci
artifact_name: macos-appleclang-universal
# - name: AppleClang iOS arm64 # TODO enable when CI is free
# platform: ios
# preset: x-ios-ci
# artifact_name: ios-appleclang-arm64
# - name: AppleClang tvOS arm64 # TODO enable when CI is free
# platform: tvos
# preset: x-tvos-ci
# artifact_name: tvos-appleclang-arm64
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: recursive
- name: Update Homebrew
if: matrix.platform == 'tvos'
run: |
brew update
brew upgrade --formula
- name: Install dependencies
run: brew install cmake ninja
- name: Install markupsafe
if: matrix.platform == 'tvos'
run: pip3 install --break-system-packages markupsafe
- name: Install Rust iOS target
if: matrix.platform == 'ios'
run: rustup target add aarch64-apple-ios
- name: Install Rust tvOS target
if: matrix.platform == 'tvos'
run: |
rustup toolchain install nightly
rustup target add --toolchain nightly aarch64-apple-tvos
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.9
- name: Configure CMake
run: cmake --preset ${{matrix.preset}}
- name: Build
run: cmake --build --preset ${{matrix.preset}}
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: dusk-${{env.DUSK_VERSION}}-${{matrix.artifact_name}}
path: |
build/install/Dusk.app
build/install/debug.tar.*
build-windows:
name: Build Windows (${{matrix.name}})
runs-on: ${{matrix.runner}}
env:
BUILD_DIR: C:\build
SCCACHE_DIR: C:\sccache
strategy:
fail-fast: false
matrix:
include:
- name: MSVC x86_64
runner: windows-latest
preset: msvc
msvc_arch: amd64
vcpkg_arch: x64
artifact_arch: x86_64
- name: MSVC arm64
runner: windows-11-arm
preset: arm64-msvc
msvc_arch: arm64
vcpkg_arch: arm64
artifact_arch: arm64
# - name: Clang x86_64
# runner: windows-latest
# preset: clang
# msvc_arch: amd64
# vcpkg_arch: x64
# artifact_arch: x86_64
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: recursive
- name: Enable Visual Studio environment
uses: ilammy/msvc-dev-cmd@v1
with:
arch: ${{matrix.msvc_arch}}
# msvc-dev-cmd sets VCPKG_ROOT, set it back
- name: Override VCPKG_ROOT
run: echo "VCPKG_ROOT=C:\vcpkg" >> $env:GITHUB_ENV
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.9
- name: Install dependencies
run: |
choco install ninja
vcpkg install zlib:${{matrix.vcpkg_arch}}-windows-static bzip2:${{matrix.vcpkg_arch}}-windows-static `
zstd:${{matrix.vcpkg_arch}}-windows-static liblzma:${{matrix.vcpkg_arch}}-windows-static `
freetype:${{matrix.vcpkg_arch}}-windows-static
- name: Configure CMake
run: cmake --preset x-windows-ci-${{matrix.preset}}
- name: Build
run: cmake --build --preset x-windows-ci-${{matrix.preset}}
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: dusk-${{env.DUSK_VERSION}}-win32-msvc-${{matrix.artifact_arch}}
path: |
${{env.BUILD_DIR}}/install/*.exe
${{env.BUILD_DIR}}/install/debug.7z
+11
View File
@@ -17,6 +17,10 @@ orig/*/*
*.map
*.MAP
# Save files
*.raw
*.gci
# Build files
build/
.ninja_*
@@ -32,9 +36,16 @@ compile_commands.json
# Miscellaneous
*.exe
*.zip
# MacOS
.DS_Store
# ISOs
*.iso
*.ini
*.controller
pipeline_cache.bin
extract
+7 -3
View File
@@ -1,5 +1,10 @@
{
"cmake.buildDirectory": "${workspaceFolder}/build/dusk/${buildType}/${variant:platform}/${variant:tp_version}",
"cmake.buildDirectory": "${workspaceFolder}/build/dusk/${buildType}/${variant:tp_version}",
"cmake.generator": "Ninja",
"cmake.configureSettings": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
},
"cmake.copyCompileCommands": "${workspaceFolder}/compile_commands.json",
"[c]": {
"files.encoding": "utf8",
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
@@ -44,8 +49,7 @@
"build.ninja": true,
".ninja_*": true,
"objdiff.json": true,
".cache/**": true,
"compile_commands.json": true,
".cache/**": true
},
"clangd.arguments": [
"--function-arg-placeholders=0",
+318 -36
View File
@@ -1,14 +1,86 @@
cmake_minimum_required(VERSION 3.13)
if (APPLE)
project(dusk LANGUAGES C CXX OBJC OBJCXX)
else ()
project(dusk LANGUAGES C CXX)
cmake_minimum_required(VERSION 3.25)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Build type options: Debug Release RelWithDebInfo MinSizeRel" FORCE)
endif ()
# 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 ${CMAKE_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --git-path HEAD
OUTPUT_VARIABLE dusk_git_head_filename
OUTPUT_STRIP_TRAILING_WHITESPACE)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${dusk_git_head_filename}")
execute_process(WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --symbolic-full-name HEAD
OUTPUT_VARIABLE dusk_git_head_symbolic
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${GIT_EXECUTABLE} rev-parse --git-path ${dusk_git_head_symbolic}
OUTPUT_VARIABLE dusk_git_head_symbolic_filename
OUTPUT_STRIP_TRAILING_WHITESPACE)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${dusk_git_head_symbolic_filename}")
# defines DUSK_WC_REVISION
execute_process(WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
OUTPUT_VARIABLE DUSK_WC_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE)
# defines DUSK_WC_DESCRIBE
execute_process(WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 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 ${CMAKE_SOURCE_DIR} 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 ${CMAKE_SOURCE_DIR} 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)
string(REGEX REPLACE "v([0-9]+)\.([0-9]+)\.([0-9]+)\-([0-9]+).*" "\\1.\\2.\\3.\\4" DUSK_VERSION_STRING "${DUSK_WC_DESCRIBE}")
string(REGEX REPLACE "v([0-9]+)\.([0-9]+)\.([0-9]+).*" "\\1.\\2.\\3" DUSK_SHORT_VERSION_STRING "${DUSK_WC_DESCRIBE}")
else ()
set(DUSK_WC_DESCRIBE "UNKNOWN-VERSION")
set(DUSK_VERSION_STRING "0.0.0")
endif ()
# Add version information to CI environment variables
if(DEFINED ENV{GITHUB_ENV})
file(APPEND "$ENV{GITHUB_ENV}" "DUSK_VERSION=${DUSK_WC_DESCRIBE}\n")
endif()
message(STATUS "Dusk version set to ${DUSK_WC_DESCRIBE}")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
project(dusk LANGUAGES C CXX VERSION ${DUSK_VERSION_STRING})
if (APPLE AND NOT TVOS AND CMAKE_SYSTEM_NAME STREQUAL tvOS)
# ios.toolchain.cmake hack for SDL
set(TVOS ON)
set(IOS OFF)
endif ()
if(APPLE AND NOT CMAKE_OSX_SYSROOT)
# If the Xcode SDK is lagging behind system version, CMake needs this done first
execute_process(COMMAND xcrun --sdk macosx --show-sdk-path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
set(DAWN_USE_WAYLAND ON CACHE BOOL "Enable support for Wayland surface" FORCE)
@@ -17,8 +89,49 @@ set(AURORA_ENABLE_DVD ON CACHE BOOL "Enable DVD API support" FORCE)
set(AURORA_ENABLE_CARD ON CACHE BOOL "Enable CARD API support" FORCE)
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
option(DUSK_BUILD_WARNINGS "If off, compiler warnings will be suppressed")
add_subdirectory(libs/freeverb)
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)
if (DUSK_MOVIE_SUPPORT)
find_package(libjpeg-turbo QUIET)
if (libjpeg-turbo_FOUND)
message(STATUS "dusk: Using system libjpeg-turbo")
else ()
message(STATUS "dusk: Fetching libjpeg-turbo")
include(ExternalProject)
set(_jpeg_install_dir ${CMAKE_BINARY_DIR}/libjpeg-turbo-install)
if (WIN32)
set(_jpeg_lib ${_jpeg_install_dir}/lib/turbojpeg-static.lib)
else ()
set(_jpeg_lib ${_jpeg_install_dir}/lib/libturbojpeg.a)
endif ()
ExternalProject_Add(libjpeg-turbo-ext
URL https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/3.1.0.tar.gz
URL_HASH SHA256=35fec2e1ddfb05ecf6d93e50bc57c1e54bc81c16d611ddf6eff73fff266d8285
CMAKE_ARGS
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX=${_jpeg_install_dir}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}
-DENABLE_SHARED=OFF
-DWITH_TURBOJPEG=ON
-DWITH_JAVA=OFF
BUILD_BYPRODUCTS ${_jpeg_lib}
)
file(MAKE_DIRECTORY ${_jpeg_install_dir}/include)
add_library(libjpeg-turbo::turbojpeg-static STATIC IMPORTED GLOBAL)
set_target_properties(libjpeg-turbo::turbojpeg-static PROPERTIES
IMPORTED_LOCATION ${_jpeg_lib}
INTERFACE_INCLUDE_DIRECTORIES ${_jpeg_install_dir}/include
)
add_dependencies(libjpeg-turbo::turbojpeg-static libjpeg-turbo-ext)
endif ()
endif ()
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
# -Wno-multichar: Multi-character constants ('ABCD') are implementation-defined but all compilers
@@ -38,6 +151,8 @@ elseif (MSVC)
add_compile_options(/bigobj)
add_compile_options(/Zc:strictStrings-)
add_compile_options(/MP)
add_compile_options(/FS)
if (NOT DUSK_BUILD_WARNINGS)
add_compile_options(/W0)
else ()
@@ -53,63 +168,153 @@ endif ()
include(FetchContent)
# Declare all dependencies first so CMake can download them in parallel
message(STATUS "dusk: Fetching cxxopts")
FetchContent_Declare(
cxxopts
GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git
GIT_TAG v3.3.1
FetchContent_Declare(cxxopts
URL https://github.com/jarro2783/cxxopts/archive/refs/tags/v3.3.1.tar.gz
URL_HASH SHA256=3bfc70542c521d4b55a46429d808178916a579b28d048bd8c727ee76c39e2072
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
message(STATUS "dusk: 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 TRUE
)
FetchContent_MakeAvailable(cxxopts json)
FetchContent_MakeAvailable(cxxopts)
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_BINARY_DIR}/version.h)
include(files.cmake)
# TODO: version handling for res includes
set(DUSK_BUNDLE_NAME Dusk)
set(DUSK_BUNDLE_IDENTIFIER dev.decomp.dusk)
set(DUSK_GAME_NAME "GZ2E")
set(DUSK_GAME_VERSION "01")
set(DUSK_TP_VERSION ${DUSK_GAME_NAME}${DUSK_GAME_VERSION})
message(STATUS "dusk: Game Name: ${DUSK_GAME_NAME}")
message(STATUS "dusk: Game Version: ${DUSK_GAME_VERSION}")
message(STATUS "dusk: TP Version: ${DUSK_TP_VERSION}")
message(STATUS "dusk: Game Version: ${DUSK_TP_VERSION}")
source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${JSYSTEM_FILES} ${JSYSTEM_DEBUG_FILES} ${REL_FILES})
source_group("dusk" FILES ${DUSK_FILES})
set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0
DUSK_TP_VERSION="${DUSK_TP_VERSION}" DUSK_GAME_NAME="${DUSK_GAME_NAME}" DUSK_GAME_VERSION="${DUSK_GAME_VERSION}")
set(GAME_INCLUDE_DIRS
include
src
assets/${DUSK_TP_VERSION}
libs/JSystem/include
libs
extern/aurora/include/dolphin
extern
${CMAKE_BINARY_DIR})
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd
aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient)
if (DUSK_MOVIE_SUPPORT)
if (TARGET libjpeg-turbo::turbojpeg-static)
list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg-static)
else ()
list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg)
endif ()
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
endif ()
# game_debug is for game code files that we know work when compiled with DEBUG=1
# Of course, if building a release build, this distinction is irrelevant
add_library(game_debug STATIC ${JSYSTEM_DEBUG_FILES} ${SSYSTEM_FILES})
target_compile_definitions(game_debug PRIVATE TARGET_PC AVOID_UB=1 VERSION=0 $<$<CONFIG:Debug>:DEBUG=1>)
add_library(game_debug OBJECT ${JSYSTEM_DEBUG_FILES} ${SSYSTEM_FILES}
src/dusk/audio/DuskAudioSystem.cpp
src/dusk/audio/JASCriticalSection.cpp
src/dusk/audio/DuskDsp.cpp
src/dusk/audio/Adpcm.cpp
src/dusk/audio/DspStub.cpp
src/dusk/imgui/ImGuiAudio.cpp)
# Make these properties PUBLIC so that the regular game target also sees them.
target_include_directories(game_debug PUBLIC
include
src
assets/${DUSK_TP_VERSION}
libs/JSystem/include
extern/aurora/include/dolphin
extern
${CMAKE_SOURCE_DIR}/build/${DUSK_TP_VERSION}/include
build/${DUSK_TP_VERSION}/include)
target_link_libraries(game_debug PUBLIC aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd aurora::card)
# game_base is for all other game code files
add_library(game_base OBJECT ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${JSYSTEM_FILES} ${REL_FILES} ${DUSK_FILES} ${DOLPHIN_FILES})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(game SHARED ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${SSYSTEM_FILES} ${JSYSTEM_FILES} ${REL_FILES} ${DUSK_FILES} ${DOLPHIN_FILES}
src/dusk/imgui/ImGuiStubLog.cpp)
target_compile_definitions(game_debug PRIVATE ${GAME_COMPILE_DEFS} $<$<CONFIG:Debug>:DEBUG=1> $<$<CONFIG:Debug>:PARTIAL_DEBUG=1>)
target_compile_definitions(game_base PRIVATE ${GAME_COMPILE_DEFS} NDEBUG=1 NDEBUG_DEFINED=1 DEBUG_DEFINED=0 $<$<CONFIG:Debug>:PARTIAL_DEBUG=1>)
# only apply PCH to game_base since not all headers are necessarily validated with DEBUG=1
target_precompile_headers(game_base PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/include/dusk_pch.hpp>")
target_include_directories(game_debug PRIVATE ${GAME_INCLUDE_DIRS})
target_include_directories(game_base PRIVATE ${GAME_INCLUDE_DIRS})
# This implicitly pulls in the library include directories even though no
# linking actually takes place for object libraries
target_link_libraries(game_debug PRIVATE ${GAME_LIBS})
target_link_libraries(game_base PRIVATE ${GAME_LIBS})
# Combined game library
add_library(game STATIC
$<TARGET_OBJECTS:game_base>
$<TARGET_OBJECTS:game_debug>)
target_link_libraries(game PUBLIC ${GAME_LIBS})
target_link_libraries(game PRIVATE game_debug cxxopts::cxxopts)
target_compile_definitions(game PRIVATE TARGET_PC AVOID_UB=1 VERSION=0 NDEBUG=1 NDEBUG_DEFINED=1 DEBUG_DEFINED=0
DUSK_TP_VERSION="${DUSK_TP_VERSION}" DUSK_GAME_NAME="${DUSK_GAME_NAME}" DUSK_GAME_VERSION="${DUSK_GAME_VERSION}")
add_executable(dusk src/dusk/main.cpp)
target_compile_definitions(dusk PRIVATE TARGET_PC AVOID_UB=1 VERSION=0)
target_include_directories(dusk PRIVATE include)
target_link_libraries(dusk PRIVATE game aurora::main)
add_custom_command(TARGET dusk POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_SOURCE_DIR}/res"
"$<TARGET_FILE_DIR:dusk>/res"
COMMENT "Copying resources"
)
if (APPLE)
if (IOS)
set(DUSK_RESOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios)
set(DUSK_INFO_PLIST ${DUSK_RESOURCE_DIR}/Info.plist.in)
file(GLOB_RECURSE DUSK_RESOURCE_FILES "${DUSK_RESOURCE_DIR}/Base.lproj/*")
endif ()
if (IOS OR TVOS)
target_sources(dusk PRIVATE ${DUSK_RESOURCE_FILES})
foreach (FILE ${DUSK_RESOURCE_FILES})
file(RELATIVE_PATH NEW_FILE "${DUSK_RESOURCE_DIR}" ${FILE})
get_filename_component(NEW_FILE_PATH ${NEW_FILE} DIRECTORY)
set_property(SOURCE ${FILE} PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${NEW_FILE_PATH}")
endforeach ()
set_target_properties(
dusk PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_BUNDLE_NAME ${DUSK_BUNDLE_NAME}
MACOSX_BUNDLE_GUI_IDENTIFIER ${DUSK_BUNDLE_IDENTIFIER}
MACOSX_BUNDLE_BUNDLE_VERSION ${DUSK_VERSION_STRING}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${DUSK_SHORT_VERSION_STRING}
OUTPUT_NAME dusk
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "YES"
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES"
)
if (CMAKE_GENERATOR STREQUAL "Xcode")
set_target_properties(dusk PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${DUSK_INFO_PLIST})
elseif (DEFINED DUSK_INFO_PLIST)
set(MACOSX_BUNDLE_EXECUTABLE_NAME dusk)
set(MACOSX_BUNDLE_GUI_IDENTIFIER ${DUSK_BUNDLE_IDENTIFIER})
set(MACOSX_BUNDLE_BUNDLE_NAME ${DUSK_BUNDLE_NAME})
set(MACOSX_BUNDLE_BUNDLE_VERSION ${DUSK_VERSION_STRING})
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${DUSK_SHORT_VERSION_STRING})
set(DUSK_GENERATED_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/dusk.Info.plist)
configure_file(${DUSK_INFO_PLIST} ${DUSK_GENERATED_INFO_PLIST})
add_custom_command(
TARGET dusk POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DUSK_GENERATED_INFO_PLIST} $<TARGET_FILE_DIR:dusk>/Info.plist
VERBATIM
)
endif ()
endif ()
endif ()
include(extern/aurora/cmake/AuroraCopyRuntimeDLLs.cmake)
aurora_copy_runtime_dlls(dusk game)
aurora_copy_runtime_dlls(dusk)
if (DUSK_SELECTED_OPT)
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
@@ -120,4 +325,81 @@ if (DUSK_SELECTED_OPT)
target_compile_options(xxhash PRIVATE ${_opt_flags})
target_compile_options(aurora_gx PRIVATE ${_opt_flags})
target_compile_options(freeverb PRIVATE ${_opt_flags})
endif ()
# Packaging logic
function(get_target_output_name target result_var)
get_target_property(output_name ${target} OUTPUT_NAME)
if (NOT output_name)
set(${result_var} "${target}" PARENT_SCOPE)
else ()
set(${result_var} "${output_name}" PARENT_SCOPE)
endif ()
endfunction()
function(get_target_prefix target result_var)
set(${result_var} "" PARENT_SCOPE)
if (APPLE)
# Have to recreate some bundle logic here, since CMake can't tell us
get_target_property(is_bundle ${target} MACOSX_BUNDLE)
if (is_bundle)
get_target_output_name(${target} output_name)
if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(${result_var} "${output_name}.app/Contents/MacOS/" PARENT_SCOPE)
else ()
set(${result_var} "${output_name}.app/" PARENT_SCOPE)
endif ()
endif ()
endif ()
endfunction()
list(APPEND BINARY_TARGETS dusk)
set(EXTRA_TARGETS "")
if (TARGET crashpad_handler)
list(APPEND EXTRA_TARGETS crashpad_handler)
endif ()
install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX})
if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
set(DEBUG_FILES_LIST "")
foreach (target IN LISTS BINARY_TARGETS EXTRA_TARGETS)
get_target_output_name(${target} output_name)
if (WIN32)
install(FILES $<TARGET_PDB_FILE:${target}> DESTINATION ${CMAKE_INSTALL_PREFIX} OPTIONAL)
elseif (APPLE)
get_target_prefix(${target} target_prefix)
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND rm -fr \"$<TARGET_FILE_NAME:${target}>.dSYM\")")
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND dsymutil \"${target_prefix}$<TARGET_FILE_NAME:${target}>\")")
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND strip -S \"${target_prefix}$<TARGET_FILE_NAME:${target}>\")")
if (NOT target_prefix STREQUAL "")
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND mv \"${target_prefix}$<TARGET_FILE_NAME:${target}>.dSYM\" .)")
endif ()
elseif (UNIX)
get_target_prefix(${target} target_prefix)
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND objcopy --only-keep-debug \"${target_prefix}$<TARGET_FILE_NAME:${target}>\" \"${target_prefix}$<TARGET_FILE_NAME:${target}>.dbg\")")
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND objcopy --strip-debug --add-gnu-debuglink=$<TARGET_FILE_NAME:${target}>.dbg \"${target_prefix}$<TARGET_FILE_NAME:${target}>\")")
endif ()
list(APPEND DEBUG_FILES_LIST "${output_name}")
endforeach ()
if (WIN32)
list(TRANSFORM DEBUG_FILES_LIST APPEND ".pdb")
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND 7z a -t7z \"${CMAKE_INSTALL_PREFIX}/debug.7z\" ${DEBUG_FILES})")
elseif (APPLE)
list(TRANSFORM DEBUG_FILES_LIST APPEND ".dSYM")
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND tar acfv \"${CMAKE_INSTALL_PREFIX}/debug.tar.xz\" ${DEBUG_FILES})")
elseif (UNIX)
list(TRANSFORM DEBUG_FILES_LIST APPEND ".dbg")
list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES)
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND tar -I \"xz -9 -T0\" -cvf \"${CMAKE_INSTALL_PREFIX}/debug.tar.xz\" ${DEBUG_FILES})")
endif ()
endif ()
foreach (target IN LISTS BINARY_TARGETS)
get_target_prefix(${target} target_prefix)
foreach (extra_target IN LISTS EXTRA_TARGETS)
get_target_prefix(${extra_target} extra_prefix)
if (NOT "${target_prefix}" STREQUAL "${extra_prefix}")
# Copy extra target to target prefix
install(CODE "execute_process(WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" COMMAND cp \"${extra_prefix}$<TARGET_FILE_NAME:${extra_target}>\" \"${target_prefix}$<TARGET_FILE_NAME:${extra_target}>\")")
endif ()
endforeach ()
endforeach ()
+603
View File
@@ -0,0 +1,603 @@
{
"version": 2,
"cmakeMinimumRequired": {
"major": 3,
"minor": 25,
"patch": 0
},
"configurePresets": [
{
"name": "debug",
"hidden": true,
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreadedDebugDLL"
}
},
{
"name": "relwithdebinfo",
"hidden": true,
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
"CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreaded"
}
},
{
"name": "linux-default",
"displayName": "Linux (default)",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [
"Linux"
]
},
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
}
}
},
{
"name": "linux-default-debug",
"displayName": "Linux (default) Debug",
"inherits": [
"debug",
"linux-default"
]
},
{
"name": "linux-default-relwithdebinfo",
"displayName": "Linux (default) RelWithDebInfo",
"inherits": [
"relwithdebinfo",
"linux-default"
]
},
{
"name": "linux-clang",
"displayName": "Linux (Clang)",
"inherits": [
"linux-default"
],
"cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++"
}
},
{
"name": "linux-clang-debug",
"displayName": "Linux (Clang) Debug",
"inherits": [
"debug",
"linux-clang"
]
},
{
"name": "linux-clang-relwithdebinfo",
"displayName": "Linux (Clang) RelWithDebInfo",
"inherits": [
"relwithdebinfo",
"linux-clang"
]
},
{
"name": "windows-msvc",
"displayName": "Windows (MSVC)",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [
"Windows"
]
}
}
},
{
"name": "windows-msvc-debug",
"displayName": "Windows (MSVC) Debug",
"inherits": [
"debug",
"windows-msvc"
]
},
{
"name": "windows-msvc-relwithdebinfo",
"displayName": "Windows (MSVC) RelWithDebInfo",
"inherits": [
"relwithdebinfo",
"windows-msvc"
]
},
{
"name": "windows-arm64-msvc",
"displayName": "Windows ARM64 (MSVC)",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"architecture": {
"value": "arm64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install",
"AURORA_DAWN_PROVIDER": "vendor"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [
"Windows"
]
}
}
},
{
"name": "windows-clang",
"displayName": "Windows (Clang)",
"inherits": [
"windows-msvc"
],
"cacheVariables": {
"CMAKE_C_COMPILER": "clang-cl",
"CMAKE_CXX_COMPILER": "clang-cl",
"CMAKE_LINKER": "lld-link"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"intelliSenseMode": "windows-clang-x64"
}
}
},
{
"name": "windows-clang-debug",
"displayName": "Windows (Clang) Debug",
"inherits": [
"debug",
"windows-clang"
]
},
{
"name": "windows-clang-relwithdebinfo",
"displayName": "Windows (Clang) RelWithDebInfo",
"inherits": [
"relwithdebinfo",
"windows-clang"
]
},
{
"name": "macos-default",
"displayName": "macOS (default)",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [
"macOS"
]
}
}
},
{
"name": "macos-default-debug",
"displayName": "macOS (default) Debug",
"inherits": [
"debug",
"macos-default"
]
},
{
"name": "macos-default-relwithdebinfo",
"displayName": "macOS (default) RelWithDebInfo",
"inherits": [
"relwithdebinfo",
"macos-default"
]
},
{
"name": "ios-default",
"displayName": "iOS",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"inherits": [
"relwithdebinfo"
],
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "ios.toolchain.cmake",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install",
"PLATFORM": "OS64",
"DEPLOYMENT_TARGET": "14.0",
"ENABLE_BITCODE": {
"type": "BOOL",
"value": false
},
"ENABLE_ARC": {
"type": "BOOL",
"value": false
},
"Rust_CARGO_TARGET": "aarch64-apple-ios",
"BUILD_SHARED_LIBS": {
"type": "BOOL",
"value": false
},
"CMAKE_DISABLE_FIND_PACKAGE_BZip2": {
"type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_LibLZMA": {
"type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_zstd": {
"type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_Freetype": {
"type": "BOOL",
"value": true
}
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [
"macOS"
]
}
}
},
{
"name": "tvos-default",
"displayName": "tvOS",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"inherits": [
"relwithdebinfo"
],
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "ios.toolchain.cmake",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install",
"PLATFORM": "TVOS",
"DEPLOYMENT_TARGET": "14.5",
"ENABLE_BITCODE": {
"type": "BOOL",
"value": false
},
"Rust_CARGO_TARGET": "aarch64-apple-tvos",
"Rust_TOOLCHAIN": "nightly",
"BUILD_SHARED_LIBS": {
"type": "BOOL",
"value": false
},
"CMAKE_DISABLE_FIND_PACKAGE_BZip2": {
"type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_LibLZMA": {
"type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_zstd": {
"type": "BOOL",
"value": true
}
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [
"macOS"
]
}
}
},
{
"name": "android-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"inherits": [
"relwithdebinfo"
],
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install",
"CMAKE_TOOLCHAIN_FILE": "$env{ANDROID_HOME}/ndk/$env{ANDROID_NDK_VERSION}/build/cmake/android.toolchain.cmake",
"ANDROID_PLATFORM": "android-24"
}
},
{
"name": "android-arm64",
"displayName": "Android (arm64-v8a)",
"inherits": [
"android-base"
],
"cacheVariables": {
"ANDROID_ABI": "arm64-v8a"
}
},
{
"name": "android-x86_64",
"displayName": "Android (x86_64)",
"inherits": [
"android-base"
],
"cacheVariables": {
"ANDROID_ABI": "x86_64"
}
},
{
"name": "x-linux-ci",
"hidden": true,
"inherits": [
"relwithdebinfo"
],
"cacheVariables": {
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
}
},
{
"name": "x-linux-ci-gcc",
"inherits": [
"x-linux-ci",
"linux-default"
]
},
{
"name": "x-linux-ci-clang",
"inherits": [
"x-linux-ci",
"linux-clang"
]
},
{
"name": "x-macos-ci",
"inherits": [
"macos-default-relwithdebinfo"
],
"cacheVariables": {
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
}
},
{
"name": "x-ios-ci",
"inherits": [
"ios-default"
],
"cacheVariables": {
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
}
},
{
"name": "x-tvos-ci",
"inherits": [
"tvos-default"
],
"cacheVariables": {
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
}
},
{
"name": "x-windows-ci",
"hidden": true,
"inherits": [
"relwithdebinfo"
],
"binaryDir": "$env{BUILD_DIR}",
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "$env{BUILD_DIR}/install",
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache",
"CMAKE_MSVC_DEBUG_INFORMATION_FORMAT": "Embedded"
}
},
{
"name": "x-windows-ci-msvc",
"inherits": [
"x-windows-ci",
"windows-msvc"
]
},
{
"name": "x-windows-ci-clang",
"inherits": [
"x-windows-ci",
"windows-clang"
]
},
{
"name": "x-windows-ci-arm64-msvc",
"inherits": [
"x-windows-ci",
"windows-arm64-msvc"
]
}
],
"buildPresets": [
{
"name": "linux-default-debug",
"configurePreset": "linux-default-debug",
"description": "Linux (default) debug build",
"displayName": "Linux (default) Debug"
},
{
"name": "linux-default-relwithdebinfo",
"configurePreset": "linux-default-relwithdebinfo",
"description": "Linux (default) release build with debug info",
"displayName": "Linux (default) RelWithDebInfo"
},
{
"name": "linux-clang-debug",
"configurePreset": "linux-clang-debug",
"description": "Linux (Clang) debug build",
"displayName": "Linux (Clang) Debug"
},
{
"name": "linux-clang-relwithdebinfo",
"configurePreset": "linux-clang-relwithdebinfo",
"description": "Linux (Clang) release build with debug info",
"displayName": "Linux (Clang) RelWithDebInfo"
},
{
"name": "macos-default-debug",
"configurePreset": "macos-default-debug",
"description": "macOS debug build",
"displayName": "macOS Debug"
},
{
"name": "macos-default-relwithdebinfo",
"configurePreset": "macos-default-relwithdebinfo",
"description": "macOS release build with debug info",
"displayName": "macOS RelWithDebInfo"
},
{
"name": "ios-default",
"configurePreset": "ios-default",
"description": "iOS release build with debug info",
"displayName": "iOS RelWithDebInfo",
"targets": [
"dusk"
]
},
{
"name": "tvos-default",
"configurePreset": "tvos-default",
"description": "tvOS release build with debug info",
"displayName": "tvOS RelWithDebInfo",
"targets": [
"dusk"
]
},
{
"name": "android-arm64",
"configurePreset": "android-arm64",
"description": "Android arm64-v8a release build with debug info",
"displayName": "Android arm64-v8a RelWithDebInfo",
"targets": [
"dusk"
]
},
{
"name": "android-x86_64",
"configurePreset": "android-x86_64",
"description": "Android x86_64 release build with debug info",
"displayName": "Android x86_64 RelWithDebInfo",
"targets": [
"dusk"
]
},
{
"name": "windows-msvc-debug",
"configurePreset": "windows-msvc-debug",
"description": "Windows (MSVC) debug build",
"displayName": "Windows (MSVC) Debug"
},
{
"name": "windows-msvc-relwithdebinfo",
"configurePreset": "windows-msvc-relwithdebinfo",
"description": "Windows (MSVC) release build with debug info",
"displayName": "Windows (MSVC) RelWithDebInfo"
},
{
"name": "windows-clang-debug",
"configurePreset": "windows-clang-debug",
"description": "Windows (Clang) debug build",
"displayName": "Windows (Clang) Debug"
},
{
"name": "windows-clang-relwithdebinfo",
"configurePreset": "windows-clang-relwithdebinfo",
"description": "Windows (Clang) release build with debug info",
"displayName": "Windows (Clang) RelWithDebInfo"
},
{
"name": "x-linux-ci-gcc",
"configurePreset": "x-linux-ci-gcc",
"description": "(Internal) Linux CI GCC",
"displayName": "(Internal) Linux CI GCC",
"targets": [
"install"
]
},
{
"name": "x-linux-ci-clang",
"configurePreset": "x-linux-ci-clang",
"description": "(Internal) Linux CI Clang",
"displayName": "(Internal) Linux CI Clang",
"targets": [
"install"
]
},
{
"name": "x-macos-ci",
"configurePreset": "x-macos-ci",
"description": "(Internal) macOS CI",
"displayName": "(Internal) macOS CI",
"targets": [
"install"
]
},
{
"name": "x-ios-ci",
"configurePreset": "x-ios-ci",
"description": "(Internal) iOS CI",
"displayName": "(Internal) iOS CI",
"targets": [
"install"
]
},
{
"name": "x-tvos-ci",
"configurePreset": "x-tvos-ci",
"description": "(Internal) tvOS CI",
"displayName": "(Internal) tvOS CI",
"targets": [
"install"
]
},
{
"name": "x-windows-ci-msvc",
"configurePreset": "x-windows-ci-msvc",
"description": "(Internal) Windows CI MSVC",
"displayName": "(Internal) Windows CI MSVC",
"targets": [
"install"
]
},
{
"name": "x-windows-ci-clang",
"configurePreset": "x-windows-ci-clang",
"description": "(Internal) Windows CI Clang",
"displayName": "(Internal) Windows CI Clang",
"targets": [
"install"
]
},
{
"name": "x-windows-ci-arm64-msvc",
"configurePreset": "x-windows-ci-arm64-msvc",
"description": "(Internal) Windows CI MSVC arm64",
"displayName": "(Internal) Windows CI MSVC arm64",
"targets": [
"install"
]
}
]
}
+50 -21
View File
@@ -2,22 +2,22 @@
### Building
#### Prerequisites
* [CMake 3.30+](https://cmake.org)
* [CMake 3.25+](https://cmake.org)
* Windows: Install `CMake Tools` in Visual Studio
* macOS: `brew install cmake`
* [Python 3+](https://python.org)
* Windows: [Microsoft Store](https://go.microsoft.com/fwlink?linkID=2082640)
* Verify it's added to `%PATH%` by typing `python` in `cmd`.
* macOS: `brew install python@3`
* **[Windows]** [Visual Studio 2022 Community](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
* **[Windows]** [Visual Studio 2026 Community](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
* Select `C++ Development` and verify the following packages are included:
* `Windows 10 SDK`
* `Windows 11 SDK`
* `CMake Tools`
* `C++ Clang Compiler`
* `C++ Clang-cl`
* **[macOS]** [Xcode 11.5+](https://developer.apple.com/xcode/download/)
* **[Linux]** Actively tested on Ubuntu 20.04, Arch Linux & derivatives.
* Ubuntu 20.04+ packages
* **[macOS]** [Xcode 16.4+](https://developer.apple.com/xcode/download/)
* **[Linux]** Actively tested on Ubuntu 24.04, Arch Linux & derivatives.
* Ubuntu 24.04+ packages
```
build-essential curl git ninja-build clang lld zlib1g-dev libcurl4-openssl-dev \
libglu1-mesa-dev libdbus-1-dev libvulkan-dev libxi-dev libxrandr-dev libasound2-dev libpulse-dev \
@@ -37,35 +37,64 @@
sudo dnf groupinstall "Development Tools" "Development Libraries"
```
#### Setup
1. Clone and initialize the Dusk repository
Clone and initialize the Dusk repository
```sh
git clone --recursive https://github.com/TakaRikka/dusk.git
git clone --recursive https://github.com/TwilitRealm/dusk.git
cd dusk
git pull
git submodule update --recursive
```
2. Generate assets
```sh
cp /path/to/GZ2E01.iso orig/GZ2E01/.
python3 ./configure.py
ninja
git submodule update --init --recursive
```
#### Building
**Visual Studio (Recommended for Windows)**
**CLion (Windows / macOS / Linux)**
Open the project directory in CLion. Enable the appropriate presets for your platform:
![CLion](assets/clion.png)
**Visual Studio (Windows)**
Open the project directory in Visual Studio. The CMake configuration will be loaded automatically.
**ninja (macOS)**
```sh
cmake -B build/dusk -G "Visual Studio 17 2022" -A x64 # Win32 for 32bit
cmake --preset macos-default-relwithdebinfo
cmake --build --preset macos-default-relwithdebinfo
```
**ninja (Windows/macOS/Linux)**
Alternate presets available:
- `macos-default-debug`: Clang, Debug
**ninja (Linux)**
```sh
cmake -B build/dusk -GNinja
ninja -C build/dusk
cmake --preset linux-default-relwithdebinfo
cmake --build --preset linux-default-relwithdebinfo
```
Alternate presets available:
- `linux-default-debug`: GCC, Debug
- `linux-clang-relwithdebinfo`: Clang, RelWithDebInfo
- `linux-clang-debug`: Clang, Debug
**ninja (Windows)**
```sh
cmake --preset windows-msvc-relwithdebinfo
cmake --build --preset windows-msvc-relwithdebinfo
```
Alternate presets available:
- `windows-msvc-debug`: MSVC, Debug
- `windows-clang-relwithdebinfo`: Clang-cl, RelWithDebInfo
- `windows-clang-debug`: Clang-cl, Debug
#### Running
Pass the disc image as a positional argument. Supported formats: ISO (GCM), RVZ, WIA, WBFS, CISO, GCZ
```sh
build/dusk/dusk /path/to/game.rvz
build/{preset}/dusk /path/to/game.rvz
```
If no path is specified, Dusk defaults to `game.iso` in the current working directory.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 543 KiB

+18
View File
@@ -0,0 +1,18 @@
#!/bin/bash -ex
shopt -s extglob
# Get linuxdeploy
cd "$RUNNER_WORKSPACE"
curl -fOL https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-$(uname -m).AppImage
chmod +x linuxdeploy-$(uname -m).AppImage
# Build AppImage
cd "$GITHUB_WORKSPACE"
mkdir -p build/appdir/usr/{bin,share/{applications,icons/hicolor}}
cp build/install/!(*.*) build/appdir/usr/bin
cp -r platforms/freedesktop/{16x16,32x32,48x48,64x64,128x128,256x256,512x512,1024x1024} build/appdir/usr/share/icons/hicolor
cp platforms/freedesktop/dusk.desktop build/appdir/usr/share/applications
cd build/install
VERSION="$DUSK_VERSION" NO_STRIP=1 "$RUNNER_WORKSPACE"/linuxdeploy-$(uname -m).AppImage \
--appdir "$GITHUB_WORKSPACE"/build/appdir --output appimage
-16
View File
@@ -14,22 +14,6 @@ buildType:
long: Optimized, with debug symbols
buildType: RelWithDebInfo
platform:
default: win64
description: Target platform
choices:
win32:
short: Win32
long: Windows 32-bit (MSVC)
settings:
CMAKE_GENERATOR_PLATFORM: Win32
win64:
short: Win64
long: Windows 64-bit (MSVC)
settings:
CMAKE_GENERATOR_PLATFORM: x64
tp_version:
default: GZ2E01
description: TP Version
+4
View File
@@ -1,5 +1,9 @@
#!/usr/bin/env python3
print("You do not need to run configure.py for Dusk! This file is here to avoid conflicts with decomp.")
print("Use CMake to configure your build instead.")
exit(1)
###
# Generates build files for the project.
# This file also includes the project configuration,
+1 -1
+14 -4
View File
@@ -507,10 +507,6 @@ set(JSYSTEM_DEBUG_FILES
libs/JSystem/src/JAudio2/JASDSPInterface.cpp
libs/JSystem/src/JAudio2/JASDriverIF.cpp
libs/JSystem/src/JAudio2/JASSoundParams.cpp
libs/JSystem/src/JAudio2/dspproc.cpp
libs/JSystem/src/JAudio2/dsptask.cpp
libs/JSystem/src/JAudio2/osdsp.cpp
libs/JSystem/src/JAudio2/osdsp_task.cpp
libs/JSystem/src/JAudio2/JAIAudible.cpp
libs/JSystem/src/JAudio2/JAIAudience.cpp
libs/JSystem/src/JAudio2/JAISe.cpp
@@ -1336,20 +1332,34 @@ set(DOLPHIN_FILES
set(DUSK_FILES
include/dusk/endian_gx.hpp
include/dusk/config.hpp
include/dusk/dvd_asset.hpp
src/dusk/dvd_asset.cpp
src/d/actor/d_a_alink_dusk.cpp
src/dusk/asserts.cpp
src/dusk/config.cpp
src/dusk/settings.cpp
src/dusk/logging.cpp
src/dusk/layout.cpp
src/dusk/stubs.cpp
src/dusk/endian.cpp
src/dusk/extras.c
src/dusk/extras.cpp
src/dusk/io.cpp
src/dusk/globals.cpp
src/dusk/settings.cpp
#src/dusk/m_Do_ext_dusk.cpp
src/dusk/imgui/ImGuiConfig.hpp
src/dusk/imgui/ImGuiConsole.hpp
src/dusk/imgui/ImGuiConsole.cpp
src/dusk/imgui/ImGuiEngine.cpp
src/dusk/imgui/ImGuiEngine.hpp
src/dusk/imgui/ImGuiMenuGame.cpp
src/dusk/imgui/ImGuiMenuGame.hpp
src/dusk/imgui/ImGuiMenuTools.cpp
src/dusk/imgui/ImGuiMenuTools.hpp
src/dusk/imgui/ImGuiMenuEnhancements.cpp
src/dusk/imgui/ImGuiMenuEnhancements.hpp
src/dusk/imgui/ImGuiProcessOverlay.cpp
src/dusk/imgui/ImGuiCameraOverlay.cpp
src/dusk/imgui/ImGuiHeapOverlay.cpp
+1 -1
View File
@@ -15,7 +15,7 @@ public:
/* 0x0400 */ cCcD_Obj* mpObjTg[0x300];
/* 0x1000 */ cCcD_Obj* mpObjCo[0x100];
/* 0x1400 */ cCcD_Obj* mpObj[0x500];
#if DEBUG
#if TARGET_PC || DEBUG
/* 0x2800 */ u32 m_debug_code;
#endif
/* 0x2800 */ u16 mObjAtCount;
+2 -2
View File
@@ -18,10 +18,10 @@ public:
SpkTable(void);
void setResource(void* res);
inline s32 getName(s32 num) {
inline const char* getName(s32 num) {
JUT_ASSERT(0x35, num >= 0);
JUT_ASSERT(0x36, num < mNumOfSound);
return *(mDataOffsets + num);
return (const char*)*(mDataOffsets + num);
}
inline s32 getNumOfSound() const { return mNumOfSound; }
inline bool isValid(void) const { return mIsInitialized; }
+1 -1
View File
@@ -19,7 +19,7 @@ public:
static SpkSoundHandle* getHandleSoundID(s32 soundNum);
static SpkSoundHandle* start(s32 id, s32 chan);
static SpkSoundHandle* startLevel(s32 id, s32 chan);
static s32 getName(s32 num);
static const char* getName(s32 num);
static s32 getNumOfSound(void);
static void stopAll(s32 chan, s32 msec);
static void stop(s32 chan);
+1 -1
View File
@@ -26,7 +26,7 @@ public:
virtual ~Z2HioSeSeqDataMgr() {}
virtual SeqDataReturnValue getSeqData(JAISoundID param_1, JAISeqData* param_2) {
if (field_0x18->getSeqList()->getSeqData(param_1, param_2)) {
param_2->field_0x4 = 4;
param_2->mOffset = 4;
return SeqDataReturnValue_2;
} else {
return JAUSeqDataMgr_SeqCollection::getSeqData(param_1, param_2);
+4
View File
@@ -6,6 +6,9 @@
#include "JSystem/JAudio2/JASAudioThread.h"
#include "JSystem/JAudio2/JAUSoundTable.h"
#if TARGET_PC
#define AUDIO_INSTANCES
#else
#define AUDIO_INSTANCES \
template<> JASDefaultBankTable* JASGlobalInstance<JASDefaultBankTable>::sInstance; \
template<> JASAudioThread* JASGlobalInstance<JASAudioThread>::sInstance; \
@@ -32,5 +35,6 @@
template<> Z2EnvSeMgr* JASGlobalInstance<Z2EnvSeMgr>::sInstance; \
template<> Z2SpeechMgr* JASGlobalInstance<Z2SpeechMgr>::sInstance; \
template<> Z2WolfHowlMgr* JASGlobalInstance<Z2WolfHowlMgr>::sInstance;
#endif
#endif
+1 -1
View File
@@ -22,7 +22,7 @@ public:
bool isActive() const;
Z2SoundHandlePool* getHandleSoundID(JAISoundID soundID);
Z2SoundHandlePool* getHandleUserData(u32 userData);
Z2SoundHandlePool* getHandleUserData(uintptr_t userData);
void stopAllSounds(u32 fadeTime);
+22 -32
View File
@@ -3,6 +3,7 @@
#include "JSystem/JAWExtSystem/JAWWindow.h"
#include "JSystem/JAudio2/JAISoundHandles.h"
#include "JSystem/JAudio2/JAUSoundTable.h"
class Z2SoundPlayer : public JAWWindow {
public:
@@ -24,43 +25,32 @@ public:
virtual void onKeyRight(const JUTGamePad&);
u32 getCursorMoveMax(const JUTGamePad&);
int getMenuNumberMax();
void correctSeNumber();
/* 0x3ED */ u8 field_0x3ed;
/* 0x3EE */ u8 field_0x3ee;
/* 0x3EF */ u8 field_0x3ef;
/* 0x3F0 */ u8 field_0x3f0;
/* 0x3F4 */ const char* field_0x3f4;
/* 0x3F8 */ short field_0x3f8;
/* 0x3FA */ short field_0x3fa;
/* 0x3FC */ short field_0x3fc;
/* 0x3FE */ short field_0x3fe;
/* 0x400 */ short field_0x400;
/* 0x402 */ short field_0x402;
/* 0x404 */ const char* field_0x404;
/* 0x408 */ const char* field_0x408;
/* 0x40C */ const char* field_0x40c;
/* 0x410 */ const char* field_0x410;
/* 0x414 */ const char* field_0x414;
/* 0x418 */ const char* field_0x418;
/* 0x41C */ const char* field_0x41c;
/* 0x420 */ const char* field_0x420;
/* 0x424 */ const char* field_0x424;
/* 0x428 */ const char* field_0x428;
/* 0x42C */ const char* field_0x42c;
/* 0x430 */ const char* field_0x430;
/* 0x434 */ const char* field_0x434;
/* 0x438 */ const char* field_0x438;
/* 0x43C */ const char* field_0x43c;
/* 0x440 */ const char* field_0x440;
/* 0x444 */ short field_0x444;
void onDrawSoundItem(JAWGraphContext*, JAUSoundNameTable*, int, const JUtility::TColor&, const JUtility::TColor&, const char*, u32, u32, u32);
/* 0x3ED */ bool field_0x3ed;
/* 0x3EE */ bool field_0x3ee;
/* 0x3EF */ bool field_0x3ef;
/* 0x3F0 */ bool field_0x3f0;
/* 0x3F4 */ const char* m_name;
/* 0x3F8 */ s16 field_0x3f8;
/* 0x3FA */ s16 field_0x3fa;
/* 0x3FC */ s16 field_0x3fc;
/* 0x3FE */ s16 field_0x3fe;
/* 0x400 */ s16 field_0x400;
/* 0x402 */ s16 m_portNum;
/* 0x404 */ const char* m_portNames[16];
/* 0x444 */ s16 m_portVal;
/* 0x446 */ u8 field_0x446;
/* 0x448 */ short* field_0x448[7];
/* 0x464 */ int field_0x464;
/* 0x468 */ int field_0x468;
/* 0x448 */ s16* field_0x448[7];
/* 0x464 */ u32 m_cursorY;
/* 0x468 */ int m_cursorMax;
/* 0x46C */ JAISoundHandle field_0x46c[8];
/* 0x48C */ JAISoundHandles field_0x48c;
/* 0x494 */ JAISoundHandle field_0x494;
/* 0x498 */ JAISoundHandle* field_0x498;
/* 0x498 */ JAISoundHandle* mp_subBgmHandle;
/* 0x49C */ JAISoundHandle field_0x49c;
/* 0x4A0 */ int field_0x4a0;
/* 0x4A4 */ f32 field_0x4a4;
+29
View File
@@ -2,10 +2,39 @@
#define Z2WAVEARCLOADER_H
#include "JSystem/JAWExtSystem/JAWWindow.h"
#include "JSystem/JAudio2/JASWaveArcLoader.h"
#include "JSystem/JAudio2/JASWaveInfo.h"
class Z2WaveArcLoader : public JAWWindow {
public:
Z2WaveArcLoader();
virtual ~Z2WaveArcLoader();
virtual void onDraw(JAWGraphContext*);
void checkWaveBank();
void checkWaveArc();
virtual void onKeyUp(const JUTGamePad&);
virtual void onKeyDown(const JUTGamePad&);
virtual void onKeyLeft(const JUTGamePad&);
virtual void onKeyRight(const JUTGamePad&);
virtual void onTrigA(const JUTGamePad&);
virtual void onTrigB(const JUTGamePad&);
virtual void onTrigZ(const JUTGamePad&);
/* 0x3F0 */ JASWaveBank* mpWaveBank;
/* 0x3F4 */ JASWaveArc* mpWaveArc;
/* 0x3F8 */ u32 mWaveUsedSize;
/* 0x3FC */ int mTotalUsedSize;
/* 0x400 */ u8 mBankNo;
/* 0x404 */ u32 mArcCount;
/* 0x408 */ u32 field_0x408;
/* 0x40C */ u32 field_0x40c;
/* 0x410 */ u32 field_0x410;
/* 0x414 */ u8 field_0x414;
/* 0x415 */ u8 field_0x415;
/* 0x416 */ bool mIsLoadTail;
};
#endif /* Z2WAVEARCLOADER_H */
+4
View File
@@ -4547,6 +4547,10 @@ public:
/* 0x03848 */ cXyz* field_0x3848;
/* 0x0384C */ cXyz* field_0x384c;
/* 0x03850 */ daAlink_procFunc mpProcFunc;
#if TARGET_PC
void handleQuickTransform();
#endif
}; // Size: 0x385C
class daAlinkHIO_data_c : public JORReflexible {
+11 -11
View File
@@ -50,30 +50,30 @@ public:
int create();
/* 0x5AC */ request_of_phase_process_class mPhase;
/* 0x5B4 */ mDoExt_McaMorfSO* mpModelMorf;
/* 0x5B4 */ mDoExt_McaMorfSO* mAnm_p;
/* 0x5B8 */ Z2CreatureEnemy mSound;
/* 0x65C */ cXyz field_0x65c;
/* 0x668 */ csXyz field_0x668;
/* 0x66E */ csXyz field_0x66e;
/* 0x65C */ cXyz mHomePos;
/* 0x668 */ csXyz mTargetWallAngle;
/* 0x66E */ csXyz mWallAngle;
/* 0x674 */ f32 mDownColor;
/* 0x678 */ f32 mBodyScale;
/* 0x67C */ int mAction;
/* 0x680 */ int mMode;
/* 0x684 */ u32 mShadowId;
/* 0x688 */ s16 mTargetAngle;
/* 0x68A */ s16 mTargetStep;
/* 0x68C */ u8 mMoveWaitTimer;
/* 0x68A */ s16 mStepAngle;
/* 0x68C */ u8 mWaitTimer;
/* 0x68E */ s16 mInvulnerabilityTimer;
/* 0x690 */ u8 field_0x690;
/* 0x691 */ u8 field_0x691;
/* 0x692 */ u8 mSwbit;
/* 0x694 */ dBgS_AcchCir mAcchCir;
/* 0x690 */ u8 mIsReturnHome;
/* 0x691 */ u8 arg0;
/* 0x692 */ u8 bitSw;
/* 0x694 */ dBgS_AcchCir mBgc;
/* 0x6D4 */ dBgS_ObjAcch mAcch;
/* 0x8AC */ dCcD_Stts mCcStts;
/* 0x8E8 */ dCcD_Sph mCcSph;
/* 0xA20 */ dCcD_Sph mCcBokkuriSph;
/* 0xB58 */ dCcU_AtInfo mAtInfo;
/* 0xB7C */ u8 mHIOInit;
/* 0xB7C */ u8 mHioSet;
};
STATIC_ASSERT(sizeof(daE_WS_c) == 0xb80);
+87
View File
@@ -1,7 +1,11 @@
#ifndef D_A_MOVIE_PLAYER_H
#define D_A_MOVIE_PLAYER_H
#if !TARGET_PC
#include <thp.h>
#else
#include <atomic>
#endif
#include "f_op/f_op_actor.h"
#include "d/d_drawlist.h"
@@ -11,6 +15,85 @@ struct daMP_THPReadBuffer {
BOOL isValid;
};
#if TARGET_PC
// Copying here because thp.h is probably erroneous in the dolphin lib,
// and it's kind of a problem being there (Aurora owns the headers).
// TODO: Move this stuff in decomp?
typedef struct THPAudioRecordHeader {
BE(u32) offsetNextChannel;
BE(u32) sampleSize;
BE(s16) lCoef[8][2];
BE(s16) rCoef[8][2];
BE(s16) lYn1;
BE(s16) lYn2;
BE(s16) rYn1;
BE(s16) rYn2;
} THPAudioRecordHeader;
typedef struct THPAudioDecodeInfo {
u8* encodeData;
u32 offsetNibbles;
u8 predictor;
u8 scale;
s16 yn1;
s16 yn2;
} THPAudioDecodeInfo;
typedef struct THPTextureSet {
u8* ytexture;
u8* utexture;
u8* vtexture;
s32 frameNumber;
} THPTextureSet;
typedef struct THPAudioBuffer {
s16* buffer;
s16* curPtr;
u32 validSample;
} THPAudioBuffer;
typedef struct THPVideoInfo {
BE(u32) xSize;
BE(u32) ySize;
BE(u32) videoType;
} THPVideoInfo;
typedef struct THPAudioInfo {
BE(u32) sndChannels;
BE(u32) sndFrequency;
BE(u32) sndNumSamples;
BE(u32) sndNumTracks;
} THPAudioInfo;
typedef struct THPFrameCompInfo {
BE(u32) numComponents;
u8 frameComp[16];
} THPFrameCompInfo;
typedef struct THPHeader {
/* 0x00 */ char magic[4];
/* 0x04 */ BE(u32) version;
/* 0x08 */ BE(u32) bufsize;
/* 0x0C */ BE(u32) audioMaxSamples;
/* 0x10 */ BE(f32) frameRate;
/* 0x14 */ BE(u32) numFrames;
/* 0x18 */ BE(u32) firstFrameSize;
/* 0x1C */ BE(u32) movieDataSize;
/* 0x20 */ BE(u32) compInfoDataOffsets;
/* 0x24 */ BE(u32) offsetDataOffsets;
/* 0x28 */ BE(u32) movieDataOffsets;
/* 0x2C */ BE(u32) finalFrameDataOffsets;
} THPHeader;
static u32 THPAudioDecode(s16* audioBuffer, u8* audioFrame, s32 flag);
static s32 __THPAudioGetNewSample(THPAudioDecodeInfo* info);
static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr);
#define THP_AUDIO_BUFFER_COUNT 3
#define THP_READ_BUFFER_COUNT 10
#define THP_TEXTURE_SET_COUNT 3
#endif
struct daMP_THPPlayer {
/* 0x000 */ DVDFileInfo fileInfo;
/* 0x03C */ THPHeader header;
@@ -34,7 +117,11 @@ struct daMP_THPPlayer {
/* 0x0C8 */ s64 retaceCount;
/* 0x0D0 */ s32 prevCount;
/* 0x0D4 */ s32 curCount;
#if TARGET_PC
/* 0x0D8 */ std::atomic<s32> videoDecodeCount;
#else
/* 0x0D8 */ s32 videoDecodeCount;
#endif
/* 0x0DC */ f32 curVolume;
/* 0x0E0 */ f32 targetVolume;
/* 0x0E4 */ f32 deltaVolume;
+1 -1
View File
@@ -77,7 +77,7 @@ public:
int CreateHeap();
int Delete();
int Execute();
void Draw();
int Draw();
static BOOL createHeapCallBack(fopAc_ac_c*);
static BOOL ctrlJointCallBack(J3DJoint*, int);
bool getType();
+5
View File
@@ -103,6 +103,11 @@ public:
/* 0x12A48 */ u32 m_Jhana01DL_size;
/* 0x12A4C */ u8* mp_Jhana01_cDL;
/* 0x12A50 */ u32 m_Jhana01_cDL_size;
#if TARGET_PC
TGXTexObj mTexObj_l_J_Ohana00_64TEX;
TGXTexObj mTexObj_l_J_Ohana01_64128_0419TEX;
#endif
}; // Size: 0x12A54
#endif /* D_FLOWER_H */
+2 -2
View File
@@ -108,8 +108,8 @@ public:
/* 0x1D714 */ s16 field_0x1d714;
#if TARGET_PC
GXTexObj mTexObj_l_M_Hijiki00TEX{};
GXTexObj mTexObj_l_M_kusa05_RGBATEX{};
TGXTexObj mTexObj_l_M_Hijiki00TEX;
TGXTexObj mTexObj_l_M_kusa05_RGBATEX;
#endif
}; // Size: 0x1D718
+3
View File
@@ -29,6 +29,9 @@ public:
void _move();
void modeWait();
void modeMove();
#if TARGET_PC
void brightCheckWide();
#endif
void _draw();
void draw() {
+1 -1
View File
@@ -1154,7 +1154,7 @@ public:
static engine_fn engine_tbl[];
/* 0x000 */ camera_class* field_0x0;
#if DEBUG
#if PARTIAL_DEBUG || DEBUG // Ensure struct layout consistent in all TUs.
cXyz dbg_field_0x04[16];
s8 dbg_field_0xc4[0x10];
u32 dbg_field_0xd4;
+49
View File
@@ -17,6 +17,8 @@
#include "m_Do/m_Do_graphic.h"
#include <cstring>
#include "tracy/Tracy.hpp"
enum dComIfG_ButtonStatus {
/* 0x00 */ BUTTON_STATUS_NONE,
/* 0x01 */ BUTTON_STATUS_LET_GO,
@@ -3109,114 +3111,133 @@ inline void dComIfGp_particle_calcMenu() {
}
inline void dComIfGp_particle_draw(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawNormal(i_drawInfo);
}
}
inline void dComIfGp_particle_drawFog(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawNormalFog(i_drawInfo);
}
}
inline void dComIfGp_particle_drawP1(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawNormalP1(i_drawInfo);
}
}
inline void dComIfGp_particle_drawProjection(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawProjection(i_drawInfo);
}
}
inline void dComIfGp_particle_drawNormalPri0_A(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawNormalPri0_A(i_drawInfo);
}
}
inline void dComIfGp_particle_drawNormalPri0_B(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawNormalPri0_B(i_drawInfo);
}
}
inline void dComIfGp_particle_drawFogPri0_A(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawFogPri0_A(i_drawInfo);
}
}
inline void dComIfGp_particle_drawFogPri0_B(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawFogPri0_B(i_drawInfo);
}
}
inline void dComIfGp_particle_drawFogPri1(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawFogPri1(i_drawInfo);
}
}
inline void dComIfGp_particle_drawFogPri2(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawFogPri2(i_drawInfo);
}
}
inline void dComIfGp_particle_drawFogPri3(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawFogPri3(i_drawInfo);
}
}
inline void dComIfGp_particle_drawFogPri4(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawFogPri4(i_drawInfo);
}
}
inline void dComIfGp_particle_drawDarkworld(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawDarkworld(i_drawInfo);
}
}
inline void dComIfGp_particle_drawScreen(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->drawFogScreen(i_drawInfo);
}
}
inline void dComIfGp_particle_draw2Dgame(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->draw2Dgame(i_drawInfo);
}
}
inline void dComIfGp_particle_draw2Dfore(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->draw2Dfore(i_drawInfo);
}
}
inline void dComIfGp_particle_draw2Dback(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->draw2Dback(i_drawInfo);
}
}
inline void dComIfGp_particle_draw2DmenuFore(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->draw2DmenuFore(i_drawInfo);
}
}
inline void dComIfGp_particle_draw2DmenuBack(JPADrawInfo* i_drawInfo) {
ZoneScoped;
if (g_dComIfG_gameInfo.play.getParticle() != NULL) {
g_dComIfG_gameInfo.play.getParticle()->draw2DmenuBack(i_drawInfo);
}
@@ -4736,114 +4757,142 @@ inline void dComIfGd_setViewport(view_port_class* port) {
}
inline void dComIfGd_entryZSortListZxlu(J3DPacket* i_packet, cXyz& param_1) {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.entryZSortListZxlu(i_packet, param_1);
}
inline void dComIfGd_entryZSortXluList(J3DPacket* i_packet, cXyz& param_1) {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.entryZSortXluList(i_packet, param_1);
}
inline void dComIfGd_drawCopy2D() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawCopy2D();
}
inline void dComIfGd_drawOpaListSky() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListSky();
}
inline void dComIfGd_drawXluListSky() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluListSky();
}
inline void dComIfGd_drawOpaListBG() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListBG();
}
inline void dComIfGd_drawOpaListDarkBG() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListDarkBG();
}
inline void dComIfGd_drawOpaListMiddle() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListMiddle();
}
inline void dComIfGd_drawOpaList() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaList();
}
inline void dComIfGd_drawOpaListDark() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListDark();
}
inline void dComIfGd_drawOpaListPacket() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListPacket();
}
inline void dComIfGd_drawXluListBG() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluListBG();
}
inline void dComIfGd_drawXluListDarkBG() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluListDarkBG();
}
inline void dComIfGd_drawXluList() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluList();
}
inline void dComIfGd_drawXluListDark() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluListDark();
}
inline void dComIfGd_drawXluListInvisible() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluListInvisible();
}
inline void dComIfGd_drawOpaListInvisible() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListInvisible();
}
inline void dComIfGd_drawXluListZxlu() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluListZxlu();
}
inline void dComIfGd_drawXluList2DScreen() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluList2DScreen();
}
inline void dComIfGd_drawOpaList3Dlast() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaList3Dlast();
}
inline void dComIfGd_draw2DOpa() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.draw2DOpa();
}
inline void dComIfGd_draw2DOpaTop() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.draw2DOpaTop();
}
inline void dComIfGd_draw2DXlu() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.draw2DXlu();
}
inline void dComIfGd_drawOpaListFilter() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListFilter();
}
inline void dComIfGd_drawIndScreen() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListP0();
}
inline void dComIfGd_drawListZxlu() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluListZxlu();
}
inline void dComIfGd_drawShadow(Mtx param_0) {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawShadow(param_0);
}
inline void dComIfGd_imageDrawShadow(Mtx param_0) {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.imageDrawShadow(param_0);
}
+3
View File
@@ -367,6 +367,9 @@ public:
void menuCursorShow();
void yesnoWakuAlpahAnmInit(u8, u8, u8, u8);
bool yesnoWakuAlpahAnm(u8);
#if TARGET_PC
void fileSelectWide();
#endif
void _draw();
void errorMoveAnmInitSet(int, int);
bool errorMoveAnm();
+8 -8
View File
@@ -66,14 +66,14 @@ struct dMap_prm_res_s {
/* 0x1A7 */ u8 field_0x1a7;
/* 0x1A8 */ u8 field_0x1a8;
/* 0x1A9 */ u8 field_0x1a9;
/* 0x1AA */ s16 field_0x1aa;
/* 0x1AC */ s16 field_0x1ac;
/* 0x1AE */ s16 field_0x1ae;
/* 0x1B0 */ s16 field_0x1b0;
/* 0x1B2 */ s16 field_0x1b2;
/* 0x1B4 */ s16 field_0x1b4;
/* 0x1B6 */ s16 field_0x1b6;
/* 0x1B8 */ f32 cursor_size;
/* 0x1AA */ BE(s16) field_0x1aa;
/* 0x1AC */ BE(s16) field_0x1ac;
/* 0x1AE */ BE(s16) field_0x1ae;
/* 0x1B0 */ BE(s16) field_0x1b0;
/* 0x1B2 */ BE(s16) field_0x1b2;
/* 0x1B4 */ BE(s16) field_0x1b4;
/* 0x1B6 */ BE(s16) field_0x1b6;
/* 0x1B8 */ BE(f32) cursor_size;
};
struct dMap_prm_hio_s {
+1 -1
View File
@@ -5,7 +5,7 @@
#include "JSystem/JHostIO/JORMContext.h"
struct dMpath_RGB5A3_s {
u16 color;
BE(u16) color;
};
namespace dMpath_ColorCnv_n {
+9
View File
@@ -29,6 +29,11 @@ public:
class dMenu_Collect2D_c : public dDlst_base_c {
public:
dMenu_Collect2D_c(JKRExpHeap*, STControl*, CSTControl*);
#if TARGET_PC
void menuCollectWide();
#endif
void _create();
void _delete();
void initialize();
@@ -45,7 +50,11 @@ public:
void changeShield();
void changeClothe();
void setArrowMaxNum(u8);
#if TARGET_PC
void setWalletSizeNum(u16);
#else
void setWalletMaxNum(u16);
#endif
void setSmellType();
void setHeartPiece();
void setPohMaxNum(u8);
+3 -3
View File
@@ -75,9 +75,9 @@ public:
/* 0x00 */ char mName[8];
/* 0x08 */ u8 mRoomNo;
/* 0x09 */ u8 mRegionNo;
/* 0x0A */ u16 mAreaName;
/* 0x0C */ f32 mOffsetX;
/* 0x10 */ f32 mOffsetZ;
/* 0x0A */ BE(u16) mAreaName;
/* 0x0C */ BE(f32) mOffsetX;
/* 0x10 */ BE(f32) mOffsetZ;
};
/* 0x0 */ u8 mCount;
+5
View File
@@ -263,6 +263,11 @@ public:
void setSaveData();
void setInitSaveData();
void _draw();
#if TARGET_PC
void menuSaveWide();
#endif
void _draw2();
virtual ~dMenu_save_c() {}
+6
View File
@@ -148,6 +148,12 @@ public:
void setEmphasisB(u8 param_0) { field_0x762 = param_0; }
u8 getInsideObjCheck() { return field_0x772; }
#if TARGET_PC
constexpr f32 getButtonZAlpha() const {
return mButtonZAlpha;
}
#endif
private:
/* 0x004 */ item_params mItemParams[4];
/* 0x074 */ JKRExpHeap* heap;
+1 -4
View File
@@ -321,6 +321,7 @@ int dMeter2Info_setNewLetterSender();
bool dMeter2Info_isItemOpenCheck();
bool dMeter2Info_isMapOpenCheck();
s16 dMeter2Info_getNowLifeGauge();
bool dMeter2Info_isNextStage(const char*, s16, s16, s16);
#if WIDESCREEN_SUPPORT
void dMeter2Info_onWide2D();
@@ -844,10 +845,6 @@ inline void dMeter2Info_onTempBit(int i_bit) {
g_meter2_info.onTempBit(i_bit);
}
inline bool dMeter2Info_isNextStage(const char*, s16, s16, s16) {
return false;
}
inline void dMeter2Info_setFloatingMessage(u16 i_msgID, s16 i_msgTimer, bool i_wakuVisible) {
g_meter2_info.setFloatingMessage(i_msgID, i_msgTimer, i_wakuVisible);
}
+5 -5
View File
@@ -89,7 +89,7 @@ public:
virtual void draw();
virtual ~dMeterMap_c();
bool isDispPosInsideFlg() { return field_0x2d != 0; }
bool isDispPosInsideFlg() { return mMapIsInside != 0; }
dMeterMap_c* getMapPointer() { return (dMeterMap_c*)mMap; }
void setSizeW(f32 w) { mSizeW = w; }
void setSizeH(f32 h) { mSizeH = h; }
@@ -108,15 +108,15 @@ private:
/* 0x0C */ s32 mIsCompass;
/* 0x10 */ s32 mIsMap;
/* 0x14 */ u32 field_0x14;
/* 0x18 */ f32 field_0x18;
/* 0x1C */ f32 field_0x1c;
/* 0x18 */ f32 mDrawPosX;
/* 0x1C */ f32 mDrawPosY;
/* 0x20 */ f32 mSizeW;
/* 0x24 */ f32 mSizeH;
/* 0x28 */ s16 field_0x28;
/* 0x28 */ s16 mSlidePositionOffset;
/* 0x2A */ u8 field_0x2a;
/* 0x2B */ u8 field_0x2b;
/* 0x2C */ u8 mMapAlpha;
/* 0x2D */ u8 field_0x2d;
/* 0x2D */ u8 mMapIsInside;
/* 0x2E */ u8 field_0x2e;
/* 0x30 */ int field_0x30;
};
+4
View File
@@ -562,6 +562,10 @@ inline void dMsgObject_setOffering(u16 i_num) {
dComIfGs_setEventReg(0xF8FF, i_num & 0xFF);
}
inline void dMsgObject_setLetterNameID(u16 id) {
dMsgObject_getMsgObjectClass()->setLetterNameID(id);
}
class dMsgObject_HowlHIO_c {
public:
dMsgObject_HowlHIO_c();
+5
View File
@@ -110,6 +110,11 @@ public:
void menuCursorMove();
void menuCursorMove2();
void selectCursorPosSet(int);
#if TARGET_PC
void nameWide();
#endif
void _draw();
void screenSet();
void displayInit();
+1 -1
View File
@@ -20,7 +20,7 @@ struct dPath {
/* 0x2 */ BE(u16) m_nextID;
/* 0x4 */ u8 field_0x4;
/* 0x5 */ bool m_closed;
/* 0x6 */ u8 field_0x6;
/* 0x6 */ u8 swbit;
/* 0x7 */ u8 field_0x7;
/* 0x8 */ OFFSET_PTR(dPnt) m_points;
};
+4
View File
@@ -48,6 +48,7 @@ public:
void FileSelectClose();
void brightCheckOpen();
void brightCheck();
void doPreLoadSetup();
void changeGameScene();
#if VERSION == VERSION_GCN_PAL
@@ -70,6 +71,9 @@ private:
/* 0x41E */ u8 mWaitTimer;
/* 0x41F */ u8 field_0x41f;
/* 0x420 */ u8 field_0x420;
#if TARGET_PC
bool mShowTvSettingsScreen;
#endif
};
#endif /* D_S_D_S_NAME_H */
+1 -1
View File
@@ -267,7 +267,7 @@ struct dStage_MemoryConfig_c {
// PATH / RPAT
struct dPath;
struct dStage_dPath_c {
/* 0x0 */ BE(int) m_num;
/* 0x0 */ BE(int) num;
/* 0x4 */ OFFSET_PTR(dPath) m_path;
};
+13 -3
View File
@@ -47,18 +47,21 @@ class dVibTest_c : public JORReflexible {
public:
dVibTest_c();
void Init();
void setDefault();
virtual void listenPropertyEvent(const JORPropertyEvent*);
virtual void genMessage(JORMContext*);
virtual ~dVibTest_c() {}
virtual ~dVibTest_c();
/* 0x04 */ s8 field_0x4;
/* 0x04 */ s8 id;
/* 0x06 */ u16 m_pattern;
/* 0x08 */ u16 m_pattern2;
/* 0x0A */ u16 field_0xa;
/* 0x0C */ s16 m_randombit;
/* 0x0E */ s16 m_length;
/* 0x10 */ int field_0x10;
/* 0x14 */ int m_vibswitch;
/* 0x14 */ s32 m_vibswitch;
/* 0x18 */ u16 m_displayDbg;
};
@@ -82,6 +85,10 @@ public:
void Pause();
void Remove();
#if DEBUG
int testShake();
#endif
static const vib_pattern MS_patt[VIBMODE_S_MAX];
static const vib_pattern CS_patt[VIBMODE_S_MAX];
static const vib_pattern MQ_patt[VIBMODE_Q_MAX];
@@ -123,4 +130,7 @@ private:
/* 0x8C */ s32 mMode;
}; // Size: 0x90
extern const char* shock_names[VIBMODE_S_MAX];
extern const char* quake_names[VIBMODE_Q_MAX];
#endif /* D_D_VIBRATION_H */
+2
View File
@@ -2,7 +2,9 @@
#define DOLZEL_BASE_PCH
// Fixes weak .bss
#if !TARGET_PC
#include "weak_bss_1109_to_1009.h" // IWYU pragma: export
#endif
#include <cmath> // IWYU pragma: export
#include <cstring> // IWYU pragma: export
+20
View File
@@ -0,0 +1,20 @@
#ifndef DUSK_APPNAME_HPP
#define DUSK_APPNAME_HPP
namespace dusk {
/**
* \brief The internal application name for the game.
*
* This gets used for file paths and such, and cannot be changed!
*/
constexpr auto AppName = "Dusk";
/**
* \brief The internal organization name for the game.
*
* This gets used for file paths and such, and cannot be changed!
*/
constexpr auto OrgName = "TwilitRealm";
}
#endif // DUSK_APPNAME_HPP
+2 -2
View File
@@ -2,13 +2,13 @@
#define DUSK_AUDIO_H
#if TARGET_PC
#define DUSK_AUDIO_DISABLED 1
#define DUSK_AUDIO_DISABLED 0
#else
#define DUSK_AUDIO_DISABLED 0
#endif
#if TARGET_PC
#define DUSK_AUDIO_SKIP(...) return __VA_ARGS__;
#define DUSK_AUDIO_SKIP(...)
#else
#define DUSK_AUDIO_SKIP(...)
#endif
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <dolphin/types.h>
namespace dusk::audio {
/**
* Initialize the audio system and start playing audio.
*/
void Initialize();
void SetEnableReverb(bool value);
void SetMasterVolume(f32 value);
u32 GetResetCount(int channelIdx);
f32 VolumeFromU16(u16 value);
}
+122
View File
@@ -0,0 +1,122 @@
#ifndef DUSK_CONFIG_HPP
#define DUSK_CONFIG_HPP
#include <stdexcept>
#include "nlohmann/json.hpp"
#include "config_var.hpp"
namespace dusk::config {
/*
* config.hpp is a heavier "full" header for the configuration system.
* For a basic overview and the basic types (sufficient for accessing settings),
* look at config_var.hpp.
*
* Avoid including this header in the entire game, it's heavier than I'd like!
*/
/**
* \brief Base class containing virtual functions used for save/load of CVars.
*/
class ConfigImplBase {
protected:
virtual ~ConfigImplBase() = default;
public:
/**
* \brief Load a JSON value into a CVar at the Value layer.
*/
virtual void loadFromJson(ConfigVarBase& cVar, const nlohmann::json& jsonValue) const = 0;
/**
* \brief Load a simple launch argument into the CVar at the Override layer.
*/
virtual void loadFromArg(ConfigVarBase& cVar, std::string_view stringValue) const = 0;
/**
* \brief Dump the value contained in the CVar to JSON.
*/
[[nodiscard]] virtual nlohmann::json dumpToJson(const ConfigVarBase& cVar) const = 0;
};
template<ConfigValue T>
class ConfigImpl : public ConfigImplBase {
// Just downcasting the references...
void loadFromJson(ConfigVarBase& cVar, const nlohmann::json& jsonValue) const final {
assert(typeid(cVar) == typeid(ConfigVar<T>));
loadFromJson(dynamic_cast<ConfigVar<T>&>(cVar), jsonValue);
}
void loadFromArg(ConfigVarBase& cVar, std::string_view stringValue) const final {
assert(typeid(cVar) == typeid(ConfigVar<T>));
loadFromArg(dynamic_cast<ConfigVar<T>&>(cVar), stringValue);
}
[[nodiscard]] nlohmann::json dumpToJson(const ConfigVarBase& cVar) const final {
assert(typeid(cVar) == typeid(ConfigVar<T>));
return dumpToJson(dynamic_cast<const ConfigVar<T>&>(cVar));
}
/**
* \brief Load a JSON value into a CVar at the Value layer.
*/
static void loadFromJson(ConfigVar<T>& cVar, const nlohmann::json& jsonValue);
/**
* \brief Load a simple launch argument into the CVar at the Override layer.
*/
static void loadFromArg(ConfigVar<T>& cVar, std::string_view stringValue);
/**
* \brief Dump the value contained in the CVar to JSON.
*/
[[nodiscard]] static nlohmann::json dumpToJson(const ConfigVar<T>& cVar);
};
/**
* \brief Thrown by config loading functions if the value provided is invalid for the CVar.
*/
class InvalidConfigError : public std::runtime_error {
public:
explicit InvalidConfigError(const char* what) : runtime_error(what) {}
};
/**
* \brief Register a CVar to make the config system aware of it.
*
* This must be done on startup *before* config has been loaded.
*/
void Register(ConfigVarBase& configVar);
/**
* \brief Indicate that all registrations have happened and everything should lock in.
*/
void FinishRegistration();
/**
* \brief Load config from the standard user preferences location.
*/
void LoadFromUserPreferences();
void LoadFromFileName(const char* path);
/**
* \brief Save the config to file.
*/
void Save();
/**
* \brief Get a registered CVar by name.
*
* @return null if the CVar does not exist.
*/
ConfigVarBase* GetConfigVar(std::string_view name);
template <ConfigValue T>
const ConfigImplBase* GetConfigImpl() {
static ConfigImpl<T> config;
return &config;
}
} // namespace dusk::config
#endif
+235
View File
@@ -0,0 +1,235 @@
#ifndef DUSK_CONFIG_VAR_HPP
#define DUSK_CONFIG_VAR_HPP
#include "dolphin/types.h"
#include <type_traits>
#include <cstdlib>
#include <string>
/**
* The configuration system.
*
* Configuration works via "configuration variables" aka "CVars". Each stores a single value that
* may be individually written to/from a configuration file.
*
* CVars, like ogres, have layers. Higher layers (e.g. a set value) override lower layers
* (e.g. the default value).
*
* To define a CVar, simply make a global variable of type ConfigVar<T>,
* and make sure Register() is called on it during program startup.
*
* config_var.hpp contains the simplest "just the configuration vars themselves".
* This should be safe to include for files that need to *access* configuration,
* without blowing up compile times on implementation details.
*
* config.hpp on the other hand contains far more calls for mutating, loading, and defining CVars.
*/
namespace dusk::config {
/**
* \brief Layers that a configuration variable can currently be at.
*
* A configuration variable can be on one of multiple *layers*, which determines where
* the current value is coming from.
*/
enum class ConfigVarLayer : u8 {
/**
* The CVar is at the default value defined by the application code.
*/
Default,
/**
* The CVar has been modified by the user and may be saved to config.
*/
Value,
/**
* The CVar is modified by launch argument, overruling the normal config value.
* Will not get saved to config.
*/
Override,
};
class ConfigImplBase;
/**
* Base class that all CVars inherit from.
* You want the templated ConfigVar instead for actual usage.
*/
class ConfigVarBase {
protected:
/**
* The name of this CVar, used in the configuration file.
*/
const char* name;
/**
* Whether this CVar has been registered with the global managing logic.
* If this is not done, it is not functional.
*/
bool registered;
/**
* The layer this CVar is at.
*/
ConfigVarLayer layer;
/**
* Pointer to an implementation struct for various load/save calls.
*/
const ConfigImplBase* impl;
ConfigVarBase(const char* name, const ConfigImplBase* impl);
virtual ~ConfigVarBase() = default;
/**
* Check that the CVar is registered, aborting if this is not the case.
*/
void checkRegistered() const {
if (!registered)
abort();
}
public:
/**
* Get the name of this CVar, used in the configuration file.
*/
[[nodiscard]] const char* getName() const noexcept;
/**
* Get the pointer to the implementation struct.
*/
[[nodiscard]] const ConfigImplBase* getImpl() const noexcept;
/**
* Get the layer this CVar is currently at.
*/
[[nodiscard]] constexpr ConfigVarLayer getLayer() const noexcept {
return layer;
}
/**
* Mark this CVar as being registered with the central save/load logic.
* This is necessary to make it legal to access.
*/
void markRegistered();
};
template <typename T>
concept ConfigValueInteger =
std::is_same_v<T, s8>
|| std::is_same_v<T, u8>
|| std::is_same_v<T, s16>
|| std::is_same_v<T, u16>
|| std::is_same_v<T, s32>
|| std::is_same_v<T, u32>
|| std::is_same_v<T, s64>
|| std::is_same_v<T, u64>;
/**
* \brief Concept that defines the legal set of types that can be used for CVar values.
*
* Valid types cannot be cv-qualified and must be basic primitive types (int, float, bool),
* strings, or enums of the basic primitives.
*/
template <typename T>
concept ConfigValue =
!std::is_const_v<T>
&& !std::is_volatile_v<T>
&& (std::is_same_v<T, bool>
|| ConfigValueInteger<T>
|| std::is_same_v<T, f32>
|| std::is_same_v<T, f64>
|| std::is_same_v<T, std::string>
|| (std::is_enum_v<T> && ConfigValueInteger<std::underlying_type_t<T>>));
template <ConfigValue T>
const ConfigImplBase* GetConfigImpl();
/**
* \brief A CVar storing values.
*
* @tparam T The type of value stored in the CVar.
*/
template <ConfigValue T>
class ConfigVar : public ConfigVarBase {
T defaultValue;
T value;
T overrideValue;
public:
/**
* \brief Construct a CVar.
*
* @param name The name of this CVar. Must be unique.
* @param arg Arguments to forward to construct the default value.
*/
template <typename... Args>
ConfigVar(const char* name, Args&&... arg)
: ConfigVarBase(name, GetConfigImpl<T>()), defaultValue(std::forward<Args>(arg)...),
value(), overrideValue() {}
/**
* \brief Get the current value of the CVar.
*
* This reference is not guaranteed to remain up-to-date after modification of the CVar.
* It will, however, remain sound to access.
*/
[[nodiscard]] constexpr const T& getValue() const noexcept {
checkRegistered();
switch (layer) {
case ConfigVarLayer::Default:
return defaultValue;
case ConfigVarLayer::Value:
return value;
case ConfigVarLayer::Override:
return overrideValue;
default:
abort();
}
}
/**
* \brief Change the value of a CVar.
*
* The new value is always stored at the Value layer.
*
* @param newValue The new value the CVar will get.
* @param replaceOverride If true, clear an existing override layer if there is one.
* If this is false and there is an override layer,
* the result of getValue() will not change immediately.
*/
void setValue(T newValue, bool replaceOverride = true) {
checkRegistered();
value = std::move(newValue);
if (replaceOverride) {
overrideValue = {};
layer = ConfigVarLayer::Value;
} else if (layer != ConfigVarLayer::Override) {
layer = ConfigVarLayer::Value;
}
}
operator const T&() {
return getValue();
}
/**
* \brief Give a CVar an override value.
*
* This overrides (but does not replace) the apparent set value of this CVar.
* The overriden value will not get saved to config.
*
* @param newValue The new value the CVar will get.
*/
void setOverrideValue(T newValue) {
checkRegistered();
overrideValue = std::move(newValue);
layer = ConfigVarLayer::Override;
}
};
}
#endif // DUSK_CONFIG_VAR_HPP
+16
View File
@@ -3,6 +3,22 @@
#include <aurora/aurora.h>
#include "aurora/gfx.h"
extern AuroraInfo auroraInfo;
extern const char* configPath;
namespace dusk {
extern AuroraStats lastFrameAuroraStats;
extern float frameUsagePct;
}
constexpr u32 defaultWindowWidth = 608;
constexpr u32 defaultWindowHeight = 448;
constexpr u32 defaultAspectRatioW = 19;
constexpr u32 defaultAspectRatioH = 14;
static_assert(defaultWindowWidth / defaultAspectRatioW == defaultWindowHeight / defaultAspectRatioH);
#endif // DUSK_DUSK_H
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "dolphin/types.h"
namespace dusk {
/**
* Load bytes from the main DOL by GameCube virtual address
*/
bool LoadDolAsset(void* dst, u32 virtualAddress, s32 size);
/**
* Load bytes from a REL file in the ISO filesystem, dst must be 32-byte aligned
*/
bool LoadRelAsset(void* dst, const char* dvdPath, s32 offset, s32 size);
/**
* Load bytes from a REL inside RELS.arc
*/
bool LoadArchivedRelAsset(void* dst, u32 memType, const char* relFileName, s32 offset, s32 size);
} // namespace dusk
+9
View File
@@ -42,4 +42,13 @@ typedef GXTexObjRAII TGXTexObj;
typedef GXTexObj TGXTexObj;
#endif
struct GXScopedDebugGroup {
explicit GXScopedDebugGroup(const char* text) {
GXPushDebugGroup(text);
}
~GXScopedDebugGroup() {
GXPopDebugGroup();
}
};
#endif // DUSK_GX_HELPER_H
+25
View File
@@ -0,0 +1,25 @@
#ifndef DUSK_HOTKEYS_H
#define DUSK_HOTKEYS_H
namespace dusk::hotkeys {
#if __APPLE__
constexpr const char* DO_RESET = "Cmd+R";
#else
constexpr const char* DO_RESET = "Ctrl+R";
#endif
constexpr const char* TOGGLE_FULLSCREEN = "F11";
constexpr const char* SHOW_PROCESS_MANAGEMENT = "F2";
constexpr const char* SHOW_DEBUG_OVERLAY = "F3";
constexpr const char* SHOW_HEAP_VIEWER = "F4";
constexpr const char* SHOW_STUB_LOG = "F5";
constexpr const char* SHOW_CAMERA_DEBUG = "F6";
constexpr const char* SHOW_AUDIO_DEBUG = "F7";
constexpr const char* TURBO = "Tab";
}
#endif // DUSK_HOTKEYS_H
+75
View File
@@ -0,0 +1,75 @@
#ifndef DUSK_IO_HPP
#define DUSK_IO_HPP
#include <vector>
// I can't believe it's 2026 and neither SDL (no error codes) nor
// C++ (no error codes) have a file system API functional enough for me to use.
// Here you go, this one's inspired by C#. I only wrote the functions I need.
namespace dusk::io {
/**
* \brief A simple file stream wrapping cstdio FILE*.
*
* Methods on this class throw appropriate C++ exceptions when an error occurs.
*/
class FileStream {
void* file;
public:
FileStream() noexcept;
/**
* \brief Take ownership of a FILE* handle.
*/
explicit FileStream(void* file);
FileStream(const FileStream& other) = delete;
FileStream(FileStream&& other) noexcept;
~FileStream();
/**
* \brief Open a file for reading at the given path.
*/
static FileStream OpenRead(const char* utf8Path);
/**
* \brief Create a file for writing.
*
* If there is an existing file, its contents are demolished.
*/
static FileStream Create(const char* utf8Path);
/**
* \brief Read the byte contents of a file directly into a vector.
*/
static std::vector<u8> ReadAllBytes(const char* utf8Path);
/**
* \brief Read the byte contents of a file directly into a vector.
*/
static void WriteAllText(const char* utf8Path, std::string_view text);
/**
* \brief Read the remaining contents of the file directly into a vector.
*/
std::vector<u8> ReadFull();
/**
* Get direct access to the underlying FILE* handle.
*/
[[nodiscard]] void* GetFileHandle() const noexcept {
return file;
}
/**
* Write data to the file.
*/
void Write(const char* data, size_t dataLen);
};
}
#endif // DUSK_IO_HPP
+37
View File
@@ -0,0 +1,37 @@
#ifndef DUSK_LAYOUT_H
#define DUSK_LAYOUT_H
#include "dolphin/types.h"
namespace dusk {
/**
* Helper struct for laying things out on the screen. Represents a rectangle via two corner
* positions.
*/
struct LayoutRect {
f32 PosX;
f32 PosY;
f32 PosX2;
f32 PosY2;
[[nodiscard]] constexpr f32 Width() const {
return PosX2 - PosX;
}
[[nodiscard]] constexpr f32 Height() const {
return PosY2 - PosY;
}
/**
* Calculates the position to render one rectangle inside another, centered and maintaining aspect ratio.
*/
[[nodiscard]] static LayoutRect FitRectInRect(
f32 widthOuter,
f32 heightOuter,
f32 widthInner,
f32 heightInner);
};
}
#endif // DUSK_LAYOUT_H
+8
View File
@@ -0,0 +1,8 @@
#ifndef DUSK_MAIN_H
#define DUSK_MAIN_H
namespace dusk {
extern bool IsShuttingDown;
}
#endif // DUSK_MAIN_H
+3
View File
@@ -617,5 +617,8 @@ static const auto gameRegions = std::to_array({
MapEntry("Cutscene: Hyrule Castle Throne Room", "R_SP301", {
{0, {0, 20, 100}},
}),
MapEntry("Title screen movie map", "S_MV000", {
{0, {0, 1}},
}),
})
});
+14
View File
@@ -0,0 +1,14 @@
#ifndef DUSK_OS_H
#define DUSK_OS_H
#ifdef __cplusplus
extern "C" {
#endif
void OSSetCurrentThreadName(const char* name);
#ifdef __cplusplus
}
#endif
#endif // DUSK_OS_H
+101
View File
@@ -0,0 +1,101 @@
#ifndef DUSK_CONFIG_H
#define DUSK_CONFIG_H
#include "dusk/config_var.hpp"
namespace dusk {
using namespace config;
// Persistent user settings
struct UserSettings {
// Program settings
struct {
// Video
ConfigVar<bool> enableFullscreen;
ConfigVar<bool> enableVsync;
ConfigVar<bool> lockAspectRatio;
} video;
struct {
// Audio
ConfigVar<int> masterVolume;
ConfigVar<int> mainMusicVolume;
ConfigVar<int> subMusicVolume;
ConfigVar<int> soundEffectsVolume;
ConfigVar<int> fanfareVolume;
ConfigVar<bool> enableReverb;
} audio;
// Game settings
struct {
// QoL
ConfigVar<bool> enableQuickTransform;
ConfigVar<bool> hideTvSettingsScreen;
ConfigVar<bool> biggerWallets;
ConfigVar<bool> noReturnRupees;
ConfigVar<bool> disableRupeeCutscenes;
ConfigVar<bool> noSwordRecoil;
ConfigVar<int> damageMultiplier;
ConfigVar<bool> instantDeath;
ConfigVar<bool> fastClimbing;
ConfigVar<bool> noMissClimbing;
ConfigVar<bool> fastTears;
ConfigVar<bool> instantSaves;
// Preferences
ConfigVar<bool> enableMirrorMode;
ConfigVar<bool> invertCameraXAxis;
// Graphics
ConfigVar<bool> enableBloom;
ConfigVar<bool> useWaterProjectionOffset;
// Audio
ConfigVar<bool> noLowHpSound;
ConfigVar<bool> midnasLamentNonStop;
// Cheats
ConfigVar<bool> enableFastIronBoots;
ConfigVar<bool> canTransformAnywhere;
ConfigVar<bool> fastSpinner;
ConfigVar<bool> freeMagicArmor;
// Technical
ConfigVar<bool> restoreWiiGlitches;
// Controls
ConfigVar<bool> enableTurboKeybind;
} game;
};
UserSettings& getSettings();
void registerSettings();
// Transient settings
struct CollisionViewSettings {
bool enableTerrainView;
bool enableWireframe;
bool enableAtView;
bool enableTgView;
bool enableCoView;
float terrainViewOpacity;
float colliderViewOpacity;
float drawRange;
};
struct TransientSettings {
CollisionViewSettings collisionView;
bool skipFrameRateLimit;
};
TransientSettings& getTransientSettings();
}
#endif // DUSK_CONFIG_H
+58
View File
@@ -0,0 +1,58 @@
#ifndef DUSK_STRING_HPP
#define DUSK_STRING_HPP
#include "global.h"
#include <cstring>
#include <dolphin/os.h>
namespace dusk {
inline void strncpyProxy(char* dst, const char* src, size_t count) {
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4996)
#endif
strncpy(dst, src, count);
#if _MSC_VER
#pragma warning(pop)
#endif
}
/**
* Copy a string to a fixed-size array.
* Truncates if the destination is not large enough, always inserts a null terminator (padding the remainder of the buffer with zeroes.)
*/
template <size_t BufSize>
void SafeStringCopyTruncate(char (&buffer)[BufSize], const char* src) {
static_assert(BufSize > 0, "Target buffer cannot be size zero");
if (buffer == src) {
CRASH("Cannot copy string to same buffer");
}
strncpyProxy(buffer, src, BufSize);
buffer[BufSize - 1] = 0;
}
/**
* Copy a string to a fixed-size array.
* Aborts if the destination is not large enough, always inserts a null terminator (padding the remainder of the buffer with zeroes.)
*/
template <size_t BufSize>
void SafeStringCopy(char (&buffer)[BufSize], const char* src) {
static_assert(BufSize > 0, "Target buffer cannot be size zero");
if (buffer == src) {
CRASH("Cannot copy string to same buffer");
}
if (strlen(src) > BufSize - 1) {
CRASH("Destination buffer too small!");
}
strncpyProxy(buffer, src, BufSize);
buffer[BufSize - 1] = 0;
}
}
#endif // DUSK_STRING_HPP
+6 -1
View File
@@ -14,6 +14,7 @@
#endif
#include <Windows.h>
#include <shellapi.h>
#include <intrin.h>
#endif
#include "dusk/logging.h"
@@ -92,7 +93,11 @@ private:
}
do {
QueryPerformanceCounter(&current);
_mm_pause(); // Yield CPU
#if defined(_M_ARM64) || defined(_M_ARM)
__yield();
#else
_mm_pause();
#endif
} while (current.QuadPart - start.QuadPart < ticksToWait);
}
#else
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#define PROCS_DUMP_NAMES 1
#include "d/dolzel.pch"
#include "d/dolzel_base.pch"
#include "d/dolzel_rel.pch"
+4
View File
@@ -9,7 +9,11 @@
#include "f_pc/f_pc_stdcreate_req.h"
#include "f_pc/f_pc_searcher.h"
#if TARGET_PC
enum : u32 {
#else
enum {
#endif
fpcM_UNK_PROCESS_ID_e = 0xFFFFFFFE,
fpcM_ERROR_PROCESS_ID_e = 0xFFFFFFFF,
};
+8 -6
View File
@@ -83,7 +83,11 @@ extern int __abs(int);
void* __memcpy(void*, const void*, int);
#endif
#ifdef _MSVC_LANG
#ifndef M_PI
#define M_PI 3.14159265358979323846f
#endif
#if defined(_MSVC_LANG) && !defined(__clang__)
inline int __builtin_clz(unsigned int v) {
int count = 32;
while (v != 0) {
@@ -94,7 +98,6 @@ inline int __builtin_clz(unsigned int v) {
}
#define COMPOUND_LITERAL(x)
#define M_PI 3.14159265358979323846f
#else
#define COMPOUND_LITERAL(x) (x)
@@ -191,15 +194,12 @@ static const float INF = 2000000000.0f;
#endif
// potential fakematch?
#if DEBUG
#define FABSF fabsf
#else
#define FABSF std::fabsf
#endif
#ifndef __MWERKS__
#if __cplusplus
#include <cmath>
#include <math.h>
using std::isnan;
#endif
#endif
@@ -215,4 +215,6 @@ using std::isnan;
#define IS_REF_NONNULL(r) (1)
#endif
#define CRASH(msg, ...) OSPanic(__FILE__, __LINE__, "%s", msg, ##__VA_ARGS__)
#endif
+27 -3
View File
@@ -3,6 +3,7 @@
#include "JSystem/JUtility/JUTGamePad.h"
#include "SSystem/SComponent/c_API_controller_pad.h"
#include "dusk/settings.h"
// Controller Ports 1 - 4
enum { PAD_1, PAD_2, PAD_3, PAD_4 };
@@ -52,8 +53,31 @@ public:
static f32 getStickX3D(u32 pad) { return getCpadInfo(pad).mMainStickPosX; }
static f32 getStickValue(u32 pad) { return getCpadInfo(pad).mMainStickValue; }
static s16 getStickAngle(u32 pad) { return getCpadInfo(pad).mMainStickAngle; }
static s16 getStickAngle3D(u32 pad) { return getCpadInfo(pad).mMainStickAngle; }
static f32 getSubStickX3D(u32 pad) { return getCpadInfo(pad).mCStickPosX; }
static s16 getStickAngle3D(u32 pad) {
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
return -getCpadInfo(pad).mMainStickAngle;
} else {
return getCpadInfo(pad).mMainStickAngle;
}
#else
return getCpadInfo(pad).mMainStickAngle;
#endif
}
static f32 getSubStickX3D(u32 pad) {
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
return -getCpadInfo(pad).mCStickPosX;
} else {
return getCpadInfo(pad).mCStickPosX;
}
#else
return getCpadInfo(pad).mCStickPosX;
#endif
}
static f32 getSubStickX(u32 pad) { return getCpadInfo(pad).mCStickPosX; }
static f32 getSubStickY(u32 pad) { return getCpadInfo(pad).mCStickPosY; }
static f32 getSubStickValue(u32 pad) { return getCpadInfo(pad).mCStickValue; }
@@ -61,7 +85,7 @@ public:
static f32 getAnalogR(u32 pad) { return getCpadInfo(pad).mTriggerRight; }
static f32 getAnalogL(u32 pad) { return getCpadInfo(pad).mTriggerLeft; }
static BOOL isConnect(u32 pad) { return JUTGamePad::getPortStatus((JUTGamePad::EPadPort)pad) == 0; }
static void startMotorWave(u32 pad, void* data, JUTGamePad::CRumble::ERumble rumble, u32 length) {
static void startMotorWave(u32 pad, u8* data, JUTGamePad::CRumble::ERumble rumble, u32 length) {
m_gamePad[pad]->startMotorWave(data, rumble, length);
}
static void stopMotor(u32 pad) { m_gamePad[pad]->stopMotor(); }
+20 -8
View File
@@ -4,12 +4,11 @@
#include "JSystem/JFramework/JFWDisplay.h"
#include "m_Do/m_Do_mtx.h"
#include "global.h"
#include "dusk/logging.h"
#if TARGET_PC
#include <aurora/aurora.h>
#endif
#if WIDESCREEN_SUPPORT
#if WIDESCREEN_SUPPORT && !TARGET_PC
#define FB_WIDTH (640)
#define FB_HEIGHT (456)
#else
@@ -100,9 +99,7 @@ public:
}
static int startFadeOut(int param_0) { return JFWDisplay::getManager()->startFadeOut(param_0); }
static int startFadeIn(int param_0) {
DuskLog.debug("mDoGph_gInf_c::startFadeIn START");
return JFWDisplay::getManager()->startFadeIn(param_0); }
static int startFadeIn(int param_0) { return JFWDisplay::getManager()->startFadeIn(param_0); }
static void setFadeColor(JUtility::TColor& color) { mFader->setColor(color); }
static void setClearColor(JUtility::TColor color) { JFWDisplay::getManager()->setClearColor(color); }
static void setBackColor(GXColor& color) { mBackColor = color; }
@@ -120,6 +117,13 @@ public:
static void setTickRate(u32 rate) { JFWDisplay::getManager()->setTickRate(rate); }
static void waitBlanking(int wait) { JFWDisplay::getManager()->waitBlanking(wait); }
#if TARGET_PC
static f32 hudAspectScaleDown;
static f32 hudAspectScaleUp;
static f32 ScaleHUDXLeft(f32 baseX) { return getMinXF() + baseX; }
static f32 ScaleHUDXRight(f32 baseX) { return -getMinXF() + baseX; }
#endif
static void setBlureMtx(const Mtx m) {
cMtx_copy(m, mBlureMtx);
}
@@ -269,7 +273,12 @@ public:
#if WIDESCREEN_SUPPORT
static void setTvSize();
#if TARGET_PC
static void onWide(f32 width, f32 height);
#else
static void onWide();
#endif
static void offWide();
static u8 isWide();
@@ -315,6 +324,12 @@ public:
static JKRHeap* m_heap;
#endif
#if PLATFORM_WII || PLATFORM_SHIELD || TARGET_PC
static ResTIMG* m_fullFrameBufferTimg;
static void* m_fullFrameBufferTex;
static TGXTexObj m_fullFrameBufferTexObj;
#endif
#if PLATFORM_WII || PLATFORM_SHIELD
static void resetDimming();
@@ -329,9 +344,6 @@ public:
#if WIDESCREEN_SUPPORT
static u8 mWide;
static u8 mWideZoom;
static ResTIMG* m_fullFrameBufferTimg;
static void* m_fullFrameBufferTex;
static TGXTexObj m_fullFrameBufferTexObj;
static f32 m_aspect;
static f32 m_scale;
+3
View File
@@ -15,6 +15,9 @@ void my_SysPrintHeap(char const*, void*, u32);
void mDoMch_HeapCheckAll();
void mDoMch_HeapFreeFillAll();
int mDoMch_Create();
#if TARGET_PC
void mDoMch_Destroy();
#endif
extern GXRenderModeObj g_ntscZeldaProg;
+6
View File
@@ -31,4 +31,10 @@ extern u8 __OSReport_Warning_disable;
extern u8 __OSReport_System_disable;
extern u8 __OSReport_enable;
#if TARGET_PC
namespace dusk {
extern bool OSReportReallyForceEnable;
}
#endif
#endif // _OS_REPORT_H
+1177
View File
File diff suppressed because it is too large Load Diff
@@ -9,9 +9,9 @@
#include "dusk/endian.h"
#if TARGET_PC
#define OFFSET_PTR BE(u32)
#define OFFSET_PTR_V0 BE(u32)
#else
#define OFFSET_PTR void*
#define OFFSET_PTR_V0 void*
#endif
struct J3DTransformInfo;
@@ -80,7 +80,7 @@ struct J3DAnmColorKeyTable {
*/
struct J3DAnmVtxColorIndexData {
/* 0x00 */ BE(u16) mNum;
/* 0x04 */ OFFSET_PTR mpData;
/* 0x04 */ OFFSET_PTR_V0 mpData;
};
/**
@@ -200,13 +200,13 @@ struct J3DAnmVtxColorFullData {
/* 0x0A */ BE(s16) mFrameMax;
/* 0x0C */ BE(u16) mAnmTableNum[2];
/* 0x10 */ u8 field_0x10[0x18 - 0x10];
/* 0x18 */ OFFSET_PTR mTableOffsets[2];
/* 0x20 */ OFFSET_PTR mVtxColorIndexDataOffsets[2];
/* 0x28 */ OFFSET_PTR mVtxColorIndexPointerOffsets[2];
/* 0x30 */ OFFSET_PTR mRValuesOffset;
/* 0x34 */ OFFSET_PTR mGValuesOffset;
/* 0x38 */ OFFSET_PTR mBValuesOffset;
/* 0x3C */ OFFSET_PTR mAValuesOffset;
/* 0x18 */ OFFSET_PTR_V0 mTableOffsets[2];
/* 0x20 */ OFFSET_PTR_V0 mVtxColorIndexDataOffsets[2];
/* 0x28 */ OFFSET_PTR_V0 mVtxColorIndexPointerOffsets[2];
/* 0x30 */ OFFSET_PTR_V0 mRValuesOffset;
/* 0x34 */ OFFSET_PTR_V0 mGValuesOffset;
/* 0x38 */ OFFSET_PTR_V0 mBValuesOffset;
/* 0x3C */ OFFSET_PTR_V0 mAValuesOffset;
}; // Size = 0x40
STATIC_ASSERT(sizeof(J3DAnmVtxColorFullData) == 0x40);
@@ -222,8 +222,8 @@ struct J3DAnmVisibilityFullData {
/* 0x0A */ BE(s16) mFrameMax;
/* 0x0C */ BE(u16) field_0xc;
/* 0x0E */ BE(u16) field_0xe;
/* 0x10 */ OFFSET_PTR mTableOffset;
/* 0x14 */ OFFSET_PTR mValuesOffset;
/* 0x10 */ OFFSET_PTR_V0 mTableOffset;
/* 0x14 */ OFFSET_PTR_V0 mValuesOffset;
}; // Size = 0x18
STATIC_ASSERT(sizeof(J3DAnmVisibilityFullData) == 0x18);
@@ -239,10 +239,10 @@ struct J3DAnmTransformFullData {
/* 0x0A */ BE(s16) mFrameMax;
/* 0x0C */ BE(u16) field_0xc;
/* 0x0E */ u8 field_0xe[0x14 - 0xe];
/* 0x14 */ OFFSET_PTR mTableOffset;
/* 0x18 */ OFFSET_PTR mScaleValOffset;
/* 0x1C */ OFFSET_PTR mRotValOffset;
/* 0x20 */ OFFSET_PTR mTransValOffset;
/* 0x14 */ OFFSET_PTR_V0 mTableOffset;
/* 0x18 */ OFFSET_PTR_V0 mScaleValOffset;
/* 0x1C */ OFFSET_PTR_V0 mRotValOffset;
/* 0x20 */ OFFSET_PTR_V0 mTransValOffset;
}; // Size = 0x24
STATIC_ASSERT(sizeof(J3DAnmTransformFullData) == 0x24);
@@ -261,13 +261,13 @@ struct J3DAnmColorKeyData {
/* 0x12 */ BE(u16) field_0x12;
/* 0x14 */ BE(u16) field_0x14;
/* 0x16 */ BE(u16) field_0x16;
/* 0x18 */ OFFSET_PTR mTableOffset;
/* 0x1C */ OFFSET_PTR mUpdateMaterialIDOffset;
/* 0x20 */ OFFSET_PTR mNameTabOffset;
/* 0x24 */ OFFSET_PTR mRValOffset;
/* 0x28 */ OFFSET_PTR mGValOffset;
/* 0x2C */ OFFSET_PTR mBValOffset;
/* 0x30 */ OFFSET_PTR mAValOffset;
/* 0x18 */ OFFSET_PTR_V0 mTableOffset;
/* 0x1C */ OFFSET_PTR_V0 mUpdateMaterialIDOffset;
/* 0x20 */ OFFSET_PTR_V0 mNameTabOffset;
/* 0x24 */ OFFSET_PTR_V0 mRValOffset;
/* 0x28 */ OFFSET_PTR_V0 mGValOffset;
/* 0x2C */ OFFSET_PTR_V0 mBValOffset;
/* 0x30 */ OFFSET_PTR_V0 mAValOffset;
}; // Size = 0x34
STATIC_ASSERT(sizeof(J3DAnmColorKeyData) == 0x34);
@@ -285,26 +285,26 @@ struct J3DAnmTextureSRTKeyData {
/* 0x0E */ BE(u16) field_0xe;
/* 0x10 */ BE(u16) field_0x10;
/* 0x12 */ BE(u16) field_0x12;
/* 0x14 */ OFFSET_PTR mTableOffset;
/* 0x18 */ OFFSET_PTR mUpdateMatIDOffset;
/* 0x1C */ OFFSET_PTR mNameTab1Offset;
/* 0x20 */ OFFSET_PTR mUpdateTexMtxIDOffset;
/* 0x24 */ OFFSET_PTR unkOffset;
/* 0x28 */ OFFSET_PTR mScaleValOffset;
/* 0x2C */ OFFSET_PTR mRotValOffset;
/* 0x30 */ OFFSET_PTR mTransValOffset;
/* 0x14 */ OFFSET_PTR_V0 mTableOffset;
/* 0x18 */ OFFSET_PTR_V0 mUpdateMatIDOffset;
/* 0x1C */ OFFSET_PTR_V0 mNameTab1Offset;
/* 0x20 */ OFFSET_PTR_V0 mUpdateTexMtxIDOffset;
/* 0x24 */ OFFSET_PTR_V0 unkOffset;
/* 0x28 */ OFFSET_PTR_V0 mScaleValOffset;
/* 0x2C */ OFFSET_PTR_V0 mRotValOffset;
/* 0x30 */ OFFSET_PTR_V0 mTransValOffset;
/* 0x34 */ BE(u16) field_0x34;
/* 0x36 */ BE(u16) field_0x36;
/* 0x38 */ BE(u16) field_0x38;
/* 0x3A */ BE(u16) field_0x3a;
/* 0x3C */ OFFSET_PTR mInfoTable2Offset;
/* 0x40 */ OFFSET_PTR field_0x40;
/* 0x44 */ OFFSET_PTR mNameTab2Offset;
/* 0x48 */ OFFSET_PTR field_0x48;
/* 0x4C */ OFFSET_PTR field_0x4c;
/* 0x50 */ OFFSET_PTR field_0x50;
/* 0x54 */ OFFSET_PTR field_0x54;
/* 0x58 */ OFFSET_PTR field_0x58;
/* 0x3C */ OFFSET_PTR_V0 mInfoTable2Offset;
/* 0x40 */ OFFSET_PTR_V0 field_0x40;
/* 0x44 */ OFFSET_PTR_V0 mNameTab2Offset;
/* 0x48 */ OFFSET_PTR_V0 field_0x48;
/* 0x4C */ OFFSET_PTR_V0 field_0x4c;
/* 0x50 */ OFFSET_PTR_V0 field_0x50;
/* 0x54 */ OFFSET_PTR_V0 field_0x54;
/* 0x58 */ OFFSET_PTR_V0 field_0x58;
/* 0x5C */ BE(s32) field_0x5c;
}; // Size = 0x60
@@ -321,13 +321,13 @@ struct J3DAnmVtxColorKeyData {
/* 0x0A */ BE(s16) mFrameMax;
/* 0x0C */ BE(u16) mAnmTableNum[2];
/* 0x10 */ u8 field_0x10[0x18 - 0x10];
/* 0x18 */ OFFSET_PTR mTableOffsets[2];
/* 0x20 */ OFFSET_PTR mVtxColoIndexDataOffset[2];
/* 0x28 */ OFFSET_PTR mVtxColoIndexPointerOffset[2];
/* 0x30 */ OFFSET_PTR mRValOffset;
/* 0x34 */ OFFSET_PTR mGValOffset;
/* 0x38 */ OFFSET_PTR mBValOffset;
/* 0x3C */ OFFSET_PTR mAValOffset;
/* 0x18 */ OFFSET_PTR_V0 mTableOffsets[2];
/* 0x20 */ OFFSET_PTR_V0 mVtxColoIndexDataOffset[2];
/* 0x28 */ OFFSET_PTR_V0 mVtxColoIndexPointerOffset[2];
/* 0x30 */ OFFSET_PTR_V0 mRValOffset;
/* 0x34 */ OFFSET_PTR_V0 mGValOffset;
/* 0x38 */ OFFSET_PTR_V0 mBValOffset;
/* 0x3C */ OFFSET_PTR_V0 mAValOffset;
}; // Size = 0x40
STATIC_ASSERT(sizeof(J3DAnmVtxColorKeyData) == 0x40);
@@ -343,10 +343,10 @@ struct J3DAnmTexPatternFullData {
/* 0x0A */ BE(s16) mFrameMax;
/* 0x0C */ BE(u16) field_0xc;
/* 0x0E */ BE(u16) field_0xe;
/* 0x10 */ OFFSET_PTR mTableOffset;
/* 0x14 */ OFFSET_PTR mValuesOffset;
/* 0x18 */ OFFSET_PTR mUpdateMaterialIDOffset;
/* 0x1C */ OFFSET_PTR mNameTabOffset;
/* 0x10 */ OFFSET_PTR_V0 mTableOffset;
/* 0x14 */ OFFSET_PTR_V0 mValuesOffset;
/* 0x18 */ OFFSET_PTR_V0 mUpdateMaterialIDOffset;
/* 0x1C */ OFFSET_PTR_V0 mNameTabOffset;
}; // Size = 0x20
STATIC_ASSERT(sizeof(J3DAnmTexPatternFullData) == 0x20);
@@ -370,20 +370,20 @@ struct J3DAnmTevRegKeyData {
/* 0x1A */ BE(u16) field_0x1a;
/* 0x1C */ BE(u16) field_0x1c;
/* 0x1E */ BE(u16) field_0x1e;
/* 0x20 */ OFFSET_PTR mCRegTableOffset;
/* 0x24 */ OFFSET_PTR mKRegTableOffset;
/* 0x28 */ OFFSET_PTR mCRegUpdateMaterialIDOffset;
/* 0x2C */ OFFSET_PTR mKRegUpdateMaterialIDOffset;
/* 0x30 */ OFFSET_PTR mCRegNameTabOffset;
/* 0x34 */ OFFSET_PTR mKRegNameTabOffset;
/* 0x38 */ OFFSET_PTR mCRValuesOffset;
/* 0x3C */ OFFSET_PTR mCGValuesOffset;
/* 0x40 */ OFFSET_PTR mCBValuesOffset;
/* 0x44 */ OFFSET_PTR mCAValuesOffset;
/* 0x48 */ OFFSET_PTR mKRValuesOffset;
/* 0x4C */ OFFSET_PTR mKGValuesOffset;
/* 0x50 */ OFFSET_PTR mKBValuesOffset;
/* 0x54 */ OFFSET_PTR mKAValuesOffset;
/* 0x20 */ OFFSET_PTR_V0 mCRegTableOffset;
/* 0x24 */ OFFSET_PTR_V0 mKRegTableOffset;
/* 0x28 */ OFFSET_PTR_V0 mCRegUpdateMaterialIDOffset;
/* 0x2C */ OFFSET_PTR_V0 mKRegUpdateMaterialIDOffset;
/* 0x30 */ OFFSET_PTR_V0 mCRegNameTabOffset;
/* 0x34 */ OFFSET_PTR_V0 mKRegNameTabOffset;
/* 0x38 */ OFFSET_PTR_V0 mCRValuesOffset;
/* 0x3C */ OFFSET_PTR_V0 mCGValuesOffset;
/* 0x40 */ OFFSET_PTR_V0 mCBValuesOffset;
/* 0x44 */ OFFSET_PTR_V0 mCAValuesOffset;
/* 0x48 */ OFFSET_PTR_V0 mKRValuesOffset;
/* 0x4C */ OFFSET_PTR_V0 mKGValuesOffset;
/* 0x50 */ OFFSET_PTR_V0 mKBValuesOffset;
/* 0x54 */ OFFSET_PTR_V0 mKAValuesOffset;
}; // Size = 0x58
STATIC_ASSERT(sizeof(J3DAnmTevRegKeyData) == 0x58);
@@ -399,13 +399,13 @@ struct J3DAnmColorFullData { /* PlaceHolder Structure */
/* 0x0C */ BE(s16) mFrameMax;
/* 0x0E */ BE(u16) mUpdateMaterialNum;
/* 0x10 */ u8 field_0x10[0x18 - 0x10];
/* 0x18 */ OFFSET_PTR mTableOffset;
/* 0x1C */ OFFSET_PTR mUpdateMaterialIDOffset;
/* 0x20 */ OFFSET_PTR mNameTabOffset;
/* 0x24 */ OFFSET_PTR mRValuesOffset;
/* 0x28 */ OFFSET_PTR mGValuesOffset;
/* 0x2C */ OFFSET_PTR mBValuesOffset;
/* 0x30 */ OFFSET_PTR mAValuesOffset;
/* 0x18 */ OFFSET_PTR_V0 mTableOffset;
/* 0x1C */ OFFSET_PTR_V0 mUpdateMaterialIDOffset;
/* 0x20 */ OFFSET_PTR_V0 mNameTabOffset;
/* 0x24 */ OFFSET_PTR_V0 mRValuesOffset;
/* 0x28 */ OFFSET_PTR_V0 mGValuesOffset;
/* 0x2C */ OFFSET_PTR_V0 mBValuesOffset;
/* 0x30 */ OFFSET_PTR_V0 mAValuesOffset;
}; // Size = 0x34
STATIC_ASSERT(sizeof(J3DAnmColorFullData) == 0x34);
@@ -431,10 +431,10 @@ struct J3DAnmTransformKeyData {
/* 0x0E */ BE(u16) mSCount;
/* 0x10 */ BE(u16) mRCount;
/* 0x12 */ BE(u16) mTCount;
/* 0x14 */ OFFSET_PTR mJointAnimationTableOffs;
/* 0x18 */ OFFSET_PTR mSTableOffs;
/* 0x1c */ OFFSET_PTR mRTableOffs;
/* 0x20 */ OFFSET_PTR mTTableOffs;
/* 0x14 */ OFFSET_PTR_V0 mJointAnimationTableOffs;
/* 0x18 */ OFFSET_PTR_V0 mSTableOffs;
/* 0x1c */ OFFSET_PTR_V0 mRTableOffs;
/* 0x20 */ OFFSET_PTR_V0 mTTableOffs;
};
/**
@@ -446,8 +446,8 @@ struct J3DAnmClusterKeyData {
/* 0x08 */ u8 field_0x8;
/* 0x0A */ BE(s16) mFrameMax;
/* 0x0C */ BE(s32) field_0xc;
/* 0x10 */ OFFSET_PTR mTableOffset;
/* 0x14 */ OFFSET_PTR mWeightOffset;
/* 0x10 */ OFFSET_PTR_V0 mTableOffset;
/* 0x14 */ OFFSET_PTR_V0 mWeightOffset;
};
/**
@@ -459,8 +459,8 @@ struct J3DAnmClusterFullData {
/* 0x08 */ u8 field_0x8;
/* 0x0A */ BE(s16) mFrameMax;
/* 0x0C */ BE(s32) field_0xc;
/* 0x10 */ OFFSET_PTR mTableOffset;
/* 0x14 */ OFFSET_PTR mWeightOffset;
/* 0x10 */ OFFSET_PTR_V0 mTableOffset;
/* 0x14 */ OFFSET_PTR_V0 mWeightOffset;
};
/**
@@ -718,7 +718,7 @@ public:
// Address to which getAnmVtxColorIndexData pointers are relative.
u16* colorAddressBase[2];
u16* offsetColorIndexAddress(u8 index, OFFSET_PTR ptr) const {
u16* offsetColorIndexAddress(u8 index, OFFSET_PTR_V0 ptr) const {
return colorAddressBase[index] + ptr;
}
#endif
@@ -994,6 +994,6 @@ public:
/* 0x10 */ f32 mFrame;
}; // Size: 0x14
#undef OFFSET_PTR
#undef OFFSET_PTR_V0
#endif /* J3DANIMATION_H */
@@ -14,9 +14,9 @@ class J3DAnmCluster;
class JUTNameTab;
#if TARGET_PC
#define OFFSET_PTR BE(u32)
#define OFFSET_PTR_V0 BE(u32)
#else
#define OFFSET_PTR void*
#define OFFSET_PTR_V0 void*
#endif
/**
@@ -49,7 +49,7 @@ public:
/* 0x00 */ BE(f32) mMaxAngle;
/* 0x04 */ BE(f32) mMinAngle;
/* 0x08 */ OFFSET_PTR mClusterKey;
/* 0x08 */ OFFSET_PTR_V0 mClusterKey;
/* 0x0C */ u8 mFlags;
/* 0x0E */ u8 field_0xe[0x10 - 0xD];
/* 0x10 */ BE(u16) mKeyNum;
@@ -57,9 +57,9 @@ public:
/* 0x14 */ BE(u16) field_0x14;
/* 0x16 */ BE(u16) field_0x16;
#if TARGET_PC
OFFSET_PTR field_0x18;
OFFSET_PTR mClusterVertex;
OFFSET_PTR mDeformer;
OFFSET_PTR_V0 field_0x18;
OFFSET_PTR_V0 mClusterVertex;
OFFSET_PTR_V0 mDeformer;
#else
/* 0x18 */ u16* field_0x18;
/* 0x1C */ J3DClusterVertex* mClusterVertex;
@@ -82,8 +82,8 @@ public:
/* 0x00 */ BE(u16) mPosNum;
/* 0x02 */ BE(u16) mNrmNum;
/* 0x04 */ OFFSET_PTR field_0x4;
/* 0x08 */ OFFSET_PTR field_0x8;
/* 0x04 */ OFFSET_PTR_V0 field_0x4;
/* 0x08 */ OFFSET_PTR_V0 field_0x8;
}; // Size: 0x0C
/**
@@ -144,14 +144,14 @@ public:
/* 0x00 */ BE(u16) mNum;
#if TARGET_PC
/* 0x04 */ OFFSET_PTR field_0x4;
/* 0x08 */ OFFSET_PTR field_0x8;
/* 0x04 */ OFFSET_PTR_V0 field_0x4;
/* 0x08 */ OFFSET_PTR_V0 field_0x8;
#else
/* 0x04 */ u16* field_0x4;
/* 0x08 */ u16* field_0x8;
#endif
}; // Size: 0x0C
#undef OFFSET_PTR
#undef OFFSET_PTR_V0
#endif /* J3DCLUSTER_H */
@@ -150,13 +150,13 @@ struct J3DSys {
void setModelDrawMtx(Mtx* pMtxArr) {
J3D_ASSERT_NULLPTR(230, pMtxArr);
mModelDrawMtx = pMtxArr;
GXSETARRAY(GX_POS_MTX_ARRAY, mModelDrawMtx, sizeof(*mModelDrawMtx), sizeof(*mModelDrawMtx));
GXSETARRAY(GX_POS_MTX_ARRAY, mModelDrawMtx, 10 * sizeof(Mtx), sizeof(*mModelDrawMtx), true);
}
void setModelNrmMtx(Mtx33* pMtxArr) {
J3D_ASSERT_NULLPTR(241, pMtxArr);
mModelNrmMtx = pMtxArr;
GXSETARRAY(GX_NRM_MTX_ARRAY, mModelNrmMtx, sizeof(*mModelNrmMtx), sizeof(*mModelNrmMtx));
GXSETARRAY(GX_NRM_MTX_ARRAY, mModelNrmMtx, 10 * sizeof(Mtx33), sizeof(*mModelNrmMtx), true);
}
void* getVtxPos() { return mVtxPos; }
@@ -7,9 +7,9 @@
#include "dusk/endian.h"
#if TARGET_PC
#define OFFSET_PTR BE(u32)
#define OFFSET_PTR_V0 BE(u32)
#else
#define OFFSET_PTR void*
#define OFFSET_PTR_V0 void*
#endif
/**
@@ -31,13 +31,13 @@ public:
/* 0x0C */ BE(u16) mClusterVertexNum;
/* 0x0E */ BE(u16) mVtxPosNum;
/* 0x10 */ BE(u16) mVtxNrmNum;
/* 0x14 */ OFFSET_PTR mClusterPointer;
/* 0x18 */ OFFSET_PTR mClusterKeyPointer;
/* 0x1C */ OFFSET_PTR mClusterVertex;
/* 0x20 */ OFFSET_PTR mVtxPos;
/* 0x24 */ OFFSET_PTR mVtxNrm;
/* 0x28 */ OFFSET_PTR mClusterName;
/* 0x2C */ OFFSET_PTR mClusterKeyName;
/* 0x14 */ OFFSET_PTR_V0 mClusterPointer;
/* 0x18 */ OFFSET_PTR_V0 mClusterKeyPointer;
/* 0x1C */ OFFSET_PTR_V0 mClusterVertex;
/* 0x20 */ OFFSET_PTR_V0 mVtxPos;
/* 0x24 */ OFFSET_PTR_V0 mVtxNrm;
/* 0x28 */ OFFSET_PTR_V0 mClusterName;
/* 0x2C */ OFFSET_PTR_V0 mClusterKeyName;
};
/**
@@ -67,6 +67,6 @@ public:
/* 0x04 */ J3DDeformData* mpDeformData;
};
#undef OFFSET_PTR
#undef OFFSET_PTR_V0
#endif /* J3DCLUSTERLOADER_H */
@@ -82,7 +82,7 @@ public:
/* 0x00 */ u16 mMaterialNum;
/* 0x04 */ J3DMaterialInitData_v21* mpMaterialInitData;
/* 0x08 */ u16* mpMaterialID;
/* 0x08 */ BE(u16)* mpMaterialID;
/* 0x0C */ GXColor* mpMatColor;
/* 0x10 */ u8* mpColorChanNum;
/* 0x14 */ J3DColorChanInfo* mpColorChanInfo;
@@ -91,10 +91,10 @@ public:
/* 0x20 */ J3DTexCoord2Info* mpTexCoord2Info;
/* 0x24 */ J3DTexMtxInfo* mpTexMtxInfo;
/* 0x28 */ J3DTexMtxInfo* field_0x28;
/* 0x2C */ u16* mpTexNo;
/* 0x30 */ GXCullMode* mpCullMode;
/* 0x2C */ BE(u16)* mpTexNo;
/* 0x30 */ BE(GXCullMode)* mpCullMode;
/* 0x34 */ J3DTevOrderInfo* mpTevOrderInfo;
/* 0x38 */ GXColorS10* mpTevColor;
/* 0x38 */ BE(GXColorS10)* mpTevColor;
/* 0x3C */ GXColor* mpTevKColor;
/* 0x40 */ u8* mpTevStageNum;
/* 0x44 */ J3DTevStageInfo* mpTevStageInfo;
@@ -24,6 +24,15 @@ public:
void setGXforPrint();
void setGXforDraw();
void color(const JUtility::TColor& color0, const JUtility::TColor& color1) {
color(color0, color1, color0, color1);
}
void lineWidth(u8 width) {
field_0x16 = width;
GXSetLineWidth(field_0x16, GX_TO_ZERO);
}
/* 0x00 */ J2DPrint* field_0x0;
/* 0x04 */ JUtility::TColor field_0x4;
/* 0x08 */ JUtility::TColor field_0x8;
@@ -16,8 +16,8 @@ public:
y = i_y;
}
/* 0x00*/ int x;
/* 0x04*/ int y;
/* 0x00 */ int x;
/* 0x04 */ int y;
};
class JAWWindow {
@@ -29,9 +29,9 @@ public:
virtual void drawSelf(f32, f32);
virtual void drawSelf(f32, f32, Mtx*);
/* 0x0FC */ JAWGraphContext field_0xfc;
/* 0x0FC */ JAWGraphContext m_graf;
/* 0x118 */ JAWWindow* m_pParent;
/* 0x11C */ JUTPoint field_0x11c;
/* 0x11C */ JUTPoint m_point;
};
class TJ2DWindowDraw : public J2DWindow {
@@ -94,21 +94,29 @@ public:
static JUtility::TColor convJudaColor(u16);
void padProc(const JUTGamePad&);
void setWindowColor(const JUtility::TColor& color) {
setWindowColor(color, color, color, color);
}
void setWindowColor(u8 r, u8 g, u8 b, u8 a) {
setWindowColor(JUtility::TColor(r, g, b, a));
}
/* 0x004 */ Mtx mMatrix;
/* 0x034 */ u8 field_0x34[0x38 - 0x34];
/* 0x038 */ TJ2DWindowDraw field_0x38;
/* 0x180 */ J2DTextBox field_0x180;
/* 0x2B0 */ TWindowText field_0x2b0;
/* 0x3D8 */ JUtility::TColor field_0x3d8;
/* 0x3DC */ JUtility::TColor field_0x3dc;
/* 0x3E0 */ JUtility::TColor field_0x3e0;
/* 0x3E4 */ JUtility::TColor field_0x3e4;
/* 0x038 */ TJ2DWindowDraw m_drawWindow;
/* 0x180 */ J2DTextBox m_titleText;
/* 0x2B0 */ TWindowText m_windowText;
/* 0x3D8 */ JUtility::TColor m_windowColor0;
/* 0x3DC */ JUtility::TColor m_windowColor1;
/* 0x3E0 */ JUtility::TColor m_windowColor2;
/* 0x3E4 */ JUtility::TColor m_windowColor3;
/* 0x3E8 */ int field_0x3e8;
/* 0x3EC */ u8 field_0x3ec;
/* 0x3EC */ u8 m_isInit;
void setMatrix(Mtx mtx) { MTXCopy(mtx, mMatrix); }
void setAlpha(u8 alpha) { field_0x38.setAlpha(alpha); }
void draw(int x, int y, const J2DGrafContext* p_grafCtx) { field_0x38.drawPane(x, y, p_grafCtx); }
void setAlpha(u8 alpha) { m_drawWindow.setAlpha(alpha); }
void draw(int x, int y, const J2DGrafContext* p_grafCtx) { m_drawWindow.drawPane(x, y, p_grafCtx); }
};
#endif /* JAWWINDOW_H */
@@ -10,17 +10,17 @@
*/
struct JAISeqData {
JAISeqData(const void* param_0, u32 param_1) {
field_0x0 = (void*)param_0;
field_0x4 = param_1;
mBase = (void*)param_0;
mOffset = param_1;
}
void set(const void* param_0, u32 param_1) {
field_0x0 = (void*)param_0;
field_0x4 = param_1;
mBase = (void*)param_0;
mOffset = param_1;
}
/* 0x00 */ void* field_0x0;
/* 0x04 */ u32 field_0x4;
/* 0x00 */ void* mBase;
/* 0x04 */ u32 mOffset;
};
/**
@@ -29,10 +29,10 @@ struct JAISeqData {
*/
struct JAISeqDataRegion {
bool intersects(const JAISeqData& seqData) const {
if ((uintptr_t)addr + size < (uintptr_t)seqData.field_0x0) {
if ((uintptr_t)addr + size < (uintptr_t)seqData.mBase) {
return false;
}
if ((uintptr_t)seqData.field_0x0 + seqData.field_0x4 < (uintptr_t)addr) {
if ((uintptr_t)seqData.mBase + seqData.mOffset < (uintptr_t)addr) {
return false;
}
return true;
@@ -5,6 +5,7 @@
#include "JSystem/JAudio2/JAIAudible.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "global.h"
#include "dusk/endian.h"
#include <cstdint>
class JAISound;
@@ -49,22 +50,28 @@ public:
JAISoundID(const JAISoundID& other) { id_.composite_ = other.id_.composite_; };
JAISoundID(unsigned int sectionID, unsigned int groupID, unsigned int waveID) {
id_.info.type.parts.sectionID = sectionID;
id_.info.type.parts.groupID = groupID;
id_.info.waveID = waveID;
}
JAISoundID() {}
bool isAnonymous() const { return id_.composite_ == -1; }
void setAnonymous() { id_.composite_ = -1; }
union {
u32 composite_;
BE(u32) composite_;
struct {
union {
u16 value;
BE(u16) value;
struct {
u8 sectionID;
u8 groupID;
} parts;
} type;
u16 waveID;
BE(u16) waveID;
} info;
} id_;
};
@@ -322,6 +329,8 @@ public:
status_.field_0x0.flags.paused = param_0;
}
bool isPaused() const { return status_.field_0x0.flags.paused; }
void updateLifeTime(u32 lifeTime) {
if (lifeTime > lifeTime_) {
lifeTime_ = lifeTime;
@@ -4,6 +4,7 @@
#include "JSystem/JAudio2/JASTaskThread.h"
#include "JSystem/JUtility/JUTAssert.h"
#include <dvd.h>
#include "dusk/endian.h"
class JASChannel;
@@ -11,12 +12,17 @@ namespace JASDsp {
struct TChannel;
}
#define STREAM_FORMAT_ADPCM4 0
#define STREAM_FORMAT_PCM16 1
/**
* @ingroup jsystem-jaudio
*
* Plays streamed music from DVD .ast files.
*/
class JASAramStream {
public:
static const int CHANNEL_MAX = 6;
typedef void (*StreamCallback)(u32, JASAramStream*, void*);
enum CallbackType {
@@ -27,34 +33,40 @@ public:
// Used internally for passing data to task functions
struct TaskData {
/* 0x0 */ JASAramStream* stream;
/* 0x4 */ u32 field_0x4;
/* 0x8 */ int field_0x8;
/* 0x4 */ u32 param0;
/* 0x8 */ int param1;
};
struct Header {
/* 0x00 */ u32 tag;
/* 0x00 */ BE(u32) tag; // 'STRM'
#if TARGET_PC
/* 0x04 */ BE(u32) soundBlockSize;
/* 0x08 */ BE(u16) format;
/* 0x0A */ BE(u16) bits;
#else
/* 0x04 */ u8 field_0x4[5];
/* 0x09 */ u8 format;
/* 0x0A */ u8 bits;
/* 0x0C */ u16 channels;
/* 0x0E */ u16 loop;
/* 0x10 */ int field_0x10;
/* 0x14 */ u8 field_0x14[4];
/* 0x18 */ int loop_start;
/* 0x1C */ int loop_end;
/* 0x20 */ u32 block_size;
/* 0x24 */ u8 field_0x24[4];
/* 0x28 */ u8 field_0x28;
/* 0x29 */ u8 field_0x29[0x17];
#endif
/* 0x0C */ BE(u16) channels;
/* 0x0E */ BE(u16) loop;
/* 0x10 */ BE(int) mSampleRate;
/* 0x14 */ BE(u32) mSampleCount; // unused
/* 0x18 */ BE(int) loop_start;
/* 0x1C */ BE(int) loop_end;
/* 0x20 */ BE(u32) block_size;
/* 0x24 */ u8 _unused2[4];
/* 0x28 */ u8 mVolume;
/* 0x29 */ u8 _unused3[0x17];
}; // Size: 0x40
struct BlockHeader {
/* 0x00 */ u32 tag;
/* 0x04 */ u32 field_0x4;
/* 0x00 */ BE(u32) tag; // 'BLCK'
/* 0x04 */ BE(u32) mSize;
/* 0x08 */ struct {
s16 field_0x0;
s16 field_0x2;
} field_0x8[6];
BE(s16) mpLast;
BE(s16) mpPenult;
} mAdpcmContinuationData[CHANNEL_MAX];
}; // Size: 0x20
static void initSystem(u32, u32);
@@ -65,6 +77,10 @@ public:
bool stop(u16);
bool pause(bool);
bool cancel();
/**
* Calculate the amount of (decoded) audio samples in a single block of streamed audio.
*/
u32 getBlockSamples() const;
static void headerLoadTask(void*);
static void firstLoadTask(void*);
@@ -128,46 +144,103 @@ public:
static u32 getBlockSize() { return sBlockSize; }
static const int CHANNEL_MAX = 6;
/**
* Queue used to send specific commands that will be processed on the audio thread.
* These commands are sent from the main thread.
*/
/* 0x000 */ OSMessageQueue mMainCommandQueue;
/* 0x000 */ OSMessageQueue field_0x000;
/* 0x020 */ OSMessageQueue field_0x020;
/* 0x040 */ void* field_0x040[16];
/* 0x080 */ void* field_0x080[4];
/**
* Queue used to send specific commands that will be processed on the audio thread.
* These commands are sent from the load (DVD) thread.
*/
/* 0x020 */ OSMessageQueue mLoadCommandQueue;
/**
* Backing message storage for mMainCommandQueue.
*/
/* 0x040 */ void* mMainCommandQueueArray[16];
/**
* Backing message storage for mLoadCommandQueue.
*/
/* 0x080 */ void* mLoadCommandQueueArray[4];
/* 0x090 */ JASChannel* mChannels[CHANNEL_MAX];
/* 0x0A8 */ JASChannel* field_0x0a8;
/* 0x0AC */ bool field_0x0ac;
/* 0x0AD */ bool field_0x0ad;
/* 0x0AE */ u8 field_0x0ae;
/**
* The first audio channel initialized among mChannels.
* Used for the majority of bookkeeping, other channels replicate its state.
*/
/* 0x0A8 */ JASChannel* mPrimaryChannel;
/**
* If true, stream has finished preparing (reading headers and initial blocks),
* and is ready to play.
*/
/* 0x0AC */ bool mPrepareFinished;
/* 0x0AD */ bool mLoopEndLoaded;
/**
* Bitflag containing pause reasons/state for the stream.
*/
/* 0x0AE */ u8 mPauseFlags;
/* 0x0B0 */ int field_0x0b0;
/* 0x0B4 */ int field_0x0b4;
/* 0x0B8 */ u32 field_0x0b8;
/**
* (adjusted) value of mSamplesLeft on the primary channel last subframe.
* Used to calculate how many samples have been read and determine when the DSP looped.
*/
/* 0x0B4 */ int mLastSamplesLeft;
/**
* How many (decoded) samples the DSP has read so far.
*/
/* 0x0B8 */ u32 mReadSample;
/* 0x0BC */ int field_0x0bc;
/* 0x0C0 */ bool field_0x0c0;
/**
* If true, the current end (of loop, or just finish) is very close.
* Loop start/end positions are modified while this is set to account for this.
*/
/* 0x0C0 */ bool mEndSetup;
/* 0x0C4 */ volatile u32 field_0x0c4;
/* 0x0C8 */ volatile f32 field_0x0c8;
/* 0x0CC */ DVDFileInfo mDvdFileInfo;
/* 0x108 */ u32 field_0x108;
/* 0x10C */ int field_0x10c;
/* 0x108 */ u32 mRingEndIndex;
/**
* Index into the ARAM ring buffer that is currently being loaded.
* Wrapped around when incremented.
*/
/* 0x10C */ int mBlockRingIndex;
/**
* Block currently being loaded.
*/
/* 0x110 */ u32 mBlock;
/* 0x114 */ u8 field_0x114;
/* 0x118 */ u32 field_0x118;
/* 0x11C */ int field_0x11c;
/* 0x120 */ int field_0x120;
/* 0x124 */ int field_0x124;
/* 0x128 */ u16 field_0x128;
/* 0x12C */ int field_0x12c;
/* 0x130 */ s16 field_0x130[CHANNEL_MAX];
/* 0x13C */ s16 field_0x13c[CHANNEL_MAX];
/* 0x148 */ int field_0x148;
/* 0x14C */ u32 field_0x14c;
/* 0x114 */ u8 mIsCancelled;
/* 0x118 */ u32 mPendingLoadTasks;
/* 0x11C */ int mUpdateSamplesLeft;
/* 0x120 */ int mUpdateLoopStartSample;
/* 0x124 */ int mUpdateEndSample;
/* 0x128 */ u16 mUpdateLoopFlag;
/**
* Bitflags updated in the play callback to track what data needs to be synchronized
* between all channels.
*/
/* 0x12C */ int mChannelUpdateFlags;
/* 0x130 */ s16 mpLasts[CHANNEL_MAX];
/* 0x13C */ s16 mpPenults[CHANNEL_MAX];
/* 0x148 */ int mAramAddress;
/* 0x14C */ u32 mAramSize;
/* 0x150 */ StreamCallback mCallback;
/* 0x154 */ void* mCallbackData;
/* 0x158 */ u16 field_0x158;
/* 0x158 */ u16 mFormat;
/* 0x15A */ u16 mChannelNum;
/* 0x15C */ u32 mBufCount;
/* 0x160 */ u32 field_0x160;
/* 0x164 */ u32 field_0x164;
/* 0x160 */ u32 mAramBlocksPerChannel;
/* 0x164 */ u32 mSampleRate;
/* 0x168 */ bool mLoop;
/* 0x16C */ u32 mLoopStart;
/* 0x170 */ u32 mLoopEnd;
@@ -177,11 +250,29 @@ public:
/* 0x194 */ f32 mChannelPan[CHANNEL_MAX];
/* 0x1AC */ f32 mChannelFxMix[CHANNEL_MAX];
/* 0x1C4 */ f32 mChannelDolby[CHANNEL_MAX];
/* 0x1DC */ u16 field_0x1dc[CHANNEL_MAX];
/* 0x1DC */ u16 mMixConfig[CHANNEL_MAX];
/**
* Thread that will be sent DVD load commands.
* This is the JASDvd thread in practice.
*/
static JASTaskThread* sLoadThread;
/**
* Buffer used to read DVD data. Can store the size of an entire streamed audio block.
*/
static u8* sReadBuffer;
/**
* Block size used by all streamed music in the game.
* This is 0x2760 for TP.
*/
static u32 sBlockSize;
/**
* Maximum amount of output channels for all streamed music in the game.
* This is 2 for TP (stereo).
*/
static u32 sChannelMax;
};
@@ -32,11 +32,6 @@ struct JASAudioThread : public JKRThread, public JASGlobalInstance<JASAudioThrea
static volatile int snIntCount; // type unsure
#if TARGET_PC
static bool sThreadInitComplete;
static OSMutex sThreadInitCompleteMutex;
static OSCond sThreadInitCompleteCond;
#endif
};
#endif /* JASAUDIOTHREAD_H */
@@ -10,21 +10,21 @@ class JKRHeap;
namespace JASBNKParser {
struct TFileHeader {
/* 0x0 */ BE(int) id;
/* 0x0 */ BE(int) mMagic;
/* 0x4 */ BE(u32) mSize;
/* 0x8 */ u8 _08[4];
/* 0x8 */ BE(u32) mGlobalId;
/* 0xC */ BE(u32) mVersion;
};
namespace Ver1 {
struct TOsc {
/* 0x00 */ BE(u32) id;
/* 0x00 */ BE(u32) id; // "Osci"
/* 0x04 */ u8 mTarget;
/* 0x08 */ BE(f32) _08;
/* 0x0C */ BE(u32) mTableOffset;
/* 0x10 */ BE(u32) _10;
/* 0x14 */ BE(f32) mScale;
/* 0x18 */ BE(f32) _18;
/* 0x08 */ BE(f32) mRate;
/* 0x0C */ BE(u32) mAttackEnvelopeOffset;
/* 0x10 */ BE(u32) mReleaseEnvelopeOffset;
/* 0x14 */ BE(f32) mScale; // width
/* 0x18 */ BE(f32) mVertex;
};
struct TPercData {
@@ -36,7 +36,7 @@ namespace JASBNKParser {
};
struct TChunk {
/* 0x0 */ BE(u32) mID;
/* 0x0 */ BE(u32) mID; // Magic
/* 0x4 */ BE(u32) mSize;
};
@@ -113,7 +113,7 @@ namespace JASBNKParser {
};
struct TOffsetData {
/* 0x000 */ u8 field_0x20[4];
/* 0x000 */ BE(u32) mMagic; // 'BANK'
/* 0x004 */ TOffset<TInst> mInstOffset[0x80];
/* 0x204 */ u8 field_0x204[0x190];
/* 0x394 */ TOffset<TPerc> mPercOffset[12];
@@ -33,7 +33,11 @@ struct JASCalc {
f32 fake2(s32 x);
f32 fake3();
#if AVOID_UB
static const s16 CUTOFF_TO_IIR_TABLE[129][4];
#else
static const s16 CUTOFF_TO_IIR_TABLE[128][4];
#endif
};
template <typename A, typename B>
@@ -6,6 +6,7 @@
#include "JSystem/JAudio2/JASOscillator.h"
#include "JSystem/JAudio2/JASSoundParams.h"
#include "JSystem/JAudio2/JASWaveInfo.h"
#include "JSystem/JAudio2/JASDSPInterface.h"
#include <os.h>
struct JASDSPChannel;
@@ -45,6 +46,9 @@ public:
/* 0x14 */ f32 mDolby;
};
#define CHANNEL_WAVE 0
#define CHANNEL_OSCILLATOR 2
/**
* @ingroup jsystem-jaudio
*
@@ -52,7 +56,7 @@ public:
class JASChannel : public JASPoolAllocObject_MultiThreaded<JASChannel> {
public:
typedef void (*Callback)(u32, JASChannel*, JASDsp::TChannel*, void*);
static const int BUSOUT_CPUCH = 6;
static const int BUSOUT_CPUCH = DSP_OUTPUT_CHANNELS;
static const int OSC_NUM = 2;
enum CallbackType {
@@ -75,7 +79,7 @@ public:
};
union MixConfig {
u16 whole;
BE(u16) whole;
struct {
u8 upper;
u8 lower0 : 4;
@@ -153,10 +157,14 @@ public:
/* 0xD4 */ u32 mKeySweepCount;
/* 0xD8 */ u32 mSkipSamples;
struct {
u32 field_0x0;
JASWaveInfo field_0x4;
u32 mChannelType; // CHANNEL_WAVE or CHANNEL_OSCILLATOR
JASWaveInfo mWaveInfo;
} field_0xdc;
intptr_t field_0x104;
union {
u32 mWaveAramAddress;
u32 mOscillatorSomething;
u32 field_0x104;
};
static OSMessageQueue sBankDisposeMsgQ;
static OSMessage sBankDisposeMsg[16];
@@ -8,12 +8,18 @@
*
*/
class JASCriticalSection {
public:
#if TARGET_PC
JASCriticalSection();
~JASCriticalSection();
#else
public:
JASCriticalSection() { mInterruptState = OSDisableInterrupts(); };
~JASCriticalSection() { OSRestoreInterrupts(mInterruptState); };
private:
u32 mInterruptState;
#endif
};
#endif /* JASCRITICALSECTION_H */
@@ -5,9 +5,14 @@
/**
* @ingroup jsystem-jaudio
*
* Responsible for allocating and prioritizing the available hardware DSP channels.
*/
struct JASDSPChannel {
/**
* Callback used to update DSP channel information on a regular basis.
* Parameters are a CallbackType, hardware channel, and specified user data.
* Return -1 to immediately abort playback.
*/
typedef s32 (*Callback)(u32, JASDsp::TChannel*, void*);
enum Status {
@@ -17,9 +22,24 @@ struct JASDSPChannel {
};
enum CallbackType {
/**
* Fired on a regular basis during play to update parameters.
*/
/* 0 */ CB_PLAY,
/**
* Fired once, when the channel starts playing.
*/
/* 1 */ CB_START,
/**
* Fired once, when the channel naturally finishes playing.
*/
/* 2 */ CB_STOP,
/**
* Fired once, if the channel is abruptly stopped due to an error or prioritization.
*/
/* 3 */ CB_DROP,
};
@@ -46,9 +66,13 @@ struct JASDSPChannel {
static JASDSPChannel* sDspChannels;
/* 0x00 */ s32 mStatus;
/**
* Priority of this DSP channel. Used to
*/
/* 0x04 */ s16 mPriority;
/* 0x08 */ u32 mFlags;
/* 0x0C */ u32 field_0xc;
/* 0x0C */ u32 mUpdateCounter;
/* 0x10 */ Callback mCallback;
/* 0x14 */ void* mCallbackData;
/* 0x18 */ JASDsp::TChannel* mChannel;
@@ -4,6 +4,21 @@
#include <cstdint>
#include <types.h>
/**
* Amount of separate audio channels (i.e. individual playbacks, voices) the DSP can mix at once.
*/
#define DSP_CHANNELS 64
/**
* Amount of audio channels the DSP can calculate outputs for.
*/
#define DSP_OUTPUT_CHANNELS 6 // Presumed 5.1 surround
/**
* Amount of audio samples rendered by the DSP in a single sub frame.
*/
#define DSP_SUBFRAME_SIZE 0x50
struct JASWaveInfo;
namespace JASDsp {
@@ -30,6 +45,24 @@ namespace JASDsp {
u16 field_0x10[8];
} FxBuf;
struct OutputChannelConfig {
u16 mBusConnect;
u16 mTargetVolume;
u16 mCurrentVolume;
/**
* Gets upper 8 bits cleared when audio volume is changed mid-playback.
* Presumed to be some kind of progress used by the DSP to calculate position between
* mTargetVolume and mCurrentVolume.
*/
u16 mVolumeProgress;
};
/**
* DSP memory for each playback channel ("voice").
* The DSP can read and write this memory. It is used as configuration, feedback,
* and working memory.
*/
struct TChannel {
void init();
void playStart();
@@ -37,67 +70,115 @@ namespace JASDsp {
void replyFinishRequest();
void forceStop();
bool isActive() const;
/**
* Check whether the DSP has finished playing this channel.
*/
bool isFinish() const;
void setWaveInfo(JASWaveInfo const&, u32, u32);
void setOscInfo(u32);
void initAutoMixer();
void setAutoMixer(u16, u8, u8, u8, u8);
void setPitch(u16);
void setMixerInitVolume(u8, s16);
void setMixerVolume(u8, s16);
void setMixerInitVolume(u8 outputChannel, s16 volume);
void setMixerVolume(u8 outputChannel, s16 volume);
void setPauseFlag(u8);
/**
* Flushes backing memory of channel out of the data cache.
*/
void flush();
void initFilter();
void setFilterMode(u16);
void setIIRFilterParam(s16*);
void setFIR8FilterParam(s16*);
void setDistFilter(s16);
void setBusConnect(u8, u8);
void setBusConnect(u8 outputChannel, u8 param_1);
/**
* Whether this channel is currently actively playing audio.
*/
/* 0x000 */ u16 mIsActive;
/**
* Written by DSP to indicate playback has finished.
*/
/* 0x002 */ u16 mIsFinished;
/**
* Pitch shift via changing playback speed.
*/
/* 0x004 */ u16 mPitch;
/* 0x006 */ short field_0x006;
/* 0x008 */ u16 field_0x008;
/* 0x00A */ u8 field_0x00A[0x00C - 0x00A];
/* 0x006 */ short _unused1;
/**
* Set to 1 when playback starts, cleared by DSP later,
* checked by JASAramStream before actually doing processing.
* Presumably to instruct DSP to clear state?
* (Corroborated by fields JASAramStream checks never being cleared explicitly by CPU.)
*/
/* 0x008 */ u16 mResetFlag;
/* 0x00A */ u8 _unused2[0x00C - 0x00A];
/* 0x00C */ s16 mPauseFlag;
/* 0x00E */ short field_0x00E;
/* 0x010 */ u16 field_0x010[1][4]; // array size unknown
/* 0x018 */ u8 field_0x018[0x050 - 0x018];
/* 0x050 */ u16 field_0x050;
/* 0x052 */ u16 field_0x052;
/* 0x054 */ u16 field_0x054;
/* 0x056 */ u16 field_0x056;
/* 0x058 */ u16 field_0x058;
/* 0x05A */ u8 field_0x05A[0x060 - 0x05A];
/* 0x060 */ short field_0x060;
/* 0x062 */ u8 field_0x062[0x064 - 0x062];
/* 0x064 */ u16 field_0x064;
/* 0x066 */ short field_0x066;
/* 0x068 */ int field_0x068;
/* 0x06C */ u8 field_0x06C[0x070 - 0x06C];
/* 0x070 */ int field_0x070;
/* 0x074 */ int field_0x074;
/* 0x078 */ short field_0x078[4];
/* 0x080 */ short field_0x080[20];
/* 0x0A8 */ short field_0x0a8[4];
/* 0x0B0 */ u16 field_0x0b0[16];
/* 0x0D0 */ u8 field_0x0D0[0x100 - 0x0D0];
/* 0x100 */ u16 field_0x100;
/* 0x102 */ u16 field_0x102;
/* 0x104 */ s16 field_0x104;
/* 0x106 */ s16 field_0x106;
/* 0x00E */ short _unused3;
/* 0x010 */ OutputChannelConfig mOutputChannels[DSP_OUTPUT_CHANNELS];
/* 0x040 */ u8 _unused4[0x050 - 0x040];
/* 0x050 */ u16 mAutoMixerPanDolby; // pan is upper 8 bits, dolby lower 8.
/* 0x052 */ u16 mAutoMixerFxMix;
/* 0x054 */ u16 mAutoMixerInitVolume;
/* 0x056 */ u16 mAutoMixerVolume;
/* 0x058 */ u16 mAutoMixerBeenSet;
/* 0x05A */ u8 _unused5[0x060 - 0x05A];
/* 0x060 */ short field_0x060; // Only cleared to zero, presumed used by DSP.
/* 0x062 */ u8 _unused6[0x064 - 0x062];
/**
* Samples per ADPCM frame for ADPCM audio. Seems just set to 1 for PCM formats.
* Name could use improvement, probably?
*/
/* 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.
/* 0x06C */ u8 _unused7[0x070 - 0x06C];
/**
* Current audio read position in ARAM. Updated by DSP.
*/
/* 0x070 */ u32 mAramStreamPosition;
/**
* Amount of (decoded) audio samples left until the end of the buffer.
* Gets written by DSP, but also CPU.
*/
/* 0x074 */ u32 mSamplesLeft; // Never directly cleared to zero. Seems sus. Cleared by DSP?
/* 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];
/* 0x100 */ u16 mBytesPerBlock;
/* 0x102 */ u16 mLoopFlag;
/**
* Used for decoding ADPCM data around loop edges.
*/
/* 0x104 */ s16 mpLast;
/**
* Used for decoding ADPCM data around loop edges.
*/
/* 0x106 */ s16 mpPenult;
/* 0x108 */ u16 mFilterMode;
/* 0x10A */ u16 mForcedStop;
/* 0x10C */ int field_0x10c;
/* 0x110 */ u32 field_0x110;
/* 0x114 */ u32 field_0x114;
/* 0x118 */ u32 field_0x118;
/* 0x11C */ int field_0x11c;
/* 0x110 */ u32 mLoopStartSample;
/* 0x114 */ u32 mEndSample;
/* 0x118 */ u32 mWaveAramAddress;
/* 0x11C */ int mSampleCount;
/* 0x120 */ s16 fir_filter_params[8];
/* 0x130 */ u8 field_0x130[0x148 - 0x130];
/* 0x130 */ u8 _unused9[0x148 - 0x130];
/* 0x148 */ s16 iir_filter_params[8];
/* 0x158 */ u8 field_0x158[0x180 - 0x158];
/* 0x158 */ u8 _unused10[0x180 - 0x158];
};
void boot(void (*)(void*));
@@ -3,6 +3,10 @@
#include "JSystem/JAudio2/JASCallback.h"
#define JAS_OUTPUT_MONO OS_SOUND_MODE_MONO
#define JAS_OUTPUT_STEREO OS_SOUND_MODE_STEREO
#define JAS_OUTPUT_SURROUND 2
typedef s32 (*DriverCallback)(void*);
namespace JASDriver {
@@ -33,6 +33,9 @@ public:
bool isAllocated() const { return mBase; }
u32 getSize() const { return mSize; }
JSUTree<JASHeap>* getFirstChild() { return mTree.getFirstChild(); }
JSUTree<JASHeap>* getEndChild() { return mTree.getEndChild(); }
/* 0x00 */ JSUTree<JASHeap> mTree;
/* 0x1C */ OSMutex mMutex;
/* 0x34 */ JASDisposer* mDisposer;
@@ -352,6 +355,28 @@ template <typename T> JASMemPool<T> JASPoolAllocObject<T>::memPool_;
template <typename T>
class JASMemPool_MultiThreaded : public JASGenericMemPool {
public:
#if TARGET_PC
OSMutex mutex;
JASMemPool_MultiThreaded() {
OSInitMutex(&mutex);
}
void newMemPool(int param_0) {
JASThreadingModel::ObjectLevelLockable<OSMutex>::Lock lock(mutex);
JASGenericMemPool::newMemPool(sizeof(T), param_0);
}
void* alloc(size_t count) {
JASThreadingModel::ObjectLevelLockable<OSMutex>::Lock lock(mutex);
return JASGenericMemPool::alloc(count);
}
void free(void* ptr, u32 param_1) {
JASThreadingModel::ObjectLevelLockable<OSMutex>::Lock lock(mutex);
JASGenericMemPool::free(ptr, param_1);
}
#else
void newMemPool(int param_0) {
typename JASThreadingModel::InterruptsDisable<JASMemPool_MultiThreaded<T> >::Lock lock(*this);
JASGenericMemPool::newMemPool(sizeof(T), param_0);
@@ -366,6 +391,7 @@ public:
typename JASThreadingModel::InterruptsDisable<JASMemPool_MultiThreaded<T> >::Lock lock(*this);
JASGenericMemPool::free(ptr, param_1);
}
#endif
};
/**
@@ -9,10 +9,21 @@
*
*/
struct JASOscillator {
enum EnvelopeMode {
/* 0x0 */ ENVELOPE_LINEAR,
/* 0x1 */ ENVELOPE_SQUARE,
/* 0x2 */ ENVELOPE_SQUARE_ROOT,
/* 0x3 */ ENVELOPE_SAMPLE_CELL,
ENVELOPE_LOOP = 0xD,
ENVELOPE_HOLD = 0xE,
ENVELOPE_STOP = 0xF,
};
struct Point {
/* 0x0 */ BE(s16) _0;
/* 0x2 */ BE(s16) _2;
/* 0x4 */ BE(s16) _4;
/* 0x0 */ BE(s16) mEnvelopeMode; // EnvelopeMode
/* 0x2 */ BE(s16) mTime;
/* 0x4 */ BE(s16) mValue;
};
struct EffectParams {
@@ -37,11 +48,11 @@ struct JASOscillator {
struct Data {
/* 0x00 */ u32 mTarget;
/* 0x04 */ f32 _04;
/* 0x04 */ f32 mRate;
/* 0x08 */ const Point* mTable;
/* 0x0C */ const Point* rel_table;
/* 0x10 */ f32 mScale;
/* 0x14 */ f32 _14;
/* 0x10 */ f32 mScale; // aka width
/* 0x14 */ f32 mVertex;
};
enum Target {
@@ -75,9 +86,9 @@ struct JASOscillator {
/* 0x08 */ f32 _08;
/* 0x0C */ f32 _0C;
/* 0x10 */ f32 _10;
/* 0x14 */ u16 _14;
/* 0x14 */ u16 mCurPoint;
/* 0x16 */ u16 mDirectRelease;
/* 0x18 */ u8 _18;
/* 0x18 */ u8 mEnvelopeMode; // EnvelopeMode
/* 0x1A */ u16 _1A;
/* 0x1C */ int _1C;
@@ -14,9 +14,9 @@ public:
enum BranchCondition {};
struct CmdInfo {
s32 (JASSeqParser::*field_0x0)(JASTrack*, u32*);
u16 field_0xc;
u16 field_0xe;
s32 (JASSeqParser::*mHandler)(JASTrack*, u32*);
u16 mParameterCount;
u16 mParameterTypes;
};
virtual ~JASSeqParser() {}
@@ -3,6 +3,8 @@
#include <types.h>
#define JAS_SEQ_STACK_SIZE 8
/**
* @ingroup jsystem-jaudio
*
@@ -19,55 +21,55 @@ public:
int readMidiValue();
void jump(u32 param_1) {
field_0x04 = field_0x00 + param_1;
mCurPos = mBase + param_1;
}
void jump(void* param_1) {
field_0x04 = (u8*)param_1;
mCurPos = (u8*)param_1;
}
u32 get24(u32 param_0) const {
return (*(u32*)(field_0x00 + param_0 - 1)) & 0xffffff;
return (*(BE(u32)*)(mBase + param_0 - 1)) & 0xffffff;
}
u32* getBase() { return (u32*)field_0x00; }
void* getAddr(u32 param_0) { return field_0x00 + param_0; }
u8 getByte(u32 param_0) const { return *(field_0x00 + param_0); }
u16 get16(u32 param_0) const { return *(u16*)(field_0x00 + param_0); }
u32 get32(u32 param_0) const { return *(u32*)(field_0x00 + param_0); }
u8* getCur() { return field_0x04; }
u32 readByte() { return *field_0x04++; }
u32* getBase() { return (u32*)mBase; }
void* getAddr(u32 param_0) { return mBase + param_0; }
u8 getByte(u32 param_0) const { return *(mBase + param_0); }
u16 get16(u32 param_0) const { return *(BE(u16)*)(mBase + param_0); }
u32 get32(u32 param_0) const { return *(BE(u32)*)(mBase + param_0); }
u8* getCur() { return mCurPos; }
u32 readByte() { return *mCurPos++; }
u32 read16() {
#ifdef __MWERKS__
return *((u16*)field_0x04)++;
return *((u16*)mCurPos)++;
#else
u16* value = (u16*)field_0x04;
field_0x04 += 2;
BE(u16)* value = (BE(u16)*)mCurPos;
mCurPos += 2;
return *value;
#endif
}
u32 read24() {
field_0x04--;
mCurPos--;
#ifdef __MWERKS__
return (*((u32*)field_0x04)++) & 0x00ffffff;
return (*((u32*)mCurPos)++) & 0x00ffffff;
#else
u32* value = (u32*)field_0x04;
field_0x04 += 4;
BE(u32)* value = (BE(u32)*)mCurPos;
mCurPos += 4;
return (*value) & 0x00ffffff;
#endif
}
u16 getLoopCount() const {
if (field_0x08 == 0) {
if (mCurStackDepth == 0) {
return 0;
}
return field_0x2c[field_0x08 - 1];
return mLoopCount[mCurStackDepth - 1];
}
/* 0x00 */ u8* field_0x00;
/* 0x04 */ u8* field_0x04;
/* 0x08 */ u32 field_0x08;
/* 0x0C */ u16* field_0x0c[8];
/* 0x2C */ u16 field_0x2c[8];
/* 0x00 */ u8* mBase;
/* 0x04 */ u8* mCurPos;
/* 0x08 */ u32 mCurStackDepth;
/* 0x0C */ u16* mReturnAddr[JAS_SEQ_STACK_SIZE];
/* 0x2C */ u16 mLoopCount[JAS_SEQ_STACK_SIZE];
};
#endif /* JASSEQREADER_H */
@@ -54,7 +54,7 @@ struct JASTrack : public JASPoolAllocObject_MultiThreaded<JASTrack> {
/* 0x4c */ JASTrack* mTrack;
};
struct TList : JGadget::TLinkList<JASTrack, JASTrackNodeOffset> {
struct TList : JGadget::TLinkList<JASTrack, -JASTrackNodeOffset> {
TList() : mCallbackRegistered(false) {}
void append(JASTrack*);
void seqMain();
@@ -19,12 +19,12 @@ public:
u32 checkImport(u32) const;
u32 checkExport(u32) const;
u16 get(u32 param_0) const { return field_0x4[param_0]; }
void set(u32 param_0, u16 param_1) { field_0x4[param_0] = param_1; }
u16 get(u32 param_0) const { return mPortValues[param_0]; }
void set(u32 param_0, u16 param_1) { mPortValues[param_0] = param_1; }
u16 field_0x0;
u16 field_0x2;
u16 field_0x4[MAX_PORTS];
u16 mPortValues[MAX_PORTS];
};
#endif /* JASTRACKPORT_H */
@@ -31,26 +31,28 @@ public:
struct TWave {
/* 0x00 */ u8 _00;
/* 0x01 */ u8 _01;
/* 0x02 */ u8 _02;
/* 0x04 */ BE(f32) _04;
/* 0x08 */ BE(u32) mOffset;
/* 0x0C */ BE(u32) _0C;
/* 0x10 */ BE(u32) _10;
/* 0x14 */ BE(u32) _14;
/* 0x18 */ BE(u32) _18;
/* 0x1C */ BE(u32) _1C;
/* 0x20 */ BE(s16) _20;
/* 0x22 */ BE(s16) _22;
/* 0x01 */ u8 mWaveFormat;
/* 0x02 */ u8 mBaseKey;
/* 0x04 */ BE(f32) mSampleRate;
/* 0x08 */ BE(u32) mAWOffsetStart;
/* 0x0C */ BE(u32) mAWOffsetEnd;
/* 0x10 */ BE(u32) mLoopFlags;
/* 0x14 */ BE(u32) mLoopStartSample;
/* 0x18 */ BE(u32) mLoopEndSample;
/* 0x1C */ BE(u32) mSampleCount;
/* 0x20 */ BE(s16) mpLast;
/* 0x22 */ BE(s16) mpPenult;
};
struct TWaveArchive {
/* 0x00 */ char mFileName[0x74]; // unknown length
/* 0x00 */ char mFileName[0x70];
/* 0x70 */ BE(u32) mWaveCount;
/* 0x74 */ TOffset<TWave> mWaveOffsets[0];
};
struct TWaveArchiveBank {
/* 0x0 */ u8 _00[8];
/* 0x0 */ BE(u32) mMagic; // 'WINF'
/* 0x0 */ BE(u32) mArchiveCounts;
/* 0x8 */ TOffset<TWaveArchive> mArchiveOffsets[0];
};
@@ -66,14 +68,17 @@ public:
};
struct TCtrlGroup {
/* 0x0 */ u8 _00[8];
/* 0x0 */ BE(u32) mMagic; // 'WBCT'
/* 0x4 */ u32 mUnknown;
/* 0x8 */ BE(u32) mGroupCount;
/* 0xC */ TOffset<TCtrlScene> mCtrlSceneOffsets[0];
};
/** @fabricated */
struct THeader {
/* 0x00 */ u8 _00[0xC];
/* 0x00 */ BE(u32) mMagic; // 'WSYS'
/* 0x04 */ BE(u32) mSize;
/* 0x08 */ BE(u32) mId;
/* 0x0C */ BE(u32) mWaveTableSize;
/* 0x10 */ TOffset<TWaveArchiveBank> mArchiveBankOffset;
/* 0x14 */ TOffset<TCtrlGroup> mCtrlGroupOffset;
@@ -54,6 +54,8 @@ struct JASWaveArc : JASDisposer {
virtual void onEraseDone() {}
s32 getStatus() const { return mStatus; }
u32 getFileSize() const { return mFileLength; }
JASHeap* getHeap() { return &mHeap; }
struct loadToAramCallbackParams {
// not official struct name
@@ -3,7 +3,12 @@
#include <types.h>
class JASWaveArc;
struct JASWaveArc;
#define WAVE_FORMAT_ADPCM4 0
#define WAVE_FORMAT_ADPCM2 1
#define WAVE_FORMAT_PCM8 2
#define WAVE_FORMAT_PCM16 3
/**
* @ingroup jsystem-jaudio
@@ -11,21 +16,21 @@ class JASWaveArc;
*/
struct JASWaveInfo {
JASWaveInfo() {
field_0x01 = 0x3c;
mBaseKey = 0x3c;
field_0x20 = &one;
}
/* 0x00 */ u8 field_0x00;
/* 0x01 */ u8 field_0x01;
/* 0x02 */ u8 field_0x02;
/* 0x04 */ f32 field_0x04;
/* 0x08 */ int field_0x08;
/* 0x0C */ int field_0x0c;
/* 0x10 */ u32 field_0x10;
/* 0x14 */ int field_0x14;
/* 0x18 */ int field_0x18;
/* 0x1C */ s16 field_0x1c;
/* 0x1E */ s16 field_0x1e;
/* 0x00 */ u8 mWaveFormat;
/* 0x01 */ u8 mBaseKey;
/* 0x02 */ u8 mLoopFlag;
/* 0x04 */ f32 mSampleRate;
/* 0x08 */ int mOffsetStart;
/* 0x0C */ int mOffsetLength;
/* 0x10 */ u32 mLoopStartSample;
/* 0x14 */ int mLoopEndSample;
/* 0x18 */ int mSampleCount;
/* 0x1C */ s16 mpLast;
/* 0x1E */ s16 mpPenult;
/* 0x20 */ const u32* field_0x20;
static u32 one;
@@ -2,6 +2,7 @@
#define JAUAUDIBLEPARAM_H
#include <types.h>
#include "dusk/endian.h"
/**
* @ingroup jsystem-jaudio
@@ -9,13 +10,13 @@
*/
struct JAUAudibleParam {
f32 getDopplerPower() const {
return (u32)((*(u8*)&field_0x0.raw >> 4) & 0xf) * (1.0f / 15.0f);
return field_0x0.bytes.b0_0 * (1.0f / 15.0f);
}
union {
struct {
u16 f0;
u16 f1;
BE(u16) f0;
BE(u16) f1;
} half;
struct {
u8 b0_0 : 4;
@@ -29,7 +30,7 @@ struct JAUAudibleParam {
u8 b2;
u8 b3;
} bytes;
u32 raw;
BE(u32) raw;
} field_0x0;
};
@@ -21,7 +21,7 @@ public:
/* 0x10 */ int audioThreadPriority_;
/* 0x14 */ int dvdThreadId_;
/* 0x18 */ int audioThreadId_;
/* 0x1C */ int field_0x1c;
/* 0x1C */ int mJasTrackPoolSize;
/* 0x20 */ int field_0x20;
/* 0x24 */ int aramBlockSize_;
/* 0x28 */ int aramChannelNum_;
@@ -38,10 +38,10 @@ public:
JAU_JAIInitializer();
void initJAInterface();
int field_0x0;
int field_0x4;
int field_0x8;
int field_0xc;
int mJaiSePoolSize;
int mJaiSeqPoolSize;
int mJaiStreamPoolSize;
int mJaiSoundChildPoolSize;
};
#endif /* JAUINITIALIZER_H */
@@ -11,11 +11,11 @@ struct JAISeqDataRegion;
*
*/
struct JAUSeqCollectionData {
s8 field_0x0;
s8 field_0x1;
BE(u16) field_0x2;
BE(u32) field_0x4;
BE(u32) field_0x8;
s8 mMagic1; // 'S'
s8 mMagic2; // 'C'
BE(u16) mNumSoundCategories;
BE(u32) mSectionSize;
BE(u32) mTableOffsets[0]; // VLA
};
/**
@@ -29,12 +29,12 @@ public:
bool getSeqData(int, int, JAISeqData*);
bool getSeqDataRegion(JAISeqDataRegion*);
bool isValid() const { return field_0x8; }
bool isValid() const { return mHeader; }
/* 0x00 */ u16 field_0x0;
/* 0x04 */ const BE(u32)* field_0x4;
/* 0x08 */ const JAUSeqCollectionData* field_0x8;
/* 0x0C */ int field_0xc;
/* 0x00 */ u16 mNumSoundCategories;
/* 0x04 */ const BE(u32)* mTableOffsets;
/* 0x08 */ const JAUSeqCollectionData* mHeader;
/* 0x0C */ u32 mSectionSize;
};
/**
@@ -49,7 +49,7 @@ public:
SeqDataReturnValue getSeqData(JAISoundID, JAISeqData*);
~JAUSeqDataMgr_SeqCollection();
const void* getResource() const { return field_0x4; }
const void* getResource() const { return mTableOffsets; }
void init(const void* param_1) { JAUSeqCollection::init(param_1); }
/* 0x14 */ JAISeqDataUser* user_;

Some files were not shown because too many files have changed in this diff Show More